aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c436
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c411
8 files changed, 470 insertions, 472 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index cee31cdf0a22..af48d07bb29d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1881,7 +1881,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
1881 info->status.rates[0].count = tx_resp->failure_frame + 1; 1881 info->status.rates[0].count = tx_resp->failure_frame + 1;
1882 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 1882 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1883 info->flags |= iwl_tx_status_to_mac80211(status); 1883 info->flags |= iwl_tx_status_to_mac80211(status);
1884 iwl_hwrate_to_tx_control(priv, rate_n_flags, info); 1884 iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
1885 /* FIXME: code repetition end */ 1885 /* FIXME: code repetition end */
1886 1886
1887 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", 1887 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
@@ -2036,7 +2036,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2036 } else { 2036 } else {
2037 info->status.rates[0].count = tx_resp->failure_frame + 1; 2037 info->status.rates[0].count = tx_resp->failure_frame + 1;
2038 info->flags |= iwl_tx_status_to_mac80211(status); 2038 info->flags |= iwl_tx_status_to_mac80211(status);
2039 iwl_hwrate_to_tx_control(priv, 2039 iwlagn_hwrate_to_tx_control(priv,
2040 le32_to_cpu(tx_resp->rate_n_flags), 2040 le32_to_cpu(tx_resp->rate_n_flags),
2041 info); 2041 info);
2042 2042
@@ -2102,7 +2102,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
2102static void iwl4965_rx_handler_setup(struct iwl_priv *priv) 2102static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
2103{ 2103{
2104 /* Legacy Rx frames */ 2104 /* Legacy Rx frames */
2105 priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx; 2105 priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx;
2106 /* Tx response */ 2106 /* Tx response */
2107 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; 2107 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
2108} 2108}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 3117382cfd48..226862d3d5ac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -26,7 +26,7 @@
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 * 27 *
28 *****************************************************************************/ 28 *****************************************************************************/
29 29#include <linux/etherdevice.h>
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/init.h> 32#include <linux/init.h>
@@ -80,7 +80,7 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
80 info->status.rates[0].count = tx_resp->failure_frame + 1; 80 info->status.rates[0].count = tx_resp->failure_frame + 1;
81 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 81 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
82 info->flags |= iwl_tx_status_to_mac80211(status); 82 info->flags |= iwl_tx_status_to_mac80211(status);
83 iwl_hwrate_to_tx_control(priv, rate_n_flags, info); 83 iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
84 84
85 /* FIXME: code repetition end */ 85 /* FIXME: code repetition end */
86 86
@@ -225,7 +225,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
225 225
226 info->status.rates[0].count = tx_resp->failure_frame + 1; 226 info->status.rates[0].count = tx_resp->failure_frame + 1;
227 info->flags |= iwl_tx_status_to_mac80211(status); 227 info->flags |= iwl_tx_status_to_mac80211(status);
228 iwl_hwrate_to_tx_control(priv, 228 iwlagn_hwrate_to_tx_control(priv,
229 le32_to_cpu(tx_resp->rate_n_flags), 229 le32_to_cpu(tx_resp->rate_n_flags),
230 info); 230 info);
231 231
@@ -709,3 +709,433 @@ int iwlagn_rxq_stop(struct iwl_priv *priv)
709 709
710 return 0; 710 return 0;
711} 711}
712
713int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
714{
715 int idx = 0;
716 int band_offset = 0;
717
718 /* HT rate format: mac80211 wants an MCS number, which is just LSB */
719 if (rate_n_flags & RATE_MCS_HT_MSK) {
720 idx = (rate_n_flags & 0xff);
721 return idx;
722 /* Legacy rate format, search for match in table */
723 } else {
724 if (band == IEEE80211_BAND_5GHZ)
725 band_offset = IWL_FIRST_OFDM_RATE;
726 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
727 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
728 return idx - band_offset;
729 }
730
731 return -1;
732}
733
734/* Calc max signal level (dBm) among 3 possible receivers */
735static inline int iwlagn_calc_rssi(struct iwl_priv *priv,
736 struct iwl_rx_phy_res *rx_resp)
737{
738 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
739}
740
741#ifdef CONFIG_IWLWIFI_DEBUG
742/**
743 * iwlagn_dbg_report_frame - dump frame to syslog during debug sessions
744 *
745 * You may hack this function to show different aspects of received frames,
746 * including selective frame dumps.
747 * group100 parameter selects whether to show 1 out of 100 good data frames.
748 * All beacon and probe response frames are printed.
749 */
750static void iwlagn_dbg_report_frame(struct iwl_priv *priv,
751 struct iwl_rx_phy_res *phy_res, u16 length,
752 struct ieee80211_hdr *header, int group100)
753{
754 u32 to_us;
755 u32 print_summary = 0;
756 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
757 u32 hundred = 0;
758 u32 dataframe = 0;
759 __le16 fc;
760 u16 seq_ctl;
761 u16 channel;
762 u16 phy_flags;
763 u32 rate_n_flags;
764 u32 tsf_low;
765 int rssi;
766
767 if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX)))
768 return;
769
770 /* MAC header */
771 fc = header->frame_control;
772 seq_ctl = le16_to_cpu(header->seq_ctrl);
773
774 /* metadata */
775 channel = le16_to_cpu(phy_res->channel);
776 phy_flags = le16_to_cpu(phy_res->phy_flags);
777 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
778
779 /* signal statistics */
780 rssi = iwlagn_calc_rssi(priv, phy_res);
781 tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
782
783 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
784
785 /* if data frame is to us and all is good,
786 * (optionally) print summary for only 1 out of every 100 */
787 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
788 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
789 dataframe = 1;
790 if (!group100)
791 print_summary = 1; /* print each frame */
792 else if (priv->framecnt_to_us < 100) {
793 priv->framecnt_to_us++;
794 print_summary = 0;
795 } else {
796 priv->framecnt_to_us = 0;
797 print_summary = 1;
798 hundred = 1;
799 }
800 } else {
801 /* print summary for all other frames */
802 print_summary = 1;
803 }
804
805 if (print_summary) {
806 char *title;
807 int rate_idx;
808 u32 bitrate;
809
810 if (hundred)
811 title = "100Frames";
812 else if (ieee80211_has_retry(fc))
813 title = "Retry";
814 else if (ieee80211_is_assoc_resp(fc))
815 title = "AscRsp";
816 else if (ieee80211_is_reassoc_resp(fc))
817 title = "RasRsp";
818 else if (ieee80211_is_probe_resp(fc)) {
819 title = "PrbRsp";
820 print_dump = 1; /* dump frame contents */
821 } else if (ieee80211_is_beacon(fc)) {
822 title = "Beacon";
823 print_dump = 1; /* dump frame contents */
824 } else if (ieee80211_is_atim(fc))
825 title = "ATIM";
826 else if (ieee80211_is_auth(fc))
827 title = "Auth";
828 else if (ieee80211_is_deauth(fc))
829 title = "DeAuth";
830 else if (ieee80211_is_disassoc(fc))
831 title = "DisAssoc";
832 else
833 title = "Frame";
834
835 rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
836 if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
837 bitrate = 0;
838 WARN_ON_ONCE(1);
839 } else {
840 bitrate = iwl_rates[rate_idx].ieee / 2;
841 }
842
843 /* print frame summary.
844 * MAC addresses show just the last byte (for brevity),
845 * but you can hack it to show more, if you'd like to. */
846 if (dataframe)
847 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
848 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
849 title, le16_to_cpu(fc), header->addr1[5],
850 length, rssi, channel, bitrate);
851 else {
852 /* src/dst addresses assume managed mode */
853 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
854 "len=%u, rssi=%d, tim=%lu usec, "
855 "phy=0x%02x, chnl=%d\n",
856 title, le16_to_cpu(fc), header->addr1[5],
857 header->addr3[5], length, rssi,
858 tsf_low - priv->scan_start_tsf,
859 phy_flags, channel);
860 }
861 }
862 if (print_dump)
863 iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
864}
865#endif
866
867static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
868{
869 u32 decrypt_out = 0;
870
871 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
872 RX_RES_STATUS_STATION_FOUND)
873 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
874 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
875
876 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
877
878 /* packet was not encrypted */
879 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
880 RX_RES_STATUS_SEC_TYPE_NONE)
881 return decrypt_out;
882
883 /* packet was encrypted with unknown alg */
884 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
885 RX_RES_STATUS_SEC_TYPE_ERR)
886 return decrypt_out;
887
888 /* decryption was not done in HW */
889 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
890 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
891 return decrypt_out;
892
893 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
894
895 case RX_RES_STATUS_SEC_TYPE_CCMP:
896 /* alg is CCM: check MIC only */
897 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
898 /* Bad MIC */
899 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
900 else
901 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
902
903 break;
904
905 case RX_RES_STATUS_SEC_TYPE_TKIP:
906 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
907 /* Bad TTAK */
908 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
909 break;
910 }
911 /* fall through if TTAK OK */
912 default:
913 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
914 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
915 else
916 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
917 break;
918 };
919
920 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
921 decrypt_in, decrypt_out);
922
923 return decrypt_out;
924}
925
926static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
927 struct ieee80211_hdr *hdr,
928 u16 len,
929 u32 ampdu_status,
930 struct iwl_rx_mem_buffer *rxb,
931 struct ieee80211_rx_status *stats)
932{
933 struct sk_buff *skb;
934 int ret = 0;
935 __le16 fc = hdr->frame_control;
936
937 /* We only process data packets if the interface is open */
938 if (unlikely(!priv->is_open)) {
939 IWL_DEBUG_DROP_LIMIT(priv,
940 "Dropping packet while interface is not open.\n");
941 return;
942 }
943
944 /* In case of HW accelerated crypto and bad decryption, drop */
945 if (!priv->cfg->mod_params->sw_crypto &&
946 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
947 return;
948
949 skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
950 if (!skb) {
951 IWL_ERR(priv, "alloc_skb failed\n");
952 return;
953 }
954
955 skb_reserve(skb, IWL_LINK_HDR_MAX);
956 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
957
958 /* mac80211 currently doesn't support paged SKB. Convert it to
959 * linear SKB for management frame and data frame requires
960 * software decryption or software defragementation. */
961 if (ieee80211_is_mgmt(fc) ||
962 ieee80211_has_protected(fc) ||
963 ieee80211_has_morefrags(fc) ||
964 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG ||
965 (ieee80211_is_data_qos(fc) &&
966 *ieee80211_get_qos_ctl(hdr) &
967 IEEE80211_QOS_CONTROL_A_MSDU_PRESENT))
968 ret = skb_linearize(skb);
969 else
970 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
971 0 : -ENOMEM;
972
973 if (ret) {
974 kfree_skb(skb);
975 goto out;
976 }
977
978 /*
979 * XXX: We cannot touch the page and its virtual memory (hdr) after
980 * here. It might have already been freed by the above skb change.
981 */
982
983 iwl_update_stats(priv, false, fc, len);
984 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
985
986 ieee80211_rx(priv->hw, skb);
987 out:
988 priv->alloc_rxb_page--;
989 rxb->page = NULL;
990}
991
992/* Called for REPLY_RX (legacy ABG frames), or
993 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
994void iwlagn_rx_reply_rx(struct iwl_priv *priv,
995 struct iwl_rx_mem_buffer *rxb)
996{
997 struct ieee80211_hdr *header;
998 struct ieee80211_rx_status rx_status;
999 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1000 struct iwl_rx_phy_res *phy_res;
1001 __le32 rx_pkt_status;
1002 struct iwl4965_rx_mpdu_res_start *amsdu;
1003 u32 len;
1004 u32 ampdu_status;
1005 u32 rate_n_flags;
1006
1007 /**
1008 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
1009 * REPLY_RX: physical layer info is in this buffer
1010 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
1011 * command and cached in priv->last_phy_res
1012 *
1013 * Here we set up local variables depending on which command is
1014 * received.
1015 */
1016 if (pkt->hdr.cmd == REPLY_RX) {
1017 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
1018 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
1019 + phy_res->cfg_phy_cnt);
1020
1021 len = le16_to_cpu(phy_res->byte_count);
1022 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
1023 phy_res->cfg_phy_cnt + len);
1024 ampdu_status = le32_to_cpu(rx_pkt_status);
1025 } else {
1026 if (!priv->last_phy_res[0]) {
1027 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1028 return;
1029 }
1030 phy_res = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
1031 amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
1032 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1033 len = le16_to_cpu(amsdu->byte_count);
1034 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1035 ampdu_status = iwlagn_translate_rx_status(priv,
1036 le32_to_cpu(rx_pkt_status));
1037 }
1038
1039 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1040 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1041 phy_res->cfg_phy_cnt);
1042 return;
1043 }
1044
1045 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1046 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1047 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1048 le32_to_cpu(rx_pkt_status));
1049 return;
1050 }
1051
1052 /* This will be used in several places later */
1053 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1054
1055 /* rx_status carries information about the packet to mac80211 */
1056 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1057 rx_status.freq =
1058 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
1059 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1060 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1061 rx_status.rate_idx =
1062 iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1063 rx_status.flag = 0;
1064
1065 /* TSF isn't reliable. In order to allow smooth user experience,
1066 * this W/A doesn't propagate it to the mac80211 */
1067 /*rx_status.flag |= RX_FLAG_TSFT;*/
1068
1069 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1070
1071 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1072 rx_status.signal = iwlagn_calc_rssi(priv, phy_res);
1073
1074 /* Meaningful noise values are available only from beacon statistics,
1075 * which are gathered only when associated, and indicate noise
1076 * only for the associated network channel ...
1077 * Ignore these noise values while scanning (other channels) */
1078 if (iwl_is_associated(priv) &&
1079 !test_bit(STATUS_SCANNING, &priv->status)) {
1080 rx_status.noise = priv->last_rx_noise;
1081 } else {
1082 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1083 }
1084
1085 /* Reset beacon noise level if not associated. */
1086 if (!iwl_is_associated(priv))
1087 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1088
1089#ifdef CONFIG_IWLWIFI_DEBUG
1090 /* Set "1" to report good data frames in groups of 100 */
1091 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
1092 iwlagn_dbg_report_frame(priv, phy_res, len, header, 1);
1093#endif
1094 iwl_dbg_log_rx_data_frame(priv, len, header);
1095 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, TSF %llu\n",
1096 rx_status.signal, rx_status.noise,
1097 (unsigned long long)rx_status.mactime);
1098
1099 /*
1100 * "antenna number"
1101 *
1102 * It seems that the antenna field in the phy flags value
1103 * is actually a bit field. This is undefined by radiotap,
1104 * it wants an actual antenna number but I always get "7"
1105 * for most legacy frames I receive indicating that the
1106 * same frame was received on all three RX chains.
1107 *
1108 * I think this field should be removed in favor of a
1109 * new 802.11n radiotap field "RX chains" that is defined
1110 * as a bitmask.
1111 */
1112 rx_status.antenna =
1113 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1114 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1115
1116 /* set the preamble flag if appropriate */
1117 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1118 rx_status.flag |= RX_FLAG_SHORTPRE;
1119
1120 /* Set up the HT phy flags */
1121 if (rate_n_flags & RATE_MCS_HT_MSK)
1122 rx_status.flag |= RX_FLAG_HT;
1123 if (rate_n_flags & RATE_MCS_HT40_MSK)
1124 rx_status.flag |= RX_FLAG_40MHZ;
1125 if (rate_n_flags & RATE_MCS_SGI_MSK)
1126 rx_status.flag |= RX_FLAG_SHORT_GI;
1127
1128 iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1129 rxb, &rx_status);
1130}
1131
1132/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1133 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1134void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
1135 struct iwl_rx_mem_buffer *rxb)
1136{
1137 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1138 priv->last_phy_res[0] = 1;
1139 memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
1140 sizeof(struct iwl_rx_phy_res));
1141}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 4e4b70d10804..257e4aff3d96 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -38,6 +38,7 @@
38#include "iwl-io.h" 38#include "iwl-io.h"
39#include "iwl-helpers.h" 39#include "iwl-helpers.h"
40#include "iwl-agn-hw.h" 40#include "iwl-agn-hw.h"
41#include "iwl-agn.h"
41 42
42/* 43/*
43 * mac80211 queues, ACs, hardware queues, FIFOs. 44 * mac80211 queues, ACs, hardware queues, FIFOs.
@@ -1206,7 +1207,7 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1206 info->flags |= IEEE80211_TX_STAT_AMPDU; 1207 info->flags |= IEEE80211_TX_STAT_AMPDU;
1207 info->status.ampdu_ack_map = successes; 1208 info->status.ampdu_ack_map = successes;
1208 info->status.ampdu_ack_len = agg->frame_count; 1209 info->status.ampdu_ack_len = agg->frame_count;
1209 iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info); 1210 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1210 1211
1211 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); 1212 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
1212 1213
@@ -1214,6 +1215,29 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1214} 1215}
1215 1216
1216/** 1217/**
1218 * translate ucode response to mac80211 tx status control values
1219 */
1220void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
1221 struct ieee80211_tx_info *info)
1222{
1223 struct ieee80211_tx_rate *r = &info->control.rates[0];
1224
1225 info->antenna_sel_tx =
1226 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
1227 if (rate_n_flags & RATE_MCS_HT_MSK)
1228 r->flags |= IEEE80211_TX_RC_MCS;
1229 if (rate_n_flags & RATE_MCS_GF_MSK)
1230 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
1231 if (rate_n_flags & RATE_MCS_HT40_MSK)
1232 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
1233 if (rate_n_flags & RATE_MCS_DUP_MSK)
1234 r->flags |= IEEE80211_TX_RC_DUP_DATA;
1235 if (rate_n_flags & RATE_MCS_SGI_MSK)
1236 r->flags |= IEEE80211_TX_RC_SHORT_GI;
1237 r->idx = iwlagn_hwrate_to_mac80211_idx(rate_n_flags, info->band);
1238}
1239
1240/**
1217 * iwlagn_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA 1241 * iwlagn_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
1218 * 1242 *
1219 * Handles block-acknowledge notification from device, which reports success 1243 * Handles block-acknowledge notification from device, which reports success
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index d9a287b639bf..bc08e9bdf9ac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -884,8 +884,8 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
884 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = 884 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
885 iwl_rx_missed_beacon_notif; 885 iwl_rx_missed_beacon_notif;
886 /* Rx handlers */ 886 /* Rx handlers */
887 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; 887 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy;
888 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; 888 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx;
889 /* block ack */ 889 /* block ack */
890 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba; 890 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba;
891 /* Set up hardware specific Rx handlers */ 891 /* Set up hardware specific Rx handlers */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 48f7de0914cb..5ad14055eda3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -124,8 +124,15 @@ void iwlagn_rx_replenish(struct iwl_priv *priv);
124void iwlagn_rx_replenish_now(struct iwl_priv *priv); 124void iwlagn_rx_replenish_now(struct iwl_priv *priv);
125void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 125void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
126int iwlagn_rxq_stop(struct iwl_priv *priv); 126int iwlagn_rxq_stop(struct iwl_priv *priv);
127int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
128void iwlagn_rx_reply_rx(struct iwl_priv *priv,
129 struct iwl_rx_mem_buffer *rxb);
130void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
131 struct iwl_rx_mem_buffer *rxb);
127 132
128/* tx */ 133/* tx */
134void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
135 struct ieee80211_tx_info *info);
129int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); 136int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
130int iwlagn_tx_agg_start(struct iwl_priv *priv, 137int iwlagn_tx_agg_start(struct iwl_priv *priv,
131 const u8 *ra, u16 tid, u16 *ssn); 138 const u8 *ra, u16 tid, u16 *ssn);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 0dc41d84dc15..6fe785380824 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -140,30 +140,6 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
140}; 140};
141EXPORT_SYMBOL(iwl_rates); 141EXPORT_SYMBOL(iwl_rates);
142 142
143/**
144 * translate ucode response to mac80211 tx status control values
145 */
146void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
147 struct ieee80211_tx_info *info)
148{
149 struct ieee80211_tx_rate *r = &info->control.rates[0];
150
151 info->antenna_sel_tx =
152 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
153 if (rate_n_flags & RATE_MCS_HT_MSK)
154 r->flags |= IEEE80211_TX_RC_MCS;
155 if (rate_n_flags & RATE_MCS_GF_MSK)
156 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
157 if (rate_n_flags & RATE_MCS_HT40_MSK)
158 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
159 if (rate_n_flags & RATE_MCS_DUP_MSK)
160 r->flags |= IEEE80211_TX_RC_DUP_DATA;
161 if (rate_n_flags & RATE_MCS_SGI_MSK)
162 r->flags |= IEEE80211_TX_RC_SHORT_GI;
163 r->idx = iwl_hwrate_to_mac80211_idx(rate_n_flags, info->band);
164}
165EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
166
167int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) 143int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
168{ 144{
169 int idx = 0; 145 int idx = 0;
@@ -195,27 +171,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
195} 171}
196EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); 172EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
197 173
198int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
199{
200 int idx = 0;
201 int band_offset = 0;
202
203 /* HT rate format: mac80211 wants an MCS number, which is just LSB */
204 if (rate_n_flags & RATE_MCS_HT_MSK) {
205 idx = (rate_n_flags & 0xff);
206 return idx;
207 /* Legacy rate format, search for match in table */
208 } else {
209 if (band == IEEE80211_BAND_5GHZ)
210 band_offset = IWL_FIRST_OFDM_RATE;
211 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
212 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
213 return idx - band_offset;
214 }
215
216 return -1;
217}
218
219u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) 174u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant)
220{ 175{
221 int i; 176 int i;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7c6ac34940fe..22f84f3c3c40 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -467,10 +467,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
467 * Rate 467 * Rate
468 ******************************************************************************/ 468 ******************************************************************************/
469 469
470void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
471 struct ieee80211_tx_info *info);
472int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); 470int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
473int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
474 471
475u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); 472u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
476 473
@@ -670,10 +667,6 @@ extern int iwl_send_statistics_request(struct iwl_priv *priv,
670extern int iwl_verify_ucode(struct iwl_priv *priv); 667extern int iwl_verify_ucode(struct iwl_priv *priv);
671extern int iwl_send_lq_cmd(struct iwl_priv *priv, 668extern int iwl_send_lq_cmd(struct iwl_priv *priv,
672 struct iwl_link_quality_cmd *lq, u8 flags, bool init); 669 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
673extern void iwl_rx_reply_rx(struct iwl_priv *priv,
674 struct iwl_rx_mem_buffer *rxb);
675extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
676 struct iwl_rx_mem_buffer *rxb);
677void iwl_apm_stop(struct iwl_priv *priv); 670void iwl_apm_stop(struct iwl_priv *priv);
678int iwl_apm_init(struct iwl_priv *priv); 671int iwl_apm_init(struct iwl_priv *priv);
679 672
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 45230c6a7899..3a4313841fe7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -489,139 +489,6 @@ void iwl_reply_statistics(struct iwl_priv *priv,
489} 489}
490EXPORT_SYMBOL(iwl_reply_statistics); 490EXPORT_SYMBOL(iwl_reply_statistics);
491 491
492/* Calc max signal level (dBm) among 3 possible receivers */
493static inline int iwl_calc_rssi(struct iwl_priv *priv,
494 struct iwl_rx_phy_res *rx_resp)
495{
496 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
497}
498
499#ifdef CONFIG_IWLWIFI_DEBUG
500/**
501 * iwl_dbg_report_frame - dump frame to syslog during debug sessions
502 *
503 * You may hack this function to show different aspects of received frames,
504 * including selective frame dumps.
505 * group100 parameter selects whether to show 1 out of 100 good data frames.
506 * All beacon and probe response frames are printed.
507 */
508static void iwl_dbg_report_frame(struct iwl_priv *priv,
509 struct iwl_rx_phy_res *phy_res, u16 length,
510 struct ieee80211_hdr *header, int group100)
511{
512 u32 to_us;
513 u32 print_summary = 0;
514 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
515 u32 hundred = 0;
516 u32 dataframe = 0;
517 __le16 fc;
518 u16 seq_ctl;
519 u16 channel;
520 u16 phy_flags;
521 u32 rate_n_flags;
522 u32 tsf_low;
523 int rssi;
524
525 if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX)))
526 return;
527
528 /* MAC header */
529 fc = header->frame_control;
530 seq_ctl = le16_to_cpu(header->seq_ctrl);
531
532 /* metadata */
533 channel = le16_to_cpu(phy_res->channel);
534 phy_flags = le16_to_cpu(phy_res->phy_flags);
535 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
536
537 /* signal statistics */
538 rssi = iwl_calc_rssi(priv, phy_res);
539 tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
540
541 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
542
543 /* if data frame is to us and all is good,
544 * (optionally) print summary for only 1 out of every 100 */
545 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
546 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
547 dataframe = 1;
548 if (!group100)
549 print_summary = 1; /* print each frame */
550 else if (priv->framecnt_to_us < 100) {
551 priv->framecnt_to_us++;
552 print_summary = 0;
553 } else {
554 priv->framecnt_to_us = 0;
555 print_summary = 1;
556 hundred = 1;
557 }
558 } else {
559 /* print summary for all other frames */
560 print_summary = 1;
561 }
562
563 if (print_summary) {
564 char *title;
565 int rate_idx;
566 u32 bitrate;
567
568 if (hundred)
569 title = "100Frames";
570 else if (ieee80211_has_retry(fc))
571 title = "Retry";
572 else if (ieee80211_is_assoc_resp(fc))
573 title = "AscRsp";
574 else if (ieee80211_is_reassoc_resp(fc))
575 title = "RasRsp";
576 else if (ieee80211_is_probe_resp(fc)) {
577 title = "PrbRsp";
578 print_dump = 1; /* dump frame contents */
579 } else if (ieee80211_is_beacon(fc)) {
580 title = "Beacon";
581 print_dump = 1; /* dump frame contents */
582 } else if (ieee80211_is_atim(fc))
583 title = "ATIM";
584 else if (ieee80211_is_auth(fc))
585 title = "Auth";
586 else if (ieee80211_is_deauth(fc))
587 title = "DeAuth";
588 else if (ieee80211_is_disassoc(fc))
589 title = "DisAssoc";
590 else
591 title = "Frame";
592
593 rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
594 if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
595 bitrate = 0;
596 WARN_ON_ONCE(1);
597 } else {
598 bitrate = iwl_rates[rate_idx].ieee / 2;
599 }
600
601 /* print frame summary.
602 * MAC addresses show just the last byte (for brevity),
603 * but you can hack it to show more, if you'd like to. */
604 if (dataframe)
605 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
606 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
607 title, le16_to_cpu(fc), header->addr1[5],
608 length, rssi, channel, bitrate);
609 else {
610 /* src/dst addresses assume managed mode */
611 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
612 "len=%u, rssi=%d, tim=%lu usec, "
613 "phy=0x%02x, chnl=%d\n",
614 title, le16_to_cpu(fc), header->addr1[5],
615 header->addr3[5], length, rssi,
616 tsf_low - priv->scan_start_tsf,
617 phy_flags, channel);
618 }
619 }
620 if (print_dump)
621 iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
622}
623#endif
624
625/* 492/*
626 * returns non-zero if packet should be dropped 493 * returns non-zero if packet should be dropped
627 */ 494 */
@@ -669,281 +536,3 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
669 return 0; 536 return 0;
670} 537}
671EXPORT_SYMBOL(iwl_set_decrypted_flag); 538EXPORT_SYMBOL(iwl_set_decrypted_flag);
672
673static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
674{
675 u32 decrypt_out = 0;
676
677 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
678 RX_RES_STATUS_STATION_FOUND)
679 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
680 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
681
682 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
683
684 /* packet was not encrypted */
685 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
686 RX_RES_STATUS_SEC_TYPE_NONE)
687 return decrypt_out;
688
689 /* packet was encrypted with unknown alg */
690 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
691 RX_RES_STATUS_SEC_TYPE_ERR)
692 return decrypt_out;
693
694 /* decryption was not done in HW */
695 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
696 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
697 return decrypt_out;
698
699 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
700
701 case RX_RES_STATUS_SEC_TYPE_CCMP:
702 /* alg is CCM: check MIC only */
703 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
704 /* Bad MIC */
705 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
706 else
707 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
708
709 break;
710
711 case RX_RES_STATUS_SEC_TYPE_TKIP:
712 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
713 /* Bad TTAK */
714 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
715 break;
716 }
717 /* fall through if TTAK OK */
718 default:
719 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
720 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
721 else
722 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
723 break;
724 };
725
726 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
727 decrypt_in, decrypt_out);
728
729 return decrypt_out;
730}
731
732static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
733 struct ieee80211_hdr *hdr,
734 u16 len,
735 u32 ampdu_status,
736 struct iwl_rx_mem_buffer *rxb,
737 struct ieee80211_rx_status *stats)
738{
739 struct sk_buff *skb;
740 int ret = 0;
741 __le16 fc = hdr->frame_control;
742
743 /* We only process data packets if the interface is open */
744 if (unlikely(!priv->is_open)) {
745 IWL_DEBUG_DROP_LIMIT(priv,
746 "Dropping packet while interface is not open.\n");
747 return;
748 }
749
750 /* In case of HW accelerated crypto and bad decryption, drop */
751 if (!priv->cfg->mod_params->sw_crypto &&
752 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
753 return;
754
755 skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
756 if (!skb) {
757 IWL_ERR(priv, "alloc_skb failed\n");
758 return;
759 }
760
761 skb_reserve(skb, IWL_LINK_HDR_MAX);
762 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
763
764 /* mac80211 currently doesn't support paged SKB. Convert it to
765 * linear SKB for management frame and data frame requires
766 * software decryption or software defragementation. */
767 if (ieee80211_is_mgmt(fc) ||
768 ieee80211_has_protected(fc) ||
769 ieee80211_has_morefrags(fc) ||
770 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG ||
771 (ieee80211_is_data_qos(fc) &&
772 *ieee80211_get_qos_ctl(hdr) &
773 IEEE80211_QOS_CONTROL_A_MSDU_PRESENT))
774 ret = skb_linearize(skb);
775 else
776 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
777 0 : -ENOMEM;
778
779 if (ret) {
780 kfree_skb(skb);
781 goto out;
782 }
783
784 /*
785 * XXX: We cannot touch the page and its virtual memory (hdr) after
786 * here. It might have already been freed by the above skb change.
787 */
788
789 iwl_update_stats(priv, false, fc, len);
790 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
791
792 ieee80211_rx(priv->hw, skb);
793 out:
794 priv->alloc_rxb_page--;
795 rxb->page = NULL;
796}
797
798/* Called for REPLY_RX (legacy ABG frames), or
799 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
800void iwl_rx_reply_rx(struct iwl_priv *priv,
801 struct iwl_rx_mem_buffer *rxb)
802{
803 struct ieee80211_hdr *header;
804 struct ieee80211_rx_status rx_status;
805 struct iwl_rx_packet *pkt = rxb_addr(rxb);
806 struct iwl_rx_phy_res *phy_res;
807 __le32 rx_pkt_status;
808 struct iwl4965_rx_mpdu_res_start *amsdu;
809 u32 len;
810 u32 ampdu_status;
811 u32 rate_n_flags;
812
813 /**
814 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
815 * REPLY_RX: physical layer info is in this buffer
816 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
817 * command and cached in priv->last_phy_res
818 *
819 * Here we set up local variables depending on which command is
820 * received.
821 */
822 if (pkt->hdr.cmd == REPLY_RX) {
823 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
824 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
825 + phy_res->cfg_phy_cnt);
826
827 len = le16_to_cpu(phy_res->byte_count);
828 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
829 phy_res->cfg_phy_cnt + len);
830 ampdu_status = le32_to_cpu(rx_pkt_status);
831 } else {
832 if (!priv->last_phy_res[0]) {
833 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
834 return;
835 }
836 phy_res = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
837 amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
838 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
839 len = le16_to_cpu(amsdu->byte_count);
840 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
841 ampdu_status = iwl_translate_rx_status(priv,
842 le32_to_cpu(rx_pkt_status));
843 }
844
845 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
846 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
847 phy_res->cfg_phy_cnt);
848 return;
849 }
850
851 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
852 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
853 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
854 le32_to_cpu(rx_pkt_status));
855 return;
856 }
857
858 /* This will be used in several places later */
859 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
860
861 /* rx_status carries information about the packet to mac80211 */
862 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
863 rx_status.freq =
864 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
865 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
866 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
867 rx_status.rate_idx =
868 iwl_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
869 rx_status.flag = 0;
870
871 /* TSF isn't reliable. In order to allow smooth user experience,
872 * this W/A doesn't propagate it to the mac80211 */
873 /*rx_status.flag |= RX_FLAG_TSFT;*/
874
875 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
876
877 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
878 rx_status.signal = iwl_calc_rssi(priv, phy_res);
879
880 /* Meaningful noise values are available only from beacon statistics,
881 * which are gathered only when associated, and indicate noise
882 * only for the associated network channel ...
883 * Ignore these noise values while scanning (other channels) */
884 if (iwl_is_associated(priv) &&
885 !test_bit(STATUS_SCANNING, &priv->status)) {
886 rx_status.noise = priv->last_rx_noise;
887 } else {
888 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
889 }
890
891 /* Reset beacon noise level if not associated. */
892 if (!iwl_is_associated(priv))
893 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
894
895#ifdef CONFIG_IWLWIFI_DEBUG
896 /* Set "1" to report good data frames in groups of 100 */
897 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
898 iwl_dbg_report_frame(priv, phy_res, len, header, 1);
899#endif
900 iwl_dbg_log_rx_data_frame(priv, len, header);
901 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, TSF %llu\n",
902 rx_status.signal, rx_status.noise,
903 (unsigned long long)rx_status.mactime);
904
905 /*
906 * "antenna number"
907 *
908 * It seems that the antenna field in the phy flags value
909 * is actually a bit field. This is undefined by radiotap,
910 * it wants an actual antenna number but I always get "7"
911 * for most legacy frames I receive indicating that the
912 * same frame was received on all three RX chains.
913 *
914 * I think this field should be removed in favor of a
915 * new 802.11n radiotap field "RX chains" that is defined
916 * as a bitmask.
917 */
918 rx_status.antenna =
919 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
920 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
921
922 /* set the preamble flag if appropriate */
923 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
924 rx_status.flag |= RX_FLAG_SHORTPRE;
925
926 /* Set up the HT phy flags */
927 if (rate_n_flags & RATE_MCS_HT_MSK)
928 rx_status.flag |= RX_FLAG_HT;
929 if (rate_n_flags & RATE_MCS_HT40_MSK)
930 rx_status.flag |= RX_FLAG_40MHZ;
931 if (rate_n_flags & RATE_MCS_SGI_MSK)
932 rx_status.flag |= RX_FLAG_SHORT_GI;
933
934 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
935 rxb, &rx_status);
936}
937EXPORT_SYMBOL(iwl_rx_reply_rx);
938
939/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
940 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
941void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
942 struct iwl_rx_mem_buffer *rxb)
943{
944 struct iwl_rx_packet *pkt = rxb_addr(rxb);
945 priv->last_phy_res[0] = 1;
946 memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
947 sizeof(struct iwl_rx_phy_res));
948}
949EXPORT_SYMBOL(iwl_rx_reply_rx_phy);