aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-rx.c
diff options
context:
space:
mode:
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}