aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-11-17 13:11:43 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-17 13:11:43 -0500
commite11c259f745889b55bc5596ca78271f2f5cf08d2 (patch)
tree5025f0bf9093e84d0643beb9097249c176dbbea7 /drivers/net/wireless/ath/ath9k
parent8d26784cf0d04c1238e906efdd5de76439cb0a1e (diff)
parentb4487c2d0edaf1332d7a9f11b5661044955ef5e2 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: include/net/bluetooth/bluetooth.h
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig1
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c140
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h26
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c254
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.h118
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c5
18 files changed, 519 insertions, 99 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index d9c08c619a3a..7b4c074e12fa 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -25,6 +25,7 @@ config ATH9K
25 25
26config ATH9K_PCI 26config ATH9K_PCI
27 bool "Atheros ath9k PCI/PCIe bus support" 27 bool "Atheros ath9k PCI/PCIe bus support"
28 default y
28 depends on ATH9K && PCI 29 depends on ATH9K && PCI
29 ---help--- 30 ---help---
30 This option enables the PCI bus support in ath9k. 31 This option enables the PCI bus support in ath9k.
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 36ed3c46fec6..49d3f25f509d 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -4,6 +4,7 @@ ath9k-y += beacon.o \
4 main.o \ 4 main.o \
5 recv.o \ 5 recv.o \
6 xmit.o \ 6 xmit.o \
7 mci.o \
7 8
8ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o 9ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
9ath9k-$(CONFIG_ATH9K_PCI) += pci.o 10ath9k-$(CONFIG_ATH9K_PCI) += pci.o
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 3b262ba6b172..a93bd63ad23b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -121,10 +121,8 @@ static const struct ar9300_eeprom ar9300_default = {
121 * if the register is per chain 121 * if the register is per chain
122 */ 122 */
123 .noiseFloorThreshCh = {-1, 0, 0}, 123 .noiseFloorThreshCh = {-1, 0, 0},
124 .ob = {1, 1, 1},/* 3 chain */ 124 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
125 .db_stage2 = {1, 1, 1}, /* 3 chain */ 125 .quick_drop = 0,
126 .db_stage3 = {0, 0, 0},
127 .db_stage4 = {0, 0, 0},
128 .xpaBiasLvl = 0, 126 .xpaBiasLvl = 0,
129 .txFrameToDataStart = 0x0e, 127 .txFrameToDataStart = 0x0e,
130 .txFrameToPaOn = 0x0e, 128 .txFrameToPaOn = 0x0e,
@@ -144,7 +142,7 @@ static const struct ar9300_eeprom ar9300_default = {
144 }, 142 },
145 .base_ext1 = { 143 .base_ext1 = {
146 .ant_div_control = 0, 144 .ant_div_control = 0,
147 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 145 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
148 }, 146 },
149 .calFreqPier2G = { 147 .calFreqPier2G = {
150 FREQ2FBIN(2412, 1), 148 FREQ2FBIN(2412, 1),
@@ -323,10 +321,8 @@ static const struct ar9300_eeprom ar9300_default = {
323 .spurChans = {0, 0, 0, 0, 0}, 321 .spurChans = {0, 0, 0, 0, 0},
324 /* noiseFloorThreshCh Check if the register is per chain */ 322 /* noiseFloorThreshCh Check if the register is per chain */
325 .noiseFloorThreshCh = {-1, 0, 0}, 323 .noiseFloorThreshCh = {-1, 0, 0},
326 .ob = {3, 3, 3}, /* 3 chain */ 324 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
327 .db_stage2 = {3, 3, 3}, /* 3 chain */ 325 .quick_drop = 0,
328 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
329 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
330 .xpaBiasLvl = 0, 326 .xpaBiasLvl = 0,
331 .txFrameToDataStart = 0x0e, 327 .txFrameToDataStart = 0x0e,
332 .txFrameToPaOn = 0x0e, 328 .txFrameToPaOn = 0x0e,
@@ -698,10 +694,8 @@ static const struct ar9300_eeprom ar9300_x113 = {
698 * if the register is per chain 694 * if the register is per chain
699 */ 695 */
700 .noiseFloorThreshCh = {-1, 0, 0}, 696 .noiseFloorThreshCh = {-1, 0, 0},
701 .ob = {1, 1, 1},/* 3 chain */ 697 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
702 .db_stage2 = {1, 1, 1}, /* 3 chain */ 698 .quick_drop = 0,
703 .db_stage3 = {0, 0, 0},
704 .db_stage4 = {0, 0, 0},
705 .xpaBiasLvl = 0, 699 .xpaBiasLvl = 0,
706 .txFrameToDataStart = 0x0e, 700 .txFrameToDataStart = 0x0e,
707 .txFrameToPaOn = 0x0e, 701 .txFrameToPaOn = 0x0e,
@@ -721,7 +715,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
721 }, 715 },
722 .base_ext1 = { 716 .base_ext1 = {
723 .ant_div_control = 0, 717 .ant_div_control = 0,
724 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 718 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
725 }, 719 },
726 .calFreqPier2G = { 720 .calFreqPier2G = {
727 FREQ2FBIN(2412, 1), 721 FREQ2FBIN(2412, 1),
@@ -900,10 +894,8 @@ static const struct ar9300_eeprom ar9300_x113 = {
900 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0}, 894 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
901 /* noiseFloorThreshCh Check if the register is per chain */ 895 /* noiseFloorThreshCh Check if the register is per chain */
902 .noiseFloorThreshCh = {-1, 0, 0}, 896 .noiseFloorThreshCh = {-1, 0, 0},
903 .ob = {3, 3, 3}, /* 3 chain */ 897 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
904 .db_stage2 = {3, 3, 3}, /* 3 chain */ 898 .quick_drop = 0,
905 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
906 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
907 .xpaBiasLvl = 0xf, 899 .xpaBiasLvl = 0xf,
908 .txFrameToDataStart = 0x0e, 900 .txFrameToDataStart = 0x0e,
909 .txFrameToPaOn = 0x0e, 901 .txFrameToPaOn = 0x0e,
@@ -1276,10 +1268,8 @@ static const struct ar9300_eeprom ar9300_h112 = {
1276 * if the register is per chain 1268 * if the register is per chain
1277 */ 1269 */
1278 .noiseFloorThreshCh = {-1, 0, 0}, 1270 .noiseFloorThreshCh = {-1, 0, 0},
1279 .ob = {1, 1, 1},/* 3 chain */ 1271 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1280 .db_stage2 = {1, 1, 1}, /* 3 chain */ 1272 .quick_drop = 0,
1281 .db_stage3 = {0, 0, 0},
1282 .db_stage4 = {0, 0, 0},
1283 .xpaBiasLvl = 0, 1273 .xpaBiasLvl = 0,
1284 .txFrameToDataStart = 0x0e, 1274 .txFrameToDataStart = 0x0e,
1285 .txFrameToPaOn = 0x0e, 1275 .txFrameToPaOn = 0x0e,
@@ -1291,20 +1281,20 @@ static const struct ar9300_eeprom ar9300_h112 = {
1291 .txEndToRxOn = 0x2, 1281 .txEndToRxOn = 0x2,
1292 .txFrameToXpaOn = 0xe, 1282 .txFrameToXpaOn = 0xe,
1293 .thresh62 = 28, 1283 .thresh62 = 28,
1294 .papdRateMaskHt20 = LE32(0x80c080), 1284 .papdRateMaskHt20 = LE32(0x0c80c080),
1295 .papdRateMaskHt40 = LE32(0x80c080), 1285 .papdRateMaskHt40 = LE32(0x0080c080),
1296 .futureModal = { 1286 .futureModal = {
1297 0, 0, 0, 0, 0, 0, 0, 0, 1287 0, 0, 0, 0, 0, 0, 0, 0,
1298 }, 1288 },
1299 }, 1289 },
1300 .base_ext1 = { 1290 .base_ext1 = {
1301 .ant_div_control = 0, 1291 .ant_div_control = 0,
1302 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 1292 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1303 }, 1293 },
1304 .calFreqPier2G = { 1294 .calFreqPier2G = {
1305 FREQ2FBIN(2412, 1), 1295 FREQ2FBIN(2412, 1),
1306 FREQ2FBIN(2437, 1), 1296 FREQ2FBIN(2437, 1),
1307 FREQ2FBIN(2472, 1), 1297 FREQ2FBIN(2462, 1),
1308 }, 1298 },
1309 /* ar9300_cal_data_per_freq_op_loop 2g */ 1299 /* ar9300_cal_data_per_freq_op_loop 2g */
1310 .calPierData2G = { 1300 .calPierData2G = {
@@ -1314,7 +1304,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
1314 }, 1304 },
1315 .calTarget_freqbin_Cck = { 1305 .calTarget_freqbin_Cck = {
1316 FREQ2FBIN(2412, 1), 1306 FREQ2FBIN(2412, 1),
1317 FREQ2FBIN(2484, 1), 1307 FREQ2FBIN(2472, 1),
1318 }, 1308 },
1319 .calTarget_freqbin_2G = { 1309 .calTarget_freqbin_2G = {
1320 FREQ2FBIN(2412, 1), 1310 FREQ2FBIN(2412, 1),
@@ -1478,10 +1468,8 @@ static const struct ar9300_eeprom ar9300_h112 = {
1478 .spurChans = {0, 0, 0, 0, 0}, 1468 .spurChans = {0, 0, 0, 0, 0},
1479 /* noiseFloorThreshCh Check if the register is per chain */ 1469 /* noiseFloorThreshCh Check if the register is per chain */
1480 .noiseFloorThreshCh = {-1, 0, 0}, 1470 .noiseFloorThreshCh = {-1, 0, 0},
1481 .ob = {3, 3, 3}, /* 3 chain */ 1471 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1482 .db_stage2 = {3, 3, 3}, /* 3 chain */ 1472 .quick_drop = 0,
1483 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
1484 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
1485 .xpaBiasLvl = 0, 1473 .xpaBiasLvl = 0,
1486 .txFrameToDataStart = 0x0e, 1474 .txFrameToDataStart = 0x0e,
1487 .txFrameToPaOn = 0x0e, 1475 .txFrameToPaOn = 0x0e,
@@ -1515,7 +1503,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
1515 FREQ2FBIN(5500, 0), 1503 FREQ2FBIN(5500, 0),
1516 FREQ2FBIN(5600, 0), 1504 FREQ2FBIN(5600, 0),
1517 FREQ2FBIN(5700, 0), 1505 FREQ2FBIN(5700, 0),
1518 FREQ2FBIN(5825, 0) 1506 FREQ2FBIN(5785, 0)
1519 }, 1507 },
1520 .calPierData5G = { 1508 .calPierData5G = {
1521 { 1509 {
@@ -1854,10 +1842,8 @@ static const struct ar9300_eeprom ar9300_x112 = {
1854 * if the register is per chain 1842 * if the register is per chain
1855 */ 1843 */
1856 .noiseFloorThreshCh = {-1, 0, 0}, 1844 .noiseFloorThreshCh = {-1, 0, 0},
1857 .ob = {1, 1, 1},/* 3 chain */ 1845 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1858 .db_stage2 = {1, 1, 1}, /* 3 chain */ 1846 .quick_drop = 0,
1859 .db_stage3 = {0, 0, 0},
1860 .db_stage4 = {0, 0, 0},
1861 .xpaBiasLvl = 0, 1847 .xpaBiasLvl = 0,
1862 .txFrameToDataStart = 0x0e, 1848 .txFrameToDataStart = 0x0e,
1863 .txFrameToPaOn = 0x0e, 1849 .txFrameToPaOn = 0x0e,
@@ -1877,7 +1863,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
1877 }, 1863 },
1878 .base_ext1 = { 1864 .base_ext1 = {
1879 .ant_div_control = 0, 1865 .ant_div_control = 0,
1880 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 1866 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1881 }, 1867 },
1882 .calFreqPier2G = { 1868 .calFreqPier2G = {
1883 FREQ2FBIN(2412, 1), 1869 FREQ2FBIN(2412, 1),
@@ -2056,10 +2042,8 @@ static const struct ar9300_eeprom ar9300_x112 = {
2056 .spurChans = {0, 0, 0, 0, 0}, 2042 .spurChans = {0, 0, 0, 0, 0},
2057 /* noiseFloorThreshch check if the register is per chain */ 2043 /* noiseFloorThreshch check if the register is per chain */
2058 .noiseFloorThreshCh = {-1, 0, 0}, 2044 .noiseFloorThreshCh = {-1, 0, 0},
2059 .ob = {3, 3, 3}, /* 3 chain */ 2045 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2060 .db_stage2 = {3, 3, 3}, /* 3 chain */ 2046 .quick_drop = 0,
2061 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
2062 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
2063 .xpaBiasLvl = 0, 2047 .xpaBiasLvl = 0,
2064 .txFrameToDataStart = 0x0e, 2048 .txFrameToDataStart = 0x0e,
2065 .txFrameToPaOn = 0x0e, 2049 .txFrameToPaOn = 0x0e,
@@ -2431,10 +2415,8 @@ static const struct ar9300_eeprom ar9300_h116 = {
2431 * if the register is per chain 2415 * if the register is per chain
2432 */ 2416 */
2433 .noiseFloorThreshCh = {-1, 0, 0}, 2417 .noiseFloorThreshCh = {-1, 0, 0},
2434 .ob = {1, 1, 1},/* 3 chain */ 2418 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2435 .db_stage2 = {1, 1, 1}, /* 3 chain */ 2419 .quick_drop = 0,
2436 .db_stage3 = {0, 0, 0},
2437 .db_stage4 = {0, 0, 0},
2438 .xpaBiasLvl = 0, 2420 .xpaBiasLvl = 0,
2439 .txFrameToDataStart = 0x0e, 2421 .txFrameToDataStart = 0x0e,
2440 .txFrameToPaOn = 0x0e, 2422 .txFrameToPaOn = 0x0e,
@@ -2454,12 +2436,12 @@ static const struct ar9300_eeprom ar9300_h116 = {
2454 }, 2436 },
2455 .base_ext1 = { 2437 .base_ext1 = {
2456 .ant_div_control = 0, 2438 .ant_div_control = 0,
2457 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 2439 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2458 }, 2440 },
2459 .calFreqPier2G = { 2441 .calFreqPier2G = {
2460 FREQ2FBIN(2412, 1), 2442 FREQ2FBIN(2412, 1),
2461 FREQ2FBIN(2437, 1), 2443 FREQ2FBIN(2437, 1),
2462 FREQ2FBIN(2472, 1), 2444 FREQ2FBIN(2462, 1),
2463 }, 2445 },
2464 /* ar9300_cal_data_per_freq_op_loop 2g */ 2446 /* ar9300_cal_data_per_freq_op_loop 2g */
2465 .calPierData2G = { 2447 .calPierData2G = {
@@ -2633,10 +2615,8 @@ static const struct ar9300_eeprom ar9300_h116 = {
2633 .spurChans = {0, 0, 0, 0, 0}, 2615 .spurChans = {0, 0, 0, 0, 0},
2634 /* noiseFloorThreshCh Check if the register is per chain */ 2616 /* noiseFloorThreshCh Check if the register is per chain */
2635 .noiseFloorThreshCh = {-1, 0, 0}, 2617 .noiseFloorThreshCh = {-1, 0, 0},
2636 .ob = {3, 3, 3}, /* 3 chain */ 2618 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2637 .db_stage2 = {3, 3, 3}, /* 3 chain */ 2619 .quick_drop = 0,
2638 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
2639 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
2640 .xpaBiasLvl = 0, 2620 .xpaBiasLvl = 0,
2641 .txFrameToDataStart = 0x0e, 2621 .txFrameToDataStart = 0x0e,
2642 .txFrameToPaOn = 0x0e, 2622 .txFrameToPaOn = 0x0e,
@@ -2663,7 +2643,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
2663 .xatten1MarginHigh = {0, 0, 0} 2643 .xatten1MarginHigh = {0, 0, 0}
2664 }, 2644 },
2665 .calFreqPier5G = { 2645 .calFreqPier5G = {
2666 FREQ2FBIN(5180, 0), 2646 FREQ2FBIN(5160, 0),
2667 FREQ2FBIN(5220, 0), 2647 FREQ2FBIN(5220, 0),
2668 FREQ2FBIN(5320, 0), 2648 FREQ2FBIN(5320, 0),
2669 FREQ2FBIN(5400, 0), 2649 FREQ2FBIN(5400, 0),
@@ -3023,6 +3003,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
3023 return eep->modalHeader5G.antennaGain; 3003 return eep->modalHeader5G.antennaGain;
3024 case EEP_ANTENNA_GAIN_2G: 3004 case EEP_ANTENNA_GAIN_2G:
3025 return eep->modalHeader2G.antennaGain; 3005 return eep->modalHeader2G.antennaGain;
3006 case EEP_QUICK_DROP:
3007 return pBase->miscConfiguration & BIT(1);
3026 default: 3008 default:
3027 return 0; 3009 return 0;
3028 } 3010 }
@@ -3428,25 +3410,14 @@ static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3428 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]); 3410 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3429 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]); 3411 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3430 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]); 3412 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3413 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3414 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3431 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl); 3415 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3432 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart); 3416 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3433 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn); 3417 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3434 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn); 3418 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3435 PR_EEP("txClip", modal_hdr->txClip); 3419 PR_EEP("txClip", modal_hdr->txClip);
3436 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize); 3420 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3437 PR_EEP("Chain0 ob", modal_hdr->ob[0]);
3438 PR_EEP("Chain1 ob", modal_hdr->ob[1]);
3439 PR_EEP("Chain2 ob", modal_hdr->ob[2]);
3440
3441 PR_EEP("Chain0 db_stage2", modal_hdr->db_stage2[0]);
3442 PR_EEP("Chain1 db_stage2", modal_hdr->db_stage2[1]);
3443 PR_EEP("Chain2 db_stage2", modal_hdr->db_stage2[2]);
3444 PR_EEP("Chain0 db_stage3", modal_hdr->db_stage3[0]);
3445 PR_EEP("Chain1 db_stage3", modal_hdr->db_stage3[1]);
3446 PR_EEP("Chain2 db_stage3", modal_hdr->db_stage3[2]);
3447 PR_EEP("Chain0 db_stage4", modal_hdr->db_stage4[0]);
3448 PR_EEP("Chain1 db_stage4", modal_hdr->db_stage4[1]);
3449 PR_EEP("Chain2 db_stage4", modal_hdr->db_stage4[2]);
3450 3421
3451 return len; 3422 return len;
3452} 3423}
@@ -3503,6 +3474,7 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3503 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4))); 3474 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3504 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5))); 3475 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3505 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0))); 3476 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3477 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3506 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1); 3478 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3507 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio); 3479 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3508 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio); 3480 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
@@ -3965,6 +3937,40 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3965 } 3937 }
3966} 3938}
3967 3939
3940static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3941{
3942 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3943 int quick_drop = ath9k_hw_ar9300_get_eeprom(ah, EEP_QUICK_DROP);
3944 s32 t[3], f[3] = {5180, 5500, 5785};
3945
3946 if (!quick_drop)
3947 return;
3948
3949 if (freq < 4000)
3950 quick_drop = eep->modalHeader2G.quick_drop;
3951 else {
3952 t[0] = eep->base_ext1.quick_drop_low;
3953 t[1] = eep->modalHeader5G.quick_drop;
3954 t[2] = eep->base_ext1.quick_drop_high;
3955 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
3956 }
3957 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
3958}
3959
3960static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq)
3961{
3962 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3963 u32 value;
3964
3965 value = (freq < 4000) ? eep->modalHeader2G.txEndToXpaOff :
3966 eep->modalHeader5G.txEndToXpaOff;
3967
3968 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3969 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
3970 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3971 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
3972}
3973
3968static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, 3974static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3969 struct ath9k_channel *chan) 3975 struct ath9k_channel *chan)
3970{ 3976{
@@ -3972,10 +3978,12 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3972 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); 3978 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
3973 ar9003_hw_drive_strength_apply(ah); 3979 ar9003_hw_drive_strength_apply(ah);
3974 ar9003_hw_atten_apply(ah, chan); 3980 ar9003_hw_atten_apply(ah, chan);
3981 ar9003_hw_quick_drop_apply(ah, chan->channel);
3975 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) 3982 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah))
3976 ar9003_hw_internal_regulator_apply(ah); 3983 ar9003_hw_internal_regulator_apply(ah);
3977 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) 3984 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3978 ar9003_hw_apply_tuning_caps(ah); 3985 ar9003_hw_apply_tuning_caps(ah);
3986 ar9003_hw_txend_to_xpa_off_apply(ah, chan->channel);
3979} 3987}
3980 3988
3981static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, 3989static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
@@ -5051,6 +5059,8 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5051 regulatory->max_power_level = targetPowerValT2[i]; 5059 regulatory->max_power_level = targetPowerValT2[i];
5052 } 5060 }
5053 5061
5062 ath9k_hw_update_regulatory_maxpower(ah);
5063
5054 if (test) 5064 if (test)
5055 return; 5065 return;
5056 5066
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 6335a867527e..bb223fe82816 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -216,10 +216,8 @@ struct ar9300_modal_eep_header {
216 u8 spurChans[AR_EEPROM_MODAL_SPURS]; 216 u8 spurChans[AR_EEPROM_MODAL_SPURS];
217 /* 3 Check if the register is per chain */ 217 /* 3 Check if the register is per chain */
218 int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; 218 int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
219 u8 ob[AR9300_MAX_CHAINS]; 219 u8 reserved[11];
220 u8 db_stage2[AR9300_MAX_CHAINS]; 220 int8_t quick_drop;
221 u8 db_stage3[AR9300_MAX_CHAINS];
222 u8 db_stage4[AR9300_MAX_CHAINS];
223 u8 xpaBiasLvl; 221 u8 xpaBiasLvl;
224 u8 txFrameToDataStart; 222 u8 txFrameToDataStart;
225 u8 txFrameToPaOn; 223 u8 txFrameToPaOn;
@@ -269,7 +267,9 @@ struct cal_ctl_data_5g {
269 267
270struct ar9300_BaseExtension_1 { 268struct ar9300_BaseExtension_1 {
271 u8 ant_div_control; 269 u8 ant_div_control;
272 u8 future[13]; 270 u8 future[11];
271 int8_t quick_drop_low;
272 int8_t quick_drop_high;
273} __packed; 273} __packed;
274 274
275struct ar9300_BaseExtension_2 { 275struct ar9300_BaseExtension_2 {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 2330e7ede199..e41d26939ab8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -199,12 +199,14 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
199 synth_freq = chan->channel; 199 synth_freq = chan->channel;
200 } 200 }
201 } else { 201 } else {
202 range = 10; 202 range = AR_SREV_9462(ah) ? 5 : 10;
203 max_spur_cnts = 4; 203 max_spur_cnts = 4;
204 synth_freq = chan->channel; 204 synth_freq = chan->channel;
205 } 205 }
206 206
207 for (i = 0; i < max_spur_cnts; i++) { 207 for (i = 0; i < max_spur_cnts; i++) {
208 if (AR_SREV_9462(ah) && (i == 0 || i == 3))
209 continue;
208 negative = 0; 210 negative = 0;
209 if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) 211 if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah))
210 cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], 212 cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 4114fe752c6b..497d7461838a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -389,6 +389,8 @@
389#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 389#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
390 390
391#define AR_PHY_RIFS_INIT_DELAY 0x3ff0000 391#define AR_PHY_RIFS_INIT_DELAY 0x3ff0000
392#define AR_PHY_AGC_QUICK_DROP 0x03c00000
393#define AR_PHY_AGC_QUICK_DROP_S 22
392#define AR_PHY_AGC_COARSE_LOW 0x00007F80 394#define AR_PHY_AGC_COARSE_LOW 0x00007F80
393#define AR_PHY_AGC_COARSE_LOW_S 7 395#define AR_PHY_AGC_COARSE_LOW_S 7
394#define AR_PHY_AGC_COARSE_HIGH 0x003F8000 396#define AR_PHY_AGC_COARSE_HIGH 0x003F8000
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index 9c51b395b4ff..259a6f312afb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -43,16 +43,16 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
43 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 43 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
44 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, 44 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
45 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, 45 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
46 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, 46 {0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x5ac640de},
47 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, 47 {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x0796be89},
48 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, 48 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
49 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, 49 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
50 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, 50 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
51 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, 51 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
52 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, 52 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
53 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, 53 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
54 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, 54 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x92c84d2e},
55 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3039605e, 0x33795d5e}, 55 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
56 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 56 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
57 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, 57 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
58 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, 58 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
@@ -688,8 +688,8 @@ static const u32 ar9462_2p0_mac_postamble_emulation[][5] = {
688static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = { 688static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = {
689 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 689 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
690 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, 690 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
691 {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, 691 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
692 {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, 692 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
693}; 693};
694 694
695static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { 695static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = {
@@ -717,8 +717,8 @@ static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = {
717static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { 717static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
718 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 718 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
719 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, 719 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
720 {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, 720 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
721 {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, 721 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
722}; 722};
723 723
724static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { 724static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = {
@@ -1059,7 +1059,7 @@ static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = {
1059 1059
1060static const u32 ar9462_2p0_soc_postamble[][5] = { 1060static const u32 ar9462_2p0_soc_postamble[][5] = {
1061 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1061 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1062 {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, 1062 {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033},
1063}; 1063};
1064 1064
1065static const u32 ar9462_2p0_baseband_core[][2] = { 1065static const u32 ar9462_2p0_baseband_core[][2] = {
@@ -1257,8 +1257,8 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
1257 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, 1257 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
1258 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, 1258 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
1259 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, 1259 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81},
1260 {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, 1260 {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83},
1261 {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, 1261 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84},
1262 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, 1262 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
1263 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, 1263 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
1264 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, 1264 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
@@ -1850,8 +1850,8 @@ static const u32 ar9462_modes_green_ob_db_tx_gain_table_2p0[][5] = {
1850 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, 1850 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
1851 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, 1851 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
1852 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, 1852 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81},
1853 {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, 1853 {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83},
1854 {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, 1854 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84},
1855 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, 1855 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
1856 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, 1856 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
1857 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, 1857 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 1c269f50822b..93b45b4b3033 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -25,6 +25,7 @@
25 25
26#include "debug.h" 26#include "debug.h"
27#include "common.h" 27#include "common.h"
28#include "mci.h"
28 29
29/* 30/*
30 * Header for the ath9k.ko driver core *only* -- hw code nor any other driver 31 * Header for the ath9k.ko driver core *only* -- hw code nor any other driver
@@ -252,6 +253,7 @@ struct ath_node {
252#ifdef CONFIG_ATH9K_DEBUGFS 253#ifdef CONFIG_ATH9K_DEBUGFS
253 struct list_head list; /* for sc->nodes */ 254 struct list_head list; /* for sc->nodes */
254 struct ieee80211_sta *sta; /* station struct we're part of */ 255 struct ieee80211_sta *sta; /* station struct we're part of */
256 struct ieee80211_vif *vif; /* interface with which we're associated */
255#endif 257#endif
256 struct ath_atx_tid tid[WME_NUM_TID]; 258 struct ath_atx_tid tid[WME_NUM_TID];
257 struct ath_atx_ac ac[WME_NUM_AC]; 259 struct ath_atx_ac ac[WME_NUM_AC];
@@ -443,7 +445,9 @@ struct ath_btcoex {
443 u32 btcoex_no_stomp; /* in usec */ 445 u32 btcoex_no_stomp; /* in usec */
444 u32 btcoex_period; /* in usec */ 446 u32 btcoex_period; /* in usec */
445 u32 btscan_no_stomp; /* in usec */ 447 u32 btscan_no_stomp; /* in usec */
448 u32 duty_cycle;
446 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ 449 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
450 struct ath_mci_profile mci;
447}; 451};
448 452
449int ath_init_btcoex_timer(struct ath_softc *sc); 453int ath_init_btcoex_timer(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 2741203e803f..6fb719d85b37 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -709,24 +709,29 @@ static ssize_t read_file_stations(struct file *file, char __user *user_buf,
709 709
710 len += snprintf(buf + len, size - len, 710 len += snprintf(buf + len, size - len,
711 "Stations:\n" 711 "Stations:\n"
712 " tid: addr sched paused buf_q-empty an ac\n" 712 " tid: addr sched paused buf_q-empty an ac baw\n"
713 " ac: addr sched tid_q-empty txq\n"); 713 " ac: addr sched tid_q-empty txq\n");
714 714
715 spin_lock(&sc->nodes_lock); 715 spin_lock(&sc->nodes_lock);
716 list_for_each_entry(an, &sc->nodes, list) { 716 list_for_each_entry(an, &sc->nodes, list) {
717 unsigned short ma = an->maxampdu;
718 if (ma == 0)
719 ma = 65535; /* see ath_lookup_rate */
717 len += snprintf(buf + len, size - len, 720 len += snprintf(buf + len, size - len,
718 "%pM\n", an->sta->addr); 721 "iface: %pM sta: %pM max-ampdu: %hu mpdu-density: %uus\n",
722 an->vif->addr, an->sta->addr, ma,
723 (unsigned int)(an->mpdudensity));
719 if (len >= size) 724 if (len >= size)
720 goto done; 725 goto done;
721 726
722 for (q = 0; q < WME_NUM_TID; q++) { 727 for (q = 0; q < WME_NUM_TID; q++) {
723 struct ath_atx_tid *tid = &(an->tid[q]); 728 struct ath_atx_tid *tid = &(an->tid[q]);
724 len += snprintf(buf + len, size - len, 729 len += snprintf(buf + len, size - len,
725 " tid: %p %s %s %i %p %p\n", 730 " tid: %p %s %s %i %p %p %hu\n",
726 tid, tid->sched ? "sched" : "idle", 731 tid, tid->sched ? "sched" : "idle",
727 tid->paused ? "paused" : "running", 732 tid->paused ? "paused" : "running",
728 skb_queue_empty(&tid->buf_q), 733 skb_queue_empty(&tid->buf_q),
729 tid->an, tid->ac); 734 tid->an, tid->ac, tid->baw_size);
730 if (len >= size) 735 if (len >= size)
731 goto done; 736 goto done;
732 } 737 }
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 49abd34be741..5ff7ab965120 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -249,7 +249,8 @@ enum eeprom_param {
249 EEP_ANT_DIV_CTL1, 249 EEP_ANT_DIV_CTL1,
250 EEP_CHAIN_MASK_REDUCE, 250 EEP_CHAIN_MASK_REDUCE,
251 EEP_ANTENNA_GAIN_2G, 251 EEP_ANTENNA_GAIN_2G,
252 EEP_ANTENNA_GAIN_5G 252 EEP_ANTENNA_GAIN_5G,
253 EEP_QUICK_DROP
253}; 254};
254 255
255enum ar5416_rates { 256enum ar5416_rates {
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 655576c8fdab..2c279dcaf4ba 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -189,8 +189,8 @@ static void ath_btcoex_period_timer(unsigned long data)
189 bool is_btscan; 189 bool is_btscan;
190 190
191 ath9k_ps_wakeup(sc); 191 ath9k_ps_wakeup(sc);
192 ath_detect_bt_priority(sc); 192 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
193 193 ath_detect_bt_priority(sc);
194 is_btscan = sc->sc_flags & SC_OP_BT_SCAN; 194 is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
195 195
196 spin_lock_bh(&btcoex->btcoex_lock); 196 spin_lock_bh(&btcoex->btcoex_lock);
@@ -212,8 +212,9 @@ static void ath_btcoex_period_timer(unsigned long data)
212 } 212 }
213 213
214 ath9k_ps_restore(sc); 214 ath9k_ps_restore(sc);
215 timer_period = btcoex->btcoex_period / 1000;
215 mod_timer(&btcoex->period_timer, jiffies + 216 mod_timer(&btcoex->period_timer, jiffies +
216 msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); 217 msecs_to_jiffies(timer_period));
217} 218}
218 219
219/* 220/*
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2f91acccb7db..662ab7e9a0f0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2335,7 +2335,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2335 ah->enabled_cals |= TX_IQ_ON_AGC_CAL; 2335 ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
2336 } 2336 }
2337 if (AR_SREV_9462(ah)) 2337 if (AR_SREV_9462(ah))
2338 pCap->hw_caps |= ATH9K_HW_CAP_RTT; 2338 pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI;
2339 2339
2340 return 0; 2340 return 0;
2341} 2341}
@@ -2583,7 +2583,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
2583 struct ath9k_channel *chan = ah->curchan; 2583 struct ath9k_channel *chan = ah->curchan;
2584 struct ieee80211_channel *channel = chan->chan; 2584 struct ieee80211_channel *channel = chan->chan;
2585 2585
2586 reg->power_limit = min_t(int, limit, MAX_RATE_POWER); 2586 reg->power_limit = min_t(u32, limit, MAX_RATE_POWER);
2587 if (test) 2587 if (test)
2588 channel->max_power = MAX_RATE_POWER / 2; 2588 channel->max_power = MAX_RATE_POWER / 2;
2589 2589
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f389b3c93cf3..33e8f2f9d425 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -203,6 +203,7 @@ enum ath9k_hw_caps {
203 ATH9K_HW_CAP_5GHZ = BIT(14), 203 ATH9K_HW_CAP_5GHZ = BIT(14),
204 ATH9K_HW_CAP_APM = BIT(15), 204 ATH9K_HW_CAP_APM = BIT(15),
205 ATH9K_HW_CAP_RTT = BIT(16), 205 ATH9K_HW_CAP_RTT = BIT(16),
206 ATH9K_HW_CAP_MCI = BIT(17),
206}; 207};
207 208
208struct ath9k_hw_capabilities { 209struct ath9k_hw_capabilities {
@@ -419,6 +420,16 @@ enum ath9k_rx_qtype {
419 ATH9K_RX_QUEUE_MAX, 420 ATH9K_RX_QUEUE_MAX,
420}; 421};
421 422
423enum ath_mci_gpm_coex_profile_type {
424 MCI_GPM_COEX_PROFILE_UNKNOWN,
425 MCI_GPM_COEX_PROFILE_RFCOMM,
426 MCI_GPM_COEX_PROFILE_A2DP,
427 MCI_GPM_COEX_PROFILE_HID,
428 MCI_GPM_COEX_PROFILE_BNEP,
429 MCI_GPM_COEX_PROFILE_VOICE,
430 MCI_GPM_COEX_PROFILE_MAX
431};
432
422struct ath9k_beacon_state { 433struct ath9k_beacon_state {
423 u32 bs_nexttbtt; 434 u32 bs_nexttbtt;
424 u32 bs_nextdtim; 435 u32 bs_nextdtim;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index d4c909f8e474..e046de94836a 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -424,6 +424,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
424 txq = sc->tx.txq_map[WME_AC_BE]; 424 txq = sc->tx.txq_map[WME_AC_BE];
425 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); 425 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
426 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; 426 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
427 sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
428 INIT_LIST_HEAD(&sc->btcoex.mci.info);
427 break; 429 break;
428 default: 430 default:
429 WARN_ON(1); 431 WARN_ON(1);
@@ -695,6 +697,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
695 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 697 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
696 698
697 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 699 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
700 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
698 701
699 hw->queues = 4; 702 hw->queues = 4;
700 hw->max_rates = 4; 703 hw->max_rates = 4;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 93fbe6f40898..e43c41cff25b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -630,7 +630,8 @@ set_timer:
630 } 630 }
631} 631}
632 632
633static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) 633static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
634 struct ieee80211_vif *vif)
634{ 635{
635 struct ath_node *an; 636 struct ath_node *an;
636 an = (struct ath_node *)sta->drv_priv; 637 an = (struct ath_node *)sta->drv_priv;
@@ -640,6 +641,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
640 list_add(&an->list, &sc->nodes); 641 list_add(&an->list, &sc->nodes);
641 spin_unlock(&sc->nodes_lock); 642 spin_unlock(&sc->nodes_lock);
642 an->sta = sta; 643 an->sta = sta;
644 an->vif = vif;
643#endif 645#endif
644 if (sc->sc_flags & SC_OP_TXAGGR) { 646 if (sc->sc_flags & SC_OP_TXAGGR) {
645 ath_tx_node_init(sc, an); 647 ath_tx_node_init(sc, an);
@@ -1133,8 +1135,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
1133 1135
1134 if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && 1136 if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
1135 !ah->btcoex_hw.enabled) { 1137 !ah->btcoex_hw.enabled) {
1136 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 1138 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
1137 AR_STOMP_LOW_WLAN_WGHT); 1139 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1140 AR_STOMP_LOW_WLAN_WGHT);
1138 ath9k_hw_btcoex_enable(ah); 1141 ath9k_hw_btcoex_enable(ah);
1139 1142
1140 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 1143 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
@@ -1237,6 +1240,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1237 ath9k_hw_btcoex_disable(ah); 1240 ath9k_hw_btcoex_disable(ah);
1238 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 1241 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1239 ath9k_btcoex_timer_pause(sc); 1242 ath9k_btcoex_timer_pause(sc);
1243 ath_mci_flush_profile(&sc->btcoex.mci);
1240 } 1244 }
1241 1245
1242 spin_lock_bh(&sc->sc_pcu_lock); 1246 spin_lock_bh(&sc->sc_pcu_lock);
@@ -1798,7 +1802,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw,
1798 struct ath_node *an = (struct ath_node *) sta->drv_priv; 1802 struct ath_node *an = (struct ath_node *) sta->drv_priv;
1799 struct ieee80211_key_conf ps_key = { }; 1803 struct ieee80211_key_conf ps_key = { };
1800 1804
1801 ath_node_attach(sc, sta); 1805 ath_node_attach(sc, sta, vif);
1802 1806
1803 if (vif->type != NL80211_IFTYPE_AP && 1807 if (vif->type != NL80211_IFTYPE_AP &&
1804 vif->type != NL80211_IFTYPE_AP_VLAN) 1808 vif->type != NL80211_IFTYPE_AP_VLAN)
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
new file mode 100644
index 000000000000..0fbb141bc302
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -0,0 +1,254 @@
1/*
2 * Copyright (c) 2010-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 "ath9k.h"
18#include "mci.h"
19
20u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 };
21
22static struct ath_mci_profile_info*
23ath_mci_find_profile(struct ath_mci_profile *mci,
24 struct ath_mci_profile_info *info)
25{
26 struct ath_mci_profile_info *entry;
27
28 list_for_each_entry(entry, &mci->info, list) {
29 if (entry->conn_handle == info->conn_handle)
30 break;
31 }
32 return entry;
33}
34
35static bool ath_mci_add_profile(struct ath_common *common,
36 struct ath_mci_profile *mci,
37 struct ath_mci_profile_info *info)
38{
39 struct ath_mci_profile_info *entry;
40
41 if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) &&
42 (info->type == MCI_GPM_COEX_PROFILE_VOICE)) {
43 ath_dbg(common, ATH_DBG_MCI,
44 "Too many SCO profile, failed to add new profile\n");
45 return false;
46 }
47
48 if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) &&
49 (info->type != MCI_GPM_COEX_PROFILE_VOICE)) {
50 ath_dbg(common, ATH_DBG_MCI,
51 "Too many ACL profile, failed to add new profile\n");
52 return false;
53 }
54
55 entry = ath_mci_find_profile(mci, info);
56
57 if (entry)
58 memcpy(entry, info, 10);
59 else {
60 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
61 if (!entry)
62 return false;
63
64 memcpy(entry, info, 10);
65 INC_PROF(mci, info);
66 list_add_tail(&info->list, &mci->info);
67 }
68 return true;
69}
70
71static void ath_mci_del_profile(struct ath_common *common,
72 struct ath_mci_profile *mci,
73 struct ath_mci_profile_info *info)
74{
75 struct ath_mci_profile_info *entry;
76
77 entry = ath_mci_find_profile(mci, info);
78
79 if (!entry) {
80 ath_dbg(common, ATH_DBG_MCI,
81 "Profile to be deleted not found\n");
82 return;
83 }
84 DEC_PROF(mci, entry);
85 list_del(&entry->list);
86 kfree(entry);
87}
88
89void ath_mci_flush_profile(struct ath_mci_profile *mci)
90{
91 struct ath_mci_profile_info *info, *tinfo;
92
93 list_for_each_entry_safe(info, tinfo, &mci->info, list) {
94 list_del(&info->list);
95 DEC_PROF(mci, info);
96 kfree(info);
97 }
98 mci->aggr_limit = 0;
99}
100
101static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex)
102{
103 struct ath_mci_profile *mci = &btcoex->mci;
104 u32 wlan_airtime = btcoex->btcoex_period *
105 (100 - btcoex->duty_cycle) / 100;
106
107 /*
108 * Scale: wlan_airtime is in ms, aggr_limit is in 0.25 ms.
109 * When wlan_airtime is less than 4ms, aggregation limit has to be
110 * adjusted half of wlan_airtime to ensure that the aggregation can fit
111 * without collision with BT traffic.
112 */
113 if ((wlan_airtime <= 4) &&
114 (!mci->aggr_limit || (mci->aggr_limit > (2 * wlan_airtime))))
115 mci->aggr_limit = 2 * wlan_airtime;
116}
117
118static void ath_mci_update_scheme(struct ath_softc *sc)
119{
120 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
121 struct ath_btcoex *btcoex = &sc->btcoex;
122 struct ath_mci_profile *mci = &btcoex->mci;
123 struct ath_mci_profile_info *info;
124 u32 num_profile = NUM_PROF(mci);
125
126 if (num_profile == 1) {
127 info = list_first_entry(&mci->info,
128 struct ath_mci_profile_info,
129 list);
130 if (mci->num_sco && info->T == 12) {
131 mci->aggr_limit = 8;
132 ath_dbg(common, ATH_DBG_MCI,
133 "Single SCO, aggregation limit 2 ms\n");
134 } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) &&
135 !info->master) {
136 btcoex->btcoex_period = 60;
137 ath_dbg(common, ATH_DBG_MCI,
138 "Single slave PAN/FTP, bt period 60 ms\n");
139 } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) &&
140 (info->T > 0 && info->T < 50) &&
141 (info->A > 1 || info->W > 1)) {
142 btcoex->duty_cycle = 30;
143 mci->aggr_limit = 8;
144 ath_dbg(common, ATH_DBG_MCI,
145 "Multiple attempt/timeout single HID "
146 "aggregation limit 2 ms dutycycle 30%%\n");
147 }
148 } else if ((num_profile == 2) && (mci->num_hid == 2)) {
149 btcoex->duty_cycle = 30;
150 mci->aggr_limit = 8;
151 ath_dbg(common, ATH_DBG_MCI,
152 "Two HIDs aggregation limit 2 ms dutycycle 30%%\n");
153 } else if (num_profile > 3) {
154 mci->aggr_limit = 6;
155 ath_dbg(common, ATH_DBG_MCI,
156 "Three or more profiles aggregation limit 1.5 ms\n");
157 }
158
159 if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) {
160 if (IS_CHAN_HT(sc->sc_ah->curchan))
161 ath_mci_adjust_aggr_limit(btcoex);
162 else
163 btcoex->btcoex_period >>= 1;
164 }
165
166 ath9k_hw_btcoex_disable(sc->sc_ah);
167 ath9k_btcoex_timer_pause(sc);
168
169 if (IS_CHAN_5GHZ(sc->sc_ah->curchan))
170 return;
171
172 btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0);
173 if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE)
174 btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE;
175
176 btcoex->btcoex_period *= 1000;
177 btcoex->btcoex_no_stomp = btcoex->btcoex_period *
178 (100 - btcoex->duty_cycle) / 100;
179
180 ath9k_hw_btcoex_enable(sc->sc_ah);
181 ath9k_btcoex_timer_resume(sc);
182}
183
184void ath_mci_process_profile(struct ath_softc *sc,
185 struct ath_mci_profile_info *info)
186{
187 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
188 struct ath_btcoex *btcoex = &sc->btcoex;
189 struct ath_mci_profile *mci = &btcoex->mci;
190
191 if (info->start) {
192 if (!ath_mci_add_profile(common, mci, info))
193 return;
194 } else
195 ath_mci_del_profile(common, mci, info);
196
197 btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD;
198 mci->aggr_limit = mci->num_sco ? 6 : 0;
199 if (NUM_PROF(mci)) {
200 btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
201 btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)];
202 } else {
203 btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL :
204 ATH_BTCOEX_STOMP_LOW;
205 btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
206 }
207
208 ath_mci_update_scheme(sc);
209}
210
211void ath_mci_process_status(struct ath_softc *sc,
212 struct ath_mci_profile_status *status)
213{
214 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
215 struct ath_btcoex *btcoex = &sc->btcoex;
216 struct ath_mci_profile *mci = &btcoex->mci;
217 struct ath_mci_profile_info info;
218 int i = 0, old_num_mgmt = mci->num_mgmt;
219
220 /* Link status type are not handled */
221 if (status->is_link) {
222 ath_dbg(common, ATH_DBG_MCI,
223 "Skip link type status update\n");
224 return;
225 }
226
227 memset(&info, 0, sizeof(struct ath_mci_profile_info));
228
229 info.conn_handle = status->conn_handle;
230 if (ath_mci_find_profile(mci, &info)) {
231 ath_dbg(common, ATH_DBG_MCI,
232 "Skip non link state update for existing profile %d\n",
233 status->conn_handle);
234 return;
235 }
236 if (status->conn_handle >= ATH_MCI_MAX_PROFILE) {
237 ath_dbg(common, ATH_DBG_MCI,
238 "Ignore too many non-link update\n");
239 return;
240 }
241 if (status->is_critical)
242 __set_bit(status->conn_handle, mci->status);
243 else
244 __clear_bit(status->conn_handle, mci->status);
245
246 mci->num_mgmt = 0;
247 do {
248 if (test_bit(i, mci->status))
249 mci->num_mgmt++;
250 } while (++i < ATH_MCI_MAX_PROFILE);
251
252 if (old_num_mgmt != mci->num_mgmt)
253 ath_mci_update_scheme(sc);
254}
diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h
new file mode 100644
index 000000000000..9590c61822d1
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/mci.h
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) 2010-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#ifndef MCI_H
18#define MCI_H
19
20#define ATH_MCI_DEF_BT_PERIOD 40
21#define ATH_MCI_BDR_DUTY_CYCLE 20
22#define ATH_MCI_MAX_DUTY_CYCLE 90
23
24#define ATH_MCI_DEF_AGGR_LIMIT 6 /* in 0.24 ms */
25#define ATH_MCI_MAX_ACL_PROFILE 7
26#define ATH_MCI_MAX_SCO_PROFILE 1
27#define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\
28 ATH_MCI_MAX_SCO_PROFILE)
29
30#define INC_PROF(_mci, _info) do { \
31 switch (_info->type) { \
32 case MCI_GPM_COEX_PROFILE_RFCOMM:\
33 _mci->num_other_acl++; \
34 break; \
35 case MCI_GPM_COEX_PROFILE_A2DP: \
36 _mci->num_a2dp++; \
37 if (!_info->edr) \
38 _mci->num_bdr++; \
39 break; \
40 case MCI_GPM_COEX_PROFILE_HID: \
41 _mci->num_hid++; \
42 break; \
43 case MCI_GPM_COEX_PROFILE_BNEP: \
44 _mci->num_pan++; \
45 break; \
46 case MCI_GPM_COEX_PROFILE_VOICE: \
47 _mci->num_sco++; \
48 break; \
49 default: \
50 break; \
51 } \
52 } while (0)
53
54#define DEC_PROF(_mci, _info) do { \
55 switch (_info->type) { \
56 case MCI_GPM_COEX_PROFILE_RFCOMM:\
57 _mci->num_other_acl--; \
58 break; \
59 case MCI_GPM_COEX_PROFILE_A2DP: \
60 _mci->num_a2dp--; \
61 if (!_info->edr) \
62 _mci->num_bdr--; \
63 break; \
64 case MCI_GPM_COEX_PROFILE_HID: \
65 _mci->num_hid--; \
66 break; \
67 case MCI_GPM_COEX_PROFILE_BNEP: \
68 _mci->num_pan--; \
69 break; \
70 case MCI_GPM_COEX_PROFILE_VOICE: \
71 _mci->num_sco--; \
72 break; \
73 default: \
74 break; \
75 } \
76 } while (0)
77
78#define NUM_PROF(_mci) (_mci->num_other_acl + _mci->num_a2dp + \
79 _mci->num_hid + _mci->num_pan + _mci->num_sco)
80
81struct ath_mci_profile_info {
82 u8 type;
83 u8 conn_handle;
84 bool start;
85 bool master;
86 bool edr;
87 u8 voice_type;
88 u16 T; /* Voice: Tvoice, HID: Tsniff, in slots */
89 u8 W; /* Voice: Wvoice, HID: Sniff timeout, in slots */
90 u8 A; /* HID: Sniff attempt, in slots */
91 struct list_head list;
92};
93
94struct ath_mci_profile_status {
95 bool is_critical;
96 bool is_link;
97 u8 conn_handle;
98};
99
100struct ath_mci_profile {
101 struct list_head info;
102 DECLARE_BITMAP(status, ATH_MCI_MAX_PROFILE);
103 u16 aggr_limit;
104 u8 num_mgmt;
105 u8 num_sco;
106 u8 num_a2dp;
107 u8 num_hid;
108 u8 num_pan;
109 u8 num_other_acl;
110 u8 num_bdr;
111};
112
113void ath_mci_flush_profile(struct ath_mci_profile *mci);
114void ath_mci_process_profile(struct ath_softc *sc,
115 struct ath_mci_profile_info *info);
116void ath_mci_process_status(struct ath_softc *sc,
117 struct ath_mci_profile_status *status);
118#endif
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 03b0a651a591..55d077e7135d 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -601,6 +601,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
601 struct sk_buff *skb; 601 struct sk_buff *skb;
602 struct ieee80211_tx_info *tx_info; 602 struct ieee80211_tx_info *tx_info;
603 struct ieee80211_tx_rate *rates; 603 struct ieee80211_tx_rate *rates;
604 struct ath_mci_profile *mci = &sc->btcoex.mci;
604 u32 max_4ms_framelen, frmlen; 605 u32 max_4ms_framelen, frmlen;
605 u16 aggr_limit, legacy = 0; 606 u16 aggr_limit, legacy = 0;
606 int i; 607 int i;
@@ -645,7 +646,9 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
645 if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) 646 if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
646 return 0; 647 return 0;
647 648
648 if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) 649 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit)
650 aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4;
651 else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED)
649 aggr_limit = min((max_4ms_framelen * 3) / 8, 652 aggr_limit = min((max_4ms_framelen * 3) / 8,
650 (u32)ATH_AMPDU_LIMIT_MAX); 653 (u32)ATH_AMPDU_LIMIT_MAX);
651 else 654 else