summaryrefslogtreecommitdiff
path: root/sys/dev/ic/ar5211.c
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2005-04-20 01:46:03 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2005-04-20 01:46:03 +0000
commitc20cf1c180724966b544b8dd1ce3af25cce428e3 (patch)
treed334fdf35e1d612062d5d18cac1ba8aee1ed835c /sys/dev/ic/ar5211.c
parent784482667e41bda24cf73adfe9ffdb740ec356b5 (diff)
support 11b and 11a mode on the ar5211. "pure" 11g mode is not yet
tested but should work as well. thanks for the hardware donation!
Diffstat (limited to 'sys/dev/ic/ar5211.c')
-rw-r--r--sys/dev/ic/ar5211.c79
1 files changed, 75 insertions, 4 deletions
diff --git a/sys/dev/ic/ar5211.c b/sys/dev/ic/ar5211.c
index dc5f260e203..8796279a0a4 100644
--- a/sys/dev/ic/ar5211.c
+++ b/sys/dev/ic/ar5211.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5211.c,v 1.11 2005/04/18 18:42:55 reyk Exp $ */
+/* $OpenBSD: ar5211.c,v 1.12 2005/04/20 01:46:02 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -29,6 +29,8 @@ 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 *);
+void ar5k_ar5211_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int,
+ u_int);
/*
* Initial register setting for the AR5211
@@ -37,6 +39,8 @@ static const struct ar5k_ini ar5211_ini[] =
AR5K_AR5211_INI;
static const struct ar5k_ar5211_ini_mode ar5211_mode[] =
AR5K_AR5211_INI_MODE;
+static const struct ar5k_ar5211_ini_rf ar5211_rf[] =
+ AR5K_AR5211_INI_RF;
AR5K_HAL_FUNCTIONS(extern, ar5k_ar5211,);
@@ -398,9 +402,6 @@ void
ar5k_ar5211_detach(hal)
struct ath_hal *hal;
{
- if (hal->ah_rf_banks != NULL)
- free(hal->ah_rf_banks, M_DEVBUF);
-
/*
* Free HAL structure, assume interrupts are down
*/
@@ -469,6 +470,11 @@ ar5k_ar5211_reset(hal, op_mode, channel, change_channel, status)
AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);
/*
+ * Write initial RF registers
+ */
+ ar5k_ar5211_rfregs(hal, channel, freq, ee_mode);
+
+ /*
* Write initial mode settings
*/
for (i = 0; i < AR5K_ELEMENTS(ar5211_mode); i++) {
@@ -2618,3 +2624,68 @@ ar5k_ar5211_eeprom_write(hal, offset, data)
return (ETIMEDOUT);
}
+
+/*
+ * RF register settings
+ */
+
+void
+ar5k_ar5211_rfregs(hal, channel, freq, ee_mode)
+ struct ath_hal *hal;
+ HAL_CHANNEL *channel;
+ u_int freq, ee_mode;
+{
+ struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
+ struct ar5k_ar5211_ini_rf rf[AR5K_ELEMENTS(ar5211_rf)];
+ u_int32_t ob, db, obdb, xpds, xpdp, x_gain;
+ u_int i;
+
+ bcopy(ar5211_rf, rf, sizeof(rf));
+ obdb = 0;
+
+ if (freq == AR5K_INI_RFGAIN_2GHZ &&
+ hal->ah_ee_version >= AR5K_EEPROM_VERSION_3_1) {
+ ob = ar5k_bitswap(ee->ee_ob[ee_mode][0], 3);
+ db = ar5k_bitswap(ee->ee_db[ee_mode][0], 3);
+ rf[25].rf_value[freq] =
+ ((ob << 6) & 0xc0) | (rf[25].rf_value[freq] & ~0xc0);
+ rf[26].rf_value[freq] =
+ (((ob >> 2) & 0x1) | ((db << 1) & 0xe)) |
+ (rf[26].rf_value[freq] & ~0xf);
+ }
+
+ if (freq == AR5K_INI_RFGAIN_5GHZ) {
+ /* For 11a and Turbo */
+ obdb = channel->c_channel >= 5725 ? 3 :
+ (channel->c_channel >= 5500 ? 2 :
+ (channel->c_channel >= 5260 ? 1 :
+ (channel->c_channel > 4000 ? 0 : -1)));
+ }
+
+ ob = ee->ee_ob[ee_mode][obdb];
+ db = ee->ee_db[ee_mode][obdb];
+ x_gain = ee->ee_x_gain[ee_mode];
+ xpds = ee->ee_xpd[ee_mode];
+ xpdp = !xpds;
+
+ rf[11].rf_value[freq] = (rf[11].rf_value[freq] & ~0xc0) |
+ (((ar5k_bitswap(x_gain, 4) << 7) | (xpdp << 6)) & 0xc0);
+ rf[12].rf_value[freq] = (rf[12].rf_value[freq] & ~0x7) |
+ ((ar5k_bitswap(x_gain, 4) >> 1) & 0x7);
+ rf[12].rf_value[freq] = (rf[12].rf_value[freq] & ~0x80) |
+ ((ar5k_bitswap(ob, 3) << 7) & 0x80);
+ rf[13].rf_value[freq] = (rf[13].rf_value[freq] & ~0x3) |
+ ((ar5k_bitswap(ob, 3) >> 1) & 0x3);
+ rf[13].rf_value[freq] = (rf[13].rf_value[freq] & ~0x1c) |
+ ((ar5k_bitswap(db, 3) << 2) & 0x1c);
+ rf[17].rf_value[freq] = (rf[17].rf_value[freq] & ~0x8) |
+ ((xpds << 3) & 0x8);
+
+ for (i = 0; i < AR5K_ELEMENTS(rf); i++) {
+ AR5K_REG_WAIT(i);
+ AR5K_REG_WRITE((u_int32_t)rf[i].rf_register,
+ rf[i].rf_value[freq]);
+ }
+
+ hal->ah_rf_gain = HAL_RFGAIN_INACTIVE;
+}