aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-09-20 18:37:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-21 16:19:42 -0400
commit247c61d625154e18a105d663281c52376a882762 (patch)
treeec06a3824fda8a119cef3f7338826b4d25eee656
parent390808db4ab5c658dc1eb8078d82027ce7d0ea78 (diff)
iwlagn: remove the callback in host commands
Before this patch, the upper layer could register a callback for each host command. This mechanism allowed the upper layer to have different callbacks for the same command ID. In fact, it wasn't used and the rx_handlers is enough: same callback for all the command with a specific command ID. The iwl_send_add_station needs the access the command that was sent while handling the response (regardless if the command was sent in SYNC or ASYNC mode). So now, all the handlers receive the host command that was sent. This implies a change in the handler signature. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c95
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-shared.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h7
15 files changed, 157 insertions, 134 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 0a1f331cb572..d30714be515b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -705,8 +705,9 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
705 } 705 }
706} 706}
707 707
708void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, 708int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
709 struct iwl_rx_mem_buffer *rxb) 709 struct iwl_rx_mem_buffer *rxb,
710 struct iwl_device_cmd *cmd)
710{ 711{
711 unsigned long flags; 712 unsigned long flags;
712 struct iwl_rx_packet *pkt = rxb_addr(rxb); 713 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -715,7 +716,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
715 716
716 if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { 717 if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
717 /* bt coex disabled */ 718 /* bt coex disabled */
718 return; 719 return 0;
719 } 720 }
720 721
721 IWL_DEBUG_COEX(priv, "BT Coex notification:\n"); 722 IWL_DEBUG_COEX(priv, "BT Coex notification:\n");
@@ -757,6 +758,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
757 spin_lock_irqsave(&priv->shrd->lock, flags); 758 spin_lock_irqsave(&priv->shrd->lock, flags);
758 priv->bt_ci_compliance = coex->bt_ci_compliance; 759 priv->bt_ci_compliance = coex->bt_ci_compliance;
759 spin_unlock_irqrestore(&priv->shrd->lock, flags); 760 spin_unlock_irqrestore(&priv->shrd->lock, flags);
761 return 0;
760} 762}
761 763
762void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv) 764void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 459b82b8a2a7..4aa414a63d6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -736,7 +736,8 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
736 } 736 }
737} 737}
738 738
739void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 739int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
740 struct iwl_device_cmd *cmd)
740{ 741{
741 struct iwl_rx_packet *pkt = rxb_addr(rxb); 742 struct iwl_rx_packet *pkt = rxb_addr(rxb);
742 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 743 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -824,6 +825,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
824 825
825 iwl_check_abort_status(priv, tx_resp->frame_count, status); 826 iwl_check_abort_status(priv, tx_resp->frame_count, status);
826 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); 827 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
828 return 0;
827} 829}
828 830
829/** 831/**
@@ -832,8 +834,9 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
832 * Handles block-acknowledge notification from device, which reports success 834 * Handles block-acknowledge notification from device, which reports success
833 * of frames sent via aggregation. 835 * of frames sent via aggregation.
834 */ 836 */
835void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, 837int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
836 struct iwl_rx_mem_buffer *rxb) 838 struct iwl_rx_mem_buffer *rxb,
839 struct iwl_device_cmd *cmd)
837{ 840{
838 struct iwl_rx_packet *pkt = rxb_addr(rxb); 841 struct iwl_rx_packet *pkt = rxb_addr(rxb);
839 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; 842 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
@@ -857,7 +860,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
857 if (scd_flow >= hw_params(priv).max_txq_num) { 860 if (scd_flow >= hw_params(priv).max_txq_num) {
858 IWL_ERR(priv, 861 IWL_ERR(priv,
859 "BUG_ON scd_flow is bigger than number of queues\n"); 862 "BUG_ON scd_flow is bigger than number of queues\n");
860 return; 863 return 0;
861 } 864 }
862 865
863 sta_id = ba_resp->sta_id; 866 sta_id = ba_resp->sta_id;
@@ -877,14 +880,14 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
877 "BA scd_flow %d does not match txq_id %d\n", 880 "BA scd_flow %d does not match txq_id %d\n",
878 scd_flow, agg->txq_id); 881 scd_flow, agg->txq_id);
879 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); 882 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
880 return; 883 return 0;
881 } 884 }
882 885
883 if (unlikely(!agg->wait_for_ba)) { 886 if (unlikely(!agg->wait_for_ba)) {
884 if (unlikely(ba_resp->bitmap)) 887 if (unlikely(ba_resp->bitmap))
885 IWL_ERR(priv, "Received BA when not expected\n"); 888 IWL_ERR(priv, "Received BA when not expected\n");
886 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); 889 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
887 return; 890 return 0;
888 } 891 }
889 892
890 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " 893 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
@@ -955,4 +958,5 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
955 } 958 }
956 959
957 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); 960 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
961 return 0;
958} 962}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 634f18f6125a..b4e1e7c4c314 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -228,8 +228,9 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
228 return iwl_trans_send_cmd(trans(priv), &cmd); 228 return iwl_trans_send_cmd(trans(priv), &cmd);
229} 229}
230 230
231void iwlagn_rx_calib_result(struct iwl_priv *priv, 231int iwlagn_rx_calib_result(struct iwl_priv *priv,
232 struct iwl_rx_mem_buffer *rxb) 232 struct iwl_rx_mem_buffer *rxb,
233 struct iwl_device_cmd *cmd)
233{ 234{
234 struct iwl_rx_packet *pkt = rxb_addr(rxb); 235 struct iwl_rx_packet *pkt = rxb_addr(rxb);
235 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; 236 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
@@ -262,9 +263,10 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv,
262 default: 263 default:
263 IWL_ERR(priv, "Unknown calibration notification %d\n", 264 IWL_ERR(priv, "Unknown calibration notification %d\n",
264 hdr->op_code); 265 hdr->op_code);
265 return; 266 return -1;
266 } 267 }
267 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len); 268 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
269 return 0;
268} 270}
269 271
270int iwlagn_init_alive_start(struct iwl_priv *priv) 272int iwlagn_init_alive_start(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 5c4f8c72ee60..2a297d1e6bc7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -88,8 +88,9 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
88 u32 changes); 88 u32 changes);
89 89
90/* uCode */ 90/* uCode */
91void iwlagn_rx_calib_result(struct iwl_priv *priv, 91int iwlagn_rx_calib_result(struct iwl_priv *priv,
92 struct iwl_rx_mem_buffer *rxb); 92 struct iwl_rx_mem_buffer *rxb,
93 struct iwl_device_cmd *cmd);
93int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); 94int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
94void iwlagn_send_prio_tbl(struct iwl_priv *priv); 95void iwlagn_send_prio_tbl(struct iwl_priv *priv);
95int iwlagn_run_init_ucode(struct iwl_priv *priv); 96int iwlagn_run_init_ucode(struct iwl_priv *priv);
@@ -116,9 +117,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
116 struct ieee80211_sta *sta, u16 tid, u16 *ssn); 117 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
117int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, 118int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
118 struct ieee80211_sta *sta, u16 tid); 119 struct ieee80211_sta *sta, u16 tid);
119void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, 120int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
120 struct iwl_rx_mem_buffer *rxb); 121 struct iwl_rx_mem_buffer *rxb,
121void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 122 struct iwl_device_cmd *cmd);
123int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
124 struct iwl_device_cmd *cmd);
122 125
123static inline u32 iwl_tx_status_to_mac80211(u32 status) 126static inline u32 iwl_tx_status_to_mac80211(u32 status)
124{ 127{
@@ -155,8 +158,9 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
155 158
156/* bt coex */ 159/* bt coex */
157void iwlagn_send_advance_bt_config(struct iwl_priv *priv); 160void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
158void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, 161int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
159 struct iwl_rx_mem_buffer *rxb); 162 struct iwl_rx_mem_buffer *rxb,
163 struct iwl_device_cmd *cmd);
160void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); 164void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
161void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); 165void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
162void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); 166void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 7f534c45d1fd..4ddaf2c63f50 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -841,8 +841,9 @@ struct iwl_priv {
841 841
842 void (*pre_rx_handler)(struct iwl_priv *priv, 842 void (*pre_rx_handler)(struct iwl_priv *priv,
843 struct iwl_rx_mem_buffer *rxb); 843 struct iwl_rx_mem_buffer *rxb);
844 void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, 844 int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
845 struct iwl_rx_mem_buffer *rxb); 845 struct iwl_rx_mem_buffer *rxb,
846 struct iwl_device_cmd *cmd);
846 847
847 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 848 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
848 849
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 7dffed186f0a..f149165e8010 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -104,7 +104,6 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
104 .len = { sizeof(struct iwl_led_cmd), }, 104 .len = { sizeof(struct iwl_led_cmd), },
105 .data = { led_cmd, }, 105 .data = { led_cmd, },
106 .flags = CMD_ASYNC, 106 .flags = CMD_ASYNC,
107 .callback = NULL,
108 }; 107 };
109 u32 reg; 108 u32 reg;
110 109
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 2ee61031e207..bcd7f64683aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -130,8 +130,9 @@ const char *get_cmd_string(u8 cmd)
130 * 130 *
131 ******************************************************************************/ 131 ******************************************************************************/
132 132
133static void iwl_rx_reply_error(struct iwl_priv *priv, 133static int iwl_rx_reply_error(struct iwl_priv *priv,
134 struct iwl_rx_mem_buffer *rxb) 134 struct iwl_rx_mem_buffer *rxb,
135 struct iwl_device_cmd *cmd)
135{ 136{
136 struct iwl_rx_packet *pkt = rxb_addr(rxb); 137 struct iwl_rx_packet *pkt = rxb_addr(rxb);
137 138
@@ -142,9 +143,11 @@ static void iwl_rx_reply_error(struct iwl_priv *priv,
142 pkt->u.err_resp.cmd_id, 143 pkt->u.err_resp.cmd_id,
143 le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), 144 le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
144 le32_to_cpu(pkt->u.err_resp.error_info)); 145 le32_to_cpu(pkt->u.err_resp.error_info));
146 return 0;
145} 147}
146 148
147static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 149static int iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
150 struct iwl_device_cmd *cmd)
148{ 151{
149 struct iwl_rx_packet *pkt = rxb_addr(rxb); 152 struct iwl_rx_packet *pkt = rxb_addr(rxb);
150 struct iwl_csa_notification *csa = &(pkt->u.csa_notif); 153 struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
@@ -156,7 +159,7 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
156 struct iwl_rxon_cmd *rxon = (void *)&ctx->active; 159 struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
157 160
158 if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) 161 if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status))
159 return; 162 return 0;
160 163
161 if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { 164 if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
162 rxon->channel = csa->channel; 165 rxon->channel = csa->channel;
@@ -169,11 +172,13 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
169 le16_to_cpu(csa->channel)); 172 le16_to_cpu(csa->channel));
170 iwl_chswitch_done(priv, false); 173 iwl_chswitch_done(priv, false);
171 } 174 }
175 return 0;
172} 176}
173 177
174 178
175static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 179static int iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
176 struct iwl_rx_mem_buffer *rxb) 180 struct iwl_rx_mem_buffer *rxb,
181 struct iwl_device_cmd *cmd)
177{ 182{
178 struct iwl_rx_packet *pkt = rxb_addr(rxb); 183 struct iwl_rx_packet *pkt = rxb_addr(rxb);
179 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); 184 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
@@ -181,15 +186,17 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
181 if (!report->state) { 186 if (!report->state) {
182 IWL_DEBUG_11H(priv, 187 IWL_DEBUG_11H(priv,
183 "Spectrum Measure Notification: Start\n"); 188 "Spectrum Measure Notification: Start\n");
184 return; 189 return 0;
185 } 190 }
186 191
187 memcpy(&priv->measure_report, report, sizeof(*report)); 192 memcpy(&priv->measure_report, report, sizeof(*report));
188 priv->measurement_status |= MEASUREMENT_READY; 193 priv->measurement_status |= MEASUREMENT_READY;
194 return 0;
189} 195}
190 196
191static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, 197static int iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
192 struct iwl_rx_mem_buffer *rxb) 198 struct iwl_rx_mem_buffer *rxb,
199 struct iwl_device_cmd *cmd)
193{ 200{
194#ifdef CONFIG_IWLWIFI_DEBUG 201#ifdef CONFIG_IWLWIFI_DEBUG
195 struct iwl_rx_packet *pkt = rxb_addr(rxb); 202 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -197,10 +204,12 @@ static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
197 IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", 204 IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
198 sleep->pm_sleep_mode, sleep->pm_wakeup_src); 205 sleep->pm_sleep_mode, sleep->pm_wakeup_src);
199#endif 206#endif
207 return 0;
200} 208}
201 209
202static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, 210static int iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
203 struct iwl_rx_mem_buffer *rxb) 211 struct iwl_rx_mem_buffer *rxb,
212 struct iwl_device_cmd *cmd)
204{ 213{
205 struct iwl_rx_packet *pkt = rxb_addr(rxb); 214 struct iwl_rx_packet *pkt = rxb_addr(rxb);
206 u32 __maybe_unused len = 215 u32 __maybe_unused len =
@@ -209,10 +218,12 @@ static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
209 "notification for %s:\n", len, 218 "notification for %s:\n", len,
210 get_cmd_string(pkt->hdr.cmd)); 219 get_cmd_string(pkt->hdr.cmd));
211 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); 220 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
221 return 0;
212} 222}
213 223
214static void iwl_rx_beacon_notif(struct iwl_priv *priv, 224static int iwl_rx_beacon_notif(struct iwl_priv *priv,
215 struct iwl_rx_mem_buffer *rxb) 225 struct iwl_rx_mem_buffer *rxb,
226 struct iwl_device_cmd *cmd)
216{ 227{
217 struct iwl_rx_packet *pkt = rxb_addr(rxb); 228 struct iwl_rx_packet *pkt = rxb_addr(rxb);
218 struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; 229 struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw;
@@ -233,6 +244,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
233 244
234 if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) 245 if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
235 queue_work(priv->shrd->workqueue, &priv->beacon_update); 246 queue_work(priv->shrd->workqueue, &priv->beacon_update);
247 return 0;
236} 248}
237 249
238/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ 250/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
@@ -475,8 +487,9 @@ iwl_accumulative_statistics(struct iwl_priv *priv,
475} 487}
476#endif 488#endif
477 489
478static void iwl_rx_statistics(struct iwl_priv *priv, 490static int iwl_rx_statistics(struct iwl_priv *priv,
479 struct iwl_rx_mem_buffer *rxb) 491 struct iwl_rx_mem_buffer *rxb,
492 struct iwl_device_cmd *cmd)
480{ 493{
481 unsigned long stamp = jiffies; 494 unsigned long stamp = jiffies;
482 const int reg_recalib_period = 60; 495 const int reg_recalib_period = 60;
@@ -530,7 +543,7 @@ static void iwl_rx_statistics(struct iwl_priv *priv,
530 WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", 543 WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
531 len, sizeof(struct iwl_bt_notif_statistics), 544 len, sizeof(struct iwl_bt_notif_statistics),
532 sizeof(struct iwl_notif_statistics)); 545 sizeof(struct iwl_notif_statistics));
533 return; 546 return 0;
534 } 547 }
535 548
536 change = common->temperature != priv->statistics.common.temperature || 549 change = common->temperature != priv->statistics.common.temperature ||
@@ -573,10 +586,12 @@ static void iwl_rx_statistics(struct iwl_priv *priv,
573 } 586 }
574 if (priv->cfg->lib->temperature && change) 587 if (priv->cfg->lib->temperature && change)
575 priv->cfg->lib->temperature(priv); 588 priv->cfg->lib->temperature(priv);
589 return 0;
576} 590}
577 591
578static void iwl_rx_reply_statistics(struct iwl_priv *priv, 592static int iwl_rx_reply_statistics(struct iwl_priv *priv,
579 struct iwl_rx_mem_buffer *rxb) 593 struct iwl_rx_mem_buffer *rxb,
594 struct iwl_device_cmd *cmd)
580{ 595{
581 struct iwl_rx_packet *pkt = rxb_addr(rxb); 596 struct iwl_rx_packet *pkt = rxb_addr(rxb);
582 597
@@ -591,13 +606,15 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv,
591#endif 606#endif
592 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 607 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
593 } 608 }
594 iwl_rx_statistics(priv, rxb); 609 iwl_rx_statistics(priv, rxb, cmd);
610 return 0;
595} 611}
596 612
597/* Handle notification from uCode that card's power state is changing 613/* Handle notification from uCode that card's power state is changing
598 * due to software, hardware, or critical temperature RFKILL */ 614 * due to software, hardware, or critical temperature RFKILL */
599static void iwl_rx_card_state_notif(struct iwl_priv *priv, 615static int iwl_rx_card_state_notif(struct iwl_priv *priv,
600 struct iwl_rx_mem_buffer *rxb) 616 struct iwl_rx_mem_buffer *rxb,
617 struct iwl_device_cmd *cmd)
601{ 618{
602 struct iwl_rx_packet *pkt = rxb_addr(rxb); 619 struct iwl_rx_packet *pkt = rxb_addr(rxb);
603 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); 620 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
@@ -645,10 +662,12 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
645 test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); 662 test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
646 else 663 else
647 wake_up(&priv->shrd->wait_command_queue); 664 wake_up(&priv->shrd->wait_command_queue);
665 return 0;
648} 666}
649 667
650static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 668static int iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
651 struct iwl_rx_mem_buffer *rxb) 669 struct iwl_rx_mem_buffer *rxb,
670 struct iwl_device_cmd *cmd)
652 671
653{ 672{
654 struct iwl_rx_packet *pkt = rxb_addr(rxb); 673 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -666,18 +685,21 @@ static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
666 if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) 685 if (!test_bit(STATUS_SCANNING, &priv->shrd->status))
667 iwl_init_sensitivity(priv); 686 iwl_init_sensitivity(priv);
668 } 687 }
688 return 0;
669} 689}
670 690
671/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). 691/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
672 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ 692 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
673static void iwl_rx_reply_rx_phy(struct iwl_priv *priv, 693static int iwl_rx_reply_rx_phy(struct iwl_priv *priv,
674 struct iwl_rx_mem_buffer *rxb) 694 struct iwl_rx_mem_buffer *rxb,
695 struct iwl_device_cmd *cmd)
675{ 696{
676 struct iwl_rx_packet *pkt = rxb_addr(rxb); 697 struct iwl_rx_packet *pkt = rxb_addr(rxb);
677 698
678 priv->last_phy_res_valid = true; 699 priv->last_phy_res_valid = true;
679 memcpy(&priv->last_phy_res, pkt->u.raw, 700 memcpy(&priv->last_phy_res, pkt->u.raw,
680 sizeof(struct iwl_rx_phy_res)); 701 sizeof(struct iwl_rx_phy_res));
702 return 0;
681} 703}
682 704
683/* 705/*
@@ -892,8 +914,9 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
892 914
893/* Called for REPLY_RX (legacy ABG frames), or 915/* Called for REPLY_RX (legacy ABG frames), or
894 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ 916 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
895static void iwl_rx_reply_rx(struct iwl_priv *priv, 917static int iwl_rx_reply_rx(struct iwl_priv *priv,
896 struct iwl_rx_mem_buffer *rxb) 918 struct iwl_rx_mem_buffer *rxb,
919 struct iwl_device_cmd *cmd)
897{ 920{
898 struct ieee80211_hdr *header; 921 struct ieee80211_hdr *header;
899 struct ieee80211_rx_status rx_status; 922 struct ieee80211_rx_status rx_status;
@@ -926,7 +949,7 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
926 } else { 949 } else {
927 if (!priv->last_phy_res_valid) { 950 if (!priv->last_phy_res_valid) {
928 IWL_ERR(priv, "MPDU frame without cached PHY data\n"); 951 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
929 return; 952 return 0;
930 } 953 }
931 phy_res = &priv->last_phy_res; 954 phy_res = &priv->last_phy_res;
932 amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; 955 amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
@@ -940,14 +963,14 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
940 if ((unlikely(phy_res->cfg_phy_cnt > 20))) { 963 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
941 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", 964 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
942 phy_res->cfg_phy_cnt); 965 phy_res->cfg_phy_cnt);
943 return; 966 return 0;
944 } 967 }
945 968
946 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || 969 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
947 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { 970 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
948 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", 971 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
949 le32_to_cpu(rx_pkt_status)); 972 le32_to_cpu(rx_pkt_status));
950 return; 973 return 0;
951 } 974 }
952 975
953 /* This will be used in several places later */ 976 /* This will be used in several places later */
@@ -1008,6 +1031,7 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
1008 1031
1009 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, 1032 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1010 rxb, &rx_status); 1033 rxb, &rx_status);
1034 return 0;
1011} 1035}
1012 1036
1013/** 1037/**
@@ -1018,7 +1042,8 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
1018 */ 1042 */
1019void iwl_setup_rx_handlers(struct iwl_priv *priv) 1043void iwl_setup_rx_handlers(struct iwl_priv *priv)
1020{ 1044{
1021 void (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 1045 int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
1046 struct iwl_device_cmd *cmd);
1022 1047
1023 handlers = priv->rx_handlers; 1048 handlers = priv->rx_handlers;
1024 1049
@@ -1028,6 +1053,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
1028 handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 1053 handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
1029 handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif; 1054 handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif;
1030 handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; 1055 handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
1056 handlers[REPLY_ADD_STA] = iwl_add_sta_callback;
1031 1057
1032 /* 1058 /*
1033 * The same handler is used for both the REPLY to a discrete 1059 * The same handler is used for both the REPLY to a discrete
@@ -1065,9 +1091,11 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
1065 1091
1066} 1092}
1067 1093
1068void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 1094int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
1095 struct iwl_device_cmd *cmd)
1069{ 1096{
1070 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1097 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1098 int err = 0;
1071 1099
1072 /* 1100 /*
1073 * Do the notification wait before RX handlers so 1101 * Do the notification wait before RX handlers so
@@ -1102,11 +1130,12 @@ void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1102 * rx_handlers table. See iwl_setup_rx_handlers() */ 1130 * rx_handlers table. See iwl_setup_rx_handlers() */
1103 if (priv->rx_handlers[pkt->hdr.cmd]) { 1131 if (priv->rx_handlers[pkt->hdr.cmd]) {
1104 priv->rx_handlers_stats[pkt->hdr.cmd]++; 1132 priv->rx_handlers_stats[pkt->hdr.cmd]++;
1105 priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); 1133 err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
1106 } else { 1134 } else {
1107 /* No handling needed */ 1135 /* No handling needed */
1108 IWL_DEBUG_RX(priv, 1136 IWL_DEBUG_RX(priv,
1109 "No handler needed for %s, 0x%02x\n", 1137 "No handler needed for %s, 0x%02x\n",
1110 get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); 1138 get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
1111 } 1139 }
1140 return err;
1112} 1141}
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 8386a86e2ca2..2b6db24daf70 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -189,8 +189,9 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
189} 189}
190 190
191/* Service response to REPLY_SCAN_CMD (0x80) */ 191/* Service response to REPLY_SCAN_CMD (0x80) */
192static void iwl_rx_reply_scan(struct iwl_priv *priv, 192static int iwl_rx_reply_scan(struct iwl_priv *priv,
193 struct iwl_rx_mem_buffer *rxb) 193 struct iwl_rx_mem_buffer *rxb,
194 struct iwl_device_cmd *cmd)
194{ 195{
195#ifdef CONFIG_IWLWIFI_DEBUG 196#ifdef CONFIG_IWLWIFI_DEBUG
196 struct iwl_rx_packet *pkt = rxb_addr(rxb); 197 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -199,11 +200,13 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
199 200
200 IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); 201 IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
201#endif 202#endif
203 return 0;
202} 204}
203 205
204/* Service SCAN_START_NOTIFICATION (0x82) */ 206/* Service SCAN_START_NOTIFICATION (0x82) */
205static void iwl_rx_scan_start_notif(struct iwl_priv *priv, 207static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
206 struct iwl_rx_mem_buffer *rxb) 208 struct iwl_rx_mem_buffer *rxb,
209 struct iwl_device_cmd *cmd)
207{ 210{
208 struct iwl_rx_packet *pkt = rxb_addr(rxb); 211 struct iwl_rx_packet *pkt = rxb_addr(rxb);
209 struct iwl_scanstart_notification *notif = 212 struct iwl_scanstart_notification *notif =
@@ -223,11 +226,14 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
223 ieee80211_ready_on_channel(priv->hw); 226 ieee80211_ready_on_channel(priv->hw);
224 priv->hw_roc_start_notified = true; 227 priv->hw_roc_start_notified = true;
225 } 228 }
229
230 return 0;
226} 231}
227 232
228/* Service SCAN_RESULTS_NOTIFICATION (0x83) */ 233/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
229static void iwl_rx_scan_results_notif(struct iwl_priv *priv, 234static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
230 struct iwl_rx_mem_buffer *rxb) 235 struct iwl_rx_mem_buffer *rxb,
236 struct iwl_device_cmd *cmd)
231{ 237{
232#ifdef CONFIG_IWLWIFI_DEBUG 238#ifdef CONFIG_IWLWIFI_DEBUG
233 struct iwl_rx_packet *pkt = rxb_addr(rxb); 239 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -245,11 +251,13 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
245 le32_to_cpu(notif->statistics[0]), 251 le32_to_cpu(notif->statistics[0]),
246 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf); 252 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
247#endif 253#endif
254 return 0;
248} 255}
249 256
250/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ 257/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
251static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, 258static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
252 struct iwl_rx_mem_buffer *rxb) 259 struct iwl_rx_mem_buffer *rxb,
260 struct iwl_device_cmd *cmd)
253{ 261{
254 struct iwl_rx_packet *pkt = rxb_addr(rxb); 262 struct iwl_rx_packet *pkt = rxb_addr(rxb);
255 struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; 263 struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
@@ -289,6 +297,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
289 queue_work(priv->shrd->workqueue, 297 queue_work(priv->shrd->workqueue,
290 &priv->bt_traffic_change_work); 298 &priv->bt_traffic_change_work);
291 } 299 }
300 return 0;
292} 301}
293 302
294void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) 303void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index 40186a61f20a..7abafe16de9a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -423,8 +423,11 @@ enum iwl_rxon_context_id {
423int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, 423int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
424 struct iwl_cfg *cfg); 424 struct iwl_cfg *cfg);
425void __devexit iwl_remove(struct iwl_priv * priv); 425void __devexit iwl_remove(struct iwl_priv * priv);
426struct iwl_device_cmd;
427int __must_check iwl_rx_dispatch(struct iwl_priv *priv,
428 struct iwl_rx_mem_buffer *rxb,
429 struct iwl_device_cmd *cmd);
426 430
427void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
428int iwlagn_hw_valid_rtc_data_addr(u32 addr); 431int iwlagn_hw_valid_rtc_data_addr(u32 addr);
429void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv, 432void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv,
430 enum iwl_rxon_context_id ctx, 433 enum iwl_rxon_context_id ctx,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index f35cfa2fe5c5..7028f907e600 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -59,8 +59,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
59 59
60static int iwl_process_add_sta_resp(struct iwl_priv *priv, 60static int iwl_process_add_sta_resp(struct iwl_priv *priv,
61 struct iwl_addsta_cmd *addsta, 61 struct iwl_addsta_cmd *addsta,
62 struct iwl_rx_packet *pkt, 62 struct iwl_rx_packet *pkt)
63 bool sync)
64{ 63{
65 u8 sta_id = addsta->sta.sta_id; 64 u8 sta_id = addsta->sta.sta_id;
66 unsigned long flags; 65 unsigned long flags;
@@ -123,15 +122,14 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
123 return ret; 122 return ret;
124} 123}
125 124
126static void iwl_add_sta_callback(struct iwl_shared *shrd, 125int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
127 struct iwl_device_cmd *cmd, 126 struct iwl_device_cmd *cmd)
128 struct iwl_rx_packet *pkt)
129{ 127{
128 struct iwl_rx_packet *pkt = rxb_addr(rxb);
130 struct iwl_addsta_cmd *addsta = 129 struct iwl_addsta_cmd *addsta =
131 (struct iwl_addsta_cmd *)cmd->cmd.payload; 130 (struct iwl_addsta_cmd *)cmd->cmd.payload;
132 131
133 iwl_process_add_sta_resp(shrd->priv, addsta, pkt, false); 132 return iwl_process_add_sta_resp(priv, addsta, pkt);
134
135} 133}
136 134
137static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) 135static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
@@ -147,7 +145,6 @@ static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
147int iwl_send_add_sta(struct iwl_priv *priv, 145int iwl_send_add_sta(struct iwl_priv *priv,
148 struct iwl_addsta_cmd *sta, u8 flags) 146 struct iwl_addsta_cmd *sta, u8 flags)
149{ 147{
150 struct iwl_rx_packet *pkt = NULL;
151 int ret = 0; 148 int ret = 0;
152 u8 data[sizeof(*sta)]; 149 u8 data[sizeof(*sta)];
153 struct iwl_host_cmd cmd = { 150 struct iwl_host_cmd cmd = {
@@ -160,9 +157,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
160 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n", 157 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
161 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); 158 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
162 159
163 if (flags & CMD_ASYNC) 160 if (!(flags & CMD_ASYNC)) {
164 cmd.callback = iwl_add_sta_callback;
165 else {
166 cmd.flags |= CMD_WANT_SKB; 161 cmd.flags |= CMD_WANT_SKB;
167 might_sleep(); 162 might_sleep();
168 } 163 }
@@ -172,14 +167,16 @@ int iwl_send_add_sta(struct iwl_priv *priv,
172 167
173 if (ret || (flags & CMD_ASYNC)) 168 if (ret || (flags & CMD_ASYNC))
174 return ret; 169 return ret;
170 /*else the command was successfully sent in SYNC mode, need to free
171 * the reply page */
175 172
176 if (ret == 0) {
177 pkt = (struct iwl_rx_packet *)cmd.reply_page;
178 ret = iwl_process_add_sta_resp(priv, sta, pkt, true);
179 }
180 iwl_free_pages(priv->shrd, cmd.reply_page); 173 iwl_free_pages(priv->shrd, cmd.reply_page);
181 174
182 return ret; 175 if (cmd.handler_status)
176 IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
177 cmd.handler_status);
178
179 return cmd.handler_status;
183} 180}
184 181
185static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, 182static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 02491b930423..1bca0dabde8d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -61,6 +61,9 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
61int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 61int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
62 struct iwl_link_quality_cmd *lq, u8 flags, bool init); 62 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
63void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 63void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
64int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
65 struct iwl_device_cmd *cmd);
66
64 67
65/** 68/**
66 * iwl_clear_driver_stations - clear knowledge of all stations from driver 69 * iwl_clear_driver_stations - clear knowledge of all stations from driver
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
index 49cd5a768280..0e7d915b547f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
@@ -118,16 +118,6 @@ struct iwl_dma_ptr {
118struct iwl_cmd_meta { 118struct iwl_cmd_meta {
119 /* only for SYNC commands, iff the reply skb is wanted */ 119 /* only for SYNC commands, iff the reply skb is wanted */
120 struct iwl_host_cmd *source; 120 struct iwl_host_cmd *source;
121 /*
122 * only for ASYNC commands
123 * (which is somewhat stupid -- look at iwl-sta.c for instance
124 * which duplicates a bunch of code because the callback isn't
125 * invoked for SYNC commands, if it were and its result passed
126 * through it would be simpler...)
127 */
128 void (*callback)(struct iwl_shared *shrd,
129 struct iwl_device_cmd *cmd,
130 struct iwl_rx_packet *pkt);
131 121
132 u32 flags; 122 u32 flags;
133 123
@@ -288,7 +278,7 @@ int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
288int __must_check iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id, 278int __must_check iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id,
289 u32 flags, u16 len, const void *data); 279 u32 flags, u16 len, const void *data);
290void iwl_tx_cmd_complete(struct iwl_trans *trans, 280void iwl_tx_cmd_complete(struct iwl_trans *trans,
291 struct iwl_rx_mem_buffer *rxb); 281 struct iwl_rx_mem_buffer *rxb, int handler_status);
292void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, 282void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
293 struct iwl_tx_queue *txq, 283 struct iwl_tx_queue *txq,
294 u16 byte_cnt); 284 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 6f3f07dd817d..3ef9eac02ff4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
@@ -372,12 +372,15 @@ static void iwl_rx_handle(struct iwl_trans *trans)
372 struct iwl_trans_pcie *trans_pcie = 372 struct iwl_trans_pcie *trans_pcie =
373 IWL_TRANS_GET_PCIE_TRANS(trans); 373 IWL_TRANS_GET_PCIE_TRANS(trans);
374 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 374 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
375 struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
376 struct iwl_device_cmd *cmd;
375 u32 r, i; 377 u32 r, i;
376 int reclaim; 378 int reclaim;
377 unsigned long flags; 379 unsigned long flags;
378 u8 fill_rx = 0; 380 u8 fill_rx = 0;
379 u32 count = 8; 381 u32 count = 8;
380 int total_empty; 382 int total_empty;
383 int index, cmd_index;
381 384
382 /* uCode's read index (stored in shared DRAM) indicates the last Rx 385 /* uCode's read index (stored in shared DRAM) indicates the last Rx
383 * buffer that the driver may process (last buffer filled by ucode). */ 386 * buffer that the driver may process (last buffer filled by ucode). */
@@ -397,7 +400,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
397 fill_rx = 1; 400 fill_rx = 1;
398 401
399 while (i != r) { 402 while (i != r) {
400 int len; 403 int len, err;
401 u16 txq_id, sequence; 404 u16 txq_id, sequence;
402 405
403 rxb = rxq->queue[i]; 406 rxb = rxq->queue[i];
@@ -439,7 +442,13 @@ static void iwl_rx_handle(struct iwl_trans *trans)
439 (pkt->hdr.cmd != REPLY_TX); 442 (pkt->hdr.cmd != REPLY_TX);
440 443
441 sequence = le16_to_cpu(pkt->hdr.sequence); 444 sequence = le16_to_cpu(pkt->hdr.sequence);
442 txq_id = SEQ_TO_QUEUE(le16_to_cpu(pkt->hdr.sequence)); 445 index = SEQ_TO_INDEX(sequence);
446 cmd_index = get_cmd_index(&txq->q, index);
447
448 if (reclaim)
449 cmd = txq->cmd[cmd_index];
450 else
451 cmd = NULL;
443 452
444 /* warn if this is cmd response / notification and the uCode 453 /* warn if this is cmd response / notification and the uCode
445 * didn't set the SEQ_RX_FRAME for a frame that is 454 * didn't set the SEQ_RX_FRAME for a frame that is
@@ -449,7 +458,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
449 "reclaim is false, SEQ_RX_FRAME unset: %s\n", 458 "reclaim is false, SEQ_RX_FRAME unset: %s\n",
450 get_cmd_string(pkt->hdr.cmd)); 459 get_cmd_string(pkt->hdr.cmd));
451 460
452 iwl_rx_dispatch(priv(trans), rxb); 461 err = iwl_rx_dispatch(priv(trans), rxb, cmd);
453 462
454 /* 463 /*
455 * XXX: After here, we should always check rxb->page 464 * XXX: After here, we should always check rxb->page
@@ -464,7 +473,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
464 * iwl_trans_send_cmd() 473 * iwl_trans_send_cmd()
465 * as we reclaim the driver command queue */ 474 * as we reclaim the driver command queue */
466 if (rxb->page) 475 if (rxb->page)
467 iwl_tx_cmd_complete(trans, rxb); 476 iwl_tx_cmd_complete(trans, rxb, err);
468 else 477 else
469 IWL_WARN(trans, "Claim null rxb?\n"); 478 IWL_WARN(trans, "Claim null rxb?\n");
470 } 479 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index 031a291a13dc..48ef6c25d5bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -762,8 +762,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
762 memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ 762 memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
763 if (cmd->flags & CMD_WANT_SKB) 763 if (cmd->flags & CMD_WANT_SKB)
764 out_meta->source = cmd; 764 out_meta->source = cmd;
765 if (cmd->flags & CMD_ASYNC)
766 out_meta->callback = cmd->callback;
767 765
768 /* set up the header */ 766 /* set up the header */
769 767
@@ -894,12 +892,15 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
894/** 892/**
895 * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them 893 * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
896 * @rxb: Rx buffer to reclaim 894 * @rxb: Rx buffer to reclaim
895 * @handler_status: return value of the handler of the command
896 * (put in setup_rx_handlers)
897 * 897 *
898 * If an Rx buffer has an async callback associated with it the callback 898 * If an Rx buffer has an async callback associated with it the callback
899 * will be executed. The attached skb (if present) will only be freed 899 * will be executed. The attached skb (if present) will only be freed
900 * if the callback returns 1 900 * if the callback returns 1
901 */ 901 */
902void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) 902void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
903 int handler_status)
903{ 904{
904 struct iwl_rx_packet *pkt = rxb_addr(rxb); 905 struct iwl_rx_packet *pkt = rxb_addr(rxb);
905 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 906 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -936,9 +937,9 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb)
936 /* Input error checking is done when commands are added to queue. */ 937 /* Input error checking is done when commands are added to queue. */
937 if (meta->flags & CMD_WANT_SKB) { 938 if (meta->flags & CMD_WANT_SKB) {
938 meta->source->reply_page = (unsigned long)rxb_addr(rxb); 939 meta->source->reply_page = (unsigned long)rxb_addr(rxb);
940 meta->source->handler_status = handler_status;
939 rxb->page = NULL; 941 rxb->page = NULL;
940 } else if (meta->callback) 942 }
941 meta->callback(trans->shrd, cmd, pkt);
942 943
943 spin_lock_irqsave(&trans->hcmd_lock, flags); 944 spin_lock_irqsave(&trans->hcmd_lock, flags);
944 945
@@ -958,30 +959,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb)
958 959
959#define HOST_COMPLETE_TIMEOUT (2 * HZ) 960#define HOST_COMPLETE_TIMEOUT (2 * HZ)
960 961
961static void iwl_generic_cmd_callback(struct iwl_shared *shrd,
962 struct iwl_device_cmd *cmd,
963 struct iwl_rx_packet *pkt)
964{
965 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
966 IWL_ERR(shrd->trans, "Bad return from %s (0x%08X)\n",
967 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
968 return;
969 }
970
971#ifdef CONFIG_IWLWIFI_DEBUG
972 switch (cmd->hdr.cmd) {
973 case REPLY_TX_LINK_QUALITY_CMD:
974 case SENSITIVITY_CMD:
975 IWL_DEBUG_HC_DUMP(shrd->trans, "back from %s (0x%08X)\n",
976 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
977 break;
978 default:
979 IWL_DEBUG_HC(shrd->trans, "back from %s (0x%08X)\n",
980 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
981 }
982#endif
983}
984
985static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) 962static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
986{ 963{
987 int ret; 964 int ret;
@@ -990,9 +967,6 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
990 if (WARN_ON(cmd->flags & CMD_WANT_SKB)) 967 if (WARN_ON(cmd->flags & CMD_WANT_SKB))
991 return -EINVAL; 968 return -EINVAL;
992 969
993 /* Assign a generic callback if one is not provided */
994 if (!cmd->callback)
995 cmd->callback = iwl_generic_cmd_callback;
996 970
997 if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) 971 if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
998 return -EBUSY; 972 return -EBUSY;
@@ -1014,10 +988,6 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
1014 988
1015 lockdep_assert_held(&trans->shrd->mutex); 989 lockdep_assert_held(&trans->shrd->mutex);
1016 990
1017 /* A synchronous command can not have a callback set. */
1018 if (WARN_ON(cmd->callback))
1019 return -EINVAL;
1020
1021 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", 991 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
1022 get_cmd_string(cmd->id)); 992 get_cmd_string(cmd->id));
1023 993
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 5b6e6842d5fc..ddb7741bed66 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -120,6 +120,8 @@ enum iwl_hcmd_dataflag {
120 * struct iwl_host_cmd - Host command to the uCode 120 * struct iwl_host_cmd - Host command to the uCode
121 * @data: array of chunks that composes the data of the host command 121 * @data: array of chunks that composes the data of the host command
122 * @reply_page: pointer to the page that holds the response to the host command 122 * @reply_page: pointer to the page that holds the response to the host command
123 * @handler_status: return value of the handler of the command
124 * (put in setup_rx_handlers) - valid for SYNC mode only
123 * @callback: 125 * @callback:
124 * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC 126 * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
125 * @len: array of the lenths of the chunks in data 127 * @len: array of the lenths of the chunks in data
@@ -129,9 +131,8 @@ enum iwl_hcmd_dataflag {
129struct iwl_host_cmd { 131struct iwl_host_cmd {
130 const void *data[IWL_MAX_CMD_TFDS]; 132 const void *data[IWL_MAX_CMD_TFDS];
131 unsigned long reply_page; 133 unsigned long reply_page;
132 void (*callback)(struct iwl_shared *shrd, 134 int handler_status;
133 struct iwl_device_cmd *cmd, 135
134 struct iwl_rx_packet *pkt);
135 u32 flags; 136 u32 flags;
136 u16 len[IWL_MAX_CMD_TFDS]; 137 u16 len[IWL_MAX_CMD_TFDS];
137 u8 dataflags[IWL_MAX_CMD_TFDS]; 138 u8 dataflags[IWL_MAX_CMD_TFDS];