diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-08-03 23:14:12 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-04 16:44:34 -0400 |
commit | d7e7d229c7d1395283e1e1fda8727af60ca6f4ad (patch) | |
tree | a342f917c1a7e5e8e0688704b773f2a1eaaea58c /drivers/net/wireless/ath | |
parent | 670388c5f56383e1d5b9f4f7fc835a280487754e (diff) |
ath9k: add initial hardware support for ar9271
We will finalize this after some driver core changes, for now
we leave this unsupported.
Cc: Stephen Chen <stephen.chen@atheros.com>
Cc: Zhifeng Cai <zhifeng.cai@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/calib.c | 106 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/eeprom.c | 142 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 104 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 2 |
4 files changed, 314 insertions, 40 deletions
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index d1bbb02af8de..26d87527acbd 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -753,6 +753,98 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah) | |||
753 | } | 753 | } |
754 | } | 754 | } |
755 | 755 | ||
756 | static void ath9k_hw_9271_pa_cal(struct ath_hw *ah) | ||
757 | { | ||
758 | u32 regVal; | ||
759 | unsigned int i; | ||
760 | u32 regList [][2] = { | ||
761 | { 0x786c, 0 }, | ||
762 | { 0x7854, 0 }, | ||
763 | { 0x7820, 0 }, | ||
764 | { 0x7824, 0 }, | ||
765 | { 0x7868, 0 }, | ||
766 | { 0x783c, 0 }, | ||
767 | { 0x7838, 0 } , | ||
768 | { 0x7828, 0 } , | ||
769 | }; | ||
770 | |||
771 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
772 | regList[i][1] = REG_READ(ah, regList[i][0]); | ||
773 | |||
774 | regVal = REG_READ(ah, 0x7834); | ||
775 | regVal &= (~(0x1)); | ||
776 | REG_WRITE(ah, 0x7834, regVal); | ||
777 | regVal = REG_READ(ah, 0x9808); | ||
778 | regVal |= (0x1 << 27); | ||
779 | REG_WRITE(ah, 0x9808, regVal); | ||
780 | |||
781 | /* 786c,b23,1, pwddac=1 */ | ||
782 | REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); | ||
783 | /* 7854, b5,1, pdrxtxbb=1 */ | ||
784 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); | ||
785 | /* 7854, b7,1, pdv2i=1 */ | ||
786 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); | ||
787 | /* 7854, b8,1, pddacinterface=1 */ | ||
788 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); | ||
789 | /* 7824,b12,0, offcal=0 */ | ||
790 | REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); | ||
791 | /* 7838, b1,0, pwddb=0 */ | ||
792 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); | ||
793 | /* 7820,b11,0, enpacal=0 */ | ||
794 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); | ||
795 | /* 7820,b25,1, pdpadrv1=0 */ | ||
796 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0); | ||
797 | /* 7820,b24,0, pdpadrv2=0 */ | ||
798 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0); | ||
799 | /* 7820,b23,0, pdpaout=0 */ | ||
800 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); | ||
801 | /* 783c,b14-16,7, padrvgn2tab_0=7 */ | ||
802 | REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7); | ||
803 | /* | ||
804 | * 7838,b29-31,0, padrvgn1tab_0=0 | ||
805 | * does not matter since we turn it off | ||
806 | */ | ||
807 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0); | ||
808 | |||
809 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff); | ||
810 | |||
811 | /* Set: | ||
812 | * localmode=1,bmode=1,bmoderxtx=1,synthon=1, | ||
813 | * txon=1,paon=1,oscon=1,synthon_force=1 | ||
814 | */ | ||
815 | REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0); | ||
816 | udelay(30); | ||
817 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0); | ||
818 | |||
819 | /* find off_6_1; */ | ||
820 | for (i = 6; i >= 0; i--) { | ||
821 | regVal = REG_READ(ah, 0x7834); | ||
822 | regVal |= (1 << (20 + i)); | ||
823 | REG_WRITE(ah, 0x7834, regVal); | ||
824 | udelay(1); | ||
825 | //regVal = REG_READ(ah, 0x7834); | ||
826 | regVal &= (~(0x1 << (20 + i))); | ||
827 | regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9) | ||
828 | << (20 + i)); | ||
829 | REG_WRITE(ah, 0x7834, regVal); | ||
830 | } | ||
831 | |||
832 | /* Empirical offset correction */ | ||
833 | #if 0 | ||
834 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0x20); | ||
835 | #endif | ||
836 | |||
837 | regVal = REG_READ(ah, 0x7834); | ||
838 | regVal |= 0x1; | ||
839 | REG_WRITE(ah, 0x7834, regVal); | ||
840 | regVal = REG_READ(ah, 0x9808); | ||
841 | regVal &= (~(0x1 << 27)); | ||
842 | REG_WRITE(ah, 0x9808, regVal); | ||
843 | |||
844 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
845 | REG_WRITE(ah, regList[i][0], regList[i][1]); | ||
846 | } | ||
847 | |||
756 | static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah) | 848 | static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah) |
757 | { | 849 | { |
758 | 850 | ||
@@ -869,14 +961,26 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, | |||
869 | } | 961 | } |
870 | } | 962 | } |
871 | 963 | ||
964 | /* Do NF cal only at longer intervals */ | ||
872 | if (longcal) { | 965 | if (longcal) { |
873 | if (AR_SREV_9285_11_OR_LATER(ah)) | 966 | /* Do periodic PAOffset Cal */ |
967 | if (AR_SREV_9271(ah)) | ||
968 | ath9k_hw_9271_pa_cal(ah); | ||
969 | else if (AR_SREV_9285_11_OR_LATER(ah)) | ||
874 | ath9k_hw_9285_pa_cal(ah); | 970 | ath9k_hw_9285_pa_cal(ah); |
875 | 971 | ||
876 | if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER) | 972 | if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER) |
877 | ath9k_olc_temp_compensation(ah); | 973 | ath9k_olc_temp_compensation(ah); |
974 | |||
975 | /* Get the value from the previous NF cal and update history buffer */ | ||
878 | ath9k_hw_getnf(ah, chan); | 976 | ath9k_hw_getnf(ah, chan); |
977 | |||
978 | /* | ||
979 | * Load the NF from history buffer of the current channel. | ||
980 | * NF is slow time-variant, so it is OK to use a historical value. | ||
981 | */ | ||
879 | ath9k_hw_loadnf(ah, ah->curchan); | 982 | ath9k_hw_loadnf(ah, ah->curchan); |
983 | |||
880 | ath9k_hw_start_nfcal(ah); | 984 | ath9k_hw_start_nfcal(ah); |
881 | } | 985 | } |
882 | 986 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 80ece019216e..9a09cc8e7044 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -1237,6 +1237,10 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah, | |||
1237 | REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); | 1237 | REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | /* | ||
1241 | * Read EEPROM header info and program the device for correct operation | ||
1242 | * given the channel value. | ||
1243 | */ | ||
1240 | static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | 1244 | static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, |
1241 | struct ath9k_channel *chan) | 1245 | struct ath9k_channel *chan) |
1242 | { | 1246 | { |
@@ -1313,38 +1317,110 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | |||
1313 | } | 1317 | } |
1314 | } | 1318 | } |
1315 | 1319 | ||
1316 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | 1320 | if (AR_SREV_9271(ah)) { |
1317 | AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]); | 1321 | ath9k_hw_analog_shift_rmw(ah, |
1318 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | 1322 | AR9285_AN_RF2G3, |
1319 | AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]); | 1323 | AR9271_AN_RF2G3_OB_cck, |
1320 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | 1324 | AR9271_AN_RF2G3_OB_cck_S, |
1321 | AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]); | 1325 | ob[0]); |
1322 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | 1326 | ath9k_hw_analog_shift_rmw(ah, |
1323 | AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]); | 1327 | AR9285_AN_RF2G3, |
1324 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | 1328 | AR9271_AN_RF2G3_OB_psk, |
1325 | AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]); | 1329 | AR9271_AN_RF2G3_OB_psk_S, |
1326 | 1330 | ob[1]); | |
1327 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | 1331 | ath9k_hw_analog_shift_rmw(ah, |
1328 | AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]); | 1332 | AR9285_AN_RF2G3, |
1329 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | 1333 | AR9271_AN_RF2G3_OB_qam, |
1330 | AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]); | 1334 | AR9271_AN_RF2G3_OB_qam_S, |
1331 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | 1335 | ob[2]); |
1332 | AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]); | 1336 | ath9k_hw_analog_shift_rmw(ah, |
1333 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | 1337 | AR9285_AN_RF2G3, |
1334 | AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]); | 1338 | AR9271_AN_RF2G3_DB_1, |
1335 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | 1339 | AR9271_AN_RF2G3_DB_1_S, |
1336 | AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]); | 1340 | db1[0]); |
1337 | 1341 | ath9k_hw_analog_shift_rmw(ah, | |
1338 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | 1342 | AR9285_AN_RF2G4, |
1339 | AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]); | 1343 | AR9271_AN_RF2G4_DB_2, |
1340 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | 1344 | AR9271_AN_RF2G4_DB_2_S, |
1341 | AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]); | 1345 | db2[0]); |
1342 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | 1346 | } else { |
1343 | AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]); | 1347 | ath9k_hw_analog_shift_rmw(ah, |
1344 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | 1348 | AR9285_AN_RF2G3, |
1345 | AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]); | 1349 | AR9285_AN_RF2G3_OB_0, |
1346 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | 1350 | AR9285_AN_RF2G3_OB_0_S, |
1347 | AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]); | 1351 | ob[0]); |
1352 | ath9k_hw_analog_shift_rmw(ah, | ||
1353 | AR9285_AN_RF2G3, | ||
1354 | AR9285_AN_RF2G3_OB_1, | ||
1355 | AR9285_AN_RF2G3_OB_1_S, | ||
1356 | ob[1]); | ||
1357 | ath9k_hw_analog_shift_rmw(ah, | ||
1358 | AR9285_AN_RF2G3, | ||
1359 | AR9285_AN_RF2G3_OB_2, | ||
1360 | AR9285_AN_RF2G3_OB_2_S, | ||
1361 | ob[2]); | ||
1362 | ath9k_hw_analog_shift_rmw(ah, | ||
1363 | AR9285_AN_RF2G3, | ||
1364 | AR9285_AN_RF2G3_OB_3, | ||
1365 | AR9285_AN_RF2G3_OB_3_S, | ||
1366 | ob[3]); | ||
1367 | ath9k_hw_analog_shift_rmw(ah, | ||
1368 | AR9285_AN_RF2G3, | ||
1369 | AR9285_AN_RF2G3_OB_4, | ||
1370 | AR9285_AN_RF2G3_OB_4_S, | ||
1371 | ob[4]); | ||
1372 | |||
1373 | ath9k_hw_analog_shift_rmw(ah, | ||
1374 | AR9285_AN_RF2G3, | ||
1375 | AR9285_AN_RF2G3_DB1_0, | ||
1376 | AR9285_AN_RF2G3_DB1_0_S, | ||
1377 | db1[0]); | ||
1378 | ath9k_hw_analog_shift_rmw(ah, | ||
1379 | AR9285_AN_RF2G3, | ||
1380 | AR9285_AN_RF2G3_DB1_1, | ||
1381 | AR9285_AN_RF2G3_DB1_1_S, | ||
1382 | db1[1]); | ||
1383 | ath9k_hw_analog_shift_rmw(ah, | ||
1384 | AR9285_AN_RF2G3, | ||
1385 | AR9285_AN_RF2G3_DB1_2, | ||
1386 | AR9285_AN_RF2G3_DB1_2_S, | ||
1387 | db1[2]); | ||
1388 | ath9k_hw_analog_shift_rmw(ah, | ||
1389 | AR9285_AN_RF2G4, | ||
1390 | AR9285_AN_RF2G4_DB1_3, | ||
1391 | AR9285_AN_RF2G4_DB1_3_S, | ||
1392 | db1[3]); | ||
1393 | ath9k_hw_analog_shift_rmw(ah, | ||
1394 | AR9285_AN_RF2G4, | ||
1395 | AR9285_AN_RF2G4_DB1_4, | ||
1396 | AR9285_AN_RF2G4_DB1_4_S, db1[4]); | ||
1397 | |||
1398 | ath9k_hw_analog_shift_rmw(ah, | ||
1399 | AR9285_AN_RF2G4, | ||
1400 | AR9285_AN_RF2G4_DB2_0, | ||
1401 | AR9285_AN_RF2G4_DB2_0_S, | ||
1402 | db2[0]); | ||
1403 | ath9k_hw_analog_shift_rmw(ah, | ||
1404 | AR9285_AN_RF2G4, | ||
1405 | AR9285_AN_RF2G4_DB2_1, | ||
1406 | AR9285_AN_RF2G4_DB2_1_S, | ||
1407 | db2[1]); | ||
1408 | ath9k_hw_analog_shift_rmw(ah, | ||
1409 | AR9285_AN_RF2G4, | ||
1410 | AR9285_AN_RF2G4_DB2_2, | ||
1411 | AR9285_AN_RF2G4_DB2_2_S, | ||
1412 | db2[2]); | ||
1413 | ath9k_hw_analog_shift_rmw(ah, | ||
1414 | AR9285_AN_RF2G4, | ||
1415 | AR9285_AN_RF2G4_DB2_3, | ||
1416 | AR9285_AN_RF2G4_DB2_3_S, | ||
1417 | db2[3]); | ||
1418 | ath9k_hw_analog_shift_rmw(ah, | ||
1419 | AR9285_AN_RF2G4, | ||
1420 | AR9285_AN_RF2G4_DB2_4, | ||
1421 | AR9285_AN_RF2G4_DB2_4_S, | ||
1422 | db2[4]); | ||
1423 | } | ||
1348 | 1424 | ||
1349 | 1425 | ||
1350 | if (AR_SREV_9285_11(ah)) | 1426 | if (AR_SREV_9285_11(ah)) |
@@ -3984,7 +4060,7 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah) | |||
3984 | if (AR_SREV_9287(ah)) { | 4060 | if (AR_SREV_9287(ah)) { |
3985 | ah->eep_map = EEP_MAP_AR9287; | 4061 | ah->eep_map = EEP_MAP_AR9287; |
3986 | ah->eep_ops = &eep_AR9287_ops; | 4062 | ah->eep_ops = &eep_AR9287_ops; |
3987 | } else if (AR_SREV_9285(ah)) { | 4063 | } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { |
3988 | ah->eep_map = EEP_MAP_4KBITS; | 4064 | ah->eep_map = EEP_MAP_4KBITS; |
3989 | ah->eep_ops = &eep_4k_ops; | 4065 | ah->eep_ops = &eep_4k_ops; |
3990 | } else { | 4066 | } else { |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 0d60b3573500..71a3bcc450a2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -638,6 +638,8 @@ static bool ath9k_hw_macversion_supported(u32 macversion) | |||
638 | case AR_SREV_VERSION_9285: | 638 | case AR_SREV_VERSION_9285: |
639 | case AR_SREV_VERSION_9287: | 639 | case AR_SREV_VERSION_9287: |
640 | return true; | 640 | return true; |
641 | /* Not yet */ | ||
642 | case AR_SREV_VERSION_9271: | ||
641 | default: | 643 | default: |
642 | break; | 644 | break; |
643 | } | 645 | } |
@@ -670,6 +672,14 @@ static void ath9k_hw_init_cal_settings(struct ath_hw *ah) | |||
670 | 672 | ||
671 | static void ath9k_hw_init_mode_regs(struct ath_hw *ah) | 673 | static void ath9k_hw_init_mode_regs(struct ath_hw *ah) |
672 | { | 674 | { |
675 | if (AR_SREV_9271(ah)) { | ||
676 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271_1_0, | ||
677 | ARRAY_SIZE(ar9271Modes_9271_1_0), 6); | ||
678 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271_1_0, | ||
679 | ARRAY_SIZE(ar9271Common_9271_1_0), 2); | ||
680 | return; | ||
681 | } | ||
682 | |||
673 | if (AR_SREV_9287_11_OR_LATER(ah)) { | 683 | if (AR_SREV_9287_11_OR_LATER(ah)) { |
674 | INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, | 684 | INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, |
675 | ARRAY_SIZE(ar9287Modes_9287_1_1), 6); | 685 | ARRAY_SIZE(ar9287Modes_9287_1_1), 6); |
@@ -943,6 +953,10 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
943 | ah->supp_cals = IQ_MISMATCH_CAL; | 953 | ah->supp_cals = IQ_MISMATCH_CAL; |
944 | ah->is_pciexpress = false; | 954 | ah->is_pciexpress = false; |
945 | } | 955 | } |
956 | |||
957 | if (AR_SREV_9271(ah)) | ||
958 | ah->is_pciexpress = false; | ||
959 | |||
946 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | 960 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); |
947 | 961 | ||
948 | ath9k_hw_init_cal_settings(ah); | 962 | ath9k_hw_init_cal_settings(ah); |
@@ -973,7 +987,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
973 | return r; | 987 | return r; |
974 | } | 988 | } |
975 | 989 | ||
976 | if (AR_SREV_9285(ah)) | 990 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) |
977 | ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S); | 991 | ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S); |
978 | else | 992 | else |
979 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); | 993 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); |
@@ -1234,6 +1248,27 @@ void ath9k_hw_detach(struct ath_hw *ah) | |||
1234 | static void ath9k_hw_override_ini(struct ath_hw *ah, | 1248 | static void ath9k_hw_override_ini(struct ath_hw *ah, |
1235 | struct ath9k_channel *chan) | 1249 | struct ath9k_channel *chan) |
1236 | { | 1250 | { |
1251 | u32 val; | ||
1252 | |||
1253 | if (AR_SREV_9271(ah)) { | ||
1254 | /* | ||
1255 | * Enable spectral scan to solution for issues with stuck | ||
1256 | * beacons on AR9271 1.0. The beacon stuck issue is not seeon on | ||
1257 | * AR9271 1.1 | ||
1258 | */ | ||
1259 | if (AR_SREV_9271_10(ah)) { | ||
1260 | val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) | AR_PHY_SPECTRAL_SCAN_ENABLE; | ||
1261 | REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); | ||
1262 | } | ||
1263 | else if (AR_SREV_9271_11(ah)) | ||
1264 | /* | ||
1265 | * change AR_PHY_RF_CTL3 setting to fix MAC issue | ||
1266 | * present on AR9271 1.1 | ||
1267 | */ | ||
1268 | REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001); | ||
1269 | return; | ||
1270 | } | ||
1271 | |||
1237 | /* | 1272 | /* |
1238 | * Set the RX_ABORT and RX_DIS and clear if off only after | 1273 | * Set the RX_ABORT and RX_DIS and clear if off only after |
1239 | * RXE is set for MAC. This prevents frames with corrupted | 1274 | * RXE is set for MAC. This prevents frames with corrupted |
@@ -1245,7 +1280,10 @@ static void ath9k_hw_override_ini(struct ath_hw *ah, | |||
1245 | if (!AR_SREV_5416_20_OR_LATER(ah) || | 1280 | if (!AR_SREV_5416_20_OR_LATER(ah) || |
1246 | AR_SREV_9280_10_OR_LATER(ah)) | 1281 | AR_SREV_9280_10_OR_LATER(ah)) |
1247 | return; | 1282 | return; |
1248 | 1283 | /* | |
1284 | * Disable BB clock gating | ||
1285 | * Necessary to avoid issues on AR5416 2.0 | ||
1286 | */ | ||
1249 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); | 1287 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); |
1250 | } | 1288 | } |
1251 | 1289 | ||
@@ -1477,23 +1515,48 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) | |||
1477 | { | 1515 | { |
1478 | u32 regval; | 1516 | u32 regval; |
1479 | 1517 | ||
1518 | /* | ||
1519 | * set AHB_MODE not to do cacheline prefetches | ||
1520 | */ | ||
1480 | regval = REG_READ(ah, AR_AHB_MODE); | 1521 | regval = REG_READ(ah, AR_AHB_MODE); |
1481 | REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); | 1522 | REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); |
1482 | 1523 | ||
1524 | /* | ||
1525 | * let mac dma reads be in 128 byte chunks | ||
1526 | */ | ||
1483 | regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; | 1527 | regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; |
1484 | REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); | 1528 | REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); |
1485 | 1529 | ||
1530 | /* | ||
1531 | * Restore TX Trigger Level to its pre-reset value. | ||
1532 | * The initial value depends on whether aggregation is enabled, and is | ||
1533 | * adjusted whenever underruns are detected. | ||
1534 | */ | ||
1486 | REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level); | 1535 | REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level); |
1487 | 1536 | ||
1537 | /* | ||
1538 | * let mac dma writes be in 128 byte chunks | ||
1539 | */ | ||
1488 | regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; | 1540 | regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; |
1489 | REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B); | 1541 | REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B); |
1490 | 1542 | ||
1543 | /* | ||
1544 | * Setup receive FIFO threshold to hold off TX activities | ||
1545 | */ | ||
1491 | REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); | 1546 | REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); |
1492 | 1547 | ||
1548 | /* | ||
1549 | * reduce the number of usable entries in PCU TXBUF to avoid | ||
1550 | * wrap around issues. | ||
1551 | */ | ||
1493 | if (AR_SREV_9285(ah)) { | 1552 | if (AR_SREV_9285(ah)) { |
1553 | /* For AR9285 the number of Fifos are reduced to half. | ||
1554 | * So set the usable tx buf size also to half to | ||
1555 | * avoid data/delimiter underruns | ||
1556 | */ | ||
1494 | REG_WRITE(ah, AR_PCU_TXBUF_CTRL, | 1557 | REG_WRITE(ah, AR_PCU_TXBUF_CTRL, |
1495 | AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE); | 1558 | AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE); |
1496 | } else { | 1559 | } else if (!AR_SREV_9271(ah)) { |
1497 | REG_WRITE(ah, AR_PCU_TXBUF_CTRL, | 1560 | REG_WRITE(ah, AR_PCU_TXBUF_CTRL, |
1498 | AR_PCU_TXBUF_CTRL_USABLE_SIZE); | 1561 | AR_PCU_TXBUF_CTRL_USABLE_SIZE); |
1499 | } | 1562 | } |
@@ -2299,11 +2362,26 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2299 | 2362 | ||
2300 | ath9k_hw_mark_phy_inactive(ah); | 2363 | ath9k_hw_mark_phy_inactive(ah); |
2301 | 2364 | ||
2365 | if (AR_SREV_9271(ah) && ah->htc_reset_init) { | ||
2366 | REG_WRITE(ah, | ||
2367 | AR9271_RESET_POWER_DOWN_CONTROL, | ||
2368 | AR9271_RADIO_RF_RST); | ||
2369 | udelay(50); | ||
2370 | } | ||
2371 | |||
2302 | if (!ath9k_hw_chip_reset(ah, chan)) { | 2372 | if (!ath9k_hw_chip_reset(ah, chan)) { |
2303 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n"); | 2373 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n"); |
2304 | return -EINVAL; | 2374 | return -EINVAL; |
2305 | } | 2375 | } |
2306 | 2376 | ||
2377 | if (AR_SREV_9271(ah) && ah->htc_reset_init) { | ||
2378 | ah->htc_reset_init = false; | ||
2379 | REG_WRITE(ah, | ||
2380 | AR9271_RESET_POWER_DOWN_CONTROL, | ||
2381 | AR9271_GATE_MAC_CTL); | ||
2382 | udelay(50); | ||
2383 | } | ||
2384 | |||
2307 | if (AR_SREV_9280_10_OR_LATER(ah)) | 2385 | if (AR_SREV_9280_10_OR_LATER(ah)) |
2308 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); | 2386 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); |
2309 | 2387 | ||
@@ -2439,6 +2517,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2439 | 2517 | ||
2440 | REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); | 2518 | REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); |
2441 | 2519 | ||
2520 | /* | ||
2521 | * For big endian systems turn on swapping for descriptors | ||
2522 | */ | ||
2442 | if (AR_SREV_9100(ah)) { | 2523 | if (AR_SREV_9100(ah)) { |
2443 | u32 mask; | 2524 | u32 mask; |
2444 | mask = REG_READ(ah, AR_CFG); | 2525 | mask = REG_READ(ah, AR_CFG); |
@@ -2453,8 +2534,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2453 | "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); | 2534 | "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); |
2454 | } | 2535 | } |
2455 | } else { | 2536 | } else { |
2537 | /* Configure AR9271 target WLAN */ | ||
2538 | if (AR_SREV_9271(ah)) | ||
2539 | REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB); | ||
2456 | #ifdef __BIG_ENDIAN | 2540 | #ifdef __BIG_ENDIAN |
2457 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 2541 | else |
2542 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | ||
2458 | #endif | 2543 | #endif |
2459 | } | 2544 | } |
2460 | 2545 | ||
@@ -2981,7 +3066,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore) | |||
2981 | if (ah->config.pcie_waen) { | 3066 | if (ah->config.pcie_waen) { |
2982 | REG_WRITE(ah, AR_WA, ah->config.pcie_waen); | 3067 | REG_WRITE(ah, AR_WA, ah->config.pcie_waen); |
2983 | } else { | 3068 | } else { |
2984 | if (AR_SREV_9285(ah)) | 3069 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) |
2985 | REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); | 3070 | REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); |
2986 | /* | 3071 | /* |
2987 | * On AR9280 chips bit 22 of 0x4004 needs to be set to | 3072 | * On AR9280 chips bit 22 of 0x4004 needs to be set to |
@@ -3445,10 +3530,17 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3445 | } | 3530 | } |
3446 | 3531 | ||
3447 | pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); | 3532 | pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); |
3533 | /* | ||
3534 | * For AR9271 we will temporarilly uses the rx chainmax as read from | ||
3535 | * the EEPROM. | ||
3536 | */ | ||
3448 | if ((ah->hw_version.devid == AR5416_DEVID_PCI) && | 3537 | if ((ah->hw_version.devid == AR5416_DEVID_PCI) && |
3449 | !(eeval & AR5416_OPFLAGS_11A)) | 3538 | !(eeval & AR5416_OPFLAGS_11A) && |
3539 | !(AR_SREV_9271(ah))) | ||
3540 | /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */ | ||
3450 | pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; | 3541 | pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; |
3451 | else | 3542 | else |
3543 | /* Use rx_chainmask from EEPROM. */ | ||
3452 | pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); | 3544 | pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); |
3453 | 3545 | ||
3454 | if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0))) | 3546 | if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0))) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 9c23db146a31..d4aaf4f8db29 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -419,6 +419,8 @@ struct ath_hw { | |||
419 | u32 wlanactive_gpio; | 419 | u32 wlanactive_gpio; |
420 | u32 ah_flags; | 420 | u32 ah_flags; |
421 | 421 | ||
422 | bool htc_reset_init; | ||
423 | |||
422 | enum nl80211_iftype opmode; | 424 | enum nl80211_iftype opmode; |
423 | enum ath9k_power_mode power_mode; | 425 | enum ath9k_power_mode power_mode; |
424 | 426 | ||