diff options
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 37 |
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); | ||
2707 | out: | 2721 | out: |
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); |