aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-rx.c
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2011-03-04 11:51:49 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-03-04 14:06:50 -0500
commit466a19a003f3b45a755bc85f967c21da947f9a00 (patch)
treeca346e832982a54da9751b411322113c35e2d897 /drivers/net/wireless/iwlwifi/iwl-rx.c
parent9d468d2269b64222a706f52b965998ee64d0b4bf (diff)
iwlwifi: move rx handlers code to iwl-rx.c
Put generic rx_handlers (except iwlagn_rx_reply_compressed_ba) to iwl-rx.c . Make functions static and change prefix from iwlagn_ to iwl_ . Beautify iwl_setup_rx_handlers and do some other minor coding style changes. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Acked-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.c523
1 files changed, 498 insertions, 25 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 566e2d979ce3..8dc129499b90 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -38,7 +38,14 @@
38#include "iwl-io.h" 38#include "iwl-io.h"
39#include "iwl-helpers.h" 39#include "iwl-helpers.h"
40#include "iwl-agn-calib.h" 40#include "iwl-agn-calib.h"
41/************************** RX-FUNCTIONS ****************************/ 41#include "iwl-agn.h"
42
43/******************************************************************************
44 *
45 * RX path functions
46 *
47 ******************************************************************************/
48
42/* 49/*
43 * Rx theory of operation 50 * Rx theory of operation
44 * 51 *
@@ -211,7 +218,104 @@ err_bd:
211 return -ENOMEM; 218 return -ENOMEM;
212} 219}
213 220
214void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 221/******************************************************************************
222 *
223 * Generic RX handler implementations
224 *
225 ******************************************************************************/
226
227static void iwl_rx_reply_alive(struct iwl_priv *priv,
228 struct iwl_rx_mem_buffer *rxb)
229{
230 struct iwl_rx_packet *pkt = rxb_addr(rxb);
231 struct iwl_alive_resp *palive;
232 struct delayed_work *pwork;
233
234 palive = &pkt->u.alive_frame;
235
236 IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
237 "0x%01X 0x%01X\n",
238 palive->is_valid, palive->ver_type,
239 palive->ver_subtype);
240
241 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
242 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
243 memcpy(&priv->card_alive_init,
244 &pkt->u.alive_frame,
245 sizeof(struct iwl_init_alive_resp));
246 pwork = &priv->init_alive_start;
247 } else {
248 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
249 memcpy(&priv->card_alive, &pkt->u.alive_frame,
250 sizeof(struct iwl_alive_resp));
251 pwork = &priv->alive_start;
252 }
253
254 /* We delay the ALIVE response by 5ms to
255 * give the HW RF Kill time to activate... */
256 if (palive->is_valid == UCODE_VALID_OK)
257 queue_delayed_work(priv->workqueue, pwork,
258 msecs_to_jiffies(5));
259 else {
260 IWL_WARN(priv, "%s uCode did not respond OK.\n",
261 (palive->ver_subtype == INITIALIZE_SUBTYPE) ?
262 "init" : "runtime");
263 /*
264 * If fail to load init uCode,
265 * let's try to load the init uCode again.
266 * We should not get into this situation, but if it
267 * does happen, we should not move on and loading "runtime"
268 * without proper calibrate the device.
269 */
270 if (palive->ver_subtype == INITIALIZE_SUBTYPE)
271 priv->ucode_type = UCODE_NONE;
272 queue_work(priv->workqueue, &priv->restart);
273 }
274}
275
276static void iwl_rx_reply_error(struct iwl_priv *priv,
277 struct iwl_rx_mem_buffer *rxb)
278{
279 struct iwl_rx_packet *pkt = rxb_addr(rxb);
280
281 IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
282 "seq 0x%04X ser 0x%08X\n",
283 le32_to_cpu(pkt->u.err_resp.error_type),
284 get_cmd_string(pkt->u.err_resp.cmd_id),
285 pkt->u.err_resp.cmd_id,
286 le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
287 le32_to_cpu(pkt->u.err_resp.error_info));
288}
289
290static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
291{
292 struct iwl_rx_packet *pkt = rxb_addr(rxb);
293 struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
294 /*
295 * MULTI-FIXME
296 * See iwl_mac_channel_switch.
297 */
298 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
299 struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
300
301 if (priv->switch_rxon.switch_in_progress) {
302 if (!le32_to_cpu(csa->status) &&
303 (csa->channel == priv->switch_rxon.channel)) {
304 rxon->channel = csa->channel;
305 ctx->staging.channel = csa->channel;
306 IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
307 le16_to_cpu(csa->channel));
308 iwl_chswitch_done(priv, true);
309 } else {
310 IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
311 le16_to_cpu(csa->channel));
312 iwl_chswitch_done(priv, false);
313 }
314 }
315}
316
317
318static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
215 struct iwl_rx_mem_buffer *rxb) 319 struct iwl_rx_mem_buffer *rxb)
216{ 320{
217 struct iwl_rx_packet *pkt = rxb_addr(rxb); 321 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -227,6 +331,52 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
227 priv->measurement_status |= MEASUREMENT_READY; 331 priv->measurement_status |= MEASUREMENT_READY;
228} 332}
229 333
334static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
335 struct iwl_rx_mem_buffer *rxb)
336{
337#ifdef CONFIG_IWLWIFI_DEBUG
338 struct iwl_rx_packet *pkt = rxb_addr(rxb);
339 struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
340 IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
341 sleep->pm_sleep_mode, sleep->pm_wakeup_src);
342#endif
343}
344
345static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
346 struct iwl_rx_mem_buffer *rxb)
347{
348 struct iwl_rx_packet *pkt = rxb_addr(rxb);
349 u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
350 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
351 "notification for %s:\n", len,
352 get_cmd_string(pkt->hdr.cmd));
353 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
354}
355
356static void iwl_rx_beacon_notif(struct iwl_priv *priv,
357 struct iwl_rx_mem_buffer *rxb)
358{
359 struct iwl_rx_packet *pkt = rxb_addr(rxb);
360 struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw;
361#ifdef CONFIG_IWLWIFI_DEBUG
362 u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status);
363 u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
364
365 IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d "
366 "tsf:0x%.8x%.8x rate:%d\n",
367 status & TX_STATUS_MSK,
368 beacon->beacon_notify_hdr.failure_frame,
369 le32_to_cpu(beacon->ibss_mgr_status),
370 le32_to_cpu(beacon->high_tsf),
371 le32_to_cpu(beacon->low_tsf), rate);
372#endif
373
374 priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
375
376 if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
377 queue_work(priv->workqueue, &priv->beacon_update);
378}
379
230/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ 380/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
231#define ACK_CNT_RATIO (50) 381#define ACK_CNT_RATIO (50)
232#define BA_TIMEOUT_CNT (5) 382#define BA_TIMEOUT_CNT (5)
@@ -298,7 +448,8 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt
298 * When the plcp error is exceeding the thresholds, reset the radio 448 * When the plcp error is exceeding the thresholds, reset the radio
299 * to improve the throughput. 449 * to improve the throughput.
300 */ 450 */
301static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) 451static bool iwl_good_plcp_health(struct iwl_priv *priv,
452 struct iwl_rx_packet *pkt)
302{ 453{
303 bool rc = true; 454 bool rc = true;
304 int combined_plcp_delta; 455 int combined_plcp_delta;
@@ -378,7 +529,8 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pk
378 return rc; 529 return rc;
379} 530}
380 531
381static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) 532static void iwl_recover_from_statistics(struct iwl_priv *priv,
533 struct iwl_rx_packet *pkt)
382{ 534{
383 const struct iwl_mod_params *mod_params = priv->cfg->mod_params; 535 const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
384 536
@@ -442,7 +594,6 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
442 last_rx_noise); 594 last_rx_noise);
443} 595}
444 596
445#ifdef CONFIG_IWLWIFI_DEBUGFS
446/* 597/*
447 * based on the assumption of all statistics counter are in DWORD 598 * based on the assumption of all statistics counter are in DWORD
448 * FIXME: This function is for debugging, do not deal with 599 * FIXME: This function is for debugging, do not deal with
@@ -451,6 +602,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
451static void iwl_accumulative_statistics(struct iwl_priv *priv, 602static void iwl_accumulative_statistics(struct iwl_priv *priv,
452 __le32 *stats) 603 __le32 *stats)
453{ 604{
605#ifdef CONFIG_IWLWIFI_DEBUGFS
454 int i, size; 606 int i, size;
455 __le32 *prev_stats; 607 __le32 *prev_stats;
456 u32 *accum_stats; 608 u32 *accum_stats;
@@ -498,14 +650,13 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
498 accum_tx->tx_power.ant_a = tx->tx_power.ant_a; 650 accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
499 accum_tx->tx_power.ant_b = tx->tx_power.ant_b; 651 accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
500 accum_tx->tx_power.ant_c = tx->tx_power.ant_c; 652 accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
501}
502#endif 653#endif
654}
503 655
504#define REG_RECALIB_PERIOD (60) 656static void iwl_rx_statistics(struct iwl_priv *priv,
505
506void iwl_rx_statistics(struct iwl_priv *priv,
507 struct iwl_rx_mem_buffer *rxb) 657 struct iwl_rx_mem_buffer *rxb)
508{ 658{
659 const int reg_recalib_period = 60;
509 int change; 660 int change;
510 struct iwl_rx_packet *pkt = rxb_addr(rxb); 661 struct iwl_rx_packet *pkt = rxb_addr(rxb);
511 662
@@ -522,10 +673,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
522 STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 673 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
523 (pkt->u.stats_bt.flag & 674 (pkt->u.stats_bt.flag &
524 STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 675 STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
525#ifdef CONFIG_IWLWIFI_DEBUGFS
526 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
527#endif
528 676
677 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
529 } else { 678 } else {
530 IWL_DEBUG_RX(priv, 679 IWL_DEBUG_RX(priv,
531 "Statistics notification received (%d vs %d).\n", 680 "Statistics notification received (%d vs %d).\n",
@@ -539,10 +688,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
539 STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 688 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
540 (pkt->u.stats.flag & 689 (pkt->u.stats.flag &
541 STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 690 STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
542#ifdef CONFIG_IWLWIFI_DEBUGFS
543 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
544#endif
545 691
692 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
546 } 693 }
547 694
548 iwl_recover_from_statistics(priv, pkt); 695 iwl_recover_from_statistics(priv, pkt);
@@ -557,11 +704,11 @@ void iwl_rx_statistics(struct iwl_priv *priv,
557 set_bit(STATUS_STATISTICS, &priv->status); 704 set_bit(STATUS_STATISTICS, &priv->status);
558 705
559 /* Reschedule the statistics timer to occur in 706 /* Reschedule the statistics timer to occur in
560 * REG_RECALIB_PERIOD seconds to ensure we get a 707 * reg_recalib_period seconds to ensure we get a
561 * thermal update even if the uCode doesn't give 708 * thermal update even if the uCode doesn't give
562 * us one */ 709 * us one */
563 mod_timer(&priv->statistics_periodic, jiffies + 710 mod_timer(&priv->statistics_periodic, jiffies +
564 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); 711 msecs_to_jiffies(reg_recalib_period * 1000));
565 712
566 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && 713 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
567 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { 714 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
@@ -572,8 +719,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
572 priv->cfg->ops->lib->temp_ops.temperature(priv); 719 priv->cfg->ops->lib->temp_ops.temperature(priv);
573} 720}
574 721
575void iwl_reply_statistics(struct iwl_priv *priv, 722static void iwl_rx_reply_statistics(struct iwl_priv *priv,
576 struct iwl_rx_mem_buffer *rxb) 723 struct iwl_rx_mem_buffer *rxb)
577{ 724{
578 struct iwl_rx_packet *pkt = rxb_addr(rxb); 725 struct iwl_rx_packet *pkt = rxb_addr(rxb);
579 726
@@ -597,8 +744,61 @@ void iwl_reply_statistics(struct iwl_priv *priv,
597 iwl_rx_statistics(priv, rxb); 744 iwl_rx_statistics(priv, rxb);
598} 745}
599 746
600void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 747/* Handle notification from uCode that card's power state is changing
601 struct iwl_rx_mem_buffer *rxb) 748 * due to software, hardware, or critical temperature RFKILL */
749static void iwl_rx_card_state_notif(struct iwl_priv *priv,
750 struct iwl_rx_mem_buffer *rxb)
751{
752 struct iwl_rx_packet *pkt = rxb_addr(rxb);
753 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
754 unsigned long status = priv->status;
755
756 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
757 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
758 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
759 (flags & CT_CARD_DISABLED) ?
760 "Reached" : "Not reached");
761
762 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
763 CT_CARD_DISABLED)) {
764
765 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
766 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
767
768 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
769 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
770
771 if (!(flags & RXON_CARD_DISABLED)) {
772 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
773 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
774 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
775 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
776 }
777 if (flags & CT_CARD_DISABLED)
778 iwl_tt_enter_ct_kill(priv);
779 }
780 if (!(flags & CT_CARD_DISABLED))
781 iwl_tt_exit_ct_kill(priv);
782
783 if (flags & HW_CARD_DISABLED)
784 set_bit(STATUS_RF_KILL_HW, &priv->status);
785 else
786 clear_bit(STATUS_RF_KILL_HW, &priv->status);
787
788
789 if (!(flags & RXON_CARD_DISABLED))
790 iwl_scan_cancel(priv);
791
792 if ((test_bit(STATUS_RF_KILL_HW, &status) !=
793 test_bit(STATUS_RF_KILL_HW, &priv->status)))
794 wiphy_rfkill_set_hw_state(priv->hw->wiphy,
795 test_bit(STATUS_RF_KILL_HW, &priv->status));
796 else
797 wake_up_interruptible(&priv->wait_command_queue);
798}
799
800static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
801 struct iwl_rx_mem_buffer *rxb)
602 802
603{ 803{
604 struct iwl_rx_packet *pkt = rxb_addr(rxb); 804 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -618,13 +818,25 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
618 } 818 }
619} 819}
620 820
821/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
822 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
823static void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
824 struct iwl_rx_mem_buffer *rxb)
825{
826 struct iwl_rx_packet *pkt = rxb_addr(rxb);
827
828 priv->_agn.last_phy_res_valid = true;
829 memcpy(&priv->_agn.last_phy_res, pkt->u.raw,
830 sizeof(struct iwl_rx_phy_res));
831}
832
621/* 833/*
622 * returns non-zero if packet should be dropped 834 * returns non-zero if packet should be dropped
623 */ 835 */
624int iwl_set_decrypted_flag(struct iwl_priv *priv, 836static int iwl_set_decrypted_flag(struct iwl_priv *priv,
625 struct ieee80211_hdr *hdr, 837 struct ieee80211_hdr *hdr,
626 u32 decrypt_res, 838 u32 decrypt_res,
627 struct ieee80211_rx_status *stats) 839 struct ieee80211_rx_status *stats)
628{ 840{
629 u16 fc = le16_to_cpu(hdr->frame_control); 841 u16 fc = le16_to_cpu(hdr->frame_control);
630 842
@@ -669,3 +881,264 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
669 } 881 }
670 return 0; 882 return 0;
671} 883}
884
885static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
886 struct ieee80211_hdr *hdr,
887 u16 len,
888 u32 ampdu_status,
889 struct iwl_rx_mem_buffer *rxb,
890 struct ieee80211_rx_status *stats)
891{
892 struct sk_buff *skb;
893 __le16 fc = hdr->frame_control;
894
895 /* We only process data packets if the interface is open */
896 if (unlikely(!priv->is_open)) {
897 IWL_DEBUG_DROP_LIMIT(priv,
898 "Dropping packet while interface is not open.\n");
899 return;
900 }
901
902 /* In case of HW accelerated crypto and bad decryption, drop */
903 if (!priv->cfg->mod_params->sw_crypto &&
904 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
905 return;
906
907 skb = dev_alloc_skb(128);
908 if (!skb) {
909 IWL_ERR(priv, "dev_alloc_skb failed\n");
910 return;
911 }
912
913 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
914
915 iwl_update_stats(priv, false, fc, len);
916 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
917
918 ieee80211_rx(priv->hw, skb);
919 priv->alloc_rxb_page--;
920 rxb->page = NULL;
921}
922
923static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
924{
925 u32 decrypt_out = 0;
926
927 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
928 RX_RES_STATUS_STATION_FOUND)
929 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
930 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
931
932 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
933
934 /* packet was not encrypted */
935 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
936 RX_RES_STATUS_SEC_TYPE_NONE)
937 return decrypt_out;
938
939 /* packet was encrypted with unknown alg */
940 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
941 RX_RES_STATUS_SEC_TYPE_ERR)
942 return decrypt_out;
943
944 /* decryption was not done in HW */
945 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
946 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
947 return decrypt_out;
948
949 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
950
951 case RX_RES_STATUS_SEC_TYPE_CCMP:
952 /* alg is CCM: check MIC only */
953 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
954 /* Bad MIC */
955 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
956 else
957 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
958
959 break;
960
961 case RX_RES_STATUS_SEC_TYPE_TKIP:
962 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
963 /* Bad TTAK */
964 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
965 break;
966 }
967 /* fall through if TTAK OK */
968 default:
969 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
970 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
971 else
972 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
973 break;
974 }
975
976 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
977 decrypt_in, decrypt_out);
978
979 return decrypt_out;
980}
981
982/* Called for REPLY_RX (legacy ABG frames), or
983 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
984static void iwl_rx_reply_rx(struct iwl_priv *priv,
985 struct iwl_rx_mem_buffer *rxb)
986{
987 struct ieee80211_hdr *header;
988 struct ieee80211_rx_status rx_status;
989 struct iwl_rx_packet *pkt = rxb_addr(rxb);
990 struct iwl_rx_phy_res *phy_res;
991 __le32 rx_pkt_status;
992 struct iwl_rx_mpdu_res_start *amsdu;
993 u32 len;
994 u32 ampdu_status;
995 u32 rate_n_flags;
996
997 /**
998 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
999 * REPLY_RX: physical layer info is in this buffer
1000 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
1001 * command and cached in priv->last_phy_res
1002 *
1003 * Here we set up local variables depending on which command is
1004 * received.
1005 */
1006 if (pkt->hdr.cmd == REPLY_RX) {
1007 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
1008 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
1009 + phy_res->cfg_phy_cnt);
1010
1011 len = le16_to_cpu(phy_res->byte_count);
1012 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
1013 phy_res->cfg_phy_cnt + len);
1014 ampdu_status = le32_to_cpu(rx_pkt_status);
1015 } else {
1016 if (!priv->_agn.last_phy_res_valid) {
1017 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1018 return;
1019 }
1020 phy_res = &priv->_agn.last_phy_res;
1021 amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
1022 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1023 len = le16_to_cpu(amsdu->byte_count);
1024 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1025 ampdu_status = iwl_translate_rx_status(priv,
1026 le32_to_cpu(rx_pkt_status));
1027 }
1028
1029 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1030 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1031 phy_res->cfg_phy_cnt);
1032 return;
1033 }
1034
1035 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1036 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1037 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1038 le32_to_cpu(rx_pkt_status));
1039 return;
1040 }
1041
1042 /* This will be used in several places later */
1043 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1044
1045 /* rx_status carries information about the packet to mac80211 */
1046 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1047 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1048 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1049 rx_status.freq =
1050 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
1051 rx_status.band);
1052 rx_status.rate_idx =
1053 iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1054 rx_status.flag = 0;
1055
1056 /* TSF isn't reliable. In order to allow smooth user experience,
1057 * this W/A doesn't propagate it to the mac80211 */
1058 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
1059
1060 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1061
1062 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1063 rx_status.signal = priv->cfg->ops->utils->calc_rssi(priv, phy_res);
1064
1065 iwl_dbg_log_rx_data_frame(priv, len, header);
1066 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",
1067 rx_status.signal, (unsigned long long)rx_status.mactime);
1068
1069 /*
1070 * "antenna number"
1071 *
1072 * It seems that the antenna field in the phy flags value
1073 * is actually a bit field. This is undefined by radiotap,
1074 * it wants an actual antenna number but I always get "7"
1075 * for most legacy frames I receive indicating that the
1076 * same frame was received on all three RX chains.
1077 *
1078 * I think this field should be removed in favor of a
1079 * new 802.11n radiotap field "RX chains" that is defined
1080 * as a bitmask.
1081 */
1082 rx_status.antenna =
1083 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1084 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1085
1086 /* set the preamble flag if appropriate */
1087 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1088 rx_status.flag |= RX_FLAG_SHORTPRE;
1089
1090 /* Set up the HT phy flags */
1091 if (rate_n_flags & RATE_MCS_HT_MSK)
1092 rx_status.flag |= RX_FLAG_HT;
1093 if (rate_n_flags & RATE_MCS_HT40_MSK)
1094 rx_status.flag |= RX_FLAG_40MHZ;
1095 if (rate_n_flags & RATE_MCS_SGI_MSK)
1096 rx_status.flag |= RX_FLAG_SHORT_GI;
1097
1098 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1099 rxb, &rx_status);
1100}
1101
1102/**
1103 * iwl_setup_rx_handlers - Initialize Rx handler callbacks
1104 *
1105 * Setup the RX handlers for each of the reply types sent from the uCode
1106 * to the host.
1107 */
1108void iwl_setup_rx_handlers(struct iwl_priv *priv)
1109{
1110 void (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
1111
1112 handlers = priv->rx_handlers;
1113
1114 handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
1115 handlers[REPLY_ERROR] = iwl_rx_reply_error;
1116 handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
1117 handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif;
1118 handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
1119 handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif;
1120 handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
1121
1122 /*
1123 * The same handler is used for both the REPLY to a discrete
1124 * statistics request from the host as well as for the periodic
1125 * statistics notifications (after received beacons) from the uCode.
1126 */
1127 handlers[REPLY_STATISTICS_CMD] = iwl_rx_reply_statistics;
1128 handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
1129
1130 iwl_setup_rx_scan_handlers(priv);
1131
1132 handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif;
1133 handlers[MISSED_BEACONS_NOTIFICATION] = iwl_rx_missed_beacon_notif;
1134
1135 /* Rx handlers */
1136 handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy;
1137 handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx;
1138
1139 /* block ack */
1140 handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba;
1141
1142 /* Set up hardware specific Rx handlers */
1143 priv->cfg->ops->lib->rx_handler_setup(priv);
1144}