X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fath9k%2Fhw.c;h=c38a00bbce64664caa1042be4ee37da97e1f6c46;hb=5ec905a8df3fa877566ba98298433fbfb3d688cc;hp=668865dce533ea8a894432945e0584a855a3ee19;hpb=098401a600b6344771900fe164c5eafb668ce99c;p=karo-tx-linux.git diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 668865dce533..c38a00bbce64 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -37,7 +37,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type); static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, enum ath9k_ht_macmode macmode); static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, - struct ar5416_eeprom *pEepData, + struct ar5416_eeprom_def *pEepData, u32 reg, u32 value); static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); @@ -392,6 +392,8 @@ static const char *ath9k_hw_devname(u16 devid) case AR9280_DEVID_PCI: case AR9280_DEVID_PCIE: return "Atheros 9280"; + case AR9285_DEVID_PCIE: + return "Atheros 9285"; } return NULL; @@ -435,6 +437,25 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah) } ah->ah_config.intr_mitigation = 1; + + /* + * We need this for PCI devices only (Cardbus, PCI, miniPCI) + * _and_ if on non-uniprocessor systems (Multiprocessor/HT). + * This means we use it for all AR5416 devices, and the few + * minor PCI AR9280 devices out there. + * + * Serialization is required because these devices do not handle + * well the case of two concurrent reads/writes due to the latency + * involved. During one read/write another read/write can be issued + * on another CPU while the previous read/write may still be working + * on our hardware, if we hit this case the hardware poops in a loop. + * We prevent this by serializing reads and writes. + * + * This issue is not present on PCI-Express devices or pre-AR5416 + * devices (legacy, 802.11abg). + */ + if (num_possible_cpus() > 1) + ah->ah_config.serialize_regmode = SER_REG_MODE_AUTO; } static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, @@ -640,10 +661,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, struct ath_hal_5416 *ahp; struct ath_hal *ah; int ecode; -#ifndef CONFIG_SLOW_ANT_DIV - u32 i; - u32 j; -#endif + u32 i, j; ahp = ath9k_hw_newstate(devid, sc, mem, status); if (ahp == NULL) @@ -669,7 +687,8 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, } if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) { - if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) { + if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI || + (AR_SREV_9280(ah) && !ah->ah_isPciExpress)) { ah->ah_config.serialize_regmode = SER_REG_MODE_ON; } else { @@ -685,7 +704,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) && (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) && (ah->ah_macVersion != AR_SREV_VERSION_9160) && - (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) { + (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Mac Chip Rev 0x%02x.%x is not supported by " "this driver\n", ah->ah_macVersion, ah->ah_macRev); @@ -736,7 +755,38 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, "This Mac Chip Rev 0x%02x.%x is \n", ah->ah_macVersion, ah->ah_macRev); - if (AR_SREV_9280_20_OR_LATER(ah)) { + if (AR_SREV_9285_12_OR_LATER(ah)) { + INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2, + ARRAY_SIZE(ar9285Modes_9285_1_2), 6); + INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2, + ARRAY_SIZE(ar9285Common_9285_1_2), 2); + + if (ah->ah_config.pcie_clock_req) { + INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, + ar9285PciePhy_clkreq_off_L1_9285_1_2, + ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2); + } else { + INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, + ar9285PciePhy_clkreq_always_on_L1_9285_1_2, + ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), + 2); + } + } else if (AR_SREV_9285_10_OR_LATER(ah)) { + INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285, + ARRAY_SIZE(ar9285Modes_9285), 6); + INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285, + ARRAY_SIZE(ar9285Common_9285), 2); + + if (ah->ah_config.pcie_clock_req) { + INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, + ar9285PciePhy_clkreq_off_L1_9285, + ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2); + } else { + INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, + ar9285PciePhy_clkreq_always_on_L1_9285, + ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2); + } + } else if (AR_SREV_9280_20_OR_LATER(ah)) { INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2, ARRAY_SIZE(ar9280Modes_9280_2), 6); INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2, @@ -846,14 +896,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, goto bad; /* rxgain table */ - if (AR_SREV_9280_20_OR_LATER(ah)) + if (AR_SREV_9280_20(ah)) ath9k_hw_init_rxgain_ini(ah); /* txgain table */ - if (AR_SREV_9280_20_OR_LATER(ah)) + if (AR_SREV_9280_20(ah)) ath9k_hw_init_txgain_ini(ah); -#ifndef CONFIG_SLOW_ANT_DIV if (ah->ah_devid == AR9280_DEVID_PCI) { for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) { u32 reg = INI_RA(&ahp->ah_iniModes, i, 0); @@ -862,12 +911,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, u32 val = INI_RA(&ahp->ah_iniModes, i, j); INI_RA(&ahp->ah_iniModes, i, j) = - ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, + ath9k_hw_ini_fixup(ah, + &ahp->ah_eeprom.def, reg, val); } } } -#endif + if (!ath9k_hw_fill_cap_info(ah)) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, "failed ath9k_hw_fill_cap_info\n"); @@ -1020,8 +1070,6 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah) } case 0x1: case 0x2: - if (!AR_SREV_9280(ah)) - break; case 0x7: REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); @@ -1166,12 +1214,10 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc, case AR9160_DEVID_PCI: case AR9280_DEVID_PCI: case AR9280_DEVID_PCIE: + case AR9285_DEVID_PCIE: ah = ath9k_hw_do_attach(devid, sc, mem, error); break; default: - DPRINTF(ah->ah_sc, ATH_DBG_ANY, - "devid=0x%x not supported.\n", devid); - ah = NULL; *error = -ENXIO; break; } @@ -1186,6 +1232,14 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc, static void ath9k_hw_override_ini(struct ath_hal *ah, struct ath9k_channel *chan) { + /* + * Set the RX_ABORT and RX_DIS and clear if off only after + * RXE is set for MAC. This prevents frames with corrupted + * descriptor status. + */ + REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); + + if (!AR_SREV_5416_V20_OR_LATER(ah) || AR_SREV_9280_10_OR_LATER(ah)) return; @@ -1193,8 +1247,8 @@ static void ath9k_hw_override_ini(struct ath_hal *ah, REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); } -static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, - struct ar5416_eeprom *pEepData, +static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah, + struct ar5416_eeprom_def *pEepData, u32 reg, u32 value) { struct base_eep_header *pBase = &(pEepData->baseEepHeader); @@ -1227,6 +1281,18 @@ static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, return value; } +static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, + struct ar5416_eeprom_def *pEepData, + u32 reg, u32 value) +{ + struct ath_hal_5416 *ahp = AH5416(ah); + + if (ahp->ah_eep_map == EEP_MAP_4KBITS) + return value; + else + return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value); +} + static int ath9k_hw_process_ini(struct ath_hal *ah, struct ath9k_channel *chan, enum ath9k_ht_macmode macmode) @@ -1294,11 +1360,6 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, u32 reg = INI_RA(&ahp->ah_iniModes, i, 0); u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex); -#ifdef CONFIG_SLOW_ANT_DIV - if (ah->ah_devid == AR9280_DEVID_PCI) - val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg, val); -#endif - REG_WRITE(ah, reg, val); if (reg >= 0x7800 && reg < 0x78a0 @@ -1309,10 +1370,10 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, DO_DELAY(regWrites); } - if (AR_SREV_9280_20_OR_LATER(ah)) + if (AR_SREV_9280(ah)) REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites); - if (AR_SREV_9280_20_OR_LATER(ah)) + if (AR_SREV_9280(ah)) REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites); for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) { @@ -1585,10 +1646,15 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, enum ath9k_ht_macmode macmode) { u32 phymode; + u32 enableDacFifo = 0; struct ath_hal_5416 *ahp = AH5416(ah); + if (AR_SREV_9285_10_OR_LATER(ah)) + enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & + AR_PHY_FC_ENABLE_DAC_FIFO); + phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 - | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH; + | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; if (IS_CHAN_HT40(chan)) { phymode |= AR_PHY_FC_DYN2040_EN; @@ -2771,11 +2837,14 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore) if (ah->ah_config.pcie_waen) { REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen); } else { - if (AR_SREV_9280(ah)) - REG_WRITE(ah, AR_WA, 0x0040073f); + if (AR_SREV_9285(ah)) + REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); + else if (AR_SREV_9280(ah)) + REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT); else - REG_WRITE(ah, AR_WA, 0x0000073f); + REG_WRITE(ah, AR_WA, AR_WA_DEFAULT); } + } /**********************/ @@ -3326,7 +3395,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) else pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; - if (AR_SREV_9280(ah)) + if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; else pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; @@ -3346,9 +3415,9 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; pCap->num_antcfg_5ghz = - ath9k_hw_get_num_ant_config(ah, IEEE80211_BAND_5GHZ); + ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ); pCap->num_antcfg_2ghz = - ath9k_hw_get_num_ant_config(ah, IEEE80211_BAND_2GHZ); + ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); return true; }