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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 19 #include <linux/module.h> 20 #include <linux/firmware.h> 21 #include <net/rsi_91x.h> 22 #include "rsi_mgmt.h" 23 #include "rsi_common.h" 24 #include "rsi_coex.h" 25 #include "rsi_hal.h" 26 #include "rsi_usb.h" 27 28 u32 rsi_zone_enabled = /* INFO_ZONE | 29 INIT_ZONE | 30 MGMT_TX_ZONE | 31 MGMT_RX_ZONE | 32 DATA_TX_ZONE | 33 DATA_RX_ZONE | 34 FSM_ZONE | 35 ISR_ZONE | */ 36 ERR_ZONE | 37 0; 38 EXPORT_SYMBOL_GPL(rsi_zone_enabled); 39 40 #ifdef CONFIG_RSI_COEX 41 static struct rsi_proto_ops g_proto_ops = { 42 .coex_send_pkt = rsi_coex_send_pkt, 43 .get_host_intf = rsi_get_host_intf, 44 .set_bt_context = rsi_set_bt_context, 45 }; 46 #endif 47 48 /** 49 * rsi_dbg() - This function outputs informational messages. 50 * @zone: Zone of interest for output message. 51 * @fmt: printf-style format for output message. 52 * 53 * Return: none 54 */ 55 void rsi_dbg(u32 zone, const char *fmt, ...) 56 { 57 struct va_format vaf; 58 va_list args; 59 60 va_start(args, fmt); 61 62 vaf.fmt = fmt; 63 vaf.va = &args; 64 65 if (zone & rsi_zone_enabled) 66 pr_info("%pV", &vaf); 67 va_end(args); 68 } 69 EXPORT_SYMBOL_GPL(rsi_dbg); 70 71 static char *opmode_str(int oper_mode) 72 { 73 switch (oper_mode) { 74 case DEV_OPMODE_WIFI_ALONE: 75 return "Wi-Fi alone"; 76 case DEV_OPMODE_BT_ALONE: 77 return "BT EDR alone"; 78 case DEV_OPMODE_BT_LE_ALONE: 79 return "BT LE alone"; 80 case DEV_OPMODE_BT_DUAL: 81 return "BT Dual"; 82 case DEV_OPMODE_STA_BT: 83 return "Wi-Fi STA + BT EDR"; 84 case DEV_OPMODE_STA_BT_LE: 85 return "Wi-Fi STA + BT LE"; 86 case DEV_OPMODE_STA_BT_DUAL: 87 return "Wi-Fi STA + BT DUAL"; 88 case DEV_OPMODE_AP_BT: 89 return "Wi-Fi AP + BT EDR"; 90 case DEV_OPMODE_AP_BT_DUAL: 91 return "Wi-Fi AP + BT DUAL"; 92 } 93 94 return "Unknown"; 95 } 96 97 void rsi_print_version(struct rsi_common *common) 98 { 99 rsi_dbg(ERR_ZONE, "================================================\n"); 100 rsi_dbg(ERR_ZONE, "================ RSI Version Info ==============\n"); 101 rsi_dbg(ERR_ZONE, "================================================\n"); 102 rsi_dbg(ERR_ZONE, "FW Version\t: %d.%d.%d\n", 103 common->lmac_ver.major, common->lmac_ver.minor, 104 common->lmac_ver.release_num); 105 rsi_dbg(ERR_ZONE, "Operating mode\t: %d [%s]", 106 common->oper_mode, opmode_str(common->oper_mode)); 107 rsi_dbg(ERR_ZONE, "Firmware file\t: %s", common->priv->fw_file_name); 108 rsi_dbg(ERR_ZONE, "================================================\n"); 109 } 110 111 /** 112 * rsi_prepare_skb() - This function prepares the skb. 113 * @common: Pointer to the driver private structure. 114 * @buffer: Pointer to the packet data. 115 * @pkt_len: Length of the packet. 116 * @extended_desc: Extended descriptor. 117 * 118 * Return: Successfully skb. 119 */ 120 static struct sk_buff *rsi_prepare_skb(struct rsi_common *common, 121 u8 *buffer, 122 u32 pkt_len, 123 u8 extended_desc) 124 { 125 struct sk_buff *skb = NULL; 126 u8 payload_offset; 127 128 if (WARN(!pkt_len, "%s: Dummy pkt received", __func__)) 129 return NULL; 130 131 if (pkt_len > (RSI_RCV_BUFFER_LEN * 4)) { 132 rsi_dbg(ERR_ZONE, "%s: Pkt size > max rx buf size %d\n", 133 __func__, pkt_len); 134 pkt_len = RSI_RCV_BUFFER_LEN * 4; 135 } 136 137 pkt_len -= extended_desc; 138 skb = dev_alloc_skb(pkt_len + FRAME_DESC_SZ); 139 if (skb == NULL) 140 return NULL; 141 142 payload_offset = (extended_desc + FRAME_DESC_SZ); 143 skb_put(skb, pkt_len); 144 memcpy((skb->data), (buffer + payload_offset), skb->len); 145 146 return skb; 147 } 148 149 /** 150 * rsi_read_pkt() - This function reads frames from the card. 151 * @common: Pointer to the driver private structure. 152 * @rx_pkt: Received pkt. 153 * @rcv_pkt_len: Received pkt length. In case of USB it is 0. 154 * 155 * Return: 0 on success, -1 on failure. 156 */ 157 int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len) 158 { 159 u8 *frame_desc = NULL, extended_desc = 0; 160 u32 index, length = 0, queueno = 0; 161 u16 actual_length = 0, offset; 162 struct sk_buff *skb = NULL; 163 #ifdef CONFIG_RSI_COEX 164 u8 bt_pkt_type; 165 #endif 166 167 index = 0; 168 do { 169 frame_desc = &rx_pkt[index]; 170 actual_length = *(u16 *)&frame_desc[0]; 171 offset = *(u16 *)&frame_desc[2]; 172 if (!rcv_pkt_len && offset > 173 RSI_MAX_RX_USB_PKT_SIZE - FRAME_DESC_SZ) 174 goto fail; 175 176 queueno = rsi_get_queueno(frame_desc, offset); 177 length = rsi_get_length(frame_desc, offset); 178 179 /* Extended descriptor is valid for WLAN queues only */ 180 if (queueno == RSI_WIFI_DATA_Q || queueno == RSI_WIFI_MGMT_Q) 181 extended_desc = rsi_get_extended_desc(frame_desc, 182 offset); 183 184 switch (queueno) { 185 case RSI_COEX_Q: 186 #ifdef CONFIG_RSI_COEX 187 if (common->coex_mode > 1) 188 rsi_coex_recv_pkt(common, frame_desc + offset); 189 else 190 #endif 191 rsi_mgmt_pkt_recv(common, 192 (frame_desc + offset)); 193 break; 194 195 case RSI_WIFI_DATA_Q: 196 skb = rsi_prepare_skb(common, 197 (frame_desc + offset), 198 length, 199 extended_desc); 200 if (skb == NULL) 201 goto fail; 202 203 rsi_indicate_pkt_to_os(common, skb); 204 break; 205 206 case RSI_WIFI_MGMT_Q: 207 rsi_mgmt_pkt_recv(common, (frame_desc + offset)); 208 break; 209 210 #ifdef CONFIG_RSI_COEX 211 case RSI_BT_MGMT_Q: 212 case RSI_BT_DATA_Q: 213 #define BT_RX_PKT_TYPE_OFST 14 214 #define BT_CARD_READY_IND 0x89 215 bt_pkt_type = frame_desc[offset + BT_RX_PKT_TYPE_OFST]; 216 if (bt_pkt_type == BT_CARD_READY_IND) { 217 rsi_dbg(INFO_ZONE, "BT Card ready recvd\n"); 218 if (common->fsm_state == FSM_MAC_INIT_DONE) 219 rsi_attach_bt(common); 220 else 221 common->bt_defer_attach = true; 222 } else { 223 if (common->bt_adapter) 224 rsi_bt_ops.recv_pkt(common->bt_adapter, 225 frame_desc + offset); 226 } 227 break; 228 #endif 229 230 default: 231 rsi_dbg(ERR_ZONE, "%s: pkt from invalid queue: %d\n", 232 __func__, queueno); 233 goto fail; 234 } 235 236 index += actual_length; 237 rcv_pkt_len -= actual_length; 238 } while (rcv_pkt_len > 0); 239 240 return 0; 241 fail: 242 return -EINVAL; 243 } 244 EXPORT_SYMBOL_GPL(rsi_read_pkt); 245 246 /** 247 * rsi_tx_scheduler_thread() - This function is a kernel thread to send the 248 * packets to the device. 249 * @common: Pointer to the driver private structure. 250 * 251 * Return: None. 252 */ 253 static void rsi_tx_scheduler_thread(struct rsi_common *common) 254 { 255 struct rsi_hw *adapter = common->priv; 256 u32 timeout = EVENT_WAIT_FOREVER; 257 258 do { 259 if (adapter->determine_event_timeout) 260 timeout = adapter->determine_event_timeout(adapter); 261 rsi_wait_event(&common->tx_thread.event, timeout); 262 rsi_reset_event(&common->tx_thread.event); 263 264 if (common->init_done) 265 rsi_core_qos_processor(common); 266 } while (atomic_read(&common->tx_thread.thread_done) == 0); 267 kthread_complete_and_exit(&common->tx_thread.completion, 0); 268 } 269 270 #ifdef CONFIG_RSI_COEX 271 enum rsi_host_intf rsi_get_host_intf(void *priv) 272 { 273 struct rsi_common *common = (struct rsi_common *)priv; 274 275 return common->priv->rsi_host_intf; 276 } 277 278 void rsi_set_bt_context(void *priv, void *bt_context) 279 { 280 struct rsi_common *common = (struct rsi_common *)priv; 281 282 common->bt_adapter = bt_context; 283 } 284 #endif 285 286 void rsi_attach_bt(struct rsi_common *common) 287 { 288 #ifdef CONFIG_RSI_COEX 289 if (rsi_bt_ops.attach(common, &g_proto_ops)) 290 rsi_dbg(ERR_ZONE, 291 "Failed to attach BT module\n"); 292 #endif 293 } 294 295 /** 296 * rsi_91x_init() - This function initializes os interface operations. 297 * @oper_mode: One of DEV_OPMODE_*. 298 * 299 * Return: Pointer to the adapter structure on success, NULL on failure . 300 */ 301 struct rsi_hw *rsi_91x_init(u16 oper_mode) 302 { 303 struct rsi_hw *adapter = NULL; 304 struct rsi_common *common = NULL; 305 u8 ii = 0; 306 307 adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); 308 if (!adapter) 309 return NULL; 310 311 adapter->priv = kzalloc(sizeof(*common), GFP_KERNEL); 312 if (adapter->priv == NULL) { 313 rsi_dbg(ERR_ZONE, "%s: Failed in allocation of memory\n", 314 __func__); 315 kfree(adapter); 316 return NULL; 317 } else { 318 common = adapter->priv; 319 common->priv = adapter; 320 } 321 322 for (ii = 0; ii < NUM_SOFT_QUEUES; ii++) 323 skb_queue_head_init(&common->tx_queue[ii]); 324 325 rsi_init_event(&common->tx_thread.event); 326 mutex_init(&common->mutex); 327 mutex_init(&common->tx_lock); 328 mutex_init(&common->rx_lock); 329 mutex_init(&common->tx_bus_mutex); 330 331 if (rsi_create_kthread(common, 332 &common->tx_thread, 333 rsi_tx_scheduler_thread, 334 "Tx-Thread")) { 335 rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__); 336 goto err; 337 } 338 339 rsi_default_ps_params(adapter); 340 init_bgscan_params(common); 341 spin_lock_init(&adapter->ps_lock); 342 timer_setup(&common->roc_timer, rsi_roc_timeout, 0); 343 init_completion(&common->wlan_init_completion); 344 adapter->device_model = RSI_DEV_9113; 345 common->oper_mode = oper_mode; 346 347 /* Determine coex mode */ 348 switch (common->oper_mode) { 349 case DEV_OPMODE_STA_BT_DUAL: 350 case DEV_OPMODE_STA_BT: 351 case DEV_OPMODE_STA_BT_LE: 352 case DEV_OPMODE_BT_ALONE: 353 case DEV_OPMODE_BT_LE_ALONE: 354 case DEV_OPMODE_BT_DUAL: 355 common->coex_mode = 2; 356 break; 357 case DEV_OPMODE_AP_BT_DUAL: 358 case DEV_OPMODE_AP_BT: 359 common->coex_mode = 4; 360 break; 361 case DEV_OPMODE_WIFI_ALONE: 362 common->coex_mode = 1; 363 break; 364 default: 365 common->oper_mode = 1; 366 common->coex_mode = 1; 367 } 368 rsi_dbg(INFO_ZONE, "%s: oper_mode = %d, coex_mode = %d\n", 369 __func__, common->oper_mode, common->coex_mode); 370 371 adapter->device_model = RSI_DEV_9113; 372 #ifdef CONFIG_RSI_COEX 373 if (common->coex_mode > 1) { 374 if (rsi_coex_attach(common)) { 375 rsi_dbg(ERR_ZONE, "Failed to init coex module\n"); 376 rsi_kill_thread(&common->tx_thread); 377 goto err; 378 } 379 } 380 #endif 381 382 common->init_done = true; 383 return adapter; 384 385 err: 386 kfree(common); 387 kfree(adapter); 388 return NULL; 389 } 390 EXPORT_SYMBOL_GPL(rsi_91x_init); 391 392 /** 393 * rsi_91x_deinit() - This function de-intializes os intf operations. 394 * @adapter: Pointer to the adapter structure. 395 * 396 * Return: None. 397 */ 398 void rsi_91x_deinit(struct rsi_hw *adapter) 399 { 400 struct rsi_common *common = adapter->priv; 401 u8 ii; 402 403 rsi_dbg(INFO_ZONE, "%s: Performing deinit os ops\n", __func__); 404 405 rsi_kill_thread(&common->tx_thread); 406 407 for (ii = 0; ii < NUM_SOFT_QUEUES; ii++) 408 skb_queue_purge(&common->tx_queue[ii]); 409 410 #ifdef CONFIG_RSI_COEX 411 if (common->coex_mode > 1) { 412 if (common->bt_adapter) { 413 rsi_bt_ops.detach(common->bt_adapter); 414 common->bt_adapter = NULL; 415 } 416 rsi_coex_detach(common); 417 } 418 #endif 419 420 common->init_done = false; 421 422 kfree(common); 423 kfree(adapter->rsi_dev); 424 kfree(adapter); 425 } 426 EXPORT_SYMBOL_GPL(rsi_91x_deinit); 427 428 /** 429 * rsi_91x_hal_module_init() - This function is invoked when the module is 430 * loaded into the kernel. 431 * It registers the client driver. 432 * @void: Void. 433 * 434 * Return: 0 on success, -1 on failure. 435 */ 436 static int rsi_91x_hal_module_init(void) 437 { 438 rsi_dbg(INIT_ZONE, "%s: Module init called\n", __func__); 439 return 0; 440 } 441 442 /** 443 * rsi_91x_hal_module_exit() - This function is called at the time of 444 * removing/unloading the module. 445 * It unregisters the client driver. 446 * @void: Void. 447 * 448 * Return: None. 449 */ 450 static void rsi_91x_hal_module_exit(void) 451 { 452 rsi_dbg(INIT_ZONE, "%s: Module exit called\n", __func__); 453 } 454 455 module_init(rsi_91x_hal_module_init); 456 module_exit(rsi_91x_hal_module_exit); 457 MODULE_AUTHOR("Redpine Signals Inc"); 458 MODULE_DESCRIPTION("Station driver for RSI 91x devices"); 459 MODULE_VERSION("0.1"); 460 MODULE_LICENSE("Dual BSD/GPL"); 461