b43: Add PIO support for PCMCIA devices
[deliverable/linux.git] / drivers / net / wireless / b43 / dma.c
index 70db0570adc5efe76fdae697a99e7dd81d73d118..f1b983cb9c1fb2891507bb2537c49a115ecf7ef4 100644 (file)
@@ -550,7 +550,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
                               struct b43_dmadesc_meta *meta, gfp_t gfp_flags)
 {
        struct b43_rxhdr_fw4 *rxhdr;
-       struct b43_hwtxstatus *txstat;
        dma_addr_t dmaaddr;
        struct sk_buff *skb;
 
@@ -586,8 +585,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
 
        rxhdr = (struct b43_rxhdr_fw4 *)(skb->data);
        rxhdr->frame_len = 0;
-       txstat = (struct b43_hwtxstatus *)(skb->data);
-       txstat->cookie = 0;
 
        return 0;
 }
@@ -776,6 +773,18 @@ static u64 supported_dma_mask(struct b43_wldev *dev)
        return DMA_30BIT_MASK;
 }
 
+static enum b43_dmatype dma_mask_to_engine_type(u64 dmamask)
+{
+       if (dmamask == DMA_30BIT_MASK)
+               return B43_DMA_30BIT;
+       if (dmamask == DMA_32BIT_MASK)
+               return B43_DMA_32BIT;
+       if (dmamask == DMA_64BIT_MASK)
+               return B43_DMA_64BIT;
+       B43_WARN_ON(1);
+       return B43_DMA_30BIT;
+}
+
 /* Main initialization function. */
 static
 struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
@@ -956,7 +965,11 @@ static void b43_destroy_dmaring(struct b43_dmaring *ring,
 
 void b43_dma_free(struct b43_wldev *dev)
 {
-       struct b43_dma *dma = &dev->dma;
+       struct b43_dma *dma;
+
+       if (b43_using_pio_transfers(dev))
+               return;
+       dma = &dev->dma;
 
        destroy_ring(dma, rx_ring);
        destroy_ring(dma, tx_ring_AC_BK);
@@ -974,19 +987,7 @@ int b43_dma_init(struct b43_wldev *dev)
        enum b43_dmatype type;
 
        dmamask = supported_dma_mask(dev);
-       switch (dmamask) {
-       default:
-               B43_WARN_ON(1);
-       case DMA_30BIT_MASK:
-               type = B43_DMA_30BIT;
-               break;
-       case DMA_32BIT_MASK:
-               type = B43_DMA_32BIT;
-               break;
-       case DMA_64BIT_MASK:
-               type = B43_DMA_64BIT;
-               break;
-       }
+       type = dma_mask_to_engine_type(dmamask);
        err = ssb_dma_set_mask(dev->dev, dmamask);
        if (err) {
                b43err(dev->wl, "The machine/kernel does not support "
@@ -1113,7 +1114,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
        size_t hdrsize = b43_txhdr_size(ring->dev);
 
 #define SLOTS_PER_PACKET  2
-       B43_WARN_ON(skb_shinfo(skb)->nr_frags);
 
        old_top_slot = ring->current_slot;
        old_used_slots = ring->used_slots;
@@ -1257,11 +1257,6 @@ int b43_dma_tx(struct b43_wldev *dev,
        int err = 0;
        unsigned long flags;
 
-       if (unlikely(skb->len < 2 + 2 + 6)) {
-               /* Too short, this can't be a valid frame. */
-               return -EINVAL;
-       }
-
        hdr = (struct ieee80211_hdr *)skb->data;
        if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
                /* The multicast ring will be sent after the DTIM */
@@ -1319,38 +1314,6 @@ out_unlock:
        return err;
 }
 
-static void b43_fill_txstatus_report(struct b43_dmaring *ring,
-                                   struct ieee80211_tx_status *report,
-                                   const struct b43_txstatus *status)
-{
-       bool frame_failed = 0;
-
-       if (status->acked) {
-               /* The frame was ACKed. */
-               report->flags |= IEEE80211_TX_STATUS_ACK;
-       } else {
-               /* The frame was not ACKed... */
-               if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
-                       /* ...but we expected an ACK. */
-                       frame_failed = 1;
-                       report->excessive_retries = 1;
-               }
-       }
-       if (status->frame_count == 0) {
-               /* The frame was not transmitted at all. */
-               report->retry_count = 0;
-       } else {
-               report->retry_count = status->frame_count - 1;
-#ifdef CONFIG_B43_DEBUG
-               if (frame_failed)
-                       ring->nr_failed_tx_packets++;
-               else
-                       ring->nr_succeed_tx_packets++;
-               ring->nr_total_packet_tries += status->frame_count;
-#endif /* DEBUG */
-       }
-}
-
 /* Called with IRQs disabled. */
 void b43_dma_handle_txstatus(struct b43_wldev *dev,
                             const struct b43_txstatus *status)
@@ -1360,6 +1323,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
        struct b43_dmadesc_generic *desc;
        struct b43_dmadesc_meta *meta;
        int slot;
+       bool frame_succeed;
 
        ring = parse_cookie(dev, status->cookie, &slot);
        if (unlikely(!ring))
@@ -1386,7 +1350,15 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                         * status of the transmission.
                         * Some fields of txstat are already filled in dma_tx().
                         */
-                       b43_fill_txstatus_report(ring, &(meta->txstat), status);
+                       frame_succeed = b43_fill_txstatus_report(
+                                               &(meta->txstat), status);
+#ifdef CONFIG_B43_DEBUG
+                       if (frame_succeed)
+                               ring->nr_succeed_tx_packets++;
+                       else
+                               ring->nr_failed_tx_packets++;
+                       ring->nr_total_packet_tries += status->frame_count;
+#endif /* DEBUG */
                        ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
                                                    &(meta->txstat));
                        /* skb is freed by ieee80211_tx_status_irqsafe() */
@@ -1573,3 +1545,39 @@ void b43_dma_tx_resume(struct b43_wldev *dev)
        b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BK);
        b43_power_saving_ctl_bits(dev, 0);
 }
+
+#ifdef CONFIG_B43_PIO
+static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type,
+                          u16 mmio_base, bool enable)
+{
+       u32 ctl;
+
+       if (type == B43_DMA_64BIT) {
+               ctl = b43_read32(dev, mmio_base + B43_DMA64_RXCTL);
+               ctl &= ~B43_DMA64_RXDIRECTFIFO;
+               if (enable)
+                       ctl |= B43_DMA64_RXDIRECTFIFO;
+               b43_write32(dev, mmio_base + B43_DMA64_RXCTL, ctl);
+       } else {
+               ctl = b43_read32(dev, mmio_base + B43_DMA32_RXCTL);
+               ctl &= ~B43_DMA32_RXDIRECTFIFO;
+               if (enable)
+                       ctl |= B43_DMA32_RXDIRECTFIFO;
+               b43_write32(dev, mmio_base + B43_DMA32_RXCTL, ctl);
+       }
+}
+
+/* Enable/Disable Direct FIFO Receive Mode (PIO) on a RX engine.
+ * This is called from PIO code, so DMA structures are not available. */
+void b43_dma_direct_fifo_rx(struct b43_wldev *dev,
+                           unsigned int engine_index, bool enable)
+{
+       enum b43_dmatype type;
+       u16 mmio_base;
+
+       type = dma_mask_to_engine_type(supported_dma_mask(dev));
+
+       mmio_base = b43_dmacontroller_base(type, engine_index);
+       direct_fifo_rx(dev, type, mmio_base, enable);
+}
+#endif /* CONFIG_B43_PIO */
This page took 0.030651 seconds and 5 git commands to generate.