Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/b43legacy/dma.c
This commit is contained in:
@@ -727,7 +727,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
|
||||
} else
|
||||
B43legacy_WARN_ON(1);
|
||||
}
|
||||
spin_lock_init(&ring->lock);
|
||||
#ifdef CONFIG_B43LEGACY_DEBUG
|
||||
ring->last_injected_overflow = jiffies;
|
||||
#endif
|
||||
@@ -1144,10 +1143,8 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
|
||||
{
|
||||
struct b43legacy_dmaring *ring;
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
|
||||
ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
|
||||
spin_lock_irqsave(&ring->lock, flags);
|
||||
B43legacy_WARN_ON(!ring->tx);
|
||||
|
||||
if (unlikely(ring->stopped)) {
|
||||
@@ -1157,16 +1154,14 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
|
||||
* 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;
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
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;
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
/* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
|
||||
@@ -1176,25 +1171,23 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
|
||||
/* Drop this packet, as we don't have the encryption key
|
||||
* anymore and must not transmit it unencrypted. */
|
||||
dev_kfree_skb_any(skb);
|
||||
err = 0;
|
||||
goto out_unlock;
|
||||
return 0;
|
||||
}
|
||||
if (unlikely(err)) {
|
||||
b43legacyerr(dev->wl, "DMA tx mapping failure\n");
|
||||
goto out_unlock;
|
||||
return err;
|
||||
}
|
||||
if ((free_slots(ring) < SLOTS_PER_PACKET) ||
|
||||
should_inject_overflow(ring)) {
|
||||
/* This TX ring is full. */
|
||||
ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring));
|
||||
unsigned int skb_mapping = skb_get_queue_mapping(skb);
|
||||
ieee80211_stop_queue(dev->wl->hw, skb_mapping);
|
||||
dev->wl->tx_queue_stopped[skb_mapping] = 1;
|
||||
ring->stopped = true;
|
||||
if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
|
||||
b43legacydbg(dev->wl, "Stopped TX ring %d\n",
|
||||
ring->index);
|
||||
}
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&ring->lock, flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1205,14 +1198,29 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
|
||||
struct b43legacy_dmadesc_meta *meta;
|
||||
int retry_limit;
|
||||
int slot;
|
||||
int firstused;
|
||||
|
||||
ring = parse_cookie(dev, status->cookie, &slot);
|
||||
if (unlikely(!ring))
|
||||
return;
|
||||
B43legacy_WARN_ON(!irqs_disabled());
|
||||
spin_lock(&ring->lock);
|
||||
|
||||
B43legacy_WARN_ON(!ring->tx);
|
||||
|
||||
/* Sanity check: TX packets are processed in-order on one ring.
|
||||
* Check if the slot deduced from the cookie really is the first
|
||||
* used slot. */
|
||||
firstused = ring->current_slot - ring->used_slots + 1;
|
||||
if (firstused < 0)
|
||||
firstused = ring->nr_slots + firstused;
|
||||
if (unlikely(slot != firstused)) {
|
||||
/* This possibly is a firmware bug and will result in
|
||||
* malfunction, memory leaks and/or stall of DMA functionality.
|
||||
*/
|
||||
b43legacydbg(dev->wl, "Out of order TX status report on DMA "
|
||||
"ring %d. Expected %d, but got %d\n",
|
||||
ring->index, firstused, slot);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
|
||||
op32_idx2desc(ring, slot, &meta);
|
||||
@@ -1285,14 +1293,21 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
|
||||
dev->stats.last_tx = jiffies;
|
||||
if (ring->stopped) {
|
||||
B43legacy_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
|
||||
ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring));
|
||||
ring->stopped = false;
|
||||
if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
|
||||
b43legacydbg(dev->wl, "Woke up TX ring %d\n",
|
||||
ring->index);
|
||||
}
|
||||
|
||||
spin_unlock(&ring->lock);
|
||||
if (dev->wl->tx_queue_stopped[ring->queue_prio]) {
|
||||
dev->wl->tx_queue_stopped[ring->queue_prio] = 0;
|
||||
} else {
|
||||
/* If the driver queue is running wake the corresponding
|
||||
* mac80211 queue. */
|
||||
ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
|
||||
if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
|
||||
b43legacydbg(dev->wl, "Woke up TX ring %d\n",
|
||||
ring->index);
|
||||
}
|
||||
/* Add work to the queue. */
|
||||
ieee80211_queue_work(dev->wl->hw, &dev->wl->tx_work);
|
||||
}
|
||||
|
||||
static void dma_rx(struct b43legacy_dmaring *ring,
|
||||
@@ -1415,22 +1430,14 @@ void b43legacy_dma_rx(struct b43legacy_dmaring *ring)
|
||||
|
||||
static void b43legacy_dma_tx_suspend_ring(struct b43legacy_dmaring *ring)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ring->lock, flags);
|
||||
B43legacy_WARN_ON(!ring->tx);
|
||||
op32_tx_suspend(ring);
|
||||
spin_unlock_irqrestore(&ring->lock, flags);
|
||||
}
|
||||
|
||||
static void b43legacy_dma_tx_resume_ring(struct b43legacy_dmaring *ring)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ring->lock, flags);
|
||||
B43legacy_WARN_ON(!ring->tx);
|
||||
op32_tx_resume(ring);
|
||||
spin_unlock_irqrestore(&ring->lock, flags);
|
||||
}
|
||||
|
||||
void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev)
|
||||
|
Reference in New Issue
Block a user