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