Skip to contentSkip to conversation

ath5k: Implement antenna control

PATCH In review Nick Kossifidis 3 participants 3 messages Apr 16, 2009 Atheros ATH5K wireless driver

lore
Share & tools
lore
#0 lore raw

PATCH 6/7 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-).

---
 drivers/net/wireless/ath/ath5k/ath5k.h  |   25 ++++-
 drivers/net/wireless/ath/ath5k/attach.c |    1 -
 drivers/net/wireless/ath/ath5k/base.c   |   66 +++++++++---
 drivers/net/wireless/ath/ath5k/eeprom.c |    8 +-
 drivers/net/wireless/ath/ath5k/eeprom.h |   11 +-
 drivers/net/wireless/ath/ath5k/phy.c    |  174 ++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath5k/reg.h    |    9 ++-
 drivers/net/wireless/ath/ath5k/reset.c  |   28 +++---
 8 files changed, 271 insertions(+), 51 deletions(-)
drivers/net/wireless/ath/ath5k/ath5k.h +20 -5
index 04b7345..33da290 100644
@@ -209,7 +209,6 @@
 #define AR5K_TUNE_MAX_TXPOWER			63
 #define AR5K_TUNE_DEFAULT_TXPOWER		25
 #define AR5K_TUNE_TPC_TXPOWER			false
-#define AR5K_TUNE_ANT_DIVERSITY			true
 #define AR5K_TUNE_HWTXTRIES			4
 
 #define AR5K_INIT_CARR_SENSE_EN			1
@@ -420,6 +419,17 @@ enum ath5k_driver_mode {
 	AR5K_MODE_MAX		=	5
 };
 
+enum ath5k_ant_mode {
+	AR5K_ANTMODE_DEFAULT	= 0,	/* default antenna setup */
+	AR5K_ANTMODE_FIXED_A	= 1,	/* only antenna A is present */
+	AR5K_ANTMODE_FIXED_B	= 2,	/* only antenna B is present */
+	AR5K_ANTMODE_SINGLE_AP	= 3,	/* sta locked on a single ap */
+	AR5K_ANTMODE_SECTOR_AP	= 4,	/* AP with tx antenna set on tx desc */
+	AR5K_ANTMODE_SECTOR_STA	= 5,	/* STA with tx antenna set on tx desc */
+	AR5K_ANTMODE_DEBUG	= 6,	/* Debug mode -A -> Rx, B-> Tx- */
+	AR5K_ANTMODE_MAX,
+};
+
 
 /****************\
   TX DEFINITIONS
@@ -1051,8 +1061,11 @@ struct ath5k_hw {
 	bool			ah_software_retry;
 	u32			ah_limit_tx_retries;
 
-	u32			ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
-	bool			ah_ant_diversity;
+	/* Antenna Control */
+	u32			ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
+	u8			ah_ant_mode;
+	u8			ah_tx_ant;
+	u8			ah_def_ant;
 
 	u8			ah_sta_id[ETH_ALEN];
 
@@ -1267,9 +1280,11 @@ extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel
 extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
 /* Misc PHY functions */
 extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
-extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
-extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
 extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
+/* Antenna control */
+extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
+extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
+extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
 /* TX power setup */
 extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
 extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
drivers/net/wireless/ath/ath5k/attach.c +0 -1
index 70d376c..c41ef58 100644
@@ -133,7 +133,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 	ah->ah_cw_min = AR5K_TUNE_CWMIN;
 	ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
 	ah->ah_software_retry = false;
-	ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
 
 	/*
 	 * Set the mac version based on the pci id
drivers/net/wireless/ath/ath5k/base.c +50 -16

109 lines not on this page · raw message

drivers/net/wireless/ath/ath5k/eeprom.c +4 -4
index cadcdae..6387676 100644
@@ -208,16 +208,16 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
 	ee->ee_ant_control[mode][i++]	= (val >> 6) & 0x3f;
 	ee->ee_ant_control[mode][i++]	= val & 0x3f;
 
-	/* Get antenna modes */
-	ah->ah_antenna[mode][0] =
+	/* Get antenna switch tables */
+	ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
 	    (ee->ee_ant_control[mode][0] << 4);
-	ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
+	ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
 	     ee->ee_ant_control[mode][1] 	|
 	    (ee->ee_ant_control[mode][2] << 6) 	|
 	    (ee->ee_ant_control[mode][3] << 12) |
 	    (ee->ee_ant_control[mode][4] << 18) |
 	    (ee->ee_ant_control[mode][5] << 24);
-	ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
+	ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
 	     ee->ee_ant_control[mode][6] 	|
 	    (ee->ee_ant_control[mode][7] << 6) 	|
 	    (ee->ee_ant_control[mode][8] << 12) |
drivers/net/wireless/ath/ath5k/eeprom.h +6 -5
index 46e4d22..64be73a 100644
@@ -240,11 +240,11 @@ enum ath5k_eeprom_freq_bands{
 #define AR5K_EEPROM_READ_HDR(_o, _v)					\
 	AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v);	\
 
-enum ath5k_ant_setting {
-	AR5K_ANT_VARIABLE	= 0,	/* variable by programming */
-	AR5K_ANT_FIXED_A	= 1,	/* fixed to 11a frequencies */
-	AR5K_ANT_FIXED_B	= 2,	/* fixed to 11b frequencies */
-	AR5K_ANT_MAX		= 3,
+enum ath5k_ant_table {
+	AR5K_ANT_CTL		= 0,	/* Idle switch table settings */
+	AR5K_ANT_SWTABLE_A	= 1,	/* Switch table for antenna A */
+	AR5K_ANT_SWTABLE_B	= 2,	/* Switch table for antenna B */
+	AR5K_ANT_MAX,
 };
 
 enum ath5k_ctl_mode {
@@ -461,6 +461,7 @@ struct ath5k_eeprom_info {
 	/* Spur mitigation data (fbin values for spur channels) */
 	u16	ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS];
 
+	/* Antenna raw switch tables */
 	u32	ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
 };
 
drivers/net/wireless/ath/ath5k/phy.c +169 -5

194 lines not on this page · raw message

drivers/net/wireless/ath/ath5k/reg.h +8 -1
index 7070d15..6809b54 100644
@@ -1148,6 +1148,11 @@
 #define AR5K_STA_ID1_CBCIV_ENDIAN	0x40000000	/* ??? */
 #define AR5K_STA_ID1_KEYSRCH_MCAST	0x80000000	/* Do key cache search for mcast frames */
 
+#define	AR5K_STA_ID1_ANTENNA_SETTINGS	(AR5K_STA_ID1_DEFAULT_ANTENNA | \
+					AR5K_STA_ID1_DESC_ANTENNA | \
+					AR5K_STA_ID1_RTS_DEF_ANTENNA | \
+					AR5K_STA_ID1_SELFGEN_DEF_ANT)
+
 /*
  * First BSSID register (MAC address, lower 32bits)
  */
@@ -2028,7 +2033,9 @@
 #define	AR5K_PHY_AGCCTL			0x9860			/* Register address */
 #define	AR5K_PHY_AGCCTL_CAL		0x00000001	/* Enable PHY calibration */
 #define	AR5K_PHY_AGCCTL_NF		0x00000002	/* Enable Noise Floor calibration */
+#define	AR5K_PHY_AGCCTL_OFDM_DIV_DIS	0x00000008	/* Disable antenna diversity on OFDM modes */
 #define	AR5K_PHY_AGCCTL_NF_EN		0x00008000	/* Enable nf calibration to happen (?) */
+#define	AR5K_PHY_AGCTL_FLTR_CAL		0x00010000	/* Allow filter calibration (?) */
 #define	AR5K_PHY_AGCCTL_NF_NOUPDATE	0x00020000	/* Don't update nf automaticaly */
 
 /*
@@ -2528,7 +2535,7 @@
  * PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
  */
 #define AR5K_PHY_CCK_CROSSCORR			0xa208
-#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR	0x0000000f
+#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR	0x0000003f
 #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S	0
 
 /* Same address is used for antenna diversity activation */
drivers/net/wireless/ath/ath5k/reset.c +14 -14
index 9e5c4b4..69d6860 100644
@@ -699,13 +699,13 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
 	/* Set antenna idle switch table */
 	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
 			AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
-			(ah->ah_antenna[ee_mode][0] |
+			(ah->ah_ant_ctl[ee_mode][0] |
 			AR5K_PHY_ANT_CTL_TXRX_EN));
 
-	/* Set antenna switch table */
-	ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
+	/* Set antenna switch tables */
+	ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]],
 		AR5K_PHY_ANT_SWITCH_TABLE_0);
-	ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
+	ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]],
 		AR5K_PHY_ANT_SWITCH_TABLE_1);
 
 	/* Noise floor threshold */
@@ -1043,17 +1043,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 
 		/*
 		 * In case a fixed antenna was set as default
-		 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
-		 * registers.
+		 * use the same switch table twice.
 		 */
-		if (s_ant != 0) {
-			if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
-				ant[0] = ant[1] = AR5K_ANT_FIXED_A;
-			else	/* 2 - Aux */
-				ant[0] = ant[1] = AR5K_ANT_FIXED_B;
-		} else {
-			ant[0] = AR5K_ANT_FIXED_A;
-			ant[1] = AR5K_ANT_FIXED_B;
+		if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
+				ant[0] = ant[1] = AR5K_ANT_SWTABLE_A;
+		else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
+				ant[0] = ant[1] = AR5K_ANT_SWTABLE_B;
+		else {
+			ant[0] = AR5K_ANT_SWTABLE_A;
+			ant[1] = AR5K_ANT_SWTABLE_B;
 		}
 
 		/* Commit values from EEPROM */
@@ -1261,6 +1259,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	 */
 	ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
 
+	/* Restore antenna mode */
+	ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
 
 	/*
 	 * Configure QCUs/DCUs
#1 lore raw

Hello Nick!

Quoted 6 lines

* Add code to support the various antenna scenarios supported by hw
=20
* 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-).

We should add or update an existing nl80211 call, to allow set the used=
antenna (multiple antennas in Draft-N?) manually, like madwifi does. T=
his is e.g. needed for long distance links.

Regards
Alina

--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
--
To unsubscribe from this list: send the line "unsubscribe linux-wireles= s" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

maintainer
#2 lore raw

2009/4/16 Alina Friedrichsen <[email protected]>:

Quoted 3 lines

Hello Nick!

Quoted 1 line

=C2=A0* Add code to support the various antenna scenarios supported =

by hw

Quoted 2 lines
Quoted 2 lines

=C2=A0* For now hardcode the default scenario (single or dual omnis =

with

Quoted 1 line
Quoted 1 line

=C2=A0tx/rx diversity working and tx antenna handled by session -hw =

keeps

Quoted 1 line
Quoted 1 line

=C2=A0track on which antenna it got ack from each ap/station and map=

s each

Quoted 3 lines
Quoted 1 line

=C2=A0ap/station to one of the antennas-).

We should add or update an existing nl80211 call, to allow set the us=

ed antenna (multiple antennas in Draft-N?) manually, like madwifi does.=
This is e.g. needed for long distance links.

Quoted 4 lines

Regards
Alina

Well it's more complicated than that, we can only set tx antenna when using a sectored ap/sta scenario (else it's possible to miss rts and self generated frames), and we can only set default antenna on scenarios that don't update the default antenna dynamicaly. Here is a more detailed explanation of antenna scenarios...

http://kerneltrap.org/mailarchive/linux-ath5k-devel/2008/11/26/4241174

I agree that one should be able to set rx/tx antenna from nl80211 (after all mac80211 has tx antenna information) but we also need a way to handle antenna scenarios. Setting antennas without setting the proper antenna scenarios will break things (as it did for mesh on the above mail).

--=20
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-) Nick
--
To unsubscribe from this list: send the line "unsubscribe linux-wireles= s" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html