#include "phy.h"
#include "initvals.h"
-static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
+static int btcoex_enable;
+module_param(btcoex_enable, bool, 0);
+MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
-extern struct hal_percal_data iq_cal_multi_sample;
-extern struct hal_percal_data iq_cal_single_sample;
-extern struct hal_percal_data adc_gain_cal_multi_sample;
-extern struct hal_percal_data adc_gain_cal_single_sample;
-extern struct hal_percal_data adc_dc_cal_multi_sample;
-extern struct hal_percal_data adc_dc_cal_single_sample;
-extern struct hal_percal_data adc_init_dc_cal;
+#define ATH9K_CLOCK_RATE_CCK 22
+#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
+#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
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);
static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
{
- if (ah->ah_curchan != NULL)
- return clks / CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
- else
- return clks / CLOCK_RATE[ATH9K_MODE_11B];
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+ if (!ah->ah_curchan) /* should really check for CCK instead */
+ return clks / ATH9K_CLOCK_RATE_CCK;
+ if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
+ return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
}
static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
{
- struct ath9k_channel *chan = ah->ah_curchan;
-
- if (chan && IS_CHAN_HT40(chan))
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+ if (conf_is_ht40(conf))
return ath9k_hw_mac_usec(ah, clks) / 2;
else
return ath9k_hw_mac_usec(ah, clks);
static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
{
- if (ah->ah_curchan != NULL)
- return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
- ah->ah_curchan)];
- else
- return usecs * CLOCK_RATE[ATH9K_MODE_11B];
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+ if (!ah->ah_curchan) /* should really check for CCK instead */
+ return usecs *ATH9K_CLOCK_RATE_CCK;
+ if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
+ return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
}
static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
{
- struct ath9k_channel *chan = ah->ah_curchan;
-
- if (chan && IS_CHAN_HT40(chan))
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+ if (conf_is_ht40(conf))
return ath9k_hw_mac_clks(ah, usecs) * 2;
else
return ath9k_hw_mac_clks(ah, usecs);
}
-enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
- const struct ath9k_channel *chan)
-{
- if (IS_CHAN_B(chan))
- return ATH9K_MODE_11B;
- if (IS_CHAN_G(chan))
- return ATH9K_MODE_11G;
-
- return ATH9K_MODE_11A;
-}
-
bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val)
{
int i;
return "Atheros 5418";
case AR9160_DEVID_PCI:
return "Atheros 9160";
+ case AR5416_AR9100_DEVID:
+ return "Atheros 9100";
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
return "Atheros 9280";
+ case AR9285_DEVID_PCIE:
+ return "Atheros 9285";
}
return NULL;
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)
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);
"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,
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);
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");
pll |= SM(0xb, AR_RTC_PLL_DIV);
}
}
- REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
udelay(RTC_PLL_SETTLE_DELAY);
}
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);
switch (devid) {
case AR5416_DEVID_PCI:
case AR5416_DEVID_PCIE:
+ case AR5416_AR9100_DEVID:
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;
}
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;
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);
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)
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
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++) {
rst_flags |= AR_RTC_RC_MAC_COLD;
}
- REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
+ REG_WRITE(ah, AR_RTC_RC, rst_flags);
udelay(50);
- REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
- if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
+ REG_WRITE(ah, AR_RTC_RC, 0);
+ if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
"RTC stuck in MAC reset\n");
return false;
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
AR_RTC_FORCE_WAKE_ON_INT);
- REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
- REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
+ REG_WRITE(ah, AR_RTC_RESET, 0);
+ REG_WRITE(ah, AR_RTC_RESET, 1);
if (!ath9k_hw_wait(ah,
AR_RTC_STATUS,
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;
return true;
}
-static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
- struct ath9k_channel *chan)
-{
- if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; not marked as "
- "2GHz or 5GHz\n", chan->channel, chan->channelFlags);
- return NULL;
- }
-
- if (!IS_CHAN_OFDM(chan) &&
- !IS_CHAN_B(chan) &&
- !IS_CHAN_HT20(chan) &&
- !IS_CHAN_HT40(chan)) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; not marked as "
- "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
- chan->channel, chan->channelFlags);
- return NULL;
- }
-
- return ath9k_regd_check_channel(ah, chan);
-}
-
static bool ath9k_hw_channel_change(struct ath_hal *ah,
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
/* workaround for gcc bug #37014 */
- volatile int tmp = abs(cur_vit_mask - bin);
+ volatile int tmp_v = abs(cur_vit_mask - bin);
- if (tmp < 75)
+ if (tmp_v < 75)
mask_amt = 1;
else
mask_amt = 0;
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
/* workaround for gcc bug #37014 */
- volatile int tmp = abs(cur_vit_mask - bin);
+ volatile int tmp_v = abs(cur_vit_mask - bin);
- if (tmp < 75)
+ if (tmp_v < 75)
mask_amt = 1;
else
mask_amt = 0;
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
}
-bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
- enum ath9k_ht_macmode macmode,
- u8 txchainmask, u8 rxchainmask,
- enum ath9k_ht_extprotspacing extprotspacing,
- bool bChannelChange, int *status)
+int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
+ bool bChannelChange)
{
u32 saveLedState;
+ struct ath_softc *sc = ah->ah_sc;
struct ath_hal_5416 *ahp = AH5416(ah);
struct ath9k_channel *curchan = ah->ah_curchan;
u32 saveDefAntenna;
u32 macStaId1;
- int ecode;
- int i, rx_chainmask;
+ int i, rx_chainmask, r;
- ahp->ah_extprotspacing = extprotspacing;
- ahp->ah_txchainmask = txchainmask;
- ahp->ah_rxchainmask = rxchainmask;
+ ahp->ah_extprotspacing = sc->sc_ht_extprotspacing;
+ ahp->ah_txchainmask = sc->sc_tx_chainmask;
+ ahp->ah_rxchainmask = sc->sc_rx_chainmask;
if (AR_SREV_9280(ah)) {
ahp->ah_txchainmask &= 0x3;
ahp->ah_rxchainmask &= 0x3;
}
- if (ath9k_hw_check_chan(ah, chan) == NULL) {
+ if (ath9k_regd_check_channel(ah, chan) == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"invalid channel %u/0x%x; no mapping\n",
chan->channel, chan->channelFlags);
- ecode = -EINVAL;
- goto bad;
+ return -EINVAL;
}
- if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
- ecode = -EIO;
- goto bad;
- }
+ if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+ return -EIO;
if (curchan)
ath9k_hw_getnf(ah, curchan);
(!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
!IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) {
- if (ath9k_hw_channel_change(ah, chan, macmode)) {
+ if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
ath9k_hw_loadnf(ah, ah->ah_curchan);
ath9k_hw_start_nfcal(ah);
- return true;
+ return 0;
}
}
if (!ath9k_hw_chip_reset(ah, chan)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
- ecode = -EINVAL;
- goto bad;
+ return -EINVAL;
}
if (AR_SREV_9280(ah)) {
ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
}
- ecode = ath9k_hw_process_ini(ah, chan, macmode);
- if (ecode != 0) {
- ecode = -EINVAL;
- goto bad;
- }
+ r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
+ if (r)
+ return r;
+
+ /* Setup MFP options for CCMP */
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
+ /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+ * frames when constructing CCMP AAD. */
+ REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+ 0xc7ff);
+ ah->sw_mgmt_crypto = false;
+ } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+ /* Disable hardware crypto for management frames */
+ REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+ REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+ ah->sw_mgmt_crypto = true;
+ } else
+ ah->sw_mgmt_crypto = true;
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
ath9k_hw_set_delta_slope(ah, chan);
if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"error setting board options\n");
- ecode = -EIO;
- goto bad;
+ return -EIO;
}
ath9k_hw_decrease_chain_power(ah, chan);
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
- ecode = -EIO;
- goto bad;
- }
+ if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
+ return -EIO;
} else {
- if (!(ath9k_hw_set_channel(ah, chan))) {
- ecode = -EIO;
- goto bad;
- }
+ if (!(ath9k_hw_set_channel(ah, chan)))
+ return -EIO;
}
for (i = 0; i < AR_NUM_DCU; i++)
ath9k_hw_init_bb(ah, chan);
- if (!ath9k_hw_init_cal(ah, chan)){
- ecode = -EIO;;
- goto bad;
- }
+ if (!ath9k_hw_init_cal(ah, chan))
+ return -EIO;;
rx_chainmask = ahp->ah_rxchainmask;
if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
#endif
}
- return true;
-bad:
- if (status)
- *status = ecode;
- return false;
+ return 0;
}
/************************/
if (!AR_SREV_9100(ah))
REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
- REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
+ REG_CLR_BIT(ah, (AR_RTC_RESET),
AR_RTC_RESET_EN);
}
}
int status = true, setChip = true;
DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n",
- modes[ahp->ah_powerMode], modes[mode],
+ modes[ah->ah_power_mode], modes[mode],
setChip ? "set chip " : "");
switch (mode) {
"Unknown power mode %u\n", mode);
return false;
}
- ahp->ah_powerMode = mode;
+ ah->ah_power_mode = mode;
return status;
}
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);
}
+
}
/**********************/
pCap->num_mr_retries = 4;
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ pCap->num_gpio_pins = AR9285_NUM_GPIO;
+ else if (AR_SREV_9280_10_OR_LATER(ah))
pCap->num_gpio_pins = AR928X_NUM_GPIO;
else
pCap->num_gpio_pins = AR_NUM_GPIO;
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;
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);
+
+ if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
+ pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
+ ah->ah_btactive_gpio = 6;
+ ah->ah_wlanactive_gpio = 5;
+ }
return true;
}
u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
{
+#define MS_REG_READ(x, y) \
+ (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
+
if (gpio >= ah->ah_caps.num_gpio_pins)
return 0xffffffff;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- return (MS
- (REG_READ(ah, AR_GPIO_IN_OUT),
- AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
- } else {
- return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
- AR_GPIO_BIT(gpio)) != 0;
- }
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ return MS_REG_READ(AR9285, gpio) != 0;
+ else if (AR_SREV_9280_10_OR_LATER(ah))
+ return MS_REG_READ(AR928X, gpio) != 0;
+ else
+ return MS_REG_READ(AR, gpio) != 0;
}
void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
REG_WRITE(ah, AR_2040_MODE, macmode);
}
+
+/***************************/
+/* Bluetooth Coexistence */
+/***************************/
+
+void ath9k_hw_btcoex_enable(struct ath_hal *ah)
+{
+ /* connect bt_active to baseband */
+ REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+ (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+ AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+
+ REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+ AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+
+ /* Set input mux for bt_active to gpio pin */
+ REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+ AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+ ah->ah_btactive_gpio);
+
+ /* Configure the desired gpio port for input */
+ ath9k_hw_cfg_gpio_input(ah, ah->ah_btactive_gpio);
+
+ /* Configure the desired GPIO port for TX_FRAME output */
+ ath9k_hw_cfg_output(ah, ah->ah_wlanactive_gpio,
+ AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+}