diff options
author | Mohamed Abbas <mohamed.abbas@intel.com> | 2009-05-22 11:01:51 -0700 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-22 14:06:08 -0400 |
commit | 4752c93c30441f98f7ed723001b1a5e3e5619829 (patch) | |
tree | de868a2003d2328ad3bd048e75bc16b7e327bd7f /drivers/net/wireless/iwlwifi/iwl-agn.c | |
parent | ef850d7cb301bda9155c096269557a4586b58071 (diff) |
iwlcore: Allow skb allocation from tasklet.
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: Mohamed Abbas <mohamed.abbas@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index fa24b019c62..be1058bdc4c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -831,6 +831,7 @@ void iwl_rx_handle(struct iwl_priv *priv) unsigned long flags; u8 fill_rx = 0; u32 count = 8; + int total_empty; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ @@ -841,7 +842,12 @@ void iwl_rx_handle(struct iwl_priv *priv) if (i == r) IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); - 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; while (i != r) { @@ -918,7 +924,7 @@ void iwl_rx_handle(struct iwl_priv *priv) count++; if (count >= 8) { priv->rxq.read = i; - iwl_rx_queue_restock(priv); + iwl_rx_replenish_now(priv); count = 0; } } @@ -926,7 +932,10 @@ void iwl_rx_handle(struct iwl_priv *priv) /* Backtrack one entry */ priv->rxq.read = i; - iwl_rx_queue_restock(priv); + if (fill_rx) + iwl_rx_replenish_now(priv); + else + iwl_rx_queue_restock(priv); } /* call this function to flush any scheduled tasklet */ |