aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a4e6a59ccac8..355f28a2f7f5 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -47,6 +47,7 @@
47#include "debugfs.h" 47#include "debugfs.h"
48#include "phy.h" 48#include "phy.h"
49#include "dma.h" 49#include "dma.h"
50#include "pio.h"
50#include "sysfs.h" 51#include "sysfs.h"
51#include "xmit.h" 52#include "xmit.h"
52#include "lo.h" 53#include "lo.h"
@@ -1593,8 +1594,12 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
1593 handle_irq_noise(dev); 1594 handle_irq_noise(dev);
1594 1595
1595 /* Check the DMA reason registers for received data. */ 1596 /* Check the DMA reason registers for received data. */
1596 if (dma_reason[0] & B43_DMAIRQ_RX_DONE) 1597 if (dma_reason[0] & B43_DMAIRQ_RX_DONE) {
1597 b43_dma_rx(dev->dma.rx_ring); 1598 if (b43_using_pio_transfers(dev))
1599 b43_pio_rx(dev->pio.rx_queue);
1600 else
1601 b43_dma_rx(dev->dma.rx_ring);
1602 }
1598 B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE); 1603 B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE);
1599 B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE); 1604 B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE);
1600 B43_WARN_ON(dma_reason[3] & B43_DMAIRQ_RX_DONE); 1605 B43_WARN_ON(dma_reason[3] & B43_DMAIRQ_RX_DONE);
@@ -2698,12 +2703,21 @@ static int b43_op_tx(struct ieee80211_hw *hw,
2698 struct b43_wldev *dev = wl->current_dev; 2703 struct b43_wldev *dev = wl->current_dev;
2699 int err = -ENODEV; 2704 int err = -ENODEV;
2700 2705
2706 if (unlikely(skb->len < 2 + 2 + 6)) {
2707 /* Too short, this can't be a valid frame. */
2708 return -EINVAL;
2709 }
2710 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
2711
2701 if (unlikely(!dev)) 2712 if (unlikely(!dev))
2702 goto out; 2713 goto out;
2703 if (unlikely(b43_status(dev) < B43_STAT_STARTED)) 2714 if (unlikely(b43_status(dev) < B43_STAT_STARTED))
2704 goto out; 2715 goto out;
2705 /* DMA-TX is done without a global lock. */ 2716 /* TX is done without a global lock. */
2706 err = b43_dma_tx(dev, skb, ctl); 2717 if (b43_using_pio_transfers(dev))
2718 err = b43_pio_tx(dev, skb, ctl);
2719 else
2720 err = b43_dma_tx(dev, skb, ctl);
2707out: 2721out:
2708 if (unlikely(err)) 2722 if (unlikely(err))
2709 return NETDEV_TX_BUSY; 2723 return NETDEV_TX_BUSY;
@@ -2897,7 +2911,10 @@ static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
2897 goto out; 2911 goto out;
2898 spin_lock_irqsave(&wl->irq_lock, flags); 2912 spin_lock_irqsave(&wl->irq_lock, flags);
2899 if (likely(b43_status(dev) >= B43_STAT_STARTED)) { 2913 if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
2900 b43_dma_get_tx_stats(dev, stats); 2914 if (b43_using_pio_transfers(dev))
2915 b43_pio_get_tx_stats(dev, stats);
2916 else
2917 b43_dma_get_tx_stats(dev, stats);
2901 err = 0; 2918 err = 0;
2902 } 2919 }
2903 spin_unlock_irqrestore(&wl->irq_lock, flags); 2920 spin_unlock_irqrestore(&wl->irq_lock, flags);
@@ -3366,6 +3383,7 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
3366 3383
3367 b43_set_status(dev, B43_STAT_INITIALIZED); 3384 b43_set_status(dev, B43_STAT_INITIALIZED);
3368 3385
3386 b43_pio_stop(dev);
3369 mutex_unlock(&wl->mutex); 3387 mutex_unlock(&wl->mutex);
3370 /* Must unlock as it would otherwise deadlock. No races here. 3388 /* Must unlock as it would otherwise deadlock. No races here.
3371 * Cancel the possibly running self-rearming periodic work. */ 3389 * Cancel the possibly running self-rearming periodic work. */
@@ -3683,6 +3701,7 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
3683 b43_rng_exit(dev->wl, false); 3701 b43_rng_exit(dev->wl, false);
3684 } 3702 }
3685 b43_dma_free(dev); 3703 b43_dma_free(dev);
3704 b43_pio_free(dev);
3686 b43_chip_exit(dev); 3705 b43_chip_exit(dev);
3687 b43_radio_turn_off(dev, 1); 3706 b43_radio_turn_off(dev, 1);
3688 b43_switch_analog(dev, 0); 3707 b43_switch_analog(dev, 0);
@@ -3780,7 +3799,13 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
3780 /* Maximum Contention Window */ 3799 /* Maximum Contention Window */
3781 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 3800 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
3782 3801
3783 err = b43_dma_init(dev); 3802 if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || B43_FORCE_PIO) {
3803 dev->__using_pio_transfers = 1;
3804 err = b43_pio_init(dev);
3805 } else {
3806 dev->__using_pio_transfers = 0;
3807 err = b43_dma_init(dev);
3808 }
3784 if (err) 3809 if (err)
3785 goto err_chip_exit; 3810 goto err_chip_exit;
3786 b43_qos_init(dev); 3811 b43_qos_init(dev);