aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
authorAbhijeet Kolekar <abhijeet.kolekar@intel.com>2009-06-03 14:44:08 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-04 10:57:36 -0400
commitd14d44407b9f06e3cf967fcef28ccb780caf0583 (patch)
tree56f5541554cd094c08caf4bc2420d7f77563bbec /drivers/net/wireless/iwlwifi/iwl3945-base.c
parentc587de0b8d6e194f7a1719fc6af8a81b4e8916d2 (diff)
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: Abhijeet Kolekar <abhijeet.kolekar@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/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 745eaaec5954..92fa1a39c446 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1176,7 +1176,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
1176 1176
1177 /* If we've added more space for the firmware to place data, tell it. 1177 /* If we've added more space for the firmware to place data, tell it.
1178 * Increment device's write pointer in multiples of 8. */ 1178 * Increment device's write pointer in multiples of 8. */
1179 if ((write != (rxq->write & ~0x7)) 1179 if ((rxq->write_actual != (rxq->write & ~0x7))
1180 || (abs(rxq->write - rxq->read) > 7)) { 1180 || (abs(rxq->write - rxq->read) > 7)) {
1181 spin_lock_irqsave(&rxq->lock, flags); 1181 spin_lock_irqsave(&rxq->lock, flags);
1182 rxq->need_update = 1; 1182 rxq->need_update = 1;
@@ -1197,7 +1197,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
1197 * Also restock the Rx queue via iwl3945_rx_queue_restock. 1197 * Also restock the Rx queue via iwl3945_rx_queue_restock.
1198 * This is called as a scheduled work item (except for during initialization) 1198 * This is called as a scheduled work item (except for during initialization)
1199 */ 1199 */
1200static void iwl3945_rx_allocate(struct iwl_priv *priv) 1200static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
1201{ 1201{
1202 struct iwl_rx_queue *rxq = &priv->rxq; 1202 struct iwl_rx_queue *rxq = &priv->rxq;
1203 struct list_head *element; 1203 struct list_head *element;
@@ -1220,7 +1220,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
1220 /* Alloc a new receive buffer */ 1220 /* Alloc a new receive buffer */
1221 rxb->skb = 1221 rxb->skb =
1222 alloc_skb(priv->hw_params.rx_buf_size, 1222 alloc_skb(priv->hw_params.rx_buf_size,
1223 GFP_KERNEL); 1223 priority);
1224 if (!rxb->skb) { 1224 if (!rxb->skb) {
1225 if (net_ratelimit()) 1225 if (net_ratelimit())
1226 IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); 1226 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 * not restocked the Rx queue with fresh buffers */ 1279 * not restocked the Rx queue with fresh buffers */
1280 rxq->read = rxq->write = 0; 1280 rxq->read = rxq->write = 0;
1281 rxq->free_count = 0; 1281 rxq->free_count = 0;
1282 rxq->write_actual = 0;
1282 spin_unlock_irqrestore(&rxq->lock, flags); 1283 spin_unlock_irqrestore(&rxq->lock, flags);
1283} 1284}
1284 1285
@@ -1287,13 +1288,21 @@ void iwl3945_rx_replenish(void *data)
1287 struct iwl_priv *priv = data; 1288 struct iwl_priv *priv = data;
1288 unsigned long flags; 1289 unsigned long flags;
1289 1290
1290 iwl3945_rx_allocate(priv); 1291 iwl3945_rx_allocate(priv, GFP_KERNEL);
1291 1292
1292 spin_lock_irqsave(&priv->lock, flags); 1293 spin_lock_irqsave(&priv->lock, flags);
1293 iwl3945_rx_queue_restock(priv); 1294 iwl3945_rx_queue_restock(priv);
1294 spin_unlock_irqrestore(&priv->lock, flags); 1295 spin_unlock_irqrestore(&priv->lock, flags);
1295} 1296}
1296 1297
1298static void iwl3945_rx_replenish_now(struct iwl_priv *priv)
1299{
1300 iwl3945_rx_allocate(priv, GFP_ATOMIC);
1301
1302 iwl3945_rx_queue_restock(priv);
1303}
1304
1305
1297/* Assumes that the skb field of the buffers in 'pool' is kept accurate. 1306/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
1298 * If an SKB has been detached, the POOL needs to have its SKB set to NULL 1307 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
1299 * This free routine walks the list of POOL entries and if SKB is set to 1308 * 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 unsigned long flags; 1425 unsigned long flags;
1417 u8 fill_rx = 0; 1426 u8 fill_rx = 0;
1418 u32 count = 8; 1427 u32 count = 8;
1428 int total_empty = 0;
1419 1429
1420 /* uCode's read index (stored in shared DRAM) indicates the last Rx 1430 /* uCode's read index (stored in shared DRAM) indicates the last Rx
1421 * buffer that the driver may process (last buffer filled by ucode). */ 1431 * buffer that the driver may process (last buffer filled by ucode). */
1422 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; 1432 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
1423 i = rxq->read; 1433 i = rxq->read;
1424 1434
1425 if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) 1435 /* calculate total frames need to be restock after handling RX */
1436 total_empty = r - priv->rxq.write_actual;
1437 if (total_empty < 0)
1438 total_empty += RX_QUEUE_SIZE;
1439
1440 if (total_empty > (RX_QUEUE_SIZE / 2))
1426 fill_rx = 1; 1441 fill_rx = 1;
1427 /* Rx interrupt, but nothing sent from uCode */ 1442 /* Rx interrupt, but nothing sent from uCode */
1428 if (i == r) 1443 if (i == r)
@@ -1499,7 +1514,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1499 count++; 1514 count++;
1500 if (count >= 8) { 1515 if (count >= 8) {
1501 priv->rxq.read = i; 1516 priv->rxq.read = i;
1502 iwl3945_rx_queue_restock(priv); 1517 iwl3945_rx_replenish_now(priv);
1503 count = 0; 1518 count = 0;
1504 } 1519 }
1505 } 1520 }
@@ -1507,7 +1522,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1507 1522
1508 /* Backtrack one entry */ 1523 /* Backtrack one entry */
1509 priv->rxq.read = i; 1524 priv->rxq.read = i;
1510 iwl3945_rx_queue_restock(priv); 1525 if (fill_rx)
1526 iwl3945_rx_replenish_now(priv);
1527 else
1528 iwl3945_rx_queue_restock(priv);
1511} 1529}
1512 1530
1513/* call this function to flush any scheduled tasklet */ 1531/* call this function to flush any scheduled tasklet */