aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-05 14:24:39 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-06 15:16:12 -0500
commit48a2d66f58d2bf1818acf5ff7ed9897a9977a96e (patch)
tree9154cf363233d28c97b584df19052e0f8e5ab577 /drivers/net/wireless/iwlwifi
parent65b94a4abfd55b3304be25ffed9832455d41e1dd (diff)
iwlwifi: don't pass iwl_rx_mem_buffer to upper layers
struct iwl_rx_mem_buffer implementation details (DMA address, list pointers) that the upper layers don't need. Introduce iwl_rx_cmd_buffer that is passed upstream and only contains the needed data (the page). Additionally, access this data only via accessor functions, allowing us to change the implementation in the future. These accessors are rxb_addr() (as before) and rxb_steal_page() to take ownership of the data. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c41
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-shared.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-ucode.c2
14 files changed, 80 insertions, 57 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 626b0d184729..e96af5133e06 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -707,7 +707,7 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
707} 707}
708 708
709int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, 709int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
710 struct iwl_rx_mem_buffer *rxb, 710 struct iwl_rx_cmd_buffer *rxb,
711 struct iwl_device_cmd *cmd) 711 struct iwl_device_cmd *cmd)
712{ 712{
713 struct iwl_rx_packet *pkt = rxb_addr(rxb); 713 struct iwl_rx_packet *pkt = rxb_addr(rxb);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index bc21586aed63..8e025e0df50d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -131,7 +131,7 @@ const char *get_cmd_string(u8 cmd)
131 ******************************************************************************/ 131 ******************************************************************************/
132 132
133static int iwlagn_rx_reply_error(struct iwl_priv *priv, 133static int iwlagn_rx_reply_error(struct iwl_priv *priv,
134 struct iwl_rx_mem_buffer *rxb, 134 struct iwl_rx_cmd_buffer *rxb,
135 struct iwl_device_cmd *cmd) 135 struct iwl_device_cmd *cmd)
136{ 136{
137 struct iwl_rx_packet *pkt = rxb_addr(rxb); 137 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -146,7 +146,7 @@ static int iwlagn_rx_reply_error(struct iwl_priv *priv,
146 return 0; 146 return 0;
147} 147}
148 148
149static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, 149static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
150 struct iwl_device_cmd *cmd) 150 struct iwl_device_cmd *cmd)
151{ 151{
152 struct iwl_rx_packet *pkt = rxb_addr(rxb); 152 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -177,7 +177,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
177 177
178 178
179static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, 179static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
180 struct iwl_rx_mem_buffer *rxb, 180 struct iwl_rx_cmd_buffer *rxb,
181 struct iwl_device_cmd *cmd) 181 struct iwl_device_cmd *cmd)
182{ 182{
183 struct iwl_rx_packet *pkt = rxb_addr(rxb); 183 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -195,7 +195,7 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
195} 195}
196 196
197static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, 197static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
198 struct iwl_rx_mem_buffer *rxb, 198 struct iwl_rx_cmd_buffer *rxb,
199 struct iwl_device_cmd *cmd) 199 struct iwl_device_cmd *cmd)
200{ 200{
201#ifdef CONFIG_IWLWIFI_DEBUG 201#ifdef CONFIG_IWLWIFI_DEBUG
@@ -208,7 +208,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
208} 208}
209 209
210static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, 210static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
211 struct iwl_rx_mem_buffer *rxb, 211 struct iwl_rx_cmd_buffer *rxb,
212 struct iwl_device_cmd *cmd) 212 struct iwl_device_cmd *cmd)
213{ 213{
214 struct iwl_rx_packet *pkt = rxb_addr(rxb); 214 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -222,7 +222,7 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
222} 222}
223 223
224static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, 224static int iwlagn_rx_beacon_notif(struct iwl_priv *priv,
225 struct iwl_rx_mem_buffer *rxb, 225 struct iwl_rx_cmd_buffer *rxb,
226 struct iwl_device_cmd *cmd) 226 struct iwl_device_cmd *cmd)
227{ 227{
228 struct iwl_rx_packet *pkt = rxb_addr(rxb); 228 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -489,7 +489,7 @@ iwlagn_accumulative_statistics(struct iwl_priv *priv,
489#endif 489#endif
490 490
491static int iwlagn_rx_statistics(struct iwl_priv *priv, 491static int iwlagn_rx_statistics(struct iwl_priv *priv,
492 struct iwl_rx_mem_buffer *rxb, 492 struct iwl_rx_cmd_buffer *rxb,
493 struct iwl_device_cmd *cmd) 493 struct iwl_device_cmd *cmd)
494{ 494{
495 unsigned long stamp = jiffies; 495 unsigned long stamp = jiffies;
@@ -597,7 +597,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
597} 597}
598 598
599static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, 599static int iwlagn_rx_reply_statistics(struct iwl_priv *priv,
600 struct iwl_rx_mem_buffer *rxb, 600 struct iwl_rx_cmd_buffer *rxb,
601 struct iwl_device_cmd *cmd) 601 struct iwl_device_cmd *cmd)
602{ 602{
603 struct iwl_rx_packet *pkt = rxb_addr(rxb); 603 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -620,7 +620,7 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv,
620/* Handle notification from uCode that card's power state is changing 620/* Handle notification from uCode that card's power state is changing
621 * due to software, hardware, or critical temperature RFKILL */ 621 * due to software, hardware, or critical temperature RFKILL */
622static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, 622static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
623 struct iwl_rx_mem_buffer *rxb, 623 struct iwl_rx_cmd_buffer *rxb,
624 struct iwl_device_cmd *cmd) 624 struct iwl_device_cmd *cmd)
625{ 625{
626 struct iwl_rx_packet *pkt = rxb_addr(rxb); 626 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -673,7 +673,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
673} 673}
674 674
675static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, 675static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
676 struct iwl_rx_mem_buffer *rxb, 676 struct iwl_rx_cmd_buffer *rxb,
677 struct iwl_device_cmd *cmd) 677 struct iwl_device_cmd *cmd)
678 678
679{ 679{
@@ -698,7 +698,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
698/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). 698/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
699 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ 699 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
700static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, 700static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
701 struct iwl_rx_mem_buffer *rxb, 701 struct iwl_rx_cmd_buffer *rxb,
702 struct iwl_device_cmd *cmd) 702 struct iwl_device_cmd *cmd)
703{ 703{
704 struct iwl_rx_packet *pkt = rxb_addr(rxb); 704 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -765,12 +765,14 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
765 struct ieee80211_hdr *hdr, 765 struct ieee80211_hdr *hdr,
766 u16 len, 766 u16 len,
767 u32 ampdu_status, 767 u32 ampdu_status,
768 struct iwl_rx_mem_buffer *rxb, 768 struct iwl_rx_cmd_buffer *rxb,
769 struct ieee80211_rx_status *stats) 769 struct ieee80211_rx_status *stats)
770{ 770{
771 struct sk_buff *skb; 771 struct sk_buff *skb;
772 __le16 fc = hdr->frame_control; 772 __le16 fc = hdr->frame_control;
773 struct iwl_rxon_context *ctx; 773 struct iwl_rxon_context *ctx;
774 struct page *p;
775 int offset;
774 776
775 /* We only process data packets if the interface is open */ 777 /* We only process data packets if the interface is open */
776 if (unlikely(!priv->is_open)) { 778 if (unlikely(!priv->is_open)) {
@@ -790,7 +792,9 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
790 return; 792 return;
791 } 793 }
792 794
793 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); 795 offset = (void *)hdr - rxb_addr(rxb);
796 p = rxb_steal_page(rxb);
797 skb_add_rx_frag(skb, 0, p, offset, len);
794 798
795 iwl_update_stats(priv, false, fc, len); 799 iwl_update_stats(priv, false, fc, len);
796 800
@@ -817,7 +821,6 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
817 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 821 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
818 822
819 ieee80211_rx(priv->hw, skb); 823 ieee80211_rx(priv->hw, skb);
820 rxb->page = NULL;
821} 824}
822 825
823static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) 826static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
@@ -923,7 +926,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
923/* Called for REPLY_RX (legacy ABG frames), or 926/* Called for REPLY_RX (legacy ABG frames), or
924 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ 927 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
925static int iwlagn_rx_reply_rx(struct iwl_priv *priv, 928static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
926 struct iwl_rx_mem_buffer *rxb, 929 struct iwl_rx_cmd_buffer *rxb,
927 struct iwl_device_cmd *cmd) 930 struct iwl_device_cmd *cmd)
928{ 931{
929 struct ieee80211_hdr *header; 932 struct ieee80211_hdr *header;
@@ -1043,7 +1046,7 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
1043} 1046}
1044 1047
1045static int iwlagn_rx_noa_notification(struct iwl_priv *priv, 1048static int iwlagn_rx_noa_notification(struct iwl_priv *priv,
1046 struct iwl_rx_mem_buffer *rxb, 1049 struct iwl_rx_cmd_buffer *rxb,
1047 struct iwl_device_cmd *cmd) 1050 struct iwl_device_cmd *cmd)
1048{ 1051{
1049 struct iwl_wipan_noa_data *new_data, *old_data; 1052 struct iwl_wipan_noa_data *new_data, *old_data;
@@ -1094,7 +1097,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv,
1094 */ 1097 */
1095void iwl_setup_rx_handlers(struct iwl_priv *priv) 1098void iwl_setup_rx_handlers(struct iwl_priv *priv)
1096{ 1099{
1097 int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, 1100 int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1098 struct iwl_device_cmd *cmd); 1101 struct iwl_device_cmd *cmd);
1099 1102
1100 handlers = priv->rx_handlers; 1103 handlers = priv->rx_handlers;
@@ -1149,8 +1152,8 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
1149 1152
1150} 1153}
1151 1154
1152int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, 1155int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
1153 struct iwl_device_cmd *cmd) 1156 struct iwl_device_cmd *cmd)
1154{ 1157{
1155 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1158 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1156 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 1159 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 9ef8da47ad04..736f8dc404df 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -123,7 +123,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
123 return ret; 123 return ret;
124} 124}
125 125
126int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, 126int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
127 struct iwl_device_cmd *cmd) 127 struct iwl_device_cmd *cmd)
128{ 128{
129 struct iwl_rx_packet *pkt = rxb_addr(rxb); 129 struct iwl_rx_packet *pkt = rxb_addr(rxb);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 1914bee1891e..dd28785e1a5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -977,7 +977,7 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
977 } 977 }
978} 978}
979 979
980int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, 980int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
981 struct iwl_device_cmd *cmd) 981 struct iwl_device_cmd *cmd)
982{ 982{
983 struct iwl_rx_packet *pkt = rxb_addr(rxb); 983 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -1108,7 +1108,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
1108 * of frames sent via aggregation. 1108 * of frames sent via aggregation.
1109 */ 1109 */
1110int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, 1110int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1111 struct iwl_rx_mem_buffer *rxb, 1111 struct iwl_rx_cmd_buffer *rxb,
1112 struct iwl_device_cmd *cmd) 1112 struct iwl_device_cmd *cmd)
1113{ 1113{
1114 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1114 struct iwl_rx_packet *pkt = rxb_addr(rxb);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index a142a197b2e4..a9c018a7b8ba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -82,7 +82,7 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv);
82void iwlagn_prepare_restart(struct iwl_priv *priv); 82void iwlagn_prepare_restart(struct iwl_priv *priv);
83void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); 83void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb);
84int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, 84int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode,
85 struct iwl_rx_mem_buffer *rxb, 85 struct iwl_rx_cmd_buffer *rxb,
86 struct iwl_device_cmd *cmd); 86 struct iwl_device_cmd *cmd);
87void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); 87void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
88void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac); 88void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
@@ -110,7 +110,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf,
110 110
111/* uCode */ 111/* uCode */
112int iwlagn_rx_calib_result(struct iwl_priv *priv, 112int iwlagn_rx_calib_result(struct iwl_priv *priv,
113 struct iwl_rx_mem_buffer *rxb, 113 struct iwl_rx_cmd_buffer *rxb,
114 struct iwl_device_cmd *cmd); 114 struct iwl_device_cmd *cmd);
115void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); 115void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags);
116 116
@@ -142,9 +142,9 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
142int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, 142int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
143 struct ieee80211_sta *sta, u16 tid); 143 struct ieee80211_sta *sta, u16 tid);
144int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, 144int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
145 struct iwl_rx_mem_buffer *rxb, 145 struct iwl_rx_cmd_buffer *rxb,
146 struct iwl_device_cmd *cmd); 146 struct iwl_device_cmd *cmd);
147int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, 147int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
148 struct iwl_device_cmd *cmd); 148 struct iwl_device_cmd *cmd);
149 149
150static inline u32 iwl_tx_status_to_mac80211(u32 status) 150static inline u32 iwl_tx_status_to_mac80211(u32 status)
@@ -179,7 +179,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv);
179/* bt coex */ 179/* bt coex */
180void iwlagn_send_advance_bt_config(struct iwl_priv *priv); 180void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
181int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, 181int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
182 struct iwl_rx_mem_buffer *rxb, 182 struct iwl_rx_cmd_buffer *rxb,
183 struct iwl_device_cmd *cmd); 183 struct iwl_device_cmd *cmd);
184void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); 184void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
185void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); 185void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
@@ -227,7 +227,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
227 u8 sta_id, struct iwl_link_quality_cmd *link_cmd); 227 u8 sta_id, struct iwl_link_quality_cmd *link_cmd);
228int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 228int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
229 struct iwl_link_quality_cmd *lq, u8 flags, bool init); 229 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
230int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, 230int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
231 struct iwl_device_cmd *cmd); 231 struct iwl_device_cmd *cmd);
232 232
233 233
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ef71463e84ea..5957209b2f37 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -729,9 +729,9 @@ struct iwl_priv {
729 enum ieee80211_band band; 729 enum ieee80211_band band;
730 730
731 void (*pre_rx_handler)(struct iwl_priv *priv, 731 void (*pre_rx_handler)(struct iwl_priv *priv,
732 struct iwl_rx_mem_buffer *rxb); 732 struct iwl_rx_cmd_buffer *rxb);
733 int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, 733 int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
734 struct iwl_rx_mem_buffer *rxb, 734 struct iwl_rx_cmd_buffer *rxb,
735 struct iwl_device_cmd *cmd); 735 struct iwl_device_cmd *cmd);
736 736
737 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 737 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index d4fc9be2d2f3..41e58a136715 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -67,7 +67,7 @@ struct iwl_op_mode;
67struct iwl_trans; 67struct iwl_trans;
68struct sk_buff; 68struct sk_buff;
69struct iwl_device_cmd; 69struct iwl_device_cmd;
70struct iwl_rx_mem_buffer; 70struct iwl_rx_cmd_buffer;
71 71
72/** 72/**
73 * DOC: Operational mode - what is it ? 73 * DOC: Operational mode - what is it ?
@@ -125,7 +125,7 @@ struct iwl_rx_mem_buffer;
125struct iwl_op_mode_ops { 125struct iwl_op_mode_ops {
126 struct iwl_op_mode *(*start)(struct iwl_trans *trans); 126 struct iwl_op_mode *(*start)(struct iwl_trans *trans);
127 void (*stop)(struct iwl_op_mode *op_mode); 127 void (*stop)(struct iwl_op_mode *op_mode);
128 int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, 128 int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
129 struct iwl_device_cmd *cmd); 129 struct iwl_device_cmd *cmd);
130 void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac); 130 void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac);
131 void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac); 131 void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac);
@@ -156,7 +156,7 @@ static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
156} 156}
157 157
158static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode, 158static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode,
159 struct iwl_rx_mem_buffer *rxb, 159 struct iwl_rx_cmd_buffer *rxb,
160 struct iwl_device_cmd *cmd) 160 struct iwl_device_cmd *cmd)
161{ 161{
162 return op_mode->ops->rx(op_mode, rxb, cmd); 162 return op_mode->ops->rx(op_mode, rxb, cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index c0fc3687a2fd..28899dabe6fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -260,7 +260,7 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
260 260
261/* Service response to REPLY_SCAN_CMD (0x80) */ 261/* Service response to REPLY_SCAN_CMD (0x80) */
262static int iwl_rx_reply_scan(struct iwl_priv *priv, 262static int iwl_rx_reply_scan(struct iwl_priv *priv,
263 struct iwl_rx_mem_buffer *rxb, 263 struct iwl_rx_cmd_buffer *rxb,
264 struct iwl_device_cmd *cmd) 264 struct iwl_device_cmd *cmd)
265{ 265{
266#ifdef CONFIG_IWLWIFI_DEBUG 266#ifdef CONFIG_IWLWIFI_DEBUG
@@ -275,7 +275,7 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv,
275 275
276/* Service SCAN_START_NOTIFICATION (0x82) */ 276/* Service SCAN_START_NOTIFICATION (0x82) */
277static int iwl_rx_scan_start_notif(struct iwl_priv *priv, 277static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
278 struct iwl_rx_mem_buffer *rxb, 278 struct iwl_rx_cmd_buffer *rxb,
279 struct iwl_device_cmd *cmd) 279 struct iwl_device_cmd *cmd)
280{ 280{
281 struct iwl_rx_packet *pkt = rxb_addr(rxb); 281 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -302,7 +302,7 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
302 302
303/* Service SCAN_RESULTS_NOTIFICATION (0x83) */ 303/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
304static int iwl_rx_scan_results_notif(struct iwl_priv *priv, 304static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
305 struct iwl_rx_mem_buffer *rxb, 305 struct iwl_rx_cmd_buffer *rxb,
306 struct iwl_device_cmd *cmd) 306 struct iwl_device_cmd *cmd)
307{ 307{
308#ifdef CONFIG_IWLWIFI_DEBUG 308#ifdef CONFIG_IWLWIFI_DEBUG
@@ -328,7 +328,7 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
328 328
329/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ 329/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
330static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, 330static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
331 struct iwl_rx_mem_buffer *rxb, 331 struct iwl_rx_cmd_buffer *rxb,
332 struct iwl_device_cmd *cmd) 332 struct iwl_device_cmd *cmd)
333{ 333{
334 struct iwl_rx_packet *pkt = rxb_addr(rxb); 334 struct iwl_rx_packet *pkt = rxb_addr(rxb);
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index 53244d88f1ab..ed1811d43550 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -433,13 +433,21 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
433 return --index & (n_bd - 1); 433 return --index & (n_bd - 1);
434} 434}
435 435
436struct iwl_rx_mem_buffer { 436struct iwl_rx_cmd_buffer {
437 dma_addr_t page_dma; 437 struct page *_page;
438 struct page *page;
439 struct list_head list;
440}; 438};
441 439
442#define rxb_addr(r) page_address(r->page) 440static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r)
441{
442 return page_address(r->_page);
443}
444
445static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
446{
447 struct page *p = r->_page;
448 r->_page = NULL;
449 return p;
450}
443 451
444/* 452/*
445 * mac80211 queues, ACs, hardware queues, FIFOs. 453 * mac80211 queues, ACs, hardware queues, FIFOs.
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c
index cc1f3e990ad6..b24b166a9482 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@ -131,7 +131,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
131 * See the struct iwl_rx_packet in iwl-commands.h for the format of the 131 * See the struct iwl_rx_packet in iwl-commands.h for the format of the
132 * received events from the device 132 * received events from the device
133 */ 133 */
134static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) 134static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb)
135{ 135{
136 struct iwl_rx_packet *pkt = rxb_addr(rxb); 136 struct iwl_rx_packet *pkt = rxb_addr(rxb);
137 if (pkt) 137 if (pkt)
@@ -162,7 +162,7 @@ static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
162 */ 162 */
163 163
164static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, 164static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
165 struct iwl_rx_mem_buffer *rxb) 165 struct iwl_rx_cmd_buffer *rxb)
166{ 166{
167 struct ieee80211_hw *hw = priv->hw; 167 struct ieee80211_hw *hw = priv->hw;
168 struct sk_buff *skb; 168 struct sk_buff *skb;
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
index b1029468ccbd..632d4099900e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
@@ -49,6 +49,12 @@ struct iwl_host_cmd;
49/*This file includes the declaration that are internal to the 49/*This file includes the declaration that are internal to the
50 * trans_pcie layer */ 50 * trans_pcie layer */
51 51
52struct iwl_rx_mem_buffer {
53 dma_addr_t page_dma;
54 struct page *page;
55 struct list_head list;
56};
57
52/** 58/**
53 * struct isr_statistics - interrupt statistics 59 * struct isr_statistics - interrupt statistics
54 * 60 *
@@ -287,7 +293,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans,
287int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); 293int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id);
288int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); 294int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
289void iwl_tx_cmd_complete(struct iwl_trans *trans, 295void iwl_tx_cmd_complete(struct iwl_trans *trans,
290 struct iwl_rx_mem_buffer *rxb, int handler_status); 296 struct iwl_rx_cmd_buffer *rxb, int handler_status);
291void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, 297void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
292 struct iwl_tx_queue *txq, 298 struct iwl_tx_queue *txq,
293 u16 byte_cnt); 299 u16 byte_cnt);
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
index 6495945637b9..68e89be60bef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
@@ -367,8 +367,6 @@ void iwl_bg_rx_replenish(struct work_struct *data)
367 */ 367 */
368static void iwl_rx_handle(struct iwl_trans *trans) 368static void iwl_rx_handle(struct iwl_trans *trans)
369{ 369{
370 struct iwl_rx_mem_buffer *rxb;
371 struct iwl_rx_packet *pkt;
372 struct iwl_trans_pcie *trans_pcie = 370 struct iwl_trans_pcie *trans_pcie =
373 IWL_TRANS_GET_PCIE_TRANS(trans); 371 IWL_TRANS_GET_PCIE_TRANS(trans);
374 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 372 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
@@ -402,6 +400,9 @@ static void iwl_rx_handle(struct iwl_trans *trans)
402 while (i != r) { 400 while (i != r) {
403 int len, err; 401 int len, err;
404 u16 sequence; 402 u16 sequence;
403 struct iwl_rx_mem_buffer *rxb;
404 struct iwl_rx_cmd_buffer rxcb;
405 struct iwl_rx_packet *pkt;
405 406
406 rxb = rxq->queue[i]; 407 rxb = rxq->queue[i];
407 408
@@ -418,7 +419,9 @@ static void iwl_rx_handle(struct iwl_trans *trans)
418 dma_unmap_page(trans->dev, rxb->page_dma, 419 dma_unmap_page(trans->dev, rxb->page_dma,
419 PAGE_SIZE << hw_params(trans).rx_page_order, 420 PAGE_SIZE << hw_params(trans).rx_page_order,
420 DMA_FROM_DEVICE); 421 DMA_FROM_DEVICE);
421 pkt = rxb_addr(rxb); 422
423 rxcb._page = rxb->page;
424 pkt = rxb_addr(&rxcb);
422 425
423 IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r, 426 IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r,
424 i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); 427 i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
@@ -461,10 +464,10 @@ static void iwl_rx_handle(struct iwl_trans *trans)
461 "reclaim is false, SEQ_RX_FRAME unset: %s\n", 464 "reclaim is false, SEQ_RX_FRAME unset: %s\n",
462 get_cmd_string(pkt->hdr.cmd)); 465 get_cmd_string(pkt->hdr.cmd));
463 466
464 err = iwl_op_mode_rx(trans->op_mode, rxb, cmd); 467 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
465 468
466 /* 469 /*
467 * XXX: After here, we should always check rxb->page 470 * XXX: After here, we should always check rxcb._page
468 * against NULL before touching it or its virtual 471 * against NULL before touching it or its virtual
469 * memory (pkt). Because some rx_handler might have 472 * memory (pkt). Because some rx_handler might have
470 * already taken or freed the pages. 473 * already taken or freed the pages.
@@ -475,12 +478,16 @@ static void iwl_rx_handle(struct iwl_trans *trans)
475 * and fire off the (possibly) blocking 478 * and fire off the (possibly) blocking
476 * iwl_trans_send_cmd() 479 * iwl_trans_send_cmd()
477 * as we reclaim the driver command queue */ 480 * as we reclaim the driver command queue */
478 if (rxb->page) 481 if (rxcb._page)
479 iwl_tx_cmd_complete(trans, rxb, err); 482 iwl_tx_cmd_complete(trans, &rxcb, err);
480 else 483 else
481 IWL_WARN(trans, "Claim null rxb?\n"); 484 IWL_WARN(trans, "Claim null rxb?\n");
482 } 485 }
483 486
487 /* page was stolen from us */
488 if (rxcb._page == NULL)
489 rxb->page = NULL;
490
484 /* Reuse the page if possible. For notification packets and 491 /* Reuse the page if possible. For notification packets and
485 * SKBs that fail to Rx correctly, add them back into the 492 * SKBs that fail to Rx correctly, add them back into the
486 * rx_free list for reuse later. */ 493 * rx_free list for reuse later. */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index 771fae2f9fd8..0513b90da040 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -841,7 +841,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
841 * will be executed. The attached skb (if present) will only be freed 841 * will be executed. The attached skb (if present) will only be freed
842 * if the callback returns 1 842 * if the callback returns 1
843 */ 843 */
844void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, 844void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
845 int handler_status) 845 int handler_status)
846{ 846{
847 struct iwl_rx_packet *pkt = rxb_addr(rxb); 847 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -879,9 +879,8 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
879 879
880 /* Input error checking is done when commands are added to queue. */ 880 /* Input error checking is done when commands are added to queue. */
881 if (meta->flags & CMD_WANT_SKB) { 881 if (meta->flags & CMD_WANT_SKB) {
882 struct page *p = rxb->page; 882 struct page *p = rxb_steal_page(rxb);
883 883
884 rxb->page = NULL;
885 meta->source->resp_pkt = pkt; 884 meta->source->resp_pkt = pkt;
886 meta->source->_rx_page_addr = (unsigned long)page_address(p); 885 meta->source->_rx_page_addr = (unsigned long)page_address(p);
887 meta->source->_rx_page_order = hw_params(trans).rx_page_order; 886 meta->source->_rx_page_order = hw_params(trans).rx_page_order;
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c
index 206a61c991dd..12e79d04374f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c
@@ -228,7 +228,7 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans)
228} 228}
229 229
230int iwlagn_rx_calib_result(struct iwl_priv *priv, 230int iwlagn_rx_calib_result(struct iwl_priv *priv,
231 struct iwl_rx_mem_buffer *rxb, 231 struct iwl_rx_cmd_buffer *rxb,
232 struct iwl_device_cmd *cmd) 232 struct iwl_device_cmd *cmd)
233{ 233{
234 struct iwl_rx_packet *pkt = rxb_addr(rxb); 234 struct iwl_rx_packet *pkt = rxb_addr(rxb);