bh.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Interrupt bottom half (BH).
  4. *
  5. * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
  6. * Copyright (c) 2010, ST-Ericsson
  7. */
  8. #include <linux/gpio/consumer.h>
  9. #include <net/mac80211.h>
  10. #include "bh.h"
  11. #include "wfx.h"
  12. #include "hwio.h"
  13. #include "traces.h"
  14. #include "hif_rx.h"
  15. #include "hif_api_cmd.h"
  16. static void device_wakeup(struct wfx_dev *wdev)
  17. {
  18. int max_retry = 3;
  19. if (!wdev->pdata.gpio_wakeup)
  20. return;
  21. if (gpiod_get_value_cansleep(wdev->pdata.gpio_wakeup) > 0)
  22. return;
  23. if (wfx_api_older_than(wdev, 1, 4)) {
  24. gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1);
  25. if (!completion_done(&wdev->hif.ctrl_ready))
  26. usleep_range(2000, 2500);
  27. return;
  28. }
  29. for (;;) {
  30. gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1);
  31. // completion.h does not provide any function to wait
  32. // completion without consume it (a kind of
  33. // wait_for_completion_done_timeout()). So we have to emulate
  34. // it.
  35. if (wait_for_completion_timeout(&wdev->hif.ctrl_ready,
  36. msecs_to_jiffies(2))) {
  37. complete(&wdev->hif.ctrl_ready);
  38. return;
  39. } else if (max_retry-- > 0) {
  40. // Older firmwares have a race in sleep/wake-up process.
  41. // Redo the process is sufficient to unfreeze the
  42. // chip.
  43. dev_err(wdev->dev, "timeout while wake up chip\n");
  44. gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 0);
  45. usleep_range(2000, 2500);
  46. } else {
  47. dev_err(wdev->dev, "max wake-up retries reached\n");
  48. return;
  49. }
  50. }
  51. }
  52. static void device_release(struct wfx_dev *wdev)
  53. {
  54. if (!wdev->pdata.gpio_wakeup)
  55. return;
  56. gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 0);
  57. }
  58. static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf)
  59. {
  60. struct sk_buff *skb;
  61. struct hif_msg *hif;
  62. size_t alloc_len;
  63. size_t computed_len;
  64. int release_count;
  65. int piggyback = 0;
  66. WARN(read_len > round_down(0xFFF, 2) * sizeof(u16),
  67. "%s: request exceed WFx capability", __func__);
  68. // Add 2 to take into account piggyback size
  69. alloc_len = wdev->hwbus_ops->align_size(wdev->hwbus_priv, read_len + 2);
  70. skb = dev_alloc_skb(alloc_len);
  71. if (!skb)
  72. return -ENOMEM;
  73. if (wfx_data_read(wdev, skb->data, alloc_len))
  74. goto err;
  75. piggyback = le16_to_cpup((__le16 *)(skb->data + alloc_len - 2));
  76. _trace_piggyback(piggyback, false);
  77. hif = (struct hif_msg *)skb->data;
  78. WARN(hif->encrypted & 0x3, "encryption is unsupported");
  79. if (WARN(read_len < sizeof(struct hif_msg), "corrupted read"))
  80. goto err;
  81. computed_len = le16_to_cpu(hif->len);
  82. computed_len = round_up(computed_len, 2);
  83. if (computed_len != read_len) {
  84. dev_err(wdev->dev, "inconsistent message length: %zu != %zu\n",
  85. computed_len, read_len);
  86. print_hex_dump(KERN_INFO, "hif: ", DUMP_PREFIX_OFFSET, 16, 1,
  87. hif, read_len, true);
  88. goto err;
  89. }
  90. if (!(hif->id & HIF_ID_IS_INDICATION)) {
  91. (*is_cnf)++;
  92. if (hif->id == HIF_CNF_ID_MULTI_TRANSMIT)
  93. release_count = ((struct hif_cnf_multi_transmit *)hif->body)->num_tx_confs;
  94. else
  95. release_count = 1;
  96. WARN(wdev->hif.tx_buffers_used < release_count, "corrupted buffer counter");
  97. wdev->hif.tx_buffers_used -= release_count;
  98. }
  99. _trace_hif_recv(hif, wdev->hif.tx_buffers_used);
  100. if (hif->id != HIF_IND_ID_EXCEPTION && hif->id != HIF_IND_ID_ERROR) {
  101. if (hif->seqnum != wdev->hif.rx_seqnum)
  102. dev_warn(wdev->dev, "wrong message sequence: %d != %d\n",
  103. hif->seqnum, wdev->hif.rx_seqnum);
  104. wdev->hif.rx_seqnum = (hif->seqnum + 1) % (HIF_COUNTER_MAX + 1);
  105. }
  106. skb_put(skb, le16_to_cpu(hif->len));
  107. // wfx_handle_rx takes care on SKB livetime
  108. wfx_handle_rx(wdev, skb);
  109. if (!wdev->hif.tx_buffers_used)
  110. wake_up(&wdev->hif.tx_buffers_empty);
  111. return piggyback;
  112. err:
  113. if (skb)
  114. dev_kfree_skb(skb);
  115. return -EIO;
  116. }
  117. static int bh_work_rx(struct wfx_dev *wdev, int max_msg, int *num_cnf)
  118. {
  119. size_t len;
  120. int i;
  121. int ctrl_reg, piggyback;
  122. piggyback = 0;
  123. for (i = 0; i < max_msg; i++) {
  124. if (piggyback & CTRL_NEXT_LEN_MASK)
  125. ctrl_reg = piggyback;
  126. else if (try_wait_for_completion(&wdev->hif.ctrl_ready))
  127. ctrl_reg = atomic_xchg(&wdev->hif.ctrl_reg, 0);
  128. else
  129. ctrl_reg = 0;
  130. if (!(ctrl_reg & CTRL_NEXT_LEN_MASK))
  131. return i;
  132. // ctrl_reg units are 16bits words
  133. len = (ctrl_reg & CTRL_NEXT_LEN_MASK) * 2;
  134. piggyback = rx_helper(wdev, len, num_cnf);
  135. if (piggyback < 0)
  136. return i;
  137. if (!(piggyback & CTRL_WLAN_READY))
  138. dev_err(wdev->dev, "unexpected piggyback value: ready bit not set: %04x\n",
  139. piggyback);
  140. }
  141. if (piggyback & CTRL_NEXT_LEN_MASK) {
  142. ctrl_reg = atomic_xchg(&wdev->hif.ctrl_reg, piggyback);
  143. complete(&wdev->hif.ctrl_ready);
  144. if (ctrl_reg)
  145. dev_err(wdev->dev, "unexpected IRQ happened: %04x/%04x\n",
  146. ctrl_reg, piggyback);
  147. }
  148. return i;
  149. }
  150. static void tx_helper(struct wfx_dev *wdev, struct hif_msg *hif)
  151. {
  152. int ret;
  153. void *data;
  154. bool is_encrypted = false;
  155. size_t len = le16_to_cpu(hif->len);
  156. WARN(len < sizeof(*hif), "try to send corrupted data");
  157. hif->seqnum = wdev->hif.tx_seqnum;
  158. wdev->hif.tx_seqnum = (wdev->hif.tx_seqnum + 1) % (HIF_COUNTER_MAX + 1);
  159. data = hif;
  160. WARN(len > wdev->hw_caps.size_inp_ch_buf,
  161. "%s: request exceed WFx capability: %zu > %d\n", __func__,
  162. len, wdev->hw_caps.size_inp_ch_buf);
  163. len = wdev->hwbus_ops->align_size(wdev->hwbus_priv, len);
  164. ret = wfx_data_write(wdev, data, len);
  165. if (ret)
  166. goto end;
  167. wdev->hif.tx_buffers_used++;
  168. _trace_hif_send(hif, wdev->hif.tx_buffers_used);
  169. end:
  170. if (is_encrypted)
  171. kfree(data);
  172. }
  173. static int bh_work_tx(struct wfx_dev *wdev, int max_msg)
  174. {
  175. struct hif_msg *hif;
  176. int i;
  177. for (i = 0; i < max_msg; i++) {
  178. hif = NULL;
  179. if (wdev->hif.tx_buffers_used < wdev->hw_caps.num_inp_ch_bufs) {
  180. if (try_wait_for_completion(&wdev->hif_cmd.ready)) {
  181. WARN(!mutex_is_locked(&wdev->hif_cmd.lock), "data locking error");
  182. hif = wdev->hif_cmd.buf_send;
  183. } else {
  184. hif = wfx_tx_queues_get(wdev);
  185. }
  186. }
  187. if (!hif)
  188. return i;
  189. tx_helper(wdev, hif);
  190. }
  191. return i;
  192. }
  193. /* In SDIO mode, it is necessary to make an access to a register to acknowledge
  194. * last received message. It could be possible to restrict this acknowledge to
  195. * SDIO mode and only if last operation was rx.
  196. */
  197. static void ack_sdio_data(struct wfx_dev *wdev)
  198. {
  199. u32 cfg_reg;
  200. config_reg_read(wdev, &cfg_reg);
  201. if (cfg_reg & 0xFF) {
  202. dev_warn(wdev->dev, "chip reports errors: %02x\n",
  203. cfg_reg & 0xFF);
  204. config_reg_write_bits(wdev, 0xFF, 0x00);
  205. }
  206. }
  207. static void bh_work(struct work_struct *work)
  208. {
  209. struct wfx_dev *wdev = container_of(work, struct wfx_dev, hif.bh);
  210. int stats_req = 0, stats_cnf = 0, stats_ind = 0;
  211. bool release_chip = false, last_op_is_rx = false;
  212. int num_tx, num_rx;
  213. device_wakeup(wdev);
  214. do {
  215. num_tx = bh_work_tx(wdev, 32);
  216. stats_req += num_tx;
  217. if (num_tx)
  218. last_op_is_rx = false;
  219. num_rx = bh_work_rx(wdev, 32, &stats_cnf);
  220. stats_ind += num_rx;
  221. if (num_rx)
  222. last_op_is_rx = true;
  223. } while (num_rx || num_tx);
  224. stats_ind -= stats_cnf;
  225. if (last_op_is_rx)
  226. ack_sdio_data(wdev);
  227. if (!wdev->hif.tx_buffers_used && !work_pending(work)) {
  228. device_release(wdev);
  229. release_chip = true;
  230. }
  231. _trace_bh_stats(stats_ind, stats_req, stats_cnf,
  232. wdev->hif.tx_buffers_used, release_chip);
  233. }
  234. /*
  235. * An IRQ from chip did occur
  236. */
  237. void wfx_bh_request_rx(struct wfx_dev *wdev)
  238. {
  239. u32 cur, prev;
  240. control_reg_read(wdev, &cur);
  241. prev = atomic_xchg(&wdev->hif.ctrl_reg, cur);
  242. complete(&wdev->hif.ctrl_ready);
  243. queue_work(system_highpri_wq, &wdev->hif.bh);
  244. if (!(cur & CTRL_NEXT_LEN_MASK))
  245. dev_err(wdev->dev, "unexpected control register value: length field is 0: %04x\n",
  246. cur);
  247. if (prev != 0)
  248. dev_err(wdev->dev, "received IRQ but previous data was not (yet) read: %04x/%04x\n",
  249. prev, cur);
  250. }
  251. /*
  252. * Driver want to send data
  253. */
  254. void wfx_bh_request_tx(struct wfx_dev *wdev)
  255. {
  256. queue_work(system_highpri_wq, &wdev->hif.bh);
  257. }
  258. /*
  259. * If IRQ is not available, this function allow to manually poll the control
  260. * register and simulate an IRQ ahen an event happened.
  261. *
  262. * Note that the device has a bug: If an IRQ raise while host read control
  263. * register, the IRQ is lost. So, use this function carefully (only duing
  264. * device initialisation).
  265. */
  266. void wfx_bh_poll_irq(struct wfx_dev *wdev)
  267. {
  268. ktime_t now, start;
  269. u32 reg;
  270. WARN(!wdev->poll_irq, "unexpected IRQ polling can mask IRQ");
  271. start = ktime_get();
  272. for (;;) {
  273. control_reg_read(wdev, &reg);
  274. now = ktime_get();
  275. if (reg & 0xFFF)
  276. break;
  277. if (ktime_after(now, ktime_add_ms(start, 1000))) {
  278. dev_err(wdev->dev, "time out while polling control register\n");
  279. return;
  280. }
  281. udelay(200);
  282. }
  283. wfx_bh_request_rx(wdev);
  284. }
  285. void wfx_bh_register(struct wfx_dev *wdev)
  286. {
  287. INIT_WORK(&wdev->hif.bh, bh_work);
  288. init_completion(&wdev->hif.ctrl_ready);
  289. init_waitqueue_head(&wdev->hif.tx_buffers_empty);
  290. }
  291. void wfx_bh_unregister(struct wfx_dev *wdev)
  292. {
  293. flush_work(&wdev->hif.bh);
  294. }