aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c242
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c178
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c665
7 files changed, 570 insertions, 613 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index fd142bee9189..25fccf9a3001 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -533,9 +533,10 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
533 533
534void iwlagn_temperature(struct iwl_priv *priv) 534void iwlagn_temperature(struct iwl_priv *priv)
535{ 535{
536 /* store temperature from statistics (in Celsius) */ 536 /* store temperature from correct statistics (in Celsius) */
537 priv->temperature = 537 priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ?
538 le32_to_cpu(priv->_agn.statistics.general.common.temperature); 538 priv->_agn.statistics_bt.general.common.temperature :
539 priv->_agn.statistics.general.common.temperature);
539 iwl_tt_handler(priv); 540 iwl_tt_handler(priv);
540} 541}
541 542
@@ -994,241 +995,6 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
994 return -1; 995 return -1;
995} 996}
996 997
997/* Calc max signal level (dBm) among 3 possible receivers */
998static inline int iwlagn_calc_rssi(struct iwl_priv *priv,
999 struct iwl_rx_phy_res *rx_resp)
1000{
1001 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
1002}
1003
1004static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
1005{
1006 u32 decrypt_out = 0;
1007
1008 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
1009 RX_RES_STATUS_STATION_FOUND)
1010 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
1011 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
1012
1013 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
1014
1015 /* packet was not encrypted */
1016 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
1017 RX_RES_STATUS_SEC_TYPE_NONE)
1018 return decrypt_out;
1019
1020 /* packet was encrypted with unknown alg */
1021 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
1022 RX_RES_STATUS_SEC_TYPE_ERR)
1023 return decrypt_out;
1024
1025 /* decryption was not done in HW */
1026 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
1027 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
1028 return decrypt_out;
1029
1030 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
1031
1032 case RX_RES_STATUS_SEC_TYPE_CCMP:
1033 /* alg is CCM: check MIC only */
1034 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
1035 /* Bad MIC */
1036 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
1037 else
1038 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
1039
1040 break;
1041
1042 case RX_RES_STATUS_SEC_TYPE_TKIP:
1043 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
1044 /* Bad TTAK */
1045 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
1046 break;
1047 }
1048 /* fall through if TTAK OK */
1049 default:
1050 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
1051 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
1052 else
1053 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
1054 break;
1055 }
1056
1057 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
1058 decrypt_in, decrypt_out);
1059
1060 return decrypt_out;
1061}
1062
1063static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
1064 struct ieee80211_hdr *hdr,
1065 u16 len,
1066 u32 ampdu_status,
1067 struct iwl_rx_mem_buffer *rxb,
1068 struct ieee80211_rx_status *stats)
1069{
1070 struct sk_buff *skb;
1071 __le16 fc = hdr->frame_control;
1072
1073 /* We only process data packets if the interface is open */
1074 if (unlikely(!priv->is_open)) {
1075 IWL_DEBUG_DROP_LIMIT(priv,
1076 "Dropping packet while interface is not open.\n");
1077 return;
1078 }
1079
1080 /* In case of HW accelerated crypto and bad decryption, drop */
1081 if (!priv->cfg->mod_params->sw_crypto &&
1082 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
1083 return;
1084
1085 skb = dev_alloc_skb(128);
1086 if (!skb) {
1087 IWL_ERR(priv, "dev_alloc_skb failed\n");
1088 return;
1089 }
1090
1091 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
1092
1093 iwl_update_stats(priv, false, fc, len);
1094 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
1095
1096 ieee80211_rx(priv->hw, skb);
1097 priv->alloc_rxb_page--;
1098 rxb->page = NULL;
1099}
1100
1101/* Called for REPLY_RX (legacy ABG frames), or
1102 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
1103void iwlagn_rx_reply_rx(struct iwl_priv *priv,
1104 struct iwl_rx_mem_buffer *rxb)
1105{
1106 struct ieee80211_hdr *header;
1107 struct ieee80211_rx_status rx_status;
1108 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1109 struct iwl_rx_phy_res *phy_res;
1110 __le32 rx_pkt_status;
1111 struct iwl_rx_mpdu_res_start *amsdu;
1112 u32 len;
1113 u32 ampdu_status;
1114 u32 rate_n_flags;
1115
1116 /**
1117 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
1118 * REPLY_RX: physical layer info is in this buffer
1119 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
1120 * command and cached in priv->last_phy_res
1121 *
1122 * Here we set up local variables depending on which command is
1123 * received.
1124 */
1125 if (pkt->hdr.cmd == REPLY_RX) {
1126 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
1127 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
1128 + phy_res->cfg_phy_cnt);
1129
1130 len = le16_to_cpu(phy_res->byte_count);
1131 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
1132 phy_res->cfg_phy_cnt + len);
1133 ampdu_status = le32_to_cpu(rx_pkt_status);
1134 } else {
1135 if (!priv->_agn.last_phy_res_valid) {
1136 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1137 return;
1138 }
1139 phy_res = &priv->_agn.last_phy_res;
1140 amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
1141 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1142 len = le16_to_cpu(amsdu->byte_count);
1143 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1144 ampdu_status = iwlagn_translate_rx_status(priv,
1145 le32_to_cpu(rx_pkt_status));
1146 }
1147
1148 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1149 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1150 phy_res->cfg_phy_cnt);
1151 return;
1152 }
1153
1154 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1155 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1156 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1157 le32_to_cpu(rx_pkt_status));
1158 return;
1159 }
1160
1161 /* This will be used in several places later */
1162 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1163
1164 /* rx_status carries information about the packet to mac80211 */
1165 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1166 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1167 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1168 rx_status.freq =
1169 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
1170 rx_status.band);
1171 rx_status.rate_idx =
1172 iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1173 rx_status.flag = 0;
1174
1175 /* TSF isn't reliable. In order to allow smooth user experience,
1176 * this W/A doesn't propagate it to the mac80211 */
1177 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
1178
1179 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1180
1181 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1182 rx_status.signal = iwlagn_calc_rssi(priv, phy_res);
1183
1184 iwl_dbg_log_rx_data_frame(priv, len, header);
1185 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",
1186 rx_status.signal, (unsigned long long)rx_status.mactime);
1187
1188 /*
1189 * "antenna number"
1190 *
1191 * It seems that the antenna field in the phy flags value
1192 * is actually a bit field. This is undefined by radiotap,
1193 * it wants an actual antenna number but I always get "7"
1194 * for most legacy frames I receive indicating that the
1195 * same frame was received on all three RX chains.
1196 *
1197 * I think this field should be removed in favor of a
1198 * new 802.11n radiotap field "RX chains" that is defined
1199 * as a bitmask.
1200 */
1201 rx_status.antenna =
1202 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1203 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1204
1205 /* set the preamble flag if appropriate */
1206 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1207 rx_status.flag |= RX_FLAG_SHORTPRE;
1208
1209 /* Set up the HT phy flags */
1210 if (rate_n_flags & RATE_MCS_HT_MSK)
1211 rx_status.flag |= RX_FLAG_HT;
1212 if (rate_n_flags & RATE_MCS_HT40_MSK)
1213 rx_status.flag |= RX_FLAG_40MHZ;
1214 if (rate_n_flags & RATE_MCS_SGI_MSK)
1215 rx_status.flag |= RX_FLAG_SHORT_GI;
1216
1217 iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1218 rxb, &rx_status);
1219}
1220
1221/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1222 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1223void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
1224 struct iwl_rx_mem_buffer *rxb)
1225{
1226 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1227 priv->_agn.last_phy_res_valid = true;
1228 memcpy(&priv->_agn.last_phy_res, pkt->u.raw,
1229 sizeof(struct iwl_rx_phy_res));
1230}
1231
1232static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, 998static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
1233 struct ieee80211_vif *vif, 999 struct ieee80211_vif *vif,
1234 enum ieee80211_band band, 1000 enum ieee80211_band band,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index f189bbe78fa6..e0cd3e27a0d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -424,60 +424,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv,
424 return 0; 424 return 0;
425} 425}
426 426
427/******************************************************************************
428 *
429 * Generic RX handler implementations
430 *
431 ******************************************************************************/
432static void iwl_rx_reply_alive(struct iwl_priv *priv,
433 struct iwl_rx_mem_buffer *rxb)
434{
435 struct iwl_rx_packet *pkt = rxb_addr(rxb);
436 struct iwl_alive_resp *palive;
437 struct delayed_work *pwork;
438
439 palive = &pkt->u.alive_frame;
440
441 IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
442 "0x%01X 0x%01X\n",
443 palive->is_valid, palive->ver_type,
444 palive->ver_subtype);
445
446 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
447 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
448 memcpy(&priv->card_alive_init,
449 &pkt->u.alive_frame,
450 sizeof(struct iwl_init_alive_resp));
451 pwork = &priv->init_alive_start;
452 } else {
453 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
454 memcpy(&priv->card_alive, &pkt->u.alive_frame,
455 sizeof(struct iwl_alive_resp));
456 pwork = &priv->alive_start;
457 }
458
459 /* We delay the ALIVE response by 5ms to
460 * give the HW RF Kill time to activate... */
461 if (palive->is_valid == UCODE_VALID_OK)
462 queue_delayed_work(priv->workqueue, pwork,
463 msecs_to_jiffies(5));
464 else {
465 IWL_WARN(priv, "%s uCode did not respond OK.\n",
466 (palive->ver_subtype == INITIALIZE_SUBTYPE) ?
467 "init" : "runtime");
468 /*
469 * If fail to load init uCode,
470 * let's try to load the init uCode again.
471 * We should not get into this situation, but if it
472 * does happen, we should not move on and loading "runtime"
473 * without proper calibrate the device.
474 */
475 if (palive->ver_subtype == INITIALIZE_SUBTYPE)
476 priv->ucode_type = UCODE_NONE;
477 queue_work(priv->workqueue, &priv->restart);
478 }
479}
480
481static void iwl_bg_beacon_update(struct work_struct *work) 427static void iwl_bg_beacon_update(struct work_struct *work)
482{ 428{
483 struct iwl_priv *priv = 429 struct iwl_priv *priv =
@@ -712,83 +658,6 @@ static void iwl_bg_ucode_trace(unsigned long data)
712 } 658 }
713} 659}
714 660
715static void iwlagn_rx_beacon_notif(struct iwl_priv *priv,
716 struct iwl_rx_mem_buffer *rxb)
717{
718 struct iwl_rx_packet *pkt = rxb_addr(rxb);
719 struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw;
720#ifdef CONFIG_IWLWIFI_DEBUG
721 u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status);
722 u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
723
724 IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d "
725 "tsf:0x%.8x%.8x rate:%d\n",
726 status & TX_STATUS_MSK,
727 beacon->beacon_notify_hdr.failure_frame,
728 le32_to_cpu(beacon->ibss_mgr_status),
729 le32_to_cpu(beacon->high_tsf),
730 le32_to_cpu(beacon->low_tsf), rate);
731#endif
732
733 priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
734
735 if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
736 queue_work(priv->workqueue, &priv->beacon_update);
737}
738
739/* Handle notification from uCode that card's power state is changing
740 * due to software, hardware, or critical temperature RFKILL */
741static void iwl_rx_card_state_notif(struct iwl_priv *priv,
742 struct iwl_rx_mem_buffer *rxb)
743{
744 struct iwl_rx_packet *pkt = rxb_addr(rxb);
745 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
746 unsigned long status = priv->status;
747
748 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
749 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
750 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
751 (flags & CT_CARD_DISABLED) ?
752 "Reached" : "Not reached");
753
754 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
755 CT_CARD_DISABLED)) {
756
757 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
758 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
759
760 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
761 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
762
763 if (!(flags & RXON_CARD_DISABLED)) {
764 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
765 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
766 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
767 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
768 }
769 if (flags & CT_CARD_DISABLED)
770 iwl_tt_enter_ct_kill(priv);
771 }
772 if (!(flags & CT_CARD_DISABLED))
773 iwl_tt_exit_ct_kill(priv);
774
775 if (flags & HW_CARD_DISABLED)
776 set_bit(STATUS_RF_KILL_HW, &priv->status);
777 else
778 clear_bit(STATUS_RF_KILL_HW, &priv->status);
779
780
781 if (!(flags & RXON_CARD_DISABLED))
782 iwl_scan_cancel(priv);
783
784 if ((test_bit(STATUS_RF_KILL_HW, &status) !=
785 test_bit(STATUS_RF_KILL_HW, &priv->status)))
786 wiphy_rfkill_set_hw_state(priv->hw->wiphy,
787 test_bit(STATUS_RF_KILL_HW, &priv->status));
788 else
789 wake_up_interruptible(&priv->wait_command_queue);
790}
791
792static void iwl_bg_tx_flush(struct work_struct *work) 661static void iwl_bg_tx_flush(struct work_struct *work)
793{ 662{
794 struct iwl_priv *priv = 663 struct iwl_priv *priv =
@@ -808,51 +677,6 @@ static void iwl_bg_tx_flush(struct work_struct *work)
808} 677}
809 678
810/** 679/**
811 * iwl_setup_rx_handlers - Initialize Rx handler callbacks
812 *
813 * Setup the RX handlers for each of the reply types sent from the uCode
814 * to the host.
815 *
816 * This function chains into the hardware specific files for them to setup
817 * any hardware specific handlers as well.
818 */
819static void iwl_setup_rx_handlers(struct iwl_priv *priv)
820{
821 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
822 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
823 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
824 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
825 iwl_rx_spectrum_measure_notif;
826 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
827 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
828 iwl_rx_pm_debug_statistics_notif;
829 priv->rx_handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif;
830
831 /*
832 * The same handler is used for both the REPLY to a discrete
833 * statistics request from the host as well as for the periodic
834 * statistics notifications (after received beacons) from the uCode.
835 */
836 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
837 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
838
839 iwl_setup_rx_scan_handlers(priv);
840
841 /* status change handler */
842 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif;
843
844 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
845 iwl_rx_missed_beacon_notif;
846 /* Rx handlers */
847 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy;
848 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx;
849 /* block ack */
850 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba;
851 /* Set up hardware specific Rx handlers */
852 priv->cfg->ops->lib->rx_handler_setup(priv);
853}
854
855/**
856 * iwl_rx_handle - Main entry function for receiving responses from uCode 680 * iwl_rx_handle - Main entry function for receiving responses from uCode
857 * 681 *
858 * Uses the priv->rx_handlers callback function array to invoke 682 * Uses the priv->rx_handlers callback function array to invoke
@@ -3913,6 +3737,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
3913 priv->force_reset[IWL_FW_RESET].reset_duration = 3737 priv->force_reset[IWL_FW_RESET].reset_duration =
3914 IWL_DELAY_NEXT_FORCE_FW_RELOAD; 3738 IWL_DELAY_NEXT_FORCE_FW_RELOAD;
3915 3739
3740 priv->rx_statistics_jiffies = jiffies;
3741
3916 /* Choose which receivers/antennas to use */ 3742 /* Choose which receivers/antennas to use */
3917 if (priv->cfg->ops->hcmd->set_rxon_chain) 3743 if (priv->cfg->ops->hcmd->set_rxon_chain)
3918 priv->cfg->ops->hcmd->set_rxon_chain(priv, 3744 priv->cfg->ops->hcmd->set_rxon_chain(priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index b5a169be48e2..20f8e4188994 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -190,10 +190,7 @@ void iwlagn_rx_replenish_now(struct iwl_priv *priv);
190void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 190void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
191int iwlagn_rxq_stop(struct iwl_priv *priv); 191int iwlagn_rxq_stop(struct iwl_priv *priv);
192int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); 192int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
193void iwlagn_rx_reply_rx(struct iwl_priv *priv, 193void iwl_setup_rx_handlers(struct iwl_priv *priv);
194 struct iwl_rx_mem_buffer *rxb);
195void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
196 struct iwl_rx_mem_buffer *rxb);
197 194
198/* tx */ 195/* tx */
199void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); 196void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
@@ -243,14 +240,6 @@ static inline bool iwl_is_tx_success(u32 status)
243 240
244u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); 241u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
245 242
246/* rx */
247void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
248 struct iwl_rx_mem_buffer *rxb);
249void iwl_rx_statistics(struct iwl_priv *priv,
250 struct iwl_rx_mem_buffer *rxb);
251void iwl_reply_statistics(struct iwl_priv *priv,
252 struct iwl_rx_mem_buffer *rxb);
253
254/* scan */ 243/* scan */
255int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); 244int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
256void iwlagn_post_scan(struct iwl_priv *priv); 245void iwlagn_post_scan(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 4bd342060254..6c30fa652e27 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -869,33 +869,6 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
869 } 869 }
870} 870}
871 871
872void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
873{
874 struct iwl_rx_packet *pkt = rxb_addr(rxb);
875 struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
876 /*
877 * MULTI-FIXME
878 * See iwl_mac_channel_switch.
879 */
880 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
881 struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
882
883 if (priv->switch_rxon.switch_in_progress) {
884 if (!le32_to_cpu(csa->status) &&
885 (csa->channel == priv->switch_rxon.channel)) {
886 rxon->channel = csa->channel;
887 ctx->staging.channel = csa->channel;
888 IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
889 le16_to_cpu(csa->channel));
890 iwl_chswitch_done(priv, true);
891 } else {
892 IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
893 le16_to_cpu(csa->channel));
894 iwl_chswitch_done(priv, false);
895 }
896 }
897}
898
899#ifdef CONFIG_IWLWIFI_DEBUG 872#ifdef CONFIG_IWLWIFI_DEBUG
900void iwl_print_rx_config_cmd(struct iwl_priv *priv, 873void iwl_print_rx_config_cmd(struct iwl_priv *priv,
901 struct iwl_rxon_context *ctx) 874 struct iwl_rxon_context *ctx)
@@ -1245,42 +1218,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
1245 &statistics_cmd); 1218 &statistics_cmd);
1246} 1219}
1247 1220
1248void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
1249 struct iwl_rx_mem_buffer *rxb)
1250{
1251#ifdef CONFIG_IWLWIFI_DEBUG
1252 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1253 struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
1254 IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
1255 sleep->pm_sleep_mode, sleep->pm_wakeup_src);
1256#endif
1257}
1258
1259void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
1260 struct iwl_rx_mem_buffer *rxb)
1261{
1262 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1263 u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
1264 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
1265 "notification for %s:\n", len,
1266 get_cmd_string(pkt->hdr.cmd));
1267 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
1268}
1269
1270void iwl_rx_reply_error(struct iwl_priv *priv,
1271 struct iwl_rx_mem_buffer *rxb)
1272{
1273 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1274
1275 IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
1276 "seq 0x%04X ser 0x%08X\n",
1277 le32_to_cpu(pkt->u.err_resp.error_type),
1278 get_cmd_string(pkt->u.err_resp.cmd_id),
1279 pkt->u.err_resp.cmd_id,
1280 le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
1281 le32_to_cpu(pkt->u.err_resp.error_info));
1282}
1283
1284void iwl_clear_isr_stats(struct iwl_priv *priv) 1221void iwl_clear_isr_stats(struct iwl_priv *priv)
1285{ 1222{
1286 memset(&priv->isr_stats, 0, sizeof(priv->isr_stats)); 1223 memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index d47f3a87fce4..af47750f8985 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -441,10 +441,6 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
441void iwl_connection_init_rx_config(struct iwl_priv *priv, 441void iwl_connection_init_rx_config(struct iwl_priv *priv,
442 struct iwl_rxon_context *ctx); 442 struct iwl_rxon_context *ctx);
443void iwl_set_rate(struct iwl_priv *priv); 443void iwl_set_rate(struct iwl_priv *priv);
444int iwl_set_decrypted_flag(struct iwl_priv *priv,
445 struct ieee80211_hdr *hdr,
446 u32 decrypt_res,
447 struct ieee80211_rx_status *stats);
448void iwl_irq_handle_error(struct iwl_priv *priv); 444void iwl_irq_handle_error(struct iwl_priv *priv);
449int iwl_mac_add_interface(struct ieee80211_hw *hw, 445int iwl_mac_add_interface(struct ieee80211_hw *hw,
450 struct ieee80211_vif *vif); 446 struct ieee80211_vif *vif);
@@ -493,15 +489,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
493{ 489{
494} 490}
495#endif 491#endif
496/*****************************************************
497 * RX handlers.
498 * **************************************************/
499void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
500 struct iwl_rx_mem_buffer *rxb);
501void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
502 struct iwl_rx_mem_buffer *rxb);
503void iwl_rx_reply_error(struct iwl_priv *priv,
504 struct iwl_rx_mem_buffer *rxb);
505 492
506/***************************************************** 493/*****************************************************
507* RX 494* RX
@@ -513,11 +500,8 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
513 struct iwl_rx_queue *q); 500 struct iwl_rx_queue *q);
514int iwl_rx_queue_space(const struct iwl_rx_queue *q); 501int iwl_rx_queue_space(const struct iwl_rx_queue *q);
515void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 502void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
516/* Handlers */ 503
517void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
518 struct iwl_rx_mem_buffer *rxb);
519void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); 504void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
520void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
521 505
522/* TX helpers */ 506/* TX helpers */
523 507
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 58165c769cf1..6a41deba6863 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1261,8 +1261,8 @@ struct iwl_priv {
1261 /* track IBSS manager (last beacon) status */ 1261 /* track IBSS manager (last beacon) status */
1262 u32 ibss_manager; 1262 u32 ibss_manager;
1263 1263
1264 /* storing the jiffies when the plcp error rate is received */ 1264 /* jiffies when last recovery from statistics was performed */
1265 unsigned long plcp_jiffies; 1265 unsigned long rx_statistics_jiffies;
1266 1266
1267 /* force reset */ 1267 /* force reset */
1268 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; 1268 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 566e2d979ce3..6f9a2fa04763 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -29,6 +29,7 @@
29 29
30#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/sched.h>
32#include <net/mac80211.h> 33#include <net/mac80211.h>
33#include <asm/unaligned.h> 34#include <asm/unaligned.h>
34#include "iwl-eeprom.h" 35#include "iwl-eeprom.h"
@@ -38,7 +39,14 @@
38#include "iwl-io.h" 39#include "iwl-io.h"
39#include "iwl-helpers.h" 40#include "iwl-helpers.h"
40#include "iwl-agn-calib.h" 41#include "iwl-agn-calib.h"
41/************************** RX-FUNCTIONS ****************************/ 42#include "iwl-agn.h"
43
44/******************************************************************************
45 *
46 * RX path functions
47 *
48 ******************************************************************************/
49
42/* 50/*
43 * Rx theory of operation 51 * Rx theory of operation
44 * 52 *
@@ -211,7 +219,104 @@ err_bd:
211 return -ENOMEM; 219 return -ENOMEM;
212} 220}
213 221
214void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 222/******************************************************************************
223 *
224 * Generic RX handler implementations
225 *
226 ******************************************************************************/
227
228static void iwl_rx_reply_alive(struct iwl_priv *priv,
229 struct iwl_rx_mem_buffer *rxb)
230{
231 struct iwl_rx_packet *pkt = rxb_addr(rxb);
232 struct iwl_alive_resp *palive;
233 struct delayed_work *pwork;
234
235 palive = &pkt->u.alive_frame;
236
237 IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
238 "0x%01X 0x%01X\n",
239 palive->is_valid, palive->ver_type,
240 palive->ver_subtype);
241
242 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
243 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
244 memcpy(&priv->card_alive_init,
245 &pkt->u.alive_frame,
246 sizeof(struct iwl_init_alive_resp));
247 pwork = &priv->init_alive_start;
248 } else {
249 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
250 memcpy(&priv->card_alive, &pkt->u.alive_frame,
251 sizeof(struct iwl_alive_resp));
252 pwork = &priv->alive_start;
253 }
254
255 /* We delay the ALIVE response by 5ms to
256 * give the HW RF Kill time to activate... */
257 if (palive->is_valid == UCODE_VALID_OK)
258 queue_delayed_work(priv->workqueue, pwork,
259 msecs_to_jiffies(5));
260 else {
261 IWL_WARN(priv, "%s uCode did not respond OK.\n",
262 (palive->ver_subtype == INITIALIZE_SUBTYPE) ?
263 "init" : "runtime");
264 /*
265 * If fail to load init uCode,
266 * let's try to load the init uCode again.
267 * We should not get into this situation, but if it
268 * does happen, we should not move on and loading "runtime"
269 * without proper calibrate the device.
270 */
271 if (palive->ver_subtype == INITIALIZE_SUBTYPE)
272 priv->ucode_type = UCODE_NONE;
273 queue_work(priv->workqueue, &priv->restart);
274 }
275}
276
277static void iwl_rx_reply_error(struct iwl_priv *priv,
278 struct iwl_rx_mem_buffer *rxb)
279{
280 struct iwl_rx_packet *pkt = rxb_addr(rxb);
281
282 IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
283 "seq 0x%04X ser 0x%08X\n",
284 le32_to_cpu(pkt->u.err_resp.error_type),
285 get_cmd_string(pkt->u.err_resp.cmd_id),
286 pkt->u.err_resp.cmd_id,
287 le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
288 le32_to_cpu(pkt->u.err_resp.error_info));
289}
290
291static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
292{
293 struct iwl_rx_packet *pkt = rxb_addr(rxb);
294 struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
295 /*
296 * MULTI-FIXME
297 * See iwl_mac_channel_switch.
298 */
299 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
300 struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
301
302 if (priv->switch_rxon.switch_in_progress) {
303 if (!le32_to_cpu(csa->status) &&
304 (csa->channel == priv->switch_rxon.channel)) {
305 rxon->channel = csa->channel;
306 ctx->staging.channel = csa->channel;
307 IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
308 le16_to_cpu(csa->channel));
309 iwl_chswitch_done(priv, true);
310 } else {
311 IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
312 le16_to_cpu(csa->channel));
313 iwl_chswitch_done(priv, false);
314 }
315 }
316}
317
318
319static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
215 struct iwl_rx_mem_buffer *rxb) 320 struct iwl_rx_mem_buffer *rxb)
216{ 321{
217 struct iwl_rx_packet *pkt = rxb_addr(rxb); 322 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -227,6 +332,52 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
227 priv->measurement_status |= MEASUREMENT_READY; 332 priv->measurement_status |= MEASUREMENT_READY;
228} 333}
229 334
335static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
336 struct iwl_rx_mem_buffer *rxb)
337{
338#ifdef CONFIG_IWLWIFI_DEBUG
339 struct iwl_rx_packet *pkt = rxb_addr(rxb);
340 struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
341 IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
342 sleep->pm_sleep_mode, sleep->pm_wakeup_src);
343#endif
344}
345
346static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
347 struct iwl_rx_mem_buffer *rxb)
348{
349 struct iwl_rx_packet *pkt = rxb_addr(rxb);
350 u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
351 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
352 "notification for %s:\n", len,
353 get_cmd_string(pkt->hdr.cmd));
354 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
355}
356
357static void iwl_rx_beacon_notif(struct iwl_priv *priv,
358 struct iwl_rx_mem_buffer *rxb)
359{
360 struct iwl_rx_packet *pkt = rxb_addr(rxb);
361 struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw;
362#ifdef CONFIG_IWLWIFI_DEBUG
363 u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status);
364 u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
365
366 IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d "
367 "tsf:0x%.8x%.8x rate:%d\n",
368 status & TX_STATUS_MSK,
369 beacon->beacon_notify_hdr.failure_frame,
370 le32_to_cpu(beacon->ibss_mgr_status),
371 le32_to_cpu(beacon->high_tsf),
372 le32_to_cpu(beacon->low_tsf), rate);
373#endif
374
375 priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
376
377 if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
378 queue_work(priv->workqueue, &priv->beacon_update);
379}
380
230/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ 381/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
231#define ACK_CNT_RATIO (50) 382#define ACK_CNT_RATIO (50)
232#define BA_TIMEOUT_CNT (5) 383#define BA_TIMEOUT_CNT (5)
@@ -298,92 +449,72 @@ 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 449 * When the plcp error is exceeding the thresholds, reset the radio
299 * to improve the throughput. 450 * to improve the throughput.
300 */ 451 */
301static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) 452static bool iwl_good_plcp_health(struct iwl_priv *priv,
453 struct iwl_rx_packet *pkt, unsigned int msecs)
302{ 454{
303 bool rc = true; 455 int delta;
304 int combined_plcp_delta; 456 int threshold = priv->cfg->base_params->plcp_delta_threshold;
305 unsigned int plcp_msec;
306 unsigned long plcp_received_jiffies;
307 457
308 if (priv->cfg->base_params->plcp_delta_threshold == 458 if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
309 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
310 IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); 459 IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
311 return rc; 460 return true;
312 } 461 }
313 462
314 /* 463 if (iwl_bt_statistics(priv)) {
315 * check for plcp_err and trigger radio reset if it exceeds 464 struct statistics_rx_bt *cur, *old;
316 * the plcp error threshold plcp_delta.
317 */
318 plcp_received_jiffies = jiffies;
319 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
320 (long) priv->plcp_jiffies);
321 priv->plcp_jiffies = plcp_received_jiffies;
322 /*
323 * check to make sure plcp_msec is not 0 to prevent division
324 * by zero.
325 */
326 if (plcp_msec) {
327 struct statistics_rx_phy *ofdm;
328 struct statistics_rx_ht_phy *ofdm_ht;
329
330 if (iwl_bt_statistics(priv)) {
331 ofdm = &pkt->u.stats_bt.rx.ofdm;
332 ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
333 combined_plcp_delta =
334 (le32_to_cpu(ofdm->plcp_err) -
335 le32_to_cpu(priv->_agn.statistics_bt.
336 rx.ofdm.plcp_err)) +
337 (le32_to_cpu(ofdm_ht->plcp_err) -
338 le32_to_cpu(priv->_agn.statistics_bt.
339 rx.ofdm_ht.plcp_err));
340 } else {
341 ofdm = &pkt->u.stats.rx.ofdm;
342 ofdm_ht = &pkt->u.stats.rx.ofdm_ht;
343 combined_plcp_delta =
344 (le32_to_cpu(ofdm->plcp_err) -
345 le32_to_cpu(priv->_agn.statistics.
346 rx.ofdm.plcp_err)) +
347 (le32_to_cpu(ofdm_ht->plcp_err) -
348 le32_to_cpu(priv->_agn.statistics.
349 rx.ofdm_ht.plcp_err));
350 }
351 465
352 if ((combined_plcp_delta > 0) && 466 cur = &pkt->u.stats_bt.rx;
353 ((combined_plcp_delta * 100) / plcp_msec) > 467 old = &priv->_agn.statistics_bt.rx;
354 priv->cfg->base_params->plcp_delta_threshold) { 468
355 /* 469 delta = le32_to_cpu(cur->ofdm.plcp_err) -
356 * if plcp_err exceed the threshold, 470 le32_to_cpu(old->ofdm.plcp_err) +
357 * the following data is printed in csv format: 471 le32_to_cpu(cur->ofdm_ht.plcp_err) -
358 * Text: plcp_err exceeded %d, 472 le32_to_cpu(old->ofdm_ht.plcp_err);
359 * Received ofdm.plcp_err, 473 } else {
360 * Current ofdm.plcp_err, 474 struct statistics_rx *cur, *old;
361 * Received ofdm_ht.plcp_err, 475
362 * Current ofdm_ht.plcp_err, 476 cur = &pkt->u.stats.rx;
363 * combined_plcp_delta, 477 old = &priv->_agn.statistics.rx;
364 * plcp_msec 478
365 */ 479 delta = le32_to_cpu(cur->ofdm.plcp_err) -
366 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " 480 le32_to_cpu(old->ofdm.plcp_err) +
367 "%u, %u, %u, %u, %d, %u mSecs\n", 481 le32_to_cpu(cur->ofdm_ht.plcp_err) -
368 priv->cfg->base_params->plcp_delta_threshold, 482 le32_to_cpu(old->ofdm_ht.plcp_err);
369 le32_to_cpu(ofdm->plcp_err),
370 le32_to_cpu(ofdm->plcp_err),
371 le32_to_cpu(ofdm_ht->plcp_err),
372 le32_to_cpu(ofdm_ht->plcp_err),
373 combined_plcp_delta, plcp_msec);
374
375 rc = false;
376 }
377 } 483 }
378 return rc; 484
485 /* Can be negative if firmware reseted statistics */
486 if (delta <= 0)
487 return true;
488
489 if ((delta * 100 / msecs) > threshold) {
490 IWL_DEBUG_RADIO(priv,
491 "plcp health threshold %u delta %d msecs %u\n",
492 threshold, delta, msecs);
493 return false;
494 }
495
496 return true;
379} 497}
380 498
381static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) 499static void iwl_recover_from_statistics(struct iwl_priv *priv,
500 struct iwl_rx_packet *pkt)
382{ 501{
383 const struct iwl_mod_params *mod_params = priv->cfg->mod_params; 502 const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
503 unsigned int msecs;
504 unsigned long stamp;
384 505
385 if (test_bit(STATUS_EXIT_PENDING, &priv->status) || 506 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
386 !iwl_is_any_associated(priv)) 507 return;
508
509 stamp = jiffies;
510 msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies);
511
512 /* Only gather statistics and update time stamp when not associated */
513 if (!iwl_is_any_associated(priv))
514 goto out;
515
516 /* Do not check/recover when do not have enough statistics data */
517 if (msecs < 99)
387 return; 518 return;
388 519
389 if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { 520 if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) {
@@ -392,8 +523,18 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_pac
392 return; 523 return;
393 } 524 }
394 525
395 if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt)) 526 if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs))
396 iwl_force_reset(priv, IWL_RF_RESET, false); 527 iwl_force_reset(priv, IWL_RF_RESET, false);
528
529out:
530 if (iwl_bt_statistics(priv))
531 memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
532 sizeof(priv->_agn.statistics_bt));
533 else
534 memcpy(&priv->_agn.statistics, &pkt->u.stats,
535 sizeof(priv->_agn.statistics));
536
537 priv->rx_statistics_jiffies = stamp;
397} 538}
398 539
399/* Calculate noise level, based on measurements during network silence just 540/* Calculate noise level, based on measurements during network silence just
@@ -442,7 +583,6 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
442 last_rx_noise); 583 last_rx_noise);
443} 584}
444 585
445#ifdef CONFIG_IWLWIFI_DEBUGFS
446/* 586/*
447 * based on the assumption of all statistics counter are in DWORD 587 * based on the assumption of all statistics counter are in DWORD
448 * FIXME: This function is for debugging, do not deal with 588 * FIXME: This function is for debugging, do not deal with
@@ -451,6 +591,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
451static void iwl_accumulative_statistics(struct iwl_priv *priv, 591static void iwl_accumulative_statistics(struct iwl_priv *priv,
452 __le32 *stats) 592 __le32 *stats)
453{ 593{
594#ifdef CONFIG_IWLWIFI_DEBUGFS
454 int i, size; 595 int i, size;
455 __le32 *prev_stats; 596 __le32 *prev_stats;
456 u32 *accum_stats; 597 u32 *accum_stats;
@@ -498,14 +639,13 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
498 accum_tx->tx_power.ant_a = tx->tx_power.ant_a; 639 accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
499 accum_tx->tx_power.ant_b = tx->tx_power.ant_b; 640 accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
500 accum_tx->tx_power.ant_c = tx->tx_power.ant_c; 641 accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
501}
502#endif 642#endif
643}
503 644
504#define REG_RECALIB_PERIOD (60) 645static void iwl_rx_statistics(struct iwl_priv *priv,
505
506void iwl_rx_statistics(struct iwl_priv *priv,
507 struct iwl_rx_mem_buffer *rxb) 646 struct iwl_rx_mem_buffer *rxb)
508{ 647{
648 const int reg_recalib_period = 60;
509 int change; 649 int change;
510 struct iwl_rx_packet *pkt = rxb_addr(rxb); 650 struct iwl_rx_packet *pkt = rxb_addr(rxb);
511 651
@@ -522,10 +662,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
522 STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 662 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
523 (pkt->u.stats_bt.flag & 663 (pkt->u.stats_bt.flag &
524 STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 664 STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
525#ifdef CONFIG_IWLWIFI_DEBUGFS
526 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
527#endif
528 665
666 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
529 } else { 667 } else {
530 IWL_DEBUG_RX(priv, 668 IWL_DEBUG_RX(priv,
531 "Statistics notification received (%d vs %d).\n", 669 "Statistics notification received (%d vs %d).\n",
@@ -539,29 +677,20 @@ void iwl_rx_statistics(struct iwl_priv *priv,
539 STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 677 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
540 (pkt->u.stats.flag & 678 (pkt->u.stats.flag &
541 STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 679 STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
542#ifdef CONFIG_IWLWIFI_DEBUGFS
543 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
544#endif
545 680
681 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
546 } 682 }
547 683
548 iwl_recover_from_statistics(priv, pkt); 684 iwl_recover_from_statistics(priv, pkt);
549 685
550 if (iwl_bt_statistics(priv))
551 memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
552 sizeof(priv->_agn.statistics_bt));
553 else
554 memcpy(&priv->_agn.statistics, &pkt->u.stats,
555 sizeof(priv->_agn.statistics));
556
557 set_bit(STATUS_STATISTICS, &priv->status); 686 set_bit(STATUS_STATISTICS, &priv->status);
558 687
559 /* Reschedule the statistics timer to occur in 688 /* Reschedule the statistics timer to occur in
560 * REG_RECALIB_PERIOD seconds to ensure we get a 689 * reg_recalib_period seconds to ensure we get a
561 * thermal update even if the uCode doesn't give 690 * thermal update even if the uCode doesn't give
562 * us one */ 691 * us one */
563 mod_timer(&priv->statistics_periodic, jiffies + 692 mod_timer(&priv->statistics_periodic, jiffies +
564 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); 693 msecs_to_jiffies(reg_recalib_period * 1000));
565 694
566 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && 695 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
567 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { 696 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
@@ -572,8 +701,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
572 priv->cfg->ops->lib->temp_ops.temperature(priv); 701 priv->cfg->ops->lib->temp_ops.temperature(priv);
573} 702}
574 703
575void iwl_reply_statistics(struct iwl_priv *priv, 704static void iwl_rx_reply_statistics(struct iwl_priv *priv,
576 struct iwl_rx_mem_buffer *rxb) 705 struct iwl_rx_mem_buffer *rxb)
577{ 706{
578 struct iwl_rx_packet *pkt = rxb_addr(rxb); 707 struct iwl_rx_packet *pkt = rxb_addr(rxb);
579 708
@@ -597,8 +726,61 @@ void iwl_reply_statistics(struct iwl_priv *priv,
597 iwl_rx_statistics(priv, rxb); 726 iwl_rx_statistics(priv, rxb);
598} 727}
599 728
600void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 729/* Handle notification from uCode that card's power state is changing
601 struct iwl_rx_mem_buffer *rxb) 730 * due to software, hardware, or critical temperature RFKILL */
731static void iwl_rx_card_state_notif(struct iwl_priv *priv,
732 struct iwl_rx_mem_buffer *rxb)
733{
734 struct iwl_rx_packet *pkt = rxb_addr(rxb);
735 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
736 unsigned long status = priv->status;
737
738 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
739 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
740 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
741 (flags & CT_CARD_DISABLED) ?
742 "Reached" : "Not reached");
743
744 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
745 CT_CARD_DISABLED)) {
746
747 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
748 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
749
750 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
751 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
752
753 if (!(flags & RXON_CARD_DISABLED)) {
754 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
755 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
756 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
757 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
758 }
759 if (flags & CT_CARD_DISABLED)
760 iwl_tt_enter_ct_kill(priv);
761 }
762 if (!(flags & CT_CARD_DISABLED))
763 iwl_tt_exit_ct_kill(priv);
764
765 if (flags & HW_CARD_DISABLED)
766 set_bit(STATUS_RF_KILL_HW, &priv->status);
767 else
768 clear_bit(STATUS_RF_KILL_HW, &priv->status);
769
770
771 if (!(flags & RXON_CARD_DISABLED))
772 iwl_scan_cancel(priv);
773
774 if ((test_bit(STATUS_RF_KILL_HW, &status) !=
775 test_bit(STATUS_RF_KILL_HW, &priv->status)))
776 wiphy_rfkill_set_hw_state(priv->hw->wiphy,
777 test_bit(STATUS_RF_KILL_HW, &priv->status));
778 else
779 wake_up_interruptible(&priv->wait_command_queue);
780}
781
782static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
783 struct iwl_rx_mem_buffer *rxb)
602 784
603{ 785{
604 struct iwl_rx_packet *pkt = rxb_addr(rxb); 786 struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -618,13 +800,25 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
618 } 800 }
619} 801}
620 802
803/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
804 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
805static void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
806 struct iwl_rx_mem_buffer *rxb)
807{
808 struct iwl_rx_packet *pkt = rxb_addr(rxb);
809
810 priv->_agn.last_phy_res_valid = true;
811 memcpy(&priv->_agn.last_phy_res, pkt->u.raw,
812 sizeof(struct iwl_rx_phy_res));
813}
814
621/* 815/*
622 * returns non-zero if packet should be dropped 816 * returns non-zero if packet should be dropped
623 */ 817 */
624int iwl_set_decrypted_flag(struct iwl_priv *priv, 818static int iwl_set_decrypted_flag(struct iwl_priv *priv,
625 struct ieee80211_hdr *hdr, 819 struct ieee80211_hdr *hdr,
626 u32 decrypt_res, 820 u32 decrypt_res,
627 struct ieee80211_rx_status *stats) 821 struct ieee80211_rx_status *stats)
628{ 822{
629 u16 fc = le16_to_cpu(hdr->frame_control); 823 u16 fc = le16_to_cpu(hdr->frame_control);
630 824
@@ -669,3 +863,264 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
669 } 863 }
670 return 0; 864 return 0;
671} 865}
866
867static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
868 struct ieee80211_hdr *hdr,
869 u16 len,
870 u32 ampdu_status,
871 struct iwl_rx_mem_buffer *rxb,
872 struct ieee80211_rx_status *stats)
873{
874 struct sk_buff *skb;
875 __le16 fc = hdr->frame_control;
876
877 /* We only process data packets if the interface is open */
878 if (unlikely(!priv->is_open)) {
879 IWL_DEBUG_DROP_LIMIT(priv,
880 "Dropping packet while interface is not open.\n");
881 return;
882 }
883
884 /* In case of HW accelerated crypto and bad decryption, drop */
885 if (!priv->cfg->mod_params->sw_crypto &&
886 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
887 return;
888
889 skb = dev_alloc_skb(128);
890 if (!skb) {
891 IWL_ERR(priv, "dev_alloc_skb failed\n");
892 return;
893 }
894
895 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
896
897 iwl_update_stats(priv, false, fc, len);
898 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
899
900 ieee80211_rx(priv->hw, skb);
901 priv->alloc_rxb_page--;
902 rxb->page = NULL;
903}
904
905static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
906{
907 u32 decrypt_out = 0;
908
909 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
910 RX_RES_STATUS_STATION_FOUND)
911 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
912 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
913
914 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
915
916 /* packet was not encrypted */
917 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
918 RX_RES_STATUS_SEC_TYPE_NONE)
919 return decrypt_out;
920
921 /* packet was encrypted with unknown alg */
922 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
923 RX_RES_STATUS_SEC_TYPE_ERR)
924 return decrypt_out;
925
926 /* decryption was not done in HW */
927 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
928 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
929 return decrypt_out;
930
931 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
932
933 case RX_RES_STATUS_SEC_TYPE_CCMP:
934 /* alg is CCM: check MIC only */
935 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
936 /* Bad MIC */
937 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
938 else
939 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
940
941 break;
942
943 case RX_RES_STATUS_SEC_TYPE_TKIP:
944 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
945 /* Bad TTAK */
946 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
947 break;
948 }
949 /* fall through if TTAK OK */
950 default:
951 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
952 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
953 else
954 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
955 break;
956 }
957
958 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
959 decrypt_in, decrypt_out);
960
961 return decrypt_out;
962}
963
964/* Called for REPLY_RX (legacy ABG frames), or
965 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
966static void iwl_rx_reply_rx(struct iwl_priv *priv,
967 struct iwl_rx_mem_buffer *rxb)
968{
969 struct ieee80211_hdr *header;
970 struct ieee80211_rx_status rx_status;
971 struct iwl_rx_packet *pkt = rxb_addr(rxb);
972 struct iwl_rx_phy_res *phy_res;
973 __le32 rx_pkt_status;
974 struct iwl_rx_mpdu_res_start *amsdu;
975 u32 len;
976 u32 ampdu_status;
977 u32 rate_n_flags;
978
979 /**
980 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
981 * REPLY_RX: physical layer info is in this buffer
982 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
983 * command and cached in priv->last_phy_res
984 *
985 * Here we set up local variables depending on which command is
986 * received.
987 */
988 if (pkt->hdr.cmd == REPLY_RX) {
989 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
990 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
991 + phy_res->cfg_phy_cnt);
992
993 len = le16_to_cpu(phy_res->byte_count);
994 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
995 phy_res->cfg_phy_cnt + len);
996 ampdu_status = le32_to_cpu(rx_pkt_status);
997 } else {
998 if (!priv->_agn.last_phy_res_valid) {
999 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1000 return;
1001 }
1002 phy_res = &priv->_agn.last_phy_res;
1003 amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
1004 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1005 len = le16_to_cpu(amsdu->byte_count);
1006 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1007 ampdu_status = iwl_translate_rx_status(priv,
1008 le32_to_cpu(rx_pkt_status));
1009 }
1010
1011 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1012 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1013 phy_res->cfg_phy_cnt);
1014 return;
1015 }
1016
1017 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1018 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1019 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1020 le32_to_cpu(rx_pkt_status));
1021 return;
1022 }
1023
1024 /* This will be used in several places later */
1025 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1026
1027 /* rx_status carries information about the packet to mac80211 */
1028 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1029 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1030 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1031 rx_status.freq =
1032 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
1033 rx_status.band);
1034 rx_status.rate_idx =
1035 iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1036 rx_status.flag = 0;
1037
1038 /* TSF isn't reliable. In order to allow smooth user experience,
1039 * this W/A doesn't propagate it to the mac80211 */
1040 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
1041
1042 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1043
1044 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1045 rx_status.signal = priv->cfg->ops->utils->calc_rssi(priv, phy_res);
1046
1047 iwl_dbg_log_rx_data_frame(priv, len, header);
1048 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",
1049 rx_status.signal, (unsigned long long)rx_status.mactime);
1050
1051 /*
1052 * "antenna number"
1053 *
1054 * It seems that the antenna field in the phy flags value
1055 * is actually a bit field. This is undefined by radiotap,
1056 * it wants an actual antenna number but I always get "7"
1057 * for most legacy frames I receive indicating that the
1058 * same frame was received on all three RX chains.
1059 *
1060 * I think this field should be removed in favor of a
1061 * new 802.11n radiotap field "RX chains" that is defined
1062 * as a bitmask.
1063 */
1064 rx_status.antenna =
1065 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1066 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1067
1068 /* set the preamble flag if appropriate */
1069 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1070 rx_status.flag |= RX_FLAG_SHORTPRE;
1071
1072 /* Set up the HT phy flags */
1073 if (rate_n_flags & RATE_MCS_HT_MSK)
1074 rx_status.flag |= RX_FLAG_HT;
1075 if (rate_n_flags & RATE_MCS_HT40_MSK)
1076 rx_status.flag |= RX_FLAG_40MHZ;
1077 if (rate_n_flags & RATE_MCS_SGI_MSK)
1078 rx_status.flag |= RX_FLAG_SHORT_GI;
1079
1080 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1081 rxb, &rx_status);
1082}
1083
1084/**
1085 * iwl_setup_rx_handlers - Initialize Rx handler callbacks
1086 *
1087 * Setup the RX handlers for each of the reply types sent from the uCode
1088 * to the host.
1089 */
1090void iwl_setup_rx_handlers(struct iwl_priv *priv)
1091{
1092 void (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
1093
1094 handlers = priv->rx_handlers;
1095
1096 handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
1097 handlers[REPLY_ERROR] = iwl_rx_reply_error;
1098 handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
1099 handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif;
1100 handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
1101 handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif;
1102 handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
1103
1104 /*
1105 * The same handler is used for both the REPLY to a discrete
1106 * statistics request from the host as well as for the periodic
1107 * statistics notifications (after received beacons) from the uCode.
1108 */
1109 handlers[REPLY_STATISTICS_CMD] = iwl_rx_reply_statistics;
1110 handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
1111
1112 iwl_setup_rx_scan_handlers(priv);
1113
1114 handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif;
1115 handlers[MISSED_BEACONS_NOTIFICATION] = iwl_rx_missed_beacon_notif;
1116
1117 /* Rx handlers */
1118 handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy;
1119 handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx;
1120
1121 /* block ack */
1122 handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba;
1123
1124 /* Set up hardware specific Rx handlers */
1125 priv->cfg->ops->lib->rx_handler_setup(priv);
1126}