Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2014 Redpine Signals Inc.
0003  *
0004  * Permission to use, copy, modify, and/or distribute this software for any
0005  * purpose with or without fee is hereby granted, provided that the above
0006  * copyright notice and this permission notice appear in all copies.
0007  *
0008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0015  */
0016 
0017 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0018 
0019 #include <linux/module.h>
0020 #include <linux/firmware.h>
0021 #include <net/rsi_91x.h>
0022 #include "rsi_mgmt.h"
0023 #include "rsi_common.h"
0024 #include "rsi_coex.h"
0025 #include "rsi_hal.h"
0026 #include "rsi_usb.h"
0027 
0028 u32 rsi_zone_enabled = /* INFO_ZONE |
0029             INIT_ZONE |
0030             MGMT_TX_ZONE |
0031             MGMT_RX_ZONE |
0032             DATA_TX_ZONE |
0033             DATA_RX_ZONE |
0034             FSM_ZONE |
0035             ISR_ZONE | */
0036             ERR_ZONE |
0037             0;
0038 EXPORT_SYMBOL_GPL(rsi_zone_enabled);
0039 
0040 #ifdef CONFIG_RSI_COEX
0041 static struct rsi_proto_ops g_proto_ops = {
0042     .coex_send_pkt = rsi_coex_send_pkt,
0043     .get_host_intf = rsi_get_host_intf,
0044     .set_bt_context = rsi_set_bt_context,
0045 };
0046 #endif
0047 
0048 /**
0049  * rsi_dbg() - This function outputs informational messages.
0050  * @zone: Zone of interest for output message.
0051  * @fmt: printf-style format for output message.
0052  *
0053  * Return: none
0054  */
0055 void rsi_dbg(u32 zone, const char *fmt, ...)
0056 {
0057     struct va_format vaf;
0058     va_list args;
0059 
0060     va_start(args, fmt);
0061 
0062     vaf.fmt = fmt;
0063     vaf.va = &args;
0064 
0065     if (zone & rsi_zone_enabled)
0066         pr_info("%pV", &vaf);
0067     va_end(args);
0068 }
0069 EXPORT_SYMBOL_GPL(rsi_dbg);
0070 
0071 static char *opmode_str(int oper_mode)
0072 {
0073     switch (oper_mode) {
0074     case DEV_OPMODE_WIFI_ALONE:
0075         return "Wi-Fi alone";
0076     case DEV_OPMODE_BT_ALONE:
0077         return "BT EDR alone";
0078     case DEV_OPMODE_BT_LE_ALONE:
0079         return "BT LE alone";
0080     case DEV_OPMODE_BT_DUAL:
0081         return "BT Dual";
0082     case DEV_OPMODE_STA_BT:
0083         return "Wi-Fi STA + BT EDR";
0084     case DEV_OPMODE_STA_BT_LE:
0085         return "Wi-Fi STA + BT LE";
0086     case DEV_OPMODE_STA_BT_DUAL:
0087         return "Wi-Fi STA + BT DUAL";
0088     case DEV_OPMODE_AP_BT:
0089         return "Wi-Fi AP + BT EDR";
0090     case DEV_OPMODE_AP_BT_DUAL:
0091         return "Wi-Fi AP + BT DUAL";
0092     }
0093 
0094     return "Unknown";
0095 }
0096 
0097 void rsi_print_version(struct rsi_common *common)
0098 {
0099     rsi_dbg(ERR_ZONE, "================================================\n");
0100     rsi_dbg(ERR_ZONE, "================ RSI Version Info ==============\n");
0101     rsi_dbg(ERR_ZONE, "================================================\n");
0102     rsi_dbg(ERR_ZONE, "FW Version\t: %d.%d.%d\n",
0103         common->lmac_ver.major, common->lmac_ver.minor,
0104         common->lmac_ver.release_num);
0105     rsi_dbg(ERR_ZONE, "Operating mode\t: %d [%s]",
0106         common->oper_mode, opmode_str(common->oper_mode));
0107     rsi_dbg(ERR_ZONE, "Firmware file\t: %s", common->priv->fw_file_name);
0108     rsi_dbg(ERR_ZONE, "================================================\n");
0109 }
0110 
0111 /**
0112  * rsi_prepare_skb() - This function prepares the skb.
0113  * @common: Pointer to the driver private structure.
0114  * @buffer: Pointer to the packet data.
0115  * @pkt_len: Length of the packet.
0116  * @extended_desc: Extended descriptor.
0117  *
0118  * Return: Successfully skb.
0119  */
0120 static struct sk_buff *rsi_prepare_skb(struct rsi_common *common,
0121                        u8 *buffer,
0122                        u32 pkt_len,
0123                        u8 extended_desc)
0124 {
0125     struct sk_buff *skb = NULL;
0126     u8 payload_offset;
0127 
0128     if (WARN(!pkt_len, "%s: Dummy pkt received", __func__))
0129         return NULL;
0130 
0131     if (pkt_len > (RSI_RCV_BUFFER_LEN * 4)) {
0132         rsi_dbg(ERR_ZONE, "%s: Pkt size > max rx buf size %d\n",
0133             __func__, pkt_len);
0134         pkt_len = RSI_RCV_BUFFER_LEN * 4;
0135     }
0136 
0137     pkt_len -= extended_desc;
0138     skb = dev_alloc_skb(pkt_len + FRAME_DESC_SZ);
0139     if (skb == NULL)
0140         return NULL;
0141 
0142     payload_offset = (extended_desc + FRAME_DESC_SZ);
0143     skb_put(skb, pkt_len);
0144     memcpy((skb->data), (buffer + payload_offset), skb->len);
0145 
0146     return skb;
0147 }
0148 
0149 /**
0150  * rsi_read_pkt() - This function reads frames from the card.
0151  * @common: Pointer to the driver private structure.
0152  * @rx_pkt: Received pkt.
0153  * @rcv_pkt_len: Received pkt length. In case of USB it is 0.
0154  *
0155  * Return: 0 on success, -1 on failure.
0156  */
0157 int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
0158 {
0159     u8 *frame_desc = NULL, extended_desc = 0;
0160     u32 index, length = 0, queueno = 0;
0161     u16 actual_length = 0, offset;
0162     struct sk_buff *skb = NULL;
0163 #ifdef CONFIG_RSI_COEX
0164     u8 bt_pkt_type;
0165 #endif
0166 
0167     index = 0;
0168     do {
0169         frame_desc = &rx_pkt[index];
0170         actual_length = *(u16 *)&frame_desc[0];
0171         offset = *(u16 *)&frame_desc[2];
0172         if (!rcv_pkt_len && offset >
0173             RSI_MAX_RX_USB_PKT_SIZE - FRAME_DESC_SZ)
0174             goto fail;
0175 
0176         queueno = rsi_get_queueno(frame_desc, offset);
0177         length = rsi_get_length(frame_desc, offset);
0178 
0179         /* Extended descriptor is valid for WLAN queues only */
0180         if (queueno == RSI_WIFI_DATA_Q || queueno == RSI_WIFI_MGMT_Q)
0181             extended_desc = rsi_get_extended_desc(frame_desc,
0182                                   offset);
0183 
0184         switch (queueno) {
0185         case RSI_COEX_Q:
0186 #ifdef CONFIG_RSI_COEX
0187             if (common->coex_mode > 1)
0188                 rsi_coex_recv_pkt(common, frame_desc + offset);
0189             else
0190 #endif
0191                 rsi_mgmt_pkt_recv(common,
0192                           (frame_desc + offset));
0193             break;
0194 
0195         case RSI_WIFI_DATA_Q:
0196             skb = rsi_prepare_skb(common,
0197                           (frame_desc + offset),
0198                           length,
0199                           extended_desc);
0200             if (skb == NULL)
0201                 goto fail;
0202 
0203             rsi_indicate_pkt_to_os(common, skb);
0204             break;
0205 
0206         case RSI_WIFI_MGMT_Q:
0207             rsi_mgmt_pkt_recv(common, (frame_desc + offset));
0208             break;
0209 
0210 #ifdef CONFIG_RSI_COEX
0211         case RSI_BT_MGMT_Q:
0212         case RSI_BT_DATA_Q:
0213 #define BT_RX_PKT_TYPE_OFST 14
0214 #define BT_CARD_READY_IND   0x89
0215             bt_pkt_type = frame_desc[offset + BT_RX_PKT_TYPE_OFST];
0216             if (bt_pkt_type == BT_CARD_READY_IND) {
0217                 rsi_dbg(INFO_ZONE, "BT Card ready recvd\n");
0218                 if (common->fsm_state == FSM_MAC_INIT_DONE)
0219                     rsi_attach_bt(common);
0220                 else
0221                     common->bt_defer_attach = true;
0222             } else {
0223                 if (common->bt_adapter)
0224                     rsi_bt_ops.recv_pkt(common->bt_adapter,
0225                             frame_desc + offset);
0226             }
0227             break;
0228 #endif
0229 
0230         default:
0231             rsi_dbg(ERR_ZONE, "%s: pkt from invalid queue: %d\n",
0232                 __func__,   queueno);
0233             goto fail;
0234         }
0235 
0236         index  += actual_length;
0237         rcv_pkt_len -= actual_length;
0238     } while (rcv_pkt_len > 0);
0239 
0240     return 0;
0241 fail:
0242     return -EINVAL;
0243 }
0244 EXPORT_SYMBOL_GPL(rsi_read_pkt);
0245 
0246 /**
0247  * rsi_tx_scheduler_thread() - This function is a kernel thread to send the
0248  *                 packets to the device.
0249  * @common: Pointer to the driver private structure.
0250  *
0251  * Return: None.
0252  */
0253 static void rsi_tx_scheduler_thread(struct rsi_common *common)
0254 {
0255     struct rsi_hw *adapter = common->priv;
0256     u32 timeout = EVENT_WAIT_FOREVER;
0257 
0258     do {
0259         if (adapter->determine_event_timeout)
0260             timeout = adapter->determine_event_timeout(adapter);
0261         rsi_wait_event(&common->tx_thread.event, timeout);
0262         rsi_reset_event(&common->tx_thread.event);
0263 
0264         if (common->init_done)
0265             rsi_core_qos_processor(common);
0266     } while (atomic_read(&common->tx_thread.thread_done) == 0);
0267     kthread_complete_and_exit(&common->tx_thread.completion, 0);
0268 }
0269 
0270 #ifdef CONFIG_RSI_COEX
0271 enum rsi_host_intf rsi_get_host_intf(void *priv)
0272 {
0273     struct rsi_common *common = (struct rsi_common *)priv;
0274 
0275     return common->priv->rsi_host_intf;
0276 }
0277 
0278 void rsi_set_bt_context(void *priv, void *bt_context)
0279 {
0280     struct rsi_common *common = (struct rsi_common *)priv;
0281 
0282     common->bt_adapter = bt_context;
0283 }
0284 #endif
0285 
0286 void rsi_attach_bt(struct rsi_common *common)
0287 {
0288 #ifdef CONFIG_RSI_COEX
0289     if (rsi_bt_ops.attach(common, &g_proto_ops))
0290         rsi_dbg(ERR_ZONE,
0291             "Failed to attach BT module\n");
0292 #endif
0293 }
0294 
0295 /**
0296  * rsi_91x_init() - This function initializes os interface operations.
0297  * @oper_mode: One of DEV_OPMODE_*.
0298  *
0299  * Return: Pointer to the adapter structure on success, NULL on failure .
0300  */
0301 struct rsi_hw *rsi_91x_init(u16 oper_mode)
0302 {
0303     struct rsi_hw *adapter = NULL;
0304     struct rsi_common *common = NULL;
0305     u8 ii = 0;
0306 
0307     adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
0308     if (!adapter)
0309         return NULL;
0310 
0311     adapter->priv = kzalloc(sizeof(*common), GFP_KERNEL);
0312     if (adapter->priv == NULL) {
0313         rsi_dbg(ERR_ZONE, "%s: Failed in allocation of memory\n",
0314             __func__);
0315         kfree(adapter);
0316         return NULL;
0317     } else {
0318         common = adapter->priv;
0319         common->priv = adapter;
0320     }
0321 
0322     for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
0323         skb_queue_head_init(&common->tx_queue[ii]);
0324 
0325     rsi_init_event(&common->tx_thread.event);
0326     mutex_init(&common->mutex);
0327     mutex_init(&common->tx_lock);
0328     mutex_init(&common->rx_lock);
0329     mutex_init(&common->tx_bus_mutex);
0330 
0331     if (rsi_create_kthread(common,
0332                    &common->tx_thread,
0333                    rsi_tx_scheduler_thread,
0334                    "Tx-Thread")) {
0335         rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
0336         goto err;
0337     }
0338 
0339     rsi_default_ps_params(adapter);
0340     init_bgscan_params(common);
0341     spin_lock_init(&adapter->ps_lock);
0342     timer_setup(&common->roc_timer, rsi_roc_timeout, 0);
0343     init_completion(&common->wlan_init_completion);
0344     adapter->device_model = RSI_DEV_9113;
0345     common->oper_mode = oper_mode;
0346 
0347     /* Determine coex mode */
0348     switch (common->oper_mode) {
0349     case DEV_OPMODE_STA_BT_DUAL:
0350     case DEV_OPMODE_STA_BT:
0351     case DEV_OPMODE_STA_BT_LE:
0352     case DEV_OPMODE_BT_ALONE:
0353     case DEV_OPMODE_BT_LE_ALONE:
0354     case DEV_OPMODE_BT_DUAL:
0355         common->coex_mode = 2;
0356         break;
0357     case DEV_OPMODE_AP_BT_DUAL:
0358     case DEV_OPMODE_AP_BT:
0359         common->coex_mode = 4;
0360         break;
0361     case DEV_OPMODE_WIFI_ALONE:
0362         common->coex_mode = 1;
0363         break;
0364     default:
0365         common->oper_mode = 1;
0366         common->coex_mode = 1;
0367     }
0368     rsi_dbg(INFO_ZONE, "%s: oper_mode = %d, coex_mode = %d\n",
0369         __func__, common->oper_mode, common->coex_mode);
0370 
0371     adapter->device_model = RSI_DEV_9113;
0372 #ifdef CONFIG_RSI_COEX
0373     if (common->coex_mode > 1) {
0374         if (rsi_coex_attach(common)) {
0375             rsi_dbg(ERR_ZONE, "Failed to init coex module\n");
0376             rsi_kill_thread(&common->tx_thread);
0377             goto err;
0378         }
0379     }
0380 #endif
0381 
0382     common->init_done = true;
0383     return adapter;
0384 
0385 err:
0386     kfree(common);
0387     kfree(adapter);
0388     return NULL;
0389 }
0390 EXPORT_SYMBOL_GPL(rsi_91x_init);
0391 
0392 /**
0393  * rsi_91x_deinit() - This function de-intializes os intf operations.
0394  * @adapter: Pointer to the adapter structure.
0395  *
0396  * Return: None.
0397  */
0398 void rsi_91x_deinit(struct rsi_hw *adapter)
0399 {
0400     struct rsi_common *common = adapter->priv;
0401     u8 ii;
0402 
0403     rsi_dbg(INFO_ZONE, "%s: Performing deinit os ops\n", __func__);
0404 
0405     rsi_kill_thread(&common->tx_thread);
0406 
0407     for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
0408         skb_queue_purge(&common->tx_queue[ii]);
0409 
0410 #ifdef CONFIG_RSI_COEX
0411     if (common->coex_mode > 1) {
0412         if (common->bt_adapter) {
0413             rsi_bt_ops.detach(common->bt_adapter);
0414             common->bt_adapter = NULL;
0415         }
0416         rsi_coex_detach(common);
0417     }
0418 #endif
0419 
0420     common->init_done = false;
0421 
0422     kfree(common);
0423     kfree(adapter->rsi_dev);
0424     kfree(adapter);
0425 }
0426 EXPORT_SYMBOL_GPL(rsi_91x_deinit);
0427 
0428 /**
0429  * rsi_91x_hal_module_init() - This function is invoked when the module is
0430  *                 loaded into the kernel.
0431  *                 It registers the client driver.
0432  * @void: Void.
0433  *
0434  * Return: 0 on success, -1 on failure.
0435  */
0436 static int rsi_91x_hal_module_init(void)
0437 {
0438     rsi_dbg(INIT_ZONE, "%s: Module init called\n", __func__);
0439     return 0;
0440 }
0441 
0442 /**
0443  * rsi_91x_hal_module_exit() - This function is called at the time of
0444  *                 removing/unloading the module.
0445  *                 It unregisters the client driver.
0446  * @void: Void.
0447  *
0448  * Return: None.
0449  */
0450 static void rsi_91x_hal_module_exit(void)
0451 {
0452     rsi_dbg(INIT_ZONE, "%s: Module exit called\n", __func__);
0453 }
0454 
0455 module_init(rsi_91x_hal_module_init);
0456 module_exit(rsi_91x_hal_module_exit);
0457 MODULE_AUTHOR("Redpine Signals Inc");
0458 MODULE_DESCRIPTION("Station driver for RSI 91x devices");
0459 MODULE_VERSION("0.1");
0460 MODULE_LICENSE("Dual BSD/GPL");