Commit d14d4440 authored by Abhijeet Kolekar's avatar Abhijeet Kolekar Committed by John W. Linville

iwl3945: port allow skb allocation in tasklet patch

Port "iwlcore: Allow skb allocation from tasklet." to 3945

If RX queue becomes empty then we need to restock the queue from
tasklet to prevent ucode from starving. A caller to iwl_rx_allocate
will decide if allocated buffer should come from GFP_ATOMIC or
GFP_KERNEL.
Signed-off-by: default avatarAbhijeet Kolekar <abhijeet.kolekar@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c587de0b
...@@ -1176,7 +1176,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) ...@@ -1176,7 +1176,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
/* If we've added more space for the firmware to place data, tell it. /* If we've added more space for the firmware to place data, tell it.
* Increment device's write pointer in multiples of 8. */ * Increment device's write pointer in multiples of 8. */
if ((write != (rxq->write & ~0x7)) if ((rxq->write_actual != (rxq->write & ~0x7))
|| (abs(rxq->write - rxq->read) > 7)) { || (abs(rxq->write - rxq->read) > 7)) {
spin_lock_irqsave(&rxq->lock, flags); spin_lock_irqsave(&rxq->lock, flags);
rxq->need_update = 1; rxq->need_update = 1;
...@@ -1197,7 +1197,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) ...@@ -1197,7 +1197,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
* Also restock the Rx queue via iwl3945_rx_queue_restock. * Also restock the Rx queue via iwl3945_rx_queue_restock.
* This is called as a scheduled work item (except for during initialization) * This is called as a scheduled work item (except for during initialization)
*/ */
static void iwl3945_rx_allocate(struct iwl_priv *priv) static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
{ {
struct iwl_rx_queue *rxq = &priv->rxq; struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element; struct list_head *element;
...@@ -1220,7 +1220,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv) ...@@ -1220,7 +1220,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
/* Alloc a new receive buffer */ /* Alloc a new receive buffer */
rxb->skb = rxb->skb =
alloc_skb(priv->hw_params.rx_buf_size, alloc_skb(priv->hw_params.rx_buf_size,
GFP_KERNEL); priority);
if (!rxb->skb) { if (!rxb->skb) {
if (net_ratelimit()) if (net_ratelimit())
IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
...@@ -1279,6 +1279,7 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) ...@@ -1279,6 +1279,7 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
* not restocked the Rx queue with fresh buffers */ * not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0; rxq->read = rxq->write = 0;
rxq->free_count = 0; rxq->free_count = 0;
rxq->write_actual = 0;
spin_unlock_irqrestore(&rxq->lock, flags); spin_unlock_irqrestore(&rxq->lock, flags);
} }
...@@ -1287,13 +1288,21 @@ void iwl3945_rx_replenish(void *data) ...@@ -1287,13 +1288,21 @@ void iwl3945_rx_replenish(void *data)
struct iwl_priv *priv = data; struct iwl_priv *priv = data;
unsigned long flags; unsigned long flags;
iwl3945_rx_allocate(priv); iwl3945_rx_allocate(priv, GFP_KERNEL);
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
iwl3945_rx_queue_restock(priv); iwl3945_rx_queue_restock(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
} }
static void iwl3945_rx_replenish_now(struct iwl_priv *priv)
{
iwl3945_rx_allocate(priv, GFP_ATOMIC);
iwl3945_rx_queue_restock(priv);
}
/* Assumes that the skb field of the buffers in 'pool' is kept accurate. /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
* If an SKB has been detached, the POOL needs to have its SKB set to NULL * If an SKB has been detached, the POOL needs to have its SKB set to NULL
* This free routine walks the list of POOL entries and if SKB is set to * This free routine walks the list of POOL entries and if SKB is set to
...@@ -1416,13 +1425,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) ...@@ -1416,13 +1425,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
unsigned long flags; unsigned long flags;
u8 fill_rx = 0; u8 fill_rx = 0;
u32 count = 8; u32 count = 8;
int total_empty = 0;
/* uCode's read index (stored in shared DRAM) indicates the last Rx /* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */ * buffer that the driver may process (last buffer filled by ucode). */
r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
i = rxq->read; i = rxq->read;
if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) /* calculate total frames need to be restock after handling RX */
total_empty = r - priv->rxq.write_actual;
if (total_empty < 0)
total_empty += RX_QUEUE_SIZE;
if (total_empty > (RX_QUEUE_SIZE / 2))
fill_rx = 1; fill_rx = 1;
/* Rx interrupt, but nothing sent from uCode */ /* Rx interrupt, but nothing sent from uCode */
if (i == r) if (i == r)
...@@ -1499,7 +1514,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) ...@@ -1499,7 +1514,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
count++; count++;
if (count >= 8) { if (count >= 8) {
priv->rxq.read = i; priv->rxq.read = i;
iwl3945_rx_queue_restock(priv); iwl3945_rx_replenish_now(priv);
count = 0; count = 0;
} }
} }
...@@ -1507,7 +1522,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) ...@@ -1507,7 +1522,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
/* Backtrack one entry */ /* Backtrack one entry */
priv->rxq.read = i; priv->rxq.read = i;
iwl3945_rx_queue_restock(priv); if (fill_rx)
iwl3945_rx_replenish_now(priv);
else
iwl3945_rx_queue_restock(priv);
} }
/* call this function to flush any scheduled tasklet */ /* call this function to flush any scheduled tasklet */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment