0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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 =
0029
0030
0031
0032
0033
0034
0035
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
0050
0051
0052
0053
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
0113
0114
0115
0116
0117
0118
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
0151
0152
0153
0154
0155
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
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
0248
0249
0250
0251
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
0297
0298
0299
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
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
0394
0395
0396
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
0430
0431
0432
0433
0434
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
0444
0445
0446
0447
0448
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");