1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2017-2026 Morse Micro
4 */
5 #include <linux/gpio.h>
6 #include <linux/random.h>
7 #include <linux/timer.h>
8 #include <linux/bitops.h>
9 #include <linux/slab.h>
10 #include "hif.h"
11 #include "ps.h"
12 #include "bus.h"
13 #include "command.h"
14 #include "skbq.h"
15
16 /* This is a fail safe timeout */
17 #define CHIP_FULL_RECOVERY_TIMEOUT_MS 30
18
19 /* Defined as the max number of MPDUs per AMPDU */
20 #define MAX_PKTS_PER_TX_TXN 16
21 #define MAX_PKTS_PER_RX_TXN 32
22
mm81x_yaps_alloc_pkt_buffers(struct mm81x_yaps * yaps)23 static int mm81x_yaps_alloc_pkt_buffers(struct mm81x_yaps *yaps)
24 {
25 yaps->hw.to_chip_pkts = kcalloc(MAX_PKTS_PER_TX_TXN,
26 sizeof(*yaps->hw.to_chip_pkts),
27 GFP_KERNEL);
28 if (!yaps->hw.to_chip_pkts)
29 return -ENOMEM;
30
31 yaps->hw.from_chip_pkts = kcalloc(MAX_PKTS_PER_RX_TXN,
32 sizeof(*yaps->hw.from_chip_pkts),
33 GFP_KERNEL);
34 if (!yaps->hw.from_chip_pkts) {
35 kfree(yaps->hw.to_chip_pkts);
36 yaps->hw.to_chip_pkts = NULL;
37 return -ENOMEM;
38 }
39
40 return 0;
41 }
42
mm81x_yaps_free_pkt_buffers(struct mm81x_yaps * yaps)43 static void mm81x_yaps_free_pkt_buffers(struct mm81x_yaps *yaps)
44 {
45 kfree(yaps->hw.from_chip_pkts);
46 yaps->hw.from_chip_pkts = NULL;
47 kfree(yaps->hw.to_chip_pkts);
48 yaps->hw.to_chip_pkts = NULL;
49 }
50
mm81x_yaps_write_pkts(struct mm81x_yaps * yaps,struct mm81x_yaps_pkt * pkts,int num_pkts,int * num_pkts_sent)51 static int mm81x_yaps_write_pkts(struct mm81x_yaps *yaps,
52 struct mm81x_yaps_pkt *pkts, int num_pkts,
53 int *num_pkts_sent)
54 {
55 return yaps->ops->write_pkts(yaps, pkts, num_pkts, num_pkts_sent);
56 }
57
mm81x_yaps_read_pkts(struct mm81x_yaps * yaps,struct mm81x_yaps_pkt * pkts,int num_pkts_max,int * num_pkts_received)58 static int mm81x_yaps_read_pkts(struct mm81x_yaps *yaps,
59 struct mm81x_yaps_pkt *pkts, int num_pkts_max,
60 int *num_pkts_received)
61 {
62 return yaps->ops->read_pkts(yaps, pkts, num_pkts_max,
63 num_pkts_received);
64 }
65
mm81x_yaps_update_status(struct mm81x_yaps * yaps)66 static int mm81x_yaps_update_status(struct mm81x_yaps *yaps)
67 {
68 return yaps->ops->update_status(yaps);
69 }
70
71 /* Mappings between sk_buff, skbq and yaps */
mm81x_yaps_tc_q_from_aci(struct mm81x * mors,int aci)72 static struct mm81x_skbq *mm81x_yaps_tc_q_from_aci(struct mm81x *mors, int aci)
73 {
74 struct mm81x_yaps *yaps = &mors->hif.u.yaps;
75
76 if (aci >= ARRAY_SIZE(yaps->data_tx_qs))
77 return NULL;
78 return &yaps->data_tx_qs[aci];
79 }
80
mm81x_yaps_get_tx_qs(struct mm81x * mors,struct mm81x_skbq ** qs,int * num_qs)81 static void mm81x_yaps_get_tx_qs(struct mm81x *mors, struct mm81x_skbq **qs,
82 int *num_qs)
83 {
84 *qs = mors->hif.u.yaps.data_tx_qs;
85 *num_qs = YAPS_TX_SKBQ_MAX;
86 }
87
mm81x_yaps_get_bcn_tc_q(struct mm81x * mors)88 static struct mm81x_skbq *mm81x_yaps_get_bcn_tc_q(struct mm81x *mors)
89 {
90 return &mors->hif.u.yaps.beacon_q;
91 }
92
mm81x_yaps_get_mgmt_tc_q(struct mm81x * mors)93 static struct mm81x_skbq *mm81x_yaps_get_mgmt_tc_q(struct mm81x *mors)
94 {
95 return &mors->hif.u.yaps.mgmt_q;
96 }
97
mm81x_yaps_get_tx_cmd_queue(struct mm81x * mors)98 static struct mm81x_skbq *mm81x_yaps_get_tx_cmd_queue(struct mm81x *mors)
99 {
100 return &mors->hif.u.yaps.cmd_q;
101 }
102
mm81x_yaps_irq_handler(struct mm81x * mors,u32 status)103 static int mm81x_yaps_irq_handler(struct mm81x *mors, u32 status)
104 {
105 if (status & BIT(MM81X_INT_YAPS_FC_PKT_WAITING_IRQN))
106 set_bit(MM81X_HIF_EVT_RX_PEND, &mors->hif.event_flags);
107
108 if (status & BIT(MM81X_INT_YAPS_FC_PACKET_FREED_UP_IRQN)) {
109 timer_delete_sync_try(&mors->hif.u.yaps.chip_queue_full.timer);
110 set_bit(MM81X_HIF_EVT_TX_PACKET_FREED_UP_PEND,
111 &mors->hif.event_flags);
112 }
113
114 queue_work(mors->chip_wq, &mors->hif_work);
115 return 0;
116 }
117
118 const struct mm81x_hif_ops mm81x_yaps_ops = {
119 .init = mm81x_yaps_init,
120 .flush_tx_data = mm81x_yaps_flush_tx_data,
121 .flush_cmds = mm81x_yaps_flush_cmds,
122 .get_tx_status_pending_count = mm81x_yaps_get_tx_status_pending_count,
123 .get_tx_buffered_count = mm81x_yaps_get_tx_buffered_count,
124 .finish = mm81x_yaps_finish,
125 .skbq_get_tx_qs = mm81x_yaps_get_tx_qs,
126 .get_tx_beacon_queue = mm81x_yaps_get_bcn_tc_q,
127 .get_tx_mgmt_queue = mm81x_yaps_get_mgmt_tc_q,
128 .get_tx_cmd_queue = mm81x_yaps_get_tx_cmd_queue,
129 .get_tx_data_queue = mm81x_yaps_tc_q_from_aci,
130 .handle_irq = mm81x_yaps_irq_handler
131 };
132
mm81x_yaps_read_pkt(struct mm81x_yaps * yaps,struct sk_buff * skb)133 static int mm81x_yaps_read_pkt(struct mm81x_yaps *yaps, struct sk_buff *skb)
134 {
135 struct mm81x *mors = yaps->mors;
136 struct sk_buff_head skbq;
137 struct mm81x_skbq *mq = NULL;
138 struct mm81x_skb_hdr *hdr;
139 int skb_bytes_remaining;
140 int skb_len;
141 int ret = 0;
142
143 if (!skb) {
144 ret = -EINVAL;
145 goto exit_return_page;
146 }
147
148 __skb_queue_head_init(&skbq);
149
150 hdr = (struct mm81x_skb_hdr *)skb->data;
151 if (hdr->sync != MM81X_SKB_HEADER_SYNC) {
152 dev_err(mors->dev, "sync value error [0xAA:%d], hdr.len %d",
153 hdr->sync, hdr->len);
154 ret = -EIO;
155 goto exit_return_page;
156 }
157
158 if (yaps->mors->hif.validate_skb_checksum &&
159 !mm81x_skbq_validate_checksum(skb->data)) {
160 dev_dbg(yaps->mors->dev,
161 "SKB checksum is invalid hdr:[c:%02X s:%02X len:%d]",
162 hdr->channel, hdr->sync, hdr->len);
163
164 if (hdr->channel != MM81X_SKB_CHAN_TX_STATUS) {
165 ret = -EIO;
166 goto exit;
167 }
168 }
169
170 switch (hdr->channel) {
171 case MM81X_SKB_CHAN_DATA:
172 case MM81X_SKB_CHAN_NDP_FRAMES:
173 case MM81X_SKB_CHAN_TX_STATUS:
174 case MM81X_SKB_CHAN_DATA_NOACK:
175 case MM81X_SKB_CHAN_BEACON:
176 case MM81X_SKB_CHAN_MGMT:
177 mq = &yaps->data_rx_q;
178 break;
179 case MM81X_SKB_CHAN_COMMAND:
180 mq = &yaps->cmd_resp_q;
181 break;
182 default:
183 dev_err(mors->dev, "channel value error [%d]", hdr->channel);
184 ret = -EIO;
185 goto exit_return_page;
186 }
187
188 skb_len = sizeof(*hdr) + hdr->offset + le16_to_cpu(hdr->len);
189 skb_bytes_remaining = mm81x_skbq_space(mq);
190
191 if (skb_len > skb_bytes_remaining) {
192 dev_err(mors->dev,
193 "Page will not fit in SKBQ, dropping - len %d remain %d",
194 skb_len, skb_bytes_remaining);
195 ret = -ENOMEM;
196 /* Queue work to clear backlog */
197 queue_work(mors->net_wq, &mq->dispatch_work);
198 goto exit_return_page;
199 }
200
201 skb_trim(skb, skb_len);
202 __skb_queue_tail(&skbq, skb);
203
204 if (skb_queue_len(&skbq))
205 mm81x_skbq_enq(mq, &skbq);
206
207 /* push packets up in a different context */
208 queue_work(mors->net_wq, &mq->dispatch_work);
209
210 goto exit;
211
212 exit_return_page:
213 if (ret && mq) {
214 dev_err(mors->dev, "failed %d", ret);
215 mm81x_skbq_purge(mq, &skbq);
216 goto exit;
217 }
218
219 exit:
220 if (ret && skb)
221 dev_kfree_skb(skb);
222
223 return ret;
224 }
225
mm81x_yaps_tx(struct mm81x_yaps * yaps,struct mm81x_skbq * mq)226 static int mm81x_yaps_tx(struct mm81x_yaps *yaps, struct mm81x_skbq *mq)
227 {
228 int i;
229 int ret = 0;
230 int num_skbs = 0;
231 int tc_pkt_idx = 0;
232 int num_pkts_sent = 0;
233 struct sk_buff *skb;
234 struct sk_buff_head skbq_to_send;
235 struct sk_buff_head skbq_sent;
236 struct sk_buff_head skbq_failed;
237 struct sk_buff *pfirst, *pnext;
238 struct mm81x *mors = yaps->mors;
239 struct mm81x_skb_hdr *hdr;
240
241 /* Check there is something on the queue */
242 spin_lock_bh(&mq->lock);
243 skb = skb_peek(&mq->skbq);
244 spin_unlock_bh(&mq->lock);
245 if (!skb)
246 return 0;
247
248 __skb_queue_head_init(&skbq_to_send);
249 __skb_queue_head_init(&skbq_sent);
250 __skb_queue_head_init(&skbq_failed);
251
252 if (mq == &yaps->cmd_q)
253 /* Purge timed-out commands (this should not happen) */
254 mm81x_skbq_purge(mq, &mq->pending);
255 else if (mq == &yaps->mgmt_q && skb_queue_len(&mq->skbq) > 0)
256 /*
257 * Purge old mgmt frames that have not been sent due to
258 * congestion
259 */
260 mm81x_skbq_purge_aged(mors, mq);
261
262 num_skbs =
263 mm81x_skbq_deq_num_skb(mq, &skbq_to_send, MAX_PKTS_PER_TX_TXN);
264
265 skb_queue_walk_safe(&skbq_to_send, pfirst, pnext) {
266 enum mm81x_yaps_to_chip_q tc_queue;
267
268 hdr = (struct mm81x_skb_hdr *)pfirst->data;
269 switch (hdr->channel) {
270 case MM81X_SKB_CHAN_COMMAND:
271 tc_queue = MM81X_YAPS_CMD_Q;
272 break;
273 case MM81X_SKB_CHAN_BEACON:
274 tc_queue = MM81X_YAPS_BEACON_Q;
275 break;
276 case MM81X_SKB_CHAN_MGMT:
277 tc_queue = MM81X_YAPS_MGMT_Q;
278 break;
279 default:
280 tc_queue = MM81X_YAPS_TX_Q;
281 break;
282 }
283 yaps->hw.to_chip_pkts[tc_pkt_idx].tc_queue = tc_queue;
284 yaps->hw.to_chip_pkts[tc_pkt_idx].skb = pfirst;
285 tc_pkt_idx++;
286 }
287
288 /* Send queued packets to chip */
289 ret = mm81x_yaps_update_status(yaps);
290 if (ret)
291 return ret;
292
293 ret = mm81x_yaps_write_pkts(yaps, yaps->hw.to_chip_pkts, tc_pkt_idx,
294 &num_pkts_sent);
295
296 /* Move sent packets to done queue */
297 for (i = 0; i < num_pkts_sent; ++i) {
298 pfirst = __skb_dequeue(&skbq_to_send);
299 __skb_queue_tail(&skbq_sent, pfirst);
300 }
301
302 for (i = num_pkts_sent; i < num_skbs; ++i) {
303 pfirst = __skb_dequeue(&skbq_to_send);
304 __skb_queue_tail(&skbq_failed, pfirst);
305 }
306
307 if (skb_queue_len(&skbq_failed) > 0) {
308 mm81x_skbq_enq_prepend(mq, &skbq_failed);
309
310 /* queue full, can't requeue */
311 if (skb_queue_len(&skbq_failed) > 0) {
312 dev_warn(mors->dev,
313 "can't requeue failed pkts, purging");
314 __skb_queue_purge(&skbq_failed);
315 }
316 }
317
318 if (skb_queue_len(&skbq_sent) > 0)
319 mm81x_skbq_tx_complete(mq, &skbq_sent);
320
321 return ret;
322 }
323
324 /* Returns true if there are TX data pages waiting to be sent */
mm81x_yaps_tx_data_handler(struct mm81x_yaps * yaps)325 static bool mm81x_yaps_tx_data_handler(struct mm81x_yaps *yaps)
326 {
327 s16 aci;
328 u32 count = 0;
329 struct mm81x *mors = yaps->mors;
330
331 for (aci = MM81X_ACI_VO; aci >= 0; aci--) {
332 struct mm81x_skbq *data_q = mm81x_yaps_tc_q_from_aci(mors, aci);
333
334 if (!mm81x_is_data_tx_allowed(mors))
335 break;
336
337 yaps->chip_queue_full.is_full = mm81x_yaps_tx(yaps, data_q);
338 count += mm81x_skbq_count(data_q);
339
340 if (yaps->chip_queue_full.is_full)
341 break;
342
343 if (aci == MM81X_ACI_BE)
344 break;
345 }
346
347 /*
348 * Data has potentially been transmitted from the data SKBQs.
349 * If the mac80211 TX data Qs were previously stopped, now would
350 * be a good time to check if they can be started again.
351 */
352 mm81x_skbq_may_wake_tx_queues(mors);
353
354 return (count > 0) && mm81x_is_data_tx_allowed(mors);
355 }
356
357 /* Returns true if there are commands waiting to be sent */
mm81x_yaps_tx_cmd_handler(struct mm81x_yaps * yaps)358 static bool mm81x_yaps_tx_cmd_handler(struct mm81x_yaps *yaps)
359 {
360 struct mm81x_skbq *cmd_q = &yaps->cmd_q;
361
362 mm81x_yaps_tx(yaps, cmd_q);
363
364 return mm81x_skbq_count(cmd_q) > 0;
365 }
366
mm81x_yaps_tx_beacon_handler(struct mm81x_yaps * yaps)367 static bool mm81x_yaps_tx_beacon_handler(struct mm81x_yaps *yaps)
368 {
369 struct mm81x_skbq *beacon_q = &yaps->beacon_q;
370
371 mm81x_yaps_tx(yaps, beacon_q);
372
373 return mm81x_skbq_count(beacon_q) > 0;
374 }
375
mm81x_yaps_tx_mgmt_handler(struct mm81x_yaps * yaps)376 static bool mm81x_yaps_tx_mgmt_handler(struct mm81x_yaps *yaps)
377 {
378 struct mm81x_skbq *mgmt_q = &yaps->mgmt_q;
379
380 mm81x_yaps_tx(yaps, mgmt_q);
381
382 return mm81x_skbq_count(mgmt_q) > 0;
383 }
384
385 /* Returns true if there are populated RX pages left in the device */
mm81x_yaps_rx_handler(struct mm81x_yaps * yaps)386 static bool mm81x_yaps_rx_handler(struct mm81x_yaps *yaps)
387 {
388 int ret = 0;
389 int i;
390 int num_pks_received;
391
392 ret = mm81x_yaps_update_status(yaps);
393 if (ret)
394 goto exit;
395
396 ret = mm81x_yaps_read_pkts(yaps, yaps->hw.from_chip_pkts,
397 MAX_PKTS_PER_RX_TXN, &num_pks_received);
398 if (ret && ret != -EAGAIN) {
399 dev_err(yaps->mors->dev, "YAPS read_pkts fail: %d", ret);
400 goto exit;
401 }
402
403 for (i = 0; i < num_pks_received; ++i) {
404 mm81x_yaps_read_pkt(yaps, yaps->hw.from_chip_pkts[i].skb);
405 yaps->hw.from_chip_pkts[i].skb = NULL;
406 }
407
408 exit:
409 if (ret == -ENOMEM || ret == -EAGAIN)
410 return true;
411 else
412 return false;
413 }
414
mm81x_yaps_stale_tx_work(struct work_struct * work)415 void mm81x_yaps_stale_tx_work(struct work_struct *work)
416 {
417 int i;
418 int flushed = 0;
419 struct mm81x *mors = container_of(work, struct mm81x, tx_stale_work);
420 struct mm81x_yaps *yaps;
421
422 yaps = &mors->hif.u.yaps;
423 flushed += mm81x_skbq_check_for_stale_tx(mors, &yaps->beacon_q);
424 flushed += mm81x_skbq_check_for_stale_tx(mors, &yaps->mgmt_q);
425
426 for (i = 0; i < ARRAY_SIZE(yaps->data_tx_qs); i++)
427 flushed += mm81x_skbq_check_for_stale_tx(mors,
428 &yaps->data_tx_qs[i]);
429
430 if (!flushed)
431 return;
432
433 dev_dbg(mors->dev, "Flushed %d stale TX SKBs", flushed);
434
435 if (mors->ps.enable && !mors->ps.suspended &&
436 (mm81x_yaps_get_tx_buffered_count(mors) == 0)) {
437 /* Evaluate ps to check if it was gated on a stale tx status */
438 queue_delayed_work(mors->chip_wq, &mors->ps.delayed_eval_work,
439 0);
440 }
441 }
442
mm81x_yaps_work(struct work_struct * work)443 void mm81x_yaps_work(struct work_struct *work)
444 {
445 struct mm81x *mors = container_of(work, struct mm81x, hif_work);
446 unsigned long *flags = &mors->hif.event_flags;
447 struct mm81x_yaps *yaps = &mors->hif.u.yaps;
448
449 if (test_bit(MM81X_STATE_CHIP_UNRESPONSIVE, &mors->state_flags))
450 return;
451
452 if (!*flags)
453 return;
454
455 /* Disable power save in case it is running */
456 mm81x_ps_disable(mors);
457 mm81x_claim_bus(mors);
458
459 /*
460 * Handle any populated RX pages from chip first to
461 * avoid dropping pkts due to full on-chip buffers.
462 * Check if all pages were removed, set event flags if not.
463 */
464 if (test_and_clear_bit(MM81X_HIF_EVT_RX_PEND, flags)) {
465 if (mm81x_yaps_rx_handler(yaps))
466 set_bit(MM81X_HIF_EVT_RX_PEND, flags);
467 }
468
469 /* TX any commands before considering data */
470 if (test_and_clear_bit(MM81X_HIF_EVT_TX_COMMAND_PEND, flags)) {
471 if (mm81x_yaps_tx_cmd_handler(yaps))
472 set_bit(MM81X_HIF_EVT_TX_COMMAND_PEND, flags);
473 }
474
475 /* TX beacons before considering mgmt/data */
476 if (test_and_clear_bit(MM81X_HIF_EVT_TX_BEACON_PEND, flags)) {
477 if (mm81x_yaps_tx_beacon_handler(yaps))
478 set_bit(MM81X_HIF_EVT_TX_BEACON_PEND, flags);
479 }
480
481 /* TX mgmt before considering data */
482 if (test_and_clear_bit(MM81X_HIF_EVT_TX_MGMT_PEND, flags)) {
483 if (mm81x_yaps_tx_mgmt_handler(yaps))
484 set_bit(MM81X_HIF_EVT_TX_MGMT_PEND, flags);
485 }
486
487 /* Pause TX data Qs */
488 if (test_and_clear_bit(MM81X_HIF_EVT_DATA_TRAFFIC_PAUSE_PEND, flags)) {
489 test_and_clear_bit(MM81X_HIF_EVT_DATA_TRAFFIC_RESUME_PEND,
490 flags);
491 mm81x_skbq_data_traffic_pause(mors);
492 }
493
494 /* Resume TX data Qs */
495 if (test_and_clear_bit(MM81X_HIF_EVT_DATA_TRAFFIC_RESUME_PEND, flags))
496 mm81x_skbq_data_traffic_resume(mors);
497
498 /* Handle chip queue status */
499 if (test_and_clear_bit(MM81X_HIF_EVT_TX_PACKET_FREED_UP_PEND, flags))
500 yaps->chip_queue_full.is_full = false;
501
502 /* Check to see if the queue is full or
503 * long enough has past since the queue was full
504 */
505 if (yaps->chip_queue_full.is_full &&
506 time_before(jiffies, yaps->chip_queue_full.retry_expiry))
507 goto exit;
508
509 /* Finally TX any data */
510 if (test_and_clear_bit(MM81X_HIF_EVT_TX_DATA_PEND, flags)) {
511 if (mm81x_yaps_tx_data_handler(yaps))
512 set_bit(MM81X_HIF_EVT_TX_DATA_PEND, flags);
513
514 if (yaps->chip_queue_full.is_full) {
515 yaps->chip_queue_full.retry_expiry =
516 jiffies +
517 msecs_to_jiffies(CHIP_FULL_RECOVERY_TIMEOUT_MS);
518 mod_timer(&yaps->chip_queue_full.timer,
519 yaps->chip_queue_full.retry_expiry);
520 }
521 }
522
523 exit:
524
525 /* Disable power save in case it is running */
526 mm81x_release_bus(mors);
527 mm81x_ps_enable(mors);
528
529 /* Don't requeue work if we are shutting down. */
530 if (yaps->finish)
531 return;
532 /*
533 * Evaluate all events except MM81X_HIF_EVT_TX_DATA_PEND in case data
534 * tx queue is full
535 */
536 if ((*flags) & ~(1 << MM81X_HIF_EVT_TX_DATA_PEND))
537 queue_work(mors->chip_wq, &mors->hif_work);
538 /*
539 * if data tx queue is not full and the work hasn't been queued let's
540 * queue it
541 */
542 else if (!yaps->chip_queue_full.is_full && *flags)
543 queue_work(mors->chip_wq, &mors->hif_work);
544 }
545
mm81x_yaps_get_tx_status_pending_count(struct mm81x * mors)546 int mm81x_yaps_get_tx_status_pending_count(struct mm81x *mors)
547 {
548 int i = 0;
549 int count = 0;
550 struct mm81x_yaps *yaps;
551
552 yaps = &mors->hif.u.yaps;
553 count += skb_queue_len(&yaps->beacon_q.pending);
554 count += skb_queue_len(&yaps->mgmt_q.pending);
555 count += skb_queue_len(&yaps->cmd_q.pending);
556
557 for (i = 0; i < ARRAY_SIZE(yaps->data_tx_qs); i++)
558 count += skb_queue_len(&yaps->data_tx_qs[i].pending);
559
560 return count;
561 }
562
mm81x_yaps_get_tx_buffered_count(struct mm81x * mors)563 int mm81x_yaps_get_tx_buffered_count(struct mm81x *mors)
564 {
565 int i = 0;
566 int count = 0;
567 struct mm81x_yaps *yaps;
568
569 yaps = &mors->hif.u.yaps;
570 count += skb_queue_len(&yaps->beacon_q.skbq) +
571 skb_queue_len(&yaps->beacon_q.pending);
572 count += skb_queue_len(&yaps->mgmt_q.skbq) +
573 skb_queue_len(&yaps->mgmt_q.pending);
574 count += skb_queue_len(&yaps->cmd_q.skbq) +
575 skb_queue_len(&yaps->cmd_q.pending);
576
577 for (i = 0; i < ARRAY_SIZE(yaps->data_tx_qs); i++)
578 count += mm81x_skbq_count_tx_ready(&yaps->data_tx_qs[i]) +
579 skb_queue_len(&yaps->data_tx_qs[i].pending);
580
581 return count;
582 }
583
mm81x_yaps_tx_q_full_timer(struct timer_list * t)584 static void mm81x_yaps_tx_q_full_timer(struct timer_list *t)
585 {
586 struct mm81x_yaps *yaps =
587 timer_container_of(yaps, t, chip_queue_full.timer);
588
589 queue_work(yaps->mors->chip_wq, &yaps->mors->hif_work);
590 }
591
mm81x_yaps_q_chip_full_timer_init(struct mm81x_yaps * yaps)592 static void mm81x_yaps_q_chip_full_timer_init(struct mm81x_yaps *yaps)
593 {
594 timer_setup(&yaps->chip_queue_full.timer, mm81x_yaps_tx_q_full_timer,
595 0);
596 }
597
mm81x_yaps_q_chip_full_timer_finish(struct mm81x_yaps * yaps)598 static void mm81x_yaps_q_chip_full_timer_finish(struct mm81x_yaps *yaps)
599 {
600 timer_shutdown_sync(&yaps->chip_queue_full.timer);
601 }
602
mm81x_yaps_init(struct mm81x * mors)603 int mm81x_yaps_init(struct mm81x *mors)
604 {
605 int i, ret;
606 struct mm81x_yaps *yaps;
607
608 ret = mm81x_yaps_hw_init(mors);
609 if (ret) {
610 dev_err(mors->dev, "mm81x_yaps_hw_init failed %d", ret);
611 return ret;
612 }
613
614 yaps = &mors->hif.u.yaps;
615 yaps->mors = mors;
616
617 mm81x_claim_bus(mors);
618
619 ret = mm81x_yaps_alloc_pkt_buffers(yaps);
620 if (ret) {
621 dev_err(mors->dev, "Failed to allocate YAPS packet buffers: %d",
622 ret);
623 mm81x_yaps_hw_finish(mors);
624 mm81x_release_bus(mors);
625 return ret;
626 }
627
628 /* YAPS is bi-directional */
629 mm81x_skbq_init(mors, &yaps->data_rx_q,
630 MM81X_HIF_FLAGS_DATA | MM81X_HIF_FLAGS_DIR_TO_HOST);
631 mm81x_skbq_init(mors, &yaps->beacon_q,
632 MM81X_HIF_FLAGS_DATA | MM81X_HIF_FLAGS_DIR_TO_HOST);
633 mm81x_skbq_init(mors, &yaps->mgmt_q,
634 MM81X_HIF_FLAGS_DATA | MM81X_HIF_FLAGS_DIR_TO_HOST);
635
636 for (i = 0; i < ARRAY_SIZE(yaps->data_tx_qs); i++) {
637 mm81x_skbq_init(mors, &yaps->data_tx_qs[i],
638 MM81X_HIF_FLAGS_DATA |
639 MM81X_HIF_FLAGS_DIR_TO_CHIP);
640 }
641
642 mm81x_skbq_init(mors, &yaps->cmd_q,
643 MM81X_HIF_FLAGS_COMMAND | MM81X_HIF_FLAGS_DIR_TO_CHIP);
644 mm81x_skbq_init(mors, &yaps->cmd_resp_q,
645 MM81X_HIF_FLAGS_COMMAND | MM81X_HIF_FLAGS_DIR_TO_HOST);
646
647 mm81x_yaps_q_chip_full_timer_init(yaps);
648 INIT_WORK(&mors->hif_work, mm81x_yaps_work);
649 INIT_WORK(&mors->tx_stale_work, mm81x_yaps_stale_tx_work);
650 mm81x_release_bus(mors);
651 mm81x_hw_enable_stop_notifications(mors, true);
652 return 0;
653 }
654
mm81x_yaps_finish(struct mm81x * mors)655 void mm81x_yaps_finish(struct mm81x *mors)
656 {
657 int i;
658 struct mm81x_yaps *yaps;
659
660 mm81x_yaps_hw_enable_irqs(mors, false);
661
662 yaps = &mors->hif.u.yaps;
663 yaps->finish = true;
664
665 mm81x_skbq_finish(&yaps->data_rx_q);
666 mm81x_skbq_finish(&yaps->beacon_q);
667 mm81x_skbq_finish(&yaps->mgmt_q);
668
669 for (i = 0; i < ARRAY_SIZE(yaps->data_tx_qs); i++)
670 mm81x_skbq_finish(&yaps->data_tx_qs[i]);
671
672 mm81x_skbq_finish(&yaps->cmd_q);
673 mm81x_skbq_finish(&yaps->cmd_resp_q);
674
675 mm81x_yaps_q_chip_full_timer_finish(yaps);
676
677 cancel_work_sync(&mors->hif_work);
678 cancel_work_sync(&mors->tx_stale_work);
679
680 mm81x_yaps_free_pkt_buffers(yaps);
681 mm81x_yaps_hw_finish(mors);
682 }
683
mm81x_yaps_flush_tx_data(struct mm81x * mors)684 void mm81x_yaps_flush_tx_data(struct mm81x *mors)
685 {
686 int i;
687 struct mm81x_yaps *yaps = &mors->hif.u.yaps;
688
689 mm81x_skbq_tx_flush(&yaps->beacon_q);
690 mm81x_skbq_tx_flush(&yaps->mgmt_q);
691
692 for (i = 0; i < ARRAY_SIZE(yaps->data_tx_qs); i++)
693 mm81x_skbq_tx_flush(&yaps->data_tx_qs[i]);
694 }
695
mm81x_yaps_flush_cmds(struct mm81x * mors)696 void mm81x_yaps_flush_cmds(struct mm81x *mors)
697 {
698 struct mm81x_yaps *yaps = &mors->hif.u.yaps;
699
700 if (yaps->flags & MM81X_HIF_FLAGS_COMMAND) {
701 mm81x_skbq_finish(&yaps->cmd_q);
702 mm81x_skbq_finish(&yaps->cmd_resp_q);
703 }
704 }
705