diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-04-20 01:46:03 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-04-20 01:46:03 +0000 |
commit | c20cf1c180724966b544b8dd1ce3af25cce428e3 (patch) | |
tree | d334fdf35e1d612062d5d18cac1ba8aee1ed835c /sys/dev/ic/ar5211.c | |
parent | 784482667e41bda24cf73adfe9ffdb740ec356b5 (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.c | 79 |
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; +} |