Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003 
0004   Broadcom B43 wireless driver
0005 
0006   PIO data transfer
0007 
0008   Copyright (c) 2005-2008 Michael Buesch <m@bues.ch>
0009 
0010 
0011 */
0012 
0013 #include "b43.h"
0014 #include "pio.h"
0015 #include "dma.h"
0016 #include "main.h"
0017 #include "xmit.h"
0018 
0019 #include <linux/delay.h>
0020 #include <linux/sched.h>
0021 #include <linux/slab.h>
0022 
0023 
0024 static u16 generate_cookie(struct b43_pio_txqueue *q,
0025                struct b43_pio_txpacket *pack)
0026 {
0027     u16 cookie;
0028 
0029     /* Use the upper 4 bits of the cookie as
0030      * PIO controller ID and store the packet index number
0031      * in the lower 12 bits.
0032      * Note that the cookie must never be 0, as this
0033      * is a special value used in RX path.
0034      * It can also not be 0xFFFF because that is special
0035      * for multicast frames.
0036      */
0037     cookie = (((u16)q->index + 1) << 12);
0038     cookie |= pack->index;
0039 
0040     return cookie;
0041 }
0042 
0043 static
0044 struct b43_pio_txqueue *parse_cookie(struct b43_wldev *dev,
0045                      u16 cookie,
0046                       struct b43_pio_txpacket **pack)
0047 {
0048     struct b43_pio *pio = &dev->pio;
0049     struct b43_pio_txqueue *q = NULL;
0050     unsigned int pack_index;
0051 
0052     switch (cookie & 0xF000) {
0053     case 0x1000:
0054         q = pio->tx_queue_AC_BK;
0055         break;
0056     case 0x2000:
0057         q = pio->tx_queue_AC_BE;
0058         break;
0059     case 0x3000:
0060         q = pio->tx_queue_AC_VI;
0061         break;
0062     case 0x4000:
0063         q = pio->tx_queue_AC_VO;
0064         break;
0065     case 0x5000:
0066         q = pio->tx_queue_mcast;
0067         break;
0068     }
0069     if (B43_WARN_ON(!q))
0070         return NULL;
0071     pack_index = (cookie & 0x0FFF);
0072     if (B43_WARN_ON(pack_index >= ARRAY_SIZE(q->packets)))
0073         return NULL;
0074     *pack = &q->packets[pack_index];
0075 
0076     return q;
0077 }
0078 
0079 static u16 index_to_pioqueue_base(struct b43_wldev *dev,
0080                   unsigned int index)
0081 {
0082     static const u16 bases[] = {
0083         B43_MMIO_PIO_BASE0,
0084         B43_MMIO_PIO_BASE1,
0085         B43_MMIO_PIO_BASE2,
0086         B43_MMIO_PIO_BASE3,
0087         B43_MMIO_PIO_BASE4,
0088         B43_MMIO_PIO_BASE5,
0089         B43_MMIO_PIO_BASE6,
0090         B43_MMIO_PIO_BASE7,
0091     };
0092     static const u16 bases_rev11[] = {
0093         B43_MMIO_PIO11_BASE0,
0094         B43_MMIO_PIO11_BASE1,
0095         B43_MMIO_PIO11_BASE2,
0096         B43_MMIO_PIO11_BASE3,
0097         B43_MMIO_PIO11_BASE4,
0098         B43_MMIO_PIO11_BASE5,
0099     };
0100 
0101     if (dev->dev->core_rev >= 11) {
0102         B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11));
0103         return bases_rev11[index];
0104     }
0105     B43_WARN_ON(index >= ARRAY_SIZE(bases));
0106     return bases[index];
0107 }
0108 
0109 static u16 pio_txqueue_offset(struct b43_wldev *dev)
0110 {
0111     if (dev->dev->core_rev >= 11)
0112         return 0x18;
0113     return 0;
0114 }
0115 
0116 static u16 pio_rxqueue_offset(struct b43_wldev *dev)
0117 {
0118     if (dev->dev->core_rev >= 11)
0119         return 0x38;
0120     return 8;
0121 }
0122 
0123 static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
0124                              unsigned int index)
0125 {
0126     struct b43_pio_txqueue *q;
0127     struct b43_pio_txpacket *p;
0128     unsigned int i;
0129 
0130     q = kzalloc(sizeof(*q), GFP_KERNEL);
0131     if (!q)
0132         return NULL;
0133     q->dev = dev;
0134     q->rev = dev->dev->core_rev;
0135     q->mmio_base = index_to_pioqueue_base(dev, index) +
0136                pio_txqueue_offset(dev);
0137     q->index = index;
0138 
0139     q->free_packet_slots = B43_PIO_MAX_NR_TXPACKETS;
0140     if (q->rev >= 8) {
0141         q->buffer_size = 1920; //FIXME this constant is wrong.
0142     } else {
0143         q->buffer_size = b43_piotx_read16(q, B43_PIO_TXQBUFSIZE);
0144         q->buffer_size -= 80;
0145     }
0146 
0147     INIT_LIST_HEAD(&q->packets_list);
0148     for (i = 0; i < ARRAY_SIZE(q->packets); i++) {
0149         p = &(q->packets[i]);
0150         INIT_LIST_HEAD(&p->list);
0151         p->index = i;
0152         p->queue = q;
0153         list_add(&p->list, &q->packets_list);
0154     }
0155 
0156     return q;
0157 }
0158 
0159 static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
0160                              unsigned int index)
0161 {
0162     struct b43_pio_rxqueue *q;
0163 
0164     q = kzalloc(sizeof(*q), GFP_KERNEL);
0165     if (!q)
0166         return NULL;
0167     q->dev = dev;
0168     q->rev = dev->dev->core_rev;
0169     q->mmio_base = index_to_pioqueue_base(dev, index) +
0170                pio_rxqueue_offset(dev);
0171 
0172     /* Enable Direct FIFO RX (PIO) on the engine. */
0173     b43_dma_direct_fifo_rx(dev, index, 1);
0174 
0175     return q;
0176 }
0177 
0178 static void b43_pio_cancel_tx_packets(struct b43_pio_txqueue *q)
0179 {
0180     struct b43_pio_txpacket *pack;
0181     unsigned int i;
0182 
0183     for (i = 0; i < ARRAY_SIZE(q->packets); i++) {
0184         pack = &(q->packets[i]);
0185         if (pack->skb) {
0186             ieee80211_free_txskb(q->dev->wl->hw, pack->skb);
0187             pack->skb = NULL;
0188         }
0189     }
0190 }
0191 
0192 static void b43_destroy_pioqueue_tx(struct b43_pio_txqueue *q,
0193                     const char *name)
0194 {
0195     if (!q)
0196         return;
0197     b43_pio_cancel_tx_packets(q);
0198     kfree(q);
0199 }
0200 
0201 static void b43_destroy_pioqueue_rx(struct b43_pio_rxqueue *q,
0202                     const char *name)
0203 {
0204     if (!q)
0205         return;
0206     kfree(q);
0207 }
0208 
0209 #define destroy_queue_tx(pio, queue) do {               \
0210     b43_destroy_pioqueue_tx((pio)->queue, __stringify(queue));  \
0211     (pio)->queue = NULL;                        \
0212   } while (0)
0213 
0214 #define destroy_queue_rx(pio, queue) do {               \
0215     b43_destroy_pioqueue_rx((pio)->queue, __stringify(queue));  \
0216     (pio)->queue = NULL;                        \
0217   } while (0)
0218 
0219 void b43_pio_free(struct b43_wldev *dev)
0220 {
0221     struct b43_pio *pio;
0222 
0223     if (!b43_using_pio_transfers(dev))
0224         return;
0225     pio = &dev->pio;
0226 
0227     destroy_queue_rx(pio, rx_queue);
0228     destroy_queue_tx(pio, tx_queue_mcast);
0229     destroy_queue_tx(pio, tx_queue_AC_VO);
0230     destroy_queue_tx(pio, tx_queue_AC_VI);
0231     destroy_queue_tx(pio, tx_queue_AC_BE);
0232     destroy_queue_tx(pio, tx_queue_AC_BK);
0233 }
0234 
0235 int b43_pio_init(struct b43_wldev *dev)
0236 {
0237     struct b43_pio *pio = &dev->pio;
0238     int err = -ENOMEM;
0239 
0240     b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
0241             & ~B43_MACCTL_BE);
0242     b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_RXPADOFF, 0);
0243 
0244     pio->tx_queue_AC_BK = b43_setup_pioqueue_tx(dev, 0);
0245     if (!pio->tx_queue_AC_BK)
0246         goto out;
0247 
0248     pio->tx_queue_AC_BE = b43_setup_pioqueue_tx(dev, 1);
0249     if (!pio->tx_queue_AC_BE)
0250         goto err_destroy_bk;
0251 
0252     pio->tx_queue_AC_VI = b43_setup_pioqueue_tx(dev, 2);
0253     if (!pio->tx_queue_AC_VI)
0254         goto err_destroy_be;
0255 
0256     pio->tx_queue_AC_VO = b43_setup_pioqueue_tx(dev, 3);
0257     if (!pio->tx_queue_AC_VO)
0258         goto err_destroy_vi;
0259 
0260     pio->tx_queue_mcast = b43_setup_pioqueue_tx(dev, 4);
0261     if (!pio->tx_queue_mcast)
0262         goto err_destroy_vo;
0263 
0264     pio->rx_queue = b43_setup_pioqueue_rx(dev, 0);
0265     if (!pio->rx_queue)
0266         goto err_destroy_mcast;
0267 
0268     b43dbg(dev->wl, "PIO initialized\n");
0269     err = 0;
0270 out:
0271     return err;
0272 
0273 err_destroy_mcast:
0274     destroy_queue_tx(pio, tx_queue_mcast);
0275 err_destroy_vo:
0276     destroy_queue_tx(pio, tx_queue_AC_VO);
0277 err_destroy_vi:
0278     destroy_queue_tx(pio, tx_queue_AC_VI);
0279 err_destroy_be:
0280     destroy_queue_tx(pio, tx_queue_AC_BE);
0281 err_destroy_bk:
0282     destroy_queue_tx(pio, tx_queue_AC_BK);
0283     return err;
0284 }
0285 
0286 /* Static mapping of mac80211's queues (priorities) to b43 PIO queues. */
0287 static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev,
0288                             u8 queue_prio)
0289 {
0290     struct b43_pio_txqueue *q;
0291 
0292     if (dev->qos_enabled) {
0293         /* 0 = highest priority */
0294         switch (queue_prio) {
0295         default:
0296             B43_WARN_ON(1);
0297             fallthrough;
0298         case 0:
0299             q = dev->pio.tx_queue_AC_VO;
0300             break;
0301         case 1:
0302             q = dev->pio.tx_queue_AC_VI;
0303             break;
0304         case 2:
0305             q = dev->pio.tx_queue_AC_BE;
0306             break;
0307         case 3:
0308             q = dev->pio.tx_queue_AC_BK;
0309             break;
0310         }
0311     } else
0312         q = dev->pio.tx_queue_AC_BE;
0313 
0314     return q;
0315 }
0316 
0317 static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
0318                 u16 ctl,
0319                 const void *_data,
0320                 unsigned int data_len)
0321 {
0322     struct b43_wldev *dev = q->dev;
0323     struct b43_wl *wl = dev->wl;
0324     const u8 *data = _data;
0325 
0326     ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
0327     b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
0328 
0329     b43_block_write(dev, data, (data_len & ~1),
0330             q->mmio_base + B43_PIO_TXDATA,
0331             sizeof(u16));
0332     if (data_len & 1) {
0333         u8 *tail = wl->pio_tailspace;
0334         BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
0335 
0336         /* Write the last byte. */
0337         ctl &= ~B43_PIO_TXCTL_WRITEHI;
0338         b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
0339         tail[0] = data[data_len - 1];
0340         tail[1] = 0;
0341         b43_block_write(dev, tail, 2,
0342                 q->mmio_base + B43_PIO_TXDATA,
0343                 sizeof(u16));
0344     }
0345 
0346     return ctl;
0347 }
0348 
0349 static void pio_tx_frame_2byte_queue(struct b43_pio_txpacket *pack,
0350                      const u8 *hdr, unsigned int hdrlen)
0351 {
0352     struct b43_pio_txqueue *q = pack->queue;
0353     const char *frame = pack->skb->data;
0354     unsigned int frame_len = pack->skb->len;
0355     u16 ctl;
0356 
0357     ctl = b43_piotx_read16(q, B43_PIO_TXCTL);
0358     ctl |= B43_PIO_TXCTL_FREADY;
0359     ctl &= ~B43_PIO_TXCTL_EOF;
0360 
0361     /* Transfer the header data. */
0362     ctl = tx_write_2byte_queue(q, ctl, hdr, hdrlen);
0363     /* Transfer the frame data. */
0364     ctl = tx_write_2byte_queue(q, ctl, frame, frame_len);
0365 
0366     ctl |= B43_PIO_TXCTL_EOF;
0367     b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
0368 }
0369 
0370 static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
0371                 u32 ctl,
0372                 const void *_data,
0373                 unsigned int data_len)
0374 {
0375     struct b43_wldev *dev = q->dev;
0376     struct b43_wl *wl = dev->wl;
0377     const u8 *data = _data;
0378 
0379     ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 |
0380            B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31;
0381     b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
0382 
0383     b43_block_write(dev, data, (data_len & ~3),
0384             q->mmio_base + B43_PIO8_TXDATA,
0385             sizeof(u32));
0386     if (data_len & 3) {
0387         u8 *tail = wl->pio_tailspace;
0388         BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
0389 
0390         memset(tail, 0, 4);
0391         /* Write the last few bytes. */
0392         ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
0393              B43_PIO8_TXCTL_24_31);
0394         switch (data_len & 3) {
0395         case 3:
0396             ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
0397             tail[0] = data[data_len - 3];
0398             tail[1] = data[data_len - 2];
0399             tail[2] = data[data_len - 1];
0400             break;
0401         case 2:
0402             ctl |= B43_PIO8_TXCTL_8_15;
0403             tail[0] = data[data_len - 2];
0404             tail[1] = data[data_len - 1];
0405             break;
0406         case 1:
0407             tail[0] = data[data_len - 1];
0408             break;
0409         }
0410         b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
0411         b43_block_write(dev, tail, 4,
0412                 q->mmio_base + B43_PIO8_TXDATA,
0413                 sizeof(u32));
0414     }
0415 
0416     return ctl;
0417 }
0418 
0419 static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
0420                      const u8 *hdr, unsigned int hdrlen)
0421 {
0422     struct b43_pio_txqueue *q = pack->queue;
0423     const char *frame = pack->skb->data;
0424     unsigned int frame_len = pack->skb->len;
0425     u32 ctl;
0426 
0427     ctl = b43_piotx_read32(q, B43_PIO8_TXCTL);
0428     ctl |= B43_PIO8_TXCTL_FREADY;
0429     ctl &= ~B43_PIO8_TXCTL_EOF;
0430 
0431     /* Transfer the header data. */
0432     ctl = tx_write_4byte_queue(q, ctl, hdr, hdrlen);
0433     /* Transfer the frame data. */
0434     ctl = tx_write_4byte_queue(q, ctl, frame, frame_len);
0435 
0436     ctl |= B43_PIO8_TXCTL_EOF;
0437     b43_piotx_write32(q, B43_PIO_TXCTL, ctl);
0438 }
0439 
0440 static int pio_tx_frame(struct b43_pio_txqueue *q,
0441             struct sk_buff *skb)
0442 {
0443     struct b43_wldev *dev = q->dev;
0444     struct b43_wl *wl = dev->wl;
0445     struct b43_pio_txpacket *pack;
0446     u16 cookie;
0447     int err;
0448     unsigned int hdrlen;
0449     struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
0450     struct b43_txhdr *txhdr = (struct b43_txhdr *)wl->pio_scratchspace;
0451 
0452     B43_WARN_ON(list_empty(&q->packets_list));
0453     pack = list_entry(q->packets_list.next,
0454               struct b43_pio_txpacket, list);
0455 
0456     cookie = generate_cookie(q, pack);
0457     hdrlen = b43_txhdr_size(dev);
0458     BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(struct b43_txhdr));
0459     B43_WARN_ON(sizeof(wl->pio_scratchspace) < hdrlen);
0460     err = b43_generate_txhdr(dev, (u8 *)txhdr, skb,
0461                  info, cookie);
0462     if (err)
0463         return err;
0464 
0465     if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
0466         /* Tell the firmware about the cookie of the last
0467          * mcast frame, so it can clear the more-data bit in it. */
0468         b43_shm_write16(dev, B43_SHM_SHARED,
0469                 B43_SHM_SH_MCASTCOOKIE, cookie);
0470     }
0471 
0472     pack->skb = skb;
0473     if (q->rev >= 8)
0474         pio_tx_frame_4byte_queue(pack, (const u8 *)txhdr, hdrlen);
0475     else
0476         pio_tx_frame_2byte_queue(pack, (const u8 *)txhdr, hdrlen);
0477 
0478     /* Remove it from the list of available packet slots.
0479      * It will be put back when we receive the status report. */
0480     list_del(&pack->list);
0481 
0482     /* Update the queue statistics. */
0483     q->buffer_used += roundup(skb->len + hdrlen, 4);
0484     q->free_packet_slots -= 1;
0485 
0486     return 0;
0487 }
0488 
0489 int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
0490 {
0491     struct b43_pio_txqueue *q;
0492     struct ieee80211_hdr *hdr;
0493     unsigned int hdrlen, total_len;
0494     int err = 0;
0495     struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
0496 
0497     hdr = (struct ieee80211_hdr *)skb->data;
0498 
0499     if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
0500         /* The multicast queue will be sent after the DTIM. */
0501         q = dev->pio.tx_queue_mcast;
0502         /* Set the frame More-Data bit. Ucode will clear it
0503          * for us on the last frame. */
0504         hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
0505     } else {
0506         /* Decide by priority where to put this frame. */
0507         q = select_queue_by_priority(dev, skb_get_queue_mapping(skb));
0508     }
0509 
0510     hdrlen = b43_txhdr_size(dev);
0511     total_len = roundup(skb->len + hdrlen, 4);
0512 
0513     if (unlikely(total_len > q->buffer_size)) {
0514         err = -ENOBUFS;
0515         b43dbg(dev->wl, "PIO: TX packet longer than queue.\n");
0516         goto out;
0517     }
0518     if (unlikely(q->free_packet_slots == 0)) {
0519         err = -ENOBUFS;
0520         b43warn(dev->wl, "PIO: TX packet overflow.\n");
0521         goto out;
0522     }
0523     B43_WARN_ON(q->buffer_used > q->buffer_size);
0524 
0525     if (total_len > (q->buffer_size - q->buffer_used)) {
0526         /* Not enough memory on the queue. */
0527         err = -EBUSY;
0528         ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
0529         q->stopped = true;
0530         goto out;
0531     }
0532 
0533     /* Assign the queue number to the ring (if not already done before)
0534      * so TX status handling can use it. The mac80211-queue to b43-queue
0535      * mapping is static, so we don't need to store it per frame. */
0536     q->queue_prio = skb_get_queue_mapping(skb);
0537 
0538     err = pio_tx_frame(q, skb);
0539     if (unlikely(err == -ENOKEY)) {
0540         /* Drop this packet, as we don't have the encryption key
0541          * anymore and must not transmit it unencrypted. */
0542         ieee80211_free_txskb(dev->wl->hw, skb);
0543         err = 0;
0544         goto out;
0545     }
0546     if (unlikely(err)) {
0547         b43err(dev->wl, "PIO transmission failure\n");
0548         goto out;
0549     }
0550 
0551     B43_WARN_ON(q->buffer_used > q->buffer_size);
0552     if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
0553         (q->free_packet_slots == 0)) {
0554         /* The queue is full. */
0555         ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
0556         q->stopped = true;
0557     }
0558 
0559 out:
0560     return err;
0561 }
0562 
0563 void b43_pio_handle_txstatus(struct b43_wldev *dev,
0564                  const struct b43_txstatus *status)
0565 {
0566     struct b43_pio_txqueue *q;
0567     struct b43_pio_txpacket *pack = NULL;
0568     unsigned int total_len;
0569     struct ieee80211_tx_info *info;
0570 
0571     q = parse_cookie(dev, status->cookie, &pack);
0572     if (unlikely(!q))
0573         return;
0574     B43_WARN_ON(!pack);
0575 
0576     info = IEEE80211_SKB_CB(pack->skb);
0577 
0578     b43_fill_txstatus_report(dev, info, status);
0579 
0580     total_len = pack->skb->len + b43_txhdr_size(dev);
0581     total_len = roundup(total_len, 4);
0582     q->buffer_used -= total_len;
0583     q->free_packet_slots += 1;
0584 
0585     ieee80211_tx_status(dev->wl->hw, pack->skb);
0586     pack->skb = NULL;
0587     list_add(&pack->list, &q->packets_list);
0588 
0589     if (q->stopped) {
0590         ieee80211_wake_queue(dev->wl->hw, q->queue_prio);
0591         q->stopped = false;
0592     }
0593 }
0594 
0595 /* Returns whether we should fetch another frame. */
0596 static bool pio_rx_frame(struct b43_pio_rxqueue *q)
0597 {
0598     struct b43_wldev *dev = q->dev;
0599     struct b43_wl *wl = dev->wl;
0600     u16 len;
0601     u32 macstat = 0;
0602     unsigned int i, padding;
0603     struct sk_buff *skb;
0604     const char *err_msg = NULL;
0605     struct b43_rxhdr_fw4 *rxhdr =
0606         (struct b43_rxhdr_fw4 *)wl->pio_scratchspace;
0607     size_t rxhdr_size = sizeof(*rxhdr);
0608 
0609     BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(*rxhdr));
0610     switch (dev->fw.hdr_format) {
0611     case B43_FW_HDR_410:
0612     case B43_FW_HDR_351:
0613         rxhdr_size -= sizeof(rxhdr->format_598) -
0614             sizeof(rxhdr->format_351);
0615         break;
0616     case B43_FW_HDR_598:
0617         break;
0618     }
0619     memset(rxhdr, 0, rxhdr_size);
0620 
0621     /* Check if we have data and wait for it to get ready. */
0622     if (q->rev >= 8) {
0623         u32 ctl;
0624 
0625         ctl = b43_piorx_read32(q, B43_PIO8_RXCTL);
0626         if (!(ctl & B43_PIO8_RXCTL_FRAMERDY))
0627             return false;
0628         b43_piorx_write32(q, B43_PIO8_RXCTL,
0629                   B43_PIO8_RXCTL_FRAMERDY);
0630         for (i = 0; i < 10; i++) {
0631             ctl = b43_piorx_read32(q, B43_PIO8_RXCTL);
0632             if (ctl & B43_PIO8_RXCTL_DATARDY)
0633                 goto data_ready;
0634             udelay(10);
0635         }
0636     } else {
0637         u16 ctl;
0638 
0639         ctl = b43_piorx_read16(q, B43_PIO_RXCTL);
0640         if (!(ctl & B43_PIO_RXCTL_FRAMERDY))
0641             return false;
0642         b43_piorx_write16(q, B43_PIO_RXCTL,
0643                   B43_PIO_RXCTL_FRAMERDY);
0644         for (i = 0; i < 10; i++) {
0645             ctl = b43_piorx_read16(q, B43_PIO_RXCTL);
0646             if (ctl & B43_PIO_RXCTL_DATARDY)
0647                 goto data_ready;
0648             udelay(10);
0649         }
0650     }
0651     b43dbg(q->dev->wl, "PIO RX timed out\n");
0652     return true;
0653 data_ready:
0654 
0655     /* Get the preamble (RX header) */
0656     if (q->rev >= 8) {
0657         b43_block_read(dev, rxhdr, rxhdr_size,
0658                    q->mmio_base + B43_PIO8_RXDATA,
0659                    sizeof(u32));
0660     } else {
0661         b43_block_read(dev, rxhdr, rxhdr_size,
0662                    q->mmio_base + B43_PIO_RXDATA,
0663                    sizeof(u16));
0664     }
0665     /* Sanity checks. */
0666     len = le16_to_cpu(rxhdr->frame_len);
0667     if (unlikely(len > 0x700)) {
0668         err_msg = "len > 0x700";
0669         goto rx_error;
0670     }
0671     if (unlikely(len == 0)) {
0672         err_msg = "len == 0";
0673         goto rx_error;
0674     }
0675 
0676     switch (dev->fw.hdr_format) {
0677     case B43_FW_HDR_598:
0678         macstat = le32_to_cpu(rxhdr->format_598.mac_status);
0679         break;
0680     case B43_FW_HDR_410:
0681     case B43_FW_HDR_351:
0682         macstat = le32_to_cpu(rxhdr->format_351.mac_status);
0683         break;
0684     }
0685     if (macstat & B43_RX_MAC_FCSERR) {
0686         if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
0687             /* Drop frames with failed FCS. */
0688             err_msg = "Frame FCS error";
0689             goto rx_error;
0690         }
0691     }
0692 
0693     /* We always pad 2 bytes, as that's what upstream code expects
0694      * due to the RX-header being 30 bytes. In case the frame is
0695      * unaligned, we pad another 2 bytes. */
0696     padding = (macstat & B43_RX_MAC_PADDING) ? 2 : 0;
0697     skb = dev_alloc_skb(len + padding + 2);
0698     if (unlikely(!skb)) {
0699         err_msg = "Out of memory";
0700         goto rx_error;
0701     }
0702     skb_reserve(skb, 2);
0703     skb_put(skb, len + padding);
0704     if (q->rev >= 8) {
0705         b43_block_read(dev, skb->data + padding, (len & ~3),
0706                    q->mmio_base + B43_PIO8_RXDATA,
0707                    sizeof(u32));
0708         if (len & 3) {
0709             u8 *tail = wl->pio_tailspace;
0710             BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
0711 
0712             /* Read the last few bytes. */
0713             b43_block_read(dev, tail, 4,
0714                        q->mmio_base + B43_PIO8_RXDATA,
0715                        sizeof(u32));
0716             switch (len & 3) {
0717             case 3:
0718                 skb->data[len + padding - 3] = tail[0];
0719                 skb->data[len + padding - 2] = tail[1];
0720                 skb->data[len + padding - 1] = tail[2];
0721                 break;
0722             case 2:
0723                 skb->data[len + padding - 2] = tail[0];
0724                 skb->data[len + padding - 1] = tail[1];
0725                 break;
0726             case 1:
0727                 skb->data[len + padding - 1] = tail[0];
0728                 break;
0729             }
0730         }
0731     } else {
0732         b43_block_read(dev, skb->data + padding, (len & ~1),
0733                    q->mmio_base + B43_PIO_RXDATA,
0734                    sizeof(u16));
0735         if (len & 1) {
0736             u8 *tail = wl->pio_tailspace;
0737             BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
0738 
0739             /* Read the last byte. */
0740             b43_block_read(dev, tail, 2,
0741                        q->mmio_base + B43_PIO_RXDATA,
0742                        sizeof(u16));
0743             skb->data[len + padding - 1] = tail[0];
0744         }
0745     }
0746 
0747     b43_rx(q->dev, skb, rxhdr);
0748 
0749     return true;
0750 
0751 rx_error:
0752     if (err_msg)
0753         b43dbg(q->dev->wl, "PIO RX error: %s\n", err_msg);
0754     if (q->rev >= 8)
0755         b43_piorx_write32(q, B43_PIO8_RXCTL, B43_PIO8_RXCTL_DATARDY);
0756     else
0757         b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY);
0758 
0759     return true;
0760 }
0761 
0762 void b43_pio_rx(struct b43_pio_rxqueue *q)
0763 {
0764     unsigned int count = 0;
0765     bool stop;
0766 
0767     while (1) {
0768         stop = !pio_rx_frame(q);
0769         if (stop)
0770             break;
0771         cond_resched();
0772         if (WARN_ON_ONCE(++count > 10000))
0773             break;
0774     }
0775 }
0776 
0777 static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
0778 {
0779     if (q->rev >= 8) {
0780         b43_piotx_write32(q, B43_PIO8_TXCTL,
0781                   b43_piotx_read32(q, B43_PIO8_TXCTL)
0782                   | B43_PIO8_TXCTL_SUSPREQ);
0783     } else {
0784         b43_piotx_write16(q, B43_PIO_TXCTL,
0785                   b43_piotx_read16(q, B43_PIO_TXCTL)
0786                   | B43_PIO_TXCTL_SUSPREQ);
0787     }
0788 }
0789 
0790 static void b43_pio_tx_resume_queue(struct b43_pio_txqueue *q)
0791 {
0792     if (q->rev >= 8) {
0793         b43_piotx_write32(q, B43_PIO8_TXCTL,
0794                   b43_piotx_read32(q, B43_PIO8_TXCTL)
0795                   & ~B43_PIO8_TXCTL_SUSPREQ);
0796     } else {
0797         b43_piotx_write16(q, B43_PIO_TXCTL,
0798                   b43_piotx_read16(q, B43_PIO_TXCTL)
0799                   & ~B43_PIO_TXCTL_SUSPREQ);
0800     }
0801 }
0802 
0803 void b43_pio_tx_suspend(struct b43_wldev *dev)
0804 {
0805     b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
0806     b43_pio_tx_suspend_queue(dev->pio.tx_queue_AC_BK);
0807     b43_pio_tx_suspend_queue(dev->pio.tx_queue_AC_BE);
0808     b43_pio_tx_suspend_queue(dev->pio.tx_queue_AC_VI);
0809     b43_pio_tx_suspend_queue(dev->pio.tx_queue_AC_VO);
0810     b43_pio_tx_suspend_queue(dev->pio.tx_queue_mcast);
0811 }
0812 
0813 void b43_pio_tx_resume(struct b43_wldev *dev)
0814 {
0815     b43_pio_tx_resume_queue(dev->pio.tx_queue_mcast);
0816     b43_pio_tx_resume_queue(dev->pio.tx_queue_AC_VO);
0817     b43_pio_tx_resume_queue(dev->pio.tx_queue_AC_VI);
0818     b43_pio_tx_resume_queue(dev->pio.tx_queue_AC_BE);
0819     b43_pio_tx_resume_queue(dev->pio.tx_queue_AC_BK);
0820     b43_power_saving_ctl_bits(dev, 0);
0821 }