aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c24
2 files changed, 33 insertions, 15 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 8150c5c3a16..b90adcb73b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -239,26 +239,22 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
struct iwl_rx_mem_buffer *rxb;
+ struct sk_buff *skb;
unsigned long flags;
while (1) {
spin_lock_irqsave(&rxq->lock, flags);
-
if (list_empty(&rxq->rx_used)) {
spin_unlock_irqrestore(&rxq->lock, flags);
return;
}
- element = rxq->rx_used.next;
- rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
- list_del(element);
-
spin_unlock_irqrestore(&rxq->lock, flags);
/* Alloc a new receive buffer */
- rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
+ skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
priority);
- if (!rxb->skb) {
+ if (!skb) {
IWL_CRIT(priv, "Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
* call the restock method and if it still needs
@@ -266,6 +262,20 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
break;
}
+ spin_lock_irqsave(&rxq->lock, flags);
+
+ if (list_empty(&rxq->rx_used)) {
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ dev_kfree_skb_any(skb);
+ return;
+ }
+ element = rxq->rx_used.next;
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+ list_del(element);
+
+ spin_unlock_irqrestore(&rxq->lock, flags);
+
+ rxb->skb = skb;
/* Get physical address of RB/SKB */
rxb->real_dma_addr = pci_map_single(
priv->pci_dev,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 2238c9f2018..090966837f3 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1134,6 +1134,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
struct iwl_rx_mem_buffer *rxb;
+ struct sk_buff *skb;
unsigned long flags;
while (1) {
@@ -1143,17 +1144,11 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
spin_unlock_irqrestore(&rxq->lock, flags);
return;
}
-
- element = rxq->rx_used.next;
- rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
- list_del(element);
spin_unlock_irqrestore(&rxq->lock, flags);
/* Alloc a new receive buffer */
- rxb->skb =
- alloc_skb(priv->hw_params.rx_buf_size,
- priority);
- if (!rxb->skb) {
+ skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
+ if (!skb) {
if (net_ratelimit())
IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
@@ -1162,6 +1157,19 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
break;
}
+ spin_lock_irqsave(&rxq->lock, flags);
+ if (list_empty(&rxq->rx_used)) {
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ dev_kfree_skb_any(skb);
+ return;
+ }
+ element = rxq->rx_used.next;
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+ list_del(element);
+ spin_unlock_irqrestore(&rxq->lock, flags);
+
+ rxb->skb = skb;
+
/* If radiotap head is required, reserve some headroom here.
* The physical head count is a variable rx_stats->phy_count.
* We reserve 4 bytes here. Plus these extra bytes, the