aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hw.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c150
1 files changed, 42 insertions, 108 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index ae371448b5a..1a27f39c1ad 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -52,28 +52,6 @@ module_exit(ath9k_exit);
52/* Helper Functions */ 52/* Helper Functions */
53/********************/ 53/********************/
54 54
55static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
56{
57 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
58
59 if (!ah->curchan) /* should really check for CCK instead */
60 return clks / ATH9K_CLOCK_RATE_CCK;
61 if (conf->channel->band == IEEE80211_BAND_2GHZ)
62 return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
63
64 return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
65}
66
67static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
68{
69 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
70
71 if (conf_is_ht40(conf))
72 return ath9k_hw_mac_usec(ah, clks) / 2;
73 else
74 return ath9k_hw_mac_usec(ah, clks);
75}
76
77static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) 55static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
78{ 56{
79 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 57 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
@@ -343,30 +321,6 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
343 return true; 321 return true;
344} 322}
345 323
346static const char *ath9k_hw_devname(u16 devid)
347{
348 switch (devid) {
349 case AR5416_DEVID_PCI:
350 return "Atheros 5416";
351 case AR5416_DEVID_PCIE:
352 return "Atheros 5418";
353 case AR9160_DEVID_PCI:
354 return "Atheros 9160";
355 case AR5416_AR9100_DEVID:
356 return "Atheros 9100";
357 case AR9280_DEVID_PCI:
358 case AR9280_DEVID_PCIE:
359 return "Atheros 9280";
360 case AR9285_DEVID_PCIE:
361 return "Atheros 9285";
362 case AR5416_DEVID_AR9287_PCI:
363 case AR5416_DEVID_AR9287_PCIE:
364 return "Atheros 9287";
365 }
366
367 return NULL;
368}
369
370static void ath9k_hw_init_config(struct ath_hw *ah) 324static void ath9k_hw_init_config(struct ath_hw *ah)
371{ 325{
372 int i; 326 int i;
@@ -392,7 +346,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
392 ah->config.spurchans[i][1] = AR_NO_SPUR; 346 ah->config.spurchans[i][1] = AR_NO_SPUR;
393 } 347 }
394 348
395 ah->config.intr_mitigation = true; 349 ah->config.rx_intr_mitigation = true;
396 350
397 /* 351 /*
398 * We need this for PCI devices only (Cardbus, PCI, miniPCI) 352 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -437,8 +391,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
437 ah->beacon_interval = 100; 391 ah->beacon_interval = 100;
438 ah->enable_32kHz_clock = DONT_USE_32KHZ; 392 ah->enable_32kHz_clock = DONT_USE_32KHZ;
439 ah->slottime = (u32) -1; 393 ah->slottime = (u32) -1;
440 ah->acktimeout = (u32) -1;
441 ah->ctstimeout = (u32) -1;
442 ah->globaltxtimeout = (u32) -1; 394 ah->globaltxtimeout = (u32) -1;
443 ah->power_mode = ATH9K_PM_UNDEFINED; 395 ah->power_mode = ATH9K_PM_UNDEFINED;
444} 396}
@@ -1183,7 +1135,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1183 AR_IMR_RXORN | 1135 AR_IMR_RXORN |
1184 AR_IMR_BCNMISC; 1136 AR_IMR_BCNMISC;
1185 1137
1186 if (ah->config.intr_mitigation) 1138 if (ah->config.rx_intr_mitigation)
1187 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; 1139 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
1188 else 1140 else
1189 ah->mask_reg |= AR_IMR_RXOK; 1141 ah->mask_reg |= AR_IMR_RXOK;
@@ -1203,34 +1155,25 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1203 } 1155 }
1204} 1156}
1205 1157
1206static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) 1158static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
1207{ 1159{
1208 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { 1160 u32 val = ath9k_hw_mac_to_clks(ah, us);
1209 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, 1161 val = min(val, (u32) 0xFFFF);
1210 "bad ack timeout %u\n", us); 1162 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
1211 ah->acktimeout = (u32) -1;
1212 return false;
1213 } else {
1214 REG_RMW_FIELD(ah, AR_TIME_OUT,
1215 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
1216 ah->acktimeout = us;
1217 return true;
1218 }
1219} 1163}
1220 1164
1221static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) 1165static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
1222{ 1166{
1223 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { 1167 u32 val = ath9k_hw_mac_to_clks(ah, us);
1224 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, 1168 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
1225 "bad cts timeout %u\n", us); 1169 REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
1226 ah->ctstimeout = (u32) -1; 1170}
1227 return false; 1171
1228 } else { 1172static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
1229 REG_RMW_FIELD(ah, AR_TIME_OUT, 1173{
1230 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); 1174 u32 val = ath9k_hw_mac_to_clks(ah, us);
1231 ah->ctstimeout = us; 1175 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
1232 return true; 1176 REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
1233 }
1234} 1177}
1235 1178
1236static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) 1179static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
@@ -1247,31 +1190,37 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
1247 } 1190 }
1248} 1191}
1249 1192
1250static void ath9k_hw_init_user_settings(struct ath_hw *ah) 1193void ath9k_hw_init_global_settings(struct ath_hw *ah)
1251{ 1194{
1195 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
1196 int acktimeout;
1197 int slottime;
1198 int sifstime;
1199
1252 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", 1200 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
1253 ah->misc_mode); 1201 ah->misc_mode);
1254 1202
1255 if (ah->misc_mode != 0) 1203 if (ah->misc_mode != 0)
1256 REG_WRITE(ah, AR_PCU_MISC, 1204 REG_WRITE(ah, AR_PCU_MISC,
1257 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); 1205 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
1258 if (ah->slottime != (u32) -1) 1206
1259 ath9k_hw_setslottime(ah, ah->slottime); 1207 if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
1260 if (ah->acktimeout != (u32) -1) 1208 sifstime = 16;
1261 ath9k_hw_set_ack_timeout(ah, ah->acktimeout); 1209 else
1262 if (ah->ctstimeout != (u32) -1) 1210 sifstime = 10;
1263 ath9k_hw_set_cts_timeout(ah, ah->ctstimeout); 1211
1212 /* As defined by IEEE 802.11-2007 17.3.8.6 */
1213 slottime = ah->slottime + 3 * ah->coverage_class;
1214 acktimeout = slottime + sifstime;
1215 ath9k_hw_setslottime(ah, slottime);
1216 ath9k_hw_set_ack_timeout(ah, acktimeout);
1217 ath9k_hw_set_cts_timeout(ah, acktimeout);
1264 if (ah->globaltxtimeout != (u32) -1) 1218 if (ah->globaltxtimeout != (u32) -1)
1265 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); 1219 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
1266} 1220}
1221EXPORT_SYMBOL(ath9k_hw_init_global_settings);
1267 1222
1268const char *ath9k_hw_probe(u16 vendorid, u16 devid) 1223void ath9k_hw_deinit(struct ath_hw *ah)
1269{
1270 return vendorid == ATHEROS_VENDOR_ID ?
1271 ath9k_hw_devname(devid) : NULL;
1272}
1273
1274void ath9k_hw_detach(struct ath_hw *ah)
1275{ 1224{
1276 struct ath_common *common = ath9k_hw_common(ah); 1225 struct ath_common *common = ath9k_hw_common(ah);
1277 1226
@@ -1289,7 +1238,7 @@ free_hw:
1289 kfree(ah); 1238 kfree(ah);
1290 ah = NULL; 1239 ah = NULL;
1291} 1240}
1292EXPORT_SYMBOL(ath9k_hw_detach); 1241EXPORT_SYMBOL(ath9k_hw_deinit);
1293 1242
1294/*******/ 1243/*******/
1295/* INI */ 1244/* INI */
@@ -2090,7 +2039,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2090 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 2039 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
2091 ath9k_enable_rfkill(ah); 2040 ath9k_enable_rfkill(ah);
2092 2041
2093 ath9k_hw_init_user_settings(ah); 2042 ath9k_hw_init_global_settings(ah);
2094 2043
2095 if (AR_SREV_9287_12_OR_LATER(ah)) { 2044 if (AR_SREV_9287_12_OR_LATER(ah)) {
2096 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 2045 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
@@ -2120,7 +2069,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2120 2069
2121 REG_WRITE(ah, AR_OBS, 8); 2070 REG_WRITE(ah, AR_OBS, 8);
2122 2071
2123 if (ah->config.intr_mitigation) { 2072 if (ah->config.rx_intr_mitigation) {
2124 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 2073 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
2125 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 2074 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
2126 } 2075 }
@@ -2780,7 +2729,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
2780 2729
2781 *masked = isr & ATH9K_INT_COMMON; 2730 *masked = isr & ATH9K_INT_COMMON;
2782 2731
2783 if (ah->config.intr_mitigation) { 2732 if (ah->config.rx_intr_mitigation) {
2784 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) 2733 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
2785 *masked |= ATH9K_INT_RX; 2734 *masked |= ATH9K_INT_RX;
2786 } 2735 }
@@ -2913,7 +2862,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2913 } 2862 }
2914 if (ints & ATH9K_INT_RX) { 2863 if (ints & ATH9K_INT_RX) {
2915 mask |= AR_IMR_RXERR; 2864 mask |= AR_IMR_RXERR;
2916 if (ah->config.intr_mitigation) 2865 if (ah->config.rx_intr_mitigation)
2917 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; 2866 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
2918 else 2867 else
2919 mask |= AR_IMR_RXOK | AR_IMR_RXDESC; 2868 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -3687,21 +3636,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp)
3687} 3636}
3688EXPORT_SYMBOL(ath9k_hw_extend_tsf); 3637EXPORT_SYMBOL(ath9k_hw_extend_tsf);
3689 3638
3690bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
3691{
3692 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
3693 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
3694 "bad slot time %u\n", us);
3695 ah->slottime = (u32) -1;
3696 return false;
3697 } else {
3698 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
3699 ah->slottime = us;
3700 return true;
3701 }
3702}
3703EXPORT_SYMBOL(ath9k_hw_setslottime);
3704
3705void ath9k_hw_set11nmac2040(struct ath_hw *ah) 3639void ath9k_hw_set11nmac2040(struct ath_hw *ah)
3706{ 3640{
3707 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 3641 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;