GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / net / wireless / st / cw1200 / bh.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Device handling thread implementation for mac80211 ST-Ericsson CW1200 drivers
4  *
5  * Copyright (c) 2010, ST-Ericsson
6  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7  *
8  * Based on:
9  * ST-Ericsson UMAC CW1200 driver, which is
10  * Copyright (c) 2010, ST-Ericsson
11  * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
12  */
13
14 #include <linux/module.h>
15 #include <net/mac80211.h>
16 #include <linux/kthread.h>
17 #include <linux/timer.h>
18
19 #include "cw1200.h"
20 #include "bh.h"
21 #include "hwio.h"
22 #include "wsm.h"
23 #include "hwbus.h"
24 #include "debug.h"
25 #include "fwio.h"
26
27 static int cw1200_bh(void *arg);
28
29 #define DOWNLOAD_BLOCK_SIZE_WR  (0x1000 - 4)
30 /* an SPI message cannot be bigger than (2"12-1)*2 bytes
31  * "*2" to cvt to bytes
32  */
33 #define MAX_SZ_RD_WR_BUFFERS    (DOWNLOAD_BLOCK_SIZE_WR*2)
34 #define PIGGYBACK_CTRL_REG      (2)
35 #define EFFECTIVE_BUF_SIZE      (MAX_SZ_RD_WR_BUFFERS - PIGGYBACK_CTRL_REG)
36
37 /* Suspend state privates */
38 enum cw1200_bh_pm_state {
39         CW1200_BH_RESUMED = 0,
40         CW1200_BH_SUSPEND,
41         CW1200_BH_SUSPENDED,
42         CW1200_BH_RESUME,
43 };
44
45 static void cw1200_bh_work(struct work_struct *work)
46 {
47         struct cw1200_common *priv =
48         container_of(work, struct cw1200_common, bh_work);
49         cw1200_bh(priv);
50 }
51
52 int cw1200_register_bh(struct cw1200_common *priv)
53 {
54         int err = 0;
55         /* Realtime workqueue */
56         priv->bh_workqueue = alloc_workqueue("cw1200_bh",
57                                 WQ_MEM_RECLAIM | WQ_HIGHPRI
58                                 | WQ_CPU_INTENSIVE, 1);
59
60         if (!priv->bh_workqueue)
61                 return -ENOMEM;
62
63         INIT_WORK(&priv->bh_work, cw1200_bh_work);
64
65         pr_debug("[BH] register.\n");
66
67         atomic_set(&priv->bh_rx, 0);
68         atomic_set(&priv->bh_tx, 0);
69         atomic_set(&priv->bh_term, 0);
70         atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
71         priv->bh_error = 0;
72         priv->hw_bufs_used = 0;
73         priv->buf_id_tx = 0;
74         priv->buf_id_rx = 0;
75         init_waitqueue_head(&priv->bh_wq);
76         init_waitqueue_head(&priv->bh_evt_wq);
77
78         err = !queue_work(priv->bh_workqueue, &priv->bh_work);
79         WARN_ON(err);
80         return err;
81 }
82
83 void cw1200_unregister_bh(struct cw1200_common *priv)
84 {
85         atomic_inc(&priv->bh_term);
86         wake_up(&priv->bh_wq);
87
88         destroy_workqueue(priv->bh_workqueue);
89         priv->bh_workqueue = NULL;
90
91         pr_debug("[BH] unregistered.\n");
92 }
93
94 void cw1200_irq_handler(struct cw1200_common *priv)
95 {
96         pr_debug("[BH] irq.\n");
97
98         /* Disable Interrupts! */
99         /* NOTE:  hwbus_ops->lock already held */
100         __cw1200_irq_enable(priv, 0);
101
102         if (/* WARN_ON */(priv->bh_error))
103                 return;
104
105         if (atomic_inc_return(&priv->bh_rx) == 1)
106                 wake_up(&priv->bh_wq);
107 }
108 EXPORT_SYMBOL_GPL(cw1200_irq_handler);
109
110 void cw1200_bh_wakeup(struct cw1200_common *priv)
111 {
112         pr_debug("[BH] wakeup.\n");
113         if (priv->bh_error) {
114                 pr_err("[BH] wakeup failed (BH error)\n");
115                 return;
116         }
117
118         if (atomic_inc_return(&priv->bh_tx) == 1)
119                 wake_up(&priv->bh_wq);
120 }
121
122 int cw1200_bh_suspend(struct cw1200_common *priv)
123 {
124         pr_debug("[BH] suspend.\n");
125         if (priv->bh_error) {
126                 wiphy_warn(priv->hw->wiphy, "BH error -- can't suspend\n");
127                 return -EINVAL;
128         }
129
130         atomic_set(&priv->bh_suspend, CW1200_BH_SUSPEND);
131         wake_up(&priv->bh_wq);
132         return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
133                 (CW1200_BH_SUSPENDED == atomic_read(&priv->bh_suspend)),
134                  1 * HZ) ? 0 : -ETIMEDOUT;
135 }
136
137 int cw1200_bh_resume(struct cw1200_common *priv)
138 {
139         pr_debug("[BH] resume.\n");
140         if (priv->bh_error) {
141                 wiphy_warn(priv->hw->wiphy, "BH error -- can't resume\n");
142                 return -EINVAL;
143         }
144
145         atomic_set(&priv->bh_suspend, CW1200_BH_RESUME);
146         wake_up(&priv->bh_wq);
147         return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
148                 (CW1200_BH_RESUMED == atomic_read(&priv->bh_suspend)),
149                 1 * HZ) ? 0 : -ETIMEDOUT;
150 }
151
152 static inline void wsm_alloc_tx_buffer(struct cw1200_common *priv)
153 {
154         ++priv->hw_bufs_used;
155 }
156
157 int wsm_release_tx_buffer(struct cw1200_common *priv, int count)
158 {
159         int ret = 0;
160         int hw_bufs_used = priv->hw_bufs_used;
161
162         priv->hw_bufs_used -= count;
163         if (WARN_ON(priv->hw_bufs_used < 0))
164                 ret = -1;
165         else if (hw_bufs_used >= priv->wsm_caps.input_buffers)
166                 ret = 1;
167         if (!priv->hw_bufs_used)
168                 wake_up(&priv->bh_evt_wq);
169         return ret;
170 }
171
172 static int cw1200_bh_read_ctrl_reg(struct cw1200_common *priv,
173                                           u16 *ctrl_reg)
174 {
175         int ret;
176
177         ret = cw1200_reg_read_16(priv,
178                         ST90TDS_CONTROL_REG_ID, ctrl_reg);
179         if (ret) {
180                 ret = cw1200_reg_read_16(priv,
181                                 ST90TDS_CONTROL_REG_ID, ctrl_reg);
182                 if (ret)
183                         pr_err("[BH] Failed to read control register.\n");
184         }
185
186         return ret;
187 }
188
189 static int cw1200_device_wakeup(struct cw1200_common *priv)
190 {
191         u16 ctrl_reg;
192         int ret;
193
194         pr_debug("[BH] Device wakeup.\n");
195
196         /* First, set the dpll register */
197         ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
198                                   cw1200_dpll_from_clk(priv->hw_refclk));
199         if (WARN_ON(ret))
200                 return ret;
201
202         /* To force the device to be always-on, the host sets WLAN_UP to 1 */
203         ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
204                         ST90TDS_CONT_WUP_BIT);
205         if (WARN_ON(ret))
206                 return ret;
207
208         ret = cw1200_bh_read_ctrl_reg(priv, &ctrl_reg);
209         if (WARN_ON(ret))
210                 return ret;
211
212         /* If the device returns WLAN_RDY as 1, the device is active and will
213          * remain active.
214          */
215         if (ctrl_reg & ST90TDS_CONT_RDY_BIT) {
216                 pr_debug("[BH] Device awake.\n");
217                 return 1;
218         }
219
220         return 0;
221 }
222
223 /* Must be called from BH thraed. */
224 void cw1200_enable_powersave(struct cw1200_common *priv,
225                              bool enable)
226 {
227         pr_debug("[BH] Powerave is %s.\n",
228                  enable ? "enabled" : "disabled");
229         priv->powersave_enabled = enable;
230 }
231
232 static int cw1200_bh_rx_helper(struct cw1200_common *priv,
233                                uint16_t *ctrl_reg,
234                                int *tx)
235 {
236         size_t read_len = 0;
237         struct sk_buff *skb_rx = NULL;
238         struct wsm_hdr *wsm;
239         size_t wsm_len;
240         u16 wsm_id;
241         u8 wsm_seq;
242         int rx_resync = 1;
243
244         size_t alloc_len;
245         u8 *data;
246
247         read_len = (*ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) * 2;
248         if (!read_len)
249                 return 0; /* No more work */
250
251         if (WARN_ON((read_len < sizeof(struct wsm_hdr)) ||
252                     (read_len > EFFECTIVE_BUF_SIZE))) {
253                 pr_debug("Invalid read len: %zu (%04x)",
254                          read_len, *ctrl_reg);
255                 goto err;
256         }
257
258         /* Add SIZE of PIGGYBACK reg (CONTROL Reg)
259          * to the NEXT Message length + 2 Bytes for SKB
260          */
261         read_len = read_len + 2;
262
263         alloc_len = priv->hwbus_ops->align_size(
264                 priv->hwbus_priv, read_len);
265
266         /* Check if not exceeding CW1200 capabilities */
267         if (WARN_ON_ONCE(alloc_len > EFFECTIVE_BUF_SIZE)) {
268                 pr_debug("Read aligned len: %zu\n",
269                          alloc_len);
270         }
271
272         skb_rx = dev_alloc_skb(alloc_len);
273         if (WARN_ON(!skb_rx))
274                 goto err;
275
276         skb_trim(skb_rx, 0);
277         skb_put(skb_rx, read_len);
278         data = skb_rx->data;
279         if (WARN_ON(!data))
280                 goto err;
281
282         if (WARN_ON(cw1200_data_read(priv, data, alloc_len))) {
283                 pr_err("rx blew up, len %zu\n", alloc_len);
284                 goto err;
285         }
286
287         /* Piggyback */
288         *ctrl_reg = __le16_to_cpu(
289                 ((__le16 *)data)[alloc_len / 2 - 1]);
290
291         wsm = (struct wsm_hdr *)data;
292         wsm_len = __le16_to_cpu(wsm->len);
293         if (WARN_ON(wsm_len > read_len))
294                 goto err;
295
296         if (priv->wsm_enable_wsm_dumps)
297                 print_hex_dump_bytes("<-- ",
298                                      DUMP_PREFIX_NONE,
299                                      data, wsm_len);
300
301         wsm_id  = __le16_to_cpu(wsm->id) & 0xFFF;
302         wsm_seq = (__le16_to_cpu(wsm->id) >> 13) & 7;
303
304         skb_trim(skb_rx, wsm_len);
305
306         if (wsm_id == 0x0800) {
307                 wsm_handle_exception(priv,
308                                      &data[sizeof(*wsm)],
309                                      wsm_len - sizeof(*wsm));
310                 goto err;
311         } else if (!rx_resync) {
312                 if (WARN_ON(wsm_seq != priv->wsm_rx_seq))
313                         goto err;
314         }
315         priv->wsm_rx_seq = (wsm_seq + 1) & 7;
316         rx_resync = 0;
317
318         if (wsm_id & 0x0400) {
319                 int rc = wsm_release_tx_buffer(priv, 1);
320                 if (WARN_ON(rc < 0))
321                         return rc;
322                 else if (rc > 0)
323                         *tx = 1;
324         }
325
326         /* cw1200_wsm_rx takes care on SKB livetime */
327         if (WARN_ON(wsm_handle_rx(priv, wsm_id, wsm, &skb_rx)))
328                 goto err;
329
330         dev_kfree_skb(skb_rx);
331
332         return 0;
333
334 err:
335         dev_kfree_skb(skb_rx);
336         return -1;
337 }
338
339 static int cw1200_bh_tx_helper(struct cw1200_common *priv,
340                                int *pending_tx,
341                                int *tx_burst)
342 {
343         size_t tx_len;
344         u8 *data;
345         int ret;
346         struct wsm_hdr *wsm;
347
348         if (priv->device_can_sleep) {
349                 ret = cw1200_device_wakeup(priv);
350                 if (WARN_ON(ret < 0)) { /* Error in wakeup */
351                         *pending_tx = 1;
352                         return 0;
353                 } else if (ret) { /* Woke up */
354                         priv->device_can_sleep = false;
355                 } else { /* Did not awake */
356                         *pending_tx = 1;
357                         return 0;
358                 }
359         }
360
361         wsm_alloc_tx_buffer(priv);
362         ret = wsm_get_tx(priv, &data, &tx_len, tx_burst);
363         if (ret <= 0) {
364                 wsm_release_tx_buffer(priv, 1);
365                 if (WARN_ON(ret < 0))
366                         return ret; /* Error */
367                 return 0; /* No work */
368         }
369
370         wsm = (struct wsm_hdr *)data;
371         BUG_ON(tx_len < sizeof(*wsm));
372         BUG_ON(__le16_to_cpu(wsm->len) != tx_len);
373
374         atomic_inc(&priv->bh_tx);
375
376         tx_len = priv->hwbus_ops->align_size(
377                 priv->hwbus_priv, tx_len);
378
379         /* Check if not exceeding CW1200 capabilities */
380         if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
381                 pr_debug("Write aligned len: %zu\n", tx_len);
382
383         wsm->id &= __cpu_to_le16(0xffff ^ WSM_TX_SEQ(WSM_TX_SEQ_MAX));
384         wsm->id |= __cpu_to_le16(WSM_TX_SEQ(priv->wsm_tx_seq));
385
386         if (WARN_ON(cw1200_data_write(priv, data, tx_len))) {
387                 pr_err("tx blew up, len %zu\n", tx_len);
388                 wsm_release_tx_buffer(priv, 1);
389                 return -1; /* Error */
390         }
391
392         if (priv->wsm_enable_wsm_dumps)
393                 print_hex_dump_bytes("--> ",
394                                      DUMP_PREFIX_NONE,
395                                      data,
396                                      __le16_to_cpu(wsm->len));
397
398         wsm_txed(priv, data);
399         priv->wsm_tx_seq = (priv->wsm_tx_seq + 1) & WSM_TX_SEQ_MAX;
400
401         if (*tx_burst > 1) {
402                 cw1200_debug_tx_burst(priv);
403                 return 1; /* Work remains */
404         }
405
406         return 0;
407 }
408
409 static int cw1200_bh(void *arg)
410 {
411         struct cw1200_common *priv = arg;
412         int rx, tx, term, suspend;
413         u16 ctrl_reg = 0;
414         int tx_allowed;
415         int pending_tx = 0;
416         int tx_burst;
417         long status;
418         u32 dummy;
419         int ret;
420
421         for (;;) {
422                 if (!priv->hw_bufs_used &&
423                     priv->powersave_enabled &&
424                     !priv->device_can_sleep &&
425                     !atomic_read(&priv->recent_scan)) {
426                         status = 1 * HZ;
427                         pr_debug("[BH] Device wakedown. No data.\n");
428                         cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID, 0);
429                         priv->device_can_sleep = true;
430                 } else if (priv->hw_bufs_used) {
431                         /* Interrupt loss detection */
432                         status = 1 * HZ;
433                 } else {
434                         status = MAX_SCHEDULE_TIMEOUT;
435                 }
436
437                 /* Dummy Read for SDIO retry mechanism*/
438                 if ((priv->hw_type != -1) &&
439                     (atomic_read(&priv->bh_rx) == 0) &&
440                     (atomic_read(&priv->bh_tx) == 0))
441                         cw1200_reg_read(priv, ST90TDS_CONFIG_REG_ID,
442                                         &dummy, sizeof(dummy));
443
444                 pr_debug("[BH] waiting ...\n");
445                 status = wait_event_interruptible_timeout(priv->bh_wq, ({
446                                 rx = atomic_xchg(&priv->bh_rx, 0);
447                                 tx = atomic_xchg(&priv->bh_tx, 0);
448                                 term = atomic_xchg(&priv->bh_term, 0);
449                                 suspend = pending_tx ?
450                                         0 : atomic_read(&priv->bh_suspend);
451                                 (rx || tx || term || suspend || priv->bh_error);
452                         }), status);
453
454                 pr_debug("[BH] - rx: %d, tx: %d, term: %d, bh_err: %d, suspend: %d, status: %ld\n",
455                          rx, tx, term, suspend, priv->bh_error, status);
456
457                 /* Did an error occur? */
458                 if ((status < 0 && status != -ERESTARTSYS) ||
459                     term || priv->bh_error) {
460                         break;
461                 }
462                 if (!status) {  /* wait_event timed out */
463                         unsigned long timestamp = jiffies;
464                         long timeout;
465                         int pending = 0;
466                         int i;
467
468                         /* Check to see if we have any outstanding frames */
469                         if (priv->hw_bufs_used && (!rx || !tx)) {
470                                 wiphy_warn(priv->hw->wiphy,
471                                            "Missed interrupt? (%d frames outstanding)\n",
472                                            priv->hw_bufs_used);
473                                 rx = 1;
474
475                                 /* Get a timestamp of "oldest" frame */
476                                 for (i = 0; i < 4; ++i)
477                                         pending += cw1200_queue_get_xmit_timestamp(
478                                                 &priv->tx_queue[i],
479                                                 &timestamp,
480                                                 priv->pending_frame_id);
481
482                                 /* Check if frame transmission is timed out.
483                                  * Add an extra second with respect to possible
484                                  * interrupt loss.
485                                  */
486                                 timeout = timestamp +
487                                         WSM_CMD_LAST_CHANCE_TIMEOUT +
488                                         1 * HZ  -
489                                         jiffies;
490
491                                 /* And terminate BH thread if the frame is "stuck" */
492                                 if (pending && timeout < 0) {
493                                         wiphy_warn(priv->hw->wiphy,
494                                                    "Timeout waiting for TX confirm (%d/%d pending, %ld vs %lu).\n",
495                                                    priv->hw_bufs_used, pending,
496                                                    timestamp, jiffies);
497                                         break;
498                                 }
499                         } else if (!priv->device_can_sleep &&
500                                    !atomic_read(&priv->recent_scan)) {
501                                 pr_debug("[BH] Device wakedown. Timeout.\n");
502                                 cw1200_reg_write_16(priv,
503                                                     ST90TDS_CONTROL_REG_ID, 0);
504                                 priv->device_can_sleep = true;
505                         }
506                         goto done;
507                 } else if (suspend) {
508                         pr_debug("[BH] Device suspend.\n");
509                         if (priv->powersave_enabled) {
510                                 pr_debug("[BH] Device wakedown. Suspend.\n");
511                                 cw1200_reg_write_16(priv,
512                                                     ST90TDS_CONTROL_REG_ID, 0);
513                                 priv->device_can_sleep = true;
514                         }
515
516                         atomic_set(&priv->bh_suspend, CW1200_BH_SUSPENDED);
517                         wake_up(&priv->bh_evt_wq);
518                         status = wait_event_interruptible(priv->bh_wq,
519                                                           CW1200_BH_RESUME == atomic_read(&priv->bh_suspend));
520                         if (status < 0) {
521                                 wiphy_err(priv->hw->wiphy,
522                                           "Failed to wait for resume: %ld.\n",
523                                           status);
524                                 break;
525                         }
526                         pr_debug("[BH] Device resume.\n");
527                         atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
528                         wake_up(&priv->bh_evt_wq);
529                         atomic_inc(&priv->bh_rx);
530                         goto done;
531                 }
532
533         rx:
534                 tx += pending_tx;
535                 pending_tx = 0;
536
537                 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
538                         break;
539
540                 /* Don't bother trying to rx unless we have data to read */
541                 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
542                         ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
543                         if (ret < 0)
544                                 break;
545                         /* Double up here if there's more data.. */
546                         if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
547                                 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
548                                 if (ret < 0)
549                                         break;
550                         }
551                 }
552
553         tx:
554                 if (tx) {
555                         tx = 0;
556
557                         BUG_ON(priv->hw_bufs_used > priv->wsm_caps.input_buffers);
558                         tx_burst = priv->wsm_caps.input_buffers - priv->hw_bufs_used;
559                         tx_allowed = tx_burst > 0;
560
561                         if (!tx_allowed) {
562                                 /* Buffers full.  Ensure we process tx
563                                  * after we handle rx..
564                                  */
565                                 pending_tx = tx;
566                                 goto done_rx;
567                         }
568                         ret = cw1200_bh_tx_helper(priv, &pending_tx, &tx_burst);
569                         if (ret < 0)
570                                 break;
571                         if (ret > 0) /* More to transmit */
572                                 tx = ret;
573
574                         /* Re-read ctrl reg */
575                         if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
576                                 break;
577                 }
578
579         done_rx:
580                 if (priv->bh_error)
581                         break;
582                 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK)
583                         goto rx;
584                 if (tx)
585                         goto tx;
586
587         done:
588                 /* Re-enable device interrupts */
589                 priv->hwbus_ops->lock(priv->hwbus_priv);
590                 __cw1200_irq_enable(priv, 1);
591                 priv->hwbus_ops->unlock(priv->hwbus_priv);
592         }
593
594         /* Explicitly disable device interrupts */
595         priv->hwbus_ops->lock(priv->hwbus_priv);
596         __cw1200_irq_enable(priv, 0);
597         priv->hwbus_ops->unlock(priv->hwbus_priv);
598
599         if (!term) {
600                 pr_err("[BH] Fatal error, exiting.\n");
601                 priv->bh_error = 1;
602                 /* TODO: schedule_work(recovery) */
603         }
604         return 0;
605 }