1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 4 Broadcom B43legacy wireless driver 5 6 PIO Transmission 7 8 Copyright (c) 2005 Michael Buesch <m@bues.ch> 9 10 11 */ 12 13 #include "b43legacy.h" 14 #include "pio.h" 15 #include "main.h" 16 #include "xmit.h" 17 18 #include <linux/delay.h> 19 #include <linux/slab.h> 20 21 22 static void tx_start(struct b43legacy_pioqueue *queue) 23 { 24 b43legacy_pio_write(queue, B43legacy_PIO_TXCTL, 25 B43legacy_PIO_TXCTL_INIT); 26 } 27 28 static void tx_octet(struct b43legacy_pioqueue *queue, 29 u8 octet) 30 { 31 if (queue->need_workarounds) { 32 b43legacy_pio_write(queue, B43legacy_PIO_TXDATA, octet); 33 b43legacy_pio_write(queue, B43legacy_PIO_TXCTL, 34 B43legacy_PIO_TXCTL_WRITELO); 35 } else { 36 b43legacy_pio_write(queue, B43legacy_PIO_TXCTL, 37 B43legacy_PIO_TXCTL_WRITELO); 38 b43legacy_pio_write(queue, B43legacy_PIO_TXDATA, octet); 39 } 40 } 41 42 static u16 tx_get_next_word(const u8 *txhdr, 43 const u8 *packet, 44 size_t txhdr_size, 45 unsigned int *pos) 46 { 47 const u8 *source; 48 unsigned int i = *pos; 49 u16 ret; 50 51 if (i < txhdr_size) 52 source = txhdr; 53 else { 54 source = packet; 55 i -= txhdr_size; 56 } 57 ret = le16_to_cpu(*((__le16 *)(source + i))); 58 *pos += 2; 59 60 return ret; 61 } 62 63 static void tx_data(struct b43legacy_pioqueue *queue, 64 u8 *txhdr, 65 const u8 *packet, 66 unsigned int octets) 67 { 68 u16 data; 69 unsigned int i = 0; 70 71 if (queue->need_workarounds) { 72 data = tx_get_next_word(txhdr, packet, 73 sizeof(struct b43legacy_txhdr_fw3), &i); 74 b43legacy_pio_write(queue, B43legacy_PIO_TXDATA, data); 75 } 76 b43legacy_pio_write(queue, B43legacy_PIO_TXCTL, 77 B43legacy_PIO_TXCTL_WRITELO | 78 B43legacy_PIO_TXCTL_WRITEHI); 79 while (i < octets - 1) { 80 data = tx_get_next_word(txhdr, packet, 81 sizeof(struct b43legacy_txhdr_fw3), &i); 82 b43legacy_pio_write(queue, B43legacy_PIO_TXDATA, data); 83 } 84 if (octets % 2) 85 tx_octet(queue, packet[octets - 86 sizeof(struct b43legacy_txhdr_fw3) - 1]); 87 } 88 89 static void tx_complete(struct b43legacy_pioqueue *queue, 90 struct sk_buff *skb) 91 { 92 if (queue->need_workarounds) { 93 b43legacy_pio_write(queue, B43legacy_PIO_TXDATA, 94 skb->data[skb->len - 1]); 95 b43legacy_pio_write(queue, B43legacy_PIO_TXCTL, 96 B43legacy_PIO_TXCTL_WRITELO | 97 B43legacy_PIO_TXCTL_COMPLETE); 98 } else 99 b43legacy_pio_write(queue, B43legacy_PIO_TXCTL, 100 B43legacy_PIO_TXCTL_COMPLETE); 101 } 102 103 static u16 generate_cookie(struct b43legacy_pioqueue *queue, 104 struct b43legacy_pio_txpacket *packet) 105 { 106 u16 cookie = 0x0000; 107 int packetindex; 108 109 /* We use the upper 4 bits for the PIO 110 * controller ID and the lower 12 bits 111 * for the packet index (in the cache). 112 */ 113 switch (queue->mmio_base) { 114 case B43legacy_MMIO_PIO1_BASE: 115 break; 116 case B43legacy_MMIO_PIO2_BASE: 117 cookie = 0x1000; 118 break; 119 case B43legacy_MMIO_PIO3_BASE: 120 cookie = 0x2000; 121 break; 122 case B43legacy_MMIO_PIO4_BASE: 123 cookie = 0x3000; 124 break; 125 default: 126 B43legacy_WARN_ON(1); 127 } 128 packetindex = pio_txpacket_getindex(packet); 129 B43legacy_WARN_ON(!(((u16)packetindex & 0xF000) == 0x0000)); 130 cookie |= (u16)packetindex; 131 132 return cookie; 133 } 134 135 static 136 struct b43legacy_pioqueue *parse_cookie(struct b43legacy_wldev *dev, 137 u16 cookie, 138 struct b43legacy_pio_txpacket **packet) 139 { 140 struct b43legacy_pio *pio = &dev->pio; 141 struct b43legacy_pioqueue *queue = NULL; 142 int packetindex; 143 144 switch (cookie & 0xF000) { 145 case 0x0000: 146 queue = pio->queue0; 147 break; 148 case 0x1000: 149 queue = pio->queue1; 150 break; 151 case 0x2000: 152 queue = pio->queue2; 153 break; 154 case 0x3000: 155 queue = pio->queue3; 156 break; 157 default: 158 B43legacy_WARN_ON(1); 159 } 160 packetindex = (cookie & 0x0FFF); 161 B43legacy_WARN_ON(!(packetindex >= 0 && packetindex 162 < B43legacy_PIO_MAXTXPACKETS)); 163 *packet = &(queue->tx_packets_cache[packetindex]); 164 165 return queue; 166 } 167 168 union txhdr_union { 169 struct b43legacy_txhdr_fw3 txhdr_fw3; 170 }; 171 172 static int pio_tx_write_fragment(struct b43legacy_pioqueue *queue, 173 struct sk_buff *skb, 174 struct b43legacy_pio_txpacket *packet, 175 size_t txhdr_size) 176 { 177 union txhdr_union txhdr_data; 178 u8 *txhdr = NULL; 179 unsigned int octets; 180 int err; 181 182 txhdr = (u8 *)(&txhdr_data.txhdr_fw3); 183 184 B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); 185 err = b43legacy_generate_txhdr(queue->dev, 186 txhdr, skb->data, skb->len, 187 IEEE80211_SKB_CB(skb), 188 generate_cookie(queue, packet)); 189 if (err) 190 return err; 191 192 tx_start(queue); 193 octets = skb->len + txhdr_size; 194 if (queue->need_workarounds) 195 octets--; 196 tx_data(queue, txhdr, (u8 *)skb->data, octets); 197 tx_complete(queue, skb); 198 199 return 0; 200 } 201 202 static void free_txpacket(struct b43legacy_pio_txpacket *packet, 203 int irq_context) 204 { 205 struct b43legacy_pioqueue *queue = packet->queue; 206 207 if (packet->skb) { 208 if (irq_context) 209 dev_kfree_skb_irq(packet->skb); 210 else 211 dev_kfree_skb(packet->skb); 212 } 213 list_move(&packet->list, &queue->txfree); 214 queue->nr_txfree++; 215 } 216 217 static int pio_tx_packet(struct b43legacy_pio_txpacket *packet) 218 { 219 struct b43legacy_pioqueue *queue = packet->queue; 220 struct sk_buff *skb = packet->skb; 221 u16 octets; 222 int err; 223 224 octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3); 225 if (queue->tx_devq_size < octets) { 226 b43legacywarn(queue->dev->wl, "PIO queue too small. " 227 "Dropping packet.\n"); 228 /* Drop it silently (return success) */ 229 free_txpacket(packet, 1); 230 return 0; 231 } 232 B43legacy_WARN_ON(queue->tx_devq_packets > 233 B43legacy_PIO_MAXTXDEVQPACKETS); 234 B43legacy_WARN_ON(queue->tx_devq_used > queue->tx_devq_size); 235 /* Check if there is sufficient free space on the device 236 * TX queue. If not, return and let the TX tasklet 237 * retry later. 238 */ 239 if (queue->tx_devq_packets == B43legacy_PIO_MAXTXDEVQPACKETS) 240 return -EBUSY; 241 if (queue->tx_devq_used + octets > queue->tx_devq_size) 242 return -EBUSY; 243 /* Now poke the device. */ 244 err = pio_tx_write_fragment(queue, skb, packet, 245 sizeof(struct b43legacy_txhdr_fw3)); 246 if (unlikely(err == -ENOKEY)) { 247 /* Drop this packet, as we don't have the encryption key 248 * anymore and must not transmit it unencrypted. */ 249 free_txpacket(packet, 1); 250 return 0; 251 } 252 253 /* Account for the packet size. 254 * (We must not overflow the device TX queue) 255 */ 256 queue->tx_devq_packets++; 257 queue->tx_devq_used += octets; 258 259 /* Transmission started, everything ok, move the 260 * packet to the txrunning list. 261 */ 262 list_move_tail(&packet->list, &queue->txrunning); 263 264 return 0; 265 } 266 267 static void tx_tasklet(unsigned long d) 268 { 269 struct b43legacy_pioqueue *queue = (struct b43legacy_pioqueue *)d; 270 struct b43legacy_wldev *dev = queue->dev; 271 unsigned long flags; 272 struct b43legacy_pio_txpacket *packet, *tmp_packet; 273 int err; 274 u16 txctl; 275 276 spin_lock_irqsave(&dev->wl->irq_lock, flags); 277 if (queue->tx_frozen) 278 goto out_unlock; 279 txctl = b43legacy_pio_read(queue, B43legacy_PIO_TXCTL); 280 if (txctl & B43legacy_PIO_TXCTL_SUSPEND) 281 goto out_unlock; 282 283 list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { 284 /* Try to transmit the packet. This can fail, if 285 * the device queue is full. In case of failure, the 286 * packet is left in the txqueue. 287 * If transmission succeed, the packet is moved to txrunning. 288 * If it is impossible to transmit the packet, it 289 * is dropped. 290 */ 291 err = pio_tx_packet(packet); 292 if (err) 293 break; 294 } 295 out_unlock: 296 spin_unlock_irqrestore(&dev->wl->irq_lock, flags); 297 } 298 299 static void setup_txqueues(struct b43legacy_pioqueue *queue) 300 { 301 struct b43legacy_pio_txpacket *packet; 302 int i; 303 304 queue->nr_txfree = B43legacy_PIO_MAXTXPACKETS; 305 for (i = 0; i < B43legacy_PIO_MAXTXPACKETS; i++) { 306 packet = &(queue->tx_packets_cache[i]); 307 308 packet->queue = queue; 309 INIT_LIST_HEAD(&packet->list); 310 311 list_add(&packet->list, &queue->txfree); 312 } 313 } 314 315 static 316 struct b43legacy_pioqueue *b43legacy_setup_pioqueue(struct b43legacy_wldev *dev, 317 u16 pio_mmio_base) 318 { 319 struct b43legacy_pioqueue *queue; 320 u32 value; 321 u16 qsize; 322 323 queue = kzalloc(sizeof(*queue), GFP_KERNEL); 324 if (!queue) 325 goto out; 326 327 queue->dev = dev; 328 queue->mmio_base = pio_mmio_base; 329 queue->need_workarounds = (dev->dev->id.revision < 3); 330 331 INIT_LIST_HEAD(&queue->txfree); 332 INIT_LIST_HEAD(&queue->txqueue); 333 INIT_LIST_HEAD(&queue->txrunning); 334 tasklet_init(&queue->txtask, tx_tasklet, 335 (unsigned long)queue); 336 337 value = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); 338 value &= ~B43legacy_MACCTL_BE; 339 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value); 340 341 qsize = b43legacy_read16(dev, queue->mmio_base 342 + B43legacy_PIO_TXQBUFSIZE); 343 if (qsize == 0) { 344 b43legacyerr(dev->wl, "This card does not support PIO " 345 "operation mode. Please use DMA mode " 346 "(module parameter pio=0).\n"); 347 goto err_freequeue; 348 } 349 if (qsize <= B43legacy_PIO_TXQADJUST) { 350 b43legacyerr(dev->wl, "PIO tx device-queue too small (%u)\n", 351 qsize); 352 goto err_freequeue; 353 } 354 qsize -= B43legacy_PIO_TXQADJUST; 355 queue->tx_devq_size = qsize; 356 357 setup_txqueues(queue); 358 359 out: 360 return queue; 361 362 err_freequeue: 363 kfree(queue); 364 queue = NULL; 365 goto out; 366 } 367 368 static void cancel_transfers(struct b43legacy_pioqueue *queue) 369 { 370 struct b43legacy_pio_txpacket *packet, *tmp_packet; 371 372 tasklet_kill(&queue->txtask); 373 374 list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) 375 free_txpacket(packet, 0); 376 list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) 377 free_txpacket(packet, 0); 378 } 379 380 static void b43legacy_destroy_pioqueue(struct b43legacy_pioqueue *queue) 381 { 382 if (!queue) 383 return; 384 385 cancel_transfers(queue); 386 kfree(queue); 387 } 388 389 void b43legacy_pio_free(struct b43legacy_wldev *dev) 390 { 391 struct b43legacy_pio *pio; 392 393 if (!b43legacy_using_pio(dev)) 394 return; 395 pio = &dev->pio; 396 397 b43legacy_destroy_pioqueue(pio->queue3); 398 pio->queue3 = NULL; 399 b43legacy_destroy_pioqueue(pio->queue2); 400 pio->queue2 = NULL; 401 b43legacy_destroy_pioqueue(pio->queue1); 402 pio->queue1 = NULL; 403 b43legacy_destroy_pioqueue(pio->queue0); 404 pio->queue0 = NULL; 405 } 406 407 int b43legacy_pio_init(struct b43legacy_wldev *dev) 408 { 409 struct b43legacy_pio *pio = &dev->pio; 410 struct b43legacy_pioqueue *queue; 411 int err = -ENOMEM; 412 413 queue = b43legacy_setup_pioqueue(dev, B43legacy_MMIO_PIO1_BASE); 414 if (!queue) 415 goto out; 416 pio->queue0 = queue; 417 418 queue = b43legacy_setup_pioqueue(dev, B43legacy_MMIO_PIO2_BASE); 419 if (!queue) 420 goto err_destroy0; 421 pio->queue1 = queue; 422 423 queue = b43legacy_setup_pioqueue(dev, B43legacy_MMIO_PIO3_BASE); 424 if (!queue) 425 goto err_destroy1; 426 pio->queue2 = queue; 427 428 queue = b43legacy_setup_pioqueue(dev, B43legacy_MMIO_PIO4_BASE); 429 if (!queue) 430 goto err_destroy2; 431 pio->queue3 = queue; 432 433 if (dev->dev->id.revision < 3) 434 dev->irq_mask |= B43legacy_IRQ_PIO_WORKAROUND; 435 436 b43legacydbg(dev->wl, "PIO initialized\n"); 437 err = 0; 438 out: 439 return err; 440 441 err_destroy2: 442 b43legacy_destroy_pioqueue(pio->queue2); 443 pio->queue2 = NULL; 444 err_destroy1: 445 b43legacy_destroy_pioqueue(pio->queue1); 446 pio->queue1 = NULL; 447 err_destroy0: 448 b43legacy_destroy_pioqueue(pio->queue0); 449 pio->queue0 = NULL; 450 goto out; 451 } 452 453 int b43legacy_pio_tx(struct b43legacy_wldev *dev, 454 struct sk_buff *skb) 455 { 456 struct b43legacy_pioqueue *queue = dev->pio.queue1; 457 struct b43legacy_pio_txpacket *packet; 458 459 B43legacy_WARN_ON(queue->tx_suspended); 460 B43legacy_WARN_ON(list_empty(&queue->txfree)); 461 462 packet = list_entry(queue->txfree.next, struct b43legacy_pio_txpacket, 463 list); 464 packet->skb = skb; 465 466 list_move_tail(&packet->list, &queue->txqueue); 467 queue->nr_txfree--; 468 B43legacy_WARN_ON(queue->nr_txfree >= B43legacy_PIO_MAXTXPACKETS); 469 470 tasklet_schedule(&queue->txtask); 471 472 return 0; 473 } 474 475 void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev, 476 const struct b43legacy_txstatus *status) 477 { 478 struct b43legacy_pioqueue *queue; 479 struct b43legacy_pio_txpacket *packet; 480 struct ieee80211_tx_info *info; 481 int retry_limit; 482 483 queue = parse_cookie(dev, status->cookie, &packet); 484 B43legacy_WARN_ON(!queue); 485 486 if (!packet->skb) 487 return; 488 489 queue->tx_devq_packets--; 490 queue->tx_devq_used -= (packet->skb->len + 491 sizeof(struct b43legacy_txhdr_fw3)); 492 493 info = IEEE80211_SKB_CB(packet->skb); 494 495 /* preserve the confiured retry limit before clearing the status 496 * The xmit function has overwritten the rc's value with the actual 497 * retry limit done by the hardware */ 498 retry_limit = info->status.rates[0].count; 499 ieee80211_tx_info_clear_status(info); 500 501 if (status->acked) 502 info->flags |= IEEE80211_TX_STAT_ACK; 503 504 if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { 505 /* 506 * If the short retries (RTS, not data frame) have exceeded 507 * the limit, the hw will not have tried the selected rate, 508 * but will have used the fallback rate instead. 509 * Don't let the rate control count attempts for the selected 510 * rate in this case, otherwise the statistics will be off. 511 */ 512 info->status.rates[0].count = 0; 513 info->status.rates[1].count = status->frame_count; 514 } else { 515 if (status->frame_count > retry_limit) { 516 info->status.rates[0].count = retry_limit; 517 info->status.rates[1].count = status->frame_count - 518 retry_limit; 519 520 } else { 521 info->status.rates[0].count = status->frame_count; 522 info->status.rates[1].idx = -1; 523 } 524 } 525 ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb); 526 packet->skb = NULL; 527 528 free_txpacket(packet, 1); 529 /* If there are packets on the txqueue, poke the tasklet 530 * to transmit them. 531 */ 532 if (!list_empty(&queue->txqueue)) 533 tasklet_schedule(&queue->txtask); 534 } 535 536 static void pio_rx_error(struct b43legacy_pioqueue *queue, 537 int clear_buffers, 538 const char *error) 539 { 540 int i; 541 542 b43legacyerr(queue->dev->wl, "PIO RX error: %s\n", error); 543 b43legacy_pio_write(queue, B43legacy_PIO_RXCTL, 544 B43legacy_PIO_RXCTL_READY); 545 if (clear_buffers) { 546 B43legacy_WARN_ON(queue->mmio_base != B43legacy_MMIO_PIO1_BASE); 547 for (i = 0; i < 15; i++) { 548 /* Dummy read. */ 549 b43legacy_pio_read(queue, B43legacy_PIO_RXDATA); 550 } 551 } 552 } 553 554 void b43legacy_pio_rx(struct b43legacy_pioqueue *queue) 555 { 556 __le16 preamble[21] = { 0 }; 557 struct b43legacy_rxhdr_fw3 *rxhdr; 558 u16 tmp; 559 u16 len; 560 u16 macstat; 561 int i; 562 int preamble_readwords; 563 struct sk_buff *skb; 564 565 tmp = b43legacy_pio_read(queue, B43legacy_PIO_RXCTL); 566 if (!(tmp & B43legacy_PIO_RXCTL_DATAAVAILABLE)) 567 return; 568 b43legacy_pio_write(queue, B43legacy_PIO_RXCTL, 569 B43legacy_PIO_RXCTL_DATAAVAILABLE); 570 571 for (i = 0; i < 10; i++) { 572 tmp = b43legacy_pio_read(queue, B43legacy_PIO_RXCTL); 573 if (tmp & B43legacy_PIO_RXCTL_READY) 574 goto data_ready; 575 udelay(10); 576 } 577 b43legacydbg(queue->dev->wl, "PIO RX timed out\n"); 578 return; 579 data_ready: 580 581 len = b43legacy_pio_read(queue, B43legacy_PIO_RXDATA); 582 if (unlikely(len > 0x700)) { 583 pio_rx_error(queue, 0, "len > 0x700"); 584 return; 585 } 586 if (unlikely(len == 0 && queue->mmio_base != 587 B43legacy_MMIO_PIO4_BASE)) { 588 pio_rx_error(queue, 0, "len == 0"); 589 return; 590 } 591 preamble[0] = cpu_to_le16(len); 592 if (queue->mmio_base == B43legacy_MMIO_PIO4_BASE) 593 preamble_readwords = 14 / sizeof(u16); 594 else 595 preamble_readwords = 18 / sizeof(u16); 596 for (i = 0; i < preamble_readwords; i++) { 597 tmp = b43legacy_pio_read(queue, B43legacy_PIO_RXDATA); 598 preamble[i + 1] = cpu_to_le16(tmp); 599 } 600 rxhdr = (struct b43legacy_rxhdr_fw3 *)preamble; 601 macstat = le16_to_cpu(rxhdr->mac_status); 602 if (macstat & B43legacy_RX_MAC_FCSERR) { 603 pio_rx_error(queue, 604 (queue->mmio_base == B43legacy_MMIO_PIO1_BASE), 605 "Frame FCS error"); 606 return; 607 } 608 if (queue->mmio_base == B43legacy_MMIO_PIO4_BASE) { 609 /* We received an xmit status. */ 610 struct b43legacy_hwtxstatus *hw; 611 612 hw = (struct b43legacy_hwtxstatus *)(preamble + 1); 613 b43legacy_handle_hwtxstatus(queue->dev, hw); 614 615 return; 616 } 617 618 skb = dev_alloc_skb(len); 619 if (unlikely(!skb)) { 620 pio_rx_error(queue, 1, "OOM"); 621 return; 622 } 623 skb_put(skb, len); 624 for (i = 0; i < len - 1; i += 2) { 625 tmp = b43legacy_pio_read(queue, B43legacy_PIO_RXDATA); 626 *((__le16 *)(skb->data + i)) = cpu_to_le16(tmp); 627 } 628 if (len % 2) { 629 tmp = b43legacy_pio_read(queue, B43legacy_PIO_RXDATA); 630 skb->data[len - 1] = (tmp & 0x00FF); 631 } 632 b43legacy_rx(queue->dev, skb, rxhdr); 633 } 634 635 void b43legacy_pio_tx_suspend(struct b43legacy_pioqueue *queue) 636 { 637 b43legacy_power_saving_ctl_bits(queue->dev, -1, 1); 638 b43legacy_pio_write(queue, B43legacy_PIO_TXCTL, 639 b43legacy_pio_read(queue, B43legacy_PIO_TXCTL) 640 | B43legacy_PIO_TXCTL_SUSPEND); 641 } 642 643 void b43legacy_pio_tx_resume(struct b43legacy_pioqueue *queue) 644 { 645 b43legacy_pio_write(queue, B43legacy_PIO_TXCTL, 646 b43legacy_pio_read(queue, B43legacy_PIO_TXCTL) 647 & ~B43legacy_PIO_TXCTL_SUSPEND); 648 b43legacy_power_saving_ctl_bits(queue->dev, -1, -1); 649 tasklet_schedule(&queue->txtask); 650 } 651 652 void b43legacy_pio_freeze_txqueues(struct b43legacy_wldev *dev) 653 { 654 struct b43legacy_pio *pio; 655 656 B43legacy_WARN_ON(!b43legacy_using_pio(dev)); 657 pio = &dev->pio; 658 pio->queue0->tx_frozen = 1; 659 pio->queue1->tx_frozen = 1; 660 pio->queue2->tx_frozen = 1; 661 pio->queue3->tx_frozen = 1; 662 } 663 664 void b43legacy_pio_thaw_txqueues(struct b43legacy_wldev *dev) 665 { 666 struct b43legacy_pio *pio; 667 668 B43legacy_WARN_ON(!b43legacy_using_pio(dev)); 669 pio = &dev->pio; 670 pio->queue0->tx_frozen = 0; 671 pio->queue1->tx_frozen = 0; 672 pio->queue2->tx_frozen = 0; 673 pio->queue3->tx_frozen = 0; 674 if (!list_empty(&pio->queue0->txqueue)) 675 tasklet_schedule(&pio->queue0->txtask); 676 if (!list_empty(&pio->queue1->txqueue)) 677 tasklet_schedule(&pio->queue1->txtask); 678 if (!list_empty(&pio->queue2->txqueue)) 679 tasklet_schedule(&pio->queue2->txtask); 680 if (!list_empty(&pio->queue3->txqueue)) 681 tasklet_schedule(&pio->queue3->txtask); 682 } 683