diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy')
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/xmit.c | 4 |
3 files changed, 29 insertions, 17 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 2f90fb9f536..86640341581 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -1366,15 +1366,25 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); spin_lock_irqsave(&ring->lock, flags); B43legacy_WARN_ON(!ring->tx); - if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) { - b43legacywarn(dev->wl, "DMA queue overflow\n"); + + if (unlikely(ring->stopped)) { + /* We get here only because of a bug in mac80211. + * Because of a race, one packet may be queued after + * the queue is stopped, thus we got called when we shouldn't. + * For now, just refuse the transmit. */ + if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) + b43legacyerr(dev->wl, "Packet after queue stopped\n"); + err = -ENOSPC; + goto out_unlock; + } + + if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) { + /* If we get here, we have a real error with the queue + * full, but queues not stopped. */ + b43legacyerr(dev->wl, "DMA queue overflow\n"); err = -ENOSPC; goto out_unlock; } - /* Check if the queue was stopped in mac80211, - * but we got called nevertheless. - * That would be a mac80211 bug. */ - B43legacy_BUG_ON(ring->stopped); err = dma_tx_fragment(ring, skb); if (unlikely(err == -ENOKEY)) { diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c4973c1942b..1d9223b3d4c 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1252,7 +1252,7 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl) wl->current_beacon = beacon; wl->beacon0_uploaded = 0; wl->beacon1_uploaded = 0; - queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); + ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger); } static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, @@ -2300,7 +2300,7 @@ out_requeue: delay = msecs_to_jiffies(50); else delay = round_jiffies_relative(HZ * 15); - queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay); + ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay); out: mutex_unlock(&wl->mutex); } @@ -2311,7 +2311,7 @@ static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev) dev->periodic_state = 0; INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler); - queue_delayed_work(dev->wl->hw->workqueue, work, 0); + ieee80211_queue_delayed_work(dev->wl->hw, work, 0); } /* Validate access to the chip (SHM) */ @@ -2836,9 +2836,7 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw, static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, unsigned int changed, - unsigned int *fflags, - int mc_count, - struct dev_addr_list *mc_list) + unsigned int *fflags,u64 multicast) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -3108,16 +3106,20 @@ static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev) bus->pcicore.dev->id.revision <= 5) { /* IMCFGLO timeouts workaround. */ tmp = ssb_read32(dev->dev, SSB_IMCFGLO); - tmp &= ~SSB_IMCFGLO_REQTO; - tmp &= ~SSB_IMCFGLO_SERTO; switch (bus->bustype) { case SSB_BUSTYPE_PCI: case SSB_BUSTYPE_PCMCIA: + tmp &= ~SSB_IMCFGLO_REQTO; + tmp &= ~SSB_IMCFGLO_SERTO; tmp |= 0x32; break; case SSB_BUSTYPE_SSB: + tmp &= ~SSB_IMCFGLO_REQTO; + tmp &= ~SSB_IMCFGLO_SERTO; tmp |= 0x53; break; + default: + break; } ssb_write32(dev->dev, SSB_IMCFGLO, tmp); } @@ -3885,7 +3887,7 @@ void b43legacy_controller_restart(struct b43legacy_wldev *dev, if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) return; b43legacyinfo(dev->wl, "Controller RESET (%s) ...\n", reason); - queue_work(dev->wl->hw->workqueue, &dev->restart_work); + ieee80211_queue_work(dev->wl->hw, &dev->restart_work); } #ifdef CONFIG_PM diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index b8e39dd06e9..103f3c9e7f5 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -590,8 +590,8 @@ void b43legacy_rx(struct b43legacy_wldev *dev, chanstat); } - dev->stats.last_rx = jiffies; - ieee80211_rx_irqsafe(dev->wl->hw, skb, &status); + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); + ieee80211_rx_irqsafe(dev->wl->hw, skb); return; drop: |