root/drivers/net/wireless/broadcom/b43legacy/pio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tx_start
  2. tx_octet
  3. tx_get_next_word
  4. tx_data
  5. tx_complete
  6. generate_cookie
  7. parse_cookie
  8. pio_tx_write_fragment
  9. free_txpacket
  10. pio_tx_packet
  11. tx_tasklet
  12. setup_txqueues
  13. b43legacy_setup_pioqueue
  14. cancel_transfers
  15. b43legacy_destroy_pioqueue
  16. b43legacy_pio_free
  17. b43legacy_pio_init
  18. b43legacy_pio_tx
  19. b43legacy_pio_handle_txstatus
  20. pio_rx_error
  21. b43legacy_pio_rx
  22. b43legacy_pio_tx_suspend
  23. b43legacy_pio_tx_resume
  24. b43legacy_pio_freeze_txqueues
  25. b43legacy_pio_thaw_txqueues

   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 }

/* [<][>][^][v][top][bottom][index][help] */