1/** 2 * Copyright (c) 2014 Redpine Signals Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * 16 */ 17 18#include <linux/firmware.h> 19#include "rsi_usb.h" 20 21/** 22 * rsi_copy_to_card() - This function includes the actual funtionality of 23 * copying the TA firmware to the card.Basically this 24 * function includes opening the TA file,reading the TA 25 * file and writing their values in blocks of data. 26 * @common: Pointer to the driver private structure. 27 * @fw: Pointer to the firmware value to be written. 28 * @len: length of firmware file. 29 * @num_blocks: Number of blocks to be written to the card. 30 * 31 * Return: 0 on success and -1 on failure. 32 */ 33static int rsi_copy_to_card(struct rsi_common *common, 34 const u8 *fw, 35 u32 len, 36 u32 num_blocks) 37{ 38 struct rsi_hw *adapter = common->priv; 39 struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 40 u32 indx, ii; 41 u32 block_size = dev->tx_blk_size; 42 u32 lsb_address; 43 u32 base_address; 44 45 base_address = TA_LOAD_ADDRESS; 46 47 for (indx = 0, ii = 0; ii < num_blocks; ii++, indx += block_size) { 48 lsb_address = base_address; 49 if (rsi_usb_write_register_multiple(adapter, 50 lsb_address, 51 (u8 *)(fw + indx), 52 block_size)) { 53 rsi_dbg(ERR_ZONE, 54 "%s: Unable to load %s blk\n", __func__, 55 FIRMWARE_RSI9113); 56 return -EIO; 57 } 58 rsi_dbg(INIT_ZONE, "%s: loading block: %d\n", __func__, ii); 59 base_address += block_size; 60 } 61 62 if (len % block_size) { 63 lsb_address = base_address; 64 if (rsi_usb_write_register_multiple(adapter, 65 lsb_address, 66 (u8 *)(fw + indx), 67 len % block_size)) { 68 rsi_dbg(ERR_ZONE, 69 "%s: Unable to load %s blk\n", __func__, 70 FIRMWARE_RSI9113); 71 return -EIO; 72 } 73 } 74 rsi_dbg(INIT_ZONE, 75 "%s: Succesfully loaded %s instructions\n", __func__, 76 FIRMWARE_RSI9113); 77 78 rsi_dbg(INIT_ZONE, "%s: loaded firmware\n", __func__); 79 return 0; 80} 81 82/** 83 * rsi_usb_rx_thread() - This is a kernel thread to receive the packets from 84 * the USB device. 85 * @common: Pointer to the driver private structure. 86 * 87 * Return: None. 88 */ 89void rsi_usb_rx_thread(struct rsi_common *common) 90{ 91 struct rsi_hw *adapter = common->priv; 92 struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 93 int status; 94 95 do { 96 rsi_wait_event(&dev->rx_thread.event, EVENT_WAIT_FOREVER); 97 98 if (atomic_read(&dev->rx_thread.thread_done)) 99 goto out; 100 101 mutex_lock(&common->tx_rxlock); 102 status = rsi_read_pkt(common, 0); 103 if (status) { 104 rsi_dbg(ERR_ZONE, "%s: Failed To read data", __func__); 105 mutex_unlock(&common->tx_rxlock); 106 return; 107 } 108 mutex_unlock(&common->tx_rxlock); 109 rsi_reset_event(&dev->rx_thread.event); 110 if (adapter->rx_urb_submit(adapter)) { 111 rsi_dbg(ERR_ZONE, 112 "%s: Failed in urb submission", __func__); 113 return; 114 } 115 } while (1); 116 117out: 118 rsi_dbg(INFO_ZONE, "%s: Terminated thread\n", __func__); 119 complete_and_exit(&dev->rx_thread.completion, 0); 120} 121 122 123/** 124 * rsi_load_ta_instructions() - This function includes the actual funtionality 125 * of loading the TA firmware.This function also 126 * includes opening the TA file,reading the TA 127 * file and writing their value in blocks of data. 128 * @common: Pointer to the driver private structure. 129 * 130 * Return: status: 0 on success, -1 on failure. 131 */ 132static int rsi_load_ta_instructions(struct rsi_common *common) 133{ 134 struct rsi_hw *adapter = common->priv; 135 struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 136 const struct firmware *fw_entry = NULL; 137 u32 block_size = dev->tx_blk_size; 138 const u8 *fw; 139 u32 num_blocks, len; 140 int status = 0; 141 142 status = request_firmware(&fw_entry, FIRMWARE_RSI9113, adapter->device); 143 if (status < 0) { 144 rsi_dbg(ERR_ZONE, "%s Firmware file %s not found\n", 145 __func__, FIRMWARE_RSI9113); 146 return status; 147 } 148 149 /* Copy firmware into DMA-accessible memory */ 150 fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); 151 if (!fw) { 152 status = -ENOMEM; 153 goto out; 154 } 155 len = fw_entry->size; 156 157 if (len % 4) 158 len += (4 - (len % 4)); 159 160 num_blocks = (len / block_size); 161 162 rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len); 163 rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks); 164 165 status = rsi_copy_to_card(common, fw, len, num_blocks); 166 kfree(fw); 167 168out: 169 release_firmware(fw_entry); 170 return status; 171} 172 173/** 174 * rsi_device_init() - This Function Initializes The HAL. 175 * @common: Pointer to the driver private structure. 176 * 177 * Return: 0 on success, -1 on failure. 178 */ 179int rsi_usb_device_init(struct rsi_common *common) 180{ 181 if (rsi_load_ta_instructions(common)) 182 return -EIO; 183 184 return 0; 185 } 186