aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl-dev.h
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2009-10-09 17:19:45 +0800
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 451aa65b1a5..35d579455c3 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);
#define DEFAULT_LONG_RETRY_LIMIT 4U
struct iwl_rx_mem_buffer {
- dma_addr_t real_dma_addr;
- dma_addr_t aligned_dma_addr;
- struct sk_buff *skb;
+ dma_addr_t page_dma;
+ struct page *page;
struct list_head list;
};
+#define rxb_addr(r) page_address(r->page)
+
/* defined below */
struct iwl_device_cmd;
@@ -167,7 +168,7 @@ struct iwl_cmd_meta {
*/
void (*callback)(struct iwl_priv *priv,
struct iwl_device_cmd *cmd,
- struct sk_buff *skb);
+ struct iwl_rx_packet *pkt);
/* The CMD_SIZE_HUGE flag bit indicates that the command
* structure is stored at the end of the shared queue memory. */
@@ -366,6 +367,13 @@ enum {
#define IWL_CMD_MAX_PAYLOAD 320
+/*
+ * IWL_LINK_HDR_MAX should include ieee80211_hdr, radiotap header,
+ * SNAP header and alignment. It should also be big enough for 802.11
+ * control frames.
+ */
+#define IWL_LINK_HDR_MAX 64
+
/**
* struct iwl_device_cmd
*
@@ -390,10 +398,10 @@ struct iwl_device_cmd {
struct iwl_host_cmd {
const void *data;
- struct sk_buff *reply_skb;
+ unsigned long reply_page;
void (*callback)(struct iwl_priv *priv,
struct iwl_device_cmd *cmd,
- struct sk_buff *skb);
+ struct iwl_rx_packet *pkt);
u32 flags;
u16 len;
u8 id;
@@ -650,7 +658,7 @@ struct iwl_sensitivity_ranges {
* @valid_tx/rx_ant: usable antennas
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
* @max_rxq_log: Log-base-2 of max_rxq_size
- * @rx_buf_size: Rx buffer size
+ * @rx_page_order: Rx buffer page order
* @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
* @max_stations:
* @bcast_sta_id:
@@ -673,9 +681,8 @@ struct iwl_hw_params {
u8 valid_rx_ant;
u16 max_rxq_size;
u16 max_rxq_log;
- u32 rx_buf_size;
+ u32 rx_page_order;
u32 rx_wrt_ptr_reg;
- u32 max_pkt_size;
u8 max_stations;
u8 bcast_sta_id;
u8 ht40_channel;
@@ -987,7 +994,7 @@ struct iwl_priv {
int frames_count;
enum ieee80211_band band;
- int alloc_rxb_skb;
+ int alloc_rxb_page;
void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);