rsi_91x_main.c 11 KB

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