aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-dev.h
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-dev.h
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-dev.h')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 451aa65b1a56..35d579455c3c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -146,12 +146,13 @@ extern void iwl5000_temperature(struct iwl_priv *priv);
146#define DEFAULT_LONG_RETRY_LIMIT 4U 146#define DEFAULT_LONG_RETRY_LIMIT 4U
147 147
148struct iwl_rx_mem_buffer { 148struct iwl_rx_mem_buffer {
149 dma_addr_t real_dma_addr; 149 dma_addr_t page_dma;
150 dma_addr_t aligned_dma_addr; 150 struct page *page;
151 struct sk_buff *skb;
152 struct list_head list; 151 struct list_head list;
153}; 152};
154 153
154#define rxb_addr(r) page_address(r->page)
155
155/* defined below */ 156/* defined below */
156struct iwl_device_cmd; 157struct iwl_device_cmd;
157 158
@@ -167,7 +168,7 @@ struct iwl_cmd_meta {
167 */ 168 */
168 void (*callback)(struct iwl_priv *priv, 169 void (*callback)(struct iwl_priv *priv,
169 struct iwl_device_cmd *cmd, 170 struct iwl_device_cmd *cmd,
170 struct sk_buff *skb); 171 struct iwl_rx_packet *pkt);
171 172
172 /* The CMD_SIZE_HUGE flag bit indicates that the command 173 /* The CMD_SIZE_HUGE flag bit indicates that the command
173 * structure is stored at the end of the shared queue memory. */ 174 * structure is stored at the end of the shared queue memory. */
@@ -366,6 +367,13 @@ enum {
366 367
367#define IWL_CMD_MAX_PAYLOAD 320 368#define IWL_CMD_MAX_PAYLOAD 320
368 369
370/*
371 * IWL_LINK_HDR_MAX should include ieee80211_hdr, radiotap header,
372 * SNAP header and alignment. It should also be big enough for 802.11
373 * control frames.
374 */
375#define IWL_LINK_HDR_MAX 64
376
369/** 377/**
370 * struct iwl_device_cmd 378 * struct iwl_device_cmd
371 * 379 *
@@ -390,10 +398,10 @@ struct iwl_device_cmd {
390 398
391struct iwl_host_cmd { 399struct iwl_host_cmd {
392 const void *data; 400 const void *data;
393 struct sk_buff *reply_skb; 401 unsigned long reply_page;
394 void (*callback)(struct iwl_priv *priv, 402 void (*callback)(struct iwl_priv *priv,
395 struct iwl_device_cmd *cmd, 403 struct iwl_device_cmd *cmd,
396 struct sk_buff *skb); 404 struct iwl_rx_packet *pkt);
397 u32 flags; 405 u32 flags;
398 u16 len; 406 u16 len;
399 u8 id; 407 u8 id;
@@ -650,7 +658,7 @@ struct iwl_sensitivity_ranges {
650 * @valid_tx/rx_ant: usable antennas 658 * @valid_tx/rx_ant: usable antennas
651 * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) 659 * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
652 * @max_rxq_log: Log-base-2 of max_rxq_size 660 * @max_rxq_log: Log-base-2 of max_rxq_size
653 * @rx_buf_size: Rx buffer size 661 * @rx_page_order: Rx buffer page order
654 * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR 662 * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
655 * @max_stations: 663 * @max_stations:
656 * @bcast_sta_id: 664 * @bcast_sta_id:
@@ -673,9 +681,8 @@ struct iwl_hw_params {
673 u8 valid_rx_ant; 681 u8 valid_rx_ant;
674 u16 max_rxq_size; 682 u16 max_rxq_size;
675 u16 max_rxq_log; 683 u16 max_rxq_log;
676 u32 rx_buf_size; 684 u32 rx_page_order;
677 u32 rx_wrt_ptr_reg; 685 u32 rx_wrt_ptr_reg;
678 u32 max_pkt_size;
679 u8 max_stations; 686 u8 max_stations;
680 u8 bcast_sta_id; 687 u8 bcast_sta_id;
681 u8 ht40_channel; 688 u8 ht40_channel;
@@ -987,7 +994,7 @@ struct iwl_priv {
987 int frames_count; 994 int frames_count;
988 995
989 enum ieee80211_band band; 996 enum ieee80211_band band;
990 int alloc_rxb_skb; 997 int alloc_rxb_page;
991 998
992 void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, 999 void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
993 struct iwl_rx_mem_buffer *rxb); 1000 struct iwl_rx_mem_buffer *rxb);