diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
42 files changed, 1446 insertions, 3302 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 7b96b3e5712d..8fcc029a76a6 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -120,18 +120,6 @@ config ATH9K_WOW | |||
120 | This option enables Wake on Wireless LAN support for certain cards. | 120 | This option enables Wake on Wireless LAN support for certain cards. |
121 | Currently, AR9462 is supported. | 121 | Currently, AR9462 is supported. |
122 | 122 | ||
123 | config ATH9K_LEGACY_RATE_CONTROL | ||
124 | bool "Atheros ath9k rate control" | ||
125 | depends on ATH9K | ||
126 | default n | ||
127 | ---help--- | ||
128 | Say Y, if you want to use the ath9k specific rate control | ||
129 | module instead of minstrel_ht. Be warned that there are various | ||
130 | issues with the ath9k RC and minstrel is a more robust algorithm. | ||
131 | Note that even if this option is selected, "ath9k_rate_control" | ||
132 | has to be passed to mac80211 using the module parameter, | ||
133 | ieee80211_default_rc_algo. | ||
134 | |||
135 | config ATH9K_RFKILL | 123 | config ATH9K_RFKILL |
136 | bool "Atheros ath9k rfkill support" if EXPERT | 124 | bool "Atheros ath9k rfkill support" if EXPERT |
137 | depends on ATH9K | 125 | depends on ATH9K |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index a40e5c5d7418..8e1c7b0fe76c 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -8,7 +8,6 @@ ath9k-y += beacon.o \ | |||
8 | antenna.o | 8 | antenna.o |
9 | 9 | ||
10 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o | 10 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o |
11 | ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o | ||
12 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o | 11 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o |
13 | ath9k-$(CONFIG_ATH9K_AHB) += ahb.o | 12 | ath9k-$(CONFIG_ATH9K_AHB) += ahb.o |
14 | ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o | 13 | ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o |
@@ -52,7 +51,9 @@ ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ | |||
52 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o | 51 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o |
53 | 52 | ||
54 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o | 53 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o |
55 | ath9k_common-y:= common.o | 54 | ath9k_common-y:= common.o \ |
55 | common-init.o \ | ||
56 | common-beacon.o | ||
56 | 57 | ||
57 | ath9k_htc-y += htc_hst.o \ | 58 | ath9k_htc-y += htc_hst.o \ |
58 | hif_usb.o \ | 59 | hif_usb.o \ |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 2dff2765769b..a0398fe3eb28 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -39,6 +39,10 @@ static const struct platform_device_id ath9k_platform_id_table[] = { | |||
39 | .name = "qca955x_wmac", | 39 | .name = "qca955x_wmac", |
40 | .driver_data = AR9300_DEVID_QCA955X, | 40 | .driver_data = AR9300_DEVID_QCA955X, |
41 | }, | 41 | }, |
42 | { | ||
43 | .name = "qca953x_wmac", | ||
44 | .driver_data = AR9300_DEVID_AR953X, | ||
45 | }, | ||
42 | {}, | 46 | {}, |
43 | }; | 47 | }; |
44 | 48 | ||
@@ -82,6 +86,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
82 | int irq; | 86 | int irq; |
83 | int ret = 0; | 87 | int ret = 0; |
84 | struct ath_hw *ah; | 88 | struct ath_hw *ah; |
89 | struct ath_common *common; | ||
85 | char hw_name[64]; | 90 | char hw_name[64]; |
86 | 91 | ||
87 | if (!dev_get_platdata(&pdev->dev)) { | 92 | if (!dev_get_platdata(&pdev->dev)) { |
@@ -124,9 +129,6 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
124 | sc->mem = mem; | 129 | sc->mem = mem; |
125 | sc->irq = irq; | 130 | sc->irq = irq; |
126 | 131 | ||
127 | /* Will be cleared in ath9k_start() */ | ||
128 | set_bit(SC_OP_INVALID, &sc->sc_flags); | ||
129 | |||
130 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 132 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
131 | if (ret) { | 133 | if (ret) { |
132 | dev_err(&pdev->dev, "request_irq failed\n"); | 134 | dev_err(&pdev->dev, "request_irq failed\n"); |
@@ -144,6 +146,9 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
144 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", | 146 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", |
145 | hw_name, (unsigned long)mem, irq); | 147 | hw_name, (unsigned long)mem, irq); |
146 | 148 | ||
149 | common = ath9k_hw_common(sc->sc_ah); | ||
150 | /* Will be cleared in ath9k_start() */ | ||
151 | set_bit(ATH_OP_INVALID, &common->op_flags); | ||
147 | return 0; | 152 | return 0; |
148 | 153 | ||
149 | err_irq: | 154 | err_irq: |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index d28923b7435b..6d47783f2e5b 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -176,16 +176,26 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, | |||
176 | if (ah->opmode == NL80211_IFTYPE_STATION && | 176 | if (ah->opmode == NL80211_IFTYPE_STATION && |
177 | BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH) | 177 | BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH) |
178 | weak_sig = true; | 178 | weak_sig = true; |
179 | |||
180 | /* | 179 | /* |
181 | * OFDM Weak signal detection is always enabled for AP mode. | 180 | * Newer chipsets are better at dealing with high PHY error counts - |
181 | * keep weak signal detection enabled when no RSSI threshold is | ||
182 | * available to determine if it is needed (mode != STA) | ||
182 | */ | 183 | */ |
183 | if (ah->opmode != NL80211_IFTYPE_AP && | 184 | else if (AR_SREV_9300_20_OR_LATER(ah) && |
184 | aniState->ofdmWeakSigDetect != weak_sig) { | 185 | ah->opmode != NL80211_IFTYPE_STATION) |
185 | ath9k_hw_ani_control(ah, | 186 | weak_sig = true; |
186 | ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | 187 | |
187 | entry_ofdm->ofdm_weak_signal_on); | 188 | /* Older chipsets are more sensitive to high PHY error counts */ |
188 | } | 189 | else if (!AR_SREV_9300_20_OR_LATER(ah) && |
190 | aniState->ofdmNoiseImmunityLevel >= 8) | ||
191 | weak_sig = false; | ||
192 | |||
193 | if (aniState->ofdmWeakSigDetect != weak_sig) | ||
194 | ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | ||
195 | weak_sig); | ||
196 | |||
197 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
198 | return; | ||
189 | 199 | ||
190 | if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) { | 200 | if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) { |
191 | ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; | 201 | ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; |
@@ -308,17 +318,6 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) | |||
308 | BUG_ON(aniState == NULL); | 318 | BUG_ON(aniState == NULL); |
309 | ah->stats.ast_ani_reset++; | 319 | ah->stats.ast_ani_reset++; |
310 | 320 | ||
311 | /* only allow a subset of functions in AP mode */ | ||
312 | if (ah->opmode == NL80211_IFTYPE_AP) { | ||
313 | if (IS_CHAN_2GHZ(chan)) { | ||
314 | ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | | ||
315 | ATH9K_ANI_FIRSTEP_LEVEL); | ||
316 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
317 | ah->ani_function |= ATH9K_ANI_MRC_CCK; | ||
318 | } else | ||
319 | ah->ani_function = 0; | ||
320 | } | ||
321 | |||
322 | ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL, | 321 | ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL, |
323 | aniState->ofdmNoiseImmunityLevel); | 322 | aniState->ofdmNoiseImmunityLevel); |
324 | cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL, | 323 | cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL, |
@@ -483,10 +482,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah) | |||
483 | 482 | ||
484 | ath_dbg(common, ANI, "Initialize ANI\n"); | 483 | ath_dbg(common, ANI, "Initialize ANI\n"); |
485 | 484 | ||
486 | ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; | 485 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
487 | ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; | 486 | ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; |
488 | ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; | 487 | ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; |
489 | ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; | 488 | ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; |
489 | ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; | ||
490 | } else { | ||
491 | ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; | ||
492 | ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD; | ||
493 | ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD; | ||
494 | ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD; | ||
495 | } | ||
490 | 496 | ||
491 | ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; | 497 | ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; |
492 | ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; | 498 | ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; |
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 21e7b83c3f6a..c40965b4c1e2 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h | |||
@@ -22,12 +22,16 @@ | |||
22 | /* units are errors per second */ | 22 | /* units are errors per second */ |
23 | #define ATH9K_ANI_OFDM_TRIG_HIGH 3500 | 23 | #define ATH9K_ANI_OFDM_TRIG_HIGH 3500 |
24 | #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000 | 24 | #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000 |
25 | #define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500 | ||
25 | 26 | ||
26 | #define ATH9K_ANI_OFDM_TRIG_LOW 400 | 27 | #define ATH9K_ANI_OFDM_TRIG_LOW 400 |
27 | #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900 | 28 | #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900 |
29 | #define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200 | ||
28 | 30 | ||
29 | #define ATH9K_ANI_CCK_TRIG_HIGH 600 | 31 | #define ATH9K_ANI_CCK_TRIG_HIGH 600 |
32 | #define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200 | ||
30 | #define ATH9K_ANI_CCK_TRIG_LOW 300 | 33 | #define ATH9K_ANI_CCK_TRIG_LOW 300 |
34 | #define ATH9K_ANI_CCK_TRIG_LOW_OLD 100 | ||
31 | 35 | ||
32 | #define ATH9K_ANI_SPUR_IMMUNE_LVL 3 | 36 | #define ATH9K_ANI_SPUR_IMMUNE_LVL 3 |
33 | #define ATH9K_ANI_FIRSTEP_LVL 2 | 37 | #define ATH9K_ANI_FIRSTEP_LVL 2 |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index ff415e863ee9..3b3e91057a4c 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -26,10 +26,6 @@ static const int firstep_table[] = | |||
26 | /* level: 0 1 2 3 4 5 6 7 8 */ | 26 | /* level: 0 1 2 3 4 5 6 7 8 */ |
27 | { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ | 27 | { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ |
28 | 28 | ||
29 | static const int cycpwrThr1_table[] = | ||
30 | /* level: 0 1 2 3 4 5 6 7 8 */ | ||
31 | { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ | ||
32 | |||
33 | /* | 29 | /* |
34 | * register values to turn OFDM weak signal detection OFF | 30 | * register values to turn OFDM weak signal detection OFF |
35 | */ | 31 | */ |
@@ -921,7 +917,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
921 | struct ath_common *common = ath9k_hw_common(ah); | 917 | struct ath_common *common = ath9k_hw_common(ah); |
922 | struct ath9k_channel *chan = ah->curchan; | 918 | struct ath9k_channel *chan = ah->curchan; |
923 | struct ar5416AniState *aniState = &ah->ani; | 919 | struct ar5416AniState *aniState = &ah->ani; |
924 | s32 value, value2; | 920 | s32 value; |
925 | 921 | ||
926 | switch (cmd & ah->ani_function) { | 922 | switch (cmd & ah->ani_function) { |
927 | case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ | 923 | case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ |
@@ -1008,42 +1004,11 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1008 | case ATH9K_ANI_FIRSTEP_LEVEL:{ | 1004 | case ATH9K_ANI_FIRSTEP_LEVEL:{ |
1009 | u32 level = param; | 1005 | u32 level = param; |
1010 | 1006 | ||
1011 | if (level >= ARRAY_SIZE(firstep_table)) { | 1007 | value = level * 2; |
1012 | ath_dbg(common, ANI, | ||
1013 | "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n", | ||
1014 | level, ARRAY_SIZE(firstep_table)); | ||
1015 | return false; | ||
1016 | } | ||
1017 | |||
1018 | /* | ||
1019 | * make register setting relative to default | ||
1020 | * from INI file & cap value | ||
1021 | */ | ||
1022 | value = firstep_table[level] - | ||
1023 | firstep_table[ATH9K_ANI_FIRSTEP_LVL] + | ||
1024 | aniState->iniDef.firstep; | ||
1025 | if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) | ||
1026 | value = ATH9K_SIG_FIRSTEP_SETTING_MIN; | ||
1027 | if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX) | ||
1028 | value = ATH9K_SIG_FIRSTEP_SETTING_MAX; | ||
1029 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | 1008 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, |
1030 | AR_PHY_FIND_SIG_FIRSTEP, | 1009 | AR_PHY_FIND_SIG_FIRSTEP, value); |
1031 | value); | ||
1032 | /* | ||
1033 | * we need to set first step low register too | ||
1034 | * make register setting relative to default | ||
1035 | * from INI file & cap value | ||
1036 | */ | ||
1037 | value2 = firstep_table[level] - | ||
1038 | firstep_table[ATH9K_ANI_FIRSTEP_LVL] + | ||
1039 | aniState->iniDef.firstepLow; | ||
1040 | if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) | ||
1041 | value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; | ||
1042 | if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX) | ||
1043 | value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX; | ||
1044 | |||
1045 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, | 1010 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, |
1046 | AR_PHY_FIND_SIG_FIRSTEP_LOW, value2); | 1011 | AR_PHY_FIND_SIG_FIRSTEP_LOW, value); |
1047 | 1012 | ||
1048 | if (level != aniState->firstepLevel) { | 1013 | if (level != aniState->firstepLevel) { |
1049 | ath_dbg(common, ANI, | 1014 | ath_dbg(common, ANI, |
@@ -1060,7 +1025,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1060 | aniState->firstepLevel, | 1025 | aniState->firstepLevel, |
1061 | level, | 1026 | level, |
1062 | ATH9K_ANI_FIRSTEP_LVL, | 1027 | ATH9K_ANI_FIRSTEP_LVL, |
1063 | value2, | 1028 | value, |
1064 | aniState->iniDef.firstepLow); | 1029 | aniState->iniDef.firstepLow); |
1065 | if (level > aniState->firstepLevel) | 1030 | if (level > aniState->firstepLevel) |
1066 | ah->stats.ast_ani_stepup++; | 1031 | ah->stats.ast_ani_stepup++; |
@@ -1073,41 +1038,13 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1073 | case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ | 1038 | case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ |
1074 | u32 level = param; | 1039 | u32 level = param; |
1075 | 1040 | ||
1076 | if (level >= ARRAY_SIZE(cycpwrThr1_table)) { | 1041 | value = (level + 1) * 2; |
1077 | ath_dbg(common, ANI, | ||
1078 | "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n", | ||
1079 | level, ARRAY_SIZE(cycpwrThr1_table)); | ||
1080 | return false; | ||
1081 | } | ||
1082 | /* | ||
1083 | * make register setting relative to default | ||
1084 | * from INI file & cap value | ||
1085 | */ | ||
1086 | value = cycpwrThr1_table[level] - | ||
1087 | cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + | ||
1088 | aniState->iniDef.cycpwrThr1; | ||
1089 | if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) | ||
1090 | value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; | ||
1091 | if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX) | ||
1092 | value = ATH9K_SIG_SPUR_IMM_SETTING_MAX; | ||
1093 | REG_RMW_FIELD(ah, AR_PHY_TIMING5, | 1042 | REG_RMW_FIELD(ah, AR_PHY_TIMING5, |
1094 | AR_PHY_TIMING5_CYCPWR_THR1, | 1043 | AR_PHY_TIMING5_CYCPWR_THR1, value); |
1095 | value); | ||
1096 | 1044 | ||
1097 | /* | 1045 | if (IS_CHAN_HT40(ah->curchan)) |
1098 | * set AR_PHY_EXT_CCA for extension channel | 1046 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, |
1099 | * make register setting relative to default | 1047 | AR_PHY_EXT_TIMING5_CYCPWR_THR1, value); |
1100 | * from INI file & cap value | ||
1101 | */ | ||
1102 | value2 = cycpwrThr1_table[level] - | ||
1103 | cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + | ||
1104 | aniState->iniDef.cycpwrThr1Ext; | ||
1105 | if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) | ||
1106 | value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; | ||
1107 | if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX) | ||
1108 | value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX; | ||
1109 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, | ||
1110 | AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2); | ||
1111 | 1048 | ||
1112 | if (level != aniState->spurImmunityLevel) { | 1049 | if (level != aniState->spurImmunityLevel) { |
1113 | ath_dbg(common, ANI, | 1050 | ath_dbg(common, ANI, |
@@ -1124,7 +1061,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1124 | aniState->spurImmunityLevel, | 1061 | aniState->spurImmunityLevel, |
1125 | level, | 1062 | level, |
1126 | ATH9K_ANI_SPUR_IMMUNE_LVL, | 1063 | ATH9K_ANI_SPUR_IMMUNE_LVL, |
1127 | value2, | 1064 | value, |
1128 | aniState->iniDef.cycpwrThr1Ext); | 1065 | aniState->iniDef.cycpwrThr1Ext); |
1129 | if (level > aniState->spurImmunityLevel) | 1066 | if (level > aniState->spurImmunityLevel) |
1130 | ah->stats.ast_ani_spurup++; | 1067 | ah->stats.ast_ani_spurup++; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index a352128c40ad..ac8301ef5242 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -23,10 +23,11 @@ | |||
23 | #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT | 23 | #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT |
24 | #define MAX_MAG_DELTA 11 | 24 | #define MAX_MAG_DELTA 11 |
25 | #define MAX_PHS_DELTA 10 | 25 | #define MAX_PHS_DELTA 10 |
26 | #define MAXIQCAL 3 | ||
26 | 27 | ||
27 | struct coeff { | 28 | struct coeff { |
28 | int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; | 29 | int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; |
29 | int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; | 30 | int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; |
30 | int iqc_coeff[2]; | 31 | int iqc_coeff[2]; |
31 | }; | 32 | }; |
32 | 33 | ||
@@ -655,9 +656,6 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
655 | if (i2_m_q2_a0_d1 > 0x800) | 656 | if (i2_m_q2_a0_d1 > 0x800) |
656 | i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); | 657 | i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); |
657 | 658 | ||
658 | if (i2_p_q2_a0_d1 > 0x1000) | ||
659 | i2_p_q2_a0_d1 = -((0x1fff - i2_p_q2_a0_d1) + 1); | ||
660 | |||
661 | if (iq_corr_a0_d1 > 0x800) | 659 | if (iq_corr_a0_d1 > 0x800) |
662 | iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); | 660 | iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); |
663 | 661 | ||
@@ -800,7 +798,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
800 | if (q_q_coff > 63) | 798 | if (q_q_coff > 63) |
801 | q_q_coff = 63; | 799 | q_q_coff = 63; |
802 | 800 | ||
803 | iqc_coeff[0] = (q_q_coff * 128) + q_i_coff; | 801 | iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff); |
804 | 802 | ||
805 | ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n", | 803 | ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n", |
806 | chain_idx, iqc_coeff[0]); | 804 | chain_idx, iqc_coeff[0]); |
@@ -831,7 +829,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
831 | if (q_q_coff > 63) | 829 | if (q_q_coff > 63) |
832 | q_q_coff = 63; | 830 | q_q_coff = 63; |
833 | 831 | ||
834 | iqc_coeff[1] = (q_q_coff * 128) + q_i_coff; | 832 | iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff); |
835 | 833 | ||
836 | ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n", | 834 | ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n", |
837 | chain_idx, iqc_coeff[1]); | 835 | chain_idx, iqc_coeff[1]); |
@@ -839,7 +837,8 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
839 | return true; | 837 | return true; |
840 | } | 838 | } |
841 | 839 | ||
842 | static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, | 840 | static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL], |
841 | int nmeasurement, | ||
843 | int max_delta) | 842 | int max_delta) |
844 | { | 843 | { |
845 | int mp_max = -64, max_idx = 0; | 844 | int mp_max = -64, max_idx = 0; |
@@ -848,20 +847,20 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, | |||
848 | 847 | ||
849 | /* find min/max mismatch across all calibrated gains */ | 848 | /* find min/max mismatch across all calibrated gains */ |
850 | for (i = 0; i < nmeasurement; i++) { | 849 | for (i = 0; i < nmeasurement; i++) { |
851 | if (mp_coeff[i] > mp_max) { | 850 | if (mp_coeff[i][0] > mp_max) { |
852 | mp_max = mp_coeff[i]; | 851 | mp_max = mp_coeff[i][0]; |
853 | max_idx = i; | 852 | max_idx = i; |
854 | } else if (mp_coeff[i] < mp_min) { | 853 | } else if (mp_coeff[i][0] < mp_min) { |
855 | mp_min = mp_coeff[i]; | 854 | mp_min = mp_coeff[i][0]; |
856 | min_idx = i; | 855 | min_idx = i; |
857 | } | 856 | } |
858 | } | 857 | } |
859 | 858 | ||
860 | /* find average (exclude max abs value) */ | 859 | /* find average (exclude max abs value) */ |
861 | for (i = 0; i < nmeasurement; i++) { | 860 | for (i = 0; i < nmeasurement; i++) { |
862 | if ((abs(mp_coeff[i]) < abs(mp_max)) || | 861 | if ((abs(mp_coeff[i][0]) < abs(mp_max)) || |
863 | (abs(mp_coeff[i]) < abs(mp_min))) { | 862 | (abs(mp_coeff[i][0]) < abs(mp_min))) { |
864 | mp_avg += mp_coeff[i]; | 863 | mp_avg += mp_coeff[i][0]; |
865 | mp_count++; | 864 | mp_count++; |
866 | } | 865 | } |
867 | } | 866 | } |
@@ -873,7 +872,7 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, | |||
873 | if (mp_count) | 872 | if (mp_count) |
874 | mp_avg /= mp_count; | 873 | mp_avg /= mp_count; |
875 | else | 874 | else |
876 | mp_avg = mp_coeff[nmeasurement - 1]; | 875 | mp_avg = mp_coeff[nmeasurement - 1][0]; |
877 | 876 | ||
878 | /* detect outlier */ | 877 | /* detect outlier */ |
879 | if (abs(mp_max - mp_min) > max_delta) { | 878 | if (abs(mp_max - mp_min) > max_delta) { |
@@ -882,15 +881,16 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, | |||
882 | else | 881 | else |
883 | outlier_idx = min_idx; | 882 | outlier_idx = min_idx; |
884 | 883 | ||
885 | mp_coeff[outlier_idx] = mp_avg; | 884 | mp_coeff[outlier_idx][0] = mp_avg; |
886 | } | 885 | } |
887 | } | 886 | } |
888 | 887 | ||
889 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | 888 | static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah, |
890 | struct coeff *coeff, | 889 | struct coeff *coeff, |
891 | bool is_reusable) | 890 | bool is_reusable) |
892 | { | 891 | { |
893 | int i, im, nmeasurement; | 892 | int i, im, nmeasurement; |
893 | int magnitude, phase; | ||
894 | u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; | 894 | u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; |
895 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 895 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
896 | 896 | ||
@@ -920,21 +920,30 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
920 | if (nmeasurement > MAX_MEASUREMENT) | 920 | if (nmeasurement > MAX_MEASUREMENT) |
921 | nmeasurement = MAX_MEASUREMENT; | 921 | nmeasurement = MAX_MEASUREMENT; |
922 | 922 | ||
923 | /* detect outlier only if nmeasurement > 1 */ | 923 | /* |
924 | if (nmeasurement > 1) { | 924 | * Skip normal outlier detection for AR9550. |
925 | /* Detect magnitude outlier */ | 925 | */ |
926 | ar9003_hw_detect_outlier(coeff->mag_coeff[i], | 926 | if (!AR_SREV_9550(ah)) { |
927 | nmeasurement, MAX_MAG_DELTA); | 927 | /* detect outlier only if nmeasurement > 1 */ |
928 | 928 | if (nmeasurement > 1) { | |
929 | /* Detect phase outlier */ | 929 | /* Detect magnitude outlier */ |
930 | ar9003_hw_detect_outlier(coeff->phs_coeff[i], | 930 | ar9003_hw_detect_outlier(coeff->mag_coeff[i], |
931 | nmeasurement, MAX_PHS_DELTA); | 931 | nmeasurement, |
932 | MAX_MAG_DELTA); | ||
933 | |||
934 | /* Detect phase outlier */ | ||
935 | ar9003_hw_detect_outlier(coeff->phs_coeff[i], | ||
936 | nmeasurement, | ||
937 | MAX_PHS_DELTA); | ||
938 | } | ||
932 | } | 939 | } |
933 | 940 | ||
934 | for (im = 0; im < nmeasurement; im++) { | 941 | for (im = 0; im < nmeasurement; im++) { |
942 | magnitude = coeff->mag_coeff[i][im][0]; | ||
943 | phase = coeff->phs_coeff[i][im][0]; | ||
935 | 944 | ||
936 | coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) | | 945 | coeff->iqc_coeff[0] = |
937 | ((coeff->phs_coeff[i][im] & 0x7f) << 7); | 946 | (phase & 0x7f) | ((magnitude & 0x7f) << 7); |
938 | 947 | ||
939 | if ((im % 2) == 0) | 948 | if ((im % 2) == 0) |
940 | REG_RMW_FIELD(ah, tx_corr_coeff[im][i], | 949 | REG_RMW_FIELD(ah, tx_corr_coeff[im][i], |
@@ -991,7 +1000,63 @@ static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) | |||
991 | return true; | 1000 | return true; |
992 | } | 1001 | } |
993 | 1002 | ||
994 | static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | 1003 | static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah, |
1004 | struct coeff *coeff, | ||
1005 | int i, int nmeasurement) | ||
1006 | { | ||
1007 | struct ath_common *common = ath9k_hw_common(ah); | ||
1008 | int im, ix, iy, temp; | ||
1009 | |||
1010 | for (im = 0; im < nmeasurement; im++) { | ||
1011 | for (ix = 0; ix < MAXIQCAL - 1; ix++) { | ||
1012 | for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) { | ||
1013 | if (coeff->mag_coeff[i][im][iy] < | ||
1014 | coeff->mag_coeff[i][im][ix]) { | ||
1015 | temp = coeff->mag_coeff[i][im][ix]; | ||
1016 | coeff->mag_coeff[i][im][ix] = | ||
1017 | coeff->mag_coeff[i][im][iy]; | ||
1018 | coeff->mag_coeff[i][im][iy] = temp; | ||
1019 | } | ||
1020 | if (coeff->phs_coeff[i][im][iy] < | ||
1021 | coeff->phs_coeff[i][im][ix]) { | ||
1022 | temp = coeff->phs_coeff[i][im][ix]; | ||
1023 | coeff->phs_coeff[i][im][ix] = | ||
1024 | coeff->phs_coeff[i][im][iy]; | ||
1025 | coeff->phs_coeff[i][im][iy] = temp; | ||
1026 | } | ||
1027 | } | ||
1028 | } | ||
1029 | coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2]; | ||
1030 | coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2]; | ||
1031 | |||
1032 | ath_dbg(common, CALIBRATE, | ||
1033 | "IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n", | ||
1034 | i, im, | ||
1035 | coeff->mag_coeff[i][im][0], | ||
1036 | coeff->phs_coeff[i][im][0]); | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | static bool ar955x_tx_iq_cal_median(struct ath_hw *ah, | ||
1041 | struct coeff *coeff, | ||
1042 | int iqcal_idx, | ||
1043 | int nmeasurement) | ||
1044 | { | ||
1045 | int i; | ||
1046 | |||
1047 | if ((iqcal_idx + 1) != MAXIQCAL) | ||
1048 | return false; | ||
1049 | |||
1050 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
1051 | __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement); | ||
1052 | } | ||
1053 | |||
1054 | return true; | ||
1055 | } | ||
1056 | |||
1057 | static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, | ||
1058 | int iqcal_idx, | ||
1059 | bool is_reusable) | ||
995 | { | 1060 | { |
996 | struct ath_common *common = ath9k_hw_common(ah); | 1061 | struct ath_common *common = ath9k_hw_common(ah); |
997 | const u32 txiqcal_status[AR9300_MAX_CHAINS] = { | 1062 | const u32 txiqcal_status[AR9300_MAX_CHAINS] = { |
@@ -1004,10 +1069,11 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
1004 | AR_PHY_CHAN_INFO_TAB_1, | 1069 | AR_PHY_CHAN_INFO_TAB_1, |
1005 | AR_PHY_CHAN_INFO_TAB_2, | 1070 | AR_PHY_CHAN_INFO_TAB_2, |
1006 | }; | 1071 | }; |
1007 | struct coeff coeff; | 1072 | static struct coeff coeff; |
1008 | s32 iq_res[6]; | 1073 | s32 iq_res[6]; |
1009 | int i, im, j; | 1074 | int i, im, j; |
1010 | int nmeasurement; | 1075 | int nmeasurement = 0; |
1076 | bool outlier_detect = true; | ||
1011 | 1077 | ||
1012 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 1078 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
1013 | if (!(ah->txchainmask & (1 << i))) | 1079 | if (!(ah->txchainmask & (1 << i))) |
@@ -1065,17 +1131,23 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
1065 | goto tx_iqcal_fail; | 1131 | goto tx_iqcal_fail; |
1066 | } | 1132 | } |
1067 | 1133 | ||
1068 | coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f; | 1134 | coeff.phs_coeff[i][im][iqcal_idx] = |
1069 | coeff.phs_coeff[i][im] = | 1135 | coeff.iqc_coeff[0] & 0x7f; |
1136 | coeff.mag_coeff[i][im][iqcal_idx] = | ||
1070 | (coeff.iqc_coeff[0] >> 7) & 0x7f; | 1137 | (coeff.iqc_coeff[0] >> 7) & 0x7f; |
1071 | 1138 | ||
1072 | if (coeff.mag_coeff[i][im] > 63) | 1139 | if (coeff.mag_coeff[i][im][iqcal_idx] > 63) |
1073 | coeff.mag_coeff[i][im] -= 128; | 1140 | coeff.mag_coeff[i][im][iqcal_idx] -= 128; |
1074 | if (coeff.phs_coeff[i][im] > 63) | 1141 | if (coeff.phs_coeff[i][im][iqcal_idx] > 63) |
1075 | coeff.phs_coeff[i][im] -= 128; | 1142 | coeff.phs_coeff[i][im][iqcal_idx] -= 128; |
1076 | } | 1143 | } |
1077 | } | 1144 | } |
1078 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable); | 1145 | |
1146 | if (AR_SREV_9550(ah)) | ||
1147 | outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff, | ||
1148 | iqcal_idx, nmeasurement); | ||
1149 | if (outlier_detect) | ||
1150 | ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable); | ||
1079 | 1151 | ||
1080 | return; | 1152 | return; |
1081 | 1153 | ||
@@ -1409,7 +1481,7 @@ skip_tx_iqcal: | |||
1409 | } | 1481 | } |
1410 | 1482 | ||
1411 | if (txiqcal_done) | 1483 | if (txiqcal_done) |
1412 | ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); | 1484 | ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable); |
1413 | else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) | 1485 | else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) |
1414 | ar9003_hw_tx_iq_cal_reload(ah); | 1486 | ar9003_hw_tx_iq_cal_reload(ah); |
1415 | 1487 | ||
@@ -1455,14 +1527,38 @@ skip_tx_iqcal: | |||
1455 | return true; | 1527 | return true; |
1456 | } | 1528 | } |
1457 | 1529 | ||
1530 | static bool do_ar9003_agc_cal(struct ath_hw *ah) | ||
1531 | { | ||
1532 | struct ath_common *common = ath9k_hw_common(ah); | ||
1533 | bool status; | ||
1534 | |||
1535 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
1536 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
1537 | AR_PHY_AGC_CONTROL_CAL); | ||
1538 | |||
1539 | status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | ||
1540 | AR_PHY_AGC_CONTROL_CAL, | ||
1541 | 0, AH_WAIT_TIMEOUT); | ||
1542 | if (!status) { | ||
1543 | ath_dbg(common, CALIBRATE, | ||
1544 | "offset calibration failed to complete in %d ms," | ||
1545 | "noisy environment?\n", | ||
1546 | AH_WAIT_TIMEOUT / 1000); | ||
1547 | return false; | ||
1548 | } | ||
1549 | |||
1550 | return true; | ||
1551 | } | ||
1552 | |||
1458 | static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, | 1553 | static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, |
1459 | struct ath9k_channel *chan) | 1554 | struct ath9k_channel *chan) |
1460 | { | 1555 | { |
1461 | struct ath_common *common = ath9k_hw_common(ah); | 1556 | struct ath_common *common = ath9k_hw_common(ah); |
1462 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 1557 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
1463 | bool txiqcal_done = false; | 1558 | bool txiqcal_done = false; |
1464 | bool is_reusable = true, status = true; | 1559 | bool status = true; |
1465 | bool run_agc_cal = false, sep_iq_cal = false; | 1560 | bool run_agc_cal = false, sep_iq_cal = false; |
1561 | int i = 0; | ||
1466 | 1562 | ||
1467 | /* Use chip chainmask only for calibration */ | 1563 | /* Use chip chainmask only for calibration */ |
1468 | ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); | 1564 | ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); |
@@ -1485,7 +1581,12 @@ static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, | |||
1485 | * AGC calibration. Specifically, AR9550 in SoC chips. | 1581 | * AGC calibration. Specifically, AR9550 in SoC chips. |
1486 | */ | 1582 | */ |
1487 | if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { | 1583 | if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { |
1488 | txiqcal_done = true; | 1584 | if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, |
1585 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) { | ||
1586 | txiqcal_done = true; | ||
1587 | } else { | ||
1588 | txiqcal_done = false; | ||
1589 | } | ||
1489 | run_agc_cal = true; | 1590 | run_agc_cal = true; |
1490 | } else { | 1591 | } else { |
1491 | sep_iq_cal = true; | 1592 | sep_iq_cal = true; |
@@ -1512,27 +1613,37 @@ skip_tx_iqcal: | |||
1512 | if (AR_SREV_9330_11(ah)) | 1613 | if (AR_SREV_9330_11(ah)) |
1513 | ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan)); | 1614 | ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan)); |
1514 | 1615 | ||
1515 | /* Calibrate the AGC */ | 1616 | /* |
1516 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | 1617 | * For non-AR9550 chips, we just trigger AGC calibration |
1517 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | 1618 | * in the HW, poll for completion and then process |
1518 | AR_PHY_AGC_CONTROL_CAL); | 1619 | * the results. |
1519 | 1620 | * | |
1520 | /* Poll for offset calibration complete */ | 1621 | * For AR955x, we run it multiple times and use |
1521 | status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | 1622 | * median IQ correction. |
1522 | AR_PHY_AGC_CONTROL_CAL, | 1623 | */ |
1523 | 0, AH_WAIT_TIMEOUT); | 1624 | if (!AR_SREV_9550(ah)) { |
1524 | } | 1625 | status = do_ar9003_agc_cal(ah); |
1626 | if (!status) | ||
1627 | return false; | ||
1525 | 1628 | ||
1526 | if (!status) { | 1629 | if (txiqcal_done) |
1527 | ath_dbg(common, CALIBRATE, | 1630 | ar9003_hw_tx_iq_cal_post_proc(ah, 0, false); |
1528 | "offset calibration failed to complete in %d ms; noisy environment?\n", | 1631 | } else { |
1529 | AH_WAIT_TIMEOUT / 1000); | 1632 | if (!txiqcal_done) { |
1530 | return false; | 1633 | status = do_ar9003_agc_cal(ah); |
1634 | if (!status) | ||
1635 | return false; | ||
1636 | } else { | ||
1637 | for (i = 0; i < MAXIQCAL; i++) { | ||
1638 | status = do_ar9003_agc_cal(ah); | ||
1639 | if (!status) | ||
1640 | return false; | ||
1641 | ar9003_hw_tx_iq_cal_post_proc(ah, i, false); | ||
1642 | } | ||
1643 | } | ||
1644 | } | ||
1531 | } | 1645 | } |
1532 | 1646 | ||
1533 | if (txiqcal_done) | ||
1534 | ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); | ||
1535 | |||
1536 | /* Revert chainmask to runtime parameters */ | 1647 | /* Revert chainmask to runtime parameters */ |
1537 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | 1648 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
1538 | 1649 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index b8daff78b9d1..235053ba7737 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -23,8 +23,8 @@ | |||
23 | #define COMP_HDR_LEN 4 | 23 | #define COMP_HDR_LEN 4 |
24 | #define COMP_CKSUM_LEN 2 | 24 | #define COMP_CKSUM_LEN 2 |
25 | 25 | ||
26 | #define LE16(x) __constant_cpu_to_le16(x) | 26 | #define LE16(x) cpu_to_le16(x) |
27 | #define LE32(x) __constant_cpu_to_le32(x) | 27 | #define LE32(x) cpu_to_le32(x) |
28 | 28 | ||
29 | /* Local defines to distinguish between extension and control CTL's */ | 29 | /* Local defines to distinguish between extension and control CTL's */ |
30 | #define EXT_ADDITIVE (0x8000) | 30 | #define EXT_ADDITIVE (0x8000) |
@@ -4792,43 +4792,54 @@ static void ar9003_hw_power_control_override(struct ath_hw *ah, | |||
4792 | 4792 | ||
4793 | tempslope: | 4793 | tempslope: |
4794 | if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { | 4794 | if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { |
4795 | u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4; | ||
4796 | |||
4795 | /* | 4797 | /* |
4796 | * AR955x has tempSlope register for each chain. | 4798 | * AR955x has tempSlope register for each chain. |
4797 | * Check whether temp_compensation feature is enabled or not. | 4799 | * Check whether temp_compensation feature is enabled or not. |
4798 | */ | 4800 | */ |
4799 | if (eep->baseEepHeader.featureEnable & 0x1) { | 4801 | if (eep->baseEepHeader.featureEnable & 0x1) { |
4800 | if (frequency < 4000) { | 4802 | if (frequency < 4000) { |
4801 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, | 4803 | if (txmask & BIT(0)) |
4802 | AR_PHY_TPC_19_ALPHA_THERM, | 4804 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, |
4803 | eep->base_ext2.tempSlopeLow); | 4805 | AR_PHY_TPC_19_ALPHA_THERM, |
4804 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, | 4806 | eep->base_ext2.tempSlopeLow); |
4805 | AR_PHY_TPC_19_ALPHA_THERM, | 4807 | if (txmask & BIT(1)) |
4806 | temp_slope); | 4808 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, |
4807 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | 4809 | AR_PHY_TPC_19_ALPHA_THERM, |
4808 | AR_PHY_TPC_19_ALPHA_THERM, | 4810 | temp_slope); |
4809 | eep->base_ext2.tempSlopeHigh); | 4811 | if (txmask & BIT(2)) |
4812 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | ||
4813 | AR_PHY_TPC_19_ALPHA_THERM, | ||
4814 | eep->base_ext2.tempSlopeHigh); | ||
4810 | } else { | 4815 | } else { |
4811 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, | 4816 | if (txmask & BIT(0)) |
4812 | AR_PHY_TPC_19_ALPHA_THERM, | 4817 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, |
4813 | temp_slope); | 4818 | AR_PHY_TPC_19_ALPHA_THERM, |
4814 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, | 4819 | temp_slope); |
4815 | AR_PHY_TPC_19_ALPHA_THERM, | 4820 | if (txmask & BIT(1)) |
4816 | temp_slope1); | 4821 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, |
4817 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | 4822 | AR_PHY_TPC_19_ALPHA_THERM, |
4818 | AR_PHY_TPC_19_ALPHA_THERM, | 4823 | temp_slope1); |
4819 | temp_slope2); | 4824 | if (txmask & BIT(2)) |
4825 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | ||
4826 | AR_PHY_TPC_19_ALPHA_THERM, | ||
4827 | temp_slope2); | ||
4820 | } | 4828 | } |
4821 | } else { | 4829 | } else { |
4822 | /* | 4830 | /* |
4823 | * If temp compensation is not enabled, | 4831 | * If temp compensation is not enabled, |
4824 | * set all registers to 0. | 4832 | * set all registers to 0. |
4825 | */ | 4833 | */ |
4826 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, | 4834 | if (txmask & BIT(0)) |
4827 | AR_PHY_TPC_19_ALPHA_THERM, 0); | 4835 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, |
4828 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, | 4836 | AR_PHY_TPC_19_ALPHA_THERM, 0); |
4829 | AR_PHY_TPC_19_ALPHA_THERM, 0); | 4837 | if (txmask & BIT(1)) |
4830 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | 4838 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, |
4831 | AR_PHY_TPC_19_ALPHA_THERM, 0); | 4839 | AR_PHY_TPC_19_ALPHA_THERM, 0); |
4840 | if (txmask & BIT(2)) | ||
4841 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | ||
4842 | AR_PHY_TPC_19_ALPHA_THERM, 0); | ||
4832 | } | 4843 | } |
4833 | } else { | 4844 | } else { |
4834 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, | 4845 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 09facba1dc6d..8927fc34d84c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -868,10 +868,6 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah, | |||
868 | 868 | ||
869 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | 869 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
870 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); | 870 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); |
871 | if (IS_CHAN_QUARTER_RATE(chan)) | ||
872 | rfMode |= AR_PHY_MODE_QUARTER; | ||
873 | if (IS_CHAN_HALF_RATE(chan)) | ||
874 | rfMode |= AR_PHY_MODE_HALF; | ||
875 | 871 | ||
876 | if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF)) | 872 | if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF)) |
877 | REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, | 873 | REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b5ac32cfbeb8..44d74495c4de 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -30,7 +30,6 @@ | |||
30 | #include "spectral.h" | 30 | #include "spectral.h" |
31 | 31 | ||
32 | struct ath_node; | 32 | struct ath_node; |
33 | struct ath_rate_table; | ||
34 | 33 | ||
35 | extern struct ieee80211_ops ath9k_ops; | 34 | extern struct ieee80211_ops ath9k_ops; |
36 | extern int ath9k_modparam_nohwcrypt; | 35 | extern int ath9k_modparam_nohwcrypt; |
@@ -150,6 +149,11 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
150 | #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) | 149 | #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) |
151 | #define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf)) | 150 | #define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf)) |
152 | 151 | ||
152 | enum { | ||
153 | WLAN_RC_PHY_OFDM, | ||
154 | WLAN_RC_PHY_CCK, | ||
155 | }; | ||
156 | |||
153 | struct ath_txq { | 157 | struct ath_txq { |
154 | int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ | 158 | int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ |
155 | u32 axq_qnum; /* ath9k hardware queue number */ | 159 | u32 axq_qnum; /* ath9k hardware queue number */ |
@@ -399,21 +403,10 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
399 | #define ATH_BCBUF 8 | 403 | #define ATH_BCBUF 8 |
400 | #define ATH_DEFAULT_BINTVAL 100 /* TU */ | 404 | #define ATH_DEFAULT_BINTVAL 100 /* TU */ |
401 | #define ATH_DEFAULT_BMISS_LIMIT 10 | 405 | #define ATH_DEFAULT_BMISS_LIMIT 10 |
402 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | ||
403 | 406 | ||
404 | #define TSF_TO_TU(_h,_l) \ | 407 | #define TSF_TO_TU(_h,_l) \ |
405 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) | 408 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) |
406 | 409 | ||
407 | struct ath_beacon_config { | ||
408 | int beacon_interval; | ||
409 | u16 listen_interval; | ||
410 | u16 dtim_period; | ||
411 | u16 bmiss_timeout; | ||
412 | u8 dtim_count; | ||
413 | bool enable_beacon; | ||
414 | bool ibss_creator; | ||
415 | }; | ||
416 | |||
417 | struct ath_beacon { | 410 | struct ath_beacon { |
418 | enum { | 411 | enum { |
419 | OK, /* no change needed */ | 412 | OK, /* no change needed */ |
@@ -423,11 +416,9 @@ struct ath_beacon { | |||
423 | 416 | ||
424 | u32 beaconq; | 417 | u32 beaconq; |
425 | u32 bmisscnt; | 418 | u32 bmisscnt; |
426 | u32 bc_tstamp; | ||
427 | struct ieee80211_vif *bslot[ATH_BCBUF]; | 419 | struct ieee80211_vif *bslot[ATH_BCBUF]; |
428 | int slottime; | 420 | int slottime; |
429 | int slotupdate; | 421 | int slotupdate; |
430 | struct ath9k_tx_queue_info beacon_qi; | ||
431 | struct ath_descdma bdma; | 422 | struct ath_descdma bdma; |
432 | struct ath_txq *cabq; | 423 | struct ath_txq *cabq; |
433 | struct list_head bbuf; | 424 | struct list_head bbuf; |
@@ -442,7 +433,8 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
442 | void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); | 433 | void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); |
443 | void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); | 434 | void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); |
444 | void ath9k_set_beacon(struct ath_softc *sc); | 435 | void ath9k_set_beacon(struct ath_softc *sc); |
445 | bool ath9k_csa_is_finished(struct ath_softc *sc); | 436 | bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif); |
437 | void ath9k_csa_update(struct ath_softc *sc); | ||
446 | 438 | ||
447 | /*******************/ | 439 | /*******************/ |
448 | /* Link Monitoring */ | 440 | /* Link Monitoring */ |
@@ -693,15 +685,6 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); | |||
693 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | 685 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ |
694 | #define MAX_GTT_CNT 5 | 686 | #define MAX_GTT_CNT 5 |
695 | 687 | ||
696 | enum sc_op_flags { | ||
697 | SC_OP_INVALID, | ||
698 | SC_OP_BEACONS, | ||
699 | SC_OP_ANI_RUN, | ||
700 | SC_OP_PRIM_STA_VIF, | ||
701 | SC_OP_HW_RESET, | ||
702 | SC_OP_SCANNING, | ||
703 | }; | ||
704 | |||
705 | /* Powersave flags */ | 688 | /* Powersave flags */ |
706 | #define PS_WAIT_FOR_BEACON BIT(0) | 689 | #define PS_WAIT_FOR_BEACON BIT(0) |
707 | #define PS_WAIT_FOR_CAB BIT(1) | 690 | #define PS_WAIT_FOR_CAB BIT(1) |
@@ -731,7 +714,6 @@ struct ath_softc { | |||
731 | struct completion paprd_complete; | 714 | struct completion paprd_complete; |
732 | wait_queue_head_t tx_wait; | 715 | wait_queue_head_t tx_wait; |
733 | 716 | ||
734 | unsigned long sc_flags; | ||
735 | unsigned long driver_data; | 717 | unsigned long driver_data; |
736 | 718 | ||
737 | u8 gtt_cnt; | 719 | u8 gtt_cnt; |
@@ -748,7 +730,6 @@ struct ath_softc { | |||
748 | struct ath_rx rx; | 730 | struct ath_rx rx; |
749 | struct ath_tx tx; | 731 | struct ath_tx tx; |
750 | struct ath_beacon beacon; | 732 | struct ath_beacon beacon; |
751 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
752 | 733 | ||
753 | #ifdef CONFIG_MAC80211_LEDS | 734 | #ifdef CONFIG_MAC80211_LEDS |
754 | bool led_registered; | 735 | bool led_registered; |
@@ -757,7 +738,6 @@ struct ath_softc { | |||
757 | #endif | 738 | #endif |
758 | 739 | ||
759 | struct ath9k_hw_cal_data caldata; | 740 | struct ath9k_hw_cal_data caldata; |
760 | int last_rssi; | ||
761 | 741 | ||
762 | #ifdef CONFIG_ATH9K_DEBUGFS | 742 | #ifdef CONFIG_ATH9K_DEBUGFS |
763 | struct ath9k_debug debug; | 743 | struct ath9k_debug debug; |
@@ -774,7 +754,6 @@ struct ath_softc { | |||
774 | #endif | 754 | #endif |
775 | 755 | ||
776 | struct ath_descdma txsdma; | 756 | struct ath_descdma txsdma; |
777 | struct ieee80211_vif *csa_vif; | ||
778 | 757 | ||
779 | struct ath_ant_comb ant_comb; | 758 | struct ath_ant_comb ant_comb; |
780 | u8 ant_tx, ant_rx; | 759 | u8 ant_tx, ant_rx; |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 2e8bba0eb361..471e0f624e81 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -80,7 +80,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
80 | u8 chainmask = ah->txchainmask; | 80 | u8 chainmask = ah->txchainmask; |
81 | u8 rate = 0; | 81 | u8 rate = 0; |
82 | 82 | ||
83 | sband = &sc->sbands[common->hw->conf.chandef.chan->band]; | 83 | sband = &common->sbands[common->hw->conf.chandef.chan->band]; |
84 | rate = sband->bitrates[rateidx].hw_value; | 84 | rate = sband->bitrates[rateidx].hw_value; |
85 | if (vif->bss_conf.use_short_preamble) | 85 | if (vif->bss_conf.use_short_preamble) |
86 | rate |= sband->bitrates[rateidx].hw_value_short; | 86 | rate |= sband->bitrates[rateidx].hw_value_short; |
@@ -292,11 +292,8 @@ static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
292 | (unsigned long long)tsfadjust, avp->av_bslot); | 292 | (unsigned long long)tsfadjust, avp->av_bslot); |
293 | } | 293 | } |
294 | 294 | ||
295 | bool ath9k_csa_is_finished(struct ath_softc *sc) | 295 | bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif) |
296 | { | 296 | { |
297 | struct ieee80211_vif *vif; | ||
298 | |||
299 | vif = sc->csa_vif; | ||
300 | if (!vif || !vif->csa_active) | 297 | if (!vif || !vif->csa_active) |
301 | return false; | 298 | return false; |
302 | 299 | ||
@@ -304,11 +301,23 @@ bool ath9k_csa_is_finished(struct ath_softc *sc) | |||
304 | return false; | 301 | return false; |
305 | 302 | ||
306 | ieee80211_csa_finish(vif); | 303 | ieee80211_csa_finish(vif); |
307 | |||
308 | sc->csa_vif = NULL; | ||
309 | return true; | 304 | return true; |
310 | } | 305 | } |
311 | 306 | ||
307 | static void ath9k_csa_update_vif(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
308 | { | ||
309 | struct ath_softc *sc = data; | ||
310 | ath9k_csa_is_finished(sc, vif); | ||
311 | } | ||
312 | |||
313 | void ath9k_csa_update(struct ath_softc *sc) | ||
314 | { | ||
315 | ieee80211_iterate_active_interfaces(sc->hw, | ||
316 | IEEE80211_IFACE_ITER_NORMAL, | ||
317 | ath9k_csa_update_vif, | ||
318 | sc); | ||
319 | } | ||
320 | |||
312 | void ath9k_beacon_tasklet(unsigned long data) | 321 | void ath9k_beacon_tasklet(unsigned long data) |
313 | { | 322 | { |
314 | struct ath_softc *sc = (struct ath_softc *)data; | 323 | struct ath_softc *sc = (struct ath_softc *)data; |
@@ -319,7 +328,7 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
319 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | 328 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); |
320 | int slot; | 329 | int slot; |
321 | 330 | ||
322 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) { | 331 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) { |
323 | ath_dbg(common, RESET, | 332 | ath_dbg(common, RESET, |
324 | "reset work is pending, skip beaconing now\n"); | 333 | "reset work is pending, skip beaconing now\n"); |
325 | return; | 334 | return; |
@@ -362,13 +371,13 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
362 | return; | 371 | return; |
363 | } | 372 | } |
364 | 373 | ||
365 | /* EDMA devices check that in the tx completion function. */ | ||
366 | if (!edma && ath9k_csa_is_finished(sc)) | ||
367 | return; | ||
368 | |||
369 | slot = ath9k_beacon_choose_slot(sc); | 374 | slot = ath9k_beacon_choose_slot(sc); |
370 | vif = sc->beacon.bslot[slot]; | 375 | vif = sc->beacon.bslot[slot]; |
371 | 376 | ||
377 | /* EDMA devices check that in the tx completion function. */ | ||
378 | if (!edma && ath9k_csa_is_finished(sc, vif)) | ||
379 | return; | ||
380 | |||
372 | if (!vif || !vif->bss_conf.enable_beacon) | 381 | if (!vif || !vif->bss_conf.enable_beacon) |
373 | return; | 382 | return; |
374 | 383 | ||
@@ -438,33 +447,6 @@ static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, | |||
438 | ath9k_hw_enable_interrupts(ah); | 447 | ath9k_hw_enable_interrupts(ah); |
439 | } | 448 | } |
440 | 449 | ||
441 | /* Calculate the modulo of a 64 bit TSF snapshot with a TU divisor */ | ||
442 | static u32 ath9k_mod_tsf64_tu(u64 tsf, u32 div_tu) | ||
443 | { | ||
444 | u32 tsf_mod, tsf_hi, tsf_lo, mod_hi, mod_lo; | ||
445 | |||
446 | tsf_mod = tsf & (BIT(10) - 1); | ||
447 | tsf_hi = tsf >> 32; | ||
448 | tsf_lo = ((u32) tsf) >> 10; | ||
449 | |||
450 | mod_hi = tsf_hi % div_tu; | ||
451 | mod_lo = ((mod_hi << 22) + tsf_lo) % div_tu; | ||
452 | |||
453 | return (mod_lo << 10) | tsf_mod; | ||
454 | } | ||
455 | |||
456 | static u32 ath9k_get_next_tbtt(struct ath_softc *sc, u64 tsf, | ||
457 | unsigned int interval) | ||
458 | { | ||
459 | struct ath_hw *ah = sc->sc_ah; | ||
460 | unsigned int offset; | ||
461 | |||
462 | tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time); | ||
463 | offset = ath9k_mod_tsf64_tu(tsf, interval); | ||
464 | |||
465 | return (u32) tsf + TU_TO_USEC(interval) - offset; | ||
466 | } | ||
467 | |||
468 | /* | 450 | /* |
469 | * For multi-bss ap support beacons are either staggered evenly over N slots or | 451 | * For multi-bss ap support beacons are either staggered evenly over N slots or |
470 | * burst together. For the former arrange for the SWBA to be delivered for each | 452 | * burst together. For the former arrange for the SWBA to be delivered for each |
@@ -474,115 +456,18 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc, | |||
474 | struct ath_beacon_config *conf) | 456 | struct ath_beacon_config *conf) |
475 | { | 457 | { |
476 | struct ath_hw *ah = sc->sc_ah; | 458 | struct ath_hw *ah = sc->sc_ah; |
477 | struct ath_common *common = ath9k_hw_common(ah); | ||
478 | u32 nexttbtt, intval; | ||
479 | |||
480 | /* NB: the beacon interval is kept internally in TU's */ | ||
481 | intval = TU_TO_USEC(conf->beacon_interval); | ||
482 | intval /= ATH_BCBUF; | ||
483 | nexttbtt = ath9k_get_next_tbtt(sc, ath9k_hw_gettsf64(ah), | ||
484 | conf->beacon_interval); | ||
485 | |||
486 | if (conf->enable_beacon) | ||
487 | ah->imask |= ATH9K_INT_SWBA; | ||
488 | else | ||
489 | ah->imask &= ~ATH9K_INT_SWBA; | ||
490 | |||
491 | ath_dbg(common, BEACON, | ||
492 | "AP (%s) nexttbtt: %u intval: %u conf_intval: %u\n", | ||
493 | (conf->enable_beacon) ? "Enable" : "Disable", | ||
494 | nexttbtt, intval, conf->beacon_interval); | ||
495 | 459 | ||
496 | ath9k_beacon_init(sc, nexttbtt, intval, false); | 460 | ath9k_cmn_beacon_config_ap(ah, conf, ATH_BCBUF); |
461 | ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, false); | ||
497 | } | 462 | } |
498 | 463 | ||
499 | /* | 464 | static void ath9k_beacon_config_sta(struct ath_hw *ah, |
500 | * This sets up the beacon timers according to the timestamp of the last | ||
501 | * received beacon and the current TSF, configures PCF and DTIM | ||
502 | * handling, programs the sleep registers so the hardware will wakeup in | ||
503 | * time to receive beacons, and configures the beacon miss handling so | ||
504 | * we'll receive a BMISS interrupt when we stop seeing beacons from the AP | ||
505 | * we've associated with. | ||
506 | */ | ||
507 | static void ath9k_beacon_config_sta(struct ath_softc *sc, | ||
508 | struct ath_beacon_config *conf) | 465 | struct ath_beacon_config *conf) |
509 | { | 466 | { |
510 | struct ath_hw *ah = sc->sc_ah; | ||
511 | struct ath_common *common = ath9k_hw_common(ah); | ||
512 | struct ath9k_beacon_state bs; | 467 | struct ath9k_beacon_state bs; |
513 | int dtim_intval, sleepduration; | ||
514 | u32 nexttbtt = 0, intval; | ||
515 | u64 tsf; | ||
516 | 468 | ||
517 | /* No need to configure beacon if we are not associated */ | 469 | if (ath9k_cmn_beacon_config_sta(ah, conf, &bs) == -EPERM) |
518 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | ||
519 | ath_dbg(common, BEACON, | ||
520 | "STA is not yet associated..skipping beacon config\n"); | ||
521 | return; | 470 | return; |
522 | } | ||
523 | |||
524 | memset(&bs, 0, sizeof(bs)); | ||
525 | intval = conf->beacon_interval; | ||
526 | |||
527 | /* | ||
528 | * Setup dtim parameters according to | ||
529 | * last beacon we received (which may be none). | ||
530 | */ | ||
531 | dtim_intval = intval * conf->dtim_period; | ||
532 | sleepduration = conf->listen_interval * intval; | ||
533 | |||
534 | /* | ||
535 | * Pull nexttbtt forward to reflect the current | ||
536 | * TSF and calculate dtim state for the result. | ||
537 | */ | ||
538 | tsf = ath9k_hw_gettsf64(ah); | ||
539 | nexttbtt = ath9k_get_next_tbtt(sc, tsf, intval); | ||
540 | |||
541 | bs.bs_intval = TU_TO_USEC(intval); | ||
542 | bs.bs_dtimperiod = conf->dtim_period * bs.bs_intval; | ||
543 | bs.bs_nexttbtt = nexttbtt; | ||
544 | bs.bs_nextdtim = nexttbtt; | ||
545 | if (conf->dtim_period > 1) | ||
546 | bs.bs_nextdtim = ath9k_get_next_tbtt(sc, tsf, dtim_intval); | ||
547 | |||
548 | /* | ||
549 | * Calculate the number of consecutive beacons to miss* before taking | ||
550 | * a BMISS interrupt. The configuration is specified in TU so we only | ||
551 | * need calculate based on the beacon interval. Note that we clamp the | ||
552 | * result to at most 15 beacons. | ||
553 | */ | ||
554 | if (sleepduration > intval) { | ||
555 | bs.bs_bmissthreshold = conf->listen_interval * | ||
556 | ATH_DEFAULT_BMISS_LIMIT / 2; | ||
557 | } else { | ||
558 | bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval); | ||
559 | if (bs.bs_bmissthreshold > 15) | ||
560 | bs.bs_bmissthreshold = 15; | ||
561 | else if (bs.bs_bmissthreshold <= 0) | ||
562 | bs.bs_bmissthreshold = 1; | ||
563 | } | ||
564 | |||
565 | /* | ||
566 | * Calculate sleep duration. The configuration is given in ms. | ||
567 | * We ensure a multiple of the beacon period is used. Also, if the sleep | ||
568 | * duration is greater than the DTIM period then it makes senses | ||
569 | * to make it a multiple of that. | ||
570 | * | ||
571 | * XXX fixed at 100ms | ||
572 | */ | ||
573 | |||
574 | bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100), | ||
575 | sleepduration)); | ||
576 | if (bs.bs_sleepduration > bs.bs_dtimperiod) | ||
577 | bs.bs_sleepduration = bs.bs_dtimperiod; | ||
578 | |||
579 | /* TSF out of range threshold fixed at 1 second */ | ||
580 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | ||
581 | |||
582 | ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n", | ||
583 | bs.bs_bmissthreshold, bs.bs_sleepduration); | ||
584 | |||
585 | /* Set the computed STA beacon timers */ | ||
586 | 471 | ||
587 | ath9k_hw_disable_interrupts(ah); | 472 | ath9k_hw_disable_interrupts(ah); |
588 | ath9k_hw_set_sta_beacon_timers(ah, &bs); | 473 | ath9k_hw_set_sta_beacon_timers(ah, &bs); |
@@ -597,36 +482,19 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc, | |||
597 | { | 482 | { |
598 | struct ath_hw *ah = sc->sc_ah; | 483 | struct ath_hw *ah = sc->sc_ah; |
599 | struct ath_common *common = ath9k_hw_common(ah); | 484 | struct ath_common *common = ath9k_hw_common(ah); |
600 | u32 intval, nexttbtt; | ||
601 | 485 | ||
602 | ath9k_reset_beacon_status(sc); | 486 | ath9k_reset_beacon_status(sc); |
603 | 487 | ||
604 | intval = TU_TO_USEC(conf->beacon_interval); | 488 | ath9k_cmn_beacon_config_adhoc(ah, conf); |
605 | |||
606 | if (conf->ibss_creator) | ||
607 | nexttbtt = intval; | ||
608 | else | ||
609 | nexttbtt = ath9k_get_next_tbtt(sc, ath9k_hw_gettsf64(ah), | ||
610 | conf->beacon_interval); | ||
611 | |||
612 | if (conf->enable_beacon) | ||
613 | ah->imask |= ATH9K_INT_SWBA; | ||
614 | else | ||
615 | ah->imask &= ~ATH9K_INT_SWBA; | ||
616 | |||
617 | ath_dbg(common, BEACON, | ||
618 | "IBSS (%s) nexttbtt: %u intval: %u conf_intval: %u\n", | ||
619 | (conf->enable_beacon) ? "Enable" : "Disable", | ||
620 | nexttbtt, intval, conf->beacon_interval); | ||
621 | 489 | ||
622 | ath9k_beacon_init(sc, nexttbtt, intval, conf->ibss_creator); | 490 | ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, conf->ibss_creator); |
623 | 491 | ||
624 | /* | 492 | /* |
625 | * Set the global 'beacon has been configured' flag for the | 493 | * Set the global 'beacon has been configured' flag for the |
626 | * joiner case in IBSS mode. | 494 | * joiner case in IBSS mode. |
627 | */ | 495 | */ |
628 | if (!conf->ibss_creator && conf->enable_beacon) | 496 | if (!conf->ibss_creator && conf->enable_beacon) |
629 | set_bit(SC_OP_BEACONS, &sc->sc_flags); | 497 | set_bit(ATH_OP_BEACONS, &common->op_flags); |
630 | } | 498 | } |
631 | 499 | ||
632 | static bool ath9k_allow_beacon_config(struct ath_softc *sc, | 500 | static bool ath9k_allow_beacon_config(struct ath_softc *sc, |
@@ -646,7 +514,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc, | |||
646 | 514 | ||
647 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { | 515 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { |
648 | if ((vif->type == NL80211_IFTYPE_STATION) && | 516 | if ((vif->type == NL80211_IFTYPE_STATION) && |
649 | test_bit(SC_OP_BEACONS, &sc->sc_flags) && | 517 | test_bit(ATH_OP_BEACONS, &common->op_flags) && |
650 | !avp->primary_sta_vif) { | 518 | !avp->primary_sta_vif) { |
651 | ath_dbg(common, CONFIG, | 519 | ath_dbg(common, CONFIG, |
652 | "Beacon already configured for a station interface\n"); | 520 | "Beacon already configured for a station interface\n"); |
@@ -668,7 +536,6 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc, | |||
668 | 536 | ||
669 | cur_conf->beacon_interval = bss_conf->beacon_int; | 537 | cur_conf->beacon_interval = bss_conf->beacon_int; |
670 | cur_conf->dtim_period = bss_conf->dtim_period; | 538 | cur_conf->dtim_period = bss_conf->dtim_period; |
671 | cur_conf->listen_interval = 1; | ||
672 | cur_conf->dtim_count = 1; | 539 | cur_conf->dtim_count = 1; |
673 | cur_conf->ibss_creator = bss_conf->ibss_creator; | 540 | cur_conf->ibss_creator = bss_conf->ibss_creator; |
674 | cur_conf->bmiss_timeout = | 541 | cur_conf->bmiss_timeout = |
@@ -698,6 +565,8 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
698 | { | 565 | { |
699 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 566 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
700 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | 567 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; |
568 | struct ath_hw *ah = sc->sc_ah; | ||
569 | struct ath_common *common = ath9k_hw_common(ah); | ||
701 | unsigned long flags; | 570 | unsigned long flags; |
702 | bool skip_beacon = false; | 571 | bool skip_beacon = false; |
703 | 572 | ||
@@ -710,7 +579,7 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
710 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { | 579 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { |
711 | ath9k_cache_beacon_config(sc, bss_conf); | 580 | ath9k_cache_beacon_config(sc, bss_conf); |
712 | ath9k_set_beacon(sc); | 581 | ath9k_set_beacon(sc); |
713 | set_bit(SC_OP_BEACONS, &sc->sc_flags); | 582 | set_bit(ATH_OP_BEACONS, &common->op_flags); |
714 | return; | 583 | return; |
715 | } | 584 | } |
716 | 585 | ||
@@ -749,13 +618,13 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
749 | } | 618 | } |
750 | 619 | ||
751 | /* | 620 | /* |
752 | * Do not set the SC_OP_BEACONS flag for IBSS joiner mode | 621 | * Do not set the ATH_OP_BEACONS flag for IBSS joiner mode |
753 | * here, it is done in ath9k_beacon_config_adhoc(). | 622 | * here, it is done in ath9k_beacon_config_adhoc(). |
754 | */ | 623 | */ |
755 | if (cur_conf->enable_beacon && !skip_beacon) | 624 | if (cur_conf->enable_beacon && !skip_beacon) |
756 | set_bit(SC_OP_BEACONS, &sc->sc_flags); | 625 | set_bit(ATH_OP_BEACONS, &common->op_flags); |
757 | else | 626 | else |
758 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | 627 | clear_bit(ATH_OP_BEACONS, &common->op_flags); |
759 | } | 628 | } |
760 | } | 629 | } |
761 | 630 | ||
@@ -773,7 +642,7 @@ void ath9k_set_beacon(struct ath_softc *sc) | |||
773 | ath9k_beacon_config_adhoc(sc, cur_conf); | 642 | ath9k_beacon_config_adhoc(sc, cur_conf); |
774 | break; | 643 | break; |
775 | case NL80211_IFTYPE_STATION: | 644 | case NL80211_IFTYPE_STATION: |
776 | ath9k_beacon_config_sta(sc, cur_conf); | 645 | ath9k_beacon_config_sta(sc->sc_ah, cur_conf); |
777 | break; | 646 | break; |
778 | default: | 647 | default: |
779 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); | 648 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/common-beacon.c b/drivers/net/wireless/ath/ath9k/common-beacon.c new file mode 100644 index 000000000000..775d1d20ce0b --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/common-beacon.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "common.h" | ||
18 | |||
19 | #define FUDGE 2 | ||
20 | |||
21 | /* Calculate the modulo of a 64 bit TSF snapshot with a TU divisor */ | ||
22 | static u32 ath9k_mod_tsf64_tu(u64 tsf, u32 div_tu) | ||
23 | { | ||
24 | u32 tsf_mod, tsf_hi, tsf_lo, mod_hi, mod_lo; | ||
25 | |||
26 | tsf_mod = tsf & (BIT(10) - 1); | ||
27 | tsf_hi = tsf >> 32; | ||
28 | tsf_lo = ((u32) tsf) >> 10; | ||
29 | |||
30 | mod_hi = tsf_hi % div_tu; | ||
31 | mod_lo = ((mod_hi << 22) + tsf_lo) % div_tu; | ||
32 | |||
33 | return (mod_lo << 10) | tsf_mod; | ||
34 | } | ||
35 | |||
36 | static u32 ath9k_get_next_tbtt(struct ath_hw *ah, u64 tsf, | ||
37 | unsigned int interval) | ||
38 | { | ||
39 | unsigned int offset; | ||
40 | |||
41 | tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time); | ||
42 | offset = ath9k_mod_tsf64_tu(tsf, interval); | ||
43 | |||
44 | return (u32) tsf + TU_TO_USEC(interval) - offset; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * This sets up the beacon timers according to the timestamp of the last | ||
49 | * received beacon and the current TSF, configures PCF and DTIM | ||
50 | * handling, programs the sleep registers so the hardware will wakeup in | ||
51 | * time to receive beacons, and configures the beacon miss handling so | ||
52 | * we'll receive a BMISS interrupt when we stop seeing beacons from the AP | ||
53 | * we've associated with. | ||
54 | */ | ||
55 | int ath9k_cmn_beacon_config_sta(struct ath_hw *ah, | ||
56 | struct ath_beacon_config *conf, | ||
57 | struct ath9k_beacon_state *bs) | ||
58 | { | ||
59 | struct ath_common *common = ath9k_hw_common(ah); | ||
60 | int dtim_intval; | ||
61 | u64 tsf; | ||
62 | |||
63 | /* No need to configure beacon if we are not associated */ | ||
64 | if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) { | ||
65 | ath_dbg(common, BEACON, | ||
66 | "STA is not yet associated..skipping beacon config\n"); | ||
67 | return -EPERM; | ||
68 | } | ||
69 | |||
70 | memset(bs, 0, sizeof(*bs)); | ||
71 | conf->intval = conf->beacon_interval; | ||
72 | |||
73 | /* | ||
74 | * Setup dtim parameters according to | ||
75 | * last beacon we received (which may be none). | ||
76 | */ | ||
77 | dtim_intval = conf->intval * conf->dtim_period; | ||
78 | |||
79 | /* | ||
80 | * Pull nexttbtt forward to reflect the current | ||
81 | * TSF and calculate dtim state for the result. | ||
82 | */ | ||
83 | tsf = ath9k_hw_gettsf64(ah); | ||
84 | conf->nexttbtt = ath9k_get_next_tbtt(ah, tsf, conf->intval); | ||
85 | |||
86 | bs->bs_intval = TU_TO_USEC(conf->intval); | ||
87 | bs->bs_dtimperiod = conf->dtim_period * bs->bs_intval; | ||
88 | bs->bs_nexttbtt = conf->nexttbtt; | ||
89 | bs->bs_nextdtim = conf->nexttbtt; | ||
90 | if (conf->dtim_period > 1) | ||
91 | bs->bs_nextdtim = ath9k_get_next_tbtt(ah, tsf, dtim_intval); | ||
92 | |||
93 | /* | ||
94 | * Calculate the number of consecutive beacons to miss* before taking | ||
95 | * a BMISS interrupt. The configuration is specified in TU so we only | ||
96 | * need calculate based on the beacon interval. Note that we clamp the | ||
97 | * result to at most 15 beacons. | ||
98 | */ | ||
99 | bs->bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, conf->intval); | ||
100 | if (bs->bs_bmissthreshold > 15) | ||
101 | bs->bs_bmissthreshold = 15; | ||
102 | else if (bs->bs_bmissthreshold <= 0) | ||
103 | bs->bs_bmissthreshold = 1; | ||
104 | |||
105 | /* | ||
106 | * Calculate sleep duration. The configuration is given in ms. | ||
107 | * We ensure a multiple of the beacon period is used. Also, if the sleep | ||
108 | * duration is greater than the DTIM period then it makes senses | ||
109 | * to make it a multiple of that. | ||
110 | * | ||
111 | * XXX fixed at 100ms | ||
112 | */ | ||
113 | |||
114 | bs->bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100), | ||
115 | conf->intval)); | ||
116 | if (bs->bs_sleepduration > bs->bs_dtimperiod) | ||
117 | bs->bs_sleepduration = bs->bs_dtimperiod; | ||
118 | |||
119 | /* TSF out of range threshold fixed at 1 second */ | ||
120 | bs->bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | ||
121 | |||
122 | ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n", | ||
123 | bs->bs_bmissthreshold, bs->bs_sleepduration); | ||
124 | return 0; | ||
125 | } | ||
126 | EXPORT_SYMBOL(ath9k_cmn_beacon_config_sta); | ||
127 | |||
128 | void ath9k_cmn_beacon_config_adhoc(struct ath_hw *ah, | ||
129 | struct ath_beacon_config *conf) | ||
130 | { | ||
131 | struct ath_common *common = ath9k_hw_common(ah); | ||
132 | |||
133 | conf->intval = TU_TO_USEC(conf->beacon_interval); | ||
134 | |||
135 | if (conf->ibss_creator) | ||
136 | conf->nexttbtt = conf->intval; | ||
137 | else | ||
138 | conf->nexttbtt = ath9k_get_next_tbtt(ah, ath9k_hw_gettsf64(ah), | ||
139 | conf->beacon_interval); | ||
140 | |||
141 | if (conf->enable_beacon) | ||
142 | ah->imask |= ATH9K_INT_SWBA; | ||
143 | else | ||
144 | ah->imask &= ~ATH9K_INT_SWBA; | ||
145 | |||
146 | ath_dbg(common, BEACON, | ||
147 | "IBSS (%s) nexttbtt: %u intval: %u conf_intval: %u\n", | ||
148 | (conf->enable_beacon) ? "Enable" : "Disable", | ||
149 | conf->nexttbtt, conf->intval, conf->beacon_interval); | ||
150 | } | ||
151 | EXPORT_SYMBOL(ath9k_cmn_beacon_config_adhoc); | ||
152 | |||
153 | /* | ||
154 | * For multi-bss ap support beacons are either staggered evenly over N slots or | ||
155 | * burst together. For the former arrange for the SWBA to be delivered for each | ||
156 | * slot. Slots that are not occupied will generate nothing. | ||
157 | */ | ||
158 | void ath9k_cmn_beacon_config_ap(struct ath_hw *ah, | ||
159 | struct ath_beacon_config *conf, | ||
160 | unsigned int bc_buf) | ||
161 | { | ||
162 | struct ath_common *common = ath9k_hw_common(ah); | ||
163 | |||
164 | /* NB: the beacon interval is kept internally in TU's */ | ||
165 | conf->intval = TU_TO_USEC(conf->beacon_interval); | ||
166 | conf->intval /= bc_buf; | ||
167 | conf->nexttbtt = ath9k_get_next_tbtt(ah, ath9k_hw_gettsf64(ah), | ||
168 | conf->beacon_interval); | ||
169 | |||
170 | if (conf->enable_beacon) | ||
171 | ah->imask |= ATH9K_INT_SWBA; | ||
172 | else | ||
173 | ah->imask &= ~ATH9K_INT_SWBA; | ||
174 | |||
175 | ath_dbg(common, BEACON, | ||
176 | "AP (%s) nexttbtt: %u intval: %u conf_intval: %u\n", | ||
177 | (conf->enable_beacon) ? "Enable" : "Disable", | ||
178 | conf->nexttbtt, conf->intval, conf->beacon_interval); | ||
179 | } | ||
180 | EXPORT_SYMBOL(ath9k_cmn_beacon_config_ap); | ||
diff --git a/drivers/net/wireless/ath/ath9k/common-beacon.h b/drivers/net/wireless/ath/ath9k/common-beacon.h new file mode 100644 index 000000000000..3665d27f0dc7 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/common-beacon.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | struct ath_beacon_config; | ||
18 | |||
19 | int ath9k_cmn_beacon_config_sta(struct ath_hw *ah, | ||
20 | struct ath_beacon_config *conf, | ||
21 | struct ath9k_beacon_state *bs); | ||
22 | void ath9k_cmn_beacon_config_adhoc(struct ath_hw *ah, | ||
23 | struct ath_beacon_config *conf); | ||
24 | void ath9k_cmn_beacon_config_ap(struct ath_hw *ah, | ||
25 | struct ath_beacon_config *conf, | ||
26 | unsigned int bc_buf); | ||
diff --git a/drivers/net/wireless/ath/ath9k/common-init.c b/drivers/net/wireless/ath/ath9k/common-init.c new file mode 100644 index 000000000000..a006c1499728 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/common-init.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | /* We use the hw_value as an index into our private channel structure */ | ||
18 | |||
19 | #include "common.h" | ||
20 | |||
21 | #define CHAN2G(_freq, _idx) { \ | ||
22 | .band = IEEE80211_BAND_2GHZ, \ | ||
23 | .center_freq = (_freq), \ | ||
24 | .hw_value = (_idx), \ | ||
25 | .max_power = 20, \ | ||
26 | } | ||
27 | |||
28 | #define CHAN5G(_freq, _idx) { \ | ||
29 | .band = IEEE80211_BAND_5GHZ, \ | ||
30 | .center_freq = (_freq), \ | ||
31 | .hw_value = (_idx), \ | ||
32 | .max_power = 20, \ | ||
33 | } | ||
34 | |||
35 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
36 | * on 5 MHz steps, we support the channels which we know | ||
37 | * we have calibration data for all cards though to make | ||
38 | * this static */ | ||
39 | static const struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
40 | CHAN2G(2412, 0), /* Channel 1 */ | ||
41 | CHAN2G(2417, 1), /* Channel 2 */ | ||
42 | CHAN2G(2422, 2), /* Channel 3 */ | ||
43 | CHAN2G(2427, 3), /* Channel 4 */ | ||
44 | CHAN2G(2432, 4), /* Channel 5 */ | ||
45 | CHAN2G(2437, 5), /* Channel 6 */ | ||
46 | CHAN2G(2442, 6), /* Channel 7 */ | ||
47 | CHAN2G(2447, 7), /* Channel 8 */ | ||
48 | CHAN2G(2452, 8), /* Channel 9 */ | ||
49 | CHAN2G(2457, 9), /* Channel 10 */ | ||
50 | CHAN2G(2462, 10), /* Channel 11 */ | ||
51 | CHAN2G(2467, 11), /* Channel 12 */ | ||
52 | CHAN2G(2472, 12), /* Channel 13 */ | ||
53 | CHAN2G(2484, 13), /* Channel 14 */ | ||
54 | }; | ||
55 | |||
56 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
57 | * on 5 MHz steps, we support the channels which we know | ||
58 | * we have calibration data for all cards though to make | ||
59 | * this static */ | ||
60 | static const struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
61 | /* _We_ call this UNII 1 */ | ||
62 | CHAN5G(5180, 14), /* Channel 36 */ | ||
63 | CHAN5G(5200, 15), /* Channel 40 */ | ||
64 | CHAN5G(5220, 16), /* Channel 44 */ | ||
65 | CHAN5G(5240, 17), /* Channel 48 */ | ||
66 | /* _We_ call this UNII 2 */ | ||
67 | CHAN5G(5260, 18), /* Channel 52 */ | ||
68 | CHAN5G(5280, 19), /* Channel 56 */ | ||
69 | CHAN5G(5300, 20), /* Channel 60 */ | ||
70 | CHAN5G(5320, 21), /* Channel 64 */ | ||
71 | /* _We_ call this "Middle band" */ | ||
72 | CHAN5G(5500, 22), /* Channel 100 */ | ||
73 | CHAN5G(5520, 23), /* Channel 104 */ | ||
74 | CHAN5G(5540, 24), /* Channel 108 */ | ||
75 | CHAN5G(5560, 25), /* Channel 112 */ | ||
76 | CHAN5G(5580, 26), /* Channel 116 */ | ||
77 | CHAN5G(5600, 27), /* Channel 120 */ | ||
78 | CHAN5G(5620, 28), /* Channel 124 */ | ||
79 | CHAN5G(5640, 29), /* Channel 128 */ | ||
80 | CHAN5G(5660, 30), /* Channel 132 */ | ||
81 | CHAN5G(5680, 31), /* Channel 136 */ | ||
82 | CHAN5G(5700, 32), /* Channel 140 */ | ||
83 | /* _We_ call this UNII 3 */ | ||
84 | CHAN5G(5745, 33), /* Channel 149 */ | ||
85 | CHAN5G(5765, 34), /* Channel 153 */ | ||
86 | CHAN5G(5785, 35), /* Channel 157 */ | ||
87 | CHAN5G(5805, 36), /* Channel 161 */ | ||
88 | CHAN5G(5825, 37), /* Channel 165 */ | ||
89 | }; | ||
90 | |||
91 | /* Atheros hardware rate code addition for short premble */ | ||
92 | #define SHPCHECK(__hw_rate, __flags) \ | ||
93 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) | ||
94 | |||
95 | #define RATE(_bitrate, _hw_rate, _flags) { \ | ||
96 | .bitrate = (_bitrate), \ | ||
97 | .flags = (_flags), \ | ||
98 | .hw_value = (_hw_rate), \ | ||
99 | .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ | ||
100 | } | ||
101 | |||
102 | static struct ieee80211_rate ath9k_legacy_rates[] = { | ||
103 | RATE(10, 0x1b, 0), | ||
104 | RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), | ||
105 | RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), | ||
106 | RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), | ||
107 | RATE(60, 0x0b, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
108 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
109 | RATE(90, 0x0f, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
110 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
111 | RATE(120, 0x0a, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
112 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
113 | RATE(180, 0x0e, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
114 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
115 | RATE(240, 0x09, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
116 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
117 | RATE(360, 0x0d, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
118 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
119 | RATE(480, 0x08, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
120 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
121 | RATE(540, 0x0c, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
122 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
123 | }; | ||
124 | |||
125 | int ath9k_cmn_init_channels_rates(struct ath_common *common) | ||
126 | { | ||
127 | struct ath_hw *ah = (struct ath_hw *)common->ah; | ||
128 | void *channels; | ||
129 | |||
130 | BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) + | ||
131 | ARRAY_SIZE(ath9k_5ghz_chantable) != | ||
132 | ATH9K_NUM_CHANNELS); | ||
133 | |||
134 | if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { | ||
135 | channels = devm_kzalloc(ah->dev, | ||
136 | sizeof(ath9k_2ghz_chantable), GFP_KERNEL); | ||
137 | if (!channels) | ||
138 | return -ENOMEM; | ||
139 | |||
140 | memcpy(channels, ath9k_2ghz_chantable, | ||
141 | sizeof(ath9k_2ghz_chantable)); | ||
142 | common->sbands[IEEE80211_BAND_2GHZ].channels = channels; | ||
143 | common->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
144 | common->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
145 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
146 | common->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
147 | common->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
148 | ARRAY_SIZE(ath9k_legacy_rates); | ||
149 | } | ||
150 | |||
151 | if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { | ||
152 | channels = devm_kzalloc(ah->dev, | ||
153 | sizeof(ath9k_5ghz_chantable), GFP_KERNEL); | ||
154 | if (!channels) | ||
155 | return -ENOMEM; | ||
156 | |||
157 | memcpy(channels, ath9k_5ghz_chantable, | ||
158 | sizeof(ath9k_5ghz_chantable)); | ||
159 | common->sbands[IEEE80211_BAND_5GHZ].channels = channels; | ||
160 | common->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
161 | common->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
162 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
163 | common->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
164 | ath9k_legacy_rates + 4; | ||
165 | common->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | ||
166 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | ||
167 | } | ||
168 | return 0; | ||
169 | } | ||
170 | EXPORT_SYMBOL(ath9k_cmn_init_channels_rates); | ||
171 | |||
172 | void ath9k_cmn_setup_ht_cap(struct ath_hw *ah, | ||
173 | struct ieee80211_sta_ht_cap *ht_info) | ||
174 | { | ||
175 | struct ath_common *common = ath9k_hw_common(ah); | ||
176 | u8 tx_streams, rx_streams; | ||
177 | int i, max_streams; | ||
178 | |||
179 | ht_info->ht_supported = true; | ||
180 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
181 | IEEE80211_HT_CAP_SM_PS | | ||
182 | IEEE80211_HT_CAP_SGI_40 | | ||
183 | IEEE80211_HT_CAP_DSSSCCK40; | ||
184 | |||
185 | if (ah->caps.hw_caps & ATH9K_HW_CAP_LDPC) | ||
186 | ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
187 | |||
188 | if (ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) | ||
189 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
190 | |||
191 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
192 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
193 | |||
194 | if (AR_SREV_9271(ah) || AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) | ||
195 | max_streams = 1; | ||
196 | else if (AR_SREV_9462(ah)) | ||
197 | max_streams = 2; | ||
198 | else if (AR_SREV_9300_20_OR_LATER(ah)) | ||
199 | max_streams = 3; | ||
200 | else | ||
201 | max_streams = 2; | ||
202 | |||
203 | if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
204 | if (max_streams >= 2) | ||
205 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; | ||
206 | ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); | ||
207 | } | ||
208 | |||
209 | /* set up supported mcs set */ | ||
210 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
211 | tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams); | ||
212 | rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams); | ||
213 | |||
214 | ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n", | ||
215 | tx_streams, rx_streams); | ||
216 | |||
217 | if (tx_streams != rx_streams) { | ||
218 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
219 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | ||
220 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
221 | } | ||
222 | |||
223 | for (i = 0; i < rx_streams; i++) | ||
224 | ht_info->mcs.rx_mask[i] = 0xff; | ||
225 | |||
226 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
227 | } | ||
228 | EXPORT_SYMBOL(ath9k_cmn_setup_ht_cap); | ||
229 | |||
230 | void ath9k_cmn_reload_chainmask(struct ath_hw *ah) | ||
231 | { | ||
232 | struct ath_common *common = ath9k_hw_common(ah); | ||
233 | |||
234 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_HT)) | ||
235 | return; | ||
236 | |||
237 | if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) | ||
238 | ath9k_cmn_setup_ht_cap(ah, | ||
239 | &common->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
240 | if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) | ||
241 | ath9k_cmn_setup_ht_cap(ah, | ||
242 | &common->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
243 | } | ||
244 | EXPORT_SYMBOL(ath9k_cmn_reload_chainmask); | ||
diff --git a/drivers/net/wireless/ath/ath9k/common-init.h b/drivers/net/wireless/ath/ath9k/common-init.h new file mode 100644 index 000000000000..ac03fca5ffdd --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/common-init.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | int ath9k_cmn_init_channels_rates(struct ath_common *common); | ||
18 | void ath9k_cmn_setup_ht_cap(struct ath_hw *ah, | ||
19 | struct ieee80211_sta_ht_cap *ht_info); | ||
20 | void ath9k_cmn_reload_chainmask(struct ath_hw *ah); | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 768c733cad31..c6dd7f1fed65 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -27,6 +27,250 @@ MODULE_AUTHOR("Atheros Communications"); | |||
27 | MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); | 27 | MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); |
28 | MODULE_LICENSE("Dual BSD/GPL"); | 28 | MODULE_LICENSE("Dual BSD/GPL"); |
29 | 29 | ||
30 | /* Assumes you've already done the endian to CPU conversion */ | ||
31 | bool ath9k_cmn_rx_accept(struct ath_common *common, | ||
32 | struct ieee80211_hdr *hdr, | ||
33 | struct ieee80211_rx_status *rxs, | ||
34 | struct ath_rx_status *rx_stats, | ||
35 | bool *decrypt_error, | ||
36 | unsigned int rxfilter) | ||
37 | { | ||
38 | struct ath_hw *ah = common->ah; | ||
39 | bool is_mc, is_valid_tkip, strip_mic, mic_error; | ||
40 | __le16 fc; | ||
41 | |||
42 | fc = hdr->frame_control; | ||
43 | |||
44 | is_mc = !!is_multicast_ether_addr(hdr->addr1); | ||
45 | is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && | ||
46 | test_bit(rx_stats->rs_keyix, common->tkip_keymap); | ||
47 | strip_mic = is_valid_tkip && ieee80211_is_data(fc) && | ||
48 | ieee80211_has_protected(fc) && | ||
49 | !(rx_stats->rs_status & | ||
50 | (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC | | ||
51 | ATH9K_RXERR_KEYMISS)); | ||
52 | |||
53 | /* | ||
54 | * Key miss events are only relevant for pairwise keys where the | ||
55 | * descriptor does contain a valid key index. This has been observed | ||
56 | * mostly with CCMP encryption. | ||
57 | */ | ||
58 | if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID || | ||
59 | !test_bit(rx_stats->rs_keyix, common->ccmp_keymap)) | ||
60 | rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS; | ||
61 | |||
62 | mic_error = is_valid_tkip && !ieee80211_is_ctl(fc) && | ||
63 | !ieee80211_has_morefrags(fc) && | ||
64 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && | ||
65 | (rx_stats->rs_status & ATH9K_RXERR_MIC); | ||
66 | |||
67 | /* | ||
68 | * The rx_stats->rs_status will not be set until the end of the | ||
69 | * chained descriptors so it can be ignored if rs_more is set. The | ||
70 | * rs_more will be false at the last element of the chained | ||
71 | * descriptors. | ||
72 | */ | ||
73 | if (rx_stats->rs_status != 0) { | ||
74 | u8 status_mask; | ||
75 | |||
76 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) { | ||
77 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
78 | mic_error = false; | ||
79 | } | ||
80 | |||
81 | if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) || | ||
82 | (!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) { | ||
83 | *decrypt_error = true; | ||
84 | mic_error = false; | ||
85 | } | ||
86 | |||
87 | |||
88 | /* | ||
89 | * Reject error frames with the exception of | ||
90 | * decryption and MIC failures. For monitor mode, | ||
91 | * we also ignore the CRC error. | ||
92 | */ | ||
93 | status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
94 | ATH9K_RXERR_KEYMISS; | ||
95 | |||
96 | if (ah->is_monitoring && (rxfilter & FIF_FCSFAIL)) | ||
97 | status_mask |= ATH9K_RXERR_CRC; | ||
98 | |||
99 | if (rx_stats->rs_status & ~status_mask) | ||
100 | return false; | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * For unicast frames the MIC error bit can have false positives, | ||
105 | * so all MIC error reports need to be validated in software. | ||
106 | * False negatives are not common, so skip software verification | ||
107 | * if the hardware considers the MIC valid. | ||
108 | */ | ||
109 | if (strip_mic) | ||
110 | rxs->flag |= RX_FLAG_MMIC_STRIPPED; | ||
111 | else if (is_mc && mic_error) | ||
112 | rxs->flag |= RX_FLAG_MMIC_ERROR; | ||
113 | |||
114 | return true; | ||
115 | } | ||
116 | EXPORT_SYMBOL(ath9k_cmn_rx_accept); | ||
117 | |||
118 | void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | ||
119 | struct sk_buff *skb, | ||
120 | struct ath_rx_status *rx_stats, | ||
121 | struct ieee80211_rx_status *rxs, | ||
122 | bool decrypt_error) | ||
123 | { | ||
124 | struct ath_hw *ah = common->ah; | ||
125 | struct ieee80211_hdr *hdr; | ||
126 | int hdrlen, padpos, padsize; | ||
127 | u8 keyix; | ||
128 | __le16 fc; | ||
129 | |||
130 | /* see if any padding is done by the hw and remove it */ | ||
131 | hdr = (struct ieee80211_hdr *) skb->data; | ||
132 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
133 | fc = hdr->frame_control; | ||
134 | padpos = ieee80211_hdrlen(fc); | ||
135 | |||
136 | /* The MAC header is padded to have 32-bit boundary if the | ||
137 | * packet payload is non-zero. The general calculation for | ||
138 | * padsize would take into account odd header lengths: | ||
139 | * padsize = (4 - padpos % 4) % 4; However, since only | ||
140 | * even-length headers are used, padding can only be 0 or 2 | ||
141 | * bytes and we can optimize this a bit. In addition, we must | ||
142 | * not try to remove padding from short control frames that do | ||
143 | * not have payload. */ | ||
144 | padsize = padpos & 3; | ||
145 | if (padsize && skb->len>=padpos+padsize+FCS_LEN) { | ||
146 | memmove(skb->data + padsize, skb->data, padpos); | ||
147 | skb_pull(skb, padsize); | ||
148 | } | ||
149 | |||
150 | keyix = rx_stats->rs_keyix; | ||
151 | |||
152 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && | ||
153 | ieee80211_has_protected(fc)) { | ||
154 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
155 | } else if (ieee80211_has_protected(fc) | ||
156 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
157 | keyix = skb->data[hdrlen + 3] >> 6; | ||
158 | |||
159 | if (test_bit(keyix, common->keymap)) | ||
160 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
161 | } | ||
162 | if (ah->sw_mgmt_crypto && | ||
163 | (rxs->flag & RX_FLAG_DECRYPTED) && | ||
164 | ieee80211_is_mgmt(fc)) | ||
165 | /* Use software decrypt for management frames. */ | ||
166 | rxs->flag &= ~RX_FLAG_DECRYPTED; | ||
167 | } | ||
168 | EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess); | ||
169 | |||
170 | int ath9k_cmn_process_rate(struct ath_common *common, | ||
171 | struct ieee80211_hw *hw, | ||
172 | struct ath_rx_status *rx_stats, | ||
173 | struct ieee80211_rx_status *rxs) | ||
174 | { | ||
175 | struct ieee80211_supported_band *sband; | ||
176 | enum ieee80211_band band; | ||
177 | unsigned int i = 0; | ||
178 | struct ath_hw *ah = common->ah; | ||
179 | |||
180 | band = ah->curchan->chan->band; | ||
181 | sband = hw->wiphy->bands[band]; | ||
182 | |||
183 | if (IS_CHAN_QUARTER_RATE(ah->curchan)) | ||
184 | rxs->flag |= RX_FLAG_5MHZ; | ||
185 | else if (IS_CHAN_HALF_RATE(ah->curchan)) | ||
186 | rxs->flag |= RX_FLAG_10MHZ; | ||
187 | |||
188 | if (rx_stats->rs_rate & 0x80) { | ||
189 | /* HT rate */ | ||
190 | rxs->flag |= RX_FLAG_HT; | ||
191 | rxs->flag |= rx_stats->flag; | ||
192 | rxs->rate_idx = rx_stats->rs_rate & 0x7f; | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | for (i = 0; i < sband->n_bitrates; i++) { | ||
197 | if (sband->bitrates[i].hw_value == rx_stats->rs_rate) { | ||
198 | rxs->rate_idx = i; | ||
199 | return 0; | ||
200 | } | ||
201 | if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { | ||
202 | rxs->flag |= RX_FLAG_SHORTPRE; | ||
203 | rxs->rate_idx = i; | ||
204 | return 0; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | return -EINVAL; | ||
209 | } | ||
210 | EXPORT_SYMBOL(ath9k_cmn_process_rate); | ||
211 | |||
212 | void ath9k_cmn_process_rssi(struct ath_common *common, | ||
213 | struct ieee80211_hw *hw, | ||
214 | struct ath_rx_status *rx_stats, | ||
215 | struct ieee80211_rx_status *rxs) | ||
216 | { | ||
217 | struct ath_hw *ah = common->ah; | ||
218 | int last_rssi; | ||
219 | int rssi = rx_stats->rs_rssi; | ||
220 | int i, j; | ||
221 | |||
222 | /* | ||
223 | * RSSI is not available for subframes in an A-MPDU. | ||
224 | */ | ||
225 | if (rx_stats->rs_moreaggr) { | ||
226 | rxs->flag |= RX_FLAG_NO_SIGNAL_VAL; | ||
227 | return; | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * Check if the RSSI for the last subframe in an A-MPDU | ||
232 | * or an unaggregated frame is valid. | ||
233 | */ | ||
234 | if (rx_stats->rs_rssi == ATH9K_RSSI_BAD) { | ||
235 | rxs->flag |= RX_FLAG_NO_SIGNAL_VAL; | ||
236 | return; | ||
237 | } | ||
238 | |||
239 | for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) { | ||
240 | s8 rssi; | ||
241 | |||
242 | if (!(ah->rxchainmask & BIT(i))) | ||
243 | continue; | ||
244 | |||
245 | rssi = rx_stats->rs_rssi_ctl[i]; | ||
246 | if (rssi != ATH9K_RSSI_BAD) { | ||
247 | rxs->chains |= BIT(j); | ||
248 | rxs->chain_signal[j] = ah->noise + rssi; | ||
249 | } | ||
250 | j++; | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * Update Beacon RSSI, this is used by ANI. | ||
255 | */ | ||
256 | if (rx_stats->is_mybeacon && | ||
257 | ((ah->opmode == NL80211_IFTYPE_STATION) || | ||
258 | (ah->opmode == NL80211_IFTYPE_ADHOC))) { | ||
259 | ATH_RSSI_LPF(common->last_rssi, rx_stats->rs_rssi); | ||
260 | last_rssi = common->last_rssi; | ||
261 | |||
262 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | ||
263 | rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); | ||
264 | if (rssi < 0) | ||
265 | rssi = 0; | ||
266 | |||
267 | ah->stats.avgbrssi = rssi; | ||
268 | } | ||
269 | |||
270 | rxs->signal = ah->noise + rx_stats->rs_rssi; | ||
271 | } | ||
272 | EXPORT_SYMBOL(ath9k_cmn_process_rssi); | ||
273 | |||
30 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) | 274 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) |
31 | { | 275 | { |
32 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 276 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index eb85e1bdca88..ca38116838f0 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #include "hw.h" | 21 | #include "hw.h" |
22 | #include "hw-ops.h" | 22 | #include "hw-ops.h" |
23 | 23 | ||
24 | #include "common-init.h" | ||
25 | #include "common-beacon.h" | ||
26 | |||
24 | /* Common header for Atheros 802.11n base driver cores */ | 27 | /* Common header for Atheros 802.11n base driver cores */ |
25 | 28 | ||
26 | #define WME_BA_BMP_SIZE 64 | 29 | #define WME_BA_BMP_SIZE 64 |
@@ -42,6 +45,38 @@ | |||
42 | #define ATH_EP_RND(x, mul) \ | 45 | #define ATH_EP_RND(x, mul) \ |
43 | (((x) + ((mul)/2)) / (mul)) | 46 | (((x) + ((mul)/2)) / (mul)) |
44 | 47 | ||
48 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | ||
49 | |||
50 | struct ath_beacon_config { | ||
51 | int beacon_interval; | ||
52 | u16 dtim_period; | ||
53 | u16 bmiss_timeout; | ||
54 | u8 dtim_count; | ||
55 | bool enable_beacon; | ||
56 | bool ibss_creator; | ||
57 | u32 nexttbtt; | ||
58 | u32 intval; | ||
59 | }; | ||
60 | |||
61 | bool ath9k_cmn_rx_accept(struct ath_common *common, | ||
62 | struct ieee80211_hdr *hdr, | ||
63 | struct ieee80211_rx_status *rxs, | ||
64 | struct ath_rx_status *rx_stats, | ||
65 | bool *decrypt_error, | ||
66 | unsigned int rxfilter); | ||
67 | void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | ||
68 | struct sk_buff *skb, | ||
69 | struct ath_rx_status *rx_stats, | ||
70 | struct ieee80211_rx_status *rxs, | ||
71 | bool decrypt_error); | ||
72 | int ath9k_cmn_process_rate(struct ath_common *common, | ||
73 | struct ieee80211_hw *hw, | ||
74 | struct ath_rx_status *rx_stats, | ||
75 | struct ieee80211_rx_status *rxs); | ||
76 | void ath9k_cmn_process_rssi(struct ath_common *common, | ||
77 | struct ieee80211_hw *hw, | ||
78 | struct ath_rx_status *rx_stats, | ||
79 | struct ieee80211_rx_status *rxs); | ||
45 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); | 80 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); |
46 | struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw, | 81 | struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw, |
47 | struct ath_hw *ah, | 82 | struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index ab7264c1d8f7..780ff1bee6f6 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -135,46 +135,45 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, | |||
135 | struct ath_softc *sc = file->private_data; | 135 | struct ath_softc *sc = file->private_data; |
136 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 136 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
137 | struct ath_hw *ah = sc->sc_ah; | 137 | struct ath_hw *ah = sc->sc_ah; |
138 | unsigned int len = 0, size = 1024; | 138 | unsigned int len = 0; |
139 | const unsigned int size = 1024; | ||
139 | ssize_t retval = 0; | 140 | ssize_t retval = 0; |
140 | char *buf; | 141 | char *buf; |
142 | int i; | ||
143 | struct { | ||
144 | const char *name; | ||
145 | unsigned int val; | ||
146 | } ani_info[] = { | ||
147 | { "ANI RESET", ah->stats.ast_ani_reset }, | ||
148 | { "OFDM LEVEL", ah->ani.ofdmNoiseImmunityLevel }, | ||
149 | { "CCK LEVEL", ah->ani.cckNoiseImmunityLevel }, | ||
150 | { "SPUR UP", ah->stats.ast_ani_spurup }, | ||
151 | { "SPUR DOWN", ah->stats.ast_ani_spurup }, | ||
152 | { "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon }, | ||
153 | { "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff }, | ||
154 | { "MRC-CCK ON", ah->stats.ast_ani_ccklow }, | ||
155 | { "MRC-CCK OFF", ah->stats.ast_ani_cckhigh }, | ||
156 | { "FIR-STEP UP", ah->stats.ast_ani_stepup }, | ||
157 | { "FIR-STEP DOWN", ah->stats.ast_ani_stepdown }, | ||
158 | { "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero }, | ||
159 | { "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs }, | ||
160 | { "CCK ERRORS", ah->stats.ast_ani_cckerrs }, | ||
161 | }; | ||
141 | 162 | ||
142 | buf = kzalloc(size, GFP_KERNEL); | 163 | buf = kzalloc(size, GFP_KERNEL); |
143 | if (buf == NULL) | 164 | if (buf == NULL) |
144 | return -ENOMEM; | 165 | return -ENOMEM; |
145 | 166 | ||
146 | if (common->disable_ani) { | 167 | len += scnprintf(buf + len, size - len, "%15s: %s\n", "ANI", |
147 | len += scnprintf(buf + len, size - len, "%s: %s\n", | 168 | common->disable_ani ? "DISABLED" : "ENABLED"); |
148 | "ANI", "DISABLED"); | 169 | |
170 | if (common->disable_ani) | ||
149 | goto exit; | 171 | goto exit; |
150 | } | ||
151 | 172 | ||
152 | len += scnprintf(buf + len, size - len, "%15s: %s\n", | 173 | for (i = 0; i < ARRAY_SIZE(ani_info); i++) |
153 | "ANI", "ENABLED"); | 174 | len += scnprintf(buf + len, size - len, "%15s: %u\n", |
154 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | 175 | ani_info[i].name, ani_info[i].val); |
155 | "ANI RESET", ah->stats.ast_ani_reset); | 176 | |
156 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
157 | "SPUR UP", ah->stats.ast_ani_spurup); | ||
158 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
159 | "SPUR DOWN", ah->stats.ast_ani_spurup); | ||
160 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
161 | "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon); | ||
162 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
163 | "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff); | ||
164 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
165 | "MRC-CCK ON", ah->stats.ast_ani_ccklow); | ||
166 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
167 | "MRC-CCK OFF", ah->stats.ast_ani_cckhigh); | ||
168 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
169 | "FIR-STEP UP", ah->stats.ast_ani_stepup); | ||
170 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
171 | "FIR-STEP DOWN", ah->stats.ast_ani_stepdown); | ||
172 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
173 | "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero); | ||
174 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
175 | "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs); | ||
176 | len += scnprintf(buf + len, size - len, "%15s: %u\n", | ||
177 | "CCK ERRORS", ah->stats.ast_ani_cckerrs); | ||
178 | exit: | 177 | exit: |
179 | if (len > size) | 178 | if (len > size) |
180 | len = size; | 179 | len = size; |
@@ -209,7 +208,7 @@ static ssize_t write_file_ani(struct file *file, | |||
209 | common->disable_ani = !ani; | 208 | common->disable_ani = !ani; |
210 | 209 | ||
211 | if (common->disable_ani) { | 210 | if (common->disable_ani) { |
212 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 211 | clear_bit(ATH_OP_ANI_RUN, &common->op_flags); |
213 | ath_stop_ani(sc); | 212 | ath_stop_ani(sc); |
214 | } else { | 213 | } else { |
215 | ath_check_ani(sc); | 214 | ath_check_ani(sc); |
@@ -307,13 +306,13 @@ static ssize_t read_file_antenna_diversity(struct file *file, | |||
307 | struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN]; | 306 | struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN]; |
308 | struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT]; | 307 | struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT]; |
309 | struct ath_hw_antcomb_conf div_ant_conf; | 308 | struct ath_hw_antcomb_conf div_ant_conf; |
310 | unsigned int len = 0, size = 1024; | 309 | unsigned int len = 0; |
310 | const unsigned int size = 1024; | ||
311 | ssize_t retval = 0; | 311 | ssize_t retval = 0; |
312 | char *buf; | 312 | char *buf; |
313 | char *lna_conf_str[4] = {"LNA1_MINUS_LNA2", | 313 | static const char *lna_conf_str[4] = { |
314 | "LNA2", | 314 | "LNA1_MINUS_LNA2", "LNA2", "LNA1", "LNA1_PLUS_LNA2" |
315 | "LNA1", | 315 | }; |
316 | "LNA1_PLUS_LNA2"}; | ||
317 | 316 | ||
318 | buf = kzalloc(size, GFP_KERNEL); | 317 | buf = kzalloc(size, GFP_KERNEL); |
319 | if (buf == NULL) | 318 | if (buf == NULL) |
@@ -716,10 +715,13 @@ static ssize_t read_file_queues(struct file *file, char __user *user_buf, | |||
716 | struct ath_softc *sc = file->private_data; | 715 | struct ath_softc *sc = file->private_data; |
717 | struct ath_txq *txq; | 716 | struct ath_txq *txq; |
718 | char *buf; | 717 | char *buf; |
719 | unsigned int len = 0, size = 1024; | 718 | unsigned int len = 0; |
719 | const unsigned int size = 1024; | ||
720 | ssize_t retval = 0; | 720 | ssize_t retval = 0; |
721 | int i; | 721 | int i; |
722 | char *qname[4] = {"VO", "VI", "BE", "BK"}; | 722 | static const char *qname[4] = { |
723 | "VO", "VI", "BE", "BK" | ||
724 | }; | ||
723 | 725 | ||
724 | buf = kzalloc(size, GFP_KERNEL); | 726 | buf = kzalloc(size, GFP_KERNEL); |
725 | if (buf == NULL) | 727 | if (buf == NULL) |
@@ -866,6 +868,12 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf, | |||
866 | "%17s: %2d\n", "PLL RX Hang", | 868 | "%17s: %2d\n", "PLL RX Hang", |
867 | sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); | 869 | sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); |
868 | len += scnprintf(buf + len, sizeof(buf) - len, | 870 | len += scnprintf(buf + len, sizeof(buf) - len, |
871 | "%17s: %2d\n", "MAC Hang", | ||
872 | sc->debug.stats.reset[RESET_TYPE_MAC_HANG]); | ||
873 | len += scnprintf(buf + len, sizeof(buf) - len, | ||
874 | "%17s: %2d\n", "Stuck Beacon", | ||
875 | sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]); | ||
876 | len += scnprintf(buf + len, sizeof(buf) - len, | ||
869 | "%17s: %2d\n", "MCI Reset", | 877 | "%17s: %2d\n", "MCI Reset", |
870 | sc->debug.stats.reset[RESET_TYPE_MCI]); | 878 | sc->debug.stats.reset[RESET_TYPE_MCI]); |
871 | 879 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index cc7a025d833e..559a68c2709c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -18,7 +18,6 @@ | |||
18 | #define DEBUG_H | 18 | #define DEBUG_H |
19 | 19 | ||
20 | #include "hw.h" | 20 | #include "hw.h" |
21 | #include "rc.h" | ||
22 | #include "dfs_debug.h" | 21 | #include "dfs_debug.h" |
23 | 22 | ||
24 | struct ath_txq; | 23 | struct ath_txq; |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.h b/drivers/net/wireless/ath/ath9k/dfs_debug.h index 0a7ddf4c88c9..7936c9126a20 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_debug.h +++ b/drivers/net/wireless/ath/ath9k/dfs_debug.h | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #include "hw.h" | 22 | #include "hw.h" |
23 | 23 | ||
24 | struct ath_softc; | ||
25 | |||
24 | /** | 26 | /** |
25 | * struct ath_dfs_stats - DFS Statistics per wiphy | 27 | * struct ath_dfs_stats - DFS Statistics per wiphy |
26 | * @pulses_total: pulses reported by HW | 28 | * @pulses_total: pulses reported by HW |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 6d5d716adc1b..8e7153b186ed 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -54,6 +54,8 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { | |||
54 | .driver_info = AR9280_USB }, /* SMC Networks */ | 54 | .driver_info = AR9280_USB }, /* SMC Networks */ |
55 | { USB_DEVICE(0x0411, 0x017f), | 55 | { USB_DEVICE(0x0411, 0x017f), |
56 | .driver_info = AR9280_USB }, /* Sony UWA-BR100 */ | 56 | .driver_info = AR9280_USB }, /* Sony UWA-BR100 */ |
57 | { USB_DEVICE(0x0411, 0x0197), | ||
58 | .driver_info = AR9280_USB }, /* Buffalo WLI-UV-AG300P */ | ||
57 | { USB_DEVICE(0x04da, 0x3904), | 59 | { USB_DEVICE(0x04da, 0x3904), |
58 | .driver_info = AR9280_USB }, | 60 | .driver_info = AR9280_USB }, |
59 | 61 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 99a203174f45..dab1f0cab993 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -39,7 +39,6 @@ | |||
39 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | 39 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ |
40 | 40 | ||
41 | #define ATH_DEFAULT_BMISS_LIMIT 10 | 41 | #define ATH_DEFAULT_BMISS_LIMIT 10 |
42 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | ||
43 | #define TSF_TO_TU(_h, _l) \ | 42 | #define TSF_TO_TU(_h, _l) \ |
44 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) | 43 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) |
45 | 44 | ||
@@ -277,7 +276,6 @@ struct ath9k_htc_rxbuf { | |||
277 | }; | 276 | }; |
278 | 277 | ||
279 | struct ath9k_htc_rx { | 278 | struct ath9k_htc_rx { |
280 | int last_rssi; /* FIXME: per-STA */ | ||
281 | struct list_head rxbuf; | 279 | struct list_head rxbuf; |
282 | spinlock_t rxbuflock; | 280 | spinlock_t rxbuflock; |
283 | }; | 281 | }; |
@@ -407,12 +405,18 @@ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | |||
407 | #define DEFAULT_SWBA_RESPONSE 40 /* in TUs */ | 405 | #define DEFAULT_SWBA_RESPONSE 40 /* in TUs */ |
408 | #define MIN_SWBA_RESPONSE 10 /* in TUs */ | 406 | #define MIN_SWBA_RESPONSE 10 /* in TUs */ |
409 | 407 | ||
410 | struct htc_beacon_config { | 408 | struct htc_beacon { |
409 | enum { | ||
410 | OK, /* no change needed */ | ||
411 | UPDATE, /* update pending */ | ||
412 | COMMIT /* beacon sent, commit change */ | ||
413 | } updateslot; /* slot time update fsm */ | ||
414 | |||
411 | struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; | 415 | struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; |
412 | u16 beacon_interval; | 416 | u32 bmisscnt; |
413 | u16 dtim_period; | 417 | u32 beaconq; |
414 | u16 bmiss_timeout; | 418 | int slottime; |
415 | u32 bmiss_cnt; | 419 | int slotupdate; |
416 | }; | 420 | }; |
417 | 421 | ||
418 | struct ath_btcoex { | 422 | struct ath_btcoex { |
@@ -440,12 +444,8 @@ static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv) | |||
440 | } | 444 | } |
441 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 445 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
442 | 446 | ||
443 | #define OP_INVALID BIT(0) | ||
444 | #define OP_SCANNING BIT(1) | ||
445 | #define OP_ENABLE_BEACON BIT(2) | ||
446 | #define OP_BT_PRIORITY_DETECTED BIT(3) | 447 | #define OP_BT_PRIORITY_DETECTED BIT(3) |
447 | #define OP_BT_SCAN BIT(4) | 448 | #define OP_BT_SCAN BIT(4) |
448 | #define OP_ANI_RUNNING BIT(5) | ||
449 | #define OP_TSF_RESET BIT(6) | 449 | #define OP_TSF_RESET BIT(6) |
450 | 450 | ||
451 | struct ath9k_htc_priv { | 451 | struct ath9k_htc_priv { |
@@ -488,10 +488,10 @@ struct ath9k_htc_priv { | |||
488 | unsigned long op_flags; | 488 | unsigned long op_flags; |
489 | 489 | ||
490 | struct ath9k_hw_cal_data caldata; | 490 | struct ath9k_hw_cal_data caldata; |
491 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
492 | 491 | ||
493 | spinlock_t beacon_lock; | 492 | spinlock_t beacon_lock; |
494 | struct htc_beacon_config cur_beacon_conf; | 493 | struct ath_beacon_config cur_beacon_conf; |
494 | struct htc_beacon beacon; | ||
495 | 495 | ||
496 | struct ath9k_htc_rx rx; | 496 | struct ath9k_htc_rx rx; |
497 | struct ath9k_htc_tx tx; | 497 | struct ath9k_htc_tx tx; |
@@ -516,7 +516,6 @@ struct ath9k_htc_priv { | |||
516 | struct work_struct led_work; | 516 | struct work_struct led_work; |
517 | #endif | 517 | #endif |
518 | 518 | ||
519 | int beaconq; | ||
520 | int cabq; | 519 | int cabq; |
521 | int hwq_map[IEEE80211_NUM_ACS]; | 520 | int hwq_map[IEEE80211_NUM_ACS]; |
522 | 521 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 8b5757734596..e8b6ec3c1dbb 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -26,7 +26,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | |||
26 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | 26 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); |
27 | memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); | 27 | memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); |
28 | 28 | ||
29 | ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); | 29 | ath9k_hw_get_txq_props(ah, priv->beacon.beaconq, &qi); |
30 | 30 | ||
31 | if (priv->ah->opmode == NL80211_IFTYPE_AP || | 31 | if (priv->ah->opmode == NL80211_IFTYPE_AP || |
32 | priv->ah->opmode == NL80211_IFTYPE_MESH_POINT) { | 32 | priv->ah->opmode == NL80211_IFTYPE_MESH_POINT) { |
@@ -54,220 +54,78 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | |||
54 | 54 | ||
55 | } | 55 | } |
56 | 56 | ||
57 | if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { | 57 | if (!ath9k_hw_set_txq_props(ah, priv->beacon.beaconq, &qi)) { |
58 | ath_err(ath9k_hw_common(ah), | 58 | ath_err(ath9k_hw_common(ah), |
59 | "Unable to update beacon queue %u!\n", priv->beaconq); | 59 | "Unable to update beacon queue %u!\n", priv->beacon.beaconq); |
60 | } else { | 60 | } else { |
61 | ath9k_hw_resettxqueue(ah, priv->beaconq); | 61 | ath9k_hw_resettxqueue(ah, priv->beacon.beaconq); |
62 | } | 62 | } |
63 | } | 63 | } |
64 | 64 | ||
65 | 65 | /* | |
66 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | 66 | * Both nexttbtt and intval have to be in usecs. |
67 | struct htc_beacon_config *bss_conf) | 67 | */ |
68 | static void ath9k_htc_beacon_init(struct ath9k_htc_priv *priv, | ||
69 | struct ath_beacon_config *conf, | ||
70 | bool reset_tsf) | ||
68 | { | 71 | { |
69 | struct ath_common *common = ath9k_hw_common(priv->ah); | 72 | struct ath_hw *ah = priv->ah; |
70 | struct ath9k_beacon_state bs; | ||
71 | enum ath9k_int imask = 0; | ||
72 | int dtimperiod, dtimcount, sleepduration; | ||
73 | int bmiss_timeout; | ||
74 | u32 nexttbtt = 0, intval, tsftu; | ||
75 | __be32 htc_imask = 0; | ||
76 | u64 tsf; | ||
77 | int num_beacons, offset, dtim_dec_count; | ||
78 | int ret __attribute__ ((unused)); | 73 | int ret __attribute__ ((unused)); |
74 | __be32 htc_imask = 0; | ||
79 | u8 cmd_rsp; | 75 | u8 cmd_rsp; |
80 | 76 | ||
81 | memset(&bs, 0, sizeof(bs)); | 77 | if (conf->intval >= TU_TO_USEC(DEFAULT_SWBA_RESPONSE)) |
82 | 78 | ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | |
83 | intval = bss_conf->beacon_interval; | 79 | else |
84 | bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval); | 80 | ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; |
85 | |||
86 | /* | ||
87 | * Setup dtim parameters according to | ||
88 | * last beacon we received (which may be none). | ||
89 | */ | ||
90 | dtimperiod = bss_conf->dtim_period; | ||
91 | if (dtimperiod <= 0) /* NB: 0 if not known */ | ||
92 | dtimperiod = 1; | ||
93 | dtimcount = 1; | ||
94 | if (dtimcount >= dtimperiod) /* NB: sanity check */ | ||
95 | dtimcount = 0; | ||
96 | |||
97 | sleepduration = intval; | ||
98 | if (sleepduration <= 0) | ||
99 | sleepduration = intval; | ||
100 | |||
101 | /* | ||
102 | * Pull nexttbtt forward to reflect the current | ||
103 | * TSF and calculate dtim state for the result. | ||
104 | */ | ||
105 | tsf = ath9k_hw_gettsf64(priv->ah); | ||
106 | tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; | ||
107 | |||
108 | num_beacons = tsftu / intval + 1; | ||
109 | offset = tsftu % intval; | ||
110 | nexttbtt = tsftu - offset; | ||
111 | if (offset) | ||
112 | nexttbtt += intval; | ||
113 | |||
114 | /* DTIM Beacon every dtimperiod Beacon */ | ||
115 | dtim_dec_count = num_beacons % dtimperiod; | ||
116 | dtimcount -= dtim_dec_count; | ||
117 | if (dtimcount < 0) | ||
118 | dtimcount += dtimperiod; | ||
119 | |||
120 | bs.bs_intval = TU_TO_USEC(intval); | ||
121 | bs.bs_nexttbtt = TU_TO_USEC(nexttbtt); | ||
122 | bs.bs_dtimperiod = dtimperiod * bs.bs_intval; | ||
123 | bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount * bs.bs_intval; | ||
124 | |||
125 | /* | ||
126 | * Calculate the number of consecutive beacons to miss* before taking | ||
127 | * a BMISS interrupt. The configuration is specified in TU so we only | ||
128 | * need calculate based on the beacon interval. Note that we clamp the | ||
129 | * result to at most 15 beacons. | ||
130 | */ | ||
131 | if (sleepduration > intval) { | ||
132 | bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2; | ||
133 | } else { | ||
134 | bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval); | ||
135 | if (bs.bs_bmissthreshold > 15) | ||
136 | bs.bs_bmissthreshold = 15; | ||
137 | else if (bs.bs_bmissthreshold <= 0) | ||
138 | bs.bs_bmissthreshold = 1; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * Calculate sleep duration. The configuration is given in ms. | ||
143 | * We ensure a multiple of the beacon period is used. Also, if the sleep | ||
144 | * duration is greater than the DTIM period then it makes senses | ||
145 | * to make it a multiple of that. | ||
146 | * | ||
147 | * XXX fixed at 100ms | ||
148 | */ | ||
149 | |||
150 | bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100), | ||
151 | sleepduration)); | ||
152 | if (bs.bs_sleepduration > bs.bs_dtimperiod) | ||
153 | bs.bs_sleepduration = bs.bs_dtimperiod; | ||
154 | |||
155 | /* TSF out of range threshold fixed at 1 second */ | ||
156 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | ||
157 | |||
158 | ath_dbg(common, CONFIG, "intval: %u tsf: %llu tsftu: %u\n", | ||
159 | intval, tsf, tsftu); | ||
160 | ath_dbg(common, CONFIG, "bmiss: %u sleep: %u\n", | ||
161 | bs.bs_bmissthreshold, bs.bs_sleepduration); | ||
162 | |||
163 | /* Set the computed STA beacon timers */ | ||
164 | 81 | ||
165 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 82 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
166 | ath9k_hw_set_sta_beacon_timers(priv->ah, &bs); | 83 | if (reset_tsf) |
167 | imask |= ATH9K_INT_BMISS; | 84 | ath9k_hw_reset_tsf(ah); |
168 | htc_imask = cpu_to_be32(imask); | 85 | ath9k_htc_beaconq_config(priv); |
86 | ath9k_hw_beaconinit(ah, conf->nexttbtt, conf->intval); | ||
87 | priv->beacon.bmisscnt = 0; | ||
88 | htc_imask = cpu_to_be32(ah->imask); | ||
169 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 89 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
170 | } | 90 | } |
171 | 91 | ||
172 | static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | 92 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, |
173 | struct htc_beacon_config *bss_conf) | 93 | struct ath_beacon_config *bss_conf) |
174 | { | 94 | { |
175 | struct ath_common *common = ath9k_hw_common(priv->ah); | 95 | struct ath9k_beacon_state bs; |
176 | enum ath9k_int imask = 0; | 96 | enum ath9k_int imask = 0; |
177 | u32 nexttbtt, intval, tsftu; | ||
178 | __be32 htc_imask = 0; | 97 | __be32 htc_imask = 0; |
179 | int ret __attribute__ ((unused)); | 98 | int ret __attribute__ ((unused)); |
180 | u8 cmd_rsp; | 99 | u8 cmd_rsp; |
181 | u64 tsf; | ||
182 | 100 | ||
183 | intval = bss_conf->beacon_interval; | 101 | if (ath9k_cmn_beacon_config_sta(priv->ah, bss_conf, &bs) == -EPERM) |
184 | intval /= ATH9K_HTC_MAX_BCN_VIF; | 102 | return; |
185 | nexttbtt = intval; | ||
186 | |||
187 | /* | ||
188 | * To reduce beacon misses under heavy TX load, | ||
189 | * set the beacon response time to a larger value. | ||
190 | */ | ||
191 | if (intval > DEFAULT_SWBA_RESPONSE) | ||
192 | priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | ||
193 | else | ||
194 | priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; | ||
195 | |||
196 | if (test_bit(OP_TSF_RESET, &priv->op_flags)) { | ||
197 | ath9k_hw_reset_tsf(priv->ah); | ||
198 | clear_bit(OP_TSF_RESET, &priv->op_flags); | ||
199 | } else { | ||
200 | /* | ||
201 | * Pull nexttbtt forward to reflect the current TSF. | ||
202 | */ | ||
203 | tsf = ath9k_hw_gettsf64(priv->ah); | ||
204 | tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE; | ||
205 | do { | ||
206 | nexttbtt += intval; | ||
207 | } while (nexttbtt < tsftu); | ||
208 | } | ||
209 | |||
210 | if (test_bit(OP_ENABLE_BEACON, &priv->op_flags)) | ||
211 | imask |= ATH9K_INT_SWBA; | ||
212 | |||
213 | ath_dbg(common, CONFIG, | ||
214 | "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d imask: 0x%x\n", | ||
215 | bss_conf->beacon_interval, nexttbtt, | ||
216 | priv->ah->config.sw_beacon_response_time, imask); | ||
217 | |||
218 | ath9k_htc_beaconq_config(priv); | ||
219 | 103 | ||
220 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 104 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
221 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); | 105 | ath9k_hw_set_sta_beacon_timers(priv->ah, &bs); |
222 | priv->cur_beacon_conf.bmiss_cnt = 0; | 106 | imask |= ATH9K_INT_BMISS; |
223 | htc_imask = cpu_to_be32(imask); | 107 | htc_imask = cpu_to_be32(imask); |
224 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 108 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
225 | } | 109 | } |
226 | 110 | ||
227 | static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | 111 | static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, |
228 | struct htc_beacon_config *bss_conf) | 112 | struct ath_beacon_config *conf) |
229 | { | 113 | { |
230 | struct ath_common *common = ath9k_hw_common(priv->ah); | 114 | struct ath_hw *ah = priv->ah; |
231 | enum ath9k_int imask = 0; | 115 | ah->imask = 0; |
232 | u32 nexttbtt, intval, tsftu; | ||
233 | __be32 htc_imask = 0; | ||
234 | int ret __attribute__ ((unused)); | ||
235 | u8 cmd_rsp; | ||
236 | u64 tsf; | ||
237 | |||
238 | intval = bss_conf->beacon_interval; | ||
239 | nexttbtt = intval; | ||
240 | |||
241 | /* | ||
242 | * Pull nexttbtt forward to reflect the current TSF. | ||
243 | */ | ||
244 | tsf = ath9k_hw_gettsf64(priv->ah); | ||
245 | tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE; | ||
246 | do { | ||
247 | nexttbtt += intval; | ||
248 | } while (nexttbtt < tsftu); | ||
249 | |||
250 | /* | ||
251 | * Only one IBSS interfce is allowed. | ||
252 | */ | ||
253 | if (intval > DEFAULT_SWBA_RESPONSE) | ||
254 | priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | ||
255 | else | ||
256 | priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; | ||
257 | 116 | ||
258 | if (test_bit(OP_ENABLE_BEACON, &priv->op_flags)) | 117 | ath9k_cmn_beacon_config_ap(ah, conf, ATH9K_HTC_MAX_BCN_VIF); |
259 | imask |= ATH9K_INT_SWBA; | 118 | ath9k_htc_beacon_init(priv, conf, false); |
119 | } | ||
260 | 120 | ||
261 | ath_dbg(common, CONFIG, | 121 | static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, |
262 | "IBSS Beacon config, intval: %d, nexttbtt: %u, resp_time: %d, imask: 0x%x\n", | 122 | struct ath_beacon_config *conf) |
263 | bss_conf->beacon_interval, nexttbtt, | 123 | { |
264 | priv->ah->config.sw_beacon_response_time, imask); | 124 | struct ath_hw *ah = priv->ah; |
125 | ah->imask = 0; | ||
265 | 126 | ||
266 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 127 | ath9k_cmn_beacon_config_adhoc(ah, conf); |
267 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); | 128 | ath9k_htc_beacon_init(priv, conf, conf->ibss_creator); |
268 | priv->cur_beacon_conf.bmiss_cnt = 0; | ||
269 | htc_imask = cpu_to_be32(imask); | ||
270 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | ||
271 | } | 129 | } |
272 | 130 | ||
273 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | 131 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, |
@@ -287,7 +145,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, | |||
287 | 145 | ||
288 | spin_lock_bh(&priv->beacon_lock); | 146 | spin_lock_bh(&priv->beacon_lock); |
289 | 147 | ||
290 | vif = priv->cur_beacon_conf.bslot[slot]; | 148 | vif = priv->beacon.bslot[slot]; |
291 | 149 | ||
292 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | 150 | skb = ieee80211_get_buffered_bc(priv->hw, vif); |
293 | 151 | ||
@@ -348,10 +206,10 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, | |||
348 | 206 | ||
349 | spin_lock_bh(&priv->beacon_lock); | 207 | spin_lock_bh(&priv->beacon_lock); |
350 | 208 | ||
351 | vif = priv->cur_beacon_conf.bslot[slot]; | 209 | vif = priv->beacon.bslot[slot]; |
352 | avp = (struct ath9k_htc_vif *)vif->drv_priv; | 210 | avp = (struct ath9k_htc_vif *)vif->drv_priv; |
353 | 211 | ||
354 | if (unlikely(test_bit(OP_SCANNING, &priv->op_flags))) { | 212 | if (unlikely(test_bit(ATH_OP_SCANNING, &common->op_flags))) { |
355 | spin_unlock_bh(&priv->beacon_lock); | 213 | spin_unlock_bh(&priv->beacon_lock); |
356 | return; | 214 | return; |
357 | } | 215 | } |
@@ -431,8 +289,8 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, | |||
431 | int slot; | 289 | int slot; |
432 | 290 | ||
433 | if (swba->beacon_pending != 0) { | 291 | if (swba->beacon_pending != 0) { |
434 | priv->cur_beacon_conf.bmiss_cnt++; | 292 | priv->beacon.bmisscnt++; |
435 | if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { | 293 | if (priv->beacon.bmisscnt > BSTUCK_THRESHOLD) { |
436 | ath_dbg(common, BSTUCK, "Beacon stuck, HW reset\n"); | 294 | ath_dbg(common, BSTUCK, "Beacon stuck, HW reset\n"); |
437 | ieee80211_queue_work(priv->hw, | 295 | ieee80211_queue_work(priv->hw, |
438 | &priv->fatal_work); | 296 | &priv->fatal_work); |
@@ -440,16 +298,16 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, | |||
440 | return; | 298 | return; |
441 | } | 299 | } |
442 | 300 | ||
443 | if (priv->cur_beacon_conf.bmiss_cnt) { | 301 | if (priv->beacon.bmisscnt) { |
444 | ath_dbg(common, BSTUCK, | 302 | ath_dbg(common, BSTUCK, |
445 | "Resuming beacon xmit after %u misses\n", | 303 | "Resuming beacon xmit after %u misses\n", |
446 | priv->cur_beacon_conf.bmiss_cnt); | 304 | priv->beacon.bmisscnt); |
447 | priv->cur_beacon_conf.bmiss_cnt = 0; | 305 | priv->beacon.bmisscnt = 0; |
448 | } | 306 | } |
449 | 307 | ||
450 | slot = ath9k_htc_choose_bslot(priv, swba); | 308 | slot = ath9k_htc_choose_bslot(priv, swba); |
451 | spin_lock_bh(&priv->beacon_lock); | 309 | spin_lock_bh(&priv->beacon_lock); |
452 | if (priv->cur_beacon_conf.bslot[slot] == NULL) { | 310 | if (priv->beacon.bslot[slot] == NULL) { |
453 | spin_unlock_bh(&priv->beacon_lock); | 311 | spin_unlock_bh(&priv->beacon_lock); |
454 | return; | 312 | return; |
455 | } | 313 | } |
@@ -468,13 +326,13 @@ void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, | |||
468 | 326 | ||
469 | spin_lock_bh(&priv->beacon_lock); | 327 | spin_lock_bh(&priv->beacon_lock); |
470 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) { | 328 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) { |
471 | if (priv->cur_beacon_conf.bslot[i] == NULL) { | 329 | if (priv->beacon.bslot[i] == NULL) { |
472 | avp->bslot = i; | 330 | avp->bslot = i; |
473 | break; | 331 | break; |
474 | } | 332 | } |
475 | } | 333 | } |
476 | 334 | ||
477 | priv->cur_beacon_conf.bslot[avp->bslot] = vif; | 335 | priv->beacon.bslot[avp->bslot] = vif; |
478 | spin_unlock_bh(&priv->beacon_lock); | 336 | spin_unlock_bh(&priv->beacon_lock); |
479 | 337 | ||
480 | ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", | 338 | ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", |
@@ -488,7 +346,7 @@ void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | |||
488 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | 346 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; |
489 | 347 | ||
490 | spin_lock_bh(&priv->beacon_lock); | 348 | spin_lock_bh(&priv->beacon_lock); |
491 | priv->cur_beacon_conf.bslot[avp->bslot] = NULL; | 349 | priv->beacon.bslot[avp->bslot] = NULL; |
492 | spin_unlock_bh(&priv->beacon_lock); | 350 | spin_unlock_bh(&priv->beacon_lock); |
493 | 351 | ||
494 | ath_dbg(common, CONFIG, "Removed interface at beacon slot: %d\n", | 352 | ath_dbg(common, CONFIG, "Removed interface at beacon slot: %d\n", |
@@ -504,7 +362,7 @@ void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, | |||
504 | { | 362 | { |
505 | struct ath_common *common = ath9k_hw_common(priv->ah); | 363 | struct ath_common *common = ath9k_hw_common(priv->ah); |
506 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | 364 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; |
507 | struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; | 365 | struct ath_beacon_config *cur_conf = &priv->cur_beacon_conf; |
508 | u64 tsfadjust; | 366 | u64 tsfadjust; |
509 | 367 | ||
510 | if (avp->bslot == 0) | 368 | if (avp->bslot == 0) |
@@ -536,7 +394,7 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv, | |||
536 | struct ieee80211_vif *vif) | 394 | struct ieee80211_vif *vif) |
537 | { | 395 | { |
538 | struct ath_common *common = ath9k_hw_common(priv->ah); | 396 | struct ath_common *common = ath9k_hw_common(priv->ah); |
539 | struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; | 397 | struct ath_beacon_config *cur_conf = &priv->cur_beacon_conf; |
540 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 398 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
541 | bool beacon_configured; | 399 | bool beacon_configured; |
542 | 400 | ||
@@ -591,7 +449,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | |||
591 | struct ieee80211_vif *vif) | 449 | struct ieee80211_vif *vif) |
592 | { | 450 | { |
593 | struct ath_common *common = ath9k_hw_common(priv->ah); | 451 | struct ath_common *common = ath9k_hw_common(priv->ah); |
594 | struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; | 452 | struct ath_beacon_config *cur_conf = &priv->cur_beacon_conf; |
595 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 453 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
596 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv; | 454 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv; |
597 | 455 | ||
@@ -627,7 +485,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | |||
627 | void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv) | 485 | void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv) |
628 | { | 486 | { |
629 | struct ath_common *common = ath9k_hw_common(priv->ah); | 487 | struct ath_common *common = ath9k_hw_common(priv->ah); |
630 | struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; | 488 | struct ath_beacon_config *cur_conf = &priv->cur_beacon_conf; |
631 | 489 | ||
632 | switch (priv->ah->opmode) { | 490 | switch (priv->ah->opmode) { |
633 | case NL80211_IFTYPE_STATION: | 491 | case NL80211_IFTYPE_STATION: |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index c57d6b859c04..8a3bd5fe3a54 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -38,93 +38,6 @@ static int ath9k_ps_enable; | |||
38 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | 38 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); |
39 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | 39 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); |
40 | 40 | ||
41 | #define CHAN2G(_freq, _idx) { \ | ||
42 | .center_freq = (_freq), \ | ||
43 | .hw_value = (_idx), \ | ||
44 | .max_power = 20, \ | ||
45 | } | ||
46 | |||
47 | #define CHAN5G(_freq, _idx) { \ | ||
48 | .band = IEEE80211_BAND_5GHZ, \ | ||
49 | .center_freq = (_freq), \ | ||
50 | .hw_value = (_idx), \ | ||
51 | .max_power = 20, \ | ||
52 | } | ||
53 | |||
54 | static struct ieee80211_channel ath9k_2ghz_channels[] = { | ||
55 | CHAN2G(2412, 0), /* Channel 1 */ | ||
56 | CHAN2G(2417, 1), /* Channel 2 */ | ||
57 | CHAN2G(2422, 2), /* Channel 3 */ | ||
58 | CHAN2G(2427, 3), /* Channel 4 */ | ||
59 | CHAN2G(2432, 4), /* Channel 5 */ | ||
60 | CHAN2G(2437, 5), /* Channel 6 */ | ||
61 | CHAN2G(2442, 6), /* Channel 7 */ | ||
62 | CHAN2G(2447, 7), /* Channel 8 */ | ||
63 | CHAN2G(2452, 8), /* Channel 9 */ | ||
64 | CHAN2G(2457, 9), /* Channel 10 */ | ||
65 | CHAN2G(2462, 10), /* Channel 11 */ | ||
66 | CHAN2G(2467, 11), /* Channel 12 */ | ||
67 | CHAN2G(2472, 12), /* Channel 13 */ | ||
68 | CHAN2G(2484, 13), /* Channel 14 */ | ||
69 | }; | ||
70 | |||
71 | static struct ieee80211_channel ath9k_5ghz_channels[] = { | ||
72 | /* _We_ call this UNII 1 */ | ||
73 | CHAN5G(5180, 14), /* Channel 36 */ | ||
74 | CHAN5G(5200, 15), /* Channel 40 */ | ||
75 | CHAN5G(5220, 16), /* Channel 44 */ | ||
76 | CHAN5G(5240, 17), /* Channel 48 */ | ||
77 | /* _We_ call this UNII 2 */ | ||
78 | CHAN5G(5260, 18), /* Channel 52 */ | ||
79 | CHAN5G(5280, 19), /* Channel 56 */ | ||
80 | CHAN5G(5300, 20), /* Channel 60 */ | ||
81 | CHAN5G(5320, 21), /* Channel 64 */ | ||
82 | /* _We_ call this "Middle band" */ | ||
83 | CHAN5G(5500, 22), /* Channel 100 */ | ||
84 | CHAN5G(5520, 23), /* Channel 104 */ | ||
85 | CHAN5G(5540, 24), /* Channel 108 */ | ||
86 | CHAN5G(5560, 25), /* Channel 112 */ | ||
87 | CHAN5G(5580, 26), /* Channel 116 */ | ||
88 | CHAN5G(5600, 27), /* Channel 120 */ | ||
89 | CHAN5G(5620, 28), /* Channel 124 */ | ||
90 | CHAN5G(5640, 29), /* Channel 128 */ | ||
91 | CHAN5G(5660, 30), /* Channel 132 */ | ||
92 | CHAN5G(5680, 31), /* Channel 136 */ | ||
93 | CHAN5G(5700, 32), /* Channel 140 */ | ||
94 | /* _We_ call this UNII 3 */ | ||
95 | CHAN5G(5745, 33), /* Channel 149 */ | ||
96 | CHAN5G(5765, 34), /* Channel 153 */ | ||
97 | CHAN5G(5785, 35), /* Channel 157 */ | ||
98 | CHAN5G(5805, 36), /* Channel 161 */ | ||
99 | CHAN5G(5825, 37), /* Channel 165 */ | ||
100 | }; | ||
101 | |||
102 | /* Atheros hardware rate code addition for short premble */ | ||
103 | #define SHPCHECK(__hw_rate, __flags) \ | ||
104 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0) | ||
105 | |||
106 | #define RATE(_bitrate, _hw_rate, _flags) { \ | ||
107 | .bitrate = (_bitrate), \ | ||
108 | .flags = (_flags), \ | ||
109 | .hw_value = (_hw_rate), \ | ||
110 | .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ | ||
111 | } | ||
112 | |||
113 | static struct ieee80211_rate ath9k_legacy_rates[] = { | ||
114 | RATE(10, 0x1b, 0), | ||
115 | RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */ | ||
116 | RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */ | ||
117 | RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */ | ||
118 | RATE(60, 0x0b, 0), | ||
119 | RATE(90, 0x0f, 0), | ||
120 | RATE(120, 0x0a, 0), | ||
121 | RATE(180, 0x0e, 0), | ||
122 | RATE(240, 0x09, 0), | ||
123 | RATE(360, 0x0d, 0), | ||
124 | RATE(480, 0x08, 0), | ||
125 | RATE(540, 0x0c, 0), | ||
126 | }; | ||
127 | |||
128 | #ifdef CONFIG_MAC80211_LEDS | 41 | #ifdef CONFIG_MAC80211_LEDS |
129 | static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { | 42 | static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { |
130 | { .throughput = 0 * 1024, .blink_time = 334 }, | 43 | { .throughput = 0 * 1024, .blink_time = 334 }, |
@@ -343,6 +256,25 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr, | |||
343 | } | 256 | } |
344 | } | 257 | } |
345 | 258 | ||
259 | static void ath9k_regwrite_multi(struct ath_common *common) | ||
260 | { | ||
261 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
262 | u32 rsp_status; | ||
263 | int r; | ||
264 | |||
265 | r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID, | ||
266 | (u8 *) &priv->wmi->multi_write, | ||
267 | sizeof(struct register_write) * priv->wmi->multi_write_idx, | ||
268 | (u8 *) &rsp_status, sizeof(rsp_status), | ||
269 | 100); | ||
270 | if (unlikely(r)) { | ||
271 | ath_dbg(common, WMI, | ||
272 | "REGISTER WRITE FAILED, multi len: %d\n", | ||
273 | priv->wmi->multi_write_idx); | ||
274 | } | ||
275 | priv->wmi->multi_write_idx = 0; | ||
276 | } | ||
277 | |||
346 | static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) | 278 | static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) |
347 | { | 279 | { |
348 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | 280 | struct ath_hw *ah = (struct ath_hw *) hw_priv; |
@@ -369,8 +301,6 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset) | |||
369 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | 301 | struct ath_hw *ah = (struct ath_hw *) hw_priv; |
370 | struct ath_common *common = ath9k_hw_common(ah); | 302 | struct ath_common *common = ath9k_hw_common(ah); |
371 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | 303 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; |
372 | u32 rsp_status; | ||
373 | int r; | ||
374 | 304 | ||
375 | mutex_lock(&priv->wmi->multi_write_mutex); | 305 | mutex_lock(&priv->wmi->multi_write_mutex); |
376 | 306 | ||
@@ -383,19 +313,8 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset) | |||
383 | priv->wmi->multi_write_idx++; | 313 | priv->wmi->multi_write_idx++; |
384 | 314 | ||
385 | /* If the buffer is full, send it out. */ | 315 | /* If the buffer is full, send it out. */ |
386 | if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER) { | 316 | if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER) |
387 | r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID, | 317 | ath9k_regwrite_multi(common); |
388 | (u8 *) &priv->wmi->multi_write, | ||
389 | sizeof(struct register_write) * priv->wmi->multi_write_idx, | ||
390 | (u8 *) &rsp_status, sizeof(rsp_status), | ||
391 | 100); | ||
392 | if (unlikely(r)) { | ||
393 | ath_dbg(common, WMI, | ||
394 | "REGISTER WRITE FAILED, multi len: %d\n", | ||
395 | priv->wmi->multi_write_idx); | ||
396 | } | ||
397 | priv->wmi->multi_write_idx = 0; | ||
398 | } | ||
399 | 318 | ||
400 | mutex_unlock(&priv->wmi->multi_write_mutex); | 319 | mutex_unlock(&priv->wmi->multi_write_mutex); |
401 | } | 320 | } |
@@ -426,26 +345,13 @@ static void ath9k_regwrite_flush(void *hw_priv) | |||
426 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | 345 | struct ath_hw *ah = (struct ath_hw *) hw_priv; |
427 | struct ath_common *common = ath9k_hw_common(ah); | 346 | struct ath_common *common = ath9k_hw_common(ah); |
428 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | 347 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; |
429 | u32 rsp_status; | ||
430 | int r; | ||
431 | 348 | ||
432 | atomic_dec(&priv->wmi->mwrite_cnt); | 349 | atomic_dec(&priv->wmi->mwrite_cnt); |
433 | 350 | ||
434 | mutex_lock(&priv->wmi->multi_write_mutex); | 351 | mutex_lock(&priv->wmi->multi_write_mutex); |
435 | 352 | ||
436 | if (priv->wmi->multi_write_idx) { | 353 | if (priv->wmi->multi_write_idx) |
437 | r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID, | 354 | ath9k_regwrite_multi(common); |
438 | (u8 *) &priv->wmi->multi_write, | ||
439 | sizeof(struct register_write) * priv->wmi->multi_write_idx, | ||
440 | (u8 *) &rsp_status, sizeof(rsp_status), | ||
441 | 100); | ||
442 | if (unlikely(r)) { | ||
443 | ath_dbg(common, WMI, | ||
444 | "REGISTER WRITE FAILED, multi len: %d\n", | ||
445 | priv->wmi->multi_write_idx); | ||
446 | } | ||
447 | priv->wmi->multi_write_idx = 0; | ||
448 | } | ||
449 | 355 | ||
450 | mutex_unlock(&priv->wmi->multi_write_mutex); | 356 | mutex_unlock(&priv->wmi->multi_write_mutex); |
451 | } | 357 | } |
@@ -491,51 +397,6 @@ static const struct ath_bus_ops ath9k_usb_bus_ops = { | |||
491 | .eeprom_read = ath_usb_eeprom_read, | 397 | .eeprom_read = ath_usb_eeprom_read, |
492 | }; | 398 | }; |
493 | 399 | ||
494 | static void setup_ht_cap(struct ath9k_htc_priv *priv, | ||
495 | struct ieee80211_sta_ht_cap *ht_info) | ||
496 | { | ||
497 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
498 | u8 tx_streams, rx_streams; | ||
499 | int i; | ||
500 | |||
501 | ht_info->ht_supported = true; | ||
502 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
503 | IEEE80211_HT_CAP_SM_PS | | ||
504 | IEEE80211_HT_CAP_SGI_40 | | ||
505 | IEEE80211_HT_CAP_DSSSCCK40; | ||
506 | |||
507 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) | ||
508 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
509 | |||
510 | ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); | ||
511 | |||
512 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
513 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
514 | |||
515 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
516 | |||
517 | /* ath9k_htc supports only 1 or 2 stream devices */ | ||
518 | tx_streams = ath9k_cmn_count_streams(priv->ah->txchainmask, 2); | ||
519 | rx_streams = ath9k_cmn_count_streams(priv->ah->rxchainmask, 2); | ||
520 | |||
521 | ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n", | ||
522 | tx_streams, rx_streams); | ||
523 | |||
524 | if (tx_streams >= 2) | ||
525 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; | ||
526 | |||
527 | if (tx_streams != rx_streams) { | ||
528 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
529 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | ||
530 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
531 | } | ||
532 | |||
533 | for (i = 0; i < rx_streams; i++) | ||
534 | ht_info->mcs.rx_mask[i] = 0xff; | ||
535 | |||
536 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
537 | } | ||
538 | |||
539 | static int ath9k_init_queues(struct ath9k_htc_priv *priv) | 400 | static int ath9k_init_queues(struct ath9k_htc_priv *priv) |
540 | { | 401 | { |
541 | struct ath_common *common = ath9k_hw_common(priv->ah); | 402 | struct ath_common *common = ath9k_hw_common(priv->ah); |
@@ -544,8 +405,8 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv) | |||
544 | for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++) | 405 | for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++) |
545 | priv->hwq_map[i] = -1; | 406 | priv->hwq_map[i] = -1; |
546 | 407 | ||
547 | priv->beaconq = ath9k_hw_beaconq_setup(priv->ah); | 408 | priv->beacon.beaconq = ath9k_hw_beaconq_setup(priv->ah); |
548 | if (priv->beaconq == -1) { | 409 | if (priv->beacon.beaconq == -1) { |
549 | ath_err(common, "Unable to setup BEACON xmit queue\n"); | 410 | ath_err(common, "Unable to setup BEACON xmit queue\n"); |
550 | goto err; | 411 | goto err; |
551 | } | 412 | } |
@@ -580,37 +441,13 @@ err: | |||
580 | return -EINVAL; | 441 | return -EINVAL; |
581 | } | 442 | } |
582 | 443 | ||
583 | static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) | ||
584 | { | ||
585 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { | ||
586 | priv->sbands[IEEE80211_BAND_2GHZ].channels = | ||
587 | ath9k_2ghz_channels; | ||
588 | priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
589 | priv->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
590 | ARRAY_SIZE(ath9k_2ghz_channels); | ||
591 | priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
592 | priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
593 | ARRAY_SIZE(ath9k_legacy_rates); | ||
594 | } | ||
595 | |||
596 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { | ||
597 | priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels; | ||
598 | priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
599 | priv->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
600 | ARRAY_SIZE(ath9k_5ghz_channels); | ||
601 | priv->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
602 | ath9k_legacy_rates + 4; | ||
603 | priv->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | ||
604 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | ||
605 | } | ||
606 | } | ||
607 | |||
608 | static void ath9k_init_misc(struct ath9k_htc_priv *priv) | 444 | static void ath9k_init_misc(struct ath9k_htc_priv *priv) |
609 | { | 445 | { |
610 | struct ath_common *common = ath9k_hw_common(priv->ah); | 446 | struct ath_common *common = ath9k_hw_common(priv->ah); |
611 | 447 | ||
612 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 448 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
613 | 449 | ||
450 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
614 | priv->ah->opmode = NL80211_IFTYPE_STATION; | 451 | priv->ah->opmode = NL80211_IFTYPE_STATION; |
615 | } | 452 | } |
616 | 453 | ||
@@ -622,12 +459,11 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
622 | struct ath_common *common; | 459 | struct ath_common *common; |
623 | int i, ret = 0, csz = 0; | 460 | int i, ret = 0, csz = 0; |
624 | 461 | ||
625 | set_bit(OP_INVALID, &priv->op_flags); | ||
626 | |||
627 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | 462 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); |
628 | if (!ah) | 463 | if (!ah) |
629 | return -ENOMEM; | 464 | return -ENOMEM; |
630 | 465 | ||
466 | ah->dev = priv->dev; | ||
631 | ah->hw_version.devid = devid; | 467 | ah->hw_version.devid = devid; |
632 | ah->hw_version.usbdev = drv_info; | 468 | ah->hw_version.usbdev = drv_info; |
633 | ah->ah_flags |= AH_USE_EEPROM; | 469 | ah->ah_flags |= AH_USE_EEPROM; |
@@ -647,6 +483,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
647 | common->priv = priv; | 483 | common->priv = priv; |
648 | common->debug_mask = ath9k_debug; | 484 | common->debug_mask = ath9k_debug; |
649 | common->btcoex_enabled = ath9k_htc_btcoex_enable == 1; | 485 | common->btcoex_enabled = ath9k_htc_btcoex_enable == 1; |
486 | set_bit(ATH_OP_INVALID, &common->op_flags); | ||
650 | 487 | ||
651 | spin_lock_init(&priv->beacon_lock); | 488 | spin_lock_init(&priv->beacon_lock); |
652 | spin_lock_init(&priv->tx.tx_lock); | 489 | spin_lock_init(&priv->tx.tx_lock); |
@@ -682,10 +519,11 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
682 | goto err_queues; | 519 | goto err_queues; |
683 | 520 | ||
684 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) | 521 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) |
685 | priv->cur_beacon_conf.bslot[i] = NULL; | 522 | priv->beacon.bslot[i] = NULL; |
523 | priv->beacon.slottime = ATH9K_SLOT_TIME_9; | ||
686 | 524 | ||
525 | ath9k_cmn_init_channels_rates(common); | ||
687 | ath9k_cmn_init_crypto(ah); | 526 | ath9k_cmn_init_crypto(ah); |
688 | ath9k_init_channels_rates(priv); | ||
689 | ath9k_init_misc(priv); | 527 | ath9k_init_misc(priv); |
690 | ath9k_htc_init_btcoex(priv, product); | 528 | ath9k_htc_init_btcoex(priv, product); |
691 | 529 | ||
@@ -721,6 +559,7 @@ static const struct ieee80211_iface_combination if_comb = { | |||
721 | static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | 559 | static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, |
722 | struct ieee80211_hw *hw) | 560 | struct ieee80211_hw *hw) |
723 | { | 561 | { |
562 | struct ath_hw *ah = priv->ah; | ||
724 | struct ath_common *common = ath9k_hw_common(priv->ah); | 563 | struct ath_common *common = ath9k_hw_common(priv->ah); |
725 | struct base_eep_header *pBase; | 564 | struct base_eep_header *pBase; |
726 | 565 | ||
@@ -765,19 +604,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
765 | 604 | ||
766 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) | 605 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) |
767 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | 606 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
768 | &priv->sbands[IEEE80211_BAND_2GHZ]; | 607 | &common->sbands[IEEE80211_BAND_2GHZ]; |
769 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) | 608 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) |
770 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 609 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
771 | &priv->sbands[IEEE80211_BAND_5GHZ]; | 610 | &common->sbands[IEEE80211_BAND_5GHZ]; |
772 | 611 | ||
773 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 612 | ath9k_cmn_reload_chainmask(ah); |
774 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) | ||
775 | setup_ht_cap(priv, | ||
776 | &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
777 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) | ||
778 | setup_ht_cap(priv, | ||
779 | &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
780 | } | ||
781 | 613 | ||
782 | pBase = ath9k_htc_get_eeprom_base(priv); | 614 | pBase = ath9k_htc_get_eeprom_base(priv); |
783 | if (pBase) { | 615 | if (pBase) { |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index c9254a61ca52..f46cd0250e48 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -250,7 +250,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
250 | u8 cmd_rsp; | 250 | u8 cmd_rsp; |
251 | int ret; | 251 | int ret; |
252 | 252 | ||
253 | if (test_bit(OP_INVALID, &priv->op_flags)) | 253 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) |
254 | return -EIO; | 254 | return -EIO; |
255 | 255 | ||
256 | fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); | 256 | fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); |
@@ -304,7 +304,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
304 | 304 | ||
305 | htc_start(priv->htc); | 305 | htc_start(priv->htc); |
306 | 306 | ||
307 | if (!test_bit(OP_SCANNING, &priv->op_flags) && | 307 | if (!test_bit(ATH_OP_SCANNING, &common->op_flags) && |
308 | !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | 308 | !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) |
309 | ath9k_htc_vif_reconfig(priv); | 309 | ath9k_htc_vif_reconfig(priv); |
310 | 310 | ||
@@ -748,7 +748,7 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv) | |||
748 | common->ani.shortcal_timer = timestamp; | 748 | common->ani.shortcal_timer = timestamp; |
749 | common->ani.checkani_timer = timestamp; | 749 | common->ani.checkani_timer = timestamp; |
750 | 750 | ||
751 | set_bit(OP_ANI_RUNNING, &priv->op_flags); | 751 | set_bit(ATH_OP_ANI_RUN, &common->op_flags); |
752 | 752 | ||
753 | ieee80211_queue_delayed_work(common->hw, &priv->ani_work, | 753 | ieee80211_queue_delayed_work(common->hw, &priv->ani_work, |
754 | msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | 754 | msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); |
@@ -756,8 +756,9 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv) | |||
756 | 756 | ||
757 | void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv) | 757 | void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv) |
758 | { | 758 | { |
759 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
759 | cancel_delayed_work_sync(&priv->ani_work); | 760 | cancel_delayed_work_sync(&priv->ani_work); |
760 | clear_bit(OP_ANI_RUNNING, &priv->op_flags); | 761 | clear_bit(ATH_OP_ANI_RUN, &common->op_flags); |
761 | } | 762 | } |
762 | 763 | ||
763 | void ath9k_htc_ani_work(struct work_struct *work) | 764 | void ath9k_htc_ani_work(struct work_struct *work) |
@@ -942,7 +943,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
942 | ath_dbg(common, CONFIG, | 943 | ath_dbg(common, CONFIG, |
943 | "Failed to update capability in target\n"); | 944 | "Failed to update capability in target\n"); |
944 | 945 | ||
945 | clear_bit(OP_INVALID, &priv->op_flags); | 946 | clear_bit(ATH_OP_INVALID, &common->op_flags); |
946 | htc_start(priv->htc); | 947 | htc_start(priv->htc); |
947 | 948 | ||
948 | spin_lock_bh(&priv->tx.tx_lock); | 949 | spin_lock_bh(&priv->tx.tx_lock); |
@@ -971,7 +972,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
971 | 972 | ||
972 | mutex_lock(&priv->mutex); | 973 | mutex_lock(&priv->mutex); |
973 | 974 | ||
974 | if (test_bit(OP_INVALID, &priv->op_flags)) { | 975 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) { |
975 | ath_dbg(common, ANY, "Device not present\n"); | 976 | ath_dbg(common, ANY, "Device not present\n"); |
976 | mutex_unlock(&priv->mutex); | 977 | mutex_unlock(&priv->mutex); |
977 | return; | 978 | return; |
@@ -1013,7 +1014,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1013 | ath9k_htc_ps_restore(priv); | 1014 | ath9k_htc_ps_restore(priv); |
1014 | ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); | 1015 | ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); |
1015 | 1016 | ||
1016 | set_bit(OP_INVALID, &priv->op_flags); | 1017 | set_bit(ATH_OP_INVALID, &common->op_flags); |
1017 | 1018 | ||
1018 | ath_dbg(common, CONFIG, "Driver halt\n"); | 1019 | ath_dbg(common, CONFIG, "Driver halt\n"); |
1019 | mutex_unlock(&priv->mutex); | 1020 | mutex_unlock(&priv->mutex); |
@@ -1087,7 +1088,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1087 | ath9k_htc_set_opmode(priv); | 1088 | ath9k_htc_set_opmode(priv); |
1088 | 1089 | ||
1089 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && | 1090 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && |
1090 | !test_bit(OP_ANI_RUNNING, &priv->op_flags)) { | 1091 | !test_bit(ATH_OP_ANI_RUN, &common->op_flags)) { |
1091 | ath9k_hw_set_tsfadjust(priv->ah, true); | 1092 | ath9k_hw_set_tsfadjust(priv->ah, true); |
1092 | ath9k_htc_start_ani(priv); | 1093 | ath9k_htc_start_ani(priv); |
1093 | } | 1094 | } |
@@ -1245,13 +1246,14 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | |||
1245 | u64 multicast) | 1246 | u64 multicast) |
1246 | { | 1247 | { |
1247 | struct ath9k_htc_priv *priv = hw->priv; | 1248 | struct ath9k_htc_priv *priv = hw->priv; |
1249 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1248 | u32 rfilt; | 1250 | u32 rfilt; |
1249 | 1251 | ||
1250 | mutex_lock(&priv->mutex); | 1252 | mutex_lock(&priv->mutex); |
1251 | changed_flags &= SUPPORTED_FILTERS; | 1253 | changed_flags &= SUPPORTED_FILTERS; |
1252 | *total_flags &= SUPPORTED_FILTERS; | 1254 | *total_flags &= SUPPORTED_FILTERS; |
1253 | 1255 | ||
1254 | if (test_bit(OP_INVALID, &priv->op_flags)) { | 1256 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) { |
1255 | ath_dbg(ath9k_hw_common(priv->ah), ANY, | 1257 | ath_dbg(ath9k_hw_common(priv->ah), ANY, |
1256 | "Unable to configure filter on invalid state\n"); | 1258 | "Unable to configure filter on invalid state\n"); |
1257 | mutex_unlock(&priv->mutex); | 1259 | mutex_unlock(&priv->mutex); |
@@ -1474,7 +1476,9 @@ static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1474 | 1476 | ||
1475 | if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) { | 1477 | if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) { |
1476 | common->curaid = bss_conf->aid; | 1478 | common->curaid = bss_conf->aid; |
1479 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
1477 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1480 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1481 | set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); | ||
1478 | } | 1482 | } |
1479 | } | 1483 | } |
1480 | 1484 | ||
@@ -1496,6 +1500,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1496 | struct ath9k_htc_priv *priv = hw->priv; | 1500 | struct ath9k_htc_priv *priv = hw->priv; |
1497 | struct ath_hw *ah = priv->ah; | 1501 | struct ath_hw *ah = priv->ah; |
1498 | struct ath_common *common = ath9k_hw_common(ah); | 1502 | struct ath_common *common = ath9k_hw_common(ah); |
1503 | int slottime; | ||
1499 | 1504 | ||
1500 | mutex_lock(&priv->mutex); | 1505 | mutex_lock(&priv->mutex); |
1501 | ath9k_htc_ps_wakeup(priv); | 1506 | ath9k_htc_ps_wakeup(priv); |
@@ -1507,6 +1512,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1507 | bss_conf->assoc ? | 1512 | bss_conf->assoc ? |
1508 | priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; | 1513 | priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; |
1509 | 1514 | ||
1515 | if (!bss_conf->assoc) | ||
1516 | clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); | ||
1517 | |||
1510 | if (priv->ah->opmode == NL80211_IFTYPE_STATION) { | 1518 | if (priv->ah->opmode == NL80211_IFTYPE_STATION) { |
1511 | ath9k_htc_choose_set_bssid(priv); | 1519 | ath9k_htc_choose_set_bssid(priv); |
1512 | if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) | 1520 | if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) |
@@ -1528,7 +1536,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1528 | ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n", | 1536 | ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n", |
1529 | bss_conf->bssid); | 1537 | bss_conf->bssid); |
1530 | ath9k_htc_set_tsfadjust(priv, vif); | 1538 | ath9k_htc_set_tsfadjust(priv, vif); |
1531 | set_bit(OP_ENABLE_BEACON, &priv->op_flags); | 1539 | priv->cur_beacon_conf.enable_beacon = 1; |
1532 | ath9k_htc_beacon_config(priv, vif); | 1540 | ath9k_htc_beacon_config(priv, vif); |
1533 | } | 1541 | } |
1534 | 1542 | ||
@@ -1542,7 +1550,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1542 | ath_dbg(common, CONFIG, | 1550 | ath_dbg(common, CONFIG, |
1543 | "Beacon disabled for BSS: %pM\n", | 1551 | "Beacon disabled for BSS: %pM\n", |
1544 | bss_conf->bssid); | 1552 | bss_conf->bssid); |
1545 | clear_bit(OP_ENABLE_BEACON, &priv->op_flags); | 1553 | priv->cur_beacon_conf.enable_beacon = 0; |
1546 | ath9k_htc_beacon_config(priv, vif); | 1554 | ath9k_htc_beacon_config(priv, vif); |
1547 | } | 1555 | } |
1548 | } | 1556 | } |
@@ -1568,11 +1576,21 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1568 | 1576 | ||
1569 | if (changed & BSS_CHANGED_ERP_SLOT) { | 1577 | if (changed & BSS_CHANGED_ERP_SLOT) { |
1570 | if (bss_conf->use_short_slot) | 1578 | if (bss_conf->use_short_slot) |
1571 | ah->slottime = 9; | 1579 | slottime = 9; |
1572 | else | 1580 | else |
1573 | ah->slottime = 20; | 1581 | slottime = 20; |
1574 | 1582 | if (vif->type == NL80211_IFTYPE_AP) { | |
1575 | ath9k_hw_init_global_settings(ah); | 1583 | /* |
1584 | * Defer update, so that connected stations can adjust | ||
1585 | * their settings at the same time. | ||
1586 | * See beacon.c for more details | ||
1587 | */ | ||
1588 | priv->beacon.slottime = slottime; | ||
1589 | priv->beacon.updateslot = UPDATE; | ||
1590 | } else { | ||
1591 | ah->slottime = slottime; | ||
1592 | ath9k_hw_init_global_settings(ah); | ||
1593 | } | ||
1576 | } | 1594 | } |
1577 | 1595 | ||
1578 | if (changed & BSS_CHANGED_HT) | 1596 | if (changed & BSS_CHANGED_HT) |
@@ -1669,10 +1687,11 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
1669 | static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) | 1687 | static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) |
1670 | { | 1688 | { |
1671 | struct ath9k_htc_priv *priv = hw->priv; | 1689 | struct ath9k_htc_priv *priv = hw->priv; |
1690 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1672 | 1691 | ||
1673 | mutex_lock(&priv->mutex); | 1692 | mutex_lock(&priv->mutex); |
1674 | spin_lock_bh(&priv->beacon_lock); | 1693 | spin_lock_bh(&priv->beacon_lock); |
1675 | set_bit(OP_SCANNING, &priv->op_flags); | 1694 | set_bit(ATH_OP_SCANNING, &common->op_flags); |
1676 | spin_unlock_bh(&priv->beacon_lock); | 1695 | spin_unlock_bh(&priv->beacon_lock); |
1677 | cancel_work_sync(&priv->ps_work); | 1696 | cancel_work_sync(&priv->ps_work); |
1678 | ath9k_htc_stop_ani(priv); | 1697 | ath9k_htc_stop_ani(priv); |
@@ -1682,10 +1701,11 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) | |||
1682 | static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) | 1701 | static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) |
1683 | { | 1702 | { |
1684 | struct ath9k_htc_priv *priv = hw->priv; | 1703 | struct ath9k_htc_priv *priv = hw->priv; |
1704 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1685 | 1705 | ||
1686 | mutex_lock(&priv->mutex); | 1706 | mutex_lock(&priv->mutex); |
1687 | spin_lock_bh(&priv->beacon_lock); | 1707 | spin_lock_bh(&priv->beacon_lock); |
1688 | clear_bit(OP_SCANNING, &priv->op_flags); | 1708 | clear_bit(ATH_OP_SCANNING, &common->op_flags); |
1689 | spin_unlock_bh(&priv->beacon_lock); | 1709 | spin_unlock_bh(&priv->beacon_lock); |
1690 | ath9k_htc_ps_wakeup(priv); | 1710 | ath9k_htc_ps_wakeup(priv); |
1691 | ath9k_htc_vif_reconfig(priv); | 1711 | ath9k_htc_vif_reconfig(priv); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 12e0f32a4905..e8149e3dbdd5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -924,46 +924,43 @@ static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) | |||
924 | 924 | ||
925 | void ath9k_host_rx_init(struct ath9k_htc_priv *priv) | 925 | void ath9k_host_rx_init(struct ath9k_htc_priv *priv) |
926 | { | 926 | { |
927 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
927 | ath9k_hw_rxena(priv->ah); | 928 | ath9k_hw_rxena(priv->ah); |
928 | ath9k_htc_opmode_init(priv); | 929 | ath9k_htc_opmode_init(priv); |
929 | ath9k_hw_startpcureceive(priv->ah, test_bit(OP_SCANNING, &priv->op_flags)); | 930 | ath9k_hw_startpcureceive(priv->ah, test_bit(ATH_OP_SCANNING, &common->op_flags)); |
930 | priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
931 | } | 931 | } |
932 | 932 | ||
933 | static void ath9k_process_rate(struct ieee80211_hw *hw, | 933 | static inline void convert_htc_flag(struct ath_rx_status *rx_stats, |
934 | struct ieee80211_rx_status *rxs, | 934 | struct ath_htc_rx_status *rxstatus) |
935 | u8 rx_rate, u8 rs_flags) | ||
936 | { | 935 | { |
937 | struct ieee80211_supported_band *sband; | 936 | rx_stats->flag = 0; |
938 | enum ieee80211_band band; | 937 | if (rxstatus->rs_flags & ATH9K_RX_2040) |
939 | unsigned int i = 0; | 938 | rx_stats->flag |= RX_FLAG_40MHZ; |
940 | 939 | if (rxstatus->rs_flags & ATH9K_RX_GI) | |
941 | if (rx_rate & 0x80) { | 940 | rx_stats->flag |= RX_FLAG_SHORT_GI; |
942 | /* HT rate */ | 941 | } |
943 | rxs->flag |= RX_FLAG_HT; | ||
944 | if (rs_flags & ATH9K_RX_2040) | ||
945 | rxs->flag |= RX_FLAG_40MHZ; | ||
946 | if (rs_flags & ATH9K_RX_GI) | ||
947 | rxs->flag |= RX_FLAG_SHORT_GI; | ||
948 | rxs->rate_idx = rx_rate & 0x7f; | ||
949 | return; | ||
950 | } | ||
951 | |||
952 | band = hw->conf.chandef.chan->band; | ||
953 | sband = hw->wiphy->bands[band]; | ||
954 | |||
955 | for (i = 0; i < sband->n_bitrates; i++) { | ||
956 | if (sband->bitrates[i].hw_value == rx_rate) { | ||
957 | rxs->rate_idx = i; | ||
958 | return; | ||
959 | } | ||
960 | if (sband->bitrates[i].hw_value_short == rx_rate) { | ||
961 | rxs->rate_idx = i; | ||
962 | rxs->flag |= RX_FLAG_SHORTPRE; | ||
963 | return; | ||
964 | } | ||
965 | } | ||
966 | 942 | ||
943 | static void rx_status_htc_to_ath(struct ath_rx_status *rx_stats, | ||
944 | struct ath_htc_rx_status *rxstatus) | ||
945 | { | ||
946 | rx_stats->rs_datalen = rxstatus->rs_datalen; | ||
947 | rx_stats->rs_status = rxstatus->rs_status; | ||
948 | rx_stats->rs_phyerr = rxstatus->rs_phyerr; | ||
949 | rx_stats->rs_rssi = rxstatus->rs_rssi; | ||
950 | rx_stats->rs_keyix = rxstatus->rs_keyix; | ||
951 | rx_stats->rs_rate = rxstatus->rs_rate; | ||
952 | rx_stats->rs_antenna = rxstatus->rs_antenna; | ||
953 | rx_stats->rs_more = rxstatus->rs_more; | ||
954 | |||
955 | memcpy(rx_stats->rs_rssi_ctl, rxstatus->rs_rssi_ctl, | ||
956 | sizeof(rx_stats->rs_rssi_ctl)); | ||
957 | memcpy(rx_stats->rs_rssi_ext, rxstatus->rs_rssi_ext, | ||
958 | sizeof(rx_stats->rs_rssi_ext)); | ||
959 | |||
960 | rx_stats->rs_isaggr = rxstatus->rs_isaggr; | ||
961 | rx_stats->rs_moreaggr = rxstatus->rs_moreaggr; | ||
962 | rx_stats->rs_num_delims = rxstatus->rs_num_delims; | ||
963 | convert_htc_flag(rx_stats, rxstatus); | ||
967 | } | 964 | } |
968 | 965 | ||
969 | static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | 966 | static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, |
@@ -975,10 +972,10 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
975 | struct ieee80211_hw *hw = priv->hw; | 972 | struct ieee80211_hw *hw = priv->hw; |
976 | struct sk_buff *skb = rxbuf->skb; | 973 | struct sk_buff *skb = rxbuf->skb; |
977 | struct ath_common *common = ath9k_hw_common(priv->ah); | 974 | struct ath_common *common = ath9k_hw_common(priv->ah); |
975 | struct ath_hw *ah = common->ah; | ||
978 | struct ath_htc_rx_status *rxstatus; | 976 | struct ath_htc_rx_status *rxstatus; |
979 | int hdrlen, padsize; | 977 | struct ath_rx_status rx_stats; |
980 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | 978 | bool decrypt_error; |
981 | __le16 fc; | ||
982 | 979 | ||
983 | if (skb->len < HTC_RX_FRAME_HEADER_SIZE) { | 980 | if (skb->len < HTC_RX_FRAME_HEADER_SIZE) { |
984 | ath_err(common, "Corrupted RX frame, dropping (len: %d)\n", | 981 | ath_err(common, "Corrupted RX frame, dropping (len: %d)\n", |
@@ -999,103 +996,39 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
999 | ath9k_htc_err_stat_rx(priv, rxstatus); | 996 | ath9k_htc_err_stat_rx(priv, rxstatus); |
1000 | 997 | ||
1001 | /* Get the RX status information */ | 998 | /* Get the RX status information */ |
1002 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); | ||
1003 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); | ||
1004 | |||
1005 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1006 | fc = hdr->frame_control; | ||
1007 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1008 | |||
1009 | padsize = hdrlen & 3; | ||
1010 | if (padsize && skb->len >= hdrlen+padsize+FCS_LEN) { | ||
1011 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
1012 | skb_pull(skb, padsize); | ||
1013 | } | ||
1014 | 999 | ||
1015 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | 1000 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); |
1016 | 1001 | ||
1017 | if (rxbuf->rxstatus.rs_status != 0) { | 1002 | /* Copy everything from ath_htc_rx_status (HTC_RX_FRAME_HEADER). |
1018 | if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_CRC) | 1003 | * After this, we can drop this part of skb. */ |
1019 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 1004 | rx_status_htc_to_ath(&rx_stats, rxstatus); |
1020 | if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_PHY) | 1005 | rx_status->mactime = be64_to_cpu(rxstatus->rs_tstamp); |
1021 | goto rx_next; | 1006 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); |
1022 | |||
1023 | if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT) { | ||
1024 | /* FIXME */ | ||
1025 | } else if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_MIC) { | ||
1026 | if (ieee80211_is_ctl(fc)) | ||
1027 | /* | ||
1028 | * Sometimes, we get invalid | ||
1029 | * MIC failures on valid control frames. | ||
1030 | * Remove these mic errors. | ||
1031 | */ | ||
1032 | rxbuf->rxstatus.rs_status &= ~ATH9K_RXERR_MIC; | ||
1033 | else | ||
1034 | rx_status->flag |= RX_FLAG_MMIC_ERROR; | ||
1035 | } | ||
1036 | |||
1037 | /* | ||
1038 | * Reject error frames with the exception of | ||
1039 | * decryption and MIC failures. For monitor mode, | ||
1040 | * we also ignore the CRC error. | ||
1041 | */ | ||
1042 | if (priv->ah->opmode == NL80211_IFTYPE_MONITOR) { | ||
1043 | if (rxbuf->rxstatus.rs_status & | ||
1044 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
1045 | ATH9K_RXERR_CRC)) | ||
1046 | goto rx_next; | ||
1047 | } else { | ||
1048 | if (rxbuf->rxstatus.rs_status & | ||
1049 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { | ||
1050 | goto rx_next; | ||
1051 | } | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1055 | if (!(rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT)) { | ||
1056 | u8 keyix; | ||
1057 | keyix = rxbuf->rxstatus.rs_keyix; | ||
1058 | if (keyix != ATH9K_RXKEYIX_INVALID) { | ||
1059 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
1060 | } else if (ieee80211_has_protected(fc) && | ||
1061 | skb->len >= hdrlen + 4) { | ||
1062 | keyix = skb->data[hdrlen + 3] >> 6; | ||
1063 | if (test_bit(keyix, common->keymap)) | ||
1064 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate, | ||
1069 | rxbuf->rxstatus.rs_flags); | ||
1070 | |||
1071 | if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD && | ||
1072 | !rxbuf->rxstatus.rs_moreaggr) | ||
1073 | ATH_RSSI_LPF(priv->rx.last_rssi, | ||
1074 | rxbuf->rxstatus.rs_rssi); | ||
1075 | |||
1076 | last_rssi = priv->rx.last_rssi; | ||
1077 | 1007 | ||
1078 | if (ath_is_mybeacon(common, hdr)) { | 1008 | /* |
1079 | s8 rssi = rxbuf->rxstatus.rs_rssi; | 1009 | * everything but the rate is checked here, the rate check is done |
1010 | * separately to avoid doing two lookups for a rate for each frame. | ||
1011 | */ | ||
1012 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1013 | if (!ath9k_cmn_rx_accept(common, hdr, rx_status, &rx_stats, | ||
1014 | &decrypt_error, priv->rxfilter)) | ||
1015 | goto rx_next; | ||
1080 | 1016 | ||
1081 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | 1017 | ath9k_cmn_rx_skb_postprocess(common, skb, &rx_stats, |
1082 | rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); | 1018 | rx_status, decrypt_error); |
1083 | 1019 | ||
1084 | if (rssi < 0) | 1020 | if (ath9k_cmn_process_rate(common, hw, &rx_stats, rx_status)) |
1085 | rssi = 0; | 1021 | goto rx_next; |
1086 | 1022 | ||
1087 | priv->ah->stats.avgbrssi = rssi; | 1023 | rx_stats.is_mybeacon = ath_is_mybeacon(common, hdr); |
1088 | } | 1024 | ath9k_cmn_process_rssi(common, hw, &rx_stats, rx_status); |
1089 | 1025 | ||
1090 | rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); | 1026 | rx_status->band = ah->curchan->chan->band; |
1091 | rx_status->band = hw->conf.chandef.chan->band; | 1027 | rx_status->freq = ah->curchan->chan->center_freq; |
1092 | rx_status->freq = hw->conf.chandef.chan->center_freq; | 1028 | rx_status->antenna = rx_stats.rs_antenna; |
1093 | rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; | ||
1094 | rx_status->antenna = rxbuf->rxstatus.rs_antenna; | ||
1095 | rx_status->flag |= RX_FLAG_MACTIME_END; | 1029 | rx_status->flag |= RX_FLAG_MACTIME_END; |
1096 | 1030 | ||
1097 | return true; | 1031 | return true; |
1098 | |||
1099 | rx_next: | 1032 | rx_next: |
1100 | return false; | 1033 | return false; |
1101 | } | 1034 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index aac4a406a513..a0ff5b637054 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -358,6 +358,36 @@ ret: | |||
358 | kfree_skb(skb); | 358 | kfree_skb(skb); |
359 | } | 359 | } |
360 | 360 | ||
361 | static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle, | ||
362 | struct sk_buff *skb) | ||
363 | { | ||
364 | uint32_t *pattern = (uint32_t *)skb->data; | ||
365 | |||
366 | switch (*pattern) { | ||
367 | case 0x33221199: | ||
368 | { | ||
369 | struct htc_panic_bad_vaddr *htc_panic; | ||
370 | htc_panic = (struct htc_panic_bad_vaddr *) skb->data; | ||
371 | dev_err(htc_handle->dev, "ath: firmware panic! " | ||
372 | "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n", | ||
373 | htc_panic->exccause, htc_panic->pc, | ||
374 | htc_panic->badvaddr); | ||
375 | break; | ||
376 | } | ||
377 | case 0x33221299: | ||
378 | { | ||
379 | struct htc_panic_bad_epid *htc_panic; | ||
380 | htc_panic = (struct htc_panic_bad_epid *) skb->data; | ||
381 | dev_err(htc_handle->dev, "ath: firmware panic! " | ||
382 | "bad epid: 0x%08x\n", htc_panic->epid); | ||
383 | break; | ||
384 | } | ||
385 | default: | ||
386 | dev_err(htc_handle->dev, "ath: uknown panic pattern!\n"); | ||
387 | break; | ||
388 | } | ||
389 | } | ||
390 | |||
361 | /* | 391 | /* |
362 | * HTC Messages are handled directly here and the obtained SKB | 392 | * HTC Messages are handled directly here and the obtained SKB |
363 | * is freed. | 393 | * is freed. |
@@ -379,6 +409,12 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle, | |||
379 | htc_hdr = (struct htc_frame_hdr *) skb->data; | 409 | htc_hdr = (struct htc_frame_hdr *) skb->data; |
380 | epid = htc_hdr->endpoint_id; | 410 | epid = htc_hdr->endpoint_id; |
381 | 411 | ||
412 | if (epid == 0x99) { | ||
413 | ath9k_htc_fw_panic_report(htc_handle, skb); | ||
414 | kfree_skb(skb); | ||
415 | return; | ||
416 | } | ||
417 | |||
382 | if (epid >= ENDPOINT_MAX) { | 418 | if (epid >= ENDPOINT_MAX) { |
383 | if (pipe_id != USB_REG_IN_PIPE) | 419 | if (pipe_id != USB_REG_IN_PIPE) |
384 | dev_kfree_skb_any(skb); | 420 | dev_kfree_skb_any(skb); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index e1ffbb6bd636..06474ccc7696 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h | |||
@@ -77,6 +77,18 @@ struct htc_config_pipe_msg { | |||
77 | u8 credits; | 77 | u8 credits; |
78 | } __packed; | 78 | } __packed; |
79 | 79 | ||
80 | struct htc_panic_bad_vaddr { | ||
81 | __be32 pattern; | ||
82 | __be32 exccause; | ||
83 | __be32 pc; | ||
84 | __be32 badvaddr; | ||
85 | } __packed; | ||
86 | |||
87 | struct htc_panic_bad_epid { | ||
88 | __be32 pattern; | ||
89 | __be32 epid; | ||
90 | } __packed; | ||
91 | |||
80 | struct htc_ep_callbacks { | 92 | struct htc_ep_callbacks { |
81 | void *priv; | 93 | void *priv; |
82 | void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok); | 94 | void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9078a6c5a74e..c8a9dfab1fee 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include "hw.h" | 24 | #include "hw.h" |
25 | #include "hw-ops.h" | 25 | #include "hw-ops.h" |
26 | #include "rc.h" | ||
27 | #include "ar9003_mac.h" | 26 | #include "ar9003_mac.h" |
28 | #include "ar9003_mci.h" | 27 | #include "ar9003_mci.h" |
29 | #include "ar9003_phy.h" | 28 | #include "ar9003_phy.h" |
@@ -883,7 +882,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
883 | AR_IMR_RXORN | | 882 | AR_IMR_RXORN | |
884 | AR_IMR_BCNMISC; | 883 | AR_IMR_BCNMISC; |
885 | 884 | ||
886 | if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) | 885 | if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) |
887 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | 886 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; |
888 | 887 | ||
889 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 888 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
@@ -3048,6 +3047,7 @@ static struct { | |||
3048 | { AR_SREV_VERSION_9462, "9462" }, | 3047 | { AR_SREV_VERSION_9462, "9462" }, |
3049 | { AR_SREV_VERSION_9550, "9550" }, | 3048 | { AR_SREV_VERSION_9550, "9550" }, |
3050 | { AR_SREV_VERSION_9565, "9565" }, | 3049 | { AR_SREV_VERSION_9565, "9565" }, |
3050 | { AR_SREV_VERSION_9531, "9531" }, | ||
3051 | }; | 3051 | }; |
3052 | 3052 | ||
3053 | /* For devices with external radios */ | 3053 | /* For devices with external radios */ |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 1fc2e5a26b52..c0a4e866edca 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -62,111 +62,6 @@ module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | |||
62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | 62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); |
63 | 63 | ||
64 | bool is_ath9k_unloaded; | 64 | bool is_ath9k_unloaded; |
65 | /* We use the hw_value as an index into our private channel structure */ | ||
66 | |||
67 | #define CHAN2G(_freq, _idx) { \ | ||
68 | .band = IEEE80211_BAND_2GHZ, \ | ||
69 | .center_freq = (_freq), \ | ||
70 | .hw_value = (_idx), \ | ||
71 | .max_power = 20, \ | ||
72 | } | ||
73 | |||
74 | #define CHAN5G(_freq, _idx) { \ | ||
75 | .band = IEEE80211_BAND_5GHZ, \ | ||
76 | .center_freq = (_freq), \ | ||
77 | .hw_value = (_idx), \ | ||
78 | .max_power = 20, \ | ||
79 | } | ||
80 | |||
81 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
82 | * on 5 MHz steps, we support the channels which we know | ||
83 | * we have calibration data for all cards though to make | ||
84 | * this static */ | ||
85 | static const struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
86 | CHAN2G(2412, 0), /* Channel 1 */ | ||
87 | CHAN2G(2417, 1), /* Channel 2 */ | ||
88 | CHAN2G(2422, 2), /* Channel 3 */ | ||
89 | CHAN2G(2427, 3), /* Channel 4 */ | ||
90 | CHAN2G(2432, 4), /* Channel 5 */ | ||
91 | CHAN2G(2437, 5), /* Channel 6 */ | ||
92 | CHAN2G(2442, 6), /* Channel 7 */ | ||
93 | CHAN2G(2447, 7), /* Channel 8 */ | ||
94 | CHAN2G(2452, 8), /* Channel 9 */ | ||
95 | CHAN2G(2457, 9), /* Channel 10 */ | ||
96 | CHAN2G(2462, 10), /* Channel 11 */ | ||
97 | CHAN2G(2467, 11), /* Channel 12 */ | ||
98 | CHAN2G(2472, 12), /* Channel 13 */ | ||
99 | CHAN2G(2484, 13), /* Channel 14 */ | ||
100 | }; | ||
101 | |||
102 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
103 | * on 5 MHz steps, we support the channels which we know | ||
104 | * we have calibration data for all cards though to make | ||
105 | * this static */ | ||
106 | static const struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
107 | /* _We_ call this UNII 1 */ | ||
108 | CHAN5G(5180, 14), /* Channel 36 */ | ||
109 | CHAN5G(5200, 15), /* Channel 40 */ | ||
110 | CHAN5G(5220, 16), /* Channel 44 */ | ||
111 | CHAN5G(5240, 17), /* Channel 48 */ | ||
112 | /* _We_ call this UNII 2 */ | ||
113 | CHAN5G(5260, 18), /* Channel 52 */ | ||
114 | CHAN5G(5280, 19), /* Channel 56 */ | ||
115 | CHAN5G(5300, 20), /* Channel 60 */ | ||
116 | CHAN5G(5320, 21), /* Channel 64 */ | ||
117 | /* _We_ call this "Middle band" */ | ||
118 | CHAN5G(5500, 22), /* Channel 100 */ | ||
119 | CHAN5G(5520, 23), /* Channel 104 */ | ||
120 | CHAN5G(5540, 24), /* Channel 108 */ | ||
121 | CHAN5G(5560, 25), /* Channel 112 */ | ||
122 | CHAN5G(5580, 26), /* Channel 116 */ | ||
123 | CHAN5G(5600, 27), /* Channel 120 */ | ||
124 | CHAN5G(5620, 28), /* Channel 124 */ | ||
125 | CHAN5G(5640, 29), /* Channel 128 */ | ||
126 | CHAN5G(5660, 30), /* Channel 132 */ | ||
127 | CHAN5G(5680, 31), /* Channel 136 */ | ||
128 | CHAN5G(5700, 32), /* Channel 140 */ | ||
129 | /* _We_ call this UNII 3 */ | ||
130 | CHAN5G(5745, 33), /* Channel 149 */ | ||
131 | CHAN5G(5765, 34), /* Channel 153 */ | ||
132 | CHAN5G(5785, 35), /* Channel 157 */ | ||
133 | CHAN5G(5805, 36), /* Channel 161 */ | ||
134 | CHAN5G(5825, 37), /* Channel 165 */ | ||
135 | }; | ||
136 | |||
137 | /* Atheros hardware rate code addition for short premble */ | ||
138 | #define SHPCHECK(__hw_rate, __flags) \ | ||
139 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) | ||
140 | |||
141 | #define RATE(_bitrate, _hw_rate, _flags) { \ | ||
142 | .bitrate = (_bitrate), \ | ||
143 | .flags = (_flags), \ | ||
144 | .hw_value = (_hw_rate), \ | ||
145 | .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ | ||
146 | } | ||
147 | |||
148 | static struct ieee80211_rate ath9k_legacy_rates[] = { | ||
149 | RATE(10, 0x1b, 0), | ||
150 | RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), | ||
151 | RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), | ||
152 | RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), | ||
153 | RATE(60, 0x0b, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
154 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
155 | RATE(90, 0x0f, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
156 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
157 | RATE(120, 0x0a, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
158 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
159 | RATE(180, 0x0e, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
160 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
161 | RATE(240, 0x09, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
162 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
163 | RATE(360, 0x0d, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
164 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
165 | RATE(480, 0x08, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
166 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
167 | RATE(540, 0x0c, (IEEE80211_RATE_SUPPORTS_5MHZ | | ||
168 | IEEE80211_RATE_SUPPORTS_10MHZ)), | ||
169 | }; | ||
170 | 65 | ||
171 | #ifdef CONFIG_MAC80211_LEDS | 66 | #ifdef CONFIG_MAC80211_LEDS |
172 | static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { | 67 | static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { |
@@ -258,64 +153,6 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl | |||
258 | /* Initialization */ | 153 | /* Initialization */ |
259 | /**************************/ | 154 | /**************************/ |
260 | 155 | ||
261 | static void setup_ht_cap(struct ath_softc *sc, | ||
262 | struct ieee80211_sta_ht_cap *ht_info) | ||
263 | { | ||
264 | struct ath_hw *ah = sc->sc_ah; | ||
265 | struct ath_common *common = ath9k_hw_common(ah); | ||
266 | u8 tx_streams, rx_streams; | ||
267 | int i, max_streams; | ||
268 | |||
269 | ht_info->ht_supported = true; | ||
270 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
271 | IEEE80211_HT_CAP_SM_PS | | ||
272 | IEEE80211_HT_CAP_SGI_40 | | ||
273 | IEEE80211_HT_CAP_DSSSCCK40; | ||
274 | |||
275 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC) | ||
276 | ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
277 | |||
278 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) | ||
279 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
280 | |||
281 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
282 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
283 | |||
284 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) | ||
285 | max_streams = 1; | ||
286 | else if (AR_SREV_9462(ah)) | ||
287 | max_streams = 2; | ||
288 | else if (AR_SREV_9300_20_OR_LATER(ah)) | ||
289 | max_streams = 3; | ||
290 | else | ||
291 | max_streams = 2; | ||
292 | |||
293 | if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
294 | if (max_streams >= 2) | ||
295 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; | ||
296 | ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); | ||
297 | } | ||
298 | |||
299 | /* set up supported mcs set */ | ||
300 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
301 | tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams); | ||
302 | rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams); | ||
303 | |||
304 | ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n", | ||
305 | tx_streams, rx_streams); | ||
306 | |||
307 | if (tx_streams != rx_streams) { | ||
308 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
309 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | ||
310 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
311 | } | ||
312 | |||
313 | for (i = 0; i < rx_streams; i++) | ||
314 | ht_info->mcs.rx_mask[i] = 0xff; | ||
315 | |||
316 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
317 | } | ||
318 | |||
319 | static void ath9k_reg_notifier(struct wiphy *wiphy, | 156 | static void ath9k_reg_notifier(struct wiphy *wiphy, |
320 | struct regulatory_request *request) | 157 | struct regulatory_request *request) |
321 | { | 158 | { |
@@ -486,51 +323,6 @@ static int ath9k_init_queues(struct ath_softc *sc) | |||
486 | return 0; | 323 | return 0; |
487 | } | 324 | } |
488 | 325 | ||
489 | static int ath9k_init_channels_rates(struct ath_softc *sc) | ||
490 | { | ||
491 | void *channels; | ||
492 | |||
493 | BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) + | ||
494 | ARRAY_SIZE(ath9k_5ghz_chantable) != | ||
495 | ATH9K_NUM_CHANNELS); | ||
496 | |||
497 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { | ||
498 | channels = devm_kzalloc(sc->dev, | ||
499 | sizeof(ath9k_2ghz_chantable), GFP_KERNEL); | ||
500 | if (!channels) | ||
501 | return -ENOMEM; | ||
502 | |||
503 | memcpy(channels, ath9k_2ghz_chantable, | ||
504 | sizeof(ath9k_2ghz_chantable)); | ||
505 | sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; | ||
506 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
507 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
508 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
509 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
510 | sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
511 | ARRAY_SIZE(ath9k_legacy_rates); | ||
512 | } | ||
513 | |||
514 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { | ||
515 | channels = devm_kzalloc(sc->dev, | ||
516 | sizeof(ath9k_5ghz_chantable), GFP_KERNEL); | ||
517 | if (!channels) | ||
518 | return -ENOMEM; | ||
519 | |||
520 | memcpy(channels, ath9k_5ghz_chantable, | ||
521 | sizeof(ath9k_5ghz_chantable)); | ||
522 | sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; | ||
523 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
524 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
525 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
526 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
527 | ath9k_legacy_rates + 4; | ||
528 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | ||
529 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | ||
530 | } | ||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static void ath9k_init_misc(struct ath_softc *sc) | 326 | static void ath9k_init_misc(struct ath_softc *sc) |
535 | { | 327 | { |
536 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 328 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -538,7 +330,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
538 | 330 | ||
539 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 331 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); |
540 | 332 | ||
541 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 333 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; |
542 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | 334 | sc->config.txpowlimit = ATH_TXPOWER_MAX; |
543 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 335 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
544 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | 336 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; |
@@ -793,7 +585,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
793 | if (ret) | 585 | if (ret) |
794 | goto err_btcoex; | 586 | goto err_btcoex; |
795 | 587 | ||
796 | ret = ath9k_init_channels_rates(sc); | 588 | ret = ath9k_cmn_init_channels_rates(common); |
797 | if (ret) | 589 | if (ret) |
798 | goto err_btcoex; | 590 | goto err_btcoex; |
799 | 591 | ||
@@ -823,10 +615,11 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) | |||
823 | struct ieee80211_supported_band *sband; | 615 | struct ieee80211_supported_band *sband; |
824 | struct ieee80211_channel *chan; | 616 | struct ieee80211_channel *chan; |
825 | struct ath_hw *ah = sc->sc_ah; | 617 | struct ath_hw *ah = sc->sc_ah; |
618 | struct ath_common *common = ath9k_hw_common(ah); | ||
826 | struct cfg80211_chan_def chandef; | 619 | struct cfg80211_chan_def chandef; |
827 | int i; | 620 | int i; |
828 | 621 | ||
829 | sband = &sc->sbands[band]; | 622 | sband = &common->sbands[band]; |
830 | for (i = 0; i < sband->n_channels; i++) { | 623 | for (i = 0; i < sband->n_channels; i++) { |
831 | chan = &sband->channels[i]; | 624 | chan = &sband->channels[i]; |
832 | ah->curchan = &ah->channels[chan->hw_value]; | 625 | ah->curchan = &ah->channels[chan->hw_value]; |
@@ -849,17 +642,6 @@ static void ath9k_init_txpower_limits(struct ath_softc *sc) | |||
849 | ah->curchan = curchan; | 642 | ah->curchan = curchan; |
850 | } | 643 | } |
851 | 644 | ||
852 | void ath9k_reload_chainmask_settings(struct ath_softc *sc) | ||
853 | { | ||
854 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)) | ||
855 | return; | ||
856 | |||
857 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) | ||
858 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
859 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) | ||
860 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
861 | } | ||
862 | |||
863 | static const struct ieee80211_iface_limit if_limits[] = { | 645 | static const struct ieee80211_iface_limit if_limits[] = { |
864 | { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | | 646 | { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | |
865 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | 647 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
@@ -949,6 +731,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
949 | hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 731 | hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
950 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; | 732 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; |
951 | hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; | 733 | hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; |
734 | hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; | ||
952 | 735 | ||
953 | hw->queues = 4; | 736 | hw->queues = 4; |
954 | hw->max_rates = 4; | 737 | hw->max_rates = 4; |
@@ -969,13 +752,13 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
969 | 752 | ||
970 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) | 753 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) |
971 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | 754 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
972 | &sc->sbands[IEEE80211_BAND_2GHZ]; | 755 | &common->sbands[IEEE80211_BAND_2GHZ]; |
973 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) | 756 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) |
974 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 757 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
975 | &sc->sbands[IEEE80211_BAND_5GHZ]; | 758 | &common->sbands[IEEE80211_BAND_5GHZ]; |
976 | 759 | ||
977 | ath9k_init_wow(hw); | 760 | ath9k_init_wow(hw); |
978 | ath9k_reload_chainmask_settings(sc); | 761 | ath9k_cmn_reload_chainmask(ah); |
979 | 762 | ||
980 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | 763 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); |
981 | } | 764 | } |
@@ -1106,19 +889,11 @@ static int __init ath9k_init(void) | |||
1106 | { | 889 | { |
1107 | int error; | 890 | int error; |
1108 | 891 | ||
1109 | /* Register rate control algorithm */ | ||
1110 | error = ath_rate_control_register(); | ||
1111 | if (error != 0) { | ||
1112 | pr_err("Unable to register rate control algorithm: %d\n", | ||
1113 | error); | ||
1114 | goto err_out; | ||
1115 | } | ||
1116 | |||
1117 | error = ath_pci_init(); | 892 | error = ath_pci_init(); |
1118 | if (error < 0) { | 893 | if (error < 0) { |
1119 | pr_err("No PCI devices found, driver not installed\n"); | 894 | pr_err("No PCI devices found, driver not installed\n"); |
1120 | error = -ENODEV; | 895 | error = -ENODEV; |
1121 | goto err_rate_unregister; | 896 | goto err_out; |
1122 | } | 897 | } |
1123 | 898 | ||
1124 | error = ath_ahb_init(); | 899 | error = ath_ahb_init(); |
@@ -1131,9 +906,6 @@ static int __init ath9k_init(void) | |||
1131 | 906 | ||
1132 | err_pci_exit: | 907 | err_pci_exit: |
1133 | ath_pci_exit(); | 908 | ath_pci_exit(); |
1134 | |||
1135 | err_rate_unregister: | ||
1136 | ath_rate_control_unregister(); | ||
1137 | err_out: | 909 | err_out: |
1138 | return error; | 910 | return error; |
1139 | } | 911 | } |
@@ -1144,7 +916,6 @@ static void __exit ath9k_exit(void) | |||
1144 | is_ath9k_unloaded = true; | 916 | is_ath9k_unloaded = true; |
1145 | ath_ahb_exit(); | 917 | ath_ahb_exit(); |
1146 | ath_pci_exit(); | 918 | ath_pci_exit(); |
1147 | ath_rate_control_unregister(); | ||
1148 | pr_info("%s: Driver unloaded\n", dev_info); | 919 | pr_info("%s: Driver unloaded\n", dev_info); |
1149 | } | 920 | } |
1150 | module_exit(ath9k_exit); | 921 | module_exit(ath9k_exit); |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 30dcef5aba10..72a715fe8f24 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -115,13 +115,14 @@ void ath_hw_pll_work(struct work_struct *work) | |||
115 | u32 pll_sqsum; | 115 | u32 pll_sqsum; |
116 | struct ath_softc *sc = container_of(work, struct ath_softc, | 116 | struct ath_softc *sc = container_of(work, struct ath_softc, |
117 | hw_pll_work.work); | 117 | hw_pll_work.work); |
118 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
118 | /* | 119 | /* |
119 | * ensure that the PLL WAR is executed only | 120 | * ensure that the PLL WAR is executed only |
120 | * after the STA is associated (or) if the | 121 | * after the STA is associated (or) if the |
121 | * beaconing had started in interfaces that | 122 | * beaconing had started in interfaces that |
122 | * uses beacons. | 123 | * uses beacons. |
123 | */ | 124 | */ |
124 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) | 125 | if (!test_bit(ATH_OP_BEACONS, &common->op_flags)) |
125 | return; | 126 | return; |
126 | 127 | ||
127 | if (sc->tx99_state) | 128 | if (sc->tx99_state) |
@@ -414,7 +415,7 @@ void ath_start_ani(struct ath_softc *sc) | |||
414 | unsigned long timestamp = jiffies_to_msecs(jiffies); | 415 | unsigned long timestamp = jiffies_to_msecs(jiffies); |
415 | 416 | ||
416 | if (common->disable_ani || | 417 | if (common->disable_ani || |
417 | !test_bit(SC_OP_ANI_RUN, &sc->sc_flags) || | 418 | !test_bit(ATH_OP_ANI_RUN, &common->op_flags) || |
418 | (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | 419 | (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) |
419 | return; | 420 | return; |
420 | 421 | ||
@@ -438,6 +439,7 @@ void ath_stop_ani(struct ath_softc *sc) | |||
438 | void ath_check_ani(struct ath_softc *sc) | 439 | void ath_check_ani(struct ath_softc *sc) |
439 | { | 440 | { |
440 | struct ath_hw *ah = sc->sc_ah; | 441 | struct ath_hw *ah = sc->sc_ah; |
442 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
441 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | 443 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; |
442 | 444 | ||
443 | /* | 445 | /* |
@@ -453,23 +455,23 @@ void ath_check_ani(struct ath_softc *sc) | |||
453 | * Disable ANI only when there are no | 455 | * Disable ANI only when there are no |
454 | * associated stations. | 456 | * associated stations. |
455 | */ | 457 | */ |
456 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | 458 | if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) |
457 | goto stop_ani; | 459 | goto stop_ani; |
458 | } | 460 | } |
459 | } else if (ah->opmode == NL80211_IFTYPE_STATION) { | 461 | } else if (ah->opmode == NL80211_IFTYPE_STATION) { |
460 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | 462 | if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) |
461 | goto stop_ani; | 463 | goto stop_ani; |
462 | } | 464 | } |
463 | 465 | ||
464 | if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) { | 466 | if (!test_bit(ATH_OP_ANI_RUN, &common->op_flags)) { |
465 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 467 | set_bit(ATH_OP_ANI_RUN, &common->op_flags); |
466 | ath_start_ani(sc); | 468 | ath_start_ani(sc); |
467 | } | 469 | } |
468 | 470 | ||
469 | return; | 471 | return; |
470 | 472 | ||
471 | stop_ani: | 473 | stop_ani: |
472 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 474 | clear_bit(ATH_OP_ANI_RUN, &common->op_flags); |
473 | ath_stop_ani(sc); | 475 | ath_stop_ani(sc); |
474 | } | 476 | } |
475 | 477 | ||
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 5f727588ca27..51ce36f108f9 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -827,7 +827,7 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) | |||
827 | return; | 827 | return; |
828 | } | 828 | } |
829 | 829 | ||
830 | if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) | 830 | if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) |
831 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | 831 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; |
832 | 832 | ||
833 | async_mask = AR_INTR_MAC_IRQ; | 833 | async_mask = AR_INTR_MAC_IRQ; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 10271373a0cd..89df634e81f9 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -155,12 +155,8 @@ struct ath_htc_rx_status { | |||
155 | u8 rs_status; | 155 | u8 rs_status; |
156 | u8 rs_phyerr; | 156 | u8 rs_phyerr; |
157 | int8_t rs_rssi; | 157 | int8_t rs_rssi; |
158 | int8_t rs_rssi_ctl0; | 158 | int8_t rs_rssi_ctl[3]; |
159 | int8_t rs_rssi_ctl1; | 159 | int8_t rs_rssi_ext[3]; |
160 | int8_t rs_rssi_ctl2; | ||
161 | int8_t rs_rssi_ext0; | ||
162 | int8_t rs_rssi_ext1; | ||
163 | int8_t rs_rssi_ext2; | ||
164 | u8 rs_keyix; | 160 | u8 rs_keyix; |
165 | u8 rs_rate; | 161 | u8 rs_rate; |
166 | u8 rs_antenna; | 162 | u8 rs_antenna; |
@@ -170,6 +166,7 @@ struct ath_htc_rx_status { | |||
170 | u8 rs_num_delims; | 166 | u8 rs_num_delims; |
171 | u8 rs_flags; | 167 | u8 rs_flags; |
172 | u8 rs_dummy; | 168 | u8 rs_dummy; |
169 | /* FIXME: evm* never used? */ | ||
173 | __be32 evm0; | 170 | __be32 evm0; |
174 | __be32 evm1; | 171 | __be32 evm1; |
175 | __be32 evm2; | 172 | __be32 evm2; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5924f72dd493..d69853b848ce 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -229,16 +229,16 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
229 | ath9k_cmn_update_txpow(ah, sc->curtxpow, | 229 | ath9k_cmn_update_txpow(ah, sc->curtxpow, |
230 | sc->config.txpowlimit, &sc->curtxpow); | 230 | sc->config.txpowlimit, &sc->curtxpow); |
231 | 231 | ||
232 | clear_bit(SC_OP_HW_RESET, &sc->sc_flags); | 232 | clear_bit(ATH_OP_HW_RESET, &common->op_flags); |
233 | ath9k_hw_set_interrupts(ah); | 233 | ath9k_hw_set_interrupts(ah); |
234 | ath9k_hw_enable_interrupts(ah); | 234 | ath9k_hw_enable_interrupts(ah); |
235 | 235 | ||
236 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) { | 236 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) { |
237 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) | 237 | if (!test_bit(ATH_OP_BEACONS, &common->op_flags)) |
238 | goto work; | 238 | goto work; |
239 | 239 | ||
240 | if (ah->opmode == NL80211_IFTYPE_STATION && | 240 | if (ah->opmode == NL80211_IFTYPE_STATION && |
241 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | 241 | test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) { |
242 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 242 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
243 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | 243 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; |
244 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 244 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
@@ -336,7 +336,7 @@ static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chand | |||
336 | int old_pos = -1; | 336 | int old_pos = -1; |
337 | int r; | 337 | int r; |
338 | 338 | ||
339 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) | 339 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) |
340 | return -EIO; | 340 | return -EIO; |
341 | 341 | ||
342 | offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); | 342 | offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); |
@@ -402,7 +402,7 @@ static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chand | |||
402 | chan->center_freq); | 402 | chan->center_freq); |
403 | } else { | 403 | } else { |
404 | /* perform spectral scan if requested. */ | 404 | /* perform spectral scan if requested. */ |
405 | if (test_bit(SC_OP_SCANNING, &sc->sc_flags) && | 405 | if (test_bit(ATH_OP_SCANNING, &common->op_flags) && |
406 | sc->spectral_mode == SPECTRAL_CHANSCAN) | 406 | sc->spectral_mode == SPECTRAL_CHANSCAN) |
407 | ath9k_spectral_scan_trigger(hw); | 407 | ath9k_spectral_scan_trigger(hw); |
408 | } | 408 | } |
@@ -451,7 +451,7 @@ void ath9k_tasklet(unsigned long data) | |||
451 | * interrupts are enabled in the reset routine. | 451 | * interrupts are enabled in the reset routine. |
452 | */ | 452 | */ |
453 | atomic_inc(&ah->intr_ref_cnt); | 453 | atomic_inc(&ah->intr_ref_cnt); |
454 | ath_dbg(common, ANY, "FATAL: Skipping interrupts\n"); | 454 | ath_dbg(common, RESET, "FATAL: Skipping interrupts\n"); |
455 | goto out; | 455 | goto out; |
456 | } | 456 | } |
457 | 457 | ||
@@ -471,7 +471,7 @@ void ath9k_tasklet(unsigned long data) | |||
471 | * interrupts are enabled in the reset routine. | 471 | * interrupts are enabled in the reset routine. |
472 | */ | 472 | */ |
473 | atomic_inc(&ah->intr_ref_cnt); | 473 | atomic_inc(&ah->intr_ref_cnt); |
474 | ath_dbg(common, ANY, | 474 | ath_dbg(common, RESET, |
475 | "BB_WATCHDOG: Skipping interrupts\n"); | 475 | "BB_WATCHDOG: Skipping interrupts\n"); |
476 | goto out; | 476 | goto out; |
477 | } | 477 | } |
@@ -484,7 +484,7 @@ void ath9k_tasklet(unsigned long data) | |||
484 | type = RESET_TYPE_TX_GTT; | 484 | type = RESET_TYPE_TX_GTT; |
485 | ath9k_queue_reset(sc, type); | 485 | ath9k_queue_reset(sc, type); |
486 | atomic_inc(&ah->intr_ref_cnt); | 486 | atomic_inc(&ah->intr_ref_cnt); |
487 | ath_dbg(common, ANY, | 487 | ath_dbg(common, RESET, |
488 | "GTT: Skipping interrupts\n"); | 488 | "GTT: Skipping interrupts\n"); |
489 | goto out; | 489 | goto out; |
490 | } | 490 | } |
@@ -566,6 +566,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
566 | 566 | ||
567 | struct ath_softc *sc = dev; | 567 | struct ath_softc *sc = dev; |
568 | struct ath_hw *ah = sc->sc_ah; | 568 | struct ath_hw *ah = sc->sc_ah; |
569 | struct ath_common *common = ath9k_hw_common(ah); | ||
569 | enum ath9k_int status; | 570 | enum ath9k_int status; |
570 | u32 sync_cause = 0; | 571 | u32 sync_cause = 0; |
571 | bool sched = false; | 572 | bool sched = false; |
@@ -575,7 +576,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
575 | * touch anything. Note this can happen early | 576 | * touch anything. Note this can happen early |
576 | * on if the IRQ is shared. | 577 | * on if the IRQ is shared. |
577 | */ | 578 | */ |
578 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) | 579 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) |
579 | return IRQ_NONE; | 580 | return IRQ_NONE; |
580 | 581 | ||
581 | /* shared irq, not for us */ | 582 | /* shared irq, not for us */ |
@@ -583,7 +584,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
583 | if (!ath9k_hw_intrpend(ah)) | 584 | if (!ath9k_hw_intrpend(ah)) |
584 | return IRQ_NONE; | 585 | return IRQ_NONE; |
585 | 586 | ||
586 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) { | 587 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) { |
587 | ath9k_hw_kill_interrupts(ah); | 588 | ath9k_hw_kill_interrupts(ah); |
588 | return IRQ_HANDLED; | 589 | return IRQ_HANDLED; |
589 | } | 590 | } |
@@ -684,10 +685,11 @@ int ath_reset(struct ath_softc *sc) | |||
684 | 685 | ||
685 | void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type) | 686 | void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type) |
686 | { | 687 | { |
688 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
687 | #ifdef CONFIG_ATH9K_DEBUGFS | 689 | #ifdef CONFIG_ATH9K_DEBUGFS |
688 | RESET_STAT_INC(sc, type); | 690 | RESET_STAT_INC(sc, type); |
689 | #endif | 691 | #endif |
690 | set_bit(SC_OP_HW_RESET, &sc->sc_flags); | 692 | set_bit(ATH_OP_HW_RESET, &common->op_flags); |
691 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 693 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
692 | } | 694 | } |
693 | 695 | ||
@@ -768,7 +770,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
768 | 770 | ||
769 | ath_mci_enable(sc); | 771 | ath_mci_enable(sc); |
770 | 772 | ||
771 | clear_bit(SC_OP_INVALID, &sc->sc_flags); | 773 | clear_bit(ATH_OP_INVALID, &common->op_flags); |
772 | sc->sc_ah->is_monitoring = false; | 774 | sc->sc_ah->is_monitoring = false; |
773 | 775 | ||
774 | if (!ath_complete_reset(sc, false)) | 776 | if (!ath_complete_reset(sc, false)) |
@@ -885,7 +887,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
885 | 887 | ||
886 | ath_cancel_work(sc); | 888 | ath_cancel_work(sc); |
887 | 889 | ||
888 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { | 890 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) { |
889 | ath_dbg(common, ANY, "Device not present\n"); | 891 | ath_dbg(common, ANY, "Device not present\n"); |
890 | mutex_unlock(&sc->mutex); | 892 | mutex_unlock(&sc->mutex); |
891 | return; | 893 | return; |
@@ -940,7 +942,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
940 | 942 | ||
941 | ath9k_ps_restore(sc); | 943 | ath9k_ps_restore(sc); |
942 | 944 | ||
943 | set_bit(SC_OP_INVALID, &sc->sc_flags); | 945 | set_bit(ATH_OP_INVALID, &common->op_flags); |
944 | sc->ps_idle = prev_idle; | 946 | sc->ps_idle = prev_idle; |
945 | 947 | ||
946 | mutex_unlock(&sc->mutex); | 948 | mutex_unlock(&sc->mutex); |
@@ -1081,7 +1083,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1081 | */ | 1083 | */ |
1082 | if (ah->opmode == NL80211_IFTYPE_STATION && | 1084 | if (ah->opmode == NL80211_IFTYPE_STATION && |
1083 | old_opmode == NL80211_IFTYPE_AP && | 1085 | old_opmode == NL80211_IFTYPE_AP && |
1084 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | 1086 | test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) { |
1085 | ieee80211_iterate_active_interfaces_atomic( | 1087 | ieee80211_iterate_active_interfaces_atomic( |
1086 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, | 1088 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
1087 | ath9k_sta_vif_iter, sc); | 1089 | ath9k_sta_vif_iter, sc); |
@@ -1178,9 +1180,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1178 | if (ath9k_uses_beacons(vif->type)) | 1180 | if (ath9k_uses_beacons(vif->type)) |
1179 | ath9k_beacon_remove_slot(sc, vif); | 1181 | ath9k_beacon_remove_slot(sc, vif); |
1180 | 1182 | ||
1181 | if (sc->csa_vif == vif) | ||
1182 | sc->csa_vif = NULL; | ||
1183 | |||
1184 | ath9k_ps_wakeup(sc); | 1183 | ath9k_ps_wakeup(sc); |
1185 | ath9k_calculate_summary_state(hw, NULL); | 1184 | ath9k_calculate_summary_state(hw, NULL); |
1186 | ath9k_ps_restore(sc); | 1185 | ath9k_ps_restore(sc); |
@@ -1593,7 +1592,7 @@ static void ath9k_set_assoc_state(struct ath_softc *sc, | |||
1593 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 1592 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
1594 | unsigned long flags; | 1593 | unsigned long flags; |
1595 | 1594 | ||
1596 | set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); | 1595 | set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); |
1597 | avp->primary_sta_vif = true; | 1596 | avp->primary_sta_vif = true; |
1598 | 1597 | ||
1599 | /* | 1598 | /* |
@@ -1609,7 +1608,7 @@ static void ath9k_set_assoc_state(struct ath_softc *sc, | |||
1609 | common->curaid = bss_conf->aid; | 1608 | common->curaid = bss_conf->aid; |
1610 | ath9k_hw_write_associd(sc->sc_ah); | 1609 | ath9k_hw_write_associd(sc->sc_ah); |
1611 | 1610 | ||
1612 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 1611 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; |
1613 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1612 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
1614 | 1613 | ||
1615 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 1614 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
@@ -1628,8 +1627,9 @@ static void ath9k_bss_assoc_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1628 | { | 1627 | { |
1629 | struct ath_softc *sc = data; | 1628 | struct ath_softc *sc = data; |
1630 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 1629 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
1630 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1631 | 1631 | ||
1632 | if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | 1632 | if (test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) |
1633 | return; | 1633 | return; |
1634 | 1634 | ||
1635 | if (bss_conf->assoc) | 1635 | if (bss_conf->assoc) |
@@ -1660,18 +1660,18 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1660 | bss_conf->bssid, bss_conf->assoc); | 1660 | bss_conf->bssid, bss_conf->assoc); |
1661 | 1661 | ||
1662 | if (avp->primary_sta_vif && !bss_conf->assoc) { | 1662 | if (avp->primary_sta_vif && !bss_conf->assoc) { |
1663 | clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); | 1663 | clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); |
1664 | avp->primary_sta_vif = false; | 1664 | avp->primary_sta_vif = false; |
1665 | 1665 | ||
1666 | if (ah->opmode == NL80211_IFTYPE_STATION) | 1666 | if (ah->opmode == NL80211_IFTYPE_STATION) |
1667 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | 1667 | clear_bit(ATH_OP_BEACONS, &common->op_flags); |
1668 | } | 1668 | } |
1669 | 1669 | ||
1670 | ieee80211_iterate_active_interfaces_atomic( | 1670 | ieee80211_iterate_active_interfaces_atomic( |
1671 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, | 1671 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
1672 | ath9k_bss_assoc_iter, sc); | 1672 | ath9k_bss_assoc_iter, sc); |
1673 | 1673 | ||
1674 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) && | 1674 | if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags) && |
1675 | ah->opmode == NL80211_IFTYPE_STATION) { | 1675 | ah->opmode == NL80211_IFTYPE_STATION) { |
1676 | memset(common->curbssid, 0, ETH_ALEN); | 1676 | memset(common->curbssid, 0, ETH_ALEN); |
1677 | common->curaid = 0; | 1677 | common->curaid = 0; |
@@ -1866,7 +1866,7 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | |||
1866 | 1866 | ||
1867 | static bool ath9k_has_tx_pending(struct ath_softc *sc) | 1867 | static bool ath9k_has_tx_pending(struct ath_softc *sc) |
1868 | { | 1868 | { |
1869 | int i, npend; | 1869 | int i, npend = 0; |
1870 | 1870 | ||
1871 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 1871 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
1872 | if (!ATH_TXQ_SETUP(sc, i)) | 1872 | if (!ATH_TXQ_SETUP(sc, i)) |
@@ -1900,7 +1900,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | |||
1900 | return; | 1900 | return; |
1901 | } | 1901 | } |
1902 | 1902 | ||
1903 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { | 1903 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) { |
1904 | ath_dbg(common, ANY, "Device not present\n"); | 1904 | ath_dbg(common, ANY, "Device not present\n"); |
1905 | mutex_unlock(&sc->mutex); | 1905 | mutex_unlock(&sc->mutex); |
1906 | return; | 1906 | return; |
@@ -2056,7 +2056,7 @@ static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) | |||
2056 | ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant); | 2056 | ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant); |
2057 | 2057 | ||
2058 | ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant); | 2058 | ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant); |
2059 | ath9k_reload_chainmask_settings(sc); | 2059 | ath9k_cmn_reload_chainmask(ah); |
2060 | 2060 | ||
2061 | return 0; | 2061 | return 0; |
2062 | } | 2062 | } |
@@ -2073,26 +2073,23 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) | |||
2073 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | 2073 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) |
2074 | { | 2074 | { |
2075 | struct ath_softc *sc = hw->priv; | 2075 | struct ath_softc *sc = hw->priv; |
2076 | set_bit(SC_OP_SCANNING, &sc->sc_flags); | 2076 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2077 | set_bit(ATH_OP_SCANNING, &common->op_flags); | ||
2077 | } | 2078 | } |
2078 | 2079 | ||
2079 | static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | 2080 | static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) |
2080 | { | 2081 | { |
2081 | struct ath_softc *sc = hw->priv; | 2082 | struct ath_softc *sc = hw->priv; |
2082 | clear_bit(SC_OP_SCANNING, &sc->sc_flags); | 2083 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2084 | clear_bit(ATH_OP_SCANNING, &common->op_flags); | ||
2083 | } | 2085 | } |
2084 | 2086 | ||
2085 | static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw, | 2087 | static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw, |
2086 | struct ieee80211_vif *vif, | 2088 | struct ieee80211_vif *vif, |
2087 | struct cfg80211_chan_def *chandef) | 2089 | struct cfg80211_chan_def *chandef) |
2088 | { | 2090 | { |
2089 | struct ath_softc *sc = hw->priv; | 2091 | /* depend on vif->csa_active only */ |
2090 | 2092 | return; | |
2091 | /* mac80211 does not support CSA in multi-if cases (yet) */ | ||
2092 | if (WARN_ON(sc->csa_vif)) | ||
2093 | return; | ||
2094 | |||
2095 | sc->csa_vif = vif; | ||
2096 | } | 2093 | } |
2097 | 2094 | ||
2098 | struct ieee80211_ops ath9k_ops = { | 2095 | struct ieee80211_ops ath9k_ops = { |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 71799fcade54..a0dbcc412384 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -555,7 +555,7 @@ void ath_mci_intr(struct ath_softc *sc) | |||
555 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; | 555 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; |
556 | 556 | ||
557 | while (more_data == MCI_GPM_MORE) { | 557 | while (more_data == MCI_GPM_MORE) { |
558 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) | 558 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) |
559 | return; | 559 | return; |
560 | 560 | ||
561 | pgpm = mci->gpm_buf.bf_addr; | 561 | pgpm = mci->gpm_buf.bf_addr; |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 55724b02316b..25304adece57 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -784,6 +784,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
784 | { | 784 | { |
785 | struct ath_softc *sc; | 785 | struct ath_softc *sc; |
786 | struct ieee80211_hw *hw; | 786 | struct ieee80211_hw *hw; |
787 | struct ath_common *common; | ||
787 | u8 csz; | 788 | u8 csz; |
788 | u32 val; | 789 | u32 val; |
789 | int ret = 0; | 790 | int ret = 0; |
@@ -858,9 +859,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
858 | sc->mem = pcim_iomap_table(pdev)[0]; | 859 | sc->mem = pcim_iomap_table(pdev)[0]; |
859 | sc->driver_data = id->driver_data; | 860 | sc->driver_data = id->driver_data; |
860 | 861 | ||
861 | /* Will be cleared in ath9k_start() */ | ||
862 | set_bit(SC_OP_INVALID, &sc->sc_flags); | ||
863 | |||
864 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 862 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
865 | if (ret) { | 863 | if (ret) { |
866 | dev_err(&pdev->dev, "request_irq failed\n"); | 864 | dev_err(&pdev->dev, "request_irq failed\n"); |
@@ -879,6 +877,10 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
879 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", | 877 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", |
880 | hw_name, (unsigned long)sc->mem, pdev->irq); | 878 | hw_name, (unsigned long)sc->mem, pdev->irq); |
881 | 879 | ||
880 | /* Will be cleared in ath9k_start() */ | ||
881 | common = ath9k_hw_common(sc->sc_ah); | ||
882 | set_bit(ATH_OP_INVALID, &common->op_flags); | ||
883 | |||
882 | return 0; | 884 | return 0; |
883 | 885 | ||
884 | err_init: | 886 | err_init: |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c deleted file mode 100644 index d829bb62a3fc..000000000000 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ /dev/null | |||
@@ -1,1495 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004 Video54 Technologies, Inc. | ||
3 | * Copyright (c) 2004-2011 Atheros Communications, Inc. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and/or distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include <linux/slab.h> | ||
19 | #include <linux/export.h> | ||
20 | |||
21 | #include "ath9k.h" | ||
22 | |||
23 | static const struct ath_rate_table ar5416_11na_ratetable = { | ||
24 | 68, | ||
25 | 8, /* MCS start */ | ||
26 | { | ||
27 | [0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, | ||
28 | 5400, 0, 12 }, /* 6 Mb */ | ||
29 | [1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, | ||
30 | 7800, 1, 18 }, /* 9 Mb */ | ||
31 | [2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, | ||
32 | 10000, 2, 24 }, /* 12 Mb */ | ||
33 | [3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, | ||
34 | 13900, 3, 36 }, /* 18 Mb */ | ||
35 | [4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, | ||
36 | 17300, 4, 48 }, /* 24 Mb */ | ||
37 | [5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, | ||
38 | 23000, 5, 72 }, /* 36 Mb */ | ||
39 | [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, | ||
40 | 27400, 6, 96 }, /* 48 Mb */ | ||
41 | [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, | ||
42 | 29300, 7, 108 }, /* 54 Mb */ | ||
43 | [8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500, | ||
44 | 6400, 0, 0 }, /* 6.5 Mb */ | ||
45 | [9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, | ||
46 | 12700, 1, 1 }, /* 13 Mb */ | ||
47 | [10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, | ||
48 | 18800, 2, 2 }, /* 19.5 Mb */ | ||
49 | [11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, | ||
50 | 25000, 3, 3 }, /* 26 Mb */ | ||
51 | [12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, | ||
52 | 36700, 4, 4 }, /* 39 Mb */ | ||
53 | [13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, | ||
54 | 48100, 5, 5 }, /* 52 Mb */ | ||
55 | [14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, | ||
56 | 53500, 6, 6 }, /* 58.5 Mb */ | ||
57 | [15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, | ||
58 | 59000, 7, 7 }, /* 65 Mb */ | ||
59 | [16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, | ||
60 | 65400, 7, 7 }, /* 75 Mb */ | ||
61 | [17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, | ||
62 | 12700, 8, 8 }, /* 13 Mb */ | ||
63 | [18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, | ||
64 | 24800, 9, 9 }, /* 26 Mb */ | ||
65 | [19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, | ||
66 | 36600, 10, 10 }, /* 39 Mb */ | ||
67 | [20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, | ||
68 | 48100, 11, 11 }, /* 52 Mb */ | ||
69 | [21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, | ||
70 | 69500, 12, 12 }, /* 78 Mb */ | ||
71 | [22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, | ||
72 | 89500, 13, 13 }, /* 104 Mb */ | ||
73 | [23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, | ||
74 | 98900, 14, 14 }, /* 117 Mb */ | ||
75 | [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, | ||
76 | 108300, 15, 15 }, /* 130 Mb */ | ||
77 | [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, | ||
78 | 120000, 15, 15 }, /* 144.4 Mb */ | ||
79 | [26] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, | ||
80 | 17400, 16, 16 }, /* 19.5 Mb */ | ||
81 | [27] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, | ||
82 | 35100, 17, 17 }, /* 39 Mb */ | ||
83 | [28] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, | ||
84 | 52600, 18, 18 }, /* 58.5 Mb */ | ||
85 | [29] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, | ||
86 | 70400, 19, 19 }, /* 78 Mb */ | ||
87 | [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, | ||
88 | 104900, 20, 20 }, /* 117 Mb */ | ||
89 | [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, | ||
90 | 115800, 20, 20 }, /* 130 Mb*/ | ||
91 | [32] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, | ||
92 | 137200, 21, 21 }, /* 156 Mb */ | ||
93 | [33] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, | ||
94 | 151100, 21, 21 }, /* 173.3 Mb */ | ||
95 | [34] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, | ||
96 | 152800, 22, 22 }, /* 175.5 Mb */ | ||
97 | [35] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, | ||
98 | 168400, 22, 22 }, /* 195 Mb*/ | ||
99 | [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, | ||
100 | 168400, 23, 23 }, /* 195 Mb */ | ||
101 | [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, | ||
102 | 185000, 23, 23 }, /* 216.7 Mb */ | ||
103 | [38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, | ||
104 | 13200, 0, 0 }, /* 13.5 Mb*/ | ||
105 | [39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, | ||
106 | 25900, 1, 1 }, /* 27.0 Mb*/ | ||
107 | [40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, | ||
108 | 38600, 2, 2 }, /* 40.5 Mb*/ | ||
109 | [41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, | ||
110 | 49800, 3, 3 }, /* 54 Mb */ | ||
111 | [42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, | ||
112 | 72200, 4, 4 }, /* 81 Mb */ | ||
113 | [43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000, | ||
114 | 92900, 5, 5 }, /* 108 Mb */ | ||
115 | [44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, | ||
116 | 102700, 6, 6 }, /* 121.5 Mb*/ | ||
117 | [45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, | ||
118 | 112000, 7, 7 }, /* 135 Mb */ | ||
119 | [46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, | ||
120 | 122000, 7, 7 }, /* 150 Mb */ | ||
121 | [47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, | ||
122 | 25800, 8, 8 }, /* 27 Mb */ | ||
123 | [48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, | ||
124 | 49800, 9, 9 }, /* 54 Mb */ | ||
125 | [49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, | ||
126 | 71900, 10, 10 }, /* 81 Mb */ | ||
127 | [50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, | ||
128 | 92500, 11, 11 }, /* 108 Mb */ | ||
129 | [51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, | ||
130 | 130300, 12, 12 }, /* 162 Mb */ | ||
131 | [52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, | ||
132 | 162800, 13, 13 }, /* 216 Mb */ | ||
133 | [53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, | ||
134 | 178200, 14, 14 }, /* 243 Mb */ | ||
135 | [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, | ||
136 | 192100, 15, 15 }, /* 270 Mb */ | ||
137 | [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, | ||
138 | 207000, 15, 15 }, /* 300 Mb */ | ||
139 | [56] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, | ||
140 | 36100, 16, 16 }, /* 40.5 Mb */ | ||
141 | [57] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, | ||
142 | 72900, 17, 17 }, /* 81 Mb */ | ||
143 | [58] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, | ||
144 | 108300, 18, 18 }, /* 121.5 Mb */ | ||
145 | [59] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, | ||
146 | 142000, 19, 19 }, /* 162 Mb */ | ||
147 | [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, | ||
148 | 205100, 20, 20 }, /* 243 Mb */ | ||
149 | [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, | ||
150 | 224700, 20, 20 }, /* 270 Mb */ | ||
151 | [62] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, | ||
152 | 263100, 21, 21 }, /* 324 Mb */ | ||
153 | [63] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, | ||
154 | 288000, 21, 21 }, /* 360 Mb */ | ||
155 | [64] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, | ||
156 | 290700, 22, 22 }, /* 364.5 Mb */ | ||
157 | [65] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, | ||
158 | 317200, 22, 22 }, /* 405 Mb */ | ||
159 | [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, | ||
160 | 317200, 23, 23 }, /* 405 Mb */ | ||
161 | [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, | ||
162 | 346400, 23, 23 }, /* 450 Mb */ | ||
163 | }, | ||
164 | 50, /* probe interval */ | ||
165 | WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ | ||
166 | }; | ||
167 | |||
168 | /* 4ms frame limit not used for NG mode. The values filled | ||
169 | * for HT are the 64K max aggregate limit */ | ||
170 | |||
171 | static const struct ath_rate_table ar5416_11ng_ratetable = { | ||
172 | 72, | ||
173 | 12, /* MCS start */ | ||
174 | { | ||
175 | [0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000, | ||
176 | 900, 0, 2 }, /* 1 Mb */ | ||
177 | [1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000, | ||
178 | 1900, 1, 4 }, /* 2 Mb */ | ||
179 | [2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500, | ||
180 | 4900, 2, 11 }, /* 5.5 Mb */ | ||
181 | [3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000, | ||
182 | 8100, 3, 22 }, /* 11 Mb */ | ||
183 | [4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, | ||
184 | 5400, 4, 12 }, /* 6 Mb */ | ||
185 | [5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, | ||
186 | 7800, 5, 18 }, /* 9 Mb */ | ||
187 | [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, | ||
188 | 10100, 6, 24 }, /* 12 Mb */ | ||
189 | [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, | ||
190 | 14100, 7, 36 }, /* 18 Mb */ | ||
191 | [8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, | ||
192 | 17700, 8, 48 }, /* 24 Mb */ | ||
193 | [9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, | ||
194 | 23700, 9, 72 }, /* 36 Mb */ | ||
195 | [10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, | ||
196 | 27400, 10, 96 }, /* 48 Mb */ | ||
197 | [11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, | ||
198 | 30900, 11, 108 }, /* 54 Mb */ | ||
199 | [12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500, | ||
200 | 6400, 0, 0 }, /* 6.5 Mb */ | ||
201 | [13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, | ||
202 | 12700, 1, 1 }, /* 13 Mb */ | ||
203 | [14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, | ||
204 | 18800, 2, 2 }, /* 19.5 Mb*/ | ||
205 | [15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, | ||
206 | 25000, 3, 3 }, /* 26 Mb */ | ||
207 | [16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, | ||
208 | 36700, 4, 4 }, /* 39 Mb */ | ||
209 | [17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, | ||
210 | 48100, 5, 5 }, /* 52 Mb */ | ||
211 | [18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, | ||
212 | 53500, 6, 6 }, /* 58.5 Mb */ | ||
213 | [19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, | ||
214 | 59000, 7, 7 }, /* 65 Mb */ | ||
215 | [20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, | ||
216 | 65400, 7, 7 }, /* 65 Mb*/ | ||
217 | [21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, | ||
218 | 12700, 8, 8 }, /* 13 Mb */ | ||
219 | [22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, | ||
220 | 24800, 9, 9 }, /* 26 Mb */ | ||
221 | [23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, | ||
222 | 36600, 10, 10 }, /* 39 Mb */ | ||
223 | [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, | ||
224 | 48100, 11, 11 }, /* 52 Mb */ | ||
225 | [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, | ||
226 | 69500, 12, 12 }, /* 78 Mb */ | ||
227 | [26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, | ||
228 | 89500, 13, 13 }, /* 104 Mb */ | ||
229 | [27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, | ||
230 | 98900, 14, 14 }, /* 117 Mb */ | ||
231 | [28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, | ||
232 | 108300, 15, 15 }, /* 130 Mb */ | ||
233 | [29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, | ||
234 | 120000, 15, 15 }, /* 144.4 Mb */ | ||
235 | [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, | ||
236 | 17400, 16, 16 }, /* 19.5 Mb */ | ||
237 | [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, | ||
238 | 35100, 17, 17 }, /* 39 Mb */ | ||
239 | [32] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, | ||
240 | 52600, 18, 18 }, /* 58.5 Mb */ | ||
241 | [33] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, | ||
242 | 70400, 19, 19 }, /* 78 Mb */ | ||
243 | [34] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, | ||
244 | 104900, 20, 20 }, /* 117 Mb */ | ||
245 | [35] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, | ||
246 | 115800, 20, 20 }, /* 130 Mb */ | ||
247 | [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, | ||
248 | 137200, 21, 21 }, /* 156 Mb */ | ||
249 | [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, | ||
250 | 151100, 21, 21 }, /* 173.3 Mb */ | ||
251 | [38] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, | ||
252 | 152800, 22, 22 }, /* 175.5 Mb */ | ||
253 | [39] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, | ||
254 | 168400, 22, 22 }, /* 195 Mb */ | ||
255 | [40] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, | ||
256 | 168400, 23, 23 }, /* 195 Mb */ | ||
257 | [41] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, | ||
258 | 185000, 23, 23 }, /* 216.7 Mb */ | ||
259 | [42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, | ||
260 | 13200, 0, 0 }, /* 13.5 Mb */ | ||
261 | [43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, | ||
262 | 25900, 1, 1 }, /* 27.0 Mb */ | ||
263 | [44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, | ||
264 | 38600, 2, 2 }, /* 40.5 Mb */ | ||
265 | [45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, | ||
266 | 49800, 3, 3 }, /* 54 Mb */ | ||
267 | [46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, | ||
268 | 72200, 4, 4 }, /* 81 Mb */ | ||
269 | [47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000, | ||
270 | 92900, 5, 5 }, /* 108 Mb */ | ||
271 | [48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, | ||
272 | 102700, 6, 6 }, /* 121.5 Mb */ | ||
273 | [49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, | ||
274 | 112000, 7, 7 }, /* 135 Mb */ | ||
275 | [50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, | ||
276 | 122000, 7, 7 }, /* 150 Mb */ | ||
277 | [51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, | ||
278 | 25800, 8, 8 }, /* 27 Mb */ | ||
279 | [52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, | ||
280 | 49800, 9, 9 }, /* 54 Mb */ | ||
281 | [53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, | ||
282 | 71900, 10, 10 }, /* 81 Mb */ | ||
283 | [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, | ||
284 | 92500, 11, 11 }, /* 108 Mb */ | ||
285 | [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, | ||
286 | 130300, 12, 12 }, /* 162 Mb */ | ||
287 | [56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, | ||
288 | 162800, 13, 13 }, /* 216 Mb */ | ||
289 | [57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, | ||
290 | 178200, 14, 14 }, /* 243 Mb */ | ||
291 | [58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, | ||
292 | 192100, 15, 15 }, /* 270 Mb */ | ||
293 | [59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, | ||
294 | 207000, 15, 15 }, /* 300 Mb */ | ||
295 | [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, | ||
296 | 36100, 16, 16 }, /* 40.5 Mb */ | ||
297 | [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, | ||
298 | 72900, 17, 17 }, /* 81 Mb */ | ||
299 | [62] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, | ||
300 | 108300, 18, 18 }, /* 121.5 Mb */ | ||
301 | [63] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, | ||
302 | 142000, 19, 19 }, /* 162 Mb */ | ||
303 | [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, | ||
304 | 205100, 20, 20 }, /* 243 Mb */ | ||
305 | [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, | ||
306 | 224700, 20, 20 }, /* 270 Mb */ | ||
307 | [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, | ||
308 | 263100, 21, 21 }, /* 324 Mb */ | ||
309 | [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, | ||
310 | 288000, 21, 21 }, /* 360 Mb */ | ||
311 | [68] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, | ||
312 | 290700, 22, 22 }, /* 364.5 Mb */ | ||
313 | [69] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, | ||
314 | 317200, 22, 22 }, /* 405 Mb */ | ||
315 | [70] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, | ||
316 | 317200, 23, 23 }, /* 405 Mb */ | ||
317 | [71] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, | ||
318 | 346400, 23, 23 }, /* 450 Mb */ | ||
319 | }, | ||
320 | 50, /* probe interval */ | ||
321 | WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ | ||
322 | }; | ||
323 | |||
324 | static const struct ath_rate_table ar5416_11a_ratetable = { | ||
325 | 8, | ||
326 | 0, | ||
327 | { | ||
328 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||
329 | 5400, 0, 12}, | ||
330 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||
331 | 7800, 1, 18}, | ||
332 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||
333 | 10000, 2, 24}, | ||
334 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||
335 | 13900, 3, 36}, | ||
336 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||
337 | 17300, 4, 48}, | ||
338 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||
339 | 23000, 5, 72}, | ||
340 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||
341 | 27400, 6, 96}, | ||
342 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||
343 | 29300, 7, 108}, | ||
344 | }, | ||
345 | 50, /* probe interval */ | ||
346 | 0, /* Phy rates allowed initially */ | ||
347 | }; | ||
348 | |||
349 | static const struct ath_rate_table ar5416_11g_ratetable = { | ||
350 | 12, | ||
351 | 0, | ||
352 | { | ||
353 | { RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | ||
354 | 900, 0, 2}, | ||
355 | { RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ | ||
356 | 1900, 1, 4}, | ||
357 | { RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ | ||
358 | 4900, 2, 11}, | ||
359 | { RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ | ||
360 | 8100, 3, 22}, | ||
361 | { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||
362 | 5400, 4, 12}, | ||
363 | { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||
364 | 7800, 5, 18}, | ||
365 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||
366 | 10000, 6, 24}, | ||
367 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||
368 | 13900, 7, 36}, | ||
369 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||
370 | 17300, 8, 48}, | ||
371 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||
372 | 23000, 9, 72}, | ||
373 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||
374 | 27400, 10, 96}, | ||
375 | { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||
376 | 29300, 11, 108}, | ||
377 | }, | ||
378 | 50, /* probe interval */ | ||
379 | 0, /* Phy rates allowed initially */ | ||
380 | }; | ||
381 | |||
382 | static int ath_rc_get_rateindex(struct ath_rate_priv *ath_rc_priv, | ||
383 | struct ieee80211_tx_rate *rate) | ||
384 | { | ||
385 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | ||
386 | int rix, i, idx = 0; | ||
387 | |||
388 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) | ||
389 | return rate->idx; | ||
390 | |||
391 | for (i = 0; i < ath_rc_priv->max_valid_rate; i++) { | ||
392 | idx = ath_rc_priv->valid_rate_index[i]; | ||
393 | |||
394 | if (WLAN_RC_PHY_HT(rate_table->info[idx].phy) && | ||
395 | rate_table->info[idx].ratecode == rate->idx) | ||
396 | break; | ||
397 | } | ||
398 | |||
399 | rix = idx; | ||
400 | |||
401 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
402 | rix++; | ||
403 | |||
404 | return rix; | ||
405 | } | ||
406 | |||
407 | static void ath_rc_sort_validrates(struct ath_rate_priv *ath_rc_priv) | ||
408 | { | ||
409 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | ||
410 | u8 i, j, idx, idx_next; | ||
411 | |||
412 | for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) { | ||
413 | for (j = 0; j <= i-1; j++) { | ||
414 | idx = ath_rc_priv->valid_rate_index[j]; | ||
415 | idx_next = ath_rc_priv->valid_rate_index[j+1]; | ||
416 | |||
417 | if (rate_table->info[idx].ratekbps > | ||
418 | rate_table->info[idx_next].ratekbps) { | ||
419 | ath_rc_priv->valid_rate_index[j] = idx_next; | ||
420 | ath_rc_priv->valid_rate_index[j+1] = idx; | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | |||
426 | static inline | ||
427 | int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table, | ||
428 | struct ath_rate_priv *ath_rc_priv, | ||
429 | u8 cur_valid_txrate, | ||
430 | u8 *next_idx) | ||
431 | { | ||
432 | u8 i; | ||
433 | |||
434 | for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) { | ||
435 | if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) { | ||
436 | *next_idx = ath_rc_priv->valid_rate_index[i+1]; | ||
437 | return 1; | ||
438 | } | ||
439 | } | ||
440 | |||
441 | /* No more valid rates */ | ||
442 | *next_idx = 0; | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | /* Return true only for single stream */ | ||
448 | |||
449 | static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw) | ||
450 | { | ||
451 | if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) | ||
452 | return 0; | ||
453 | if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) | ||
454 | return 0; | ||
455 | if (WLAN_RC_PHY_TS(phy) && !(capflag & WLAN_RC_TS_FLAG)) | ||
456 | return 0; | ||
457 | if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG)) | ||
458 | return 0; | ||
459 | if (!ignore_cw && WLAN_RC_PHY_HT(phy)) | ||
460 | if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG)) | ||
461 | return 0; | ||
462 | return 1; | ||
463 | } | ||
464 | |||
465 | static inline int | ||
466 | ath_rc_get_lower_rix(struct ath_rate_priv *ath_rc_priv, | ||
467 | u8 cur_valid_txrate, u8 *next_idx) | ||
468 | { | ||
469 | int8_t i; | ||
470 | |||
471 | for (i = 1; i < ath_rc_priv->max_valid_rate ; i++) { | ||
472 | if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) { | ||
473 | *next_idx = ath_rc_priv->valid_rate_index[i-1]; | ||
474 | return 1; | ||
475 | } | ||
476 | } | ||
477 | |||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv) | ||
482 | { | ||
483 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | ||
484 | u8 i, hi = 0; | ||
485 | |||
486 | for (i = 0; i < rate_table->rate_cnt; i++) { | ||
487 | if (rate_table->info[i].rate_flags & RC_LEGACY) { | ||
488 | u32 phy = rate_table->info[i].phy; | ||
489 | u8 valid_rate_count = 0; | ||
490 | |||
491 | if (!ath_rc_valid_phyrate(phy, ath_rc_priv->ht_cap, 0)) | ||
492 | continue; | ||
493 | |||
494 | valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy]; | ||
495 | |||
496 | ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; | ||
497 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; | ||
498 | ath_rc_priv->valid_rate_index[i] = true; | ||
499 | hi = i; | ||
500 | } | ||
501 | } | ||
502 | |||
503 | return hi; | ||
504 | } | ||
505 | |||
506 | static inline bool ath_rc_check_legacy(u8 rate, u8 dot11rate, u16 rate_flags, | ||
507 | u32 phy, u32 capflag) | ||
508 | { | ||
509 | if (rate != dot11rate || WLAN_RC_PHY_HT(phy)) | ||
510 | return false; | ||
511 | |||
512 | if ((rate_flags & WLAN_RC_CAP_MODE(capflag)) != WLAN_RC_CAP_MODE(capflag)) | ||
513 | return false; | ||
514 | |||
515 | if (!(rate_flags & WLAN_RC_CAP_STREAM(capflag))) | ||
516 | return false; | ||
517 | |||
518 | return true; | ||
519 | } | ||
520 | |||
521 | static inline bool ath_rc_check_ht(u8 rate, u8 dot11rate, u16 rate_flags, | ||
522 | u32 phy, u32 capflag) | ||
523 | { | ||
524 | if (rate != dot11rate || !WLAN_RC_PHY_HT(phy)) | ||
525 | return false; | ||
526 | |||
527 | if (!WLAN_RC_PHY_HT_VALID(rate_flags, capflag)) | ||
528 | return false; | ||
529 | |||
530 | if (!(rate_flags & WLAN_RC_CAP_STREAM(capflag))) | ||
531 | return false; | ||
532 | |||
533 | return true; | ||
534 | } | ||
535 | |||
536 | static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, bool legacy) | ||
537 | { | ||
538 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | ||
539 | struct ath_rateset *rateset; | ||
540 | u32 phy, capflag = ath_rc_priv->ht_cap; | ||
541 | u16 rate_flags; | ||
542 | u8 i, j, hi = 0, rate, dot11rate, valid_rate_count; | ||
543 | |||
544 | if (legacy) | ||
545 | rateset = &ath_rc_priv->neg_rates; | ||
546 | else | ||
547 | rateset = &ath_rc_priv->neg_ht_rates; | ||
548 | |||
549 | for (i = 0; i < rateset->rs_nrates; i++) { | ||
550 | for (j = 0; j < rate_table->rate_cnt; j++) { | ||
551 | phy = rate_table->info[j].phy; | ||
552 | rate_flags = rate_table->info[j].rate_flags; | ||
553 | rate = rateset->rs_rates[i]; | ||
554 | dot11rate = rate_table->info[j].dot11rate; | ||
555 | |||
556 | if (legacy && | ||
557 | !ath_rc_check_legacy(rate, dot11rate, | ||
558 | rate_flags, phy, capflag)) | ||
559 | continue; | ||
560 | |||
561 | if (!legacy && | ||
562 | !ath_rc_check_ht(rate, dot11rate, | ||
563 | rate_flags, phy, capflag)) | ||
564 | continue; | ||
565 | |||
566 | if (!ath_rc_valid_phyrate(phy, capflag, 0)) | ||
567 | continue; | ||
568 | |||
569 | valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy]; | ||
570 | ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = j; | ||
571 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; | ||
572 | ath_rc_priv->valid_rate_index[j] = true; | ||
573 | hi = max(hi, j); | ||
574 | } | ||
575 | } | ||
576 | |||
577 | return hi; | ||
578 | } | ||
579 | |||
580 | static u8 ath_rc_get_highest_rix(struct ath_rate_priv *ath_rc_priv, | ||
581 | int *is_probing) | ||
582 | { | ||
583 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | ||
584 | u32 best_thruput, this_thruput, now_msec; | ||
585 | u8 rate, next_rate, best_rate, maxindex, minindex; | ||
586 | int8_t index = 0; | ||
587 | |||
588 | now_msec = jiffies_to_msecs(jiffies); | ||
589 | *is_probing = 0; | ||
590 | best_thruput = 0; | ||
591 | maxindex = ath_rc_priv->max_valid_rate-1; | ||
592 | minindex = 0; | ||
593 | best_rate = minindex; | ||
594 | |||
595 | /* | ||
596 | * Try the higher rate first. It will reduce memory moving time | ||
597 | * if we have very good channel characteristics. | ||
598 | */ | ||
599 | for (index = maxindex; index >= minindex ; index--) { | ||
600 | u8 per_thres; | ||
601 | |||
602 | rate = ath_rc_priv->valid_rate_index[index]; | ||
603 | if (rate > ath_rc_priv->rate_max_phy) | ||
604 | continue; | ||
605 | |||
606 | /* | ||
607 | * For TCP the average collision rate is around 11%, | ||
608 | * so we ignore PERs less than this. This is to | ||
609 | * prevent the rate we are currently using (whose | ||
610 | * PER might be in the 10-15 range because of TCP | ||
611 | * collisions) looking worse than the next lower | ||
612 | * rate whose PER has decayed close to 0. If we | ||
613 | * used to next lower rate, its PER would grow to | ||
614 | * 10-15 and we would be worse off then staying | ||
615 | * at the current rate. | ||
616 | */ | ||
617 | per_thres = ath_rc_priv->per[rate]; | ||
618 | if (per_thres < 12) | ||
619 | per_thres = 12; | ||
620 | |||
621 | this_thruput = rate_table->info[rate].user_ratekbps * | ||
622 | (100 - per_thres); | ||
623 | |||
624 | if (best_thruput <= this_thruput) { | ||
625 | best_thruput = this_thruput; | ||
626 | best_rate = rate; | ||
627 | } | ||
628 | } | ||
629 | |||
630 | rate = best_rate; | ||
631 | |||
632 | /* | ||
633 | * Must check the actual rate (ratekbps) to account for | ||
634 | * non-monoticity of 11g's rate table | ||
635 | */ | ||
636 | |||
637 | if (rate >= ath_rc_priv->rate_max_phy) { | ||
638 | rate = ath_rc_priv->rate_max_phy; | ||
639 | |||
640 | /* Probe the next allowed phy state */ | ||
641 | if (ath_rc_get_nextvalid_txrate(rate_table, | ||
642 | ath_rc_priv, rate, &next_rate) && | ||
643 | (now_msec - ath_rc_priv->probe_time > | ||
644 | rate_table->probe_interval) && | ||
645 | (ath_rc_priv->hw_maxretry_pktcnt >= 1)) { | ||
646 | rate = next_rate; | ||
647 | ath_rc_priv->probe_rate = rate; | ||
648 | ath_rc_priv->probe_time = now_msec; | ||
649 | ath_rc_priv->hw_maxretry_pktcnt = 0; | ||
650 | *is_probing = 1; | ||
651 | } | ||
652 | } | ||
653 | |||
654 | if (rate > (ath_rc_priv->rate_table_size - 1)) | ||
655 | rate = ath_rc_priv->rate_table_size - 1; | ||
656 | |||
657 | if (RC_TS_ONLY(rate_table->info[rate].rate_flags) && | ||
658 | (ath_rc_priv->ht_cap & WLAN_RC_TS_FLAG)) | ||
659 | return rate; | ||
660 | |||
661 | if (RC_DS_OR_LATER(rate_table->info[rate].rate_flags) && | ||
662 | (ath_rc_priv->ht_cap & (WLAN_RC_DS_FLAG | WLAN_RC_TS_FLAG))) | ||
663 | return rate; | ||
664 | |||
665 | if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags)) | ||
666 | return rate; | ||
667 | |||
668 | /* This should not happen */ | ||
669 | WARN_ON_ONCE(1); | ||
670 | |||
671 | rate = ath_rc_priv->valid_rate_index[0]; | ||
672 | |||
673 | return rate; | ||
674 | } | ||
675 | |||
676 | static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table, | ||
677 | struct ieee80211_tx_rate *rate, | ||
678 | struct ieee80211_tx_rate_control *txrc, | ||
679 | u8 tries, u8 rix, int rtsctsenable) | ||
680 | { | ||
681 | rate->count = tries; | ||
682 | rate->idx = rate_table->info[rix].ratecode; | ||
683 | |||
684 | if (txrc->rts || rtsctsenable) | ||
685 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; | ||
686 | |||
687 | if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) { | ||
688 | rate->flags |= IEEE80211_TX_RC_MCS; | ||
689 | if (WLAN_RC_PHY_40(rate_table->info[rix].phy) && | ||
690 | conf_is_ht40(&txrc->hw->conf)) | ||
691 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | ||
692 | if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) | ||
693 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | static void ath_rc_rate_set_rtscts(struct ath_softc *sc, | ||
698 | const struct ath_rate_table *rate_table, | ||
699 | struct ieee80211_tx_info *tx_info) | ||
700 | { | ||
701 | struct ieee80211_bss_conf *bss_conf; | ||
702 | |||
703 | if (!tx_info->control.vif) | ||
704 | return; | ||
705 | /* | ||
706 | * For legacy frames, mac80211 takes care of CTS protection. | ||
707 | */ | ||
708 | if (!(tx_info->control.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
709 | return; | ||
710 | |||
711 | bss_conf = &tx_info->control.vif->bss_conf; | ||
712 | |||
713 | if (!bss_conf->basic_rates) | ||
714 | return; | ||
715 | |||
716 | /* | ||
717 | * For now, use the lowest allowed basic rate for HT frames. | ||
718 | */ | ||
719 | tx_info->control.rts_cts_rate_idx = __ffs(bss_conf->basic_rates); | ||
720 | } | ||
721 | |||
722 | static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | ||
723 | struct ieee80211_tx_rate_control *txrc) | ||
724 | { | ||
725 | struct ath_softc *sc = priv; | ||
726 | struct ath_rate_priv *ath_rc_priv = priv_sta; | ||
727 | const struct ath_rate_table *rate_table; | ||
728 | struct sk_buff *skb = txrc->skb; | ||
729 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
730 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | ||
731 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
732 | __le16 fc = hdr->frame_control; | ||
733 | u8 try_per_rate, i = 0, rix; | ||
734 | int is_probe = 0; | ||
735 | |||
736 | if (rate_control_send_low(sta, priv_sta, txrc)) | ||
737 | return; | ||
738 | |||
739 | /* | ||
740 | * For Multi Rate Retry we use a different number of | ||
741 | * retry attempt counts. This ends up looking like this: | ||
742 | * | ||
743 | * MRR[0] = 4 | ||
744 | * MRR[1] = 4 | ||
745 | * MRR[2] = 4 | ||
746 | * MRR[3] = 8 | ||
747 | * | ||
748 | */ | ||
749 | try_per_rate = 4; | ||
750 | |||
751 | rate_table = ath_rc_priv->rate_table; | ||
752 | rix = ath_rc_get_highest_rix(ath_rc_priv, &is_probe); | ||
753 | |||
754 | if (conf_is_ht(&sc->hw->conf) && | ||
755 | (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)) | ||
756 | tx_info->flags |= IEEE80211_TX_CTL_LDPC; | ||
757 | |||
758 | if (conf_is_ht(&sc->hw->conf) && | ||
759 | (sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC)) | ||
760 | tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT); | ||
761 | |||
762 | if (is_probe) { | ||
763 | /* | ||
764 | * Set one try for probe rates. For the | ||
765 | * probes don't enable RTS. | ||
766 | */ | ||
767 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
768 | 1, rix, 0); | ||
769 | /* | ||
770 | * Get the next tried/allowed rate. | ||
771 | * No RTS for the next series after the probe rate. | ||
772 | */ | ||
773 | ath_rc_get_lower_rix(ath_rc_priv, rix, &rix); | ||
774 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
775 | try_per_rate, rix, 0); | ||
776 | |||
777 | tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
778 | } else { | ||
779 | /* | ||
780 | * Set the chosen rate. No RTS for first series entry. | ||
781 | */ | ||
782 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
783 | try_per_rate, rix, 0); | ||
784 | } | ||
785 | |||
786 | for ( ; i < 4; i++) { | ||
787 | /* | ||
788 | * Use twice the number of tries for the last MRR segment. | ||
789 | */ | ||
790 | if (i + 1 == 4) | ||
791 | try_per_rate = 8; | ||
792 | |||
793 | ath_rc_get_lower_rix(ath_rc_priv, rix, &rix); | ||
794 | |||
795 | /* | ||
796 | * All other rates in the series have RTS enabled. | ||
797 | */ | ||
798 | ath_rc_rate_set_series(rate_table, &rates[i], txrc, | ||
799 | try_per_rate, rix, 1); | ||
800 | } | ||
801 | |||
802 | /* | ||
803 | * NB:Change rate series to enable aggregation when operating | ||
804 | * at lower MCS rates. When first rate in series is MCS2 | ||
805 | * in HT40 @ 2.4GHz, series should look like: | ||
806 | * | ||
807 | * {MCS2, MCS1, MCS0, MCS0}. | ||
808 | * | ||
809 | * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should | ||
810 | * look like: | ||
811 | * | ||
812 | * {MCS3, MCS2, MCS1, MCS1} | ||
813 | * | ||
814 | * So, set fourth rate in series to be same as third one for | ||
815 | * above conditions. | ||
816 | */ | ||
817 | if ((sc->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) && | ||
818 | (conf_is_ht(&sc->hw->conf))) { | ||
819 | u8 dot11rate = rate_table->info[rix].dot11rate; | ||
820 | u8 phy = rate_table->info[rix].phy; | ||
821 | if (i == 4 && | ||
822 | ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || | ||
823 | (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) { | ||
824 | rates[3].idx = rates[2].idx; | ||
825 | rates[3].flags = rates[2].flags; | ||
826 | } | ||
827 | } | ||
828 | |||
829 | /* | ||
830 | * Force hardware to use computed duration for next | ||
831 | * fragment by disabling multi-rate retry, which | ||
832 | * updates duration based on the multi-rate duration table. | ||
833 | * | ||
834 | * FIXME: Fix duration | ||
835 | */ | ||
836 | if (ieee80211_has_morefrags(fc) || | ||
837 | (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { | ||
838 | rates[1].count = rates[2].count = rates[3].count = 0; | ||
839 | rates[1].idx = rates[2].idx = rates[3].idx = 0; | ||
840 | rates[0].count = ATH_TXMAXTRY; | ||
841 | } | ||
842 | |||
843 | ath_rc_rate_set_rtscts(sc, rate_table, tx_info); | ||
844 | } | ||
845 | |||
846 | static void ath_rc_update_per(struct ath_softc *sc, | ||
847 | const struct ath_rate_table *rate_table, | ||
848 | struct ath_rate_priv *ath_rc_priv, | ||
849 | struct ieee80211_tx_info *tx_info, | ||
850 | int tx_rate, int xretries, int retries, | ||
851 | u32 now_msec) | ||
852 | { | ||
853 | int count, n_bad_frames; | ||
854 | u8 last_per; | ||
855 | static const u32 nretry_to_per_lookup[10] = { | ||
856 | 100 * 0 / 1, | ||
857 | 100 * 1 / 4, | ||
858 | 100 * 1 / 2, | ||
859 | 100 * 3 / 4, | ||
860 | 100 * 4 / 5, | ||
861 | 100 * 5 / 6, | ||
862 | 100 * 6 / 7, | ||
863 | 100 * 7 / 8, | ||
864 | 100 * 8 / 9, | ||
865 | 100 * 9 / 10 | ||
866 | }; | ||
867 | |||
868 | last_per = ath_rc_priv->per[tx_rate]; | ||
869 | n_bad_frames = tx_info->status.ampdu_len - tx_info->status.ampdu_ack_len; | ||
870 | |||
871 | if (xretries) { | ||
872 | if (xretries == 1) { | ||
873 | ath_rc_priv->per[tx_rate] += 30; | ||
874 | if (ath_rc_priv->per[tx_rate] > 100) | ||
875 | ath_rc_priv->per[tx_rate] = 100; | ||
876 | } else { | ||
877 | /* xretries == 2 */ | ||
878 | count = ARRAY_SIZE(nretry_to_per_lookup); | ||
879 | if (retries >= count) | ||
880 | retries = count - 1; | ||
881 | |||
882 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ | ||
883 | ath_rc_priv->per[tx_rate] = | ||
884 | (u8)(last_per - (last_per >> 3) + (100 >> 3)); | ||
885 | } | ||
886 | |||
887 | /* xretries == 1 or 2 */ | ||
888 | |||
889 | if (ath_rc_priv->probe_rate == tx_rate) | ||
890 | ath_rc_priv->probe_rate = 0; | ||
891 | |||
892 | } else { /* xretries == 0 */ | ||
893 | count = ARRAY_SIZE(nretry_to_per_lookup); | ||
894 | if (retries >= count) | ||
895 | retries = count - 1; | ||
896 | |||
897 | if (n_bad_frames) { | ||
898 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) | ||
899 | * Assuming that n_frames is not 0. The current PER | ||
900 | * from the retries is 100 * retries / (retries+1), | ||
901 | * since the first retries attempts failed, and the | ||
902 | * next one worked. For the one that worked, | ||
903 | * n_bad_frames subframes out of n_frames wored, | ||
904 | * so the PER for that part is | ||
905 | * 100 * n_bad_frames / n_frames, and it contributes | ||
906 | * 100 * n_bad_frames / (n_frames * (retries+1)) to | ||
907 | * the above PER. The expression below is a | ||
908 | * simplified version of the sum of these two terms. | ||
909 | */ | ||
910 | if (tx_info->status.ampdu_len > 0) { | ||
911 | int n_frames, n_bad_tries; | ||
912 | u8 cur_per, new_per; | ||
913 | |||
914 | n_bad_tries = retries * tx_info->status.ampdu_len + | ||
915 | n_bad_frames; | ||
916 | n_frames = tx_info->status.ampdu_len * (retries + 1); | ||
917 | cur_per = (100 * n_bad_tries / n_frames) >> 3; | ||
918 | new_per = (u8)(last_per - (last_per >> 3) + cur_per); | ||
919 | ath_rc_priv->per[tx_rate] = new_per; | ||
920 | } | ||
921 | } else { | ||
922 | ath_rc_priv->per[tx_rate] = | ||
923 | (u8)(last_per - (last_per >> 3) + | ||
924 | (nretry_to_per_lookup[retries] >> 3)); | ||
925 | } | ||
926 | |||
927 | |||
928 | /* | ||
929 | * If we got at most one retry then increase the max rate if | ||
930 | * this was a probe. Otherwise, ignore the probe. | ||
931 | */ | ||
932 | if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { | ||
933 | if (retries > 0 || 2 * n_bad_frames > tx_info->status.ampdu_len) { | ||
934 | /* | ||
935 | * Since we probed with just a single attempt, | ||
936 | * any retries means the probe failed. Also, | ||
937 | * if the attempt worked, but more than half | ||
938 | * the subframes were bad then also consider | ||
939 | * the probe a failure. | ||
940 | */ | ||
941 | ath_rc_priv->probe_rate = 0; | ||
942 | } else { | ||
943 | u8 probe_rate = 0; | ||
944 | |||
945 | ath_rc_priv->rate_max_phy = | ||
946 | ath_rc_priv->probe_rate; | ||
947 | probe_rate = ath_rc_priv->probe_rate; | ||
948 | |||
949 | if (ath_rc_priv->per[probe_rate] > 30) | ||
950 | ath_rc_priv->per[probe_rate] = 20; | ||
951 | |||
952 | ath_rc_priv->probe_rate = 0; | ||
953 | |||
954 | /* | ||
955 | * Since this probe succeeded, we allow the next | ||
956 | * probe twice as soon. This allows the maxRate | ||
957 | * to move up faster if the probes are | ||
958 | * successful. | ||
959 | */ | ||
960 | ath_rc_priv->probe_time = | ||
961 | now_msec - rate_table->probe_interval / 2; | ||
962 | } | ||
963 | } | ||
964 | |||
965 | if (retries > 0) { | ||
966 | /* | ||
967 | * Don't update anything. We don't know if | ||
968 | * this was because of collisions or poor signal. | ||
969 | */ | ||
970 | ath_rc_priv->hw_maxretry_pktcnt = 0; | ||
971 | } else { | ||
972 | /* | ||
973 | * It worked with no retries. First ignore bogus (small) | ||
974 | * rssi_ack values. | ||
975 | */ | ||
976 | if (tx_rate == ath_rc_priv->rate_max_phy && | ||
977 | ath_rc_priv->hw_maxretry_pktcnt < 255) { | ||
978 | ath_rc_priv->hw_maxretry_pktcnt++; | ||
979 | } | ||
980 | |||
981 | } | ||
982 | } | ||
983 | } | ||
984 | |||
985 | static void ath_rc_update_ht(struct ath_softc *sc, | ||
986 | struct ath_rate_priv *ath_rc_priv, | ||
987 | struct ieee80211_tx_info *tx_info, | ||
988 | int tx_rate, int xretries, int retries) | ||
989 | { | ||
990 | u32 now_msec = jiffies_to_msecs(jiffies); | ||
991 | int rate; | ||
992 | u8 last_per; | ||
993 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | ||
994 | int size = ath_rc_priv->rate_table_size; | ||
995 | |||
996 | if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) | ||
997 | return; | ||
998 | |||
999 | last_per = ath_rc_priv->per[tx_rate]; | ||
1000 | |||
1001 | /* Update PER first */ | ||
1002 | ath_rc_update_per(sc, rate_table, ath_rc_priv, | ||
1003 | tx_info, tx_rate, xretries, | ||
1004 | retries, now_msec); | ||
1005 | |||
1006 | /* | ||
1007 | * If this rate looks bad (high PER) then stop using it for | ||
1008 | * a while (except if we are probing). | ||
1009 | */ | ||
1010 | if (ath_rc_priv->per[tx_rate] >= 55 && tx_rate > 0 && | ||
1011 | rate_table->info[tx_rate].ratekbps <= | ||
1012 | rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) { | ||
1013 | ath_rc_get_lower_rix(ath_rc_priv, (u8)tx_rate, | ||
1014 | &ath_rc_priv->rate_max_phy); | ||
1015 | |||
1016 | /* Don't probe for a little while. */ | ||
1017 | ath_rc_priv->probe_time = now_msec; | ||
1018 | } | ||
1019 | |||
1020 | /* Make sure the rates below this have lower PER */ | ||
1021 | /* Monotonicity is kept only for rates below the current rate. */ | ||
1022 | if (ath_rc_priv->per[tx_rate] < last_per) { | ||
1023 | for (rate = tx_rate - 1; rate >= 0; rate--) { | ||
1024 | |||
1025 | if (ath_rc_priv->per[rate] > | ||
1026 | ath_rc_priv->per[rate+1]) { | ||
1027 | ath_rc_priv->per[rate] = | ||
1028 | ath_rc_priv->per[rate+1]; | ||
1029 | } | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | /* Maintain monotonicity for rates above the current rate */ | ||
1034 | for (rate = tx_rate; rate < size - 1; rate++) { | ||
1035 | if (ath_rc_priv->per[rate+1] < | ||
1036 | ath_rc_priv->per[rate]) | ||
1037 | ath_rc_priv->per[rate+1] = | ||
1038 | ath_rc_priv->per[rate]; | ||
1039 | } | ||
1040 | |||
1041 | /* Every so often, we reduce the thresholds | ||
1042 | * and PER (different for CCK and OFDM). */ | ||
1043 | if (now_msec - ath_rc_priv->per_down_time >= | ||
1044 | rate_table->probe_interval) { | ||
1045 | for (rate = 0; rate < size; rate++) { | ||
1046 | ath_rc_priv->per[rate] = | ||
1047 | 7 * ath_rc_priv->per[rate] / 8; | ||
1048 | } | ||
1049 | |||
1050 | ath_rc_priv->per_down_time = now_msec; | ||
1051 | } | ||
1052 | |||
1053 | ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries, | ||
1054 | ath_rc_priv->per[tx_rate]); | ||
1055 | |||
1056 | } | ||
1057 | |||
1058 | static void ath_rc_tx_status(struct ath_softc *sc, | ||
1059 | struct ath_rate_priv *ath_rc_priv, | ||
1060 | struct sk_buff *skb) | ||
1061 | { | ||
1062 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1063 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | ||
1064 | struct ieee80211_tx_rate *rate; | ||
1065 | int final_ts_idx = 0, xretries = 0, long_retry = 0; | ||
1066 | u8 flags; | ||
1067 | u32 i = 0, rix; | ||
1068 | |||
1069 | for (i = 0; i < sc->hw->max_rates; i++) { | ||
1070 | rate = &tx_info->status.rates[i]; | ||
1071 | if (rate->idx < 0 || !rate->count) | ||
1072 | break; | ||
1073 | |||
1074 | final_ts_idx = i; | ||
1075 | long_retry = rate->count - 1; | ||
1076 | } | ||
1077 | |||
1078 | if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) | ||
1079 | xretries = 1; | ||
1080 | |||
1081 | /* | ||
1082 | * If the first rate is not the final index, there | ||
1083 | * are intermediate rate failures to be processed. | ||
1084 | */ | ||
1085 | if (final_ts_idx != 0) { | ||
1086 | for (i = 0; i < final_ts_idx ; i++) { | ||
1087 | if (rates[i].count != 0 && (rates[i].idx >= 0)) { | ||
1088 | flags = rates[i].flags; | ||
1089 | |||
1090 | /* If HT40 and we have switched mode from | ||
1091 | * 40 to 20 => don't update */ | ||
1092 | |||
1093 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | ||
1094 | !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG)) | ||
1095 | return; | ||
1096 | |||
1097 | rix = ath_rc_get_rateindex(ath_rc_priv, &rates[i]); | ||
1098 | ath_rc_update_ht(sc, ath_rc_priv, tx_info, | ||
1099 | rix, xretries ? 1 : 2, | ||
1100 | rates[i].count); | ||
1101 | } | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | flags = rates[final_ts_idx].flags; | ||
1106 | |||
1107 | /* If HT40 and we have switched mode from 40 to 20 => don't update */ | ||
1108 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | ||
1109 | !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG)) | ||
1110 | return; | ||
1111 | |||
1112 | rix = ath_rc_get_rateindex(ath_rc_priv, &rates[final_ts_idx]); | ||
1113 | ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry); | ||
1114 | ath_debug_stat_rc(ath_rc_priv, rix); | ||
1115 | } | ||
1116 | |||
1117 | static const | ||
1118 | struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, | ||
1119 | enum ieee80211_band band, | ||
1120 | bool is_ht) | ||
1121 | { | ||
1122 | switch(band) { | ||
1123 | case IEEE80211_BAND_2GHZ: | ||
1124 | if (is_ht) | ||
1125 | return &ar5416_11ng_ratetable; | ||
1126 | return &ar5416_11g_ratetable; | ||
1127 | case IEEE80211_BAND_5GHZ: | ||
1128 | if (is_ht) | ||
1129 | return &ar5416_11na_ratetable; | ||
1130 | return &ar5416_11a_ratetable; | ||
1131 | default: | ||
1132 | return NULL; | ||
1133 | } | ||
1134 | } | ||
1135 | |||
1136 | static void ath_rc_init(struct ath_softc *sc, | ||
1137 | struct ath_rate_priv *ath_rc_priv) | ||
1138 | { | ||
1139 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | ||
1140 | struct ath_rateset *rateset = &ath_rc_priv->neg_rates; | ||
1141 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1142 | u8 i, j, k, hi = 0, hthi = 0; | ||
1143 | |||
1144 | ath_rc_priv->rate_table_size = RATE_TABLE_SIZE; | ||
1145 | |||
1146 | for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) { | ||
1147 | ath_rc_priv->per[i] = 0; | ||
1148 | ath_rc_priv->valid_rate_index[i] = 0; | ||
1149 | } | ||
1150 | |||
1151 | for (i = 0; i < WLAN_RC_PHY_MAX; i++) { | ||
1152 | for (j = 0; j < RATE_TABLE_SIZE; j++) | ||
1153 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; | ||
1154 | ath_rc_priv->valid_phy_ratecnt[i] = 0; | ||
1155 | } | ||
1156 | |||
1157 | if (!rateset->rs_nrates) { | ||
1158 | hi = ath_rc_init_validrates(ath_rc_priv); | ||
1159 | } else { | ||
1160 | hi = ath_rc_setvalid_rates(ath_rc_priv, true); | ||
1161 | |||
1162 | if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) | ||
1163 | hthi = ath_rc_setvalid_rates(ath_rc_priv, false); | ||
1164 | |||
1165 | hi = max(hi, hthi); | ||
1166 | } | ||
1167 | |||
1168 | ath_rc_priv->rate_table_size = hi + 1; | ||
1169 | ath_rc_priv->rate_max_phy = 0; | ||
1170 | WARN_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE); | ||
1171 | |||
1172 | for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) { | ||
1173 | for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) { | ||
1174 | ath_rc_priv->valid_rate_index[k++] = | ||
1175 | ath_rc_priv->valid_phy_rateidx[i][j]; | ||
1176 | } | ||
1177 | |||
1178 | if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1) || | ||
1179 | !ath_rc_priv->valid_phy_ratecnt[i]) | ||
1180 | continue; | ||
1181 | |||
1182 | ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1]; | ||
1183 | } | ||
1184 | WARN_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE); | ||
1185 | WARN_ON(k > RATE_TABLE_SIZE); | ||
1186 | |||
1187 | ath_rc_priv->max_valid_rate = k; | ||
1188 | ath_rc_sort_validrates(ath_rc_priv); | ||
1189 | ath_rc_priv->rate_max_phy = (k > 4) ? | ||
1190 | ath_rc_priv->valid_rate_index[k-4] : | ||
1191 | ath_rc_priv->valid_rate_index[k-1]; | ||
1192 | |||
1193 | ath_dbg(common, CONFIG, "RC Initialized with capabilities: 0x%x\n", | ||
1194 | ath_rc_priv->ht_cap); | ||
1195 | } | ||
1196 | |||
1197 | static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta) | ||
1198 | { | ||
1199 | u8 caps = 0; | ||
1200 | |||
1201 | if (sta->ht_cap.ht_supported) { | ||
1202 | caps = WLAN_RC_HT_FLAG; | ||
1203 | if (sta->ht_cap.mcs.rx_mask[1] && sta->ht_cap.mcs.rx_mask[2]) | ||
1204 | caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG; | ||
1205 | else if (sta->ht_cap.mcs.rx_mask[1]) | ||
1206 | caps |= WLAN_RC_DS_FLAG; | ||
1207 | if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) { | ||
1208 | caps |= WLAN_RC_40_FLAG; | ||
1209 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) | ||
1210 | caps |= WLAN_RC_SGI_FLAG; | ||
1211 | } else { | ||
1212 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) | ||
1213 | caps |= WLAN_RC_SGI_FLAG; | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1217 | return caps; | ||
1218 | } | ||
1219 | |||
1220 | static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta, | ||
1221 | u8 tidno) | ||
1222 | { | ||
1223 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | ||
1224 | struct ath_atx_tid *txtid; | ||
1225 | |||
1226 | if (!sta->ht_cap.ht_supported) | ||
1227 | return false; | ||
1228 | |||
1229 | txtid = ATH_AN_2_TID(an, tidno); | ||
1230 | return !txtid->active; | ||
1231 | } | ||
1232 | |||
1233 | |||
1234 | /***********************************/ | ||
1235 | /* mac80211 Rate Control callbacks */ | ||
1236 | /***********************************/ | ||
1237 | |||
1238 | static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | ||
1239 | struct ieee80211_sta *sta, void *priv_sta, | ||
1240 | struct sk_buff *skb) | ||
1241 | { | ||
1242 | struct ath_softc *sc = priv; | ||
1243 | struct ath_rate_priv *ath_rc_priv = priv_sta; | ||
1244 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1245 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1246 | __le16 fc = hdr->frame_control; | ||
1247 | |||
1248 | if (!priv_sta || !ieee80211_is_data(fc)) | ||
1249 | return; | ||
1250 | |||
1251 | /* This packet was aggregated but doesn't carry status info */ | ||
1252 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && | ||
1253 | !(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) | ||
1254 | return; | ||
1255 | |||
1256 | if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) | ||
1257 | return; | ||
1258 | |||
1259 | ath_rc_tx_status(sc, ath_rc_priv, skb); | ||
1260 | |||
1261 | /* Check if aggregation has to be enabled for this tid */ | ||
1262 | if (conf_is_ht(&sc->hw->conf) && | ||
1263 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
1264 | if (ieee80211_is_data_qos(fc) && | ||
1265 | skb_get_queue_mapping(skb) != IEEE80211_AC_VO) { | ||
1266 | u8 *qc, tid; | ||
1267 | |||
1268 | qc = ieee80211_get_qos_ctl(hdr); | ||
1269 | tid = qc[0] & 0xf; | ||
1270 | |||
1271 | if(ath_tx_aggr_check(sc, sta, tid)) | ||
1272 | ieee80211_start_tx_ba_session(sta, tid, 0); | ||
1273 | } | ||
1274 | } | ||
1275 | } | ||
1276 | |||
1277 | static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | ||
1278 | struct cfg80211_chan_def *chandef, | ||
1279 | struct ieee80211_sta *sta, void *priv_sta) | ||
1280 | { | ||
1281 | struct ath_softc *sc = priv; | ||
1282 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1283 | struct ath_rate_priv *ath_rc_priv = priv_sta; | ||
1284 | int i, j = 0; | ||
1285 | u32 rate_flags = ieee80211_chandef_rate_flags(&sc->hw->conf.chandef); | ||
1286 | |||
1287 | for (i = 0; i < sband->n_bitrates; i++) { | ||
1288 | if (sta->supp_rates[sband->band] & BIT(i)) { | ||
1289 | if ((rate_flags & sband->bitrates[i].flags) | ||
1290 | != rate_flags) | ||
1291 | continue; | ||
1292 | |||
1293 | ath_rc_priv->neg_rates.rs_rates[j] | ||
1294 | = (sband->bitrates[i].bitrate * 2) / 10; | ||
1295 | j++; | ||
1296 | } | ||
1297 | } | ||
1298 | ath_rc_priv->neg_rates.rs_nrates = j; | ||
1299 | |||
1300 | if (sta->ht_cap.ht_supported) { | ||
1301 | for (i = 0, j = 0; i < 77; i++) { | ||
1302 | if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) | ||
1303 | ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; | ||
1304 | if (j == ATH_RATE_MAX) | ||
1305 | break; | ||
1306 | } | ||
1307 | ath_rc_priv->neg_ht_rates.rs_nrates = j; | ||
1308 | } | ||
1309 | |||
1310 | ath_rc_priv->rate_table = ath_choose_rate_table(sc, sband->band, | ||
1311 | sta->ht_cap.ht_supported); | ||
1312 | if (!ath_rc_priv->rate_table) { | ||
1313 | ath_err(common, "No rate table chosen\n"); | ||
1314 | return; | ||
1315 | } | ||
1316 | |||
1317 | ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta); | ||
1318 | ath_rc_init(sc, priv_sta); | ||
1319 | } | ||
1320 | |||
1321 | static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | ||
1322 | struct cfg80211_chan_def *chandef, | ||
1323 | struct ieee80211_sta *sta, void *priv_sta, | ||
1324 | u32 changed) | ||
1325 | { | ||
1326 | struct ath_softc *sc = priv; | ||
1327 | struct ath_rate_priv *ath_rc_priv = priv_sta; | ||
1328 | |||
1329 | if (changed & IEEE80211_RC_BW_CHANGED) { | ||
1330 | ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta); | ||
1331 | ath_rc_init(sc, priv_sta); | ||
1332 | |||
1333 | ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG, | ||
1334 | "Operating Bandwidth changed to: %d\n", | ||
1335 | sc->hw->conf.chandef.width); | ||
1336 | } | ||
1337 | } | ||
1338 | |||
1339 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) | ||
1340 | |||
1341 | void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) | ||
1342 | { | ||
1343 | struct ath_rc_stats *stats; | ||
1344 | |||
1345 | stats = &rc->rcstats[final_rate]; | ||
1346 | stats->success++; | ||
1347 | } | ||
1348 | |||
1349 | void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | ||
1350 | int xretries, int retries, u8 per) | ||
1351 | { | ||
1352 | struct ath_rc_stats *stats = &rc->rcstats[rix]; | ||
1353 | |||
1354 | stats->xretries += xretries; | ||
1355 | stats->retries += retries; | ||
1356 | stats->per = per; | ||
1357 | } | ||
1358 | |||
1359 | static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, | ||
1360 | size_t count, loff_t *ppos) | ||
1361 | { | ||
1362 | struct ath_rate_priv *rc = file->private_data; | ||
1363 | char *buf; | ||
1364 | unsigned int len = 0, max; | ||
1365 | int rix; | ||
1366 | ssize_t retval; | ||
1367 | |||
1368 | if (rc->rate_table == NULL) | ||
1369 | return 0; | ||
1370 | |||
1371 | max = 80 + rc->rate_table_size * 1024 + 1; | ||
1372 | buf = kmalloc(max, GFP_KERNEL); | ||
1373 | if (buf == NULL) | ||
1374 | return -ENOMEM; | ||
1375 | |||
1376 | len += sprintf(buf, "%6s %6s %6s " | ||
1377 | "%10s %10s %10s %10s\n", | ||
1378 | "HT", "MCS", "Rate", | ||
1379 | "Success", "Retries", "XRetries", "PER"); | ||
1380 | |||
1381 | for (rix = 0; rix < rc->max_valid_rate; rix++) { | ||
1382 | u8 i = rc->valid_rate_index[rix]; | ||
1383 | u32 ratekbps = rc->rate_table->info[i].ratekbps; | ||
1384 | struct ath_rc_stats *stats = &rc->rcstats[i]; | ||
1385 | char mcs[5]; | ||
1386 | char htmode[5]; | ||
1387 | int used_mcs = 0, used_htmode = 0; | ||
1388 | |||
1389 | if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) { | ||
1390 | used_mcs = scnprintf(mcs, 5, "%d", | ||
1391 | rc->rate_table->info[i].ratecode); | ||
1392 | |||
1393 | if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy)) | ||
1394 | used_htmode = scnprintf(htmode, 5, "HT40"); | ||
1395 | else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy)) | ||
1396 | used_htmode = scnprintf(htmode, 5, "HT20"); | ||
1397 | else | ||
1398 | used_htmode = scnprintf(htmode, 5, "????"); | ||
1399 | } | ||
1400 | |||
1401 | mcs[used_mcs] = '\0'; | ||
1402 | htmode[used_htmode] = '\0'; | ||
1403 | |||
1404 | len += scnprintf(buf + len, max - len, | ||
1405 | "%6s %6s %3u.%d: " | ||
1406 | "%10u %10u %10u %10u\n", | ||
1407 | htmode, | ||
1408 | mcs, | ||
1409 | ratekbps / 1000, | ||
1410 | (ratekbps % 1000) / 100, | ||
1411 | stats->success, | ||
1412 | stats->retries, | ||
1413 | stats->xretries, | ||
1414 | stats->per); | ||
1415 | } | ||
1416 | |||
1417 | if (len > max) | ||
1418 | len = max; | ||
1419 | |||
1420 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
1421 | kfree(buf); | ||
1422 | return retval; | ||
1423 | } | ||
1424 | |||
1425 | static const struct file_operations fops_rcstat = { | ||
1426 | .read = read_file_rcstat, | ||
1427 | .open = simple_open, | ||
1428 | .owner = THIS_MODULE | ||
1429 | }; | ||
1430 | |||
1431 | static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta, | ||
1432 | struct dentry *dir) | ||
1433 | { | ||
1434 | struct ath_rate_priv *rc = priv_sta; | ||
1435 | rc->debugfs_rcstats = debugfs_create_file("rc_stats", S_IRUGO, | ||
1436 | dir, rc, &fops_rcstat); | ||
1437 | } | ||
1438 | |||
1439 | static void ath_rate_remove_sta_debugfs(void *priv, void *priv_sta) | ||
1440 | { | ||
1441 | struct ath_rate_priv *rc = priv_sta; | ||
1442 | debugfs_remove(rc->debugfs_rcstats); | ||
1443 | } | ||
1444 | |||
1445 | #endif /* CONFIG_MAC80211_DEBUGFS && CONFIG_ATH9K_DEBUGFS */ | ||
1446 | |||
1447 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | ||
1448 | { | ||
1449 | return hw->priv; | ||
1450 | } | ||
1451 | |||
1452 | static void ath_rate_free(void *priv) | ||
1453 | { | ||
1454 | return; | ||
1455 | } | ||
1456 | |||
1457 | static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | ||
1458 | { | ||
1459 | return kzalloc(sizeof(struct ath_rate_priv), gfp); | ||
1460 | } | ||
1461 | |||
1462 | static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta, | ||
1463 | void *priv_sta) | ||
1464 | { | ||
1465 | struct ath_rate_priv *rate_priv = priv_sta; | ||
1466 | kfree(rate_priv); | ||
1467 | } | ||
1468 | |||
1469 | static struct rate_control_ops ath_rate_ops = { | ||
1470 | .module = NULL, | ||
1471 | .name = "ath9k_rate_control", | ||
1472 | .tx_status = ath_tx_status, | ||
1473 | .get_rate = ath_get_rate, | ||
1474 | .rate_init = ath_rate_init, | ||
1475 | .rate_update = ath_rate_update, | ||
1476 | .alloc = ath_rate_alloc, | ||
1477 | .free = ath_rate_free, | ||
1478 | .alloc_sta = ath_rate_alloc_sta, | ||
1479 | .free_sta = ath_rate_free_sta, | ||
1480 | |||
1481 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) | ||
1482 | .add_sta_debugfs = ath_rate_add_sta_debugfs, | ||
1483 | .remove_sta_debugfs = ath_rate_remove_sta_debugfs, | ||
1484 | #endif | ||
1485 | }; | ||
1486 | |||
1487 | int ath_rate_control_register(void) | ||
1488 | { | ||
1489 | return ieee80211_rate_control_register(&ath_rate_ops); | ||
1490 | } | ||
1491 | |||
1492 | void ath_rate_control_unregister(void) | ||
1493 | { | ||
1494 | ieee80211_rate_control_unregister(&ath_rate_ops); | ||
1495 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h deleted file mode 100644 index b9a87383cb43..000000000000 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ /dev/null | |||
@@ -1,248 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004 Sam Leffler, Errno Consulting | ||
3 | * Copyright (c) 2004 Video54 Technologies, Inc. | ||
4 | * Copyright (c) 2008-2011 Atheros Communications Inc. | ||
5 | * | ||
6 | * Permission to use, copy, modify, and/or distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #ifndef RC_H | ||
20 | #define RC_H | ||
21 | |||
22 | #include "hw.h" | ||
23 | |||
24 | struct ath_softc; | ||
25 | |||
26 | #define ATH_RATE_MAX 30 | ||
27 | #define RATE_TABLE_SIZE 72 | ||
28 | |||
29 | #define RC_INVALID 0x0000 | ||
30 | #define RC_LEGACY 0x0001 | ||
31 | #define RC_SS 0x0002 | ||
32 | #define RC_DS 0x0004 | ||
33 | #define RC_TS 0x0008 | ||
34 | #define RC_HT_20 0x0010 | ||
35 | #define RC_HT_40 0x0020 | ||
36 | |||
37 | #define RC_STREAM_MASK 0xe | ||
38 | #define RC_DS_OR_LATER(f) ((((f) & RC_STREAM_MASK) == RC_DS) || \ | ||
39 | (((f) & RC_STREAM_MASK) == (RC_DS | RC_TS))) | ||
40 | #define RC_TS_ONLY(f) (((f) & RC_STREAM_MASK) == RC_TS) | ||
41 | #define RC_SS_OR_LEGACY(f) ((f) & (RC_SS | RC_LEGACY)) | ||
42 | |||
43 | #define RC_HT_2040 (RC_HT_20 | RC_HT_40) | ||
44 | #define RC_ALL_STREAM (RC_SS | RC_DS | RC_TS) | ||
45 | #define RC_L_SD (RC_LEGACY | RC_SS | RC_DS) | ||
46 | #define RC_L_SDT (RC_LEGACY | RC_SS | RC_DS | RC_TS) | ||
47 | #define RC_HT_S_20 (RC_HT_20 | RC_SS) | ||
48 | #define RC_HT_D_20 (RC_HT_20 | RC_DS) | ||
49 | #define RC_HT_T_20 (RC_HT_20 | RC_TS) | ||
50 | #define RC_HT_S_40 (RC_HT_40 | RC_SS) | ||
51 | #define RC_HT_D_40 (RC_HT_40 | RC_DS) | ||
52 | #define RC_HT_T_40 (RC_HT_40 | RC_TS) | ||
53 | |||
54 | #define RC_HT_SD_20 (RC_HT_20 | RC_SS | RC_DS) | ||
55 | #define RC_HT_DT_20 (RC_HT_20 | RC_DS | RC_TS) | ||
56 | #define RC_HT_SD_40 (RC_HT_40 | RC_SS | RC_DS) | ||
57 | #define RC_HT_DT_40 (RC_HT_40 | RC_DS | RC_TS) | ||
58 | |||
59 | #define RC_HT_SD_2040 (RC_HT_2040 | RC_SS | RC_DS) | ||
60 | #define RC_HT_SDT_2040 (RC_HT_2040 | RC_SS | RC_DS | RC_TS) | ||
61 | |||
62 | #define RC_HT_SDT_20 (RC_HT_20 | RC_SS | RC_DS | RC_TS) | ||
63 | #define RC_HT_SDT_40 (RC_HT_40 | RC_SS | RC_DS | RC_TS) | ||
64 | |||
65 | #define RC_ALL (RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM) | ||
66 | |||
67 | enum { | ||
68 | WLAN_RC_PHY_OFDM, | ||
69 | WLAN_RC_PHY_CCK, | ||
70 | WLAN_RC_PHY_HT_20_SS, | ||
71 | WLAN_RC_PHY_HT_20_DS, | ||
72 | WLAN_RC_PHY_HT_20_TS, | ||
73 | WLAN_RC_PHY_HT_40_SS, | ||
74 | WLAN_RC_PHY_HT_40_DS, | ||
75 | WLAN_RC_PHY_HT_40_TS, | ||
76 | WLAN_RC_PHY_HT_20_SS_HGI, | ||
77 | WLAN_RC_PHY_HT_20_DS_HGI, | ||
78 | WLAN_RC_PHY_HT_20_TS_HGI, | ||
79 | WLAN_RC_PHY_HT_40_SS_HGI, | ||
80 | WLAN_RC_PHY_HT_40_DS_HGI, | ||
81 | WLAN_RC_PHY_HT_40_TS_HGI, | ||
82 | WLAN_RC_PHY_MAX | ||
83 | }; | ||
84 | |||
85 | #define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \ | ||
86 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ | ||
87 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ | ||
88 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||
89 | #define WLAN_RC_PHY_TS(_phy) ((_phy == WLAN_RC_PHY_HT_20_TS) \ | ||
90 | || (_phy == WLAN_RC_PHY_HT_40_TS) \ | ||
91 | || (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \ | ||
92 | || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) | ||
93 | #define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \ | ||
94 | || (_phy == WLAN_RC_PHY_HT_20_DS) \ | ||
95 | || (_phy == WLAN_RC_PHY_HT_20_TS) \ | ||
96 | || (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ | ||
97 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ | ||
98 | || (_phy == WLAN_RC_PHY_HT_20_TS_HGI)) | ||
99 | #define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ | ||
100 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ | ||
101 | || (_phy == WLAN_RC_PHY_HT_40_TS) \ | ||
102 | || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ | ||
103 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \ | ||
104 | || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) | ||
105 | #define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ | ||
106 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ | ||
107 | || (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \ | ||
108 | || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ | ||
109 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \ | ||
110 | || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) | ||
111 | |||
112 | #define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS) | ||
113 | |||
114 | #define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \ | ||
115 | ((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY)) | ||
116 | |||
117 | #define WLAN_RC_CAP_STREAM(capflag) (((capflag & WLAN_RC_TS_FLAG) ? \ | ||
118 | (RC_TS) : ((capflag & WLAN_RC_DS_FLAG) ? RC_DS : RC_SS))) | ||
119 | |||
120 | /* Return TRUE if flag supports HT20 && client supports HT20 or | ||
121 | * return TRUE if flag supports HT40 && client supports HT40. | ||
122 | * This is used becos some rates overlap between HT20/HT40. | ||
123 | */ | ||
124 | #define WLAN_RC_PHY_HT_VALID(flag, capflag) \ | ||
125 | (((flag & RC_HT_20) && !(capflag & WLAN_RC_40_FLAG)) || \ | ||
126 | ((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG))) | ||
127 | |||
128 | #define WLAN_RC_DS_FLAG (0x01) | ||
129 | #define WLAN_RC_TS_FLAG (0x02) | ||
130 | #define WLAN_RC_40_FLAG (0x04) | ||
131 | #define WLAN_RC_SGI_FLAG (0x08) | ||
132 | #define WLAN_RC_HT_FLAG (0x10) | ||
133 | |||
134 | /** | ||
135 | * struct ath_rate_table - Rate Control table | ||
136 | * @rate_cnt: total number of rates for the given wireless mode | ||
137 | * @mcs_start: MCS rate index offset | ||
138 | * @rate_flags: Rate Control flags | ||
139 | * @phy: CCK/OFDM/HT20/HT40 | ||
140 | * @ratekbps: rate in Kbits per second | ||
141 | * @user_ratekbps: user rate in Kbits per second | ||
142 | * @ratecode: rate that goes into HW descriptors | ||
143 | * @dot11rate: value that goes into supported | ||
144 | * rates info element of MLME | ||
145 | * @ctrl_rate: Index of next lower basic rate, used for duration computation | ||
146 | * @cw40index: Index of rates having 40MHz channel width | ||
147 | * @sgi_index: Index of rates having Short Guard Interval | ||
148 | * @ht_index: high throughput rates having 40MHz channel width and | ||
149 | * Short Guard Interval | ||
150 | * @probe_interval: interval for rate control to probe for other rates | ||
151 | * @initial_ratemax: initial ratemax value | ||
152 | */ | ||
153 | struct ath_rate_table { | ||
154 | int rate_cnt; | ||
155 | int mcs_start; | ||
156 | struct { | ||
157 | u16 rate_flags; | ||
158 | u8 phy; | ||
159 | u32 ratekbps; | ||
160 | u32 user_ratekbps; | ||
161 | u8 ratecode; | ||
162 | u8 dot11rate; | ||
163 | } info[RATE_TABLE_SIZE]; | ||
164 | u32 probe_interval; | ||
165 | u8 initial_ratemax; | ||
166 | }; | ||
167 | |||
168 | struct ath_rateset { | ||
169 | u8 rs_nrates; | ||
170 | u8 rs_rates[ATH_RATE_MAX]; | ||
171 | }; | ||
172 | |||
173 | struct ath_rc_stats { | ||
174 | u32 success; | ||
175 | u32 retries; | ||
176 | u32 xretries; | ||
177 | u8 per; | ||
178 | }; | ||
179 | |||
180 | /** | ||
181 | * struct ath_rate_priv - Rate Control priv data | ||
182 | * @state: RC state | ||
183 | * @probe_rate: rate we are probing at | ||
184 | * @probe_time: msec timestamp for last probe | ||
185 | * @hw_maxretry_pktcnt: num of packets since we got HW max retry error | ||
186 | * @max_valid_rate: maximum number of valid rate | ||
187 | * @per_down_time: msec timestamp for last PER down step | ||
188 | * @valid_phy_ratecnt: valid rate count | ||
189 | * @rate_max_phy: phy index for the max rate | ||
190 | * @per: PER for every valid rate in % | ||
191 | * @probe_interval: interval for ratectrl to probe for other rates | ||
192 | * @ht_cap: HT capabilities | ||
193 | * @neg_rates: Negotatied rates | ||
194 | * @neg_ht_rates: Negotiated HT rates | ||
195 | */ | ||
196 | struct ath_rate_priv { | ||
197 | u8 rate_table_size; | ||
198 | u8 probe_rate; | ||
199 | u8 hw_maxretry_pktcnt; | ||
200 | u8 max_valid_rate; | ||
201 | u8 valid_rate_index[RATE_TABLE_SIZE]; | ||
202 | u8 ht_cap; | ||
203 | u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; | ||
204 | u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE]; | ||
205 | u8 rate_max_phy; | ||
206 | u8 per[RATE_TABLE_SIZE]; | ||
207 | u32 probe_time; | ||
208 | u32 per_down_time; | ||
209 | u32 probe_interval; | ||
210 | struct ath_rateset neg_rates; | ||
211 | struct ath_rateset neg_ht_rates; | ||
212 | const struct ath_rate_table *rate_table; | ||
213 | |||
214 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) | ||
215 | struct dentry *debugfs_rcstats; | ||
216 | struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; | ||
217 | #endif | ||
218 | }; | ||
219 | |||
220 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) | ||
221 | void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate); | ||
222 | void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | ||
223 | int xretries, int retries, u8 per); | ||
224 | #else | ||
225 | static inline void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) | ||
226 | { | ||
227 | } | ||
228 | static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | ||
229 | int xretries, int retries, u8 per) | ||
230 | { | ||
231 | } | ||
232 | #endif | ||
233 | |||
234 | #ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL | ||
235 | int ath_rate_control_register(void); | ||
236 | void ath_rate_control_unregister(void); | ||
237 | #else | ||
238 | static inline int ath_rate_control_register(void) | ||
239 | { | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static inline void ath_rate_control_unregister(void) | ||
244 | { | ||
245 | } | ||
246 | #endif | ||
247 | |||
248 | #endif /* RC_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 82e340d3ec60..6c9accdb52e4 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -762,204 +762,6 @@ static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
762 | return bf; | 762 | return bf; |
763 | } | 763 | } |
764 | 764 | ||
765 | /* Assumes you've already done the endian to CPU conversion */ | ||
766 | static bool ath9k_rx_accept(struct ath_common *common, | ||
767 | struct ieee80211_hdr *hdr, | ||
768 | struct ieee80211_rx_status *rxs, | ||
769 | struct ath_rx_status *rx_stats, | ||
770 | bool *decrypt_error) | ||
771 | { | ||
772 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
773 | bool is_mc, is_valid_tkip, strip_mic, mic_error; | ||
774 | struct ath_hw *ah = common->ah; | ||
775 | __le16 fc; | ||
776 | |||
777 | fc = hdr->frame_control; | ||
778 | |||
779 | is_mc = !!is_multicast_ether_addr(hdr->addr1); | ||
780 | is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && | ||
781 | test_bit(rx_stats->rs_keyix, common->tkip_keymap); | ||
782 | strip_mic = is_valid_tkip && ieee80211_is_data(fc) && | ||
783 | ieee80211_has_protected(fc) && | ||
784 | !(rx_stats->rs_status & | ||
785 | (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC | | ||
786 | ATH9K_RXERR_KEYMISS)); | ||
787 | |||
788 | /* | ||
789 | * Key miss events are only relevant for pairwise keys where the | ||
790 | * descriptor does contain a valid key index. This has been observed | ||
791 | * mostly with CCMP encryption. | ||
792 | */ | ||
793 | if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID || | ||
794 | !test_bit(rx_stats->rs_keyix, common->ccmp_keymap)) | ||
795 | rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS; | ||
796 | |||
797 | mic_error = is_valid_tkip && !ieee80211_is_ctl(fc) && | ||
798 | !ieee80211_has_morefrags(fc) && | ||
799 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && | ||
800 | (rx_stats->rs_status & ATH9K_RXERR_MIC); | ||
801 | |||
802 | /* | ||
803 | * The rx_stats->rs_status will not be set until the end of the | ||
804 | * chained descriptors so it can be ignored if rs_more is set. The | ||
805 | * rs_more will be false at the last element of the chained | ||
806 | * descriptors. | ||
807 | */ | ||
808 | if (rx_stats->rs_status != 0) { | ||
809 | u8 status_mask; | ||
810 | |||
811 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) { | ||
812 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
813 | mic_error = false; | ||
814 | } | ||
815 | |||
816 | if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) || | ||
817 | (!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) { | ||
818 | *decrypt_error = true; | ||
819 | mic_error = false; | ||
820 | } | ||
821 | |||
822 | /* | ||
823 | * Reject error frames with the exception of | ||
824 | * decryption and MIC failures. For monitor mode, | ||
825 | * we also ignore the CRC error. | ||
826 | */ | ||
827 | status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
828 | ATH9K_RXERR_KEYMISS; | ||
829 | |||
830 | if (ah->is_monitoring && (sc->rx.rxfilter & FIF_FCSFAIL)) | ||
831 | status_mask |= ATH9K_RXERR_CRC; | ||
832 | |||
833 | if (rx_stats->rs_status & ~status_mask) | ||
834 | return false; | ||
835 | } | ||
836 | |||
837 | /* | ||
838 | * For unicast frames the MIC error bit can have false positives, | ||
839 | * so all MIC error reports need to be validated in software. | ||
840 | * False negatives are not common, so skip software verification | ||
841 | * if the hardware considers the MIC valid. | ||
842 | */ | ||
843 | if (strip_mic) | ||
844 | rxs->flag |= RX_FLAG_MMIC_STRIPPED; | ||
845 | else if (is_mc && mic_error) | ||
846 | rxs->flag |= RX_FLAG_MMIC_ERROR; | ||
847 | |||
848 | return true; | ||
849 | } | ||
850 | |||
851 | static int ath9k_process_rate(struct ath_common *common, | ||
852 | struct ieee80211_hw *hw, | ||
853 | struct ath_rx_status *rx_stats, | ||
854 | struct ieee80211_rx_status *rxs) | ||
855 | { | ||
856 | struct ieee80211_supported_band *sband; | ||
857 | enum ieee80211_band band; | ||
858 | unsigned int i = 0; | ||
859 | struct ath_softc __maybe_unused *sc = common->priv; | ||
860 | struct ath_hw *ah = sc->sc_ah; | ||
861 | |||
862 | band = ah->curchan->chan->band; | ||
863 | sband = hw->wiphy->bands[band]; | ||
864 | |||
865 | if (IS_CHAN_QUARTER_RATE(ah->curchan)) | ||
866 | rxs->flag |= RX_FLAG_5MHZ; | ||
867 | else if (IS_CHAN_HALF_RATE(ah->curchan)) | ||
868 | rxs->flag |= RX_FLAG_10MHZ; | ||
869 | |||
870 | if (rx_stats->rs_rate & 0x80) { | ||
871 | /* HT rate */ | ||
872 | rxs->flag |= RX_FLAG_HT; | ||
873 | rxs->flag |= rx_stats->flag; | ||
874 | rxs->rate_idx = rx_stats->rs_rate & 0x7f; | ||
875 | return 0; | ||
876 | } | ||
877 | |||
878 | for (i = 0; i < sband->n_bitrates; i++) { | ||
879 | if (sband->bitrates[i].hw_value == rx_stats->rs_rate) { | ||
880 | rxs->rate_idx = i; | ||
881 | return 0; | ||
882 | } | ||
883 | if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { | ||
884 | rxs->flag |= RX_FLAG_SHORTPRE; | ||
885 | rxs->rate_idx = i; | ||
886 | return 0; | ||
887 | } | ||
888 | } | ||
889 | |||
890 | /* | ||
891 | * No valid hardware bitrate found -- we should not get here | ||
892 | * because hardware has already validated this frame as OK. | ||
893 | */ | ||
894 | ath_dbg(common, ANY, | ||
895 | "unsupported hw bitrate detected 0x%02x using 1 Mbit\n", | ||
896 | rx_stats->rs_rate); | ||
897 | RX_STAT_INC(rx_rate_err); | ||
898 | return -EINVAL; | ||
899 | } | ||
900 | |||
901 | static void ath9k_process_rssi(struct ath_common *common, | ||
902 | struct ieee80211_hw *hw, | ||
903 | struct ath_rx_status *rx_stats, | ||
904 | struct ieee80211_rx_status *rxs) | ||
905 | { | ||
906 | struct ath_softc *sc = hw->priv; | ||
907 | struct ath_hw *ah = common->ah; | ||
908 | int last_rssi; | ||
909 | int rssi = rx_stats->rs_rssi; | ||
910 | int i, j; | ||
911 | |||
912 | /* | ||
913 | * RSSI is not available for subframes in an A-MPDU. | ||
914 | */ | ||
915 | if (rx_stats->rs_moreaggr) { | ||
916 | rxs->flag |= RX_FLAG_NO_SIGNAL_VAL; | ||
917 | return; | ||
918 | } | ||
919 | |||
920 | /* | ||
921 | * Check if the RSSI for the last subframe in an A-MPDU | ||
922 | * or an unaggregated frame is valid. | ||
923 | */ | ||
924 | if (rx_stats->rs_rssi == ATH9K_RSSI_BAD) { | ||
925 | rxs->flag |= RX_FLAG_NO_SIGNAL_VAL; | ||
926 | return; | ||
927 | } | ||
928 | |||
929 | for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) { | ||
930 | s8 rssi; | ||
931 | |||
932 | if (!(ah->rxchainmask & BIT(i))) | ||
933 | continue; | ||
934 | |||
935 | rssi = rx_stats->rs_rssi_ctl[i]; | ||
936 | if (rssi != ATH9K_RSSI_BAD) { | ||
937 | rxs->chains |= BIT(j); | ||
938 | rxs->chain_signal[j] = ah->noise + rssi; | ||
939 | } | ||
940 | j++; | ||
941 | } | ||
942 | |||
943 | /* | ||
944 | * Update Beacon RSSI, this is used by ANI. | ||
945 | */ | ||
946 | if (rx_stats->is_mybeacon && | ||
947 | ((ah->opmode == NL80211_IFTYPE_STATION) || | ||
948 | (ah->opmode == NL80211_IFTYPE_ADHOC))) { | ||
949 | ATH_RSSI_LPF(sc->last_rssi, rx_stats->rs_rssi); | ||
950 | last_rssi = sc->last_rssi; | ||
951 | |||
952 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | ||
953 | rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); | ||
954 | if (rssi < 0) | ||
955 | rssi = 0; | ||
956 | |||
957 | ah->stats.avgbrssi = rssi; | ||
958 | } | ||
959 | |||
960 | rxs->signal = ah->noise + rx_stats->rs_rssi; | ||
961 | } | ||
962 | |||
963 | static void ath9k_process_tsf(struct ath_rx_status *rs, | 765 | static void ath9k_process_tsf(struct ath_rx_status *rs, |
964 | struct ieee80211_rx_status *rxs, | 766 | struct ieee80211_rx_status *rxs, |
965 | u64 tsf) | 767 | u64 tsf) |
@@ -1055,7 +857,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1055 | * everything but the rate is checked here, the rate check is done | 857 | * everything but the rate is checked here, the rate check is done |
1056 | * separately to avoid doing two lookups for a rate for each frame. | 858 | * separately to avoid doing two lookups for a rate for each frame. |
1057 | */ | 859 | */ |
1058 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) | 860 | if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error, sc->rx.rxfilter)) |
1059 | return -EINVAL; | 861 | return -EINVAL; |
1060 | 862 | ||
1061 | if (ath_is_mybeacon(common, hdr)) { | 863 | if (ath_is_mybeacon(common, hdr)) { |
@@ -1069,10 +871,18 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1069 | if (WARN_ON(!ah->curchan)) | 871 | if (WARN_ON(!ah->curchan)) |
1070 | return -EINVAL; | 872 | return -EINVAL; |
1071 | 873 | ||
1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) | 874 | if (ath9k_cmn_process_rate(common, hw, rx_stats, rx_status)) { |
875 | /* | ||
876 | * No valid hardware bitrate found -- we should not get here | ||
877 | * because hardware has already validated this frame as OK. | ||
878 | */ | ||
879 | ath_dbg(common, ANY, "unsupported hw bitrate detected 0x%02x using 1 Mbit\n", | ||
880 | rx_stats->rs_rate); | ||
881 | RX_STAT_INC(rx_rate_err); | ||
1073 | return -EINVAL; | 882 | return -EINVAL; |
883 | } | ||
1074 | 884 | ||
1075 | ath9k_process_rssi(common, hw, rx_stats, rx_status); | 885 | ath9k_cmn_process_rssi(common, hw, rx_stats, rx_status); |
1076 | 886 | ||
1077 | rx_status->band = ah->curchan->chan->band; | 887 | rx_status->band = ah->curchan->chan->band; |
1078 | rx_status->freq = ah->curchan->chan->center_freq; | 888 | rx_status->freq = ah->curchan->chan->center_freq; |
@@ -1092,57 +902,6 @@ corrupt: | |||
1092 | return -EINVAL; | 902 | return -EINVAL; |
1093 | } | 903 | } |
1094 | 904 | ||
1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, | ||
1096 | struct sk_buff *skb, | ||
1097 | struct ath_rx_status *rx_stats, | ||
1098 | struct ieee80211_rx_status *rxs, | ||
1099 | bool decrypt_error) | ||
1100 | { | ||
1101 | struct ath_hw *ah = common->ah; | ||
1102 | struct ieee80211_hdr *hdr; | ||
1103 | int hdrlen, padpos, padsize; | ||
1104 | u8 keyix; | ||
1105 | __le16 fc; | ||
1106 | |||
1107 | /* see if any padding is done by the hw and remove it */ | ||
1108 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1109 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1110 | fc = hdr->frame_control; | ||
1111 | padpos = ieee80211_hdrlen(fc); | ||
1112 | |||
1113 | /* The MAC header is padded to have 32-bit boundary if the | ||
1114 | * packet payload is non-zero. The general calculation for | ||
1115 | * padsize would take into account odd header lengths: | ||
1116 | * padsize = (4 - padpos % 4) % 4; However, since only | ||
1117 | * even-length headers are used, padding can only be 0 or 2 | ||
1118 | * bytes and we can optimize this a bit. In addition, we must | ||
1119 | * not try to remove padding from short control frames that do | ||
1120 | * not have payload. */ | ||
1121 | padsize = padpos & 3; | ||
1122 | if (padsize && skb->len>=padpos+padsize+FCS_LEN) { | ||
1123 | memmove(skb->data + padsize, skb->data, padpos); | ||
1124 | skb_pull(skb, padsize); | ||
1125 | } | ||
1126 | |||
1127 | keyix = rx_stats->rs_keyix; | ||
1128 | |||
1129 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && | ||
1130 | ieee80211_has_protected(fc)) { | ||
1131 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
1132 | } else if (ieee80211_has_protected(fc) | ||
1133 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
1134 | keyix = skb->data[hdrlen + 3] >> 6; | ||
1135 | |||
1136 | if (test_bit(keyix, common->keymap)) | ||
1137 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
1138 | } | ||
1139 | if (ah->sw_mgmt_crypto && | ||
1140 | (rxs->flag & RX_FLAG_DECRYPTED) && | ||
1141 | ieee80211_is_mgmt(fc)) | ||
1142 | /* Use software decrypt for management frames. */ | ||
1143 | rxs->flag &= ~RX_FLAG_DECRYPTED; | ||
1144 | } | ||
1145 | |||
1146 | /* | 905 | /* |
1147 | * Run the LNA combining algorithm only in these cases: | 906 | * Run the LNA combining algorithm only in these cases: |
1148 | * | 907 | * |
@@ -1292,8 +1051,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1292 | skb_pull(skb, ah->caps.rx_status_len); | 1051 | skb_pull(skb, ah->caps.rx_status_len); |
1293 | 1052 | ||
1294 | if (!rs.rs_more) | 1053 | if (!rs.rs_more) |
1295 | ath9k_rx_skb_postprocess(common, hdr_skb, &rs, | 1054 | ath9k_cmn_rx_skb_postprocess(common, hdr_skb, &rs, |
1296 | rxs, decrypt_error); | 1055 | rxs, decrypt_error); |
1297 | 1056 | ||
1298 | if (rs.rs_more) { | 1057 | if (rs.rs_more) { |
1299 | RX_STAT_INC(rx_frags); | 1058 | RX_STAT_INC(rx_frags); |
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c index b686a7498450..a65cfb91adca 100644 --- a/drivers/net/wireless/ath/ath9k/tx99.c +++ b/drivers/net/wireless/ath/ath9k/tx99.c | |||
@@ -108,7 +108,7 @@ static int ath9k_tx99_init(struct ath_softc *sc) | |||
108 | struct ath_tx_control txctl; | 108 | struct ath_tx_control txctl; |
109 | int r; | 109 | int r; |
110 | 110 | ||
111 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { | 111 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) { |
112 | ath_err(common, | 112 | ath_err(common, |
113 | "driver is in invalid state unable to use TX99"); | 113 | "driver is in invalid state unable to use TX99"); |
114 | return -EINVAL; | 114 | return -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c index 1b3230fa3651..2879887f5691 100644 --- a/drivers/net/wireless/ath/ath9k/wow.c +++ b/drivers/net/wireless/ath/ath9k/wow.c | |||
@@ -198,7 +198,7 @@ int ath9k_suspend(struct ieee80211_hw *hw, | |||
198 | ath_cancel_work(sc); | 198 | ath_cancel_work(sc); |
199 | ath_stop_ani(sc); | 199 | ath_stop_ani(sc); |
200 | 200 | ||
201 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { | 201 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) { |
202 | ath_dbg(common, ANY, "Device not present\n"); | 202 | ath_dbg(common, ANY, "Device not present\n"); |
203 | ret = -EINVAL; | 203 | ret = -EINVAL; |
204 | goto fail_wow; | 204 | goto fail_wow; |
@@ -224,7 +224,7 @@ int ath9k_suspend(struct ieee80211_hw *hw, | |||
224 | * STA. | 224 | * STA. |
225 | */ | 225 | */ |
226 | 226 | ||
227 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | 227 | if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) { |
228 | ath_dbg(common, WOW, "None of the STA vifs are associated\n"); | 228 | ath_dbg(common, WOW, "None of the STA vifs are associated\n"); |
229 | ret = 1; | 229 | ret = 1; |
230 | goto fail_wow; | 230 | goto fail_wow; |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 55897d508a76..87cbec47fb48 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1040,11 +1040,11 @@ static int ath_max_framelen(int usec, int mcs, bool ht40, bool sgi) | |||
1040 | int symbols, bits; | 1040 | int symbols, bits; |
1041 | int bytes = 0; | 1041 | int bytes = 0; |
1042 | 1042 | ||
1043 | usec -= L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); | ||
1043 | symbols = sgi ? TIME_SYMBOLS_HALFGI(usec) : TIME_SYMBOLS(usec); | 1044 | symbols = sgi ? TIME_SYMBOLS_HALFGI(usec) : TIME_SYMBOLS(usec); |
1044 | bits = symbols * bits_per_symbol[mcs % 8][ht40] * streams; | 1045 | bits = symbols * bits_per_symbol[mcs % 8][ht40] * streams; |
1045 | bits -= OFDM_PLCP_BITS; | 1046 | bits -= OFDM_PLCP_BITS; |
1046 | bytes = bits / 8; | 1047 | bytes = bits / 8; |
1047 | bytes -= L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); | ||
1048 | if (bytes > 65532) | 1048 | if (bytes > 65532) |
1049 | bytes = 65532; | 1049 | bytes = 65532; |
1050 | 1050 | ||
@@ -1076,6 +1076,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
1076 | struct ath_tx_info *info, int len, bool rts) | 1076 | struct ath_tx_info *info, int len, bool rts) |
1077 | { | 1077 | { |
1078 | struct ath_hw *ah = sc->sc_ah; | 1078 | struct ath_hw *ah = sc->sc_ah; |
1079 | struct ath_common *common = ath9k_hw_common(ah); | ||
1079 | struct sk_buff *skb; | 1080 | struct sk_buff *skb; |
1080 | struct ieee80211_tx_info *tx_info; | 1081 | struct ieee80211_tx_info *tx_info; |
1081 | struct ieee80211_tx_rate *rates; | 1082 | struct ieee80211_tx_rate *rates; |
@@ -1145,7 +1146,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
1145 | } | 1146 | } |
1146 | 1147 | ||
1147 | /* legacy rates */ | 1148 | /* legacy rates */ |
1148 | rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; | 1149 | rate = &common->sbands[tx_info->band].bitrates[rates[i].idx]; |
1149 | if ((tx_info->band == IEEE80211_BAND_2GHZ) && | 1150 | if ((tx_info->band == IEEE80211_BAND_2GHZ) && |
1150 | !(rate->flags & IEEE80211_RATE_ERP_G)) | 1151 | !(rate->flags & IEEE80211_RATE_ERP_G)) |
1151 | phy = WLAN_RC_PHY_CCK; | 1152 | phy = WLAN_RC_PHY_CCK; |
@@ -1698,7 +1699,7 @@ int ath_cabq_update(struct ath_softc *sc) | |||
1698 | 1699 | ||
1699 | ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); | 1700 | ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); |
1700 | 1701 | ||
1701 | qi.tqi_readyTime = (cur_conf->beacon_interval * | 1702 | qi.tqi_readyTime = (TU_TO_USEC(cur_conf->beacon_interval) * |
1702 | ATH_CABQ_READY_TIME) / 100; | 1703 | ATH_CABQ_READY_TIME) / 100; |
1703 | ath_txq_update(sc, qnum, &qi); | 1704 | ath_txq_update(sc, qnum, &qi); |
1704 | 1705 | ||
@@ -1768,7 +1769,7 @@ bool ath_drain_all_txq(struct ath_softc *sc) | |||
1768 | int i; | 1769 | int i; |
1769 | u32 npend = 0; | 1770 | u32 npend = 0; |
1770 | 1771 | ||
1771 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) | 1772 | if (test_bit(ATH_OP_INVALID, &common->op_flags)) |
1772 | return true; | 1773 | return true; |
1773 | 1774 | ||
1774 | ath9k_hw_abort_tx_dma(ah); | 1775 | ath9k_hw_abort_tx_dma(ah); |
@@ -1816,11 +1817,12 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) | |||
1816 | */ | 1817 | */ |
1817 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | 1818 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) |
1818 | { | 1819 | { |
1820 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1819 | struct ath_atx_ac *ac, *last_ac; | 1821 | struct ath_atx_ac *ac, *last_ac; |
1820 | struct ath_atx_tid *tid, *last_tid; | 1822 | struct ath_atx_tid *tid, *last_tid; |
1821 | bool sent = false; | 1823 | bool sent = false; |
1822 | 1824 | ||
1823 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags) || | 1825 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags) || |
1824 | list_empty(&txq->axq_acq)) | 1826 | list_empty(&txq->axq_acq)) |
1825 | return; | 1827 | return; |
1826 | 1828 | ||
@@ -2470,7 +2472,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2470 | 2472 | ||
2471 | ath_txq_lock(sc, txq); | 2473 | ath_txq_lock(sc, txq); |
2472 | for (;;) { | 2474 | for (;;) { |
2473 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) | 2475 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) |
2474 | break; | 2476 | break; |
2475 | 2477 | ||
2476 | if (list_empty(&txq->axq_q)) { | 2478 | if (list_empty(&txq->axq_q)) { |
@@ -2553,7 +2555,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2553 | int status; | 2555 | int status; |
2554 | 2556 | ||
2555 | for (;;) { | 2557 | for (;;) { |
2556 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) | 2558 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) |
2557 | break; | 2559 | break; |
2558 | 2560 | ||
2559 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts); | 2561 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts); |
@@ -2569,7 +2571,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2569 | sc->beacon.tx_processed = true; | 2571 | sc->beacon.tx_processed = true; |
2570 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); | 2572 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); |
2571 | 2573 | ||
2572 | ath9k_csa_is_finished(sc); | 2574 | ath9k_csa_update(sc); |
2573 | continue; | 2575 | continue; |
2574 | } | 2576 | } |
2575 | 2577 | ||