aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-scan.c
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2009-10-09 05:19:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:48:06 -0400
commit2f301227a1ede57504694e1f64839839f5737cac (patch)
treec148ca6c3409f5f8fed4455fba3a78fe31469135 /drivers/net/wireless/iwlwifi/iwl-scan.c
parentae751bab9f55c3152ebf713c89a4fb6f439c2575 (diff)
iwlwifi: use paged Rx
This switches the iwlwifi driver to use paged skb from linear skb for Rx buffer. So that it relieves some Rx buffer allocation pressure for the memory subsystem. Currently iwlwifi (4K for 3945) requests 8K bytes for Rx buffer. Due to the trailing skb_shared_info in the skb->data, alloc_skb() will do the next order allocation, which is 16K bytes. This is suboptimal and more likely to fail when the system is under memory usage pressure. Switching to paged Rx skb lets us allocate the RXB directly by alloc_pages(), so that only order 1 allocation is required. It also adjusts the area spin_lock (with IRQ disabled) protected in the tasklet because tasklet guarentees to run only on one CPU and the new unprotected code can be preempted by the IRQ handler. This saves us from spawning another workqueue to make skb_linearize/__pskb_pull_tail happy (which cannot be called in hard irq context). Finally, mac80211 doesn't support paged Rx yet. So we linearize the skb for all the management frames and software decryption or defragmentation required data frames before handed to mac80211. For all the other frames, we __pskb_pull_tail 64 bytes in the linear area of the skb for mac80211 to handle them properly. Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-scan.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 41f9a0621250..4fca65a2fe9c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(iwl_scan_cancel_timeout);
111static int iwl_send_scan_abort(struct iwl_priv *priv) 111static int iwl_send_scan_abort(struct iwl_priv *priv)
112{ 112{
113 int ret = 0; 113 int ret = 0;
114 struct iwl_rx_packet *res; 114 struct iwl_rx_packet *pkt;
115 struct iwl_host_cmd cmd = { 115 struct iwl_host_cmd cmd = {
116 .id = REPLY_SCAN_ABORT_CMD, 116 .id = REPLY_SCAN_ABORT_CMD,
117 .flags = CMD_WANT_SKB, 117 .flags = CMD_WANT_SKB,
@@ -131,21 +131,21 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
131 return ret; 131 return ret;
132 } 132 }
133 133
134 res = (struct iwl_rx_packet *)cmd.reply_skb->data; 134 pkt = (struct iwl_rx_packet *)cmd.reply_page;
135 if (res->u.status != CAN_ABORT_STATUS) { 135 if (pkt->u.status != CAN_ABORT_STATUS) {
136 /* The scan abort will return 1 for success or 136 /* The scan abort will return 1 for success or
137 * 2 for "failure". A failure condition can be 137 * 2 for "failure". A failure condition can be
138 * due to simply not being in an active scan which 138 * due to simply not being in an active scan which
139 * can occur if we send the scan abort before we 139 * can occur if we send the scan abort before we
140 * the microcode has notified us that a scan is 140 * the microcode has notified us that a scan is
141 * completed. */ 141 * completed. */
142 IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", res->u.status); 142 IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status);
143 clear_bit(STATUS_SCAN_ABORTING, &priv->status); 143 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
144 clear_bit(STATUS_SCAN_HW, &priv->status); 144 clear_bit(STATUS_SCAN_HW, &priv->status);
145 } 145 }
146 146
147 priv->alloc_rxb_skb--; 147 priv->alloc_rxb_page--;
148 dev_kfree_skb_any(cmd.reply_skb); 148 free_pages(cmd.reply_page, priv->hw_params.rx_page_order);
149 149
150 return ret; 150 return ret;
151} 151}
@@ -155,7 +155,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
155 struct iwl_rx_mem_buffer *rxb) 155 struct iwl_rx_mem_buffer *rxb)
156{ 156{
157#ifdef CONFIG_IWLWIFI_DEBUG 157#ifdef CONFIG_IWLWIFI_DEBUG
158 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 158 struct iwl_rx_packet *pkt = rxb_addr(rxb);
159 struct iwl_scanreq_notification *notif = 159 struct iwl_scanreq_notification *notif =
160 (struct iwl_scanreq_notification *)pkt->u.raw; 160 (struct iwl_scanreq_notification *)pkt->u.raw;
161 161
@@ -167,7 +167,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
167static void iwl_rx_scan_start_notif(struct iwl_priv *priv, 167static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
168 struct iwl_rx_mem_buffer *rxb) 168 struct iwl_rx_mem_buffer *rxb)
169{ 169{
170 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 170 struct iwl_rx_packet *pkt = rxb_addr(rxb);
171 struct iwl_scanstart_notification *notif = 171 struct iwl_scanstart_notification *notif =
172 (struct iwl_scanstart_notification *)pkt->u.raw; 172 (struct iwl_scanstart_notification *)pkt->u.raw;
173 priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); 173 priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
@@ -186,7 +186,7 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
186 struct iwl_rx_mem_buffer *rxb) 186 struct iwl_rx_mem_buffer *rxb)
187{ 187{
188#ifdef CONFIG_IWLWIFI_DEBUG 188#ifdef CONFIG_IWLWIFI_DEBUG
189 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 189 struct iwl_rx_packet *pkt = rxb_addr(rxb);
190 struct iwl_scanresults_notification *notif = 190 struct iwl_scanresults_notification *notif =
191 (struct iwl_scanresults_notification *)pkt->u.raw; 191 (struct iwl_scanresults_notification *)pkt->u.raw;
192 192
@@ -213,7 +213,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
213 struct iwl_rx_mem_buffer *rxb) 213 struct iwl_rx_mem_buffer *rxb)
214{ 214{
215#ifdef CONFIG_IWLWIFI_DEBUG 215#ifdef CONFIG_IWLWIFI_DEBUG
216 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 216 struct iwl_rx_packet *pkt = rxb_addr(rxb);
217 struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; 217 struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
218 218
219 IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", 219 IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",