summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2005-03-19 17:27:47 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2005-03-19 17:27:47 +0000
commit5023fb2558e98d84e2eb680b4696bdbd4b952e2d (patch)
tree886eac1c5be6d52ed41eb862057e4e3a1a532265 /sys/dev
parent92f86cf6541a5bfb8abd1fc903ab64381d02d64c (diff)
further fixes for ar5212.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/ar5211.c54
-rw-r--r--sys/dev/ic/ar5211reg.h5
-rw-r--r--sys/dev/ic/ar5212.c112
-rw-r--r--sys/dev/ic/ar5xxx.c99
-rw-r--r--sys/dev/ic/ar5xxx.h21
-rw-r--r--sys/dev/ic/ath.c7
6 files changed, 221 insertions, 77 deletions
diff --git a/sys/dev/ic/ar5211.c b/sys/dev/ic/ar5211.c
index 8a1e9429386..7c90537554b 100644
--- a/sys/dev/ic/ar5211.c
+++ b/sys/dev/ic/ar5211.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5211.c,v 1.4 2005/03/13 18:32:21 reyk Exp $ */
+/* $OpenBSD: ar5211.c,v 1.5 2005/03/19 17:27:46 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -398,6 +398,9 @@ void
ar5k_ar5211_detach(hal)
struct ath_hal *hal;
{
+ if (hal->ah_rf_banks != NULL)
+ free(hal, M_DEVBUF);
+
/*
* Free HAL structure, assume interrupts are down
*/
@@ -414,9 +417,25 @@ ar5k_ar5211_reset(hal, op_mode, channel, change_channel, status)
{
struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
u_int8_t mac[IEEE80211_ADDR_LEN];
- u_int32_t data;
+ u_int32_t data, s_seq, s_ant, s_led[3];
u_int i, mode, freq, ee_mode, ant[2];
+ /*
+ * Save some registers before a reset
+ */
+ if (change_channel == AH_TRUE) {
+ s_seq = AR5K_REG_READ(AR5K_AR5211_DCU_SEQNUM(0));
+ s_ant = AR5K_REG_READ(AR5K_AR5211_DEFAULT_ANTENNA);
+ } else {
+ s_seq = 0;
+ s_ant = 1;
+ }
+
+ s_led[0] = AR5K_REG_READ(AR5K_AR5211_PCICFG) &
+ AR5K_AR5211_PCICFG_LEDSTATE;
+ s_led[1] = AR5K_REG_READ(AR5K_AR5211_GPIOCR);
+ s_led[2] = AR5K_REG_READ(AR5K_AR5211_GPIODO);
+
if (ar5k_ar5211_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)
return (AH_FALSE);
@@ -450,6 +469,15 @@ ar5k_ar5211_reset(hal, op_mode, channel, change_channel, status)
AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);
/*
+ * Write initial mode settings
+ */
+ for (i = 0; i < AR5K_ELEMENTS(ar5211_mode); i++) {
+ AR5K_REG_WAIT(i);
+ AR5K_REG_WRITE((u_int32_t)ar5211_mode[i].mode_register,
+ ar5211_mode[i].mode_value[mode]);
+ }
+
+ /*
* Write initial register settings
*/
for (i = 0; i < AR5K_ELEMENTS(ar5211_ini); i++) {
@@ -458,19 +486,12 @@ ar5k_ar5211_reset(hal, op_mode, channel, change_channel, status)
ar5211_ini[i].ini_register <= AR5K_AR5211_PCU_MAX)
continue;
+ AR5K_REG_WAIT(i);
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)
@@ -533,7 +554,18 @@ ar5k_ar5211_reset(hal, op_mode, channel, change_channel, status)
(ee->ee_i_cal[ee_mode] << AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF_S) |
ee->ee_q_cal[ee_mode]);
- /* Misc */
+ /*
+ * Restore saved values
+ */
+ AR5K_REG_WRITE(AR5K_AR5211_DCU_SEQNUM(0), s_seq);
+ AR5K_REG_WRITE(AR5K_AR5211_DEFAULT_ANTENNA, s_ant);
+ AR5K_REG_ENABLE_BITS(AR5K_AR5211_PCICFG, s_led[0]);
+ AR5K_REG_WRITE(AR5K_AR5211_GPIOCR, s_led[1]);
+ AR5K_REG_WRITE(AR5K_AR5211_GPIODO, s_led[2]);
+
+ /*
+ * Misc
+ */
bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
ar5k_ar5211_writeAssocid(hal, mac, 0, 0);
ar5k_ar5211_setPCUConfig(hal);
diff --git a/sys/dev/ic/ar5211reg.h b/sys/dev/ic/ar5211reg.h
index 197bc0300c7..7ffe70b110f 100644
--- a/sys/dev/ic/ar5211reg.h
+++ b/sys/dev/ic/ar5211reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5211reg.h,v 1.2 2005/03/10 08:30:56 reyk Exp $ */
+/* $OpenBSD: ar5211reg.h,v 1.3 2005/03/19 17:27:46 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -597,6 +597,9 @@ typedef enum {
#define AR5K_AR5211_PCICFG_LEDBLINK 0x00700000
#define AR5K_AR5211_PCICFG_LEDBLINK_S 20
#define AR5K_AR5211_PCICFG_LEDSLOW 0x00800000
+#define AR5K_AR5211_PCICFG_LEDSTATE \
+ (AR5K_AR5211_PCICFG_LED | AR5K_AR5211_PCICFG_LEDMODE | \
+ AR5K_AR5211_PCICFG_LEDBLINK | AR5K_AR5211_PCICFG_LEDSLOW)
/*
* "General Purpose Input/Output" (GPIO) control register
diff --git a/sys/dev/ic/ar5212.c b/sys/dev/ic/ar5212.c
index b7dfd0d586d..87a02b651c2 100644
--- a/sys/dev/ic/ar5212.c
+++ b/sys/dev/ic/ar5212.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5212.c,v 1.7 2005/03/18 20:46:32 reyk Exp $ */
+/* $OpenBSD: ar5212.c,v 1.8 2005/03/19 17:27:46 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -410,6 +410,9 @@ void
ar5k_ar5212_detach(hal)
struct ath_hal *hal;
{
+ if (hal->ah_rf_banks != NULL)
+ free(hal, M_DEVBUF);
+
/*
* Free HAL structure, assume interrupts are down
*/
@@ -446,7 +449,8 @@ ar5k_ar5212_reset(hal, op_mode, channel, change_channel, status)
s_led[1] = AR5K_REG_READ(AR5K_AR5212_GPIOCR);
s_led[2] = AR5K_REG_READ(AR5K_AR5212_GPIODO);
- ar5k_ar5212_getRfGain(hal);
+ if (change_channel == AH_TRUE && hal->ah_rf_banks != NULL)
+ ar5k_ar5212_getRfGain(hal);
if (ar5k_ar5212_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)
return (AH_FALSE);
@@ -456,6 +460,15 @@ ar5k_ar5212_reset(hal, op_mode, channel, change_channel, status)
*/
hal->ah_op_mode = op_mode;
+ if (hal->ah_radio == AR5K_AR5111) {
+ phy = AR5K_INI_PHY_5111;
+ } else if (hal->ah_radio == AR5K_AR5112) {
+ phy = AR5K_INI_PHY_5112;
+ } else {
+ AR5K_PRINTF("invalid phy radio: %u\n", hal->ah_radio);
+ return (AH_FALSE);
+ }
+
if (channel->c_channel_flags & IEEE80211_CHAN_A) {
mode = AR5K_INI_VAL_11A;
freq = AR5K_INI_RFGAIN_5GHZ;
@@ -489,27 +502,6 @@ ar5k_ar5212_reset(hal, op_mode, channel, change_channel, status)
AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
/*
- * Write initial register settings
- */
- for (i = 0; i < AR5K_ELEMENTS(ar5212_ini); i++) {
- if (change_channel == AH_TRUE &&
- ar5212_ini[i].ini_register >= AR5K_AR5212_PCU_MIN &&
- ar5212_ini[i].ini_register <= AR5K_AR5212_PCU_MAX)
- continue;
-
- if (hal->ah_radio == AR5K_AR5112) {
- if (!(ar5212_mode[i].mode_flags & AR5K_INI_FLAG_5112))
- continue;
- } else {
- if (!(ar5212_mode[i].mode_flags & AR5K_INI_FLAG_5111))
- continue;
- }
-
- AR5K_REG_WRITE((u_int32_t)ar5212_ini[i].ini_register,
- ar5212_ini[i].ini_value);
- }
-
- /*
* Write initial mode settings
*/
for (i = 0; i < AR5K_ELEMENTS(ar5212_mode); i++) {
@@ -524,11 +516,39 @@ ar5k_ar5212_reset(hal, op_mode, channel, change_channel, status)
else
continue;
+ AR5K_REG_WAIT(i);
AR5K_REG_WRITE((u_int32_t)ar5212_mode[i].mode_register,
ar5212_mode[i].mode_value[phy][mode]);
}
/*
+ * Write initial register settings
+ */
+ for (i = 0; i < AR5K_ELEMENTS(ar5212_ini); i++) {
+ if (change_channel == AH_TRUE &&
+ ar5212_ini[i].ini_register >= AR5K_AR5212_PCU_MIN &&
+ ar5212_ini[i].ini_register <= AR5K_AR5212_PCU_MAX)
+ continue;
+
+ if ((hal->ah_radio == AR5K_AR5111 &&
+ ar5212_ini[i].ini_flags & AR5K_INI_FLAG_5111) ||
+ (hal->ah_radio == AR5K_AR5112 &&
+ ar5212_ini[i].ini_flags & AR5K_INI_FLAG_5112)) {
+ AR5K_REG_WAIT(i);
+ AR5K_REG_WRITE((u_int32_t)ar5212_ini[i].ini_register,
+ ar5212_ini[i].ini_value);
+ }
+ }
+
+ /*
+ * Write initial RF gain settings
+ */
+ if (ar5k_rfgain(hal, phy, freq) == AH_FALSE)
+ return (AH_FALSE);
+
+ AR5K_DELAY(1000);
+
+ /*
* Set rate duration table
*/
rt = ar5k_ar5212_getRateTable(hal,
@@ -558,20 +578,10 @@ ar5k_ar5212_reset(hal, op_mode, channel, change_channel, status)
}
/*
- * Write initial RF gain settings
- */
- phy = hal->ah_radio == AR5K_AR5112 ?
- AR5K_INI_PHY_5112 : AR5K_INI_PHY_5111;
- if (ar5k_rfgain(hal, phy, freq) == AH_FALSE)
- return (AH_FALSE);
-
- AR5K_DELAY(1000);
-
- /*
- * Set TX power
+ * Set TX power (XXX use txpower from net80211)
*/
if (ar5k_ar5212_txpower(hal, channel,
- hal->ah_txpower.txp_max) == AH_FALSE)
+ AR5K_TUNE_DEFAULT_TXPOWER) == AH_FALSE)
return (AH_FALSE);
/*
@@ -842,6 +852,15 @@ ar5k_ar5212_perCalibration(hal, channel)
AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
AR5K_AR5212_PHY_AGCCTL_NF);
+ /* Request RF gain */
+ if (channel->c_channel_flags & IEEE80211_CHAN_5GHZ) {
+ AR5K_REG_WRITE(AR5K_AR5212_PHY_PAPD_PROBE,
+ AR5K_REG_SM(hal->ah_txpower.txp_max,
+ AR5K_AR5212_PHY_PAPD_PROBE_TXPOWER) |
+ AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT);
+ hal->ah_rf_gain = HAL_RFGAIN_READ_REQUESTED;
+ }
+
return (AH_TRUE);
}
@@ -1541,8 +1560,8 @@ ar5k_ar5212_getRxFilter(hal)
if (data & AR5K_AR5212_PHY_ERR_FIL_RADAR)
filter |= HAL_RX_FILTER_PHYRADAR;
- if (data & (AR5K_AR5212_PHY_ERR_FIL_OFDM|
- AR5K_AR5212_PHY_ERR_FIL_CCK))
+ if (data & (AR5K_AR5212_PHY_ERR_FIL_OFDM |
+ AR5K_AR5212_PHY_ERR_FIL_CCK))
filter |= HAL_RX_FILTER_PHYERR;
return (filter);
@@ -2082,7 +2101,7 @@ ar5k_ar5212_getRfGain(hal)
{
u_int32_t data, type;
- if (!hal->ah_gain.g_active)
+ if ((hal->ah_rf_banks == NULL) || (!hal->ah_gain.g_active))
return (HAL_RFGAIN_INACTIVE);
if (hal->ah_rf_gain != HAL_RFGAIN_READ_REQUESTED)
@@ -2911,14 +2930,26 @@ ar5k_ar5212_txpower(hal, channel, txpower)
HAL_CHANNEL *channel;
u_int txpower;
{
+ HAL_BOOL tpc = hal->ah_txpower.txp_tpc;
+ int i;
+
if (txpower > AR5K_TUNE_MAX_TXPOWER) {
AR5K_PRINTF("invalid tx power: %u\n", txpower);
return (AH_FALSE);
}
-#ifdef notyet
+ /* Reset TX power values */
+ bzero(&hal->ah_txpower, sizeof(hal->ah_txpower));
+ hal->ah_txpower.txp_tpc = tpc;
+
+ /* Initialize TX power table */
+ ar5k_txpower_table(hal, channel, txpower);
+
+ /*
+ * Write TX power values
+ */
for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
- AR5K_REG_WRITE(ah, AR5K_AR5212_PHY_PCDAC_TXPOWER(i),
+ AR5K_REG_WRITE(AR5K_AR5212_PHY_PCDAC_TXPOWER(i),
((((hal->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) &
0xffff) << 16) | (((hal->ah_txpower.txp_pcdac[i << 1] << 8)
| 0xff) & 0xffff));
@@ -2939,7 +2970,6 @@ ar5k_ar5212_txpower(hal, channel, txpower)
AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE4,
AR5K_TXPOWER_CCK(14, 24) | AR5K_TXPOWER_CCK(13, 16)
| AR5K_TXPOWER_CCK(12, 8) | AR5K_TXPOWER_CCK(11, 0));
-#endif
if (hal->ah_txpower.txp_tpc == AH_TRUE) {
AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
diff --git a/sys/dev/ic/ar5xxx.c b/sys/dev/ic/ar5xxx.c
index 6532bed0be6..d08a9534548 100644
--- a/sys/dev/ic/ar5xxx.c
+++ b/sys/dev/ic/ar5xxx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5xxx.c,v 1.18 2005/03/18 20:46:32 reyk Exp $ */
+/* $OpenBSD: ar5xxx.c,v 1.19 2005/03/19 17:27:46 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -80,7 +80,7 @@ HAL_BOOL ar5k_check_channel(struct ath_hal *, u_int16_t, u_int flags);
HAL_BOOL ar5k_ar5111_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
HAL_BOOL ar5k_ar5112_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
-int ar5k_rfregs_op(u_int32_t *, u_int32_t, u_int32_t, u_int32_t,
+u_int ar5k_rfregs_op(u_int32_t *, u_int32_t, u_int32_t, u_int32_t,
u_int32_t, u_int32_t, HAL_BOOL);
/*
@@ -206,7 +206,7 @@ ath_hal_attach(device, sc, st, sh, status)
hal->ah_software_retry = AH_FALSE;
hal->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
- if (attach(device, hal, st, sh, status) == NULL)
+ if ((attach)(device, hal, st, sh, status) == NULL)
goto failed;
#ifdef AR5K_DEBUG
@@ -1297,7 +1297,7 @@ ar5k_ar5112_channel(hal, channel)
return (AH_TRUE);
}
-int
+u_int
ar5k_rfregs_op(rf, offset, reg, bits, first, col, set)
u_int32_t *rf;
u_int32_t offset, reg, bits, first, col;
@@ -1307,6 +1307,11 @@ ar5k_rfregs_op(rf, offset, reg, bits, first, col, set)
int32_t left;
int i;
+ if (rf == NULL) {
+ /* should not happen */
+ return (0);
+ }
+
if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
AR5K_PRINTF("invalid values at offset %u\n", offset);
return (0);
@@ -1346,13 +1351,18 @@ ar5k_rfregs_gainf_corr(hal)
struct ath_hal *hal;
{
u_int32_t mix, step;
+ u_int32_t *rf;
+
+ if (hal->ah_rf_banks == NULL)
+ return (0);
+ rf = hal->ah_rf_banks;
hal->ah_gain.g_f_corr = 0;
- if (ar5k_rfregs_op(NULL, hal->ah_offset[7], 0, 1, 36, 0, AH_FALSE) != 1)
+ if (ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 1, 36, 0, AH_FALSE) != 1)
return (0);
- step = ar5k_rfregs_op(NULL, hal->ah_offset[7], 0, 4, 32, 0, AH_FALSE);
+ step = ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 4, 32, 0, AH_FALSE);
mix = hal->ah_gain.g_step->gos_param[0];
switch (mix) {
@@ -1378,9 +1388,15 @@ ar5k_rfregs_gain_readback(hal)
struct ath_hal *hal;
{
u_int32_t step, mix, level[4];
+ u_int32_t *rf;
+
+ if (hal->ah_rf_banks == NULL)
+ return (0);
+
+ rf = hal->ah_rf_banks;
if (hal->ah_radio == AR5K_AR5111) {
- step = ar5k_rfregs_op(NULL, hal->ah_offset[7],
+ step = ar5k_rfregs_op(rf, hal->ah_offset[7],
0, 6, 37, 0, AH_FALSE);
level[0] = 0;
level[1] = (step == 0x3f) ? 0x32 : step + 4;
@@ -1392,7 +1408,7 @@ ar5k_rfregs_gain_readback(hal)
hal->ah_gain.g_low = level[0] +
(step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
} else {
- mix = ar5k_rfregs_op(NULL, hal->ah_offset[7],
+ mix = ar5k_rfregs_op(rf, hal->ah_offset[7],
0, 1, 36, 0, AH_FALSE);
level[0] = level[2] = 0;
@@ -1474,15 +1490,28 @@ ar5k_rfregs(hal, channel, mode)
HAL_CHANNEL *channel;
u_int mode;
{
+ ar5k_rfgain_t *func = NULL;
HAL_BOOL ret;
- if (hal->ah_radio < AR5K_AR5111)
+ if (hal->ah_radio == AR5K_AR5111) {
+ hal->ah_rf_banks_size = sizeof(ar5111_rf);
+ func = ar5k_ar5111_rfregs;
+ } else if (hal->ah_radio == AR5K_AR5112) {
+ hal->ah_rf_banks_size = sizeof(ar5112_rf);
+ func = ar5k_ar5112_rfregs;
+ } else
return (AH_FALSE);
- if (hal->ah_radio == AR5K_AR5111)
- ret = ar5k_ar5111_rfregs(hal, channel, mode);
- else
- ret = ar5k_ar5112_rfregs(hal, channel, mode);
+ if (hal->ah_rf_banks == NULL) {
+ /* XXX do extra checks? */
+ if ((hal->ah_rf_banks =
+ malloc(hal->ah_rf_banks_size, M_DEVBUF, M_NOWAIT)) == NULL) {
+ AR5K_PRINT("out of memory\n");
+ return (AH_FALSE);
+ }
+ }
+
+ ret = (func)(hal, channel, mode);
if (ret == AH_TRUE)
hal->ah_rf_gain = HAL_RFGAIN_INACTIVE;
@@ -1498,12 +1527,14 @@ ar5k_ar5111_rfregs(hal, channel, mode)
{
struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
const u_int rf_size = AR5K_ELEMENTS(ar5111_rf);
- u_int32_t rf[rf_size];
+ u_int32_t *rf;
int i, obdb = -1, bank = -1;
u_int32_t ee_mode;
AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
+ rf = hal->ah_rf_banks;
+
/* Copy values to modify them */
for (i = 0; i < rf_size; i++) {
if (ar5111_rf[i].rf_bank >=
@@ -1579,8 +1610,8 @@ ar5k_ar5111_rfregs(hal, channel, mode)
/* Write RF values */
for (i = 0; i < rf_size; i++) {
+ AR5K_REG_WAIT(i);
AR5K_REG_WRITE(ar5111_rf[i].rf_register, rf[i]);
- AR5K_DELAY(1);
}
return (AH_TRUE);
@@ -1594,12 +1625,14 @@ ar5k_ar5112_rfregs(hal, channel, mode)
{
struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
const u_int rf_size = AR5K_ELEMENTS(ar5112_rf);
- u_int32_t rf[rf_size];
+ u_int32_t *rf;
int i, obdb = -1, bank = -1;
u_int32_t ee_mode;
AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
+ rf = hal->ah_rf_banks;
+
/* Copy values to modify them */
for (i = 0; i < rf_size; i++) {
if (ar5112_rf[i].rf_bank >=
@@ -1695,9 +1728,43 @@ ar5k_rfgain(hal, phy, freq)
}
for (i = 0; i < AR5K_ELEMENTS(ar5k_rfg); i++) {
+ AR5K_REG_WAIT(i);
AR5K_REG_WRITE((u_int32_t)ar5k_rfg[i].rfg_register,
ar5k_rfg[i].rfg_value[phy][freq]);
}
return (AH_TRUE);
}
+
+/*
+ * Common TX power setup
+ */
+void
+ar5k_txpower_table(hal, channel, max_power)
+ struct ath_hal *hal;
+ HAL_CHANNEL *channel;
+ int16_t max_power;
+{
+ u_int16_t txpower, *rates;
+ int i;
+
+ rates = hal->ah_txpower.txp_rates;
+
+ txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
+ if (max_power > txpower) {
+ txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
+ AR5K_TUNE_MAX_TXPOWER : max_power;
+ }
+
+ for (i = 0; i < AR5K_MAX_RATES; i++)
+ rates[i] = txpower;
+
+ /* XXX setup target powers by rate */
+
+ hal->ah_txpower.txp_min = rates[7];
+ hal->ah_txpower.txp_max = rates[0];
+ hal->ah_txpower.txp_ofdm = rates[0];
+
+ for (i = 0; i < AR5K_ELEMENTS(hal->ah_txpower.txp_pcdac); i++)
+ hal->ah_txpower.txp_pcdac[i] = AR5K_EEPROM_PCDAC_START;
+}
diff --git a/sys/dev/ic/ar5xxx.h b/sys/dev/ic/ar5xxx.h
index facb48e9182..e448bd15607 100644
--- a/sys/dev/ic/ar5xxx.h
+++ b/sys/dev/ic/ar5xxx.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5xxx.h,v 1.13 2005/03/18 20:46:32 reyk Exp $ */
+/* $OpenBSD: ar5xxx.h,v 1.14 2005/03/19 17:27:46 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -773,8 +773,6 @@ struct ar5k_eeprom_info {
int16_t ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
int8_t ee_adc_desired_size[AR5K_EEPROM_N_MODES];
int8_t ee_pga_desired_size[AR5K_EEPROM_N_MODES];
-
-
};
/*
@@ -1145,6 +1143,8 @@ struct ath_hal {
HAL_TXQ_INFO ah_txq[HAL_NUM_TX_QUEUES];
u_int32_t ah_txq_interrupts;
+ u_int32_t *ah_rf_banks;
+ size_t ah_rf_banks_size;
struct ar5k_gain ah_gain;
u_int32_t ah_offset[AR5K_MAX_RF_BANKS];
@@ -1153,6 +1153,7 @@ struct ath_hal {
u_int16_t txp_rates[AR5K_MAX_RATES];
int16_t txp_min, txp_max;
HAL_BOOL txp_tpc;
+ int16_t txp_ofdm;
} ah_txpower;
struct {
@@ -1208,8 +1209,10 @@ struct ath_hal {
#define AR5K_DELAY(_n) delay(_n)
#define AR5K_ELEMENTS(_array) (sizeof(_array) / sizeof(_array[0]))
-typedef struct ath_hal*(ar5k_attach_t)
+typedef struct ath_hal * (ar5k_attach_t)
(u_int16_t, void *, bus_space_tag_t, bus_space_handle_t, HAL_STATUS *);
+typedef HAL_BOOL (ar5k_rfgain_t)
+ (struct ath_hal *, HAL_CHANNEL *, u_int);
/*
* Some tuneable values (these should be changeable by the user)
@@ -1236,7 +1239,8 @@ typedef struct ath_hal*(ar5k_attach_t)
#define AR5K_TUNE_CWMAX_XR 7
#define AR5K_TUNE_NOISE_FLOOR -72
#define AR5K_TUNE_MAX_TXPOWER 60
-#define AR5K_TUNE_TPC_TXPOWER AH_FALSE
+#define AR5K_TUNE_DEFAULT_TXPOWER 30
+#define AR5K_TUNE_TPC_TXPOWER AH_TRUE
#define AR5K_TUNE_ANT_DIVERSITY AH_TRUE
/* Default regulation domain if stored value EEPROM value is invalid */
@@ -1327,6 +1331,10 @@ typedef struct ath_hal*(ar5k_attach_t)
#define AR5K_PHY_READ(_reg) \
AR5K_REG_READ(hal->ah_phy + ((_reg) << 2))
+#define AR5K_REG_WAIT(_i) \
+ if (_i % 64) \
+ AR5K_DELAY(1);
+
#define AR5K_EEPROM_READ(_o, _v) { \
if ((ret = hal->ah_eeprom_read(hal, (_o), \
&(_v))) != 0) \
@@ -1797,6 +1805,9 @@ HAL_BOOL ar5k_rfregs_gain_readback(struct ath_hal *);
int32_t ar5k_rfregs_gain_adjust(struct ath_hal *);
HAL_BOOL ar5k_rfgain(struct ath_hal *, u_int, u_int);
+void ar5k_txpower_table(struct ath_hal *, HAL_CHANNEL *,
+ int16_t);
+
__END_DECLS
#endif /* _AR5K_H */
diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c
index 9e6a36eb597..87647fff906 100644
--- a/sys/dev/ic/ath.c
+++ b/sys/dev/ic/ath.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ath.c,v 1.15 2005/03/18 21:37:56 reyk Exp $ */
+/* $OpenBSD: ath.c,v 1.16 2005/03/19 17:27:46 reyk Exp $ */
/* $NetBSD: ath.c,v 1.37 2004/08/18 21:59:39 dyoung Exp $ */
/*-
@@ -2988,8 +2988,9 @@ ath_getchannels(struct ath_softc *sc, u_int cc, HAL_BOOL outdoor,
free(chans, M_TEMP);
if (sc->sc_nchan < 1) {
- if_printf(ifp, "no valid channels for regdomain %s\n",
- ieee80211_regdomain2name(ath_regdomain));
+ if_printf(ifp, "no valid channels for regdomain %s(%u)\n",
+ ieee80211_regdomain2name(ath_regdomain),
+ sc->sc_ah->ah_capabilities.cap_eeprom.ee_regdomain);
return ENOENT;
}