linux/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
<<
>>
Prefs
   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