summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2005-02-25 22:25:31 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2005-02-25 22:25:31 +0000
commit7a5ae57cf7496a38699cd390f874fc3359242511 (patch)
tree620ba16fed20c23692826978981c99dcb2171f35
parenteaf739340cc437965c78359443b2c66b50cc3f23 (diff)
add support for the atheros ar5211 802.11A/B/g wireless chipset.
ok deraadt@
-rw-r--r--sys/conf/files4
-rw-r--r--sys/dev/ic/ar5211.c2488
-rw-r--r--sys/dev/ic/ar5211reg.h1033
-rw-r--r--sys/dev/ic/ar5211var.h396
-rw-r--r--sys/dev/ic/ar5212.c9
-rw-r--r--sys/dev/ic/ar5212var.h147
-rw-r--r--sys/dev/ic/ar5xxx.c39
-rw-r--r--sys/dev/ic/ar5xxx.h148
8 files changed, 4104 insertions, 160 deletions
diff --git a/sys/conf/files b/sys/conf/files
index e80bdd4da1c..925bd2f43a7 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.328 2005/02/19 16:58:00 reyk Exp $
+# $OpenBSD: files,v 1.329 2005/02/25 22:25:30 reyk Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -330,7 +330,7 @@ file dev/ic/nslm7x.c lm
define ar5xxx
file dev/ic/ar5xxx.c ar5xxx
file dev/ic/ar5210.c ar5xxx
-#file dev/ic/ar5211.c ar5xxx
+file dev/ic/ar5211.c ar5xxx
file dev/ic/ar5212.c ar5xxx
# Atheros AR5k (802.11/a/b/g) driver
diff --git a/sys/dev/ic/ar5211.c b/sys/dev/ic/ar5211.c
new file mode 100644
index 00000000000..0adaf5b861b
--- /dev/null
+++ b/sys/dev/ic/ar5211.c
@@ -0,0 +1,2488 @@
+/* $OpenBSD: ar5211.c,v 1.1 2005/02/25 22:25:30 reyk Exp $ */
+
+/*
+ * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * 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.
+ */
+
+/*
+ * HAL interface for the Atheros AR5001 Wireless LAN chipset
+ * (AR5211 + AR5111).
+ */
+
+#include <dev/ic/ar5xxx.h>
+#include <dev/ic/ar5211reg.h>
+#include <dev/ic/ar5211var.h>
+
+HAL_BOOL ar5k_ar5211_nic_reset(struct ath_hal *, u_int32_t);
+HAL_BOOL ar5k_ar5211_nic_wakeup(struct ath_hal *, u_int16_t);
+u_int16_t ar5k_ar5211_radio_revision(struct ath_hal *, HAL_CHIP);
+const void ar5k_ar5211_fill(struct ath_hal *);
+
+/*
+ * Initial register setting for the AR5211
+ */
+static const struct ar5k_ini ar5211_ini[] =
+ AR5K_AR5211_INI;
+static const struct ar5k_ar5211_ini_mode ar5211_mode[] =
+ AR5K_AR5211_INI_MODE;
+
+AR5K_HAL_FUNCTIONS(extern, ar5k_ar5211,);
+
+const void
+ar5k_ar5211_fill(hal)
+ struct ath_hal *hal;
+{
+ hal->ah_magic = AR5K_AR5211_MAGIC;
+
+ /*
+ * Init/Exit functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, getRateTable);
+ AR5K_HAL_FUNCTION(hal, ar5211, detach);
+
+ /*
+ * Reset functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, reset);
+ AR5K_HAL_FUNCTION(hal, ar5211, setPCUConfig);
+ AR5K_HAL_FUNCTION(hal, ar5211, perCalibration);
+
+ /*
+ * TX functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, updateTxTrigLevel);
+ AR5K_HAL_FUNCTION(hal, ar5211, setupTxQueue);
+ AR5K_HAL_FUNCTION(hal, ar5211, setTxQueueProps);
+ AR5K_HAL_FUNCTION(hal, ar5211, releaseTxQueue);
+ AR5K_HAL_FUNCTION(hal, ar5211, resetTxQueue);
+ AR5K_HAL_FUNCTION(hal, ar5211, getTxDP);
+ AR5K_HAL_FUNCTION(hal, ar5211, setTxDP);
+ AR5K_HAL_FUNCTION(hal, ar5211, startTxDma);
+ AR5K_HAL_FUNCTION(hal, ar5211, stopTxDma);
+ AR5K_HAL_FUNCTION(hal, ar5211, setupTxDesc);
+ AR5K_HAL_FUNCTION(hal, ar5211, setupXTxDesc);
+ AR5K_HAL_FUNCTION(hal, ar5211, fillTxDesc);
+ AR5K_HAL_FUNCTION(hal, ar5211, procTxDesc);
+ AR5K_HAL_FUNCTION(hal, ar5211, hasVEOL);
+
+ /*
+ * RX functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, getRxDP);
+ AR5K_HAL_FUNCTION(hal, ar5211, setRxDP);
+ AR5K_HAL_FUNCTION(hal, ar5211, enableReceive);
+ AR5K_HAL_FUNCTION(hal, ar5211, stopDmaReceive);
+ AR5K_HAL_FUNCTION(hal, ar5211, startPcuReceive);
+ AR5K_HAL_FUNCTION(hal, ar5211, stopPcuReceive);
+ AR5K_HAL_FUNCTION(hal, ar5211, setMulticastFilter);
+ AR5K_HAL_FUNCTION(hal, ar5211, setMulticastFilterIndex);
+ AR5K_HAL_FUNCTION(hal, ar5211, clrMulticastFilterIndex);
+ AR5K_HAL_FUNCTION(hal, ar5211, getRxFilter);
+ AR5K_HAL_FUNCTION(hal, ar5211, setRxFilter);
+ AR5K_HAL_FUNCTION(hal, ar5211, setupRxDesc);
+ AR5K_HAL_FUNCTION(hal, ar5211, procRxDesc);
+ AR5K_HAL_FUNCTION(hal, ar5211, rxMonitor);
+
+ /*
+ * Misc functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, dumpState);
+ AR5K_HAL_FUNCTION(hal, ar5211, getDiagState);
+ AR5K_HAL_FUNCTION(hal, ar5211, getMacAddress);
+ AR5K_HAL_FUNCTION(hal, ar5211, setMacAddress);
+ AR5K_HAL_FUNCTION(hal, ar5211, setRegulatoryDomain);
+ AR5K_HAL_FUNCTION(hal, ar5211, setLedState);
+ AR5K_HAL_FUNCTION(hal, ar5211, writeAssocid);
+ AR5K_HAL_FUNCTION(hal, ar5211, gpioCfgInput);
+ AR5K_HAL_FUNCTION(hal, ar5211, gpioCfgOutput);
+ AR5K_HAL_FUNCTION(hal, ar5211, gpioGet);
+ AR5K_HAL_FUNCTION(hal, ar5211, gpioSet);
+ AR5K_HAL_FUNCTION(hal, ar5211, gpioSetIntr);
+ AR5K_HAL_FUNCTION(hal, ar5211, getTsf32);
+ AR5K_HAL_FUNCTION(hal, ar5211, getTsf64);
+ AR5K_HAL_FUNCTION(hal, ar5211, resetTsf);
+ AR5K_HAL_FUNCTION(hal, ar5211, getRegDomain);
+ AR5K_HAL_FUNCTION(hal, ar5211, detectCardPresent);
+ AR5K_HAL_FUNCTION(hal, ar5211, updateMibCounters);
+ AR5K_HAL_FUNCTION(hal, ar5211, getRfGain);
+ AR5K_HAL_FUNCTION(hal, ar5211, setSlotTime);
+ AR5K_HAL_FUNCTION(hal, ar5211, getSlotTime);
+ AR5K_HAL_FUNCTION(hal, ar5211, setAckTimeout);
+ AR5K_HAL_FUNCTION(hal, ar5211, getAckTimeout);
+ AR5K_HAL_FUNCTION(hal, ar5211, setCTSTimeout);
+ AR5K_HAL_FUNCTION(hal, ar5211, getCTSTimeout);
+
+ /*
+ * Key table (WEP) functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, isHwCipherSupported);
+ AR5K_HAL_FUNCTION(hal, ar5211, getKeyCacheSize);
+ AR5K_HAL_FUNCTION(hal, ar5211, resetKeyCacheEntry);
+ AR5K_HAL_FUNCTION(hal, ar5211, isKeyCacheEntryValid);
+ AR5K_HAL_FUNCTION(hal, ar5211, setKeyCacheEntry);
+ AR5K_HAL_FUNCTION(hal, ar5211, setKeyCacheEntryMac);
+
+ /*
+ * Power management functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, setPowerMode);
+ AR5K_HAL_FUNCTION(hal, ar5211, getPowerMode);
+ AR5K_HAL_FUNCTION(hal, ar5211, queryPSPollSupport);
+ AR5K_HAL_FUNCTION(hal, ar5211, initPSPoll);
+ AR5K_HAL_FUNCTION(hal, ar5211, enablePSPoll);
+ AR5K_HAL_FUNCTION(hal, ar5211, disablePSPoll);
+
+ /*
+ * Beacon functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, beaconInit);
+ AR5K_HAL_FUNCTION(hal, ar5211, setStationBeaconTimers);
+ AR5K_HAL_FUNCTION(hal, ar5211, resetStationBeaconTimers);
+ AR5K_HAL_FUNCTION(hal, ar5211, waitForBeaconDone);
+
+ /*
+ * Interrupt functions
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, isInterruptPending);
+ AR5K_HAL_FUNCTION(hal, ar5211, getPendingInterrupts);
+ AR5K_HAL_FUNCTION(hal, ar5211, getInterrupts);
+ AR5K_HAL_FUNCTION(hal, ar5211, setInterrupts);
+
+ /*
+ * Chipset functions (ar5k-specific, non-HAL)
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, get_capabilities);
+ AR5K_HAL_FUNCTION(hal, ar5211, radar_alert);
+
+ /*
+ * EEPROM access
+ */
+ AR5K_HAL_FUNCTION(hal, ar5211, eeprom_is_busy);
+ AR5K_HAL_FUNCTION(hal, ar5211, eeprom_read);
+ AR5K_HAL_FUNCTION(hal, ar5211, eeprom_write);
+}
+
+struct ath_hal *
+ar5k_ar5211_attach(device, sc, st, sh, status)
+ u_int16_t device;
+ void *sc;
+ bus_space_tag_t st;
+ bus_space_handle_t sh;
+ int *status;
+{
+ struct ath_hal *hal = (struct ath_hal*) sc;
+ u_int8_t mac[IEEE80211_ADDR_LEN];
+ u_int32_t srev;
+
+ ar5k_ar5211_fill(hal);
+
+ /* Bring device out of sleep and reset it's units */
+ if (ar5k_ar5211_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)
+ return (NULL);
+
+ /* Get MAC, PHY and RADIO revisions */
+ srev = AR5K_REG_READ(AR5K_AR5211_SREV) & AR5K_AR5211_SREV_M;
+ hal->ah_mac_version = srev & AR5K_AR5211_SREV_VERSION;
+ hal->ah_mac_revision = srev & AR5K_AR5211_SREV_REVISION;
+ hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5211_PHY_CHIP_ID) &
+ 0x00ffffffff;
+
+ hal->ah_radio_5ghz_revision =
+ ar5k_ar5211_radio_revision(hal, HAL_CHIP_5GHZ);
+
+ /* Get the 2GHz radio revision if it's supported */
+ if (hal->ah_mac_version >= AR5K_SREV_VER_AR5211)
+ hal->ah_radio_2ghz_revision =
+ ar5k_ar5211_radio_revision(hal, HAL_CHIP_2GHZ);
+
+ /* Identify the chipset (this has to be done in an early step) */
+ hal->ah_version = AR5K_AR5211;
+ hal->ah_radio = AR5K_AR5111;
+ hal->ah_phy = AR5K_AR5211_PHY(0);
+
+ memset(&mac, 0xff, sizeof(mac));
+ ar5k_ar5211_writeAssocid(hal, mac, 0, 0);
+ ar5k_ar5211_getMacAddress(hal, mac);
+ ar5k_ar5211_setPCUConfig(hal);
+
+ return (hal);
+}
+
+HAL_BOOL
+ar5k_ar5211_nic_reset(hal, val)
+ struct ath_hal *hal;
+ u_int32_t val;
+{
+ HAL_BOOL ret = AH_FALSE;
+ u_int32_t mask = val ? val : ~0;
+
+ /* Read-and-clear */
+ AR5K_REG_READ(AR5K_AR5211_RXDP);
+
+ /*
+ * Reset the device and wait until success
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_RC, val);
+
+ /* Wait at least 128 PCI clocks */
+ AR5K_DELAY(15);
+
+ val &=
+ AR5K_AR5211_RC_PCU | AR5K_AR5211_RC_BB;
+
+ mask &=
+ AR5K_AR5211_RC_PCU | AR5K_AR5211_RC_BB;
+
+ ret = ar5k_register_timeout(hal, AR5K_AR5211_RC, mask, val, AH_FALSE);
+
+ /*
+ * Reset configuration register
+ */
+ if ((val & AR5K_AR5211_RC_PCU) == 0)
+ AR5K_REG_WRITE(AR5K_AR5211_CFG, AR5K_AR5211_INIT_CFG);
+
+ return (ret);
+}
+
+HAL_BOOL
+ar5k_ar5211_nic_wakeup(hal, flags)
+ struct ath_hal *hal;
+ u_int16_t flags;
+{
+ u_int32_t turbo, mode, clock;
+
+ turbo = 0;
+ mode = 0;
+ clock = 0;
+
+ /*
+ * Get channel mode flags
+ */
+
+ if (flags & IEEE80211_CHAN_2GHZ) {
+ mode |= AR5K_AR5211_PHY_MODE_FREQ_2GHZ;
+ clock |= AR5K_AR5211_PHY_PLL_44MHZ;
+ } else if (flags & IEEE80211_CHAN_5GHZ) {
+ mode |= AR5K_AR5211_PHY_MODE_FREQ_5GHZ;
+ clock |= AR5K_AR5211_PHY_PLL_40MHZ;
+ } else {
+ AR5K_PRINT("invalid radio frequency mode\n");
+ return (AH_FALSE);
+ }
+
+ if ((flags & IEEE80211_CHAN_CCK) ||
+ (flags & IEEE80211_CHAN_DYN)) {
+ /* Dynamic OFDM/CCK is not supported by the AR5211 */
+ mode |= AR5K_AR5211_PHY_MODE_MOD_CCK;
+ } else if (flags & IEEE80211_CHAN_OFDM) {
+ mode |= AR5K_AR5211_PHY_MODE_MOD_OFDM;
+ } else {
+ AR5K_PRINT("invalid radio frequency mode\n");
+ return (AH_FALSE);
+ }
+
+ if (flags & IEEE80211_CHAN_TURBO) {
+ turbo = AR5K_AR5211_PHY_TURBO_MODE |
+ AR5K_AR5211_PHY_TURBO_SHORT;
+ }
+
+ /*
+ * Reset and wakeup the device
+ */
+
+ /* ...reset chipset and PCI device */
+ if (ar5k_ar5211_nic_reset(hal,
+ AR5K_AR5211_RC_CHIP | AR5K_AR5211_RC_PCI) == AH_FALSE) {
+ AR5K_PRINT("failed to reset the AR5211 + PCI chipset\n");
+ return (AH_FALSE);
+ }
+
+ /* ...wakeup */
+ if (ar5k_ar5211_setPowerMode(hal,
+ HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
+ AR5K_PRINT("failed to resume the AR5211 (again)\n");
+ return (AH_FALSE);
+ }
+
+ /* ...final warm reset */
+ if (ar5k_ar5211_nic_reset(hal, 0) == AH_FALSE) {
+ AR5K_PRINT("failed to warm reset the AR5211\n");
+ return (AH_FALSE);
+ }
+
+ /* ...set the PHY operating mode */
+ AR5K_REG_WRITE(AR5K_AR5211_PHY_PLL, clock);
+ AR5K_DELAY(300);
+
+ AR5K_REG_WRITE(AR5K_AR5211_PHY_MODE, mode);
+ AR5K_REG_WRITE(AR5K_AR5211_PHY_TURBO, turbo);
+
+ return (AH_TRUE);
+}
+
+u_int16_t
+ar5k_ar5211_radio_revision(hal, chip)
+ struct ath_hal *hal;
+ HAL_CHIP chip;
+{
+ int i;
+ u_int32_t srev;
+ u_int16_t ret;
+
+ /*
+ * Set the radio chip access register
+ */
+ switch (chip) {
+ case HAL_CHIP_2GHZ:
+ AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_2GHZ);
+ break;
+ case HAL_CHIP_5GHZ:
+ AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);
+ break;
+ default:
+ return (0);
+ }
+
+ AR5K_DELAY(2000);
+
+ /* ...wait until PHY is ready and read the selected radio revision */
+ AR5K_REG_WRITE(AR5K_AR5211_PHY(0x34), 0x00001c16);
+
+ for (i = 0; i < 8; i++)
+ AR5K_REG_WRITE(AR5K_AR5211_PHY(0x20), 0x00010000);
+ srev = (AR5K_REG_READ(AR5K_AR5211_PHY(0x100)) >> 24) & 0xff;
+
+ ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);
+
+ /* Reset to the 5GHz mode */
+ AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);
+
+ return (ret);
+}
+
+const HAL_RATE_TABLE *
+ar5k_ar5211_getRateTable(hal, mode)
+ struct ath_hal *hal;
+ u_int mode;
+{
+ switch (mode) {
+ case HAL_MODE_11A:
+ return (&hal->ah_rt_11a);
+ case HAL_MODE_TURBO:
+ return (&hal->ah_rt_turbo);
+ case HAL_MODE_11B:
+ return (&hal->ah_rt_11b);
+ case HAL_MODE_11G:
+ case HAL_MODE_PUREG:
+ return (&hal->ah_rt_11g);
+ default:
+ return (NULL);
+ }
+
+ return (NULL);
+}
+
+void
+ar5k_ar5211_detach(hal)
+ struct ath_hal *hal;
+{
+ /*
+ * Free HAL structure, assume interrupts are down
+ */
+ free(hal, M_DEVBUF);
+}
+
+HAL_BOOL
+ar5k_ar5211_reset(hal, op_mode, channel, change_channel, status)
+ struct ath_hal *hal;
+ HAL_OPMODE op_mode;
+ HAL_CHANNEL *channel;
+ HAL_BOOL change_channel;
+ HAL_STATUS *status;
+{
+ struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
+ u_int8_t mac[IEEE80211_ADDR_LEN];
+ u_int32_t data;
+ u_int i, mode, freq, ee_mode, ant[2];
+
+ if (ar5k_ar5211_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)
+ return (AH_FALSE);
+
+ /*
+ * Initialize operating mode
+ */
+ hal->ah_op_mode = op_mode;
+
+ if (channel->c_channel_flags & IEEE80211_CHAN_A) {
+ mode = AR5K_INI_VAL_11A;
+ freq = AR5K_INI_RFGAIN_5GHZ;
+ ee_mode = AR5K_EEPROM_MODE_11A;
+ } else if (channel->c_channel_flags & IEEE80211_CHAN_T) {
+ mode = AR5K_INI_VAL_11A_TURBO;
+ freq = AR5K_INI_RFGAIN_5GHZ;
+ ee_mode = AR5K_EEPROM_MODE_11A;
+ } else if (channel->c_channel_flags & IEEE80211_CHAN_B) {
+ mode = AR5K_INI_VAL_11B;
+ freq = AR5K_INI_RFGAIN_2GHZ;
+ ee_mode = AR5K_EEPROM_MODE_11B;
+ } else if (channel->c_channel_flags & IEEE80211_CHAN_G) {
+ mode = AR5K_INI_VAL_11G;
+ freq = AR5K_INI_RFGAIN_2GHZ;
+ ee_mode = AR5K_EEPROM_MODE_11G;
+ } else {
+ AR5K_PRINTF("invalid channel: %d\n", channel->c_channel);
+ return (AH_FALSE);
+ }
+
+ /* PHY access enable */
+ AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);
+
+ /*
+ * Write initial register settings
+ */
+ for (i = 0; i < AR5K_ELEMENTS(ar5211_ini); i++) {
+ if (change_channel == AH_TRUE &&
+ ar5211_ini[i].ini_register >= AR5K_AR5211_PCU_MIN &&
+ ar5211_ini[i].ini_register <= AR5K_AR5211_PCU_MAX)
+ continue;
+
+ AR5K_REG_WRITE((u_int32_t)ar5211_ini[i].ini_register,
+ ar5211_ini[i].ini_value);
+ }
+
+ /*
+ * Write initial mode settings
+ */
+ for (i = 0; i < AR5K_ELEMENTS(ar5211_mode); i++) {
+ AR5K_REG_WRITE((u_int32_t)ar5211_mode[i].mode_register,
+ ar5211_mode[i].mode_value[mode]);
+ }
+
+ /*
+ * Write initial RF gain settings
+ */
+ if (ar5k_rfgain(hal, AR5K_INI_PHY_5111, freq) == AH_FALSE)
+ return (AH_FALSE);
+
+ AR5K_DELAY(1000);
+
+ /*
+ * Configure additional registers
+ */
+
+ /* Set antenna mode */
+ AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x44),
+ hal->ah_antenna[ee_mode][0], 0xfffffc06);
+
+ ant[0] = HAL_ANT_FIXED_A;
+ ant[1] = HAL_ANT_FIXED_B;
+
+ if (hal->ah_ant_diversity == AH_FALSE) {
+ if (freq == AR5K_INI_RFGAIN_2GHZ)
+ ant[0] = HAL_ANT_FIXED_B;
+ else if (freq == AR5K_INI_RFGAIN_5GHZ)
+ ant[1] = HAL_ANT_FIXED_A;
+ }
+
+ AR5K_REG_WRITE(AR5K_AR5211_PHY_ANT_SWITCH_TABLE_0,
+ hal->ah_antenna[ee_mode][ant[0]]);
+ AR5K_REG_WRITE(AR5K_AR5211_PHY_ANT_SWITCH_TABLE_1,
+ hal->ah_antenna[ee_mode][ant[1]]);
+
+ /* Commit values from EEPROM */
+ AR5K_REG_WRITE_BITS(AR5K_AR5211_PHY_FC,
+ AR5K_AR5211_PHY_FC_TX_CLIP, ee->ee_tx_clip);
+
+ AR5K_REG_WRITE(AR5K_AR5211_PHY(0x5a),
+ AR5K_AR5211_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));
+
+ AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x11),
+ (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);
+ AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x12),
+ (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);
+ AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x14),
+ (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
+ ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);
+
+ AR5K_REG_WRITE(AR5K_AR5211_PHY(0x0d),
+ (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
+ (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
+ (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
+ (ee->ee_tx_frm2xpa_enable[ee_mode]));
+
+ AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x0a),
+ ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
+ AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x19),
+ (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
+ AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x49), 4, 0xffffff01);
+
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_IQ,
+ AR5K_AR5211_PHY_IQ_CORR_ENABLE |
+ (ee->ee_i_cal[ee_mode] << AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF_S) |
+ ee->ee_q_cal[ee_mode]);
+
+ /* Misc */
+ memset(&mac, 0xff, sizeof(mac));
+ ar5k_ar5211_writeAssocid(hal, mac, 0, 0);
+ ar5k_ar5211_setPCUConfig(hal);
+ AR5K_REG_WRITE(AR5K_AR5211_PISR, 0xffffffff);
+ AR5K_REG_WRITE(AR5K_AR5211_RSSI_THR, AR5K_TUNE_RSSI_THRES);
+
+ /*
+ * Set channel and calibrate the PHY
+ */
+ if (ar5k_channel(hal, channel) == AH_FALSE)
+ return (AH_FALSE);
+
+ /*
+ * Enable the PHY and wait until completion
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_PHY_ACTIVE, AR5K_AR5211_PHY_ENABLE);
+
+ data = AR5K_REG_READ(AR5K_AR5211_PHY_RX_DELAY) &
+ AR5K_AR5211_PHY_RX_DELAY_M;
+ data = (channel->c_channel_flags & IEEE80211_CHAN_CCK) ?
+ ((data << 2) / 22) : (data / 10);
+
+ AR5K_DELAY(100 + data);
+
+ /*
+ * Start calibration
+ */
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_AGCCTL,
+ AR5K_AR5211_PHY_AGCCTL_NF |
+ AR5K_AR5211_PHY_AGCCTL_CAL);
+
+ if (channel->c_channel_flags & IEEE80211_CHAN_B) {
+ hal->ah_calibration = AH_FALSE;
+ } else {
+ hal->ah_calibration = AH_TRUE;
+ AR5K_REG_WRITE_BITS(AR5K_AR5211_PHY_IQ,
+ AR5K_AR5211_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_IQ,
+ AR5K_AR5211_PHY_IQ_RUN);
+ }
+
+ /*
+ * Reset queues and start beacon timers at the end of the reset routine
+ */
+ for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
+ AR5K_REG_WRITE_Q(AR5K_AR5211_DCU_QCUMASK(i), i);
+ if (ar5k_ar5211_resetTxQueue(hal, i) == AH_FALSE) {
+ AR5K_PRINTF("failed to reset TX queue #%d\n", i);
+ return (AH_FALSE);
+ }
+ }
+
+ /* Pre-enable interrupts */
+ ar5k_ar5211_setInterrupts(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);
+
+ /*
+ * Set RF kill flags if supported by the device (read from the EEPROM)
+ */
+ if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
+ ar5k_ar5211_gpioCfgInput(hal, 0);
+ if ((hal->ah_gpio[0] = ar5k_ar5211_gpioGet(hal, 0)) == 0)
+ ar5k_ar5211_gpioSetIntr(hal, 0, 1);
+ else
+ ar5k_ar5211_gpioSetIntr(hal, 0, 0);
+ }
+
+ /*
+ * Disable beacons and reset the register
+ */
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_BEACON,
+ AR5K_AR5211_BEACON_ENABLE | AR5K_AR5211_BEACON_RESET_TSF);
+
+ return (AH_TRUE);
+}
+
+void
+ar5k_ar5211_setPCUConfig(hal)
+ struct ath_hal *hal;
+{
+ u_int32_t pcu_reg, low_id, high_id;
+
+ pcu_reg = 0;
+
+ switch (hal->ah_op_mode) {
+ case IEEE80211_M_IBSS:
+ pcu_reg |= AR5K_AR5211_STA_ID1_ADHOC |
+ AR5K_AR5211_STA_ID1_DESC_ANTENNA;
+ break;
+
+ case IEEE80211_M_HOSTAP:
+ pcu_reg |= AR5K_AR5211_STA_ID1_AP |
+ AR5K_AR5211_STA_ID1_RTS_DEFAULT_ANTENNA;
+ break;
+
+ case IEEE80211_M_STA:
+ case IEEE80211_M_MONITOR:
+ pcu_reg |= AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA;
+ break;
+
+ default:
+ return;
+ }
+
+ /*
+ * Set PCU registers
+ */
+ memcpy(&low_id, &(hal->ah_sta_id[0]), 4);
+ memcpy(&high_id, &(hal->ah_sta_id[4]), 2);
+ AR5K_REG_WRITE(AR5K_AR5211_STA_ID0, low_id);
+ AR5K_REG_WRITE(AR5K_AR5211_STA_ID1, pcu_reg | high_id);
+
+ return;
+}
+
+HAL_BOOL
+ar5k_ar5211_perCalibration(hal, channel)
+ struct ath_hal *hal;
+ HAL_CHANNEL *channel;
+{
+ u_int32_t i_pwr, q_pwr;
+ int32_t iq_corr, i_coff, i_coffd, q_coff, q_coffd;
+
+ if (hal->ah_calibration == AH_FALSE ||
+ AR5K_REG_READ(AR5K_AR5211_PHY_IQ) & AR5K_AR5211_PHY_IQ_RUN)
+ goto done;
+
+ hal->ah_calibration = AH_FALSE;
+
+ iq_corr = AR5K_REG_READ(AR5K_AR5211_PHY_IQRES_CAL_CORR);
+ i_pwr = AR5K_REG_READ(AR5K_AR5211_PHY_IQRES_CAL_PWR_I);
+ q_pwr = AR5K_REG_READ(AR5K_AR5211_PHY_IQRES_CAL_PWR_Q);
+ i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
+ q_coffd = q_pwr >> 6;
+
+ if (i_coffd == 0 || q_coffd == 0)
+ goto done;
+
+ i_coff = ((-iq_corr) / i_coffd) & 0x3f;
+ q_coff = (((int32_t)i_pwr / q_coffd) - 64) & 0x1f;
+
+ /* Commit new IQ value */
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_IQ,
+ AR5K_AR5211_PHY_IQ_CORR_ENABLE |
+ ((u_int32_t)q_coff) |
+ ((u_int32_t)i_coff << AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF_S));
+
+ done:
+ /* Start noise floor calibration */
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_AGCCTL,
+ AR5K_AR5211_PHY_AGCCTL_NF);
+
+ return (AH_TRUE);
+}
+
+/*
+ * Transmit functions
+ */
+
+HAL_BOOL
+ar5k_ar5211_updateTxTrigLevel(hal, increase)
+ struct ath_hal *hal;
+ HAL_BOOL increase;
+{
+ u_int32_t trigger_level, imr;
+ HAL_BOOL status = AH_FALSE;
+
+ /*
+ * Disable interrupts by setting the mask
+ */
+ imr = ar5k_ar5211_setInterrupts(hal, hal->ah_imr & ~HAL_INT_GLOBAL);
+
+ trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5211_TXCFG),
+ AR5K_AR5211_TXCFG_TXFULL);
+
+ if (increase == AH_FALSE) {
+ if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
+ goto done;
+ } else
+ trigger_level +=
+ ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
+
+ /*
+ * Update trigger level on success
+ */
+ AR5K_REG_WRITE_BITS(AR5K_AR5211_TXCFG,
+ AR5K_AR5211_TXCFG_TXFULL, trigger_level);
+ status = AH_TRUE;
+
+ done:
+ /*
+ * Restore interrupt mask
+ */
+ ar5k_ar5211_setInterrupts(hal, imr);
+
+ return (status);
+}
+
+int
+ar5k_ar5211_setupTxQueue(hal, queue_type, queue_info)
+ struct ath_hal *hal;
+ HAL_TX_QUEUE queue_type;
+ const HAL_TXQ_INFO *queue_info;
+{
+ u_int queue;
+
+ /*
+ * Get queue by type
+ */
+ if (queue_type == HAL_TX_QUEUE_DATA) {
+ for (queue = HAL_TX_QUEUE_ID_DATA_MIN;
+ hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE;
+ queue++)
+ if (queue > HAL_TX_QUEUE_ID_DATA_MAX)
+ return (-1);
+ } else if (queue_type == HAL_TX_QUEUE_PSPOLL) {
+ queue = HAL_TX_QUEUE_ID_PSPOLL;
+ } else if (queue_type == HAL_TX_QUEUE_BEACON) {
+ queue = HAL_TX_QUEUE_ID_BEACON;
+ } else if (queue_type == HAL_TX_QUEUE_CAB) {
+ queue = HAL_TX_QUEUE_ID_CAB;
+ } else
+ return (-1);
+
+ /*
+ * Setup internal queue structure
+ */
+ bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
+ hal->ah_txq[queue].tqi_type = queue_type;
+
+ if (queue_info != NULL) {
+ if (ar5k_ar5211_setTxQueueProps(hal, queue, queue_info)
+ != AH_TRUE)
+ return (-1);
+ }
+
+ AR5K_Q_ENABLE_BITS(hal->ah_txq_interrupts, queue);
+
+ return (queue);
+}
+
+HAL_BOOL
+ar5k_ar5211_setTxQueueProps(hal, queue, queue_info)
+ struct ath_hal *hal;
+ int queue;
+ const HAL_TXQ_INFO *queue_info;
+{
+ AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
+
+ if (hal->ah_txq[queue].tqi_type == HAL_TX_QUEUE_INACTIVE)
+ return (AH_FALSE);
+
+ bcopy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
+
+ if (queue_info->tqi_type == HAL_TX_QUEUE_DATA &&
+ (queue_info->tqi_subtype >= HAL_WME_AC_VI) &&
+ (queue_info->tqi_subtype <= HAL_WME_UPSD))
+ hal->ah_txq[queue].tqi_flags |=
+ AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_releaseTxQueue(hal, queue)
+ struct ath_hal *hal;
+ u_int queue;
+{
+ AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
+
+ /* This queue will be skipped in further operations */
+ hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
+ AR5K_Q_DISABLE_BITS(hal->ah_txq_interrupts, queue);
+
+ return (AH_FALSE);
+}
+
+HAL_BOOL
+ar5k_ar5211_resetTxQueue(hal, queue)
+ struct ath_hal *hal;
+ u_int queue;
+{
+ u_int32_t cw_min, cw_max, retry_lg, retry_sh;
+ struct ieee80211_channel *channel = (struct ieee80211_channel*)
+ &hal->ah_current_channel;
+ HAL_TXQ_INFO *tq;
+
+ AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
+
+ tq = &hal->ah_txq[queue];
+
+ if (tq->tqi_type == HAL_TX_QUEUE_INACTIVE)
+ return (AH_TRUE);
+
+ /*
+ * Set registers by channel mode
+ */
+ if (IEEE80211_IS_CHAN_B(channel)) {
+ hal->ah_cw_min = AR5K_TUNE_CWMIN_11B;
+ hal->ah_cw_max = AR5K_TUNE_CWMAX_11B;
+ hal->ah_aifs = AR5K_TUNE_AIFS_11B;
+ } else {
+ hal->ah_cw_min = AR5K_TUNE_CWMIN;
+ hal->ah_cw_max = AR5K_TUNE_CWMAX;
+ hal->ah_aifs = AR5K_TUNE_AIFS;
+ }
+
+ /*
+ * Set retry limits
+ */
+ if (hal->ah_software_retry == AH_TRUE) {
+ /* XXX Need to test this */
+ retry_lg = hal->ah_limit_tx_retries;
+ retry_sh = retry_lg =
+ retry_lg > AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY ?
+ AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY : retry_lg;
+ } else {
+ retry_lg = AR5K_INIT_LG_RETRY;
+ retry_sh = AR5K_INIT_SH_RETRY;
+ }
+
+ AR5K_REG_WRITE(AR5K_AR5211_DCU_RETRY_LMT(queue),
+ AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
+ AR5K_AR5211_DCU_RETRY_LMT_SLG_RETRY)
+ | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
+ AR5K_AR5211_DCU_RETRY_LMT_SSH_RETRY)
+ | AR5K_REG_SM(retry_lg, AR5K_AR5211_DCU_RETRY_LMT_LG_RETRY)
+ | AR5K_REG_SM(retry_sh, AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY));
+
+ /*
+ * Set initial content window (cw_min/cw_max)
+ */
+ cw_min = 1;
+ while (cw_min < hal->ah_cw_min)
+ cw_min = (cw_min << 1) | 1;
+
+ cw_min = tq->tqi_cw_min < 0 ?
+ (cw_min >> (-tq->tqi_cw_min)) :
+ ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
+ cw_max = tq->tqi_cw_max < 0 ?
+ (cw_max >> (-tq->tqi_cw_max)) :
+ ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
+
+ AR5K_REG_WRITE(AR5K_AR5211_DCU_LCL_IFS(queue),
+ AR5K_REG_SM(cw_min, AR5K_AR5211_DCU_LCL_IFS_CW_MIN) |
+ AR5K_REG_SM(cw_max, AR5K_AR5211_DCU_LCL_IFS_CW_MAX) |
+ AR5K_REG_SM(hal->ah_aifs + tq->tqi_aifs,
+ AR5K_AR5211_DCU_LCL_IFS_AIFS));
+
+ /*
+ * Set misc registers
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_QCU_MISC(queue),
+ AR5K_AR5211_QCU_MISC_DCU_EARLY);
+
+ if (tq->tqi_cbr_period) {
+ AR5K_REG_WRITE(AR5K_AR5211_QCU_CBRCFG(queue),
+ AR5K_REG_SM(tq->tqi_cbr_period,
+ AR5K_AR5211_QCU_CBRCFG_INTVAL) |
+ AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
+ AR5K_AR5211_QCU_CBRCFG_ORN_THRES));
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
+ AR5K_AR5211_QCU_MISC_FRSHED_CBR);
+ if (tq->tqi_cbr_overflow_limit)
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
+ AR5K_AR5211_QCU_MISC_CBR_THRES_ENABLE);
+ }
+
+ if (tq->tqi_ready_time) {
+ AR5K_REG_WRITE(AR5K_AR5211_QCU_RDYTIMECFG(queue),
+ AR5K_REG_SM(tq->tqi_ready_time,
+ AR5K_AR5211_QCU_RDYTIMECFG_INTVAL) |
+ AR5K_AR5211_QCU_RDYTIMECFG_ENABLE);
+ }
+
+ if (tq->tqi_burst_time) {
+ AR5K_REG_WRITE(AR5K_AR5211_DCU_CHAN_TIME(queue),
+ AR5K_REG_SM(tq->tqi_burst_time,
+ AR5K_AR5211_DCU_CHAN_TIME_DUR) |
+ AR5K_AR5211_DCU_CHAN_TIME_ENABLE);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) {
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
+ AR5K_AR5211_QCU_MISC_TXE);
+ }
+ }
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) {
+ AR5K_REG_WRITE(AR5K_AR5211_DCU_MISC(queue),
+ AR5K_AR5211_DCU_MISC_POST_FR_BKOFF_DIS);
+ }
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
+ AR5K_REG_WRITE(AR5K_AR5211_DCU_MISC(queue),
+ AR5K_AR5211_DCU_MISC_BACKOFF_FRAG);
+ }
+
+ /*
+ * Set registers by queue type
+ */
+ switch (tq->tqi_type) {
+ case HAL_TX_QUEUE_BEACON:
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
+ AR5K_AR5211_QCU_MISC_FRSHED_DBA_GT |
+ AR5K_AR5211_QCU_MISC_CBREXP_BCN |
+ AR5K_AR5211_QCU_MISC_BCN_ENABLE);
+
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_DCU_MISC(queue),
+ (AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
+ AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL) |
+ AR5K_AR5211_DCU_MISC_POST_FR_BKOFF_DIS |
+ AR5K_AR5211_DCU_MISC_BCN_ENABLE);
+
+ AR5K_REG_WRITE(AR5K_AR5211_QCU_RDYTIMECFG(queue),
+ ((AR5K_TUNE_BEACON_INTERVAL -
+ (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
+ AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
+ AR5K_AR5211_QCU_RDYTIMECFG_ENABLE);
+ break;
+
+ case HAL_TX_QUEUE_CAB:
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
+ AR5K_AR5211_QCU_MISC_FRSHED_DBA_GT |
+ AR5K_AR5211_QCU_MISC_CBREXP |
+ AR5K_AR5211_QCU_MISC_CBREXP_BCN);
+
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_DCU_MISC(queue),
+ (AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
+ AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL));
+ break;
+
+ case HAL_TX_QUEUE_PSPOLL:
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
+ AR5K_AR5211_QCU_MISC_CBREXP);
+ break;
+
+ case HAL_TX_QUEUE_DATA:
+ default:
+ break;
+ }
+
+ /*
+ * Enable tx queue in the secondary interrupt mask registers
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_SIMR0,
+ AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5211_SIMR0_QCU_TXOK) |
+ AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5211_SIMR0_QCU_TXDESC));
+ AR5K_REG_WRITE(AR5K_AR5211_SIMR1,
+ AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5211_SIMR1_QCU_TXERR));
+ AR5K_REG_WRITE(AR5K_AR5211_SIMR2,
+ AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5211_SIMR2_QCU_TXURN));
+
+ return (AH_TRUE);
+}
+
+u_int32_t
+ar5k_ar5211_getTxDP(hal, queue)
+ struct ath_hal *hal;
+ u_int queue;
+{
+ AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
+
+ /*
+ * Get the transmit queue descriptor pointer from the selected queue
+ */
+ return (AR5K_REG_READ(AR5K_AR5211_QCU_TXDP(queue)));
+}
+
+HAL_BOOL
+ar5k_ar5211_setTxDP(hal, queue, phys_addr)
+ struct ath_hal *hal;
+ u_int queue;
+ u_int32_t phys_addr;
+{
+ AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
+
+ /*
+ * Set the transmit queue descriptor pointer for the selected queue
+ * (this won't work if the queue is still active)
+ */
+ if (AR5K_REG_READ_Q(AR5K_AR5211_QCU_TXE, queue))
+ return (AH_FALSE);
+
+ AR5K_REG_WRITE(AR5K_AR5211_QCU_TXDP(queue), phys_addr);
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_startTxDma(hal, queue)
+ struct ath_hal *hal;
+ u_int queue;
+{
+ AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
+
+ /* Return if queue is disabled */
+ if (AR5K_REG_READ_Q(AR5K_AR5211_QCU_TXD, queue))
+ return (AH_FALSE);
+
+ /* Start queue */
+ AR5K_REG_WRITE_Q(AR5K_AR5211_QCU_TXE, queue);
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_stopTxDma(hal, queue)
+ struct ath_hal *hal;
+ u_int queue;
+{
+ HAL_BOOL ret;
+
+ AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
+
+ /*
+ * Schedule TX disable and wait until queue is empty
+ */
+ AR5K_REG_WRITE_Q(AR5K_AR5211_QCU_TXD, queue);
+
+ ret = ar5k_register_timeout(hal, AR5K_AR5211_QCU_STS(queue),
+ AR5K_AR5211_QCU_STS_FRMPENDCNT, 0, AH_FALSE);
+
+ /* Clear register */
+ AR5K_REG_WRITE(AR5K_AR5211_QCU_TXD, 0);
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_setupTxDesc(hal, desc, packet_length, header_length, type, tx_power,
+ tx_rate0, tx_tries0, key_index, antenna_mode, flags, rtscts_rate,
+ rtscts_duration)
+ struct ath_hal *hal;
+ struct ath_desc *desc;
+ u_int packet_length;
+ u_int header_length;
+ HAL_PKT_TYPE type;
+ u_int tx_power;
+ u_int tx_rate0;
+ u_int tx_tries0;
+ u_int key_index;
+ u_int antenna_mode;
+ u_int flags;
+ u_int rtscts_rate;
+ u_int rtscts_duration;
+{
+ struct ar5k_ar5211_tx_desc *tx_desc;
+
+ tx_desc = (struct ar5k_ar5211_tx_desc*)&desc->ds_ctl0;
+
+ /* Clear descriptor */
+ bzero(tx_desc, sizeof(struct ar5k_ar5211_tx_desc));
+
+ /*
+ * Validate input
+ */
+ if (tx_tries0 == 0)
+ return (AH_FALSE);
+
+ if ((tx_desc->frame_len = packet_length) != packet_length)
+ return (AH_FALSE);
+
+ tx_desc->frame_type = type;
+ tx_desc->xmit_rate = tx_rate0;
+ tx_desc->ant_mode_xmit = antenna_mode;
+
+#define _TX_FLAGS(_flag, _field) \
+ tx_desc->_field = flags & HAL_TXDESC_##_flag ? 1 : 0
+
+ _TX_FLAGS(CLRDMASK, clear_dest_mask);
+ _TX_FLAGS(VEOL, veol);
+ _TX_FLAGS(INTREQ, inter_req);
+ _TX_FLAGS(NOACK, no_ack);
+ _TX_FLAGS(RTSENA, rts_cts_enable);
+
+#undef _TX_FLAGS
+
+ /*
+ * WEP crap
+ */
+ if (key_index != HAL_TXKEYIX_INVALID) {
+ tx_desc->encrypt_key_valid = 1;
+ tx_desc->encrypt_key_index = key_index;
+ }
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_fillTxDesc(hal, desc, segment_length, first_segment, last_segment)
+ struct ath_hal *hal;
+ struct ath_desc *desc;
+ u_int segment_length;
+ HAL_BOOL first_segment;
+ HAL_BOOL last_segment;
+{
+ struct ar5k_ar5211_tx_desc *tx_desc;
+
+ tx_desc = (struct ar5k_ar5211_tx_desc*)&desc->ds_ctl0;
+
+ /* Clear status descriptor */
+ desc->ds_hw[0] = desc->ds_hw[1] = 0;
+
+ /* Validate segment length and initialize the descriptor */
+ if ((tx_desc->buf_len = segment_length) != segment_length)
+ return (AH_FALSE);
+
+ if (first_segment != AH_TRUE)
+ tx_desc->frame_len = 0;
+
+ tx_desc->more = last_segment == AH_TRUE ? 0 : 1;
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_setupXTxDesc(hal, desc, tx_rate1, tx_tries1, tx_rate2, tx_tries2,
+ tx_rate3, tx_tries3)
+ struct ath_hal *hal;
+ struct ath_desc *desc;
+ u_int tx_rate1;
+ u_int tx_tries1;
+ u_int tx_rate2;
+ u_int tx_tries2;
+ u_int tx_rate3;
+ u_int tx_tries3;
+{
+ return (AH_FALSE);
+}
+
+HAL_STATUS
+ar5k_ar5211_procTxDesc(hal, desc)
+ struct ath_hal *hal;
+ struct ath_desc *desc;
+{
+ struct ar5k_ar5211_tx_status *tx_status;
+ struct ar5k_ar5211_tx_desc *tx_desc;
+
+ tx_desc = (struct ar5k_ar5211_tx_desc*)&desc->ds_ctl0;
+ tx_status = (struct ar5k_ar5211_tx_status*)&desc->ds_hw[0];
+
+ /* No frame has been send or error */
+ if (tx_status->done == 0)
+ return (HAL_EINPROGRESS);
+
+ /*
+ * Get descriptor status
+ */
+ desc->ds_us.tx.ts_seqnum = tx_status->seq_num;
+ desc->ds_us.tx.ts_tstamp = tx_status->send_timestamp;
+ desc->ds_us.tx.ts_shortretry = tx_status->rts_fail_count ?
+ (tx_status->rts_fail_count + 1) : 0;
+ desc->ds_us.tx.ts_longretry = tx_status->data_fail_count ?
+ (tx_status->data_fail_count + 1) : 0;
+ desc->ds_us.tx.ts_rssi = tx_status->ack_sig_strength;
+ desc->ds_us.tx.ts_antenna = 0;
+ desc->ds_us.tx.ts_status = 0;
+ desc->ds_us.tx.ts_rate = tx_desc->xmit_rate;
+
+ if (tx_status->frame_xmit_ok == 0) {
+ if (tx_status->excessive_retries)
+ desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
+
+ if (tx_status->fifo_underrun)
+ desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
+
+ if (tx_status->filtered)
+ desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
+ }
+
+ return (HAL_OK);
+}
+
+HAL_BOOL
+ar5k_ar5211_hasVEOL(hal)
+ struct ath_hal *hal;
+{
+ return (AH_TRUE);
+}
+
+/*
+ * Receive functions
+ */
+
+u_int32_t
+ar5k_ar5211_getRxDP(hal)
+ struct ath_hal *hal;
+{
+ return (AR5K_REG_READ(AR5K_AR5211_RXDP));
+}
+
+void
+ar5k_ar5211_setRxDP(hal, phys_addr)
+ struct ath_hal *hal;
+ u_int32_t phys_addr;
+{
+ AR5K_REG_WRITE(AR5K_AR5211_RXDP, phys_addr);
+}
+
+void
+ar5k_ar5211_enableReceive(hal)
+ struct ath_hal *hal;
+{
+ AR5K_REG_WRITE(AR5K_AR5211_CR, AR5K_AR5211_CR_RXE);
+}
+
+HAL_BOOL
+ar5k_ar5211_stopDmaReceive(hal)
+ struct ath_hal *hal;
+{
+ int i;
+
+ AR5K_REG_WRITE(AR5K_AR5211_CR, AR5K_AR5211_CR_RXD);
+
+ /*
+ * It may take some time to disable the DMA receive unit
+ */
+ for (i = 2000;
+ i > 0 && (AR5K_REG_READ(AR5K_AR5211_CR) & AR5K_AR5211_CR_RXE) != 0;
+ i--)
+ AR5K_DELAY(10);
+
+ return (i > 0 ? AH_TRUE : AH_FALSE);
+}
+
+void
+ar5k_ar5211_startPcuReceive(hal)
+ struct ath_hal *hal;
+{
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_DIAG_SW, AR5K_AR5211_DIAG_SW_DIS_RX);
+}
+
+void
+ar5k_ar5211_stopPcuReceive(hal)
+ struct ath_hal *hal;
+{
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_DIAG_SW, AR5K_AR5211_DIAG_SW_DIS_RX);
+}
+
+void
+ar5k_ar5211_setMulticastFilter(hal, filter0, filter1)
+ struct ath_hal *hal;
+ u_int32_t filter0;
+ u_int32_t filter1;
+{
+ /* Set the multicat filter */
+ AR5K_REG_WRITE(AR5K_AR5211_MCAST_FIL0, filter0);
+ AR5K_REG_WRITE(AR5K_AR5211_MCAST_FIL1, filter1);
+}
+
+HAL_BOOL
+ar5k_ar5211_setMulticastFilterIndex(hal, index)
+ struct ath_hal *hal;
+ u_int32_t index;
+{
+ if (index >= 64) {
+ return (AH_FALSE);
+ } else if (index >= 32) {
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_MCAST_FIL1,
+ (1 << (index - 32)));
+ } else {
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_MCAST_FIL0,
+ (1 << index));
+ }
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_clrMulticastFilterIndex(hal, index)
+ struct ath_hal *hal;
+ u_int32_t index;
+{
+
+ if (index >= 64) {
+ return (AH_FALSE);
+ } else if (index >= 32) {
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_MCAST_FIL1,
+ (1 << (index - 32)));
+ } else {
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_MCAST_FIL0,
+ (1 << index));
+ }
+
+ return (AH_TRUE);
+}
+
+u_int32_t
+ar5k_ar5211_getRxFilter(hal)
+ struct ath_hal *hal;
+{
+ return (AR5K_REG_READ(AR5K_AR5211_RX_FILTER));
+}
+
+void
+ar5k_ar5211_setRxFilter(hal, filter)
+ struct ath_hal *hal;
+ u_int32_t filter;
+{
+ AR5K_REG_WRITE(AR5K_AR5211_RX_FILTER, filter);
+}
+
+HAL_BOOL
+ar5k_ar5211_setupRxDesc(hal, desc, size, flags)
+ struct ath_hal *hal;
+ struct ath_desc *desc;
+ u_int32_t size;
+ u_int flags;
+{
+ struct ar5k_ar5211_rx_desc *rx_desc;
+
+ /* Reset descriptor */
+ desc->ds_ctl0 = 0;
+ desc->ds_ctl1 = 0;
+ bzero(&desc->ds_hw[0], sizeof(struct ar5k_ar5211_rx_status));
+
+ rx_desc = (struct ar5k_ar5211_rx_desc*)&desc->ds_ctl0;
+
+ if ((rx_desc->buf_len = size) != size)
+ return (AH_FALSE);
+
+ if (flags & HAL_RXDESC_INTREQ)
+ rx_desc->inter_req = 1;
+
+ return (AH_TRUE);
+}
+
+HAL_STATUS
+ar5k_ar5211_procRxDesc(hal, desc, phys_addr, next)
+ struct ath_hal *hal;
+ struct ath_desc *desc;
+ u_int32_t phys_addr;
+ struct ath_desc *next;
+{
+ u_int32_t now, tstamp;
+ struct ar5k_ar5211_rx_status *rx_status;
+
+ rx_status = (struct ar5k_ar5211_rx_status*)&desc->ds_hw[0];
+
+ /* No frame received / not ready */
+ if (!rx_status->done)
+ return (HAL_EINPROGRESS);
+
+ /*
+ * Frame receive status
+ */
+ now = (AR5K_REG_READ(AR5K_AR5211_TSF_L32) >> 10) & 0xffff;
+ tstamp = ((now & 0x1fff) < rx_status->receive_timestamp) ?
+ (((now - 0x2000) & 0xffff) |
+ (u_int32_t)rx_status->receive_timestamp) :
+ (now | (u_int32_t)rx_status->receive_timestamp);
+ desc->ds_us.rx.rs_tstamp = rx_status->receive_timestamp & 0x7fff;
+ desc->ds_us.rx.rs_datalen = rx_status->data_len;
+ desc->ds_us.rx.rs_rssi = rx_status->receive_sig_strength;
+ desc->ds_us.rx.rs_rate = rx_status->receive_rate;
+ desc->ds_us.rx.rs_antenna = rx_status->receive_antenna ? 1 : 0;
+ desc->ds_us.rx.rs_more = rx_status->more ? 1 : 0;
+ desc->ds_us.rx.rs_status = 0;
+
+ /*
+ * Key table status
+ */
+ if (!rx_status->key_index_valid) {
+ desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
+ } else {
+ desc->ds_us.rx.rs_keyix = rx_status->key_index;
+ }
+
+ /*
+ * Receive/descriptor errors
+ */
+ if (!rx_status->frame_receive_ok) {
+ if (rx_status->crc_error)
+ desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
+
+ if (rx_status->phy_error) {
+ desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
+ desc->ds_us.rx.rs_phyerr = rx_status->phy_error;
+ }
+
+ if (rx_status->decrypt_crc_error)
+ desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
+ }
+
+ return (HAL_OK);
+}
+
+void
+ar5k_ar5211_rxMonitor(hal)
+ struct ath_hal *hal;
+{
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_RX_FILTER,
+ AR5K_AR5211_RX_FILTER_PROMISC);
+}
+
+/*
+ * Misc functions
+ */
+
+void
+ar5k_ar5211_dumpState(hal)
+ struct ath_hal *hal;
+{
+ /* Not used */
+ return;
+}
+
+HAL_BOOL
+ar5k_ar5211_getDiagState(hal, id, device, size)
+ struct ath_hal *hal;
+ int id;
+ void **device;
+ u_int *size;
+
+{
+ /*
+ * We'll ignore this right now. This seems to be some kind of an obscure
+ * debugging interface for the binary-only HAL.
+ */
+ return (AH_FALSE);
+}
+
+void
+ar5k_ar5211_getMacAddress(hal, mac)
+ struct ath_hal *hal;
+ u_int8_t *mac;
+{
+ memcpy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
+}
+
+HAL_BOOL
+ar5k_ar5211_setMacAddress(hal, mac)
+ struct ath_hal *hal;
+ const u_int8_t *mac;
+{
+ u_int32_t low_id, high_id;
+
+ /* Set new station ID */
+ memcpy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
+
+ memcpy(&low_id, mac, 4);
+ memcpy(&high_id, mac + 4, 2);
+ high_id = 0x0000ffff & htole32(high_id);
+
+ AR5K_REG_WRITE(AR5K_AR5211_STA_ID0, htole32(low_id));
+ AR5K_REG_WRITE(AR5K_AR5211_STA_ID1, high_id);
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_setRegulatoryDomain(hal, regdomain, status)
+ struct ath_hal *hal;
+ u_int16_t regdomain;
+ HAL_STATUS *status;
+
+{
+ ieee80211_regdomain_t ieee_regdomain;
+
+ ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
+
+ if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
+ &ieee_regdomain) == AH_TRUE) {
+ *status = HAL_OK;
+ return (AH_TRUE);
+ }
+
+ *status = EIO;
+
+ return (AH_FALSE);
+}
+
+void
+ar5k_ar5211_setLedState(hal, state)
+ struct ath_hal *hal;
+ HAL_LED_STATE state;
+{
+ u_int32_t led;
+
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_PCICFG,
+ AR5K_AR5211_PCICFG_LEDMODE | AR5K_AR5211_PCICFG_LED);
+
+ /*
+ * Some blinking values, define at your wish
+ */
+ switch (state) {
+ case IEEE80211_S_SCAN:
+ case IEEE80211_S_AUTH:
+ led =
+ AR5K_AR5211_PCICFG_LEDMODE_PROP |
+ AR5K_AR5211_PCICFG_LED_PEND;
+ break;
+
+ case IEEE80211_S_INIT:
+ led =
+ AR5K_AR5211_PCICFG_LEDMODE_PROP |
+ AR5K_AR5211_PCICFG_LED_NONE;
+ break;
+
+ case IEEE80211_S_ASSOC:
+ case IEEE80211_S_RUN:
+ led |=
+ AR5K_AR5211_PCICFG_LEDMODE_PROP |
+ AR5K_AR5211_PCICFG_LED_ASSOC;
+ break;
+
+ default:
+ led |=
+ AR5K_AR5211_PCICFG_LEDMODE_PROM |
+ AR5K_AR5211_PCICFG_LED_NONE;
+ break;
+ }
+
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PCICFG, led);
+}
+
+void
+ar5k_ar5211_writeAssocid(hal, bssid, assoc_id, tim_offset)
+ struct ath_hal *hal;
+ const u_int8_t *bssid;
+ u_int16_t assoc_id;
+ u_int16_t tim_offset;
+{
+ u_int32_t low_id, high_id;
+
+ /*
+ * Set BSSID which triggers the "SME Join" operation
+ */
+ memcpy(&low_id, bssid, 4);
+ memcpy(&high_id, bssid + 4, 2);
+ AR5K_REG_WRITE(AR5K_AR5211_BSS_ID0, htole32(low_id));
+ AR5K_REG_WRITE(AR5K_AR5211_BSS_ID1, htole32(high_id) |
+ ((assoc_id & 0x3fff) << AR5K_AR5211_BSS_ID1_AID_S));
+ memcpy(&hal->ah_bssid, bssid, IEEE80211_ADDR_LEN);
+
+ if (assoc_id == 0) {
+ ar5k_ar5211_disablePSPoll(hal);
+ return;
+ }
+
+ AR5K_REG_WRITE(AR5K_AR5211_BEACON,
+ (AR5K_REG_READ(AR5K_AR5211_BEACON) &
+ ~AR5K_AR5211_BEACON_TIM) |
+ (((tim_offset ? tim_offset + 4 : 0) <<
+ AR5K_AR5211_BEACON_TIM_S) &
+ AR5K_AR5211_BEACON_TIM));
+
+ ar5k_ar5211_enablePSPoll(hal, NULL, 0);
+}
+
+HAL_BOOL
+ar5k_ar5211_gpioCfgOutput(hal, gpio)
+ struct ath_hal *hal;
+ u_int32_t gpio;
+{
+ if (gpio > AR5K_AR5211_NUM_GPIO)
+ return (AH_FALSE);
+
+ AR5K_REG_WRITE(AR5K_AR5211_GPIOCR,
+ (AR5K_REG_READ(AR5K_AR5211_GPIOCR) &~ AR5K_AR5211_GPIOCR_ALL(gpio))
+ | AR5K_AR5211_GPIOCR_ALL(gpio));
+
+ return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_gpioCfgInput(hal, gpio)
+ struct ath_hal *hal;
+ u_int32_t gpio;
+{
+ if (gpio > AR5K_AR5211_NUM_GPIO)
+ return (AH_FALSE);
+
+ AR5K_REG_WRITE(AR5K_AR5211_GPIOCR,
+ (AR5K_REG_READ(AR5K_AR5211_GPIOCR) &~ AR5K_AR5211_GPIOCR_ALL(gpio))
+ | AR5K_AR5211_GPIOCR_NONE(gpio));
+
+ return (AH_TRUE);
+}
+
+u_int32_t
+ar5k_ar5211_gpioGet(hal, gpio)
+ struct ath_hal *hal;
+ u_int32_t gpio;
+{
+ if (gpio > AR5K_AR5211_NUM_GPIO)
+ return (0xffffffff);
+
+ /* GPIO input magic */
+ return (((AR5K_REG_READ(AR5K_AR5211_GPIODI) &
+ AR5K_AR5211_GPIODI_M) >> gpio) & 0x1);
+}
+
+HAL_BOOL
+ar5k_ar5211_gpioSet(hal, gpio, val)
+ struct ath_hal *hal;
+ u_int32_t gpio;
+ u_int32_t val;
+{
+ u_int32_t data;
+
+ if (gpio > AR5K_AR5211_NUM_GPIO)
+ return (0xffffffff);
+
+ /* GPIO output magic */
+ data = AR5K_REG_READ(AR5K_AR5211_GPIODO);
+
+ data &= ~(1 << gpio);
+ data |= (val&1) << gpio;
+
+ AR5K_REG_WRITE(AR5K_AR5211_GPIODO, data);
+
+ return (AH_TRUE);
+}
+
+void
+ar5k_ar5211_gpioSetIntr(hal, gpio, interrupt_level)
+ struct ath_hal *hal;
+ u_int gpio;
+ u_int32_t interrupt_level;
+{
+ u_int32_t data;
+
+ if (gpio > AR5K_AR5211_NUM_GPIO)
+ return;
+
+ /*
+ * Set the GPIO interrupt
+ */
+ data = (AR5K_REG_READ(AR5K_AR5211_GPIOCR) &
+ ~(AR5K_AR5211_GPIOCR_INT_SEL(gpio) | AR5K_AR5211_GPIOCR_INT_SELH |
+ AR5K_AR5211_GPIOCR_INT_ENA | AR5K_AR5211_GPIOCR_ALL(gpio))) |
+ (AR5K_AR5211_GPIOCR_INT_SEL(gpio) | AR5K_AR5211_GPIOCR_INT_ENA);
+
+ AR5K_REG_WRITE(AR5K_AR5211_GPIOCR,
+ interrupt_level ? data : (data | AR5K_AR5211_GPIOCR_INT_SELH));
+
+ hal->ah_imr |= AR5K_AR5211_PIMR_GPIO;
+
+ /* Enable GPIO interrupts */
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PIMR, AR5K_AR5211_PIMR_GPIO);
+}
+
+u_int32_t
+ar5k_ar5211_getTsf32(hal)
+ struct ath_hal *hal;
+{
+ return (AR5K_REG_READ(AR5K_AR5211_TSF_L32));
+}
+
+u_int64_t
+ar5k_ar5211_getTsf64(hal)
+ struct ath_hal *hal;
+{
+ u_int64_t tsf = AR5K_REG_READ(AR5K_AR5211_TSF_U32);
+
+ return (AR5K_REG_READ(AR5K_AR5211_TSF_L32) | (tsf << 32));
+}
+
+void
+ar5k_ar5211_resetTsf(hal)
+ struct ath_hal *hal;
+{
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_BEACON,
+ AR5K_AR5211_BEACON_RESET_TSF);
+}
+
+u_int16_t
+ar5k_ar5211_getRegDomain(hal)
+ struct ath_hal *hal;
+{
+ return (ar5k_get_regdomain(hal));
+}
+
+HAL_BOOL
+ar5k_ar5211_detectCardPresent(hal)
+ struct ath_hal *hal;
+{
+ u_int16_t magic;
+
+ /*
+ * Checking the EEPROM's magic value could be an indication
+ * if the card is still present. I didn't find another suitable
+ * way to do this.
+ */
+ if (ar5k_ar5211_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
+ return (AH_FALSE);
+
+ return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
+}
+
+void
+ar5k_ar5211_updateMibCounters(hal, statistics)
+ struct ath_hal *hal;
+ HAL_MIB_STATS *statistics;
+{
+ statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5211_ACK_FAIL);
+ statistics->rts_bad += AR5K_REG_READ(AR5K_AR5211_RTS_FAIL);
+ statistics->rts_good += AR5K_REG_READ(AR5K_AR5211_RTS_OK);
+ statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5211_FCS_FAIL);
+ statistics->beacons += AR5K_REG_READ(AR5K_AR5211_BEACON_CNT);
+}
+
+HAL_RFGAIN
+ar5k_ar5211_getRfGain(hal)
+ struct ath_hal *hal;
+{
+ return (HAL_RFGAIN_INACTIVE);
+}
+
+HAL_BOOL
+ar5k_ar5211_setSlotTime(hal, slot_time)
+ struct ath_hal *hal;
+ u_int slot_time;
+{
+ if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
+ return (AH_FALSE);
+
+ AR5K_REG_WRITE(AR5K_AR5211_DCU_GBL_IFS_SLOT,
+ ar5k_htoclock(slot_time, hal->ah_turbo));
+
+ return (AH_TRUE);
+}
+
+u_int
+ar5k_ar5211_getSlotTime(hal)
+ struct ath_hal *hal;
+{
+ return (ar5k_clocktoh(AR5K_REG_READ(AR5K_AR5211_DCU_GBL_IFS_SLOT) &
+ 0xffff, hal->ah_turbo));
+}
+
+HAL_BOOL
+ar5k_ar5211_setAckTimeout(hal, timeout)
+ struct ath_hal *hal;
+ u_int timeout;
+{
+ if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5211_TIME_OUT_ACK),
+ hal->ah_turbo) <= timeout)
+ return (AH_FALSE);
+
+ AR5K_REG_WRITE_BITS(AR5K_AR5211_TIME_OUT, AR5K_AR5211_TIME_OUT_ACK,
+ ar5k_htoclock(timeout, hal->ah_turbo));
+
+ return (AH_TRUE);
+}
+
+u_int
+ar5k_ar5211_getAckTimeout(hal)
+ struct ath_hal *hal;
+{
+ return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5211_TIME_OUT),
+ AR5K_AR5211_TIME_OUT_ACK), hal->ah_turbo));
+}
+
+HAL_BOOL
+ar5k_ar5211_setCTSTimeout(hal, timeout)
+ struct ath_hal *hal;
+ u_int timeout;
+{
+ if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5211_TIME_OUT_CTS),
+ hal->ah_turbo) <= timeout)
+ return (AH_FALSE);
+
+ AR5K_REG_WRITE_BITS(AR5K_AR5211_TIME_OUT, AR5K_AR5211_TIME_OUT_CTS,
+ ar5k_htoclock(timeout, hal->ah_turbo));
+
+ return (AH_TRUE);
+}
+
+u_int
+ar5k_ar5211_getCTSTimeout(hal)
+ struct ath_hal *hal;
+{
+ return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5211_TIME_OUT),
+ AR5K_AR5211_TIME_OUT_CTS), hal->ah_turbo));
+}
+
+/*
+ * Key table (WEP) functions
+ */
+
+HAL_BOOL
+ar5k_ar5211_isHwCipherSupported(hal, cipher)
+ struct ath_hal *hal;
+ HAL_CIPHER cipher;
+{
+ /*
+ * The AR5211 only supports WEP
+ */
+ if (cipher == HAL_CIPHER_WEP)
+ return (AH_TRUE);
+
+ return (AH_FALSE);
+}
+
+u_int32_t
+ar5k_ar5211_getKeyCacheSize(hal)
+ struct ath_hal *hal;
+{
+ return (AR5K_AR5211_KEYTABLE_SIZE);
+}
+
+HAL_BOOL
+ar5k_ar5211_resetKeyCacheEntry(hal, entry)
+ struct ath_hal *hal;
+ u_int16_t entry;
+{
+ int i;
+
+ AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_KEYTABLE_SIZE);
+
+ for (i = 0; i < AR5K_AR5211_KEYCACHE_SIZE; i++)
+ AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE(entry) + (i * 4), 0);
+
+ return (AH_FALSE);
+}
+
+HAL_BOOL
+ar5k_ar5211_isKeyCacheEntryValid(hal, entry)
+ struct ath_hal *hal;
+ u_int16_t entry;
+{
+ int offset;
+
+ AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_KEYTABLE_SIZE);
+
+ /*
+ * Check the validation flag at the end of the entry
+ */
+ offset = (AR5K_AR5211_KEYCACHE_SIZE - 1) * 4;
+ if (AR5K_REG_READ(AR5K_AR5211_KEYTABLE(entry) + offset) &
+ AR5K_AR5211_KEYTABLE_VALID)
+ return AH_TRUE;
+
+ return (AH_FALSE);
+}
+
+HAL_BOOL
+ar5k_ar5211_setKeyCacheEntry(hal, entry, keyval, mac, xor_notused)
+ struct ath_hal *hal;
+ u_int16_t entry;
+ const HAL_KEYVAL *keyval;
+ const u_int8_t *mac;
+ int xor_notused;
+{
+ int elements = AR5K_AR5211_KEYCACHE_SIZE - 2;
+ u_int32_t key_v[elements];
+ int i, offset = 0;
+
+ AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_KEYTABLE_SIZE);
+
+ /*
+ * Store the key type in the last field
+ */
+ switch (keyval->wk_len) {
+ case 5:
+ key_v[elements - 1] = AR5K_AR5211_KEYTABLE_TYPE_40;
+ break;
+
+ case 13:
+ key_v[elements - 1] = AR5K_AR5211_KEYTABLE_TYPE_104;
+ break;
+
+ case 16:
+ key_v[elements - 1] = AR5K_AR5211_KEYTABLE_TYPE_128;
+ break;
+
+ default:
+ /* Unsupported key length (not WEP40/104/128) */
+ return (AH_FALSE);
+ }
+
+ /*
+ * Write key cache entry
+ */
+ for (i = 0; i < elements; i++) {
+ if (elements < 5) {
+ if (i % 2) {
+ key_v[i] = AR5K_LE_READ_2(keyval->wk_key +
+ offset) & 0xffff;
+ offset += 2;
+ } else {
+ key_v[i] = AR5K_LE_READ_4(keyval->wk_key +
+ offset);
+ offset += 4;
+ }
+
+ if (i == 4 && keyval->wk_len <= 13)
+ key_v[i] &= 0xff;
+ }
+
+ /* Write value */
+ AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE(entry) + (i * 4), key_v[i]);
+ }
+
+ return (ar5k_ar5211_setKeyCacheEntryMac(hal, entry, mac));
+}
+
+HAL_BOOL
+ar5k_ar5211_setKeyCacheEntryMac(hal, entry, mac)
+ struct ath_hal *hal;
+ u_int16_t entry;
+ const u_int8_t *mac;
+{
+ u_int32_t low_id, high_id;
+ int offset;
+
+ /*
+ * Invalid entry (key table overflow)
+ */
+ AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_KEYTABLE_SIZE);
+
+ offset = AR5K_AR5211_KEYCACHE_SIZE - 2;
+
+ /* XXX big endian problems? */
+ bcopy(mac, &low_id, 4);
+ bcopy(mac + 4, &high_id, 2);
+
+ high_id = 0x0000ffff & htole32(high_id);
+
+ AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE(entry) + (offset++ * 4),
+ htole32(low_id));
+ AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE(entry) + (offset * 4), high_id);
+
+ return (AH_TRUE);
+}
+
+/*
+ * Power management functions
+ */
+
+HAL_BOOL
+ar5k_ar5211_setPowerMode(hal, mode, set_chip, sleep_duration)
+ struct ath_hal *hal;
+ HAL_POWER_MODE mode;
+ HAL_BOOL set_chip;
+ u_int16_t sleep_duration;
+{
+ int i;
+
+ switch (mode) {
+ case HAL_PM_AUTO:
+ if (set_chip == AH_TRUE) {
+ AR5K_REG_WRITE(AR5K_AR5211_SCR,
+ AR5K_AR5211_SCR_SLE | sleep_duration);
+ }
+ break;
+
+ case HAL_PM_FULL_SLEEP:
+ if (set_chip == AH_TRUE) {
+ AR5K_REG_WRITE(AR5K_AR5211_SCR,
+ AR5K_AR5211_SCR_SLE_SLP);
+ }
+ break;
+
+ case HAL_PM_AWAKE:
+ if (set_chip == AH_FALSE)
+ goto commit;
+
+ AR5K_REG_WRITE(AR5K_AR5211_SCR, AR5K_AR5211_SCR_SLE_WAKE);
+
+ for (i = 5000; i > 0; i--) {
+ /* Check if the AR5211 did wake up */
+ if ((AR5K_REG_READ(AR5K_AR5211_PCICFG) &
+ AR5K_AR5211_PCICFG_SPWR_DN) == 0)
+ break;
+
+ /* Wait a bit and retry */
+ AR5K_DELAY(200);
+ AR5K_REG_WRITE(AR5K_AR5211_SCR,
+ AR5K_AR5211_SCR_SLE_WAKE);
+ }
+
+ /* Fail if the AR5211 didn't wake up */
+ if (i <= 0)
+ return (AH_FALSE);
+ break;
+
+ case HAL_PM_NETWORK_SLEEP:
+ case HAL_PM_UNDEFINED:
+ default:
+ return (AH_FALSE);
+ }
+
+ commit:
+ hal->ah_power_mode = mode;
+
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,
+ AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA);
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_STA_ID1,
+ AR5K_AR5211_STA_ID1_PWR_SV);
+
+ return (AH_TRUE);
+}
+
+HAL_POWER_MODE
+ar5k_ar5211_getPowerMode(hal)
+ struct ath_hal *hal;
+{
+ return (hal->ah_power_mode);
+}
+
+HAL_BOOL
+ar5k_ar5211_queryPSPollSupport(hal)
+ struct ath_hal *hal;
+{
+ /* nope */
+ return (AH_FALSE);
+}
+
+HAL_BOOL
+ar5k_ar5211_initPSPoll(hal)
+ struct ath_hal *hal;
+{
+ /*
+ * Not used on the AR5211
+ */
+ return (AH_FALSE);
+}
+
+HAL_BOOL
+ar5k_ar5211_enablePSPoll(hal, bssid, assoc_id)
+ struct ath_hal *hal;
+ u_int8_t *bssid;
+ u_int16_t assoc_id;
+{
+ return (AH_FALSE);
+}
+
+HAL_BOOL
+ar5k_ar5211_disablePSPoll(hal)
+ struct ath_hal *hal;
+{
+ return (AH_FALSE);
+}
+
+/*
+ * Beacon functions
+ */
+
+void
+ar5k_ar5211_beaconInit(hal, next_beacon, interval)
+ struct ath_hal *hal;
+ u_int32_t next_beacon;
+ u_int32_t interval;
+{
+ u_int32_t timer1, timer2, timer3;
+
+ /*
+ * Set the additional timers by mode
+ */
+ switch (hal->ah_op_mode) {
+ case HAL_M_STA:
+ timer1 = 0x0000ffff;
+ timer2 = 0x0007ffff;
+ break;
+
+ default:
+ timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<
+ 0x00000003;
+ timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<
+ 0x00000003;
+ }
+
+ timer3 = next_beacon +
+ (hal->ah_atim_window ? hal->ah_atim_window : 1);
+
+ /*
+ * Enable all timers and set the beacon register
+ * (next beacon, DMA beacon, software beacon, ATIM window time)
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_TIMER0, next_beacon);
+ AR5K_REG_WRITE(AR5K_AR5211_TIMER1, timer1);
+ AR5K_REG_WRITE(AR5K_AR5211_TIMER2, timer2);
+ AR5K_REG_WRITE(AR5K_AR5211_TIMER3, timer3);
+
+ AR5K_REG_WRITE(AR5K_AR5211_BEACON, interval &
+ (AR5K_AR5211_BEACON_PERIOD | AR5K_AR5211_BEACON_RESET_TSF |
+ AR5K_AR5211_BEACON_ENABLE));
+}
+
+void
+ar5k_ar5211_setStationBeaconTimers(hal, state, tsf, dtim_count, cfp_count)
+ struct ath_hal *hal;
+ const HAL_BEACON_STATE *state;
+ u_int32_t tsf;
+ u_int32_t dtim_count;
+ u_int32_t cfp_count;
+
+{
+ u_int32_t cfp_period, next_cfp;
+
+ /* Return on an invalid beacon state */
+ if (state->bs_interval < 1)
+ return;
+
+ /*
+ * PCF support?
+ */
+ if (state->bs_cfp_period > 0) {
+ /* Enable CFP mode and set the CFP and timer registers */
+ cfp_period = state->bs_cfp_period * state->bs_dtim_period *
+ state->bs_interval;
+ next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
+ state->bs_interval;
+
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,
+ AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA |
+ AR5K_AR5211_STA_ID1_PCF);
+ AR5K_REG_WRITE(AR5K_AR5211_CFP_PERIOD, cfp_period);
+ AR5K_REG_WRITE(AR5K_AR5211_CFP_DUR, state->bs_cfp_max_duration);
+ AR5K_REG_WRITE(AR5K_AR5211_TIMER2,
+ (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
+ } else {
+ /* Disable PCF mode */
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,
+ AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA |
+ AR5K_AR5211_STA_ID1_PCF);
+ }
+
+ /*
+ * Enable the beacon timer register
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_TIMER0, state->bs_next_beacon);
+
+ /*
+ * Start the beacon timers
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_BEACON,
+ (AR5K_REG_READ(AR5K_AR5211_BEACON) &~
+ (AR5K_AR5211_BEACON_PERIOD | AR5K_AR5211_BEACON_TIM)) |
+ AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
+ AR5K_AR5211_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
+ AR5K_AR5211_BEACON_PERIOD));
+
+ /*
+ * Write new beacon miss threshold, if it appears to be valid
+ */
+ if ((state->bs_bmiss_threshold > (AR5K_AR5211_RSSI_THR_BMISS >>
+ AR5K_AR5211_RSSI_THR_BMISS_S)) &&
+ (state->bs_bmiss_threshold & 0x00007) != 0) {
+ AR5K_REG_WRITE_BITS(AR5K_AR5211_RSSI_THR_M,
+ AR5K_AR5211_RSSI_THR_BMISS, state->bs_bmiss_threshold);
+ }
+}
+
+void
+ar5k_ar5211_resetStationBeaconTimers(hal)
+ struct ath_hal *hal;
+{
+ /*
+ * Disable beacon timer
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_TIMER0, 0);
+
+ /*
+ * Disable some beacon register values
+ */
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,
+ AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5211_STA_ID1_PCF);
+ AR5K_REG_WRITE(AR5K_AR5211_BEACON, AR5K_AR5211_BEACON_PERIOD);
+}
+
+HAL_BOOL
+ar5k_ar5211_waitForBeaconDone(hal, phys_addr)
+ struct ath_hal *hal;
+ bus_addr_t phys_addr;
+{
+ HAL_BOOL ret;
+
+ /*
+ * Wait for beaconn queue to be done
+ */
+ ret = ar5k_register_timeout(hal,
+ AR5K_AR5211_QCU_STS(HAL_TX_QUEUE_BEACON),
+ AR5K_AR5211_QCU_STS_FRMPENDCNT, 0, AH_FALSE);
+
+ return (ret);
+}
+
+/*
+ * Interrupt handling
+ */
+
+HAL_BOOL
+ar5k_ar5211_isInterruptPending(hal)
+ struct ath_hal *hal;
+{
+ return (AR5K_REG_READ(AR5K_AR5211_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar5211_getPendingInterrupts(hal, interrupt_mask)
+ struct ath_hal *hal;
+ u_int32_t *interrupt_mask;
+{
+ u_int32_t data;
+
+ /*
+ * Read interrupt status from the Read-And-Clear shadow register
+ */
+ data = AR5K_REG_READ(AR5K_AR5211_RAC_PISR);
+
+ /*
+ * Get abstract interrupt mask (HAL-compatible)
+ */
+ *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
+
+ if (data == HAL_INT_NOCARD)
+ return (AH_FALSE);
+
+ if (data & (AR5K_AR5211_PISR_RXOK | AR5K_AR5211_PISR_RXERR))
+ *interrupt_mask |= HAL_INT_RX;
+
+ if (data & (AR5K_AR5211_PISR_TXOK | AR5K_AR5211_PISR_TXERR))
+ *interrupt_mask |= HAL_INT_TX;
+
+ if (data & (AR5K_AR5211_PISR_HIUERR))
+ *interrupt_mask |= HAL_INT_FATAL;
+
+ /*
+ * Special interrupt handling (not catched by the driver)
+ */
+ if (((*interrupt_mask) & AR5K_AR5211_PISR_RXPHY) &&
+ hal->ah_radar.r_enabled == AH_TRUE)
+ ar5k_radar_alert(hal);
+
+ return (AH_TRUE);
+}
+
+u_int32_t
+ar5k_ar5211_getInterrupts(hal)
+ struct ath_hal *hal;
+{
+ /* Return the interrupt mask stored previously */
+ return (hal->ah_imr);
+}
+
+HAL_INT
+ar5k_ar5211_setInterrupts(hal, new_mask)
+ struct ath_hal *hal;
+ HAL_INT new_mask;
+{
+ HAL_INT old_mask, int_mask;
+
+ /*
+ * Disable card interrupts to prevent any race conditions
+ * (they will be re-enabled afterwards).
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_DISABLE);
+
+ old_mask = hal->ah_imr;
+
+ /*
+ * Add additional, chipset-dependent interrupt mask flags
+ * and write them to the IMR (interrupt mask register).
+ */
+ int_mask = new_mask & HAL_INT_COMMON;
+
+ if (new_mask & HAL_INT_RX)
+ int_mask |=
+ AR5K_AR5211_PIMR_RXOK |
+ AR5K_AR5211_PIMR_RXERR |
+ AR5K_AR5211_PIMR_RXORN |
+ AR5K_AR5211_PIMR_RXDESC;
+
+ if (new_mask & HAL_INT_TX)
+ int_mask |=
+ AR5K_AR5211_PIMR_TXOK |
+ AR5K_AR5211_PIMR_TXERR |
+ AR5K_AR5211_PIMR_TXDESC |
+ AR5K_AR5211_PIMR_TXURN;
+
+ if (new_mask & HAL_INT_FATAL) {
+ int_mask |= AR5K_AR5211_PIMR_HIUERR;
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_SIMR2,
+ AR5K_AR5211_SIMR2_MCABT |
+ AR5K_AR5211_SIMR2_SSERR |
+ AR5K_AR5211_SIMR2_DPERR);
+ }
+
+ if (hal->ah_op_mode & HAL_M_HOSTAP) {
+ int_mask |= AR5K_AR5211_PIMR_MIB;
+ } else {
+ int_mask &= ~AR5K_AR5211_PIMR_MIB;
+ }
+
+ AR5K_REG_WRITE(AR5K_AR5211_PIMR, int_mask);
+
+ /* Store new interrupt mask */
+ hal->ah_imr = new_mask;
+
+ /* ..re-enable interrupts */
+ AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_ENABLE);
+
+ return (old_mask);
+}
+
+/*
+ * Misc internal functions
+ */
+
+HAL_BOOL
+ar5k_ar5211_get_capabilities(hal)
+ struct ath_hal *hal;
+{
+ u_int16_t ee_header;
+
+ /* Capabilities stored in the EEPROM */
+ ee_header = hal->ah_capabilities.cap_eeprom.ee_header;
+
+ /*
+ * XXX The AR5211 tranceiver supports frequencies from 4920 to 6100GHz
+ * XXX and from 2312 to 2732GHz. There are problems with the current
+ * XXX ieee80211 implementation because the IEEE channel mapping
+ * XXX does not support negative channel numbers (2312MHz is channel
+ * XXX -19). Of course, this doesn't matter because these channels
+ * XXX are out of range but some regulation domains like MKK (Japan)
+ * XXX will support frequencies somewhere around 4.8GHz.
+ */
+
+ /*
+ * Set radio capabilities
+ */
+
+ if (AR5K_EEPROM_HDR_11A(ee_header)) {
+ hal->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
+ hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
+
+ /* Set supported modes */
+ hal->ah_capabilities.cap_mode = HAL_MODE_11A | HAL_MODE_TURBO;
+ }
+
+ /* This chip will support 802.11b if the 2GHz radio is connected */
+ if (AR5K_EEPROM_HDR_11B(ee_header) || AR5K_EEPROM_HDR_11G(ee_header)) {
+ hal->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
+ hal->ah_capabilities.cap_range.range_2ghz_max = 2732;
+ hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
+
+ if (AR5K_EEPROM_HDR_11B(ee_header))
+ hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
+ if (AR5K_EEPROM_HDR_11G(ee_header))
+ hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
+ }
+
+ /* GPIO */
+ hal->ah_gpio_npins = AR5K_AR5211_NUM_GPIO;
+
+ /* Set number of supported TX queues */
+ hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5211_TX_NUM_QUEUES;
+
+ return (AH_TRUE);
+}
+
+void
+ar5k_ar5211_radar_alert(hal, enable)
+ struct ath_hal *hal;
+ HAL_BOOL enable;
+{
+ /*
+ * Enable radar detection
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_DISABLE);
+
+ if (enable == AH_TRUE) {
+ AR5K_REG_WRITE(AR5K_AR5211_PHY_RADAR,
+ AR5K_AR5211_PHY_RADAR_ENABLE);
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PIMR,
+ AR5K_AR5211_PIMR_RXPHY);
+ } else {
+ AR5K_REG_WRITE(AR5K_AR5211_PHY_RADAR,
+ AR5K_AR5211_PHY_RADAR_DISABLE);
+ AR5K_REG_DISABLE_BITS(AR5K_AR5211_PIMR,
+ AR5K_AR5211_PIMR_RXPHY);
+ }
+
+ AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_ENABLE);
+}
+
+/*
+ * EEPROM access functions
+ */
+
+HAL_BOOL
+ar5k_ar5211_eeprom_is_busy(hal)
+ struct ath_hal *hal;
+{
+ return (AR5K_REG_READ(AR5K_AR5211_CFG) & AR5K_AR5211_CFG_EEBS ?
+ AH_TRUE : AH_FALSE);
+}
+
+int
+ar5k_ar5211_eeprom_read(hal, offset, data)
+ struct ath_hal *hal;
+ u_int32_t offset;
+ u_int16_t *data;
+{
+ u_int32_t status, i;
+
+ /*
+ * Initialize EEPROM access
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_EEPROM_BASE, (u_int8_t)offset);
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_EEPROM_CMD,
+ AR5K_AR5211_EEPROM_CMD_READ);
+
+ for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
+ status = AR5K_REG_READ(AR5K_AR5211_EEPROM_STATUS);
+ if (status & AR5K_AR5211_EEPROM_STAT_RDDONE) {
+ if (status & AR5K_AR5211_EEPROM_STAT_RDERR)
+ return (EIO);
+ *data = (u_int16_t)
+ (AR5K_REG_READ(AR5K_AR5211_EEPROM_DATA) & 0xffff);
+ return (0);
+ }
+ AR5K_DELAY(15);
+ }
+
+ return (ETIMEDOUT);
+}
+
+int
+ar5k_ar5211_eeprom_write(hal, offset, data)
+ struct ath_hal *hal;
+ u_int32_t offset;
+ u_int16_t data;
+{
+ u_int32_t status, timeout;
+
+ /* Enable eeprom access */
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_EEPROM_CMD,
+ AR5K_AR5211_EEPROM_CMD_RESET);
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_EEPROM_CMD,
+ AR5K_AR5211_EEPROM_CMD_WRITE);
+
+ /*
+ * Prime write pump
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_EEPROM_BASE, (u_int8_t)offset - 1);
+
+ for (timeout = 10000; timeout > 0; timeout--) {
+ AR5K_DELAY(1);
+ status = AR5K_REG_READ(AR5K_AR5211_EEPROM_STATUS);
+ if (status & AR5K_AR5211_EEPROM_STAT_WRDONE) {
+ if (status & AR5K_AR5211_EEPROM_STAT_WRERR)
+ return (EIO);
+ return (0);
+ }
+ }
+
+ return (ETIMEDOUT);
+}
diff --git a/sys/dev/ic/ar5211reg.h b/sys/dev/ic/ar5211reg.h
new file mode 100644
index 00000000000..febf1bd8009
--- /dev/null
+++ b/sys/dev/ic/ar5211reg.h
@@ -0,0 +1,1033 @@
+/* $OpenBSD: ar5211reg.h,v 1.1 2005/02/25 22:25:30 reyk Exp $ */
+
+/*
+ * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * 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.
+ */
+
+/*
+ * Known registers of the Atheros AR5001 Wireless LAN chipsets
+ * (AR5211/AR5311).
+ */
+
+#ifndef _AR5K_AR5211_REG_H
+#define _AR5K_AR5211_REG_H
+
+/*
+ * Command register
+ */
+#define AR5K_AR5211_CR 0x0008
+#define AR5K_AR5211_CR_RXE 0x00000004
+#define AR5K_AR5211_CR_RXD 0x00000020
+#define AR5K_AR5211_CR_SWI 0x00000040
+
+/*
+ * Receive queue descriptor pointer register
+ */
+#define AR5K_AR5211_RXDP 0x000c
+
+/*
+ * Configuration and status register
+ */
+#define AR5K_AR5211_CFG 0x0014
+#define AR5K_AR5211_CFG_SWTD 0x00000001
+#define AR5K_AR5211_CFG_SWTB 0x00000002
+#define AR5K_AR5211_CFG_SWRD 0x00000004
+#define AR5K_AR5211_CFG_SWRB 0x00000008
+#define AR5K_AR5211_CFG_SWRG 0x00000010
+#define AR5K_AR5211_CFG_ADHOC 0x00000020
+#define AR5K_AR5211_CFG_PHY_OK 0x00000100
+#define AR5K_AR5211_CFG_EEBS 0x00000200
+#define AR5K_AR5211_CFG_CLKGD 0x00000400
+#define AR5K_AR5211_CFG_PCI_THRES 0x00060000
+#define AR5K_AR5211_CFG_PCI_THRES_S 17
+
+/*
+ * Interrupt enable register
+ */
+#define AR5K_AR5211_IER 0x0024
+#define AR5K_AR5211_IER_DISABLE 0x00000000
+#define AR5K_AR5211_IER_ENABLE 0x00000001
+
+/*
+ * First RTS duration register
+ */
+#define AR5K_AR5211_RTSD0 0x0028
+#define AR5K_AR5211_RTSD0_6 0x000000ff
+#define AR5K_AR5211_RTSD0_6_S 0
+#define AR5K_AR5211_RTSD0_9 0x0000ff00
+#define AR5K_AR5211_RTSD0_9_S 8
+#define AR5K_AR5211_RTSD0_12 0x00ff0000
+#define AR5K_AR5211_RTSD0_12_S 16
+#define AR5K_AR5211_RTSD0_18 0xff000000
+#define AR5K_AR5211_RTSD0_18_S 24
+
+/*
+ * Second RTS duration register
+ */
+#define AR5K_AR5211_RTSD1 0x002c
+#define AR5K_AR5211_RTSD1_24 0x000000ff
+#define AR5K_AR5211_RTSD1_24_S 0
+#define AR5K_AR5211_RTSD1_36 0x0000ff00
+#define AR5K_AR5211_RTSD1_36_S 8
+#define AR5K_AR5211_RTSD1_48 0x00ff0000
+#define AR5K_AR5211_RTSD1_48_S 16
+#define AR5K_AR5211_RTSD1_54 0xff000000
+#define AR5K_AR5211_RTSD1_54_S 24
+
+/*
+ * Transmit configuration register
+ */
+#define AR5K_AR5211_TXCFG 0x0030
+#define AR5K_AR5211_TXCFG_SDMAMR 0x00000007
+#define AR5K_AR5211_TXCFG_B_MODE 0x00000008
+#define AR5K_AR5211_TXCFG_TXFULL 0x000003f0
+#define AR5K_AR5211_TXCFG_TXFULL_S 4
+#define AR5K_AR5211_TXCFG_TXFULL_0B 0x00000000
+#define AR5K_AR5211_TXCFG_TXFULL_64B 0x00000010
+#define AR5K_AR5211_TXCFG_TXFULL_128B 0x00000020
+#define AR5K_AR5211_TXCFG_TXFULL_192B 0x00000030
+#define AR5K_AR5211_TXCFG_TXFULL_256B 0x00000040
+#define AR5K_AR5211_TXCFG_TXCONT_ENABLE 0x00000080
+#define AR5K_AR5211_TXCFG_JUMBO_TXE 0x00000400
+#define AR5K_AR5211_TXCFG_RTSRND 0x00001000
+#define AR5K_AR5211_TXCFG_FRMPAD_DIS 0x00002000
+#define AR5K_AR5211_TXCFG_RDY_DIS 0x00004000
+
+/*
+ * Receive configuration register
+ */
+#define AR5K_AR5211_RXCFG 0x0034
+#define AR5K_AR5211_RXCFG_SDMAMW 0x00000007
+#define AR5K_AR5311_RXCFG_DEFAULT_ANTENNA 0x00000008
+#define AR5K_AR5211_RXCFG_ZLFDMA 0x00000010
+#define AR5K_AR5211_RXCFG_JUMBO_RXE 0x00000020
+#define AR5K_AR5211_RXCFG_JUMBO_WRAP 0x00000040
+
+/*
+ * Receive jumbo descriptor last address register
+ */
+#define AR5K_AR5211_RXJLA 0x0038
+
+/*
+ * MIB control register
+ */
+#define AR5K_AR5211_MIBC 0x0040
+#define AR5K_AR5211_MIBC_COW 0x00000001
+#define AR5K_AR5211_MIBC_FMC 0x00000002
+#define AR5K_AR5211_MIBC_CMC 0x00000004
+#define AR5K_AR5211_MIBC_MCS 0x00000008
+
+/*
+ * Timeout prescale register
+ */
+#define AR5K_AR5211_TOPS 0x0044
+#define AR5K_AR5211_TOPS_M 0x0000ffff
+
+/*
+ * Receive timeout register (no frame received)
+ */
+#define AR5K_AR5211_RXNOFRM 0x0048
+#define AR5K_AR5211_RXNOFRM_M 0x000003ff
+
+/*
+ * Transmit timeout register (no frame sent)
+ */
+#define AR5K_AR5211_TXNOFRM 0x004c
+#define AR5K_AR5211_TXNOFRM_M 0x000003ff
+#define AR5K_AR5211_TXNOFRM_QCU 0x000ffc00
+
+/*
+ * Receive frame gap timeout register
+ */
+#define AR5K_AR5211_RPGTO 0x0050
+#define AR5K_AR5211_RPGTO_M 0x000003ff
+
+/*
+ * Receive frame count limit register
+ */
+#define AR5K_AR5211_RFCNT 0x0054
+#define AR5K_AR5211_RFCNT_M 0x0000001f
+
+/*
+ * Misc settings register
+ */
+#define AR5K_AR5211_MISC 0x0058
+#define AR5K_AR5211_MISC_DMA_OBS_M 0x000001e0
+#define AR5K_AR5211_MISC_DMA_OBS_S 5
+#define AR5K_AR5211_MISC_MISC_OBS_M 0x00000e00
+#define AR5K_AR5211_MISC_MISC_OBS_S 9
+#define AR5K_AR5211_MISC_MAC_OBS_LSB_M 0x00007000
+#define AR5K_AR5211_MISC_MAC_OBS_LSB_S 12
+#define AR5K_AR5211_MISC_MAC_OBS_MSB_M 0x00038000
+#define AR5K_AR5211_MISC_MAC_OBS_MSB_S 15
+
+/*
+ * QCU/DCU clock gating register
+ */
+#define AR5K_AR5311_QCUDCU_CLKGT
+#define AR5K_AR5311_QCUDCU_CLKGT_QCU 0x0000ffff
+#define AR5K_AR5311_QCUDCU_CLKGT_DCU 0x07ff0000
+
+/*
+ * Primary interrupt status register
+ */
+#define AR5K_AR5211_PISR 0x0080
+#define AR5K_AR5211_PISR_RXOK 0x00000001
+#define AR5K_AR5211_PISR_RXDESC 0x00000002
+#define AR5K_AR5211_PISR_RXERR 0x00000004
+#define AR5K_AR5211_PISR_RXNOFRM 0x00000008
+#define AR5K_AR5211_PISR_RXEOL 0x00000010
+#define AR5K_AR5211_PISR_RXORN 0x00000020
+#define AR5K_AR5211_PISR_TXOK 0x00000040
+#define AR5K_AR5211_PISR_TXDESC 0x00000080
+#define AR5K_AR5211_PISR_TXERR 0x00000100
+#define AR5K_AR5211_PISR_TXNOFRM 0x00000200
+#define AR5K_AR5211_PISR_TXEOL 0x00000400
+#define AR5K_AR5211_PISR_TXURN 0x00000800
+#define AR5K_AR5211_PISR_MIB 0x00001000
+#define AR5K_AR5211_PISR_SWI 0x00002000
+#define AR5K_AR5211_PISR_RXPHY 0x00004000
+#define AR5K_AR5211_PISR_RXKCM 0x00008000
+#define AR5K_AR5211_PISR_SWBA 0x00010000
+#define AR5K_AR5211_PISR_BRSSI 0x00020000
+#define AR5K_AR5211_PISR_BMISS 0x00040000
+#define AR5K_AR5211_PISR_HIUERR 0x00080000
+#define AR5K_AR5211_PISR_BNR 0x00100000
+#define AR5K_AR5211_PISR_TIM 0x00800000
+#define AR5K_AR5211_PISR_GPIO 0x01000000
+#define AR5K_AR5211_PISR_QCBRORN 0x02000000
+#define AR5K_AR5211_PISR_QCBRURN 0x04000000
+#define AR5K_AR5211_PISR_QTRIG 0x08000000
+
+/*
+ * Secondary interrupt status registers (0 - 4)
+ */
+#define AR5K_AR5211_SISR0 0x0084
+#define AR5K_AR5211_SISR0_QCU_TXOK 0x000003ff
+#define AR5K_AR5211_SISR0_QCU_TXDESC 0x03ff0000
+
+#define AR5K_AR5211_SISR1 0x0088
+#define AR5K_AR5211_SISR1_QCU_TXERR 0x000003ff
+#define AR5K_AR5211_SISR1_QCU_TXEOL 0x03ff0000
+
+#define AR5K_AR5211_SISR2 0x008c
+#define AR5K_AR5211_SISR2_QCU_TXURN 0x000003ff
+#define AR5K_AR5211_SISR2_MCABT 0x00100000
+#define AR5K_AR5211_SISR2_SSERR 0x00200000
+#define AR5K_AR5211_SISR2_DPERR 0x00400000
+
+#define AR5K_AR5211_SISR3 0x0090
+#define AR5K_AR5211_SISR3_QCBRORN 0x000003ff
+#define AR5K_AR5211_SISR3_QCBRURN 0x03ff0000
+
+#define AR5K_AR5211_SISR4 0x0094
+#define AR5K_AR5211_SISR4_QTRIG 0x000003ff
+
+/*
+ * Shadow read-and-clear interrupt status registers
+ */
+#define AR5K_AR5211_RAC_PISR 0x00c0
+#define AR5K_AR5211_RAC_SISR0 0x00c4
+#define AR5K_AR5211_RAC_SISR1 0x00c8
+#define AR5K_AR5211_RAC_SISR2 0x00cc
+#define AR5K_AR5211_RAC_SISR3 0c00d0
+#define AR5K_AR5211_RAC_SISR4 0c00d4
+
+/*
+ * Primary interrupt mask register
+ */
+#define AR5K_AR5211_PIMR 0x00a0
+#define AR5K_AR5211_PIMR_RXOK 0x00000001
+#define AR5K_AR5211_PIMR_RXDESC 0x00000002
+#define AR5K_AR5211_PIMR_RXERR 0x00000004
+#define AR5K_AR5211_PIMR_RXNOFRM 0x00000008
+#define AR5K_AR5211_PIMR_RXEOL 0x00000010
+#define AR5K_AR5211_PIMR_RXORN 0x00000020
+#define AR5K_AR5211_PIMR_TXOK 0x00000040
+#define AR5K_AR5211_PIMR_TXDESC 0x00000080
+#define AR5K_AR5211_PIMR_TXERR 0x00000100
+#define AR5K_AR5211_PIMR_TXNOFRM 0x00000200
+#define AR5K_AR5211_PIMR_TXEOL 0x00000400
+#define AR5K_AR5211_PIMR_TXURN 0x00000800
+#define AR5K_AR5211_PIMR_MIB 0x00001000
+#define AR5K_AR5211_PIMR_SWI 0x00002000
+#define AR5K_AR5211_PIMR_RXPHY 0x00004000
+#define AR5K_AR5211_PIMR_RXKCM 0x00008000
+#define AR5K_AR5211_PIMR_SWBA 0x00010000
+#define AR5K_AR5211_PIMR_BRSSI 0x00020000
+#define AR5K_AR5211_PIMR_BMISS 0x00040000
+#define AR5K_AR5211_PIMR_HIUERR 0x00080000
+#define AR5K_AR5211_PIMR_BNR 0x00100000
+#define AR5K_AR5211_PIMR_TIM 0x00800000
+#define AR5K_AR5211_PIMR_GPIO 0x01000000
+#define AR5K_AR5211_PIMR_QCBRORN 0x02000000
+#define AR5K_AR5211_PIMR_QCBRURN 0x04000000
+#define AR5K_AR5211_PIMR_QTRIG 0x08000000
+
+/*
+ * Secondary interrupt mask registers (0 - 4)
+ */
+#define AR5K_AR5211_SIMR0 0x00a4
+#define AR5K_AR5211_SIMR0_QCU_TXOK 0x000003ff
+#define AR5K_AR5211_SIMR0_QCU_TXOK_S 0
+#define AR5K_AR5211_SIMR0_QCU_TXDESC 0x03ff0000
+#define AR5K_AR5211_SIMR0_QCU_TXDESC_S 16
+
+#define AR5K_AR5211_SIMR1 0x00a8
+#define AR5K_AR5211_SIMR1_QCU_TXERR 0x000003ff
+#define AR5K_AR5211_SIMR1_QCU_TXERR_S 0
+#define AR5K_AR5211_SIMR1_QCU_TXEOL 0x03ff0000
+#define AR5K_AR5211_SIMR1_QCU_TXEOL_S 16
+
+#define AR5K_AR5211_SIMR2 0x00ac
+#define AR5K_AR5211_SIMR2_QCU_TXURN 0x000003ff
+#define AR5K_AR5211_SIMR2_QCU_TXURN_S 0
+#define AR5K_AR5211_SIMR2_MCABT 0x00100000
+#define AR5K_AR5211_SIMR2_SSERR 0x00200000
+#define AR5K_AR5211_SIMR2_DPERR 0x00400000
+
+#define AR5K_AR5211_SIMR3 0x00b0
+#define AR5K_AR5211_SIMR3_QCBRORN 0x000003ff
+#define AR5K_AR5211_SIMR3_QCBRORN_S 0
+#define AR5K_AR5211_SIMR3_QCBRURN 0x03ff0000
+#define AR5K_AR5211_SIMR3_QCBRURN_S 16
+
+#define AR5K_AR5211_SIMR4 0x00b4
+#define AR5K_AR5211_SIMR4_QTRIG 0x000003ff
+#define AR5K_AR5211_SIMR4_QTRIG_S 0
+
+/*
+ * Queue control unit (QCU) registers (0 - 9)
+ */
+#define AR5K_AR5211_QCU(_n, _a) (((_n) << 2) + _a)
+
+/*
+ * QCU Transmit descriptor pointer registers
+ */
+#define AR5K_AR5211_QCU_TXDP(_n) AR5K_AR5211_QCU(_n, 0x0800)
+
+/*
+ * QCU Transmit enable register
+ */
+#define AR5K_AR5211_QCU_TXE 0x0840
+
+/*
+ * QCU Transmit disable register
+ */
+#define AR5K_AR5211_QCU_TXD 0x0880
+
+/*
+ * QCU CBR configuration registers
+ */
+#define AR5K_AR5211_QCU_CBRCFG(_n) AR5K_AR5211_QCU(_n, 0x08c0)
+#define AR5K_AR5211_QCU_CBRCFG_INTVAL 0x00ffffff
+#define AR5K_AR5211_QCU_CBRCFG_INTVAL_S 0
+#define AR5K_AR5211_QCU_CBRCFG_ORN_THRES 0xff000000
+#define AR5K_AR5211_QCU_CBRCFG_ORN_THRES_S 24
+
+/*
+ * QCU Ready time configuration registers
+ */
+#define AR5K_AR5211_QCU_RDYTIMECFG(_n) AR5K_AR5211_QCU(_n, 0x0900)
+#define AR5K_AR5211_QCU_RDYTIMECFG_INTVAL 0x00ffffff
+#define AR5K_AR5211_QCU_RDYTIMECFG_INTVAL_S 0
+#define AR5K_AR5211_QCU_RDYTIMECFG_DURATION 0x00ffffff
+#define AR5K_AR5211_QCU_RDYTIMECFG_ENABLE 0x01000000
+
+/*
+ * QCU one shot arm set registers
+ */
+#define AR5K_AR5211_QCU_ONESHOTARMS(_n) AR5K_AR5211_QCU(_n, 0x0940)
+#define AR5K_AR5211_QCU_ONESHOTARMS_M 0x0000ffff
+
+/*
+ * QCU one shot arm clear registers
+ */
+#define AR5K_AR5211_QCU_ONESHOTARMC(_n) AR5K_AR5211_QCU(_n, 0x0980)
+#define AR5K_AR5211_QCU_ONESHOTARMC_M 0x0000ffff
+
+/*
+ * QCU misc registers
+ */
+#define AR5K_AR5211_QCU_MISC(_n) AR5K_AR5211_QCU(_n, 0x09c0)
+#define AR5K_AR5211_QCU_MISC_FRSHED_M 0x0000000f
+#define AR5K_AR5211_QCU_MISC_FRSHED_ASAP 0
+#define AR5K_AR5211_QCU_MISC_FRSHED_CBR 1
+#define AR5K_AR5211_QCU_MISC_FRSHED_DBA_GT 2
+#define AR5K_AR5211_QCU_MISC_FRSHED_TIM_GT 3
+#define AR5K_AR5211_QCU_MISC_FRSHED_BCN_SENT_GT 4
+#define AR5K_AR5211_QCU_MISC_ONESHOT_ENABLE 0x00000010
+#define AR5K_AR5211_QCU_MISC_CBREXP 0x00000020
+#define AR5K_AR5211_QCU_MISC_CBREXP_BCN 0x00000040
+#define AR5K_AR5211_QCU_MISC_BCN_ENABLE 0x00000080
+#define AR5K_AR5211_QCU_MISC_CBR_THRES_ENABLE 0x00000100
+#define AR5K_AR5211_QCU_MISC_TXE 0x00000200
+#define AR5K_AR5211_QCU_MISC_CBR 0x00000400
+#define AR5K_AR5211_QCU_MISC_DCU_EARLY 0x00000800
+
+/*
+ * QCU status registers
+ */
+#define AR5K_AR5211_QCU_STS(_n) AR5K_AR5211_QCU(_n, 0x0a00)
+#define AR5K_AR5211_QCU_STS_FRMPENDCNT 0x00000003
+#define AR5K_AR5211_QCU_STS_CBREXPCNT 0x0000ff00
+
+/*
+ * QCU ready time shutdown register
+ */
+#define AR5K_AR5211_QCU_RDYTIMESHDN 0x0a40
+#define AR5K_AR5211_QCU_RDYTIMESHDN_M 0x000003ff
+
+/*
+ * DCF control unit (DCU) registers (0 - 9)
+ */
+#define AR5K_AR5211_DCU(_n, _a) AR5K_AR5211_QCU(_n, _a)
+
+/*
+ * DCU QCU mask registers
+ */
+#define AR5K_AR5211_DCU_QCUMASK(_n) AR5K_AR5211_DCU(_n, 0x1000)
+#define AR5K_AR5211_DCU_QCUMASK_M 0x000003ff
+
+/*
+ * DCU local IFS settings register
+ */
+#define AR5K_AR5211_DCU_LCL_IFS(_n) AR5K_AR5211_DCU(_n, 0x1040)
+#define AR5K_AR5211_DCU_LCL_IFS_CW_MIN 0x000003ff
+#define AR5K_AR5211_DCU_LCL_IFS_CW_MIN_S 0
+#define AR5K_AR5211_DCU_LCL_IFS_CW_MAX 0x000ffc00
+#define AR5K_AR5211_DCU_LCL_IFS_CW_MAX_S 10
+#define AR5K_AR5211_DCU_LCL_IFS_AIFS 0x0ff00000
+#define AR5K_AR5211_DCU_LCL_IFS_AIFS_S 20
+
+/*
+ * DCU retry limit registers
+ */
+#define AR5K_AR5211_DCU_RETRY_LMT(_n) AR5K_AR5211_DCU(_n, 0x1080)
+#define AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY 0x0000000f
+#define AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY_S 0
+#define AR5K_AR5211_DCU_RETRY_LMT_LG_RETRY 0x000000f0
+#define AR5K_AR5211_DCU_RETRY_LMT_LG_RETRY_S 4
+#define AR5K_AR5211_DCU_RETRY_LMT_SSH_RETRY 0x00003f00
+#define AR5K_AR5211_DCU_RETRY_LMT_SSH_RETRY_S 8
+#define AR5K_AR5211_DCU_RETRY_LMT_SLG_RETRY 0x000fc000
+#define AR5K_AR5211_DCU_RETRY_LMT_SLG_RETRY_S 14
+
+/*
+ * DCU channel time registers
+ */
+#define AR5K_AR5211_DCU_CHAN_TIME(_n) AR5K_AR5211_DCU(_n, 0x10c0)
+#define AR5K_AR5211_DCU_CHAN_TIME_ENABLE 0x00100000
+#define AR5K_AR5211_DCU_CHAN_TIME_DUR 0x000fffff
+#define AR5K_AR5211_DCU_CHAN_TIME_DUR_S 0
+
+/*
+ * DCU misc registers
+ */
+#define AR5K_AR5211_DCU_MISC(_n) AR5K_AR5211_DCU(_n, 0x1100)
+#define AR5K_AR5211_DCU_MISC_BACKOFF 0x000007ff
+#define AR5K_AR5211_DCU_MISC_BACKOFF_FRAG 0x00000200
+#define AR5K_AR5211_DCU_MISC_HCFPOLL_ENABLE 0x00000800
+#define AR5K_AR5211_DCU_MISC_BACKOFF_PERSIST 0x00001000
+#define AR5K_AR5211_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000
+#define AR5K_AR5211_DCU_MISC_VIRTCOL 0x0000c000
+#define AR5K_AR5211_DCU_MISC_VIRTCOL_NORMAL 0
+#define AR5K_AR5211_DCU_MISC_VIRTCOL_MODIFIED 1
+#define AR5K_AR5211_DCU_MISC_VIRTCOL_IGNORE 2
+#define AR5K_AR5211_DCU_MISC_BCN_ENABLE 0x00010000
+#define AR5K_AR5211_DCU_MISC_ARBLOCK_CTL 0x00060000
+#define AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_S 17
+#define AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_NONE 0
+#define AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_INTFRM 1
+#define AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL 2
+#define AR5K_AR5211_DCU_MISC_ARBLOCK_IGNORE 0x00080000
+#define AR5K_AR5211_DCU_MISC_SEQ_NUM_INCR_DIS 0x00100000
+#define AR5K_AR5211_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000
+#define AR5K_AR5211_DCU_MISC_VIRT_COLL_POLICY 0x00400000
+#define AR5K_AR5211_DCU_MISC_BLOWN_IFS_POLICY 0x00800000
+#define AR5K_AR5211_DCU_MISC_SEQNUM_CTL 0x01000000
+
+/*
+ * DCU frame sequence number registers
+ */
+#define AR5K_AR5211_DCU_SEQNUM(_n) AR5K_AR5211_DCU(_n, 0x1140)
+#define AR5K_AR5211_DCU_SEQNUM_M 0x00000fff
+/*
+ * DCU global IFS SIFS registers
+ */
+#define AR5K_AR5211_DCU_GBL_IFS_SIFS 0x1030
+#define AR5K_AR5211_DCU_GBL_IFS_SIFS_M 0x0000ffff
+
+/*
+ * DCU global IFS slot interval registers
+ */
+#define AR5K_AR5211_DCU_GBL_IFS_SLOT 0x1070
+#define AR5K_AR5211_DCU_GBL_IFS_SLOT_M 0x0000ffff
+
+/*
+ * DCU global IFS EIFS registers
+ */
+#define AR5K_AR5211_DCU_GBL_IFS_EIFS 0x10b0
+#define AR5K_AR5211_DCU_GBL_IFS_EIFS_M 0x0000ffff
+
+/*
+ * DCU global IFS misc registers
+ */
+#define AR5K_AR5211_DCU_GBL_IFS_MISC 0x10f0
+#define AR5K_AR5211_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007
+#define AR5K_AR5211_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008
+#define AR5K_AR5211_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0
+#define AR5K_AR5211_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00
+#define AR5K_AR5211_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000
+
+/*
+ * DCU frame prefetch control register
+ */
+#define AR5K_AR5211_DCU_FP 0x1230
+
+/*
+ * DCU transmit pause control/status register
+ */
+#define AR5K_AR5211_DCU_TXP 0x1270
+#define AR5K_AR5211_DCU_TXP_M 0x000003ff
+#define AR5K_AR5211_DCU_TXP_STATUS 0x00010000
+
+/*
+ * DCU transmit filter register
+ */
+#define AR5K_AR5211_DCU_TX_FILTER 0x1038
+
+/*
+ * DCU clear transmit filter register
+ */
+#define AR5K_AR5211_DCU_TX_FILTER_CLR 0x143c
+
+/*
+ * DCU set transmit filter register
+ */
+#define AR5K_AR5211_DCU_TX_FILTER_SET 0x147c
+
+/*
+ * DMA size definitions
+ */
+typedef enum {
+ AR5K_AR5211_DMASIZE_4B = 0,
+ AR5K_AR5211_DMASIZE_8B,
+ AR5K_AR5211_DMASIZE_16B,
+ AR5K_AR5211_DMASIZE_32B,
+ AR5K_AR5211_DMASIZE_64B,
+ AR5K_AR5211_DMASIZE_128B,
+ AR5K_AR5211_DMASIZE_256B,
+ AR5K_AR5211_DMASIZE_512B
+} ar5k_ar5211_dmasize_t;
+
+/*
+ * Reset control register
+ */
+#define AR5K_AR5211_RC 0x4000
+#define AR5K_AR5211_RC_PCU 0x00000001
+#define AR5K_AR5211_RC_BB 0x00000002
+#define AR5K_AR5211_RC_PCI 0x00000010
+#define AR5K_AR5211_RC_CHIP ( \
+ AR5K_AR5211_RC_PCU | AR5K_AR5211_RC_BB | AR5K_AR5211_RC_PCI \
+)
+
+/*
+ * Sleep control register
+ */
+#define AR5K_AR5211_SCR 0x4004
+#define AR5K_AR5211_SCR_SLDUR 0x0000ffff
+#define AR5K_AR5211_SCR_SLE 0x00030000
+#define AR5K_AR5211_SCR_SLE_S 16
+#define AR5K_AR5211_SCR_SLE_WAKE 0x00000000
+#define AR5K_AR5211_SCR_SLE_SLP 0x00010000
+#define AR5K_AR5211_SCR_SLE_ALLOW 0x00020000
+#define AR5K_AR5211_SCR_SLE_UNITS 0x00000008
+
+/*
+ * Interrupt pending register
+ */
+#define AR5K_AR5211_INTPEND 0x4008
+#define AR5K_AR5211_INTPEND_M 0x00000001
+
+/*
+ * Sleep force register
+ */
+#define AR5K_AR5211_SFR 0x400c
+#define AR5K_AR5211_SFR_M 0x00000001
+
+/*
+ * PCI configuration register
+ */
+#define AR5K_AR5211_PCICFG 0x4010
+#define AR5K_AR5211_PCICFG_CLKRUNEN 0x00000004
+#define AR5K_AR5211_PCICFG_EESIZE 0x00000018
+#define AR5K_AR5211_PCICFG_EESIZE_S 3
+#define AR5K_AR5211_PCICFG_EESIZE_4K 0
+#define AR5K_AR5211_PCICFG_EESIZE_8K 1
+#define AR5K_AR5211_PCICFG_EESIZE_16K 2
+#define AR5K_AR5211_PCICFG_EESIZE_FAIL 3
+#define AR5K_AR5211_PCICFG_LED 0x00000060
+#define AR5K_AR5211_PCICFG_LED_NONE 0x00000000
+#define AR5K_AR5211_PCICFG_LED_PEND 0x00000020
+#define AR5K_AR5211_PCICFG_LED_ASSOC 0x00000040
+#define AR5K_AR5211_PCICFG_BUS_SEL 0x00000380
+#define AR5K_AR5211_PCICFG_CBEFIX_DIS 0x00000400
+#define AR5K_AR5211_PCICFG_SL_INTEN 0x00000800
+#define AR5K_AR5211_PCICFG_SL_INPEN 0x00002800
+#define AR5K_AR5211_PCICFG_SPWR_DN 0x00010000
+#define AR5K_AR5211_PCICFG_LEDMODE 0x000e0000
+#define AR5K_AR5211_PCICFG_LEDMODE_PROP 0x00000000
+#define AR5K_AR5211_PCICFG_LEDMODE_PROM 0x00020000
+#define AR5K_AR5211_PCICFG_LEDMODE_PWR 0x00040000
+#define AR5K_AR5211_PCICFG_LEDMODE_RAND 0x00060000
+#define AR5K_AR5211_PCICFG_LEDBLINK 0x00700000
+#define AR5K_AR5211_PCICFG_LEDBLINK_S 20
+#define AR5K_AR5211_PCICFG_LEDSLOW 0x00800000
+
+/*
+ * "General Purpose Input/Output" (GPIO) control register
+ */
+#define AR5K_AR5211_GPIOCR 0x4014
+#define AR5K_AR5211_GPIOCR_INT_ENA 0x00008000
+#define AR5K_AR5211_GPIOCR_INT_SELL 0x00000000
+#define AR5K_AR5211_GPIOCR_INT_SELH 0x00010000
+#define AR5K_AR5211_GPIOCR_NONE(n) (0 << ((n) * 2))
+#define AR5K_AR5211_GPIOCR_OUT0(n) (1 << ((n) * 2))
+#define AR5K_AR5211_GPIOCR_OUT1(n) (2 << ((n) * 2))
+#define AR5K_AR5211_GPIOCR_ALL(n) (3 << ((n) * 2))
+#define AR5K_AR5211_GPIOCR_INT_SEL(n) ((n) << 12)
+
+#define AR5K_AR5211_NUM_GPIO 6
+
+/*
+ * "General Purpose Input/Output" (GPIO) data output register
+ */
+#define AR5K_AR5211_GPIODO 0x4018
+
+/*
+ * "General Purpose Input/Output" (GPIO) data input register
+ */
+#define AR5K_AR5211_GPIODI 0x401c
+#define AR5K_AR5211_GPIODI_M 0x0000002f
+
+/*
+ * Silicon revision register
+ */
+#define AR5K_AR5211_SREV 0x4020
+#define AR5K_AR5211_SREV_M 0x000000ff
+#define AR5K_AR5211_SREV_REVISION 0x0000000f
+#define AR5K_AR5211_SREV_VERSION 0x000000f0
+
+/*
+ * EEPROM access registers
+ */
+#define AR5K_AR5211_EEPROM_BASE 0x6000
+#define AR5K_AR5211_EEPROM_DATA 0x6004
+#define AR5K_AR5211_EEPROM_CMD 0x6008
+#define AR5K_AR5211_EEPROM_CMD_READ 0x00000001
+#define AR5K_AR5211_EEPROM_CMD_WRITE 0x00000002
+#define AR5K_AR5211_EEPROM_CMD_RESET 0x00000004
+#define AR5K_AR5211_EEPROM_STATUS 0x600c
+#define AR5K_AR5211_EEPROM_STAT_RDERR 0x00000001
+#define AR5K_AR5211_EEPROM_STAT_RDDONE 0x00000002
+#define AR5K_AR5211_EEPROM_STAT_WRERR 0x00000004
+#define AR5K_AR5211_EEPROM_STAT_WRDONE 0x00000008
+#define AR5K_AR5211_EEPROM_CFG 0x6010
+
+/*
+ * AR5211 EEPROM data registers
+ */
+#define AR5K_AR5211_EEPROM_MAGIC 0x3d
+#define AR5K_AR5211_EEPROM_MAGIC_VALUE 0x5aa5
+#define AR5K_AR5211_EEPROM_PROTECT 0x3f
+#define AR5K_AR5211_EEPROM_PROTECT_128_191 0x80
+#define AR5K_AR5211_EEPROM_REG_DOMAIN 0xbf
+#define AR5K_AR5211_EEPROM_INFO_BASE 0xc0
+#define AR5K_AR5211_EEPROM_INFO_VERSION \
+ (AR5K_AR5211_EEPROM_INFO_BASE + 1)
+#define AR5K_AR5211_EEPROM_INFO_MAX \
+ (0x400 - AR5K_AR5211_EEPROM_INFO_BASE)
+
+/*
+ * PCU registers
+ */
+
+#define AR5K_AR5211_PCU_MIN 0x8000
+#define AR5K_AR5211_PCU_MAX 0x8fff
+
+/*
+ * First station id register (MAC address in lower 32 bits)
+ */
+#define AR5K_AR5211_STA_ID0 0x8000
+
+/*
+ * Second station id register (MAC address in upper 16 bits)
+ */
+#define AR5K_AR5211_STA_ID1 0x8004
+#define AR5K_AR5211_STA_ID1_AP 0x00010000
+#define AR5K_AR5211_STA_ID1_ADHOC 0x00020000
+#define AR5K_AR5211_STA_ID1_PWR_SV 0x00040000
+#define AR5K_AR5211_STA_ID1_NO_KEYSRCH 0x00080000
+#define AR5K_AR5211_STA_ID1_PCF 0x00100000
+#define AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA 0x00200000
+#define AR5K_AR5211_STA_ID1_DESC_ANTENNA 0x00400000
+#define AR5K_AR5211_STA_ID1_RTS_DEFAULT_ANTENNA 0x00800000
+#define AR5K_AR5211_STA_ID1_ACKCTS_6MB 0x01000000
+#define AR5K_AR5211_STA_ID1_BASE_RATE_11B 0x02000000
+
+/*
+ * First BSSID register (MAC address, lower 32bits)
+ */
+#define AR5K_AR5211_BSS_ID0 0x8008
+
+/*
+ * Second BSSID register (MAC address in upper 16 bits)
+ *
+ * AID: Association ID
+ */
+#define AR5K_AR5211_BSS_ID1 0x800c
+#define AR5K_AR5211_BSS_ID1_AID 0xffff0000
+#define AR5K_AR5211_BSS_ID1_AID_S 16
+
+/*
+ * Backoff slot time register
+ */
+#define AR5K_AR5211_SLOT_TIME 0x8010
+
+/*
+ * ACK/CTS timeout register
+ */
+#define AR5K_AR5211_TIME_OUT 0x8014
+#define AR5K_AR5211_TIME_OUT_ACK 0x00001fff
+#define AR5K_AR5211_TIME_OUT_ACK_S 0
+#define AR5K_AR5211_TIME_OUT_CTS 0x1fff0000
+#define AR5K_AR5211_TIME_OUT_CTS_S 16
+
+/*
+ * RSSI threshold register
+ */
+#define AR5K_AR5211_RSSI_THR 0x8018
+#define AR5K_AR5211_RSSI_THR_M 0x000000ff
+#define AR5K_AR5211_RSSI_THR_BMISS 0x0000ff00
+#define AR5K_AR5211_RSSI_THR_BMISS_S 8
+
+/*
+ * Transmit latency register
+ */
+#define AR5K_AR5211_USEC 0x801c
+#define AR5K_AR5211_USEC_1 0x0000007f
+#define AR5K_AR5211_USEC_1_S 0
+#define AR5K_AR5211_USEC_32 0x00003f80
+#define AR5K_AR5211_USEC_32_S 7
+#define AR5K_AR5211_USEC_TX_LATENCY 0x007fc000
+#define AR5K_AR5211_USEC_TX_LATENCY_S 14
+#define AR5K_AR5211_USEC_RX_LATENCY 0x1f800000
+#define AR5K_AR5211_USEC_RX_LATENCY_S 23
+#define AR5K_AR5311_USEC_TX_LATENCY 0x000fc000
+#define AR5K_AR5311_USEC_TX_LATENCY_S 14
+#define AR5K_AR5311_USEC_RX_LATENCY 0x03f00000
+#define AR5K_AR5311_USEC_RX_LATENCY_S 20
+
+/*
+ * PCU beacon control register
+ */
+#define AR5K_AR5211_BEACON 0x8020
+#define AR5K_AR5211_BEACON_PERIOD 0x0000ffff
+#define AR5K_AR5211_BEACON_PERIOD_S 0
+#define AR5K_AR5211_BEACON_TIM 0x007f0000
+#define AR5K_AR5211_BEACON_TIM_S 16
+#define AR5K_AR5211_BEACON_ENABLE 0x00800000
+#define AR5K_AR5211_BEACON_RESET_TSF 0x01000000
+
+/*
+ * CFP period register
+ */
+#define AR5K_AR5211_CFP_PERIOD 0x8024
+
+/*
+ * Next beacon time register
+ */
+#define AR5K_AR5211_TIMER0 0x8028
+
+/*
+ * Next DMA beacon alert register
+ */
+#define AR5K_AR5211_TIMER1 0x802c
+
+/*
+ * Next software beacon alert register
+ */
+#define AR5K_AR5211_TIMER2 0x8030
+
+/*
+ * Next ATIM window time register
+ */
+#define AR5K_AR5211_TIMER3 0x8034
+
+/*
+ * CFP duration register
+ */
+#define AR5K_AR5211_CFP_DUR 0x8038
+
+/*
+ * Receive filter register
+ */
+#define AR5K_AR5211_RX_FILTER 0x803c
+#define AR5K_AR5211_RX_FILTER_UNICAST 0x00000001
+#define AR5K_AR5211_RX_FILTER_MULTICAST 0x00000002
+#define AR5K_AR5211_RX_FILTER_BROADCAST 0x00000004
+#define AR5K_AR5211_RX_FILTER_CONTROL 0x00000008
+#define AR5K_AR5211_RX_FILTER_BEACON 0x00000010
+#define AR5K_AR5211_RX_FILTER_PROMISC 0x00000020
+#define AR5K_AR5211_RX_FILTER_PHYERR 0x00000040
+#define AR5K_AR5211_RX_FILTER_RADARERR 0x00000080
+
+/*
+ * Multicast filter register (lower 32 bits)
+ */
+#define AR5K_AR5211_MCAST_FIL0 0x8040
+
+/*
+ * Multicast filter register (higher 16 bits)
+ */
+#define AR5K_AR5211_MCAST_FIL1 0x8044
+
+/*
+ * PCU control register
+ */
+#define AR5K_AR5211_DIAG_SW 0x8048
+#define AR5K_AR5211_DIAG_SW_DIS_WEP_ACK 0x00000001
+#define AR5K_AR5211_DIAG_SW_DIS_ACK 0x00000002
+#define AR5K_AR5211_DIAG_SW_DIS_CTS 0x00000004
+#define AR5K_AR5211_DIAG_SW_DIS_ENC 0x00000008
+#define AR5K_AR5211_DIAG_SW_DIS_DEC 0x00000010
+#define AR5K_AR5211_DIAG_SW_DIS_RX 0x00000020
+#define AR5K_AR5211_DIAG_SW_LOOP_BACK 0x00000040
+#define AR5K_AR5211_DIAG_SW_CORR_FCS 0x00000080
+#define AR5K_AR5211_DIAG_SW_CHAN_INFO 0x00000100
+#define AR5K_AR5211_DIAG_SW_EN_SCRAM_SEED 0x00000200
+#define AR5K_AR5211_DIAG_SW_ECO_ENABLE 0x00000400
+#define AR5K_AR5211_DIAG_SW_SCRAM_SEED_M 0x0001fc00
+#define AR5K_AR5211_DIAG_SW_SCRAM_SEED_S 10
+#define AR5K_AR5211_DIAG_SW_FRAME_NV0 0x00020000
+#define AR5K_AR5211_DIAG_SW_OBSPT_M 0x000c0000
+#define AR5K_AR5211_DIAG_SW_OBSPT_S 18
+
+/*
+ * TSF (clock) register (lower 32 bits)
+ */
+#define AR5K_AR5211_TSF_L32 0x804c
+
+/*
+ * TSF (clock) register (higher 32 bits)
+ */
+#define AR5K_AR5211_TSF_U32 0x8050
+
+/*
+ * ADDAC test register
+ */
+#define AR5K_AR5211_ADDAC_TEST 0x8054
+
+/*
+ * Default antenna register
+ */
+#define AR5K_AR5211_DEFAULT_ANTENNA 0x8058
+
+/*
+ * Last beacon timestamp register
+ */
+#define AR5K_AR5211_LAST_TSTP 0x8080
+
+/*
+ * NAV register (current)
+ */
+#define AR5K_AR5211_NAV 0x8084
+
+/*
+ * RTS success register
+ */
+#define AR5K_AR5211_RTS_OK 0x8088
+
+/*
+ * RTS failure register
+ */
+#define AR5K_AR5211_RTS_FAIL 0x808c
+
+/*
+ * ACK failure register
+ */
+#define AR5K_AR5211_ACK_FAIL 0x8090
+
+/*
+ * FCS failure register
+ */
+#define AR5K_AR5211_FCS_FAIL 0x8094
+
+/*
+ * Beacon count register
+ */
+#define AR5K_AR5211_BEACON_CNT 0x8098
+
+/*
+ * Key table (WEP) register
+ */
+#define AR5K_AR5211_KEYTABLE_0 0x8800
+#define AR5K_AR5211_KEYTABLE(n) (AR5K_AR5211_KEYTABLE_0 + ((n) * 32))
+#define AR5K_AR5211_KEYTABLE_TYPE_40 0x00000000
+#define AR5K_AR5211_KEYTABLE_TYPE_104 0x00000001
+#define AR5K_AR5211_KEYTABLE_TYPE_128 0x00000003
+#define AR5K_AR5211_KEYTABLE_TYPE_AES 0x00000005
+#define AR5K_AR5211_KEYTABLE_TYPE_NULL 0x00000007
+#define AR5K_AR5211_KEYTABLE_VALID 0x00008000
+
+#define AR5K_AR5211_KEYTABLE_SIZE 64
+#define AR5K_AR5211_KEYCACHE_SIZE 8
+
+/*
+ * PHY register
+ */
+#define AR5K_AR5211_PHY(_n) (0x9800 + ((_n) << 2))
+#define AR5K_AR5211_PHY_SHIFT_2GHZ 0x00004007
+#define AR5K_AR5211_PHY_SHIFT_5GHZ 0x00000007
+
+/*
+ * PHY turbo mode register
+ */
+#define AR5K_AR5211_PHY_TURBO 0x9804
+#define AR5K_AR5211_PHY_TURBO_MODE 0x00000001
+#define AR5K_AR5211_PHY_TURBO_SHORT 0x00000002
+
+/*
+ * PHY agility command register
+ */
+#define AR5K_AR5211_PHY_AGC 0x9808
+#define AR5K_AR5211_PHY_AGC_DISABLE 0x08000000
+
+/*
+ * PHY chip revision register
+ */
+#define AR5K_AR5211_PHY_CHIP_ID 0x9818
+
+/*
+ * PHY activation register
+ */
+#define AR5K_AR5211_PHY_ACTIVE 0x981c
+#define AR5K_AR5211_PHY_ENABLE 0x00000001
+#define AR5K_AR5211_PHY_DISABLE 0x00000002
+
+/*
+ * PHY agility control register
+ */
+#define AR5K_AR5211_PHY_AGCCTL 0x9860
+#define AR5K_AR5211_PHY_AGCCTL_CAL 0x00000001
+#define AR5K_AR5211_PHY_AGCCTL_NF 0x00000002
+
+/*
+ * PHY noise floor status register
+ */
+#define AR5K_AR5211_PHY_NF 0x9864
+#define AR5K_AR5211_PHY_NF_M 0x000001ff
+#define AR5K_AR5211_PHY_NF_ACTIVE 0x00000100
+#define AR5K_AR5211_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_AR5211_PHY_NF_M)
+#define AR5K_AR5211_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_AR5211_PHY_NF_M) + 1)
+#define AR5K_AR5211_PHY_NF_SVAL(_n) (((_n) & AR5K_AR5211_PHY_NF_M) | (1 << 9))
+
+/*
+ * PHY PLL control register
+ */
+#define AR5K_AR5211_PHY_PLL 0x987c
+#define AR5K_AR5211_PHY_PLL_20MHZ 0x13
+#define AR5K_AR5211_PHY_PLL_40MHZ 0x18
+#define AR5K_AR5211_PHY_PLL_44MHZ 0x19
+
+/*
+ * PHY receiver delay register
+ */
+#define AR5K_AR5211_PHY_RX_DELAY 0x9914
+#define AR5K_AR5211_PHY_RX_DELAY_M 0x00003fff
+
+/*
+ * PHY timing IQ control register
+ */
+#define AR5K_AR5211_PHY_IQ 0x9920
+#define AR5K_AR5211_PHY_IQ_CORR_Q_Q_COFF 0x0000001f
+#define AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF 0x000007e0
+#define AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF_S 5
+#define AR5K_AR5211_PHY_IQ_CORR_ENABLE 0x00000800
+#define AR5K_AR5211_PHY_IQ_CAL_NUM_LOG_MAX 0x0000f000
+#define AR5K_AR5211_PHY_IQ_CAL_NUM_LOG_MAX_S 12
+#define AR5K_AR5211_PHY_IQ_RUN 0x00010000
+
+/*
+ * PHY PAPD probe register
+ */
+#define AR5K_AR5211_PHY_PAPD_PROBE 0x9930
+#define AR5K_AR5211_PHY_PAPD_PROBE_TX_PWR 0x00007e00
+#define AR5K_AR5211_PHY_PAPD_PROBE_TX_PWR_S 9
+#define AR5K_AR5211_PHY_PAPD_PROBE_TX_NEXT 0x00008000
+#define AR5K_AR5211_PHY_PAPD_PROBE_GAINF 0xfe000000
+#define AR5K_AR5211_PHY_PAPD_PROBE_GAINF_S 25
+
+/*
+ * PHY frame control register
+ */
+#define AR5K_AR5211_PHY_FC 0x9944
+#define AR5K_AR5211_PHY_FC_TX_CLIP 0x00000038
+#define AR5K_AR5211_PHY_FC_TX_CLIP_S 3
+
+/*
+ * PHY radar detection enable register
+ */
+#define AR5K_AR5211_PHY_RADAR 0x9954
+#define AR5K_AR5211_PHY_RADAR_DISABLE 0x00000000
+#define AR5K_AR5211_PHY_RADAR_ENABLE 0x00000001
+
+/*
+ * PHY antenna switch table registers
+ */
+#define AR5K_AR5211_PHY_ANT_SWITCH_TABLE_0 0x9960
+#define AR5K_AR5211_PHY_ANT_SWITCH_TABLE_1 0x9964
+
+/*
+ * PHY timing IQ calibration result register
+ */
+#define AR5K_AR5211_PHY_IQRES_CAL_PWR_I 0x9c10
+#define AR5K_AR5211_PHY_IQRES_CAL_PWR_Q 0x9c14
+#define AR5K_AR5211_PHY_IQRES_CAL_CORR 0x9c18
+
+/*
+ * PHY current RSSI register
+ */
+#define AR5K_AR5211_PHY_CURRENT_RSSI 0x9c1c
+
+/*
+ * PHY mode register
+ */
+#define AR5K_AR5211_PHY_MODE 0xa200
+#define AR5K_AR5211_PHY_MODE_MOD 0x00000001
+#define AR5K_AR5211_PHY_MODE_MOD_OFDM 0
+#define AR5K_AR5211_PHY_MODE_MOD_CCK 1
+#define AR5K_AR5211_PHY_MODE_FREQ 0x00000002
+#define AR5K_AR5211_PHY_MODE_FREQ_5GHZ 0
+#define AR5K_AR5211_PHY_MODE_FREQ_2GHZ 2
+
+/*
+ * Misc PHY/radio registers
+ */
+#define AR5K_AR5211_BB_GAIN(_n) (0x9b00 + ((_n) << 2))
+#define AR5K_AR5211_RF_GAIN(_n) (0x9a00 + ((_n) << 2))
+
+#endif
diff --git a/sys/dev/ic/ar5211var.h b/sys/dev/ic/ar5211var.h
new file mode 100644
index 00000000000..f9d59a38186
--- /dev/null
+++ b/sys/dev/ic/ar5211var.h
@@ -0,0 +1,396 @@
+/* $OpenBSD: ar5211var.h,v 1.1 2005/02/25 22:25:30 reyk Exp $ */
+
+/*
+ * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * 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.
+ */
+
+/*
+ * Specific definitions for the Atheros AR5001 Wireless LAN chipset
+ * (AR5211/AR5311).
+ */
+
+#ifndef _AR5K_AR5211_VAR_H
+#define _AR5K_AR5211_VAR_H
+
+#include <dev/ic/ar5xxx.h>
+
+/*
+ * Define a "magic" code for the AR5211 (the HAL layer wants it)
+ */
+
+#define AR5K_AR5211_MAGIC 0x0000145b /* 5211 */
+#define AR5K_AR5211_TX_NUM_QUEUES 10
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define AR5K_AR5211_INIT_CFG ( \
+ AR5K_AR5211_CFG_SWTD | AR5K_AR5211_CFG_SWTB | \
+ AR5K_AR5211_CFG_SWRD | AR5K_AR5211_CFG_SWRB | \
+ AR5K_AR5211_CFG_SWRG \
+)
+#else
+#define AR5K_AR5211_INIT_CFG 0x00000000
+#endif
+
+/*
+ * Internal RX/TX descriptor structures
+ * (rX: reserved fields possibily used by future versions of the ar5k chipset)
+ */
+
+struct ar5k_ar5211_rx_desc {
+ /*
+ * First word
+ */
+ u_int32_t r1;
+
+ /*
+ * Second word
+ */
+ u_int32_t buf_len:12;
+ u_int32_t r2:1;
+ u_int32_t inter_req:1;
+ u_int32_t r3:18;
+} __packed;
+
+struct ar5k_ar5211_rx_status {
+ /*
+ * First word
+ */
+ u_int32_t data_len:12;
+ u_int32_t more:1;
+ u_int32_t r1:1;
+ u_int32_t receive_antenna:1;
+ u_int32_t receive_rate:4;
+ u_int32_t receive_sig_strength:8;
+ u_int32_t r2:5;
+
+ /*
+ * Second word
+ */
+ u_int32_t done:1;
+ u_int32_t frame_receive_ok:1;
+ u_int32_t crc_error:1;
+ u_int32_t fifo_overrun:1;
+ u_int32_t decrypt_crc_error:1;
+ u_int32_t phy_error:3;
+ u_int32_t key_index_valid:1;
+ u_int32_t key_index:6;
+ u_int32_t receive_timestamp:13;
+ u_int32_t key_cache_miss:1;
+ u_int32_t r3:3;
+} __packed;
+
+#define AR5K_AR5211_DESC_RX_PHY_ERROR_NONE 0x00
+#define AR5K_AR5211_DESC_RX_PHY_ERROR_TIMING 0x20
+#define AR5K_AR5211_DESC_RX_PHY_ERROR_PARITY 0x40
+#define AR5K_AR5211_DESC_RX_PHY_ERROR_RATE 0x60
+#define AR5K_AR5211_DESC_RX_PHY_ERROR_LENGTH 0x80
+#define AR5K_AR5211_DESC_RX_PHY_ERROR_64QAM 0xa0
+#define AR5K_AR5211_DESC_RX_PHY_ERROR_SERVICE 0xc0
+#define AR5K_AR5211_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0
+
+struct ar5k_ar5211_tx_desc {
+ /*
+ * First word
+ */
+ u_int32_t frame_len:12;
+ u_int32_t reserved_12_17:6;
+ u_int32_t xmit_rate:4;
+ u_int32_t rts_cts_enable:1;
+ u_int32_t veol:1;
+ u_int32_t clear_dest_mask:1;
+ u_int32_t ant_mode_xmit:4;
+ u_int32_t inter_req:1;
+ u_int32_t encrypt_key_valid:1;
+ u_int32_t reserved_31:1;
+
+ /*
+ * Second word
+ */
+ u_int32_t buf_len:12;
+ u_int32_t more:1;
+ u_int32_t encrypt_key_index:7;
+ u_int32_t frame_type:4;
+ u_int32_t no_ack:1;
+ u_int32_t reserved_24_31:1;
+} __packed;
+
+#define AR5K_AR5211_DESC_TX_XMIT_RATE_6 0xb
+#define AR5K_AR5211_DESC_TX_XMIT_RATE_9 0xf
+#define AR5K_AR5211_DESC_TX_XMIT_RATE_12 0xa
+#define AR5K_AR5211_DESC_TX_XMIT_RATE_18 0xe
+#define AR5K_AR5211_DESC_TX_XMIT_RATE_24 0x9
+#define AR5K_AR5211_DESC_TX_XMIT_RATE_36 0xd
+#define AR5K_AR5211_DESC_TX_XMIT_RATE_48 0x8
+#define AR5K_AR5211_DESC_TX_XMIT_RATE_54 0xc
+
+#define AR5K_AR5211_DESC_TX_FRAME_TYPE_NORMAL 0x00
+#define AR5K_AR5211_DESC_TX_FRAME_TYPE_ATIM 0x04
+#define AR5K_AR5211_DESC_TX_FRAME_TYPE_PSPOLL 0x08
+#define AR5K_AR5211_DESC_TX_FRAME_TYPE_NO_DELAY 0x0c
+#define AR5K_AR5211_DESC_TX_FRAME_TYPE_PIFS 0x10
+
+struct ar5k_ar5211_tx_status {
+ /*
+ * First word
+ */
+ u_int32_t frame_xmit_ok:1;
+ u_int32_t excessive_retries:1;
+ u_int32_t fifo_underrun:1;
+ u_int32_t filtered:1;
+ u_int32_t rts_fail_count:4;
+ u_int32_t data_fail_count:4;
+ u_int32_t virt_coll_count:4;
+ u_int32_t send_timestamp:16;
+
+ /*
+ * Second word
+ */
+ u_int32_t done:1;
+ u_int32_t seq_num:12;
+ u_int32_t ack_sig_strength:8;
+ u_int32_t reserved_21_31:11;
+} __packed;
+
+/*
+ * Public function prototypes
+ */
+extern ar5k_attach_t ar5k_ar5211_attach;
+
+/*
+ * Initial register values which have to be loaded into the
+ * card at boot time and after each reset.
+ */
+
+#define AR5K_AR5211_INI { \
+ { 0x000c, 0x00000000 }, \
+ { 0x0028, 0x84849c9c }, \
+ { 0x002c, 0x7c7c7c7c }, \
+ { 0x0034, 0x00000005 }, \
+ { 0x0040, 0x00000000 }, \
+ { 0x0044, 0x00000008 }, \
+ { 0x0048, 0x00000008 }, \
+ { 0x004c, 0x00000010 }, \
+ { 0x0050, 0x00000000 }, \
+ { 0x0054, 0x0000001f }, \
+ { 0x0800, 0x00000000 }, \
+ { 0x0804, 0x00000000 }, \
+ { 0x0808, 0x00000000 }, \
+ { 0x080c, 0x00000000 }, \
+ { 0x0810, 0x00000000 }, \
+ { 0x0814, 0x00000000 }, \
+ { 0x0818, 0x00000000 }, \
+ { 0x081c, 0x00000000 }, \
+ { 0x0820, 0x00000000 }, \
+ { 0x0824, 0x00000000 }, \
+ { 0x1230, 0x00000000 }, \
+ { 0x8004, 0x00000000 }, \
+ { 0x8008, 0x00000000 }, \
+ { 0x800c, 0x00000000 }, \
+ { 0x8018, 0x00000000 }, \
+ { 0x8024, 0x00000000 }, \
+ { 0x8028, 0x00000030 }, \
+ { 0x802c, 0x0007ffff }, \
+ { 0x8030, 0x01ffffff }, \
+ { 0x8034, 0x00000031 }, \
+ { 0x8038, 0x00000000 }, \
+ { 0x803c, 0x00000000 }, \
+ { 0x8040, 0x00000000 }, \
+ { 0x8044, 0x00000002 }, \
+ { 0x8048, 0x00000000 }, \
+ { 0x8054, 0x00000000 }, \
+ { 0x8058, 0x00000000 }, \
+ /* PHY registers */ \
+ { 0x9808, 0x00000000 }, \
+ { 0x980c, 0x2d849093 }, \
+ { 0x9810, 0x7d32e000 }, \
+ { 0x9814, 0x00000f6b }, \
+ { 0x981c, 0x00000000 }, \
+ { 0x982c, 0x00026ffe }, \
+ { 0x9830, 0x00000000 }, \
+ { 0x983c, 0x00020100 }, \
+ { 0x9840, 0x206a017a }, \
+ { 0x984c, 0x1284613c }, \
+ { 0x9854, 0x00000859 }, \
+ { 0x9868, 0x409a4190 }, \
+ { 0x986c, 0x050cb081 }, \
+ { 0x9870, 0x0000000f }, \
+ { 0x9874, 0x00000080 }, \
+ { 0x9878, 0x0000000c }, \
+ { 0x9900, 0x00000000 }, \
+ { 0x9904, 0x00000000 }, \
+ { 0x9908, 0x00000000 }, \
+ { 0x990c, 0x00800000 }, \
+ { 0x9910, 0x00000001 }, \
+ { 0x991c, 0x0000092a }, \
+ { 0x9920, 0x00000000 }, \
+ { 0x9924, 0x00058a05 }, \
+ { 0x9928, 0x00000001 }, \
+ { 0x992c, 0x00000000 }, \
+ { 0x9930, 0x00000000 }, \
+ { 0x9934, 0x00000000 }, \
+ { 0x9938, 0x00000000 }, \
+ { 0x993c, 0x0000003f }, \
+ { 0x9940, 0x00000004 }, \
+ { 0x9948, 0x00000000 }, \
+ { 0x994c, 0x00000000 }, \
+ { 0x9950, 0x00000000 }, \
+ { 0x9954, 0x5d50f14c }, \
+ { 0x9958, 0x00000018 }, \
+ { 0x995c, 0x004b6a8e }, \
+ { 0xa184, 0x06ff05ff }, \
+ { 0xa188, 0x07ff07ff }, \
+ { 0xa18c, 0x08ff08ff }, \
+ { 0xa190, 0x09ff09ff }, \
+ { 0xa194, 0x0aff0aff }, \
+ { 0xa198, 0x0bff0bff }, \
+ { 0xa19c, 0x0cff0cff }, \
+ { 0xa1a0, 0x0dff0dff }, \
+ { 0xa1a4, 0x0fff0eff }, \
+ { 0xa1a8, 0x12ff12ff }, \
+ { 0xa1ac, 0x14ff13ff }, \
+ { 0xa1b0, 0x16ff15ff }, \
+ { 0xa1b4, 0x19ff17ff }, \
+ { 0xa1b8, 0x1bff1aff }, \
+ { 0xa1bc, 0x1eff1dff }, \
+ { 0xa1c0, 0x23ff20ff }, \
+ { 0xa1c4, 0x27ff25ff }, \
+ { 0xa1c8, 0x2cff29ff }, \
+ { 0xa1cc, 0x31ff2fff }, \
+ { 0xa1d0, 0x37ff34ff }, \
+ { 0xa1d4, 0x3aff3aff }, \
+ { 0xa1d8, 0x3aff3aff }, \
+ { 0xa1dc, 0x3aff3aff }, \
+ { 0xa1e0, 0x3aff3aff }, \
+ { 0xa1e4, 0x3aff3aff }, \
+ { 0xa1e8, 0x3aff3aff }, \
+ { 0xa1ec, 0x3aff3aff }, \
+ { 0xa1f0, 0x3aff3aff }, \
+ { 0xa1f4, 0x3aff3aff }, \
+ { 0xa1f8, 0x3aff3aff }, \
+ { 0xa1fc, 0x3aff3aff }, \
+ /* BB gain table (64bytes) */ \
+ { 0x9b00, 0x00000000 }, \
+ { 0x9b04, 0x00000020 }, \
+ { 0x9b08, 0x00000010 }, \
+ { 0x9b0c, 0x00000030 }, \
+ { 0x9b10, 0x00000008 }, \
+ { 0x9b14, 0x00000028 }, \
+ { 0x9b18, 0x00000004 }, \
+ { 0x9b1c, 0x00000024 }, \
+ { 0x9b20, 0x00000014 }, \
+ { 0x9b24, 0x00000034 }, \
+ { 0x9b28, 0x0000000c }, \
+ { 0x9b2c, 0x0000002c }, \
+ { 0x9b30, 0x00000002 }, \
+ { 0x9b34, 0x00000022 }, \
+ { 0x9b38, 0x00000012 }, \
+ { 0x9b3c, 0x00000032 }, \
+ { 0x9b40, 0x0000000a }, \
+ { 0x9b44, 0x0000002a }, \
+ { 0x9b48, 0x00000006 }, \
+ { 0x9b4c, 0x00000026 }, \
+ { 0x9b50, 0x00000016 }, \
+ { 0x9b54, 0x00000036 }, \
+ { 0x9b58, 0x0000000e }, \
+ { 0x9b5c, 0x0000002e }, \
+ { 0x9b60, 0x00000001 }, \
+ { 0x9b64, 0x00000021 }, \
+ { 0x9b68, 0x00000011 }, \
+ { 0x9b6c, 0x00000031 }, \
+ { 0x9b70, 0x00000009 }, \
+ { 0x9b74, 0x00000029 }, \
+ { 0x9b78, 0x00000005 }, \
+ { 0x9b7c, 0x00000025 }, \
+ { 0x9b80, 0x00000015 }, \
+ { 0x9b84, 0x00000035 }, \
+ { 0x9b88, 0x0000000d }, \
+ { 0x9b8c, 0x0000002d }, \
+ { 0x9b90, 0x00000003 }, \
+ { 0x9b94, 0x00000023 }, \
+ { 0x9b98, 0x00000013 }, \
+ { 0x9b9c, 0x00000033 }, \
+ { 0x9ba0, 0x0000000b }, \
+ { 0x9ba4, 0x0000002b }, \
+ { 0x9ba8, 0x0000002b }, \
+ { 0x9bac, 0x0000002b }, \
+ { 0x9bb0, 0x0000002b }, \
+ { 0x9bb4, 0x0000002b }, \
+ { 0x9bb8, 0x0000002b }, \
+ { 0x9bbc, 0x0000002b }, \
+ { 0x9bc0, 0x0000002b }, \
+ { 0x9bc4, 0x0000002b }, \
+ { 0x9bc8, 0x0000002b }, \
+ { 0x9bcc, 0x0000002b }, \
+ { 0x9bd0, 0x0000002b }, \
+ { 0x9bd4, 0x0000002b }, \
+ { 0x9bd8, 0x0000002b }, \
+ { 0x9bdc, 0x0000002b }, \
+ { 0x9be0, 0x0000002b }, \
+ { 0x9be4, 0x0000002b }, \
+ { 0x9be8, 0x0000002b }, \
+ { 0x9bec, 0x0000002b }, \
+ { 0x9bf0, 0x0000002b }, \
+ { 0x9bf4, 0x0000002b }, \
+ { 0x9bf8, 0x00000002 }, \
+ { 0x9bfc, 0x00000016 }, \
+ /* PHY activation */ \
+ { 0x98d4, 0x00000020 }, \
+ { 0x98d8, 0x00601068 }, \
+}
+
+struct ar5k_ar5211_ini_mode {
+ u_int16_t mode_register;
+ u_int32_t mode_value[4];
+};
+
+#define AR5K_AR5211_INI_MODE { \
+ { 0x0030, { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } }, \
+ { 0x1040, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x1044, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x1048, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x104c, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x1050, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x1054, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x1058, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x105c, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x1060, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x1064, { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, \
+ { 0x1070, { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } }, \
+ { 0x1030, { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } }, \
+ { 0x10b0, { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } }, \
+ { 0x10f0, { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } }, \
+ { 0x8014, { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } }, \
+ { 0x801c, { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } }, \
+ { 0x9804, { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } }, \
+ { 0x9820, { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } }, \
+ { 0x9824, { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } }, \
+ { 0x9828, { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } }, \
+ { 0x9834, { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, \
+ { 0x9838, { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } }, \
+ { 0x9844, { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } }, \
+ { 0x9848, { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } }, \
+ { 0x9850, { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } }, \
+ { 0x9858, { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } }, \
+ { 0x985c, { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } }, \
+ { 0x9860, { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } }, \
+ { 0x9864, { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, \
+ { 0x9914, { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } }, \
+ { 0x9918, { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } }, \
+ { 0x9944, { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } }, \
+ { 0xa180, { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } }, \
+ { 0x98d4, { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } }, \
+}
+
+#endif /* _AR5K_AR5211_VAR_H */
diff --git a/sys/dev/ic/ar5212.c b/sys/dev/ic/ar5212.c
index a12555ca234..e539b0de8e7 100644
--- a/sys/dev/ic/ar5212.c
+++ b/sys/dev/ic/ar5212.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5212.c,v 1.2 2005/02/19 17:57:15 reyk Exp $ */
+/* $OpenBSD: ar5212.c,v 1.3 2005/02/25 22:25:30 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -38,8 +38,6 @@ static const struct ar5k_ar5212_ini ar5212_ini[] =
AR5K_AR5212_INI;
static const struct ar5k_ar5212_ini_mode ar5212_mode[] =
AR5K_AR5212_INI_MODE;
-static const struct ar5k_ar5212_ini_rfgain ar5212_rfgain[] =
- AR5K_AR5212_INI_RFGAIN;
AR5K_HAL_FUNCTIONS(extern, ar5k_ar5212,);
@@ -516,9 +514,8 @@ ar5k_ar5212_reset(hal, op_mode, channel, change_channel, status)
* Write initial RF gain settings
*/
phy = ar5112 == AH_TRUE ? AR5K_INI_PHY_5112 : AR5K_INI_PHY_5111;
- for (i = 0; i < AR5K_ELEMENTS(ar5212_rfgain); i++)
- AR5K_REG_WRITE((u_int32_t)ar5212_rfgain[i].rfg_register,
- ar5212_rfgain[i].rfg_value[phy][freq]);
+ if (ar5k_rfgain(hal, phy, freq) == AH_FALSE)
+ return (AH_FALSE);
AR5K_DELAY(1000);
diff --git a/sys/dev/ic/ar5212var.h b/sys/dev/ic/ar5212var.h
index 2bbf18022af..22340f0f2c0 100644
--- a/sys/dev/ic/ar5212var.h
+++ b/sys/dev/ic/ar5212var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5212var.h,v 1.1 2005/02/19 16:58:00 reyk Exp $ */
+/* $OpenBSD: ar5212var.h,v 1.2 2005/02/25 22:25:30 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -30,7 +30,7 @@
* Define a "magic" code for the AR5212 (the HAL layer wants it)
*/
-#define AR5K_AR5212_MAGIC 0x0000145b /* 5212 */
+#define AR5K_AR5212_MAGIC 0x0000145c /* 5212 */
#define AR5K_AR5212_TX_NUM_QUEUES 10
#if BYTE_ORDER == BIG_ENDIAN
@@ -600,10 +600,6 @@ struct ar5k_ar5212_ini_mode {
u_int16_t mode_register;
u_int8_t mode_flags;
u_int32_t mode_value[2][5];
-
-#define AR5K_INI_PHY_5111 0
-#define AR5K_INI_PHY_5112 1
-#define AR5K_INI_PHY_511X 1
};
#define AR5K_AR5212_INI_MODE { \
@@ -773,143 +769,4 @@ struct ar5k_ar5212_ini_mode {
} }, \
}
-struct ar5k_ar5212_ini_rfgain {
- u_int16_t rfg_register;
- u_int32_t rfg_value[2][2];
-
-#define AR5K_INI_RFGAIN_5GHZ 0
-#define AR5K_INI_RFGAIN_2GHZ 1
-};
-
-#define AR5K_AR5212_INI_RFGAIN { \
- { 0x9a00, { \
- { 0x000001a9, 0x00000000 }, { 0x00000007, 0x00000007 } } }, \
- { 0x9a04, { \
- { 0x000001e9, 0x00000040 }, { 0x00000047, 0x00000047 } } }, \
- { 0x9a08, { \
- { 0x00000029, 0x00000080 }, { 0x00000087, 0x00000087 } } }, \
- { 0x9a0c, { \
- { 0x00000069, 0x00000150 }, { 0x000001a0, 0x000001a0 } } }, \
- { 0x9a10, { \
- { 0x00000199, 0x00000190 }, { 0x000001e0, 0x000001e0 } } }, \
- { 0x9a14, { \
- { 0x000001d9, 0x000001d0 }, { 0x00000020, 0x00000020 } } }, \
- { 0x9a18, { \
- { 0x00000019, 0x00000010 }, { 0x00000060, 0x00000060 } } }, \
- { 0x9a1c, { \
- { 0x00000059, 0x00000044 }, { 0x000001a1, 0x000001a1 } } }, \
- { 0x9a20, { \
- { 0x00000099, 0x00000084 }, { 0x000001e1, 0x000001e1 } } }, \
- { 0x9a24, { \
- { 0x000001a5, 0x00000148 }, { 0x00000021, 0x00000021 } } }, \
- { 0x9a28, { \
- { 0x000001e5, 0x00000188 }, { 0x00000061, 0x00000061 } } }, \
- { 0x9a2c, { \
- { 0x00000025, 0x000001c8 }, { 0x00000162, 0x00000162 } } }, \
- { 0x9a30, { \
- { 0x000001c8, 0x00000014 }, { 0x000001a2, 0x000001a2 } } }, \
- { 0x9a34, { \
- { 0x00000008, 0x00000042 }, { 0x000001e2, 0x000001e2 } } }, \
- { 0x9a38, { \
- { 0x00000048, 0x00000082 }, { 0x00000022, 0x00000022 } } }, \
- { 0x9a3c, { \
- { 0x00000088, 0x00000178 }, { 0x00000062, 0x00000062 } } }, \
- { 0x9a40, { \
- { 0x00000198, 0x000001b8 }, { 0x00000163, 0x00000163 } } }, \
- { 0x9a44, { \
- { 0x000001d8, 0x000001f8 }, { 0x000001a3, 0x000001a3 } } }, \
- { 0x9a48, { \
- { 0x00000018, 0x00000012 }, { 0x000001e3, 0x000001e3 } } }, \
- { 0x9a4c, { \
- { 0x00000058, 0x00000052 }, { 0x00000023, 0x00000023 } } }, \
- { 0x9a50, { \
- { 0x00000098, 0x00000092 }, { 0x00000063, 0x00000063 } } }, \
- { 0x9a54, { \
- { 0x000001a4, 0x0000017c }, { 0x00000184, 0x00000184 } } }, \
- { 0x9a58, { \
- { 0x000001e4, 0x000001bc }, { 0x000001c4, 0x000001c4 } } }, \
- { 0x9a5c, { \
- { 0x00000024, 0x000001fc }, { 0x00000004, 0x00000004 } } }, \
- { 0x9a60, { \
- { 0x00000064, 0x0000000a }, { 0x000001ea, 0x0000000b } } }, \
- { 0x9a64, { \
- { 0x000000a4, 0x0000004a }, { 0x0000002a, 0x0000004b } } }, \
- { 0x9a68, { \
- { 0x000000e4, 0x0000008a }, { 0x0000006a, 0x0000008b } } }, \
- { 0x9a6c, { \
- { 0x0000010a, 0x0000015a }, { 0x000000aa, 0x000001ac } } }, \
- { 0x9a70, { \
- { 0x0000014a, 0x0000019a }, { 0x000001ab, 0x000001ec } } }, \
- { 0x9a74, { \
- { 0x0000018a, 0x000001da }, { 0x000001eb, 0x0000002c } } }, \
- { 0x9a78, { \
- { 0x000001ca, 0x0000000e }, { 0x0000002b, 0x00000012 } } }, \
- { 0x9a7c, { \
- { 0x0000000a, 0x0000004e }, { 0x0000006b, 0x00000052 } } }, \
- { 0x9a80, { \
- { 0x0000004a, 0x0000008e }, { 0x000000ab, 0x00000092 } } }, \
- { 0x9a84, { \
- { 0x0000008a, 0x0000015e }, { 0x000001ac, 0x00000193 } } }, \
- { 0x9a88, { \
- { 0x000001ba, 0x0000019e }, { 0x000001ec, 0x000001d3 } } }, \
- { 0x9a8c, { \
- { 0x000001fa, 0x000001de }, { 0x0000002c, 0x00000013 } } }, \
- { 0x9a90, { \
- { 0x0000003a, 0x00000009 }, { 0x0000003a, 0x00000053 } } }, \
- { 0x9a94, { \
- { 0x0000007a, 0x00000049 }, { 0x0000007a, 0x00000093 } } }, \
- { 0x9a98, { \
- { 0x00000186, 0x00000089 }, { 0x000000ba, 0x00000194 } } }, \
- { 0x9a9c, { \
- { 0x000001c6, 0x00000179 }, { 0x000001bb, 0x000001d4 } } }, \
- { 0x9aa0, { \
- { 0x00000006, 0x000001b9 }, { 0x000001fb, 0x00000014 } } }, \
- { 0x9aa4, { \
- { 0x00000046, 0x000001f9 }, { 0x0000003b, 0x0000003a } } }, \
- { 0x9aa8, { \
- { 0x00000086, 0x00000039 }, { 0x0000007b, 0x0000007a } } }, \
- { 0x9aac, { \
- { 0x000000c6, 0x00000079 }, { 0x000000bb, 0x000000ba } } }, \
- { 0x9ab0, { \
- { 0x000000c6, 0x000000b9 }, { 0x000001bc, 0x000001bb } } }, \
- { 0x9ab4, { \
- { 0x000000c6, 0x000001bd }, { 0x000001fc, 0x000001fb } } }, \
- { 0x9ab8, { \
- { 0x000000c6, 0x000001fd }, { 0x0000003c, 0x0000003b } } }, \
- { 0x9abc, { \
- { 0x000000c6, 0x0000003d }, { 0x0000007c, 0x0000007b } } }, \
- { 0x9ac0, { \
- { 0x000000c6, 0x0000007d }, { 0x000000bc, 0x000000bb } } }, \
- { 0x9ac4, { \
- { 0x000000c6, 0x000000bd }, { 0x000000fc, 0x000001bc } } }, \
- { 0x9ac8, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000001fc } } }, \
- { 0x9acc, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x0000003c } } }, \
- { 0x9ad0, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x0000007c } } }, \
- { 0x9ad4, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000bc } } }, \
- { 0x9ad8, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9adc, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9ae0, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9ae4, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9ae8, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9aec, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9af0, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9af4, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9af8, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
- { 0x9afc, { \
- { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
-}
-
#endif /* _AR5K_AR5212_VAR_H */
diff --git a/sys/dev/ic/ar5xxx.c b/sys/dev/ic/ar5xxx.c
index e89b50304e0..3d004e34fc6 100644
--- a/sys/dev/ic/ar5xxx.c
+++ b/sys/dev/ic/ar5xxx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5xxx.c,v 1.14 2005/02/23 14:26:54 reyk Exp $ */
+/* $OpenBSD: ar5xxx.c,v 1.15 2005/02/25 22:25:30 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -26,9 +26,7 @@
#include <dev/ic/ar5xxx.h>
extern ar5k_attach_t ar5k_ar5210_attach;
-#ifdef notyet
extern ar5k_attach_t ar5k_ar5211_attach;
-#endif
extern ar5k_attach_t ar5k_ar5212_attach;
static const struct
@@ -51,7 +49,6 @@ static const struct {
ar5k_ar5210_attach },
{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_DEFAULT,
ar5k_ar5210_attach },
-#ifdef notyet
{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211,
ar5k_ar5211_attach },
{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_DEFAULT,
@@ -62,7 +59,6 @@ static const struct {
ar5k_ar5211_attach },
{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_LEGACY,
ar5k_ar5211_attach },
-#endif
{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212,
ar5k_ar5212_attach },
{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_DEFAULT,
@@ -100,6 +96,8 @@ static const struct ar5k_ini_rf ar5111_rf[] =
AR5K_AR5111_INI_RF;
static const struct ar5k_ini_rf ar5112_rf[] =
AR5K_AR5112_INI_RF;
+static const struct ar5k_ini_rfgain ar5k_rfg[] =
+ AR5K_INI_RFGAIN;
/*
* Enable to overwrite the country code (use "00" for debug)
@@ -1493,3 +1491,34 @@ ar5k_ar5112_rfregs(hal, channel, mode)
return (AH_TRUE);
}
+
+HAL_BOOL
+ar5k_rfgain(hal, phy, freq)
+ struct ath_hal *hal;
+ u_int phy, freq;
+{
+ int i;
+
+ switch (phy) {
+ case AR5K_INI_PHY_5111:
+ case AR5K_INI_PHY_5112:
+ break;
+ default:
+ return (AH_FALSE);
+ }
+
+ switch (freq) {
+ case AR5K_INI_RFGAIN_2GHZ:
+ case AR5K_INI_RFGAIN_5GHZ:
+ break;
+ default:
+ return (AH_FALSE);
+ }
+
+ for (i = 0; i < AR5K_ELEMENTS(ar5k_rfg); i++) {
+ AR5K_REG_WRITE((u_int32_t)ar5k_rfg[i].rfg_register,
+ ar5k_rfg[i].rfg_value[phy][freq]);
+ }
+
+ return (AH_TRUE);
+}
diff --git a/sys/dev/ic/ar5xxx.h b/sys/dev/ic/ar5xxx.h
index 433cc6abc65..967f8d2d73d 100644
--- a/sys/dev/ic/ar5xxx.h
+++ b/sys/dev/ic/ar5xxx.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5xxx.h,v 1.11 2005/02/17 23:52:05 reyk Exp $ */
+/* $OpenBSD: ar5xxx.h,v 1.12 2005/02/25 22:25:30 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -1275,6 +1275,10 @@ struct ar5k_ini {
#define AR5K_INI_VAL_XR 0
#define AR5K_INI_VAL_MAX 5
+#define AR5K_INI_PHY_5111 0
+#define AR5K_INI_PHY_5112 1
+#define AR5K_INI_PHY_511X 1
+
#define AR5K_AR5111_INI_RF_MAX_BANKS 8
#define AR5K_AR5112_INI_RF_MAX_BANKS 8
@@ -1377,7 +1381,7 @@ struct ar5k_ini_rf {
{ 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } }, \
}
-#define AR5K_AR5112_INI_RF { \
+#define AR5K_AR5112_INI_RF { \
{ 1, 0x98d4, \
{ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, \
{ 2, 0x98d0, \
@@ -1492,6 +1496,145 @@ struct ar5k_ini_rf {
{ 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } }, \
}
+struct ar5k_ini_rfgain {
+ u_int16_t rfg_register;
+ u_int32_t rfg_value[2][2];
+
+#define AR5K_INI_RFGAIN_5GHZ 0
+#define AR5K_INI_RFGAIN_2GHZ 1
+};
+
+#define AR5K_INI_RFGAIN { \
+ { 0x9a00, { \
+ { 0x000001a9, 0x00000000 }, { 0x00000007, 0x00000007 } } }, \
+ { 0x9a04, { \
+ { 0x000001e9, 0x00000040 }, { 0x00000047, 0x00000047 } } }, \
+ { 0x9a08, { \
+ { 0x00000029, 0x00000080 }, { 0x00000087, 0x00000087 } } }, \
+ { 0x9a0c, { \
+ { 0x00000069, 0x00000150 }, { 0x000001a0, 0x000001a0 } } }, \
+ { 0x9a10, { \
+ { 0x00000199, 0x00000190 }, { 0x000001e0, 0x000001e0 } } }, \
+ { 0x9a14, { \
+ { 0x000001d9, 0x000001d0 }, { 0x00000020, 0x00000020 } } }, \
+ { 0x9a18, { \
+ { 0x00000019, 0x00000010 }, { 0x00000060, 0x00000060 } } }, \
+ { 0x9a1c, { \
+ { 0x00000059, 0x00000044 }, { 0x000001a1, 0x000001a1 } } }, \
+ { 0x9a20, { \
+ { 0x00000099, 0x00000084 }, { 0x000001e1, 0x000001e1 } } }, \
+ { 0x9a24, { \
+ { 0x000001a5, 0x00000148 }, { 0x00000021, 0x00000021 } } }, \
+ { 0x9a28, { \
+ { 0x000001e5, 0x00000188 }, { 0x00000061, 0x00000061 } } }, \
+ { 0x9a2c, { \
+ { 0x00000025, 0x000001c8 }, { 0x00000162, 0x00000162 } } }, \
+ { 0x9a30, { \
+ { 0x000001c8, 0x00000014 }, { 0x000001a2, 0x000001a2 } } }, \
+ { 0x9a34, { \
+ { 0x00000008, 0x00000042 }, { 0x000001e2, 0x000001e2 } } }, \
+ { 0x9a38, { \
+ { 0x00000048, 0x00000082 }, { 0x00000022, 0x00000022 } } }, \
+ { 0x9a3c, { \
+ { 0x00000088, 0x00000178 }, { 0x00000062, 0x00000062 } } }, \
+ { 0x9a40, { \
+ { 0x00000198, 0x000001b8 }, { 0x00000163, 0x00000163 } } }, \
+ { 0x9a44, { \
+ { 0x000001d8, 0x000001f8 }, { 0x000001a3, 0x000001a3 } } }, \
+ { 0x9a48, { \
+ { 0x00000018, 0x00000012 }, { 0x000001e3, 0x000001e3 } } }, \
+ { 0x9a4c, { \
+ { 0x00000058, 0x00000052 }, { 0x00000023, 0x00000023 } } }, \
+ { 0x9a50, { \
+ { 0x00000098, 0x00000092 }, { 0x00000063, 0x00000063 } } }, \
+ { 0x9a54, { \
+ { 0x000001a4, 0x0000017c }, { 0x00000184, 0x00000184 } } }, \
+ { 0x9a58, { \
+ { 0x000001e4, 0x000001bc }, { 0x000001c4, 0x000001c4 } } }, \
+ { 0x9a5c, { \
+ { 0x00000024, 0x000001fc }, { 0x00000004, 0x00000004 } } }, \
+ { 0x9a60, { \
+ { 0x00000064, 0x0000000a }, { 0x000001ea, 0x0000000b } } }, \
+ { 0x9a64, { \
+ { 0x000000a4, 0x0000004a }, { 0x0000002a, 0x0000004b } } }, \
+ { 0x9a68, { \
+ { 0x000000e4, 0x0000008a }, { 0x0000006a, 0x0000008b } } }, \
+ { 0x9a6c, { \
+ { 0x0000010a, 0x0000015a }, { 0x000000aa, 0x000001ac } } }, \
+ { 0x9a70, { \
+ { 0x0000014a, 0x0000019a }, { 0x000001ab, 0x000001ec } } }, \
+ { 0x9a74, { \
+ { 0x0000018a, 0x000001da }, { 0x000001eb, 0x0000002c } } }, \
+ { 0x9a78, { \
+ { 0x000001ca, 0x0000000e }, { 0x0000002b, 0x00000012 } } }, \
+ { 0x9a7c, { \
+ { 0x0000000a, 0x0000004e }, { 0x0000006b, 0x00000052 } } }, \
+ { 0x9a80, { \
+ { 0x0000004a, 0x0000008e }, { 0x000000ab, 0x00000092 } } }, \
+ { 0x9a84, { \
+ { 0x0000008a, 0x0000015e }, { 0x000001ac, 0x00000193 } } }, \
+ { 0x9a88, { \
+ { 0x000001ba, 0x0000019e }, { 0x000001ec, 0x000001d3 } } }, \
+ { 0x9a8c, { \
+ { 0x000001fa, 0x000001de }, { 0x0000002c, 0x00000013 } } }, \
+ { 0x9a90, { \
+ { 0x0000003a, 0x00000009 }, { 0x0000003a, 0x00000053 } } }, \
+ { 0x9a94, { \
+ { 0x0000007a, 0x00000049 }, { 0x0000007a, 0x00000093 } } }, \
+ { 0x9a98, { \
+ { 0x00000186, 0x00000089 }, { 0x000000ba, 0x00000194 } } }, \
+ { 0x9a9c, { \
+ { 0x000001c6, 0x00000179 }, { 0x000001bb, 0x000001d4 } } }, \
+ { 0x9aa0, { \
+ { 0x00000006, 0x000001b9 }, { 0x000001fb, 0x00000014 } } }, \
+ { 0x9aa4, { \
+ { 0x00000046, 0x000001f9 }, { 0x0000003b, 0x0000003a } } }, \
+ { 0x9aa8, { \
+ { 0x00000086, 0x00000039 }, { 0x0000007b, 0x0000007a } } }, \
+ { 0x9aac, { \
+ { 0x000000c6, 0x00000079 }, { 0x000000bb, 0x000000ba } } }, \
+ { 0x9ab0, { \
+ { 0x000000c6, 0x000000b9 }, { 0x000001bc, 0x000001bb } } }, \
+ { 0x9ab4, { \
+ { 0x000000c6, 0x000001bd }, { 0x000001fc, 0x000001fb } } }, \
+ { 0x9ab8, { \
+ { 0x000000c6, 0x000001fd }, { 0x0000003c, 0x0000003b } } }, \
+ { 0x9abc, { \
+ { 0x000000c6, 0x0000003d }, { 0x0000007c, 0x0000007b } } }, \
+ { 0x9ac0, { \
+ { 0x000000c6, 0x0000007d }, { 0x000000bc, 0x000000bb } } }, \
+ { 0x9ac4, { \
+ { 0x000000c6, 0x000000bd }, { 0x000000fc, 0x000001bc } } }, \
+ { 0x9ac8, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000001fc } } }, \
+ { 0x9acc, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x0000003c } } }, \
+ { 0x9ad0, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x0000007c } } }, \
+ { 0x9ad4, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000bc } } }, \
+ { 0x9ad8, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9adc, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9ae0, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9ae4, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9ae8, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9aec, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9af0, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9af4, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9af8, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+ { 0x9afc, { \
+ { 0x000000c6, 0x000000fd }, { 0x000000fc, 0x000000fc } } }, \
+}
+
/*
* Prototypes
*/
@@ -1532,6 +1675,7 @@ HAL_BOOL ar5k_eeprom_regulation_domain(struct ath_hal *,
HAL_BOOL ar5k_channel(struct ath_hal *, HAL_CHANNEL *);
HAL_BOOL ar5k_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
+HAL_BOOL ar5k_rfgain(struct ath_hal *, u_int, u_int);
__END_DECLS