aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorNick Kossifidis <mick@madwifi-project.org>2009-04-30 15:55:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-06 15:14:56 -0400
commit2bed03ebf62f9d013a455209bf30d7e086120443 (patch)
tree35592ca12f0e4425213e317895612c3ce15ad3a5 /drivers/net/wireless/ath
parent6f5f39c95af519c24c0187950147eb79d07d1940 (diff)
ath5k: Implement antenna control
* Add code to support the various antenna scenarios supported by hw * For now hardcode the default scenario (single or dual omnis with tx/rx diversity working and tx antenna handled by session -hw keeps track on which antenna it got ack from each ap/station and maps each ap/station to one of the antennas-). Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: Bob Copeland <me@bobcopeland.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h25
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c66
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c8
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h11
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c174
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h9
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c28
8 files changed, 271 insertions, 51 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 04b73453f6a5..33da290e4bb5 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -209,7 +209,6 @@
209#define AR5K_TUNE_MAX_TXPOWER 63 209#define AR5K_TUNE_MAX_TXPOWER 63
210#define AR5K_TUNE_DEFAULT_TXPOWER 25 210#define AR5K_TUNE_DEFAULT_TXPOWER 25
211#define AR5K_TUNE_TPC_TXPOWER false 211#define AR5K_TUNE_TPC_TXPOWER false
212#define AR5K_TUNE_ANT_DIVERSITY true
213#define AR5K_TUNE_HWTXTRIES 4 212#define AR5K_TUNE_HWTXTRIES 4
214 213
215#define AR5K_INIT_CARR_SENSE_EN 1 214#define AR5K_INIT_CARR_SENSE_EN 1
@@ -420,6 +419,17 @@ enum ath5k_driver_mode {
420 AR5K_MODE_MAX = 5 419 AR5K_MODE_MAX = 5
421}; 420};
422 421
422enum ath5k_ant_mode {
423 AR5K_ANTMODE_DEFAULT = 0, /* default antenna setup */
424 AR5K_ANTMODE_FIXED_A = 1, /* only antenna A is present */
425 AR5K_ANTMODE_FIXED_B = 2, /* only antenna B is present */
426 AR5K_ANTMODE_SINGLE_AP = 3, /* sta locked on a single ap */
427 AR5K_ANTMODE_SECTOR_AP = 4, /* AP with tx antenna set on tx desc */
428 AR5K_ANTMODE_SECTOR_STA = 5, /* STA with tx antenna set on tx desc */
429 AR5K_ANTMODE_DEBUG = 6, /* Debug mode -A -> Rx, B-> Tx- */
430 AR5K_ANTMODE_MAX,
431};
432
423 433
424/****************\ 434/****************\
425 TX DEFINITIONS 435 TX DEFINITIONS
@@ -1051,8 +1061,11 @@ struct ath5k_hw {
1051 bool ah_software_retry; 1061 bool ah_software_retry;
1052 u32 ah_limit_tx_retries; 1062 u32 ah_limit_tx_retries;
1053 1063
1054 u32 ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 1064 /* Antenna Control */
1055 bool ah_ant_diversity; 1065 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
1066 u8 ah_ant_mode;
1067 u8 ah_tx_ant;
1068 u8 ah_def_ant;
1056 1069
1057 u8 ah_sta_id[ETH_ALEN]; 1070 u8 ah_sta_id[ETH_ALEN];
1058 1071
@@ -1267,9 +1280,11 @@ extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel
1267extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); 1280extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
1268/* Misc PHY functions */ 1281/* Misc PHY functions */
1269extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); 1282extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1270extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
1271extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1272extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1283extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1284/* Antenna control */
1285extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
1286extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
1287extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1273/* TX power setup */ 1288/* TX power setup */
1274extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); 1289extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
1275extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); 1290extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 70d376c63aac..c41ef58393e7 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -133,7 +133,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
133 ah->ah_cw_min = AR5K_TUNE_CWMIN; 133 ah->ah_cw_min = AR5K_TUNE_CWMIN;
134 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; 134 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
135 ah->ah_software_retry = false; 135 ah->ah_software_retry = false;
136 ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
137 136
138 /* 137 /*
139 * Set the mac version based on the pci id 138 * Set the mac version based on the pci id
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 912ffc5c0203..6789c5dfcc76 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1279,7 +1279,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1279 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1279 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
1280 (sc->power_level * 2), 1280 (sc->power_level * 2),
1281 hw_rate, 1281 hw_rate,
1282 info->control.rates[0].count, keyidx, 0, flags, 1282 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
1283 cts_rate, duration); 1283 cts_rate, duration);
1284 if (ret) 1284 if (ret)
1285 goto err_unmap; 1285 goto err_unmap;
@@ -2009,7 +2009,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2009 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2009 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2010 struct ath5k_hw *ah = sc->ah; 2010 struct ath5k_hw *ah = sc->ah;
2011 struct ath5k_desc *ds; 2011 struct ath5k_desc *ds;
2012 int ret, antenna = 0; 2012 int ret = 0;
2013 u8 antenna;
2013 u32 flags; 2014 u32 flags;
2014 2015
2015 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 2016 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
@@ -2023,23 +2024,35 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2023 } 2024 }
2024 2025
2025 ds = bf->desc; 2026 ds = bf->desc;
2027 antenna = ah->ah_tx_ant;
2026 2028
2027 flags = AR5K_TXDESC_NOACK; 2029 flags = AR5K_TXDESC_NOACK;
2028 if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) { 2030 if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
2029 ds->ds_link = bf->daddr; /* self-linked */ 2031 ds->ds_link = bf->daddr; /* self-linked */
2030 flags |= AR5K_TXDESC_VEOL; 2032 flags |= AR5K_TXDESC_VEOL;
2031 /* 2033 } else
2032 * Let hardware handle antenna switching if txantenna is not set
2033 */
2034 } else {
2035 ds->ds_link = 0; 2034 ds->ds_link = 0;
2036 /* 2035
2037 * Switch antenna every 4 beacons if txantenna is not set 2036 /*
2038 * XXX assumes two antennas 2037 * If we use multiple antennas on AP and use
2039 */ 2038 * the Sectored AP scenario, switch antenna every
2040 if (antenna == 0) 2039 * 4 beacons to make sure everybody hears our AP.
2041 antenna = sc->bsent & 4 ? 2 : 1; 2040 * When a client tries to associate, hw will keep
2042 } 2041 * track of the tx antenna to be used for this client
2042 * automaticaly, based on ACKed packets.
2043 *
2044 * Note: AP still listens and transmits RTS on the
2045 * default antenna which is supposed to be an omni.
2046 *
2047 * Note2: On sectored scenarios it's possible to have
2048 * multiple antennas (1omni -the default- and 14 sectors)
2049 * so if we choose to actually support this mode we need
2050 * to allow user to set how many antennas we have and tweak
2051 * the code below to send beacons on all of them.
2052 */
2053 if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
2054 antenna = sc->bsent & 4 ? 2 : 1;
2055
2043 2056
2044 /* FIXME: If we are in g mode and rate is a CCK rate 2057 /* FIXME: If we are in g mode and rate is a CCK rate
2045 * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta 2058 * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
@@ -2752,12 +2765,16 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2752 struct ath5k_softc *sc = hw->priv; 2765 struct ath5k_softc *sc = hw->priv;
2753 struct ath5k_hw *ah = sc->ah; 2766 struct ath5k_hw *ah = sc->ah;
2754 struct ieee80211_conf *conf = &hw->conf; 2767 struct ieee80211_conf *conf = &hw->conf;
2755 int ret; 2768 int ret = 0;
2756 2769
2757 mutex_lock(&sc->lock); 2770 mutex_lock(&sc->lock);
2758 2771
2759 sc->bintval = conf->beacon_int; 2772 sc->bintval = conf->beacon_int;
2760 2773
2774 ret = ath5k_chan_set(sc, conf->channel);
2775 if (ret < 0)
2776 return ret;
2777
2761 if ((changed & IEEE80211_CONF_CHANGE_POWER) && 2778 if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
2762 (sc->power_level != conf->power_level)) { 2779 (sc->power_level != conf->power_level)) {
2763 sc->power_level = conf->power_level; 2780 sc->power_level = conf->power_level;
@@ -2766,10 +2783,27 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2766 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); 2783 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
2767 } 2784 }
2768 2785
2769 ret = ath5k_chan_set(sc, conf->channel); 2786 /* TODO:
2787 * 1) Move this on config_interface and handle each case
2788 * separately eg. when we have only one STA vif, use
2789 * AR5K_ANTMODE_SINGLE_AP
2790 *
2791 * 2) Allow the user to change antenna mode eg. when only
2792 * one antenna is present
2793 *
2794 * 3) Allow the user to set default/tx antenna when possible
2795 *
2796 * 4) Default mode should handle 90% of the cases, together
2797 * with fixed a/b and single AP modes we should be able to
2798 * handle 99%. Sectored modes are extreme cases and i still
2799 * haven't found a usage for them. If we decide to support them,
2800 * then we must allow the user to set how many tx antennas we
2801 * have available
2802 */
2803 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
2770 2804
2771 mutex_unlock(&sc->lock); 2805 mutex_unlock(&sc->lock);
2772 return ret; 2806 return 0;
2773} 2807}
2774 2808
2775#define SUPPORTED_FIF_FLAGS \ 2809#define SUPPORTED_FIF_FLAGS \
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 8c9dd019d761..c56b494d417a 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -208,16 +208,16 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
208 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; 208 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
209 ee->ee_ant_control[mode][i++] = val & 0x3f; 209 ee->ee_ant_control[mode][i++] = val & 0x3f;
210 210
211 /* Get antenna modes */ 211 /* Get antenna switch tables */
212 ah->ah_antenna[mode][0] = 212 ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
213 (ee->ee_ant_control[mode][0] << 4); 213 (ee->ee_ant_control[mode][0] << 4);
214 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] = 214 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
215 ee->ee_ant_control[mode][1] | 215 ee->ee_ant_control[mode][1] |
216 (ee->ee_ant_control[mode][2] << 6) | 216 (ee->ee_ant_control[mode][2] << 6) |
217 (ee->ee_ant_control[mode][3] << 12) | 217 (ee->ee_ant_control[mode][3] << 12) |
218 (ee->ee_ant_control[mode][4] << 18) | 218 (ee->ee_ant_control[mode][4] << 18) |
219 (ee->ee_ant_control[mode][5] << 24); 219 (ee->ee_ant_control[mode][5] << 24);
220 ah->ah_antenna[mode][AR5K_ANT_FIXED_B] = 220 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
221 ee->ee_ant_control[mode][6] | 221 ee->ee_ant_control[mode][6] |
222 (ee->ee_ant_control[mode][7] << 6) | 222 (ee->ee_ant_control[mode][7] << 6) |
223 (ee->ee_ant_control[mode][8] << 12) | 223 (ee->ee_ant_control[mode][8] << 12) |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 46e4d22591f6..64be73a5edae 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -240,11 +240,11 @@ enum ath5k_eeprom_freq_bands{
240#define AR5K_EEPROM_READ_HDR(_o, _v) \ 240#define AR5K_EEPROM_READ_HDR(_o, _v) \
241 AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \ 241 AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \
242 242
243enum ath5k_ant_setting { 243enum ath5k_ant_table {
244 AR5K_ANT_VARIABLE = 0, /* variable by programming */ 244 AR5K_ANT_CTL = 0, /* Idle switch table settings */
245 AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */ 245 AR5K_ANT_SWTABLE_A = 1, /* Switch table for antenna A */
246 AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */ 246 AR5K_ANT_SWTABLE_B = 2, /* Switch table for antenna B */
247 AR5K_ANT_MAX = 3, 247 AR5K_ANT_MAX,
248}; 248};
249 249
250enum ath5k_ctl_mode { 250enum ath5k_ctl_mode {
@@ -461,6 +461,7 @@ struct ath5k_eeprom_info {
461 /* Spur mitigation data (fbin values for spur channels) */ 461 /* Spur mitigation data (fbin values for spur channels) */
462 u16 ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS]; 462 u16 ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS];
463 463
464 /* Antenna raw switch tables */
464 u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 465 u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
465}; 466};
466 467
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index bb61b8e2dce9..fd93c4e20214 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1414,25 +1414,189 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1414 return ret; 1414 return ret;
1415} 1415}
1416 1416
1417/*****************\
1418* Antenna control *
1419\*****************/
1420
1417void /*TODO:Boundary check*/ 1421void /*TODO:Boundary check*/
1418ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant) 1422ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1419{ 1423{
1420 ATH5K_TRACE(ah->ah_sc); 1424 ATH5K_TRACE(ah->ah_sc);
1421 /*Just a try M.F.*/ 1425
1422 if (ah->ah_version != AR5K_AR5210) 1426 if (ah->ah_version != AR5K_AR5210)
1423 ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA); 1427 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
1424} 1428}
1425 1429
1426unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah) 1430unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
1427{ 1431{
1428 ATH5K_TRACE(ah->ah_sc); 1432 ATH5K_TRACE(ah->ah_sc);
1429 /*Just a try M.F.*/ 1433
1430 if (ah->ah_version != AR5K_AR5210) 1434 if (ah->ah_version != AR5K_AR5210)
1431 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); 1435 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
1432 1436
1433 return false; /*XXX: What do we return for 5210 ?*/ 1437 return false; /*XXX: What do we return for 5210 ?*/
1434} 1438}
1435 1439
1440/*
1441 * Enable/disable fast rx antenna diversity
1442 */
1443static void
1444ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
1445{
1446 switch (ee_mode) {
1447 case AR5K_EEPROM_MODE_11G:
1448 /* XXX: This is set to
1449 * disabled on initvals !!! */
1450 case AR5K_EEPROM_MODE_11A:
1451 if (enable)
1452 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL,
1453 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
1454 else
1455 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1456 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
1457 break;
1458 case AR5K_EEPROM_MODE_11B:
1459 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1460 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
1461 break;
1462 default:
1463 return;
1464 }
1465
1466 if (enable) {
1467 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
1468 AR5K_PHY_RESTART_DIV_GC, 0xc);
1469
1470 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
1471 AR5K_PHY_FAST_ANT_DIV_EN);
1472 } else {
1473 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
1474 AR5K_PHY_RESTART_DIV_GC, 0x8);
1475
1476 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
1477 AR5K_PHY_FAST_ANT_DIV_EN);
1478 }
1479}
1480
1481/*
1482 * Set antenna operating mode
1483 */
1484void
1485ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1486{
1487 struct ieee80211_channel *channel = &ah->ah_current_channel;
1488 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
1489 bool use_def_for_sg;
1490 u8 def_ant, tx_ant, ee_mode;
1491 u32 sta_id1 = 0;
1492
1493 def_ant = ah->ah_def_ant;
1494
1495 ATH5K_TRACE(ah->ah_sc);
1496
1497 switch (channel->hw_value & CHANNEL_MODES) {
1498 case CHANNEL_A:
1499 case CHANNEL_T:
1500 case CHANNEL_XR:
1501 ee_mode = AR5K_EEPROM_MODE_11A;
1502 break;
1503 case CHANNEL_G:
1504 case CHANNEL_TG:
1505 ee_mode = AR5K_EEPROM_MODE_11G;
1506 break;
1507 case CHANNEL_B:
1508 ee_mode = AR5K_EEPROM_MODE_11B;
1509 break;
1510 default:
1511 ATH5K_ERR(ah->ah_sc,
1512 "invalid channel: %d\n", channel->center_freq);
1513 return;
1514 }
1515
1516 switch (ant_mode) {
1517 case AR5K_ANTMODE_DEFAULT:
1518 tx_ant = 0;
1519 use_def_for_tx = false;
1520 update_def_on_tx = false;
1521 use_def_for_rts = false;
1522 use_def_for_sg = false;
1523 fast_div = true;
1524 break;
1525 case AR5K_ANTMODE_FIXED_A:
1526 def_ant = 1;
1527 tx_ant = 0;
1528 use_def_for_tx = true;
1529 update_def_on_tx = false;
1530 use_def_for_rts = true;
1531 use_def_for_sg = true;
1532 fast_div = false;
1533 break;
1534 case AR5K_ANTMODE_FIXED_B:
1535 def_ant = 2;
1536 tx_ant = 0;
1537 use_def_for_tx = true;
1538 update_def_on_tx = false;
1539 use_def_for_rts = true;
1540 use_def_for_sg = true;
1541 fast_div = false;
1542 break;
1543 case AR5K_ANTMODE_SINGLE_AP:
1544 def_ant = 1; /* updated on tx */
1545 tx_ant = 0;
1546 use_def_for_tx = true;
1547 update_def_on_tx = true;
1548 use_def_for_rts = true;
1549 use_def_for_sg = true;
1550 fast_div = true;
1551 break;
1552 case AR5K_ANTMODE_SECTOR_AP:
1553 tx_ant = 1; /* variable */
1554 use_def_for_tx = false;
1555 update_def_on_tx = false;
1556 use_def_for_rts = true;
1557 use_def_for_sg = false;
1558 fast_div = false;
1559 break;
1560 case AR5K_ANTMODE_SECTOR_STA:
1561 tx_ant = 1; /* variable */
1562 use_def_for_tx = true;
1563 update_def_on_tx = false;
1564 use_def_for_rts = true;
1565 use_def_for_sg = false;
1566 fast_div = true;
1567 break;
1568 case AR5K_ANTMODE_DEBUG:
1569 def_ant = 1;
1570 tx_ant = 2;
1571 use_def_for_tx = false;
1572 update_def_on_tx = false;
1573 use_def_for_rts = false;
1574 use_def_for_sg = false;
1575 fast_div = false;
1576 break;
1577 default:
1578 return;
1579 }
1580
1581 ah->ah_tx_ant = tx_ant;
1582 ah->ah_ant_mode = ant_mode;
1583
1584 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
1585 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
1586 sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0;
1587 sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0;
1588
1589 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS);
1590
1591 if (sta_id1)
1592 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
1593
1594 /* Note: set diversity before default antenna
1595 * because it won't work correctly */
1596 ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
1597 ath5k_hw_set_def_antenna(ah, def_ant);
1598}
1599
1436 1600
1437/****************\ 1601/****************\
1438* TX power setup * 1602* TX power setup *
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 7070d1543cdc..6809b54a2ad7 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -1148,6 +1148,11 @@
1148#define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */ 1148#define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */
1149#define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */ 1149#define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */
1150 1150
1151#define AR5K_STA_ID1_ANTENNA_SETTINGS (AR5K_STA_ID1_DEFAULT_ANTENNA | \
1152 AR5K_STA_ID1_DESC_ANTENNA | \
1153 AR5K_STA_ID1_RTS_DEF_ANTENNA | \
1154 AR5K_STA_ID1_SELFGEN_DEF_ANT)
1155
1151/* 1156/*
1152 * First BSSID register (MAC address, lower 32bits) 1157 * First BSSID register (MAC address, lower 32bits)
1153 */ 1158 */
@@ -2028,7 +2033,9 @@
2028#define AR5K_PHY_AGCCTL 0x9860 /* Register address */ 2033#define AR5K_PHY_AGCCTL 0x9860 /* Register address */
2029#define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */ 2034#define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */
2030#define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */ 2035#define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */
2036#define AR5K_PHY_AGCCTL_OFDM_DIV_DIS 0x00000008 /* Disable antenna diversity on OFDM modes */
2031#define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */ 2037#define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */
2038#define AR5K_PHY_AGCTL_FLTR_CAL 0x00010000 /* Allow filter calibration (?) */
2032#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */ 2039#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */
2033 2040
2034/* 2041/*
@@ -2528,7 +2535,7 @@
2528 * PHY CCK Cross-correlator Barker RSSI threshold register [5212+] 2535 * PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
2529 */ 2536 */
2530#define AR5K_PHY_CCK_CROSSCORR 0xa208 2537#define AR5K_PHY_CCK_CROSSCORR 0xa208
2531#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000000f 2538#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000003f
2532#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0 2539#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0
2533 2540
2534/* Same address is used for antenna diversity activation */ 2541/* Same address is used for antenna diversity activation */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index d419c6a3ded7..0e075bca384f 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -698,13 +698,13 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
698 /* Set antenna idle switch table */ 698 /* Set antenna idle switch table */
699 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, 699 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
700 AR5K_PHY_ANT_CTL_SWTABLE_IDLE, 700 AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
701 (ah->ah_antenna[ee_mode][0] | 701 (ah->ah_ant_ctl[ee_mode][0] |
702 AR5K_PHY_ANT_CTL_TXRX_EN)); 702 AR5K_PHY_ANT_CTL_TXRX_EN));
703 703
704 /* Set antenna switch table */ 704 /* Set antenna switch tables */
705 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]], 705 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]],
706 AR5K_PHY_ANT_SWITCH_TABLE_0); 706 AR5K_PHY_ANT_SWITCH_TABLE_0);
707 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]], 707 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]],
708 AR5K_PHY_ANT_SWITCH_TABLE_1); 708 AR5K_PHY_ANT_SWITCH_TABLE_1);
709 709
710 /* Noise floor threshold */ 710 /* Noise floor threshold */
@@ -1042,17 +1042,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1042 1042
1043 /* 1043 /*
1044 * In case a fixed antenna was set as default 1044 * In case a fixed antenna was set as default
1045 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE 1045 * use the same switch table twice.
1046 * registers.
1047 */ 1046 */
1048 if (s_ant != 0) { 1047 if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
1049 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */ 1048 ant[0] = ant[1] = AR5K_ANT_SWTABLE_A;
1050 ant[0] = ant[1] = AR5K_ANT_FIXED_A; 1049 else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
1051 else /* 2 - Aux */ 1050 ant[0] = ant[1] = AR5K_ANT_SWTABLE_B;
1052 ant[0] = ant[1] = AR5K_ANT_FIXED_B; 1051 else {
1053 } else { 1052 ant[0] = AR5K_ANT_SWTABLE_A;
1054 ant[0] = AR5K_ANT_FIXED_A; 1053 ant[1] = AR5K_ANT_SWTABLE_B;
1055 ant[1] = AR5K_ANT_FIXED_B;
1056 } 1054 }
1057 1055
1058 /* Commit values from EEPROM */ 1056 /* Commit values from EEPROM */
@@ -1260,6 +1258,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1260 */ 1258 */
1261 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1259 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
1262 1260
1261 /* Restore antenna mode */
1262 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
1263 1263
1264 /* 1264 /*
1265 * Configure QCUs/DCUs 1265 * Configure QCUs/DCUs