/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2008 Atheros Communications Inc.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "arn_ath9k.h"
#include "arn_core.h"
#include "arn_hw.h"
#include "arn_reg.h"
#include "arn_phy.h"
#include "arn_initvals.h"
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;
enum ath9k_ht_macmode macmode);
struct ar5416_eeprom_def *pEepData,
struct ath9k_channel *chan);
struct ath9k_channel *chan);
/* Helper Functions */
static uint32_t
{
return (clks /
else
}
static uint32_t
{
else
}
static uint32_t
{
ah->ah_curchan)]);
else
}
static uint32_t
{
else
}
/* ARGSUSED */
enum wireless_mode
{
return (ATH9K_MODE_11B);
return (ATH9K_MODE_11G);
return (ATH9K_MODE_11A);
}
{
int i;
for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
return (B_TRUE);
}
"timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
return (B_FALSE);
}
{
int i;
for (i = 0, retval = 0; i < n; i++) {
val >>= 1;
}
return (retval);
}
{
if (flags & CHANNEL_5GHZ) {
return (B_TRUE);
}
if ((flags & CHANNEL_2GHZ)) {
return (B_TRUE);
}
return (B_FALSE);
}
struct ath_rate_table *rates,
{
if (kbps == 0)
return (0);
case WLAN_RC_PHY_CCK:
phyTime >>= 1;
break;
case WLAN_RC_PHY_OFDM:
} else if (ah->ah_curchan &&
} else {
}
break;
default:
arn_problem("arn: "
"%s: unknown phy %u (rate ix %u)\n", __func__,
txTime = 0;
break;
}
}
{
if (flags & CHANNEL_2GHZ) {
if (freq == 2484)
return (14);
if (freq < 2484)
else
} else if (flags & CHANNEL_5GHZ) {
if (ath9k_regd_is_public_safety_sku(ah) &&
return (((freq * 10) +
} else {
}
} else {
if (freq == 2484)
return (14);
if (freq < 2484)
if (freq < 5000) {
if (ath9k_regd_is_public_safety_sku(ah) &&
return (((freq * 10) +
(((freq % 5) ==
2) ? 5 : 0) - 49400) / 5);
} else if (freq > 4900) {
} else {
}
}
}
}
void
struct ath9k_channel *chan,
struct chan_centers *centers)
{
if (!IS_CHAN_HT40(chan)) {
return;
}
extoff = 1;
} else {
extoff = -1;
}
HT40_CHANNEL_CENTER_SHIFT : 15));
}
/* Chip Revisions */
static void
{
if (val == 0xFF) {
} else {
if (!AR_SREV_9100(ah))
}
}
static int
{
int i;
for (i = 0; i < 8; i++)
}
/* HW Attach, Detach, Init Routines */
static void
{
if (!AR_SREV_9100(ah))
return;
}
static boolean_t
{
0x66666666, 0x99999999 };
int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 0x100; j++) {
wrData = (j << 16) | j;
"arn: ath9k_hw_chip_test(): "
"address test failed "
"addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
return (B_FALSE);
}
}
for (j = 0; j < 4; j++) {
wrData = patternData[j];
"arn: ath9k_hw_chip_test(): "
"address test failed "
"addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
return (B_FALSE);
}
}
}
drv_usecwait(100);
return (B_TRUE);
}
static const char *
{
switch (devid) {
case AR5416_DEVID_PCI:
return ("Atheros 5416");
case AR5416_DEVID_PCIE:
return ("Atheros 5418");
case AR9160_DEVID_PCI:
return ("Atheros 9160");
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
return ("Atheros 9280");
case AR9285_DEVID_PCIE:
return ("Atheros 9285");
}
return (NULL);
}
static void
{
int i;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
}
/*
* 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
* 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).
*/
/* num_of_cpus */
}
static struct ath_hal_5416 *
int *status)
{
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
ahp = (struct ath_hal_5416 *)
"failed to alloc mem for ahp\n"));
return (NULL);
}
ah->ah_subvendorid = 0;
if ((device_id == AR5416_AR9100_DEVID))
if (!AR_SREV_9100(ah))
ahp->ah_atimWindow = 0;
ahp->ah_gBeaconRate = 0;
return (ahp);
}
static int
{
int ecode = 0;
if (!rfStatus) {
"RF setup failed, status %u\n", ecode));
return (ecode);
}
return (0);
}
static int
{
switch (val & AR_RADIO_SREV_MAJOR) {
case 0:
break;
case AR_RAD5133_SREV_MAJOR:
case AR_RAD5122_SREV_MAJOR:
case AR_RAD2133_SREV_MAJOR:
case AR_RAD2122_SREV_MAJOR:
break;
default:
"arn: ath9k_hw_rf_claim(): "
"5G Radio Chip Rev 0x%02X "
"is not supported by this driver\n",
ah->ah_analog5GhzRev));
return (ENOTSUP);
}
return (0);
}
static int
{
int i;
sum = 0;
for (i = 0; i < 3; i++) {
}
"mac address read failed: %pM\n",
ahp->ah_macaddr));
return (EADDRNOTAVAIL);
}
return (0);
}
static void
{
if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) {
6);
} else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) {
6);
} else {
}
} else {
}
}
static void
{
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
6);
} else {
}
} else {
}
}
static int
{
int ecode;
if (!ath9k_hw_chip_test(ah)) {
"hardware self-test failed\n"));
}
if (ecode != 0)
return (ecode);
if (ecode != 0)
return (ecode);
if (ecode != 0)
return (ecode);
if (!AR_SREV_9100(ah)) {
}
return (0);
}
static struct ath_hal *
{
int ecode;
uint32_t i;
uint32_t j;
return (NULL);
"couldn't reset chip \n"));
goto bad;
}
"couldn't wakeup chip \n"));
goto bad;
}
} else {
}
}
"serialize_regmode is %d\n",
(!AR_SREV_9285(ah))) {
"Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
goto bad;
}
if (AR_SREV_9100(ah)) {
}
if (AR_SREV_9160_10_OR_LATER(ah)) {
if (AR_SREV_9280_10_OR_LATER(ah)) {
} else {
}
}
if (AR_SREV_9160(ah)) {
} else {
if (AR_SREV_9280_10_OR_LATER(ah)) {
ahp->ah_ani_function &=
}
}
"This Mac Chip Rev 0x%02x.%x is \n",
if (AR_SREV_9285_12_OR_LATER(ah)) {
2);
} else {
}
} else if (AR_SREV_9285_10_OR_LATER(ah)) {
} else {
2);
}
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
} else {
}
} else if (AR_SREV_9280_10_OR_LATER(ah)) {
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
if (AR_SREV_9160_11(ah)) {
} else {
}
} else if (AR_SREV_9100_OR_LATER(ah)) {
} else {
}
if (ah->ah_isPciExpress)
else
if (ecode != 0)
goto bad;
/* rxgain table */
if (AR_SREV_9280_20(ah))
/* txgain table */
if (AR_SREV_9280_20(ah))
}
}
}
if (!ath9k_hw_fill_cap_info(ah)) {
"failed ath9k_hw_fill_cap_info\n"));
goto bad;
}
if (ecode != 0) {
"%s: failed initializing mac address\n",
__func__));
goto bad;
}
if (AR_SREV_9285(ah))
else
return (ah);
bad:
if (ahp)
if (status)
return (NULL);
}
static void
{
else
synthDelay /= 10;
}
static void
{
SM(0, AR_QOS_NO_ACK_BYTE_OFF));
}
static void
{
if (AR_SREV_9100(ah)) {
pll = 0x1450;
else
pll = 0x1458;
} else {
if (AR_SREV_9280_10_OR_LATER(ah)) {
if (AR_SREV_9280_20(ah)) {
pll = 0x2850;
else
pll = 0x142c;
}
} else {
}
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
else
} else {
else
}
}
}
static void
{
switch (rx_chainmask) {
case 0x5:
/*FALLTHRU*/
case 0x3:
break;
}
/*FALLTHRU*/
case 0x1:
case 0x2:
case 0x7:
break;
default:
break;
}
if (tx_chainmask == 0x5) {
}
if (AR_SREV_9100(ah))
}
static void
{
if (ahp->ah_intrMitigation)
else
if (opmode == ATH9K_M_HOSTAP)
if (!AR_SREV_9100(ah)) {
}
}
static boolean_t
{
"bad ack timeout %u\n", us));
return (B_FALSE);
} else {
return (B_TRUE);
}
}
static boolean_t
{
"bad cts timeout %u\n", us));
return (B_FALSE);
} else {
return (B_TRUE);
}
}
static boolean_t
{
if (tu > 0xFFFF) {
"arn: ath9k_hw_set_global_txtimeout(): "
"ath9k_hw_set_global_txtimeout\n", tu));
return (B_FALSE);
} else {
return (B_TRUE);
}
}
static void
{
if (ahp->ah_miscMode != 0)
}
const char *
{
return (vendorid == ATHEROS_VENDOR_ID ?
}
void
{
if (!AR_SREV_9100(ah))
}
struct ath_hal *
{
switch (device_id) {
case AR5416_DEVID_PCI:
case AR5416_DEVID_PCIE:
case AR9160_DEVID_PCI:
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
case AR9285_DEVID_PCIE:
break;
default:
break;
}
return (ah);
}
/* INI */
/* ARGSUSED */
static void
{
/*
* 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.
*/
if (!AR_SREV_5416_V20_OR_LATER(ah) ||
return;
}
static uint32_t
struct ar5416_eeprom_def *pEepData,
{
case AR9280_DEVID_PCI:
if (reg == 0x7894) {
"arn: ath9k_hw_ini_fixup(): "
"ini VAL: %x EEPROM: %x\n",
"arn: ath9k_hw_ini_fixup(): "
"PWDCLKIND: %d\n",
} else {
"arn: ath9k_hw_ini_fixup(): "
"PWDCLKIND Earlier Rev\n"));
}
"arn: ath9k_hw_ini_fixup(): "
"final ini VAL: %x\n\n", value));
}
break;
}
return (value);
}
static uint32_t
{
return (value);
else
}
static int
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
int i, regWrites = 0;
int status;
case CHANNEL_A:
case CHANNEL_A_HT20:
modesIndex = 1;
freqIndex = 1;
break;
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
modesIndex = 2;
freqIndex = 1;
break;
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_B:
modesIndex = 4;
freqIndex = 2;
break;
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
modesIndex = 3;
freqIndex = 2;
break;
default:
"%s: err: unknow chan->chanmode\n", __func__));
return (EINVAL);
}
if (AR_SREV_5416_V22_OR_LATER(ah)) {
/* LINTED: E_CONSTANT_CONDITION */
} else {
/* LINTED: E_CONSTANT_CONDITION */
}
drv_usecwait(100);
}
/* LINTED: E_CONSTANT_CONDITION */
}
if (AR_SREV_9280(ah)) {
/* LINTED: E_CONSTANT_CONDITION */
}
if (AR_SREV_9280(ah)) {
/* LINTED: E_CONSTANT_CONDITION */
}
drv_usecwait(100);
}
/* LINTED: E_CONSTANT_CONDITION */
}
/* LINTED: E_CONSTANT_CONDITION */
}
if (status != 0) {
"%s: error init'ing transmit power\n", __func__));
return (EIO);
}
"%s: ar5416SetRfRegs failed\n", __func__));
return (EIO);
}
return (0);
}
/* Reset and Channel Switching Routines */
static void
{
return;
if (!AR_SREV_9280_10_OR_LATER(ah))
rfMode |= (AR_PHY_MODE_DYNAMIC |
}
static void
{
}
static inline void
{
if (AR_SREV_9285(ah)) {
} else {
}
}
static void
{
switch (opmode) {
case ATH9K_M_HOSTAP:
break;
case ATH9K_M_IBSS:
break;
case ATH9K_M_STA:
case ATH9K_M_MONITOR:
break;
}
}
/* ARGSUSED */
static inline void
{
break;
}
static void
struct ath9k_channel *chan)
{
if (IS_CHAN_HALF_RATE(chan))
else if (IS_CHAN_QUARTER_RATE(chan))
&ds_coef_exp);
&ds_coef_exp);
}
static boolean_t
{
if (AR_SREV_9100(ah)) {
} else {
if (tmpReg &
} else {
}
if (type == ATH9K_RESET_COLD)
}
drv_usecwait(50);
"RTC stuck in MAC reset\n"));
return (B_FALSE);
}
if (!AR_SREV_9100(ah))
if (AR_SREV_9100(ah))
drv_usecwait(50);
return (B_TRUE);
}
static boolean_t
{
if (!ath9k_hw_wait(ah,
AR_RTC_STATUS_ON)) {
"arn: ath9k_hw_set_reset_power_on(): "
"RTC not waking up \n"));
return (B_FALSE);
}
}
static boolean_t
{
switch (type) {
case ATH9K_RESET_POWER_ON:
return (ath9k_hw_set_reset_power_on(ah));
case ATH9K_RESET_WARM:
case ATH9K_RESET_COLD:
default:
return (B_FALSE);
}
}
static void
enum ath9k_ht_macmode macmode)
{
if (AR_SREV_9285_10_OR_LATER(ah))
if (IS_CHAN_HT40(chan)) {
}
}
static boolean_t
struct ath9k_channel *chan)
{
return (B_FALSE);
return (B_FALSE);
return (B_TRUE);
}
static struct ath9k_channel *
{
"%s: invalid channel %u/0x%x; not marked as "
"2GHz or 5GHz\n",
return (NULL);
}
if (!IS_CHAN_OFDM(chan) &&
!IS_CHAN_HT20(chan) &&
!IS_CHAN_HT40(chan)) {
"%s: invalid channel %u/0x%x; not marked as "
"OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
return (NULL);
}
}
static boolean_t
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
"%s: Transmit frames pending on queue %d\n",
return (B_FALSE);
}
}
"%s: Could not kill baseband RX\n", __func__));
return (B_FALSE);
}
if (AR_SREV_9280_10_OR_LATER(ah)) {
"%s: failed to set channel\n", __func__));
return (B_FALSE);
}
} else {
"%s: failed to set channel\n", __func__));
return (B_FALSE);
}
}
"%s: error init'ing transmit power\n", __func__));
return (B_FALSE);
}
else
synthDelay /= 10;
if (AR_SREV_9280_10_OR_LATER(ah))
else
if (!chan->oneTimeCalsDone)
return (B_TRUE);
}
static void
{
int freq;
int spur_freq_sd;
int spur_delta_phase;
int denominator;
int i;
};
};
int tmp_mask;
int cur_bb_spur;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
if (is2GHz)
else
if (AR_NO_SPUR == cur_bb_spur)
break;
if (IS_CHAN_HT40(chan)) {
if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
break;
}
} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
break;
}
}
if (AR_NO_SPUR == bb_spur) {
return;
} else {
}
if (IS_CHAN_HT40(chan)) {
if (bb_spur < 0) {
spur_subchannel_sd = 1;
} else {
spur_subchannel_sd = 0;
}
} else {
spur_subchannel_sd = 0;
}
if (IS_CHAN_HT40(chan))
else
cur_bin = -6000;
for (i = 0; i < 4; i++) {
int pilot_mask = 0;
int chan_mask = 0;
int bp = 0;
}
cur_bin += 100;
}
}
cur_vit_mask = 6100;
for (i = 0; i < 123; i++) {
/* workaround for gcc bug #37014 */
if (tmp < 75)
mask_amt = 1;
else
mask_amt = 0;
if (cur_vit_mask < 0)
else
}
cur_vit_mask -= 100;
}
}
static void
{
int spur_freq_sd;
int spur_delta_phase;
int denominator;
int i;
};
};
int tmp_mask;
int cur_bb_spur;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
if (AR_NO_SPUR == cur_bb_spur)
break;
break;
}
}
if (AR_NO_SPUR == bb_spur)
return;
cur_bin = -6000;
for (i = 0; i < 4; i++) {
int pilot_mask = 0;
int chan_mask = 0;
int bp = 0;
}
cur_bin += 100;
}
}
cur_vit_mask = 6100;
for (i = 0; i < 123; i++) {
/* workaround for gcc bug #37014 */
if (tmp < 75)
mask_amt = 1;
else
mask_amt = 0;
if (cur_vit_mask < 0)
else
}
cur_vit_mask -= 100;
}
}
enum ath9k_ht_macmode macmode,
{
int ecode;
int i, rx_chainmask;
if (AR_SREV_9280(ah)) {
}
"%s: invalid channel %u/0x%x; no mapping\n",
goto bad;
}
"%s: ath9k_hw_setpower failed!!!\n", __func__));
goto bad;
}
if (curchan)
if (bChannelChange &&
return (B_TRUE);
}
}
if (saveDefAntenna == 0)
saveDefAntenna = 1;
"%s: chip reset failed\n", __func__));
goto bad;
}
if (AR_SREV_9280(ah)) {
if (IS_CHAN_5GHZ(chan))
else
}
}
if (ecode != 0) {
goto bad;
}
if (AR_SREV_9280_10_OR_LATER(ah))
else
"%s: error setting board options\n", __func__));
goto bad;
}
if (AR_SREV_9280_10_OR_LATER(ah)) {
"%s: ath9k_hw_ar9280_set_channel failed!!!\n",
__func__));
goto bad;
}
} else {
"%s: ath9k_hw_set_channel failed!!!\n", __func__));
goto bad;
}
}
for (i = 0; i < AR_NUM_DCU; i++)
ahp->ah_intrTxqs = 0;
(void) ath9k_hw_resettxqueue(ah, i);
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
#endif
if (ahp->ah_intrMitigation) {
}
goto bad;
}
}
if (AR_SREV_9100(ah)) {
"%s CFG Byte Swap Set 0x%x\n",
} else {
"%s Setting CFG 0x%x\n",
}
} else {
"#ifdef __BIG_ENDIAN \n"));
#ifdef __BIG_ENDIAN
#endif
}
return (B_TRUE);
bad:
if (status)
return (B_FALSE);
}
/* Key Cache Management */
{
"entry %u out of range\n", entry));
return (B_FALSE);
}
if (keyType == AR_KEYTABLE_TYPE_TKIP &&
}
return (B_TRUE);
return (B_TRUE);
}
{
return (B_FALSE);
}
mac[0];
macLo >>= 1;
macHi >>= 1;
} else {
}
return (B_TRUE);
}
{
return (B_FALSE);
}
switch (k->kv_type) {
case ATH9K_CIPHER_AES_OCB:
break;
case ATH9K_CIPHER_AES_CCM:
"%s: AES-CCM not supported by "
"mac rev 0x%x\n", __func__,
return (B_FALSE);
}
break;
case ATH9K_CIPHER_TKIP:
if (ATH9K_IS_MIC_ENABLED(ah) &&
"%s: entry %u inappropriate for TKIP\n",
return (B_FALSE);
}
break;
case ATH9K_CIPHER_WEP:
if (k->kv_len < ATH9K_LEN_WEP40) {
"%s: WEP key length %u too small\n",
return (B_FALSE);
}
if (k->kv_len <= ATH9K_LEN_WEP40)
else if (k->kv_len <= ATH9K_LEN_WEP104)
else
break;
case ATH9K_CIPHER_CLR:
break;
default:
"%s: cipher %u not supported\n", __func__,
k->kv_type));
return (B_FALSE);
}
if (k->kv_len <= ATH9K_LEN_WEP104)
key4 &= 0xff;
} else {
}
} else {
}
return (B_TRUE);
return (B_TRUE);
}
{
if (val & AR_KEYTABLE_VALID)
return (B_TRUE);
}
return (B_FALSE);
}
/* Power Management (Chipset) */
static void
{
if (setChip) {
if (!AR_SREV_9100(ah))
}
}
static void
{
if (setChip) {
} else {
}
}
}
static boolean_t
{
int i;
if (setChip) {
if (ath9k_hw_set_reset_reg(ah,
ATH9K_RESET_POWER_ON) != B_TRUE) {
return (B_FALSE);
}
}
if (AR_SREV_9100(ah))
drv_usecwait(50);
for (i = POWER_UP_TIME / 50; i > 0; i--) {
if (val == AR_RTC_STATUS_ON)
break;
drv_usecwait(50);
}
if (i == 0) {
"arn: ath9k_hw_set_power_awake(): "
"Failed to wakeup in %uus\n",
POWER_UP_TIME / 20));
return (B_FALSE);
}
}
return (B_TRUE);
}
{
static const char *modes[] = {
"AWAKE",
"FULL-SLEEP",
"NETWORK SLEEP",
"UNDEFINED"
};
"%s -> %s (%s)\n",
switch (mode) {
case ATH9K_PM_AWAKE:
break;
case ATH9K_PM_FULL_SLEEP:
break;
case ATH9K_PM_NETWORK_SLEEP:
break;
default:
"unknown power mode %u\n", mode));
return (B_FALSE);
}
return (status);
}
void
{
uint8_t i;
return;
return;
if (restore)
return;
if (AR_SREV_9280_20_OR_LATER(ah)) {
}
drv_usecwait(1000);
} else if (AR_SREV_9280(ah) &&
else
drv_usecwait(1000);
} else {
}
} else {
if (AR_SREV_9285(ah))
else if (AR_SREV_9280(ah))
else
}
}
/* Interrupt Handling */
{
if (AR_SREV_9100(ah))
return (B_TRUE);
return (B_TRUE);
if ((host_isr & AR_INTR_SYNC_DEFAULT) &&
(host_isr != AR_INTR_SPURIOUS))
return (B_TRUE);
return (B_FALSE);
}
{
if (!AR_SREV_9100(ah)) {
== AR_RTC_STATUS_ON) {
}
}
*masked = 0;
if (!isr && !sync_cause)
return (B_FALSE);
} else {
*masked = 0;
}
if (isr) {
if (isr & AR_ISR_BCNMISC) {
if (isr2 & AR_ISR_S2_TIM)
mask2 |= ATH9K_INT_TIM;
if (isr2 & AR_ISR_S2_DTIM)
mask2 |= ATH9K_INT_DTIM;
if (isr2 & AR_ISR_S2_DTIMSYNC)
if (isr2 & (AR_ISR_S2_CABEND))
if (isr2 & AR_ISR_S2_GTT)
mask2 |= ATH9K_INT_GTT;
if (isr2 & AR_ISR_S2_CST)
mask2 |= ATH9K_INT_CST;
}
if (isr == 0xffffffff) {
*masked = 0;
return (B_FALSE);
}
if (ahp->ah_intrMitigation) {
*masked |= ATH9K_INT_RX;
}
*masked |= ATH9K_INT_RX;
if (isr &
AR_ISR_TXEOL)) {
*masked |= ATH9K_INT_TX;
}
if (isr & AR_ISR_RXORN) {
"%s: receive FIFO overrun interrupt\n", __func__));
}
if (!AR_SREV_9100(ah)) {
if (isr5 & AR_ISR_S5_TIM_TIMER)
}
}
}
if (AR_SREV_9100(ah))
return (B_TRUE);
if (sync_cause) {
fatal_int = (sync_cause &
if (fatal_int) {
if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
"%s: received PCI FATAL interrupt\n",
__func__));
}
if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
"%s: received PCI PERR interrupt\n",
__func__));
}
}
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
"%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
__func__));
*masked |= ATH9K_INT_FATAL;
}
if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
"%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
__func__));
}
}
return (B_TRUE);
}
enum ath9k_int
{
}
enum ath9k_int
{
"arn: ath9k_hw_set_interrupts(): "
if (omask & ATH9K_INT_GLOBAL) {
"arn: ath9k_hw_set_interrupts(): "
"disable IER\n"));
if (!AR_SREV_9100(ah)) {
}
}
mask2 = 0;
if (ints & ATH9K_INT_TX) {
if (ahp->ah_txOkInterruptMask)
mask |= AR_IMR_TXOK;
if (ahp->ah_txDescInterruptMask)
mask |= AR_IMR_TXDESC;
if (ahp->ah_txErrInterruptMask)
mask |= AR_IMR_TXERR;
if (ahp->ah_txEolInterruptMask)
mask |= AR_IMR_TXEOL;
}
if (ints & ATH9K_INT_RX) {
mask |= AR_IMR_RXERR;
if (ahp->ah_intrMitigation)
else
mask |= AR_IMR_GENTMR;
}
if (ints & (ATH9K_INT_BMISC)) {
mask |= AR_IMR_BCNMISC;
if (ints & ATH9K_INT_TIM)
mask2 |= AR_IMR_S2_TIM;
if (ints & ATH9K_INT_DTIM)
mask2 |= AR_IMR_S2_DTIM;
if (ints & ATH9K_INT_DTIMSYNC)
if (ints & ATH9K_INT_CABEND)
mask2 |= (AR_IMR_S2_CABEND);
}
mask |= AR_IMR_BCNMISC;
if (ints & ATH9K_INT_GTT)
mask2 |= AR_IMR_S2_GTT;
if (ints & ATH9K_INT_CST)
mask2 |= AR_IMR_S2_CST;
}
~(AR_IMR_S2_TIM |
if (ints & ATH9K_INT_TIM_TIMER)
else
}
if (ints & ATH9K_INT_GLOBAL) {
if (!AR_SREV_9100(ah)) {
}
}
return (omask);
}
/* Beacon Handling */
void
{
int flags = 0;
case ATH9K_M_STA:
case ATH9K_M_MONITOR:
break;
case ATH9K_M_IBSS:
ah_atimWindow : 1)));
flags |= AR_NDP_TIMER_EN;
/*FALLTHRU*/
case ATH9K_M_HOSTAP:
flags |=
break;
default:
"%s: unsupported opmode: %d\n",
return;
}
if (beacon_period & ATH9K_BEACON_RESET_TSF) {
}
}
void
const struct ath9k_beacon_state *bs)
{
if (beaconintval == dtimperiod)
else
else
/* TSF Out of Range Threshold */
}
/* HW Capabilities */
{
"%s: regdomain mapped to 0x%x\n", __func__,
ah->ah_currentRD));
}
if (eeval & AR5416_OPFLAGS_11A) {
if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
}
}
}
if (eeval & AR5416_OPFLAGS_11G) {
if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
}
}
}
if ((ah->ah_isPciExpress) ||
(eeval & AR5416_OPFLAGS_11A)) {
pCap->rx_chainmask =
} else {
pCap->rx_chainmask =
}
else
if (capField & AR_EEPROM_EEPCAP_MAXQCU)
pCap->total_queues =
else
else
if (AR_SREV_9280_10_OR_LATER(ah))
else
if (AR_SREV_9280_10_OR_LATER(ah)) {
} else {
}
} else {
}
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
ah->ah_rfkill_gpio =
}
#endif
else
else
} else {
}
/* ATH9K_HAL_FREQ_BAND_5GHZ == 0 */
/* ATH9K_HAL_FREQ_BAND_2GHZ == 1 */
return (B_TRUE);
}
enum ath9k_capability_type type,
{
switch (type) {
case ATH9K_CAP_CIPHER:
switch (capability) {
case ATH9K_CIPHER_AES_CCM:
case ATH9K_CIPHER_AES_OCB:
case ATH9K_CIPHER_TKIP:
case ATH9K_CIPHER_WEP:
case ATH9K_CIPHER_MIC:
case ATH9K_CIPHER_CLR:
return (B_TRUE);
default:
return (B_FALSE);
}
case ATH9K_CAP_TKIP_MIC:
switch (capability) {
case 0:
return (B_TRUE);
case 1:
return ((ahp->ah_staId1Defaults &
B_FALSE);
}
/*FALLTHRU*/
case ATH9K_CAP_TKIP_SPLIT:
case ATH9K_CAP_WME_TKIPMIC:
return (0);
case ATH9K_CAP_PHYCOUNTERS:
case ATH9K_CAP_DIVERSITY:
case ATH9K_CAP_PHYDIAG:
return (B_TRUE);
case ATH9K_CAP_MCAST_KEYSRCH:
switch (capability) {
case 0:
return (B_TRUE);
case 1:
return (B_FALSE);
} else {
return ((ahp->ah_staId1Defaults &
B_FALSE);
}
}
return (B_FALSE);
case ATH9K_CAP_TSF_ADJUST:
case ATH9K_CAP_RFSILENT:
if (capability == 3)
return (B_FALSE);
/*FALLTHRU*/
case ATH9K_CAP_ANT_CFG_2GHZ:
return (B_TRUE);
case ATH9K_CAP_ANT_CFG_5GHZ:
return (B_TRUE);
case ATH9K_CAP_TXPOW:
switch (capability) {
case 0:
return (0);
case 1:
return (0);
case 2:
return (0);
case 3:
return (0);
}
return (B_FALSE);
default:
return (B_FALSE);
}
}
/* ARGSUSED */
enum ath9k_capability_type type,
int *status)
{
uint32_t v;
switch (type) {
case ATH9K_CAP_TKIP_MIC:
if (setting)
ahp->ah_staId1Defaults |=
else
ahp->ah_staId1Defaults &=
return (B_TRUE);
case ATH9K_CAP_DIVERSITY:
if (setting)
else
return (B_TRUE);
case ATH9K_CAP_MCAST_KEYSRCH:
if (setting)
else
return (B_TRUE);
case ATH9K_CAP_TSF_ADJUST:
if (setting)
else
return (B_TRUE);
default:
return (B_FALSE);
}
}
/* GPIO / RFKILL / Antennae */
static void
{
int addr;
if (gpio > 11)
else if (gpio > 5)
else
if (AR_SREV_9280_20_OR_LATER(ah) ||
(addr != AR_GPIO_OUTPUT_MUX1)) {
(0x1f << gpio_shift));
} else {
}
}
void
{
(AR_GPIO_OE_OUT_DRV << gpio_shift));
}
{
return (0xffffffff);
if (AR_SREV_9280_10_OR_LATER(ah)) {
} else {
AR_GPIO_BIT(gpio)) != 0);
}
}
void
{
(AR_GPIO_OE_OUT_DRV << gpio_shift));
}
void
{
AR_GPIO_BIT(gpio));
}
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
void
{
}
#endif
int
{
if (cfg < halNumAntConfig) {
cfg, &ant_config)) {
return (0);
}
}
return (-EINVAL);
}
{
}
void
{
}
/* ARGSUSED */
enum ath9k_ant_setting settings,
struct ath9k_channel *chan,
{
if (AR_SREV_9280(ah)) {
if (!tx_chainmask_cfg) {
}
switch (settings) {
case ATH9K_ANT_FIXED_A:
*antenna_cfgd = B_TRUE;
break;
case ATH9K_ANT_FIXED_B:
}
*antenna_cfgd = B_TRUE;
break;
case ATH9K_ANT_VARIABLE:
*antenna_cfgd = B_TRUE;
break;
default:
break;
}
} else {
}
return (B_TRUE);
}
/* General Operation */
{
if (phybits & AR_PHY_ERR_RADAR)
return (bits);
}
void
{
phybits = 0;
if (bits & ATH9K_RX_FILTER_PHYRADAR)
if (bits & ATH9K_RX_FILTER_PHYERR)
if (phybits)
else
}
{
}
{
return (B_FALSE);
}
{
/* LINT */
return (B_FALSE);
return (B_TRUE);
}
void
{
}
{
return (B_TRUE);
}
void
{
}
void
{
}
void
{
}
{
return (B_TRUE);
}
void
{
}
{
return (tsf);
}
void
{
int count;
count = 0;
count++;
if (count > 10) {
"%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
__func__));
break;
}
drv_usecwait(10);
}
}
{
if (setting)
else
return (B_TRUE);
}
{
return (B_FALSE);
} else {
return (B_TRUE);
}
}
void
{
if (mode == ATH9K_HT_MACMODE_2040 &&
else
macmode = 0;
}