aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c235
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c176
-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-rx.c523
6 files changed, 500 insertions, 528 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 87a9fd8e41e..25fccf9a300 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -995,241 +995,6 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
995 return -1; 995 return -1;
996} 996}
997 997
998/* Calc max signal level (dBm) among 3 possible receivers */
999static inline int iwlagn_calc_rssi(struct iwl_priv *priv,
1000 struct iwl_rx_phy_res *rx_resp)
1001{
1002 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
1003}
1004
1005static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
1006{
1007 u32 decrypt_out = 0;
1008
1009 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
1010 RX_RES_STATUS_STATION_FOUND)
1011 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
1012 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
1013
1014 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
1015
1016 /* packet was not encrypted */
1017 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
1018 RX_RES_STATUS_SEC_TYPE_NONE)
1019 return decrypt_out;
1020
1021 /* packet was encrypted with unknown alg */
1022 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
1023 RX_RES_STATUS_SEC_TYPE_ERR)
1024 return decrypt_out;
1025
1026 /* decryption was not done in HW */
1027 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
1028 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
1029 return decrypt_out;
1030
1031 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
1032
1033 case RX_RES_STATUS_SEC_TYPE_CCMP:
1034 /* alg is CCM: check MIC only */
1035 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
1036 /* Bad MIC */
1037 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
1038 else
1039 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
1040
1041 break;
1042
1043 case RX_RES_STATUS_SEC_TYPE_TKIP:
1044 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
1045 /* Bad TTAK */
1046 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
1047 break;
1048 }
1049 /* fall through if TTAK OK */
1050 default:
1051 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
1052 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
1053 else
1054 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
1055 break;
1056 }
1057
1058 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
1059 decrypt_in, decrypt_out);
1060
1061 return decrypt_out;
1062}
1063
1064static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
1065 struct ieee80211_hdr *hdr,
1066 u16 len,
1067 u32 ampdu_status,
1068 struct iwl_rx_mem_buffer *rxb,
1069 struct ieee80211_rx_status *stats)
1070{
1071 struct sk_buff *skb;
1072 __le16 fc = hdr->frame_control;
1073
1074 /* We only process data packets if the interface is open */
1075 if (unlikely(!priv->is_open)) {
1076 IWL_DEBUG_DROP_LIMIT(priv,
1077 "Dropping packet while interface is not open.\n");
1078 return;
1079 }
1080
1081 /* In case of HW accelerated crypto and bad decryption, drop */
1082 if (!priv->cfg->mod_params->sw_crypto &&
1083 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
1084 return;
1085
1086 skb = dev_alloc_skb(128);
1087 if (!skb) {
1088 IWL_ERR(priv, "dev_alloc_skb failed\n");
1089 return;
1090 }
1091
1092 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
1093
1094 iwl_update_stats(priv, false, fc, len);
1095 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
1096
1097 ieee80211_rx(priv->hw, skb);
1098 priv->alloc_rxb_page--;
1099 rxb->page = NULL;
1100}
1101
1102/* Called for REPLY_RX (legacy ABG frames), or
1103 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
1104void iwlagn_rx_reply_rx(struct iwl_priv *priv,
1105 struct iwl_rx_mem_buffer *rxb)
1106{
1107 struct ieee80211_hdr *header;
1108 struct ieee80211_rx_status rx_status;
1109 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1110 struct iwl_rx_phy_res *phy_res;
1111 __le32 rx_pkt_status;
1112 struct iwl_rx_mpdu_res_start *amsdu;
1113 u32 len;
1114 u32 ampdu_status;
1115 u32 rate_n_flags;
1116
1117 /**
1118 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
1119 * REPLY_RX: physical layer info is in this buffer
1120 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
1121 * command and cached in priv->last_phy_res
1122 *
1123 * Here we set up local variables depending on which command is
1124 * received.
1125 */
1126 if (pkt->hdr.cmd == REPLY_RX) {
1127 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
1128 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
1129 + phy_res->cfg_phy_cnt);
1130
1131 len = le16_to_cpu(phy_res->byte_count);
1132 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
1133 phy_res->cfg_phy_cnt + len);
1134 ampdu_status = le32_to_cpu(rx_pkt_status);
1135 } else {
1136 if (!priv->_agn.last_phy_res_valid) {
1137 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1138 return;
1139 }
1140 phy_res = &priv->_agn.last_phy_res;
1141 amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
1142 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1143 len = le16_to_cpu(amsdu->byte_count);
1144 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1145 ampdu_status = iwlagn_translate_rx_status(priv,
1146 le32_to_cpu(rx_pkt_status));
1147 }
1148
1149 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1150 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1151 phy_res->cfg_phy_cnt);
1152 return;
1153 }
1154
1155 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1156 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1157 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1158 le32_to_cpu(rx_pkt_status));
1159 return;
1160 }
1161
1162 /* This will be used in several places later */
1163 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1164
1165 /* rx_status carries information about the packet to mac80211 */
1166 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1167 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1168 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1169 rx_status.freq =
1170 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
1171 rx_status.band);
1172 rx_status.rate_idx =
1173 iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1174 rx_status.flag = 0;
1175
1176 /* TSF isn't reliable. In order to allow smooth user experience,
1177 * this W/A doesn't propagate it to the mac80211 */
1178 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
1179
1180 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1181
1182 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1183 rx_status.signal = iwlagn_calc_rssi(priv, phy_res);
1184
1185 iwl_dbg_log_rx_data_frame(priv, len, header);
1186 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",
1187 rx_status.signal, (unsigned long long)rx_status.mactime);
1188
1189 /*
1190 * "antenna number"
1191 *
1192 * It seems that the antenna field in the phy flags value
1193 * is actually a bit field. This is undefined by radiotap,
1194 * it wants an actual antenna number but I always get "7"
1195 * for most legacy frames I receive indicating that the
1196 * same frame was received on all three RX chains.
1197 *
1198 * I think this field should be removed in favor of a
1199 * new 802.11n radiotap field "RX chains" that is defined
1200 * as a bitmask.
1201 */
1202 rx_status.antenna =
1203 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1204 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1205
1206 /* set the preamble flag if appropriate */
1207 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1208 rx_status.flag |= RX_FLAG_SHORTPRE;
1209
1210 /* Set up the HT phy flags */
1211 if (rate_n_flags & RATE_MCS_HT_MSK)
1212 rx_status.flag |= RX_FLAG_HT;
1213 if (rate_n_flags & RATE_MCS_HT40_MSK)
1214 rx_status.flag |= RX_FLAG_40MHZ;
1215 if (rate_n_flags & RATE_MCS_SGI_MSK)
1216 rx_status.flag |= RX_FLAG_SHORT_GI;
1217
1218 iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1219 rxb, &rx_status);
1220}
1221
1222/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1223 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1224void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
1225 struct iwl_rx_mem_buffer *rxb)
1226{
1227 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1228 priv->_agn.last_phy_res_valid = true;
1229 memcpy(&priv->_agn.last_phy_res, pkt->u.raw,
1230 sizeof(struct iwl_rx_phy_res));
1231}
1232
1233static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, 998static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
1234 struct ieee80211_vif *vif, 999 struct ieee80211_vif *vif,
1235 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 c96d4ad5def..6b6f2d88be1 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index b5a169be48e..20f8e418899 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 4bd34206025..6c30fa652e2 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 d47f3a87fce..af47750f898 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-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 566e2d979ce..8dc129499b9 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}