aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-rx.c
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 /drivers/net/wireless/iwlwifi/iwl-rx.c
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>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-rx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c95
1 files changed, 62 insertions, 33 deletions
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}