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 = 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 */ 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 */ 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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