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/ath9k/hw.c | |
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/ath9k/hw.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 104 |
1 files changed, 98 insertions, 6 deletions
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))) |