Picon

Implement Software Based (SLOW) Diversity for AR9283(0)

Hello, All,

I have a configuration where I want to use an AR9283 device in a Diversity only scenario (without MIMO). Radio chipset is connected to an AR7241 SoC and is running OpenWRT Linux distro.

Device is being used as bridged station (Not AP) and has 2 chains, connected to different antennas, with different lines of sight (MIMO does not seem to work efficiently on this configuration).

Since I am not able to disable chain0 from the nl80211 interface (using iw command), I was considering changing the  AR9280_PHY_RXGAIN_TXRX_ATTEN and AR_PHY_SWITCH_CHAIN_0

I would like to have a configuration where  the firmware with the help of a userspace application would pickup the radio that has the best coverage to the current access point, as suggested by AdrianChadd on this link:
https://wiki.freebsd.org/dev/ath_hal%284%29/AntennaDiversityAR5416Slow

I tried writing some values to the AR9280_PHY_RXGAIN_TXRX_ATTEN and also to the AR_PHY_SWITCH_CHAIN_0 registers but the values I used do not seem to make any difference on the behavior of chain0 or chain1.

How are the values I write on AR9280_PHY_RXGAIN_TXRX_ATTEN and AR_PHY_SWITCH_CHAIN_0 registers translated inside the Qualcomm Atheros AR9283?

Is there any documentation publicly available explaining how that works?


Thanks in advance,

Luiz Oliveira Neto
_______________________________________________
ath9k-devel mailing list
ath9k-devel <at> lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel
Oleksij Rempel | 15 May 14:35 2015
Picon

[PATCH] ath9k: add phy.c

... and move dup code from ar5008_phy.c and ar9002_phy.c to phy.c

Signed-off-by: Oleksij Rempel <linux <at> rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/Makefile     |   1 +
 drivers/net/wireless/ath/ath9k/ar5008_phy.c | 144 +----------------------
 drivers/net/wireless/ath/ath9k/ar9002_phy.c | 144 +----------------------
 drivers/net/wireless/ath/ath9k/phy.c        | 170 ++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/phy.h        |   3 +
 5 files changed, 178 insertions(+), 284 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/phy.c

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index ecda613..6e129b9 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
 <at>  <at>  -26,6 +26,7  <at>  <at>  ath9k_hw-y:=	\
 		ar9002_hw.o \
 		ar9003_hw.o \
 		hw.o \
+		phy.o \
 		ar9003_phy.o \
 		ar9002_phy.o \
 		ar5008_phy.o \
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 6c23d27..350506c 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
 <at>  <at>  -266,27 +266,15  <at>  <at>  static void ar5008_hw_spur_mitigate(struct ath_hw *ah,
 				    struct ath9k_channel *chan)
 {
 	int bb_spur = AR_NO_SPUR;
-	int bin, cur_bin;
+	int bin;
 	int spur_freq_sd;
 	int spur_delta_phase;
 	int denominator;
-	int upper, lower, cur_vit_mask;
 	int tmp, new;
 	int i;
-	static int pilot_mask_reg[4] = {
-		AR_PHY_TIMING7, AR_PHY_TIMING8,
-		AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-	};
-	static int chan_mask_reg[4] = {
-		AR_PHY_TIMING9, AR_PHY_TIMING10,
-		AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-	};
-	static int inc[4] = { 0, 100, 0, 0 };

 	int8_t mask_m[123];
 	int8_t mask_p[123];
-	int8_t mask_amt;
-	int tmp_mask;
 	int cur_bb_spur;
 	bool is2GHz = IS_CHAN_2GHZ(chan);

 <at>  <at>  -335,135 +323,7  <at>  <at>  static void ar5008_hw_spur_mitigate(struct ath_hw *ah,
 	       SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
 	REG_WRITE(ah, AR_PHY_TIMING11, new);

-	cur_bin = -6000;
-	upper = bin + 100;
-	lower = bin - 100;
-
-	for (i = 0; i < 4; i++) {
-		int pilot_mask = 0;
-		int chan_mask = 0;
-		int bp = 0;
-		for (bp = 0; bp < 30; bp++) {
-			if ((cur_bin > lower) && (cur_bin < upper)) {
-				pilot_mask = pilot_mask | 0x1 << bp;
-				chan_mask = chan_mask | 0x1 << bp;
-			}
-			cur_bin += 100;
-		}
-		cur_bin += inc[i];
-		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-	}
-
-	cur_vit_mask = 6100;
-	upper = bin + 120;
-	lower = bin - 120;
-
-	for (i = 0; i < 123; i++) {
-		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-			/* workaround for gcc bug #37014 */
-			volatile int tmp_v = abs(cur_vit_mask - bin);
-
-			if (tmp_v < 75)
-				mask_amt = 1;
-			else
-				mask_amt = 0;
-			if (cur_vit_mask < 0)
-				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-			else
-				mask_p[cur_vit_mask / 100] = mask_amt;
-		}
-		cur_vit_mask -= 100;
-	}
-
-	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-		| (mask_m[48] << 26) | (mask_m[49] << 24)
-		| (mask_m[50] << 22) | (mask_m[51] << 20)
-		| (mask_m[52] << 18) | (mask_m[53] << 16)
-		| (mask_m[54] << 14) | (mask_m[55] << 12)
-		| (mask_m[56] << 10) | (mask_m[57] << 8)
-		| (mask_m[58] << 6) | (mask_m[59] << 4)
-		| (mask_m[60] << 2) | (mask_m[61] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-	tmp_mask = (mask_m[31] << 28)
-		| (mask_m[32] << 26) | (mask_m[33] << 24)
-		| (mask_m[34] << 22) | (mask_m[35] << 20)
-		| (mask_m[36] << 18) | (mask_m[37] << 16)
-		| (mask_m[48] << 14) | (mask_m[39] << 12)
-		| (mask_m[40] << 10) | (mask_m[41] << 8)
-		| (mask_m[42] << 6) | (mask_m[43] << 4)
-		| (mask_m[44] << 2) | (mask_m[45] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-		| (mask_m[18] << 26) | (mask_m[18] << 24)
-		| (mask_m[20] << 22) | (mask_m[20] << 20)
-		| (mask_m[22] << 18) | (mask_m[22] << 16)
-		| (mask_m[24] << 14) | (mask_m[24] << 12)
-		| (mask_m[25] << 10) | (mask_m[26] << 8)
-		| (mask_m[27] << 6) | (mask_m[28] << 4)
-		| (mask_m[29] << 2) | (mask_m[30] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-		| (mask_m[2] << 26) | (mask_m[3] << 24)
-		| (mask_m[4] << 22) | (mask_m[5] << 20)
-		| (mask_m[6] << 18) | (mask_m[7] << 16)
-		| (mask_m[8] << 14) | (mask_m[9] << 12)
-		| (mask_m[10] << 10) | (mask_m[11] << 8)
-		| (mask_m[12] << 6) | (mask_m[13] << 4)
-		| (mask_m[14] << 2) | (mask_m[15] << 0);
-	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-	tmp_mask = (mask_p[15] << 28)
-		| (mask_p[14] << 26) | (mask_p[13] << 24)
-		| (mask_p[12] << 22) | (mask_p[11] << 20)
-		| (mask_p[10] << 18) | (mask_p[9] << 16)
-		| (mask_p[8] << 14) | (mask_p[7] << 12)
-		| (mask_p[6] << 10) | (mask_p[5] << 8)
-		| (mask_p[4] << 6) | (mask_p[3] << 4)
-		| (mask_p[2] << 2) | (mask_p[1] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-	tmp_mask = (mask_p[30] << 28)
-		| (mask_p[29] << 26) | (mask_p[28] << 24)
-		| (mask_p[27] << 22) | (mask_p[26] << 20)
-		| (mask_p[25] << 18) | (mask_p[24] << 16)
-		| (mask_p[23] << 14) | (mask_p[22] << 12)
-		| (mask_p[21] << 10) | (mask_p[20] << 8)
-		| (mask_p[19] << 6) | (mask_p[18] << 4)
-		| (mask_p[17] << 2) | (mask_p[16] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-	tmp_mask = (mask_p[45] << 28)
-		| (mask_p[44] << 26) | (mask_p[43] << 24)
-		| (mask_p[42] << 22) | (mask_p[41] << 20)
-		| (mask_p[40] << 18) | (mask_p[39] << 16)
-		| (mask_p[38] << 14) | (mask_p[37] << 12)
-		| (mask_p[36] << 10) | (mask_p[35] << 8)
-		| (mask_p[34] << 6) | (mask_p[33] << 4)
-		| (mask_p[32] << 2) | (mask_p[31] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-		| (mask_p[59] << 26) | (mask_p[58] << 24)
-		| (mask_p[57] << 22) | (mask_p[56] << 20)
-		| (mask_p[55] << 18) | (mask_p[54] << 16)
-		| (mask_p[53] << 14) | (mask_p[52] << 12)
-		| (mask_p[51] << 10) | (mask_p[50] << 8)
-		| (mask_p[49] << 6) | (mask_p[48] << 4)
-		| (mask_p[47] << 2) | (mask_p[46] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+	phy_hw_spur_mitigate(ah, chan, bin);
 }

 /**
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index fc08162..daf52c6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
 <at>  <at>  -169,29 +169,17  <at>  <at>  static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
 {
 	int bb_spur = AR_NO_SPUR;
 	int freq;
-	int bin, cur_bin;
+	int bin;
 	int bb_spur_off, spur_subchannel_sd;
 	int spur_freq_sd;
 	int spur_delta_phase;
 	int denominator;
-	int upper, lower, cur_vit_mask;
 	int tmp, newVal;
 	int i;
-	static const int pilot_mask_reg[4] = {
-		AR_PHY_TIMING7, AR_PHY_TIMING8,
-		AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-	};
-	static const int chan_mask_reg[4] = {
-		AR_PHY_TIMING9, AR_PHY_TIMING10,
-		AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-	};
-	static const int inc[4] = { 0, 100, 0, 0 };
 	struct chan_centers centers;

 	int8_t mask_m[123];
 	int8_t mask_p[123];
-	int8_t mask_amt;
-	int tmp_mask;
 	int cur_bb_spur;
 	bool is2GHz = IS_CHAN_2GHZ(chan);

 <at>  <at>  -288,135 +276,7  <at>  <at>  static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
 	newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
 	REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);

-	cur_bin = -6000;
-	upper = bin + 100;
-	lower = bin - 100;
-
-	for (i = 0; i < 4; i++) {
-		int pilot_mask = 0;
-		int chan_mask = 0;
-		int bp = 0;
-		for (bp = 0; bp < 30; bp++) {
-			if ((cur_bin > lower) && (cur_bin < upper)) {
-				pilot_mask = pilot_mask | 0x1 << bp;
-				chan_mask = chan_mask | 0x1 << bp;
-			}
-			cur_bin += 100;
-		}
-		cur_bin += inc[i];
-		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-	}
-
-	cur_vit_mask = 6100;
-	upper = bin + 120;
-	lower = bin - 120;
-
-	for (i = 0; i < 123; i++) {
-		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-			/* workaround for gcc bug #37014 */
-			volatile int tmp_v = abs(cur_vit_mask - bin);
-
-			if (tmp_v < 75)
-				mask_amt = 1;
-			else
-				mask_amt = 0;
-			if (cur_vit_mask < 0)
-				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-			else
-				mask_p[cur_vit_mask / 100] = mask_amt;
-		}
-		cur_vit_mask -= 100;
-	}
-
-	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-		| (mask_m[48] << 26) | (mask_m[49] << 24)
-		| (mask_m[50] << 22) | (mask_m[51] << 20)
-		| (mask_m[52] << 18) | (mask_m[53] << 16)
-		| (mask_m[54] << 14) | (mask_m[55] << 12)
-		| (mask_m[56] << 10) | (mask_m[57] << 8)
-		| (mask_m[58] << 6) | (mask_m[59] << 4)
-		| (mask_m[60] << 2) | (mask_m[61] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-	tmp_mask = (mask_m[31] << 28)
-		| (mask_m[32] << 26) | (mask_m[33] << 24)
-		| (mask_m[34] << 22) | (mask_m[35] << 20)
-		| (mask_m[36] << 18) | (mask_m[37] << 16)
-		| (mask_m[48] << 14) | (mask_m[39] << 12)
-		| (mask_m[40] << 10) | (mask_m[41] << 8)
-		| (mask_m[42] << 6) | (mask_m[43] << 4)
-		| (mask_m[44] << 2) | (mask_m[45] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-		| (mask_m[18] << 26) | (mask_m[18] << 24)
-		| (mask_m[20] << 22) | (mask_m[20] << 20)
-		| (mask_m[22] << 18) | (mask_m[22] << 16)
-		| (mask_m[24] << 14) | (mask_m[24] << 12)
-		| (mask_m[25] << 10) | (mask_m[26] << 8)
-		| (mask_m[27] << 6) | (mask_m[28] << 4)
-		| (mask_m[29] << 2) | (mask_m[30] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-		| (mask_m[2] << 26) | (mask_m[3] << 24)
-		| (mask_m[4] << 22) | (mask_m[5] << 20)
-		| (mask_m[6] << 18) | (mask_m[7] << 16)
-		| (mask_m[8] << 14) | (mask_m[9] << 12)
-		| (mask_m[10] << 10) | (mask_m[11] << 8)
-		| (mask_m[12] << 6) | (mask_m[13] << 4)
-		| (mask_m[14] << 2) | (mask_m[15] << 0);
-	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-	tmp_mask = (mask_p[15] << 28)
-		| (mask_p[14] << 26) | (mask_p[13] << 24)
-		| (mask_p[12] << 22) | (mask_p[11] << 20)
-		| (mask_p[10] << 18) | (mask_p[9] << 16)
-		| (mask_p[8] << 14) | (mask_p[7] << 12)
-		| (mask_p[6] << 10) | (mask_p[5] << 8)
-		| (mask_p[4] << 6) | (mask_p[3] << 4)
-		| (mask_p[2] << 2) | (mask_p[1] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-	tmp_mask = (mask_p[30] << 28)
-		| (mask_p[29] << 26) | (mask_p[28] << 24)
-		| (mask_p[27] << 22) | (mask_p[26] << 20)
-		| (mask_p[25] << 18) | (mask_p[24] << 16)
-		| (mask_p[23] << 14) | (mask_p[22] << 12)
-		| (mask_p[21] << 10) | (mask_p[20] << 8)
-		| (mask_p[19] << 6) | (mask_p[18] << 4)
-		| (mask_p[17] << 2) | (mask_p[16] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-	tmp_mask = (mask_p[45] << 28)
-		| (mask_p[44] << 26) | (mask_p[43] << 24)
-		| (mask_p[42] << 22) | (mask_p[41] << 20)
-		| (mask_p[40] << 18) | (mask_p[39] << 16)
-		| (mask_p[38] << 14) | (mask_p[37] << 12)
-		| (mask_p[36] << 10) | (mask_p[35] << 8)
-		| (mask_p[34] << 6) | (mask_p[33] << 4)
-		| (mask_p[32] << 2) | (mask_p[31] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-		| (mask_p[59] << 26) | (mask_p[58] << 24)
-		| (mask_p[57] << 22) | (mask_p[56] << 20)
-		| (mask_p[55] << 18) | (mask_p[54] << 16)
-		| (mask_p[53] << 14) | (mask_p[52] << 12)
-		| (mask_p[51] << 10) | (mask_p[50] << 8)
-		| (mask_p[49] << 6) | (mask_p[48] << 4)
-		| (mask_p[47] << 2) | (mask_p[46] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+	phy_hw_spur_mitigate(ah, chan, bin);

 	REGWRITE_BUFFER_FLUSH(ah);
 }
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
new file mode 100644
index 0000000..09cc68d
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/phy.c
 <at>  <at>  -0,0 +1,170  <at>  <at> 
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+#include "phy.h"
+#include "ar9002_phy.h"
+
+void phy_hw_spur_mitigate(struct ath_hw *ah,
+			  struct ath9k_channel *chan, int bin)
+{
+	int cur_bin;
+	int upper, lower, cur_vit_mask;
+	int i;
+	int8_t mask_m[123];
+	int8_t mask_p[123];
+	int8_t mask_amt;
+	int tmp_mask;
+	static int pilot_mask_reg[4] = {
+		AR_PHY_TIMING7, AR_PHY_TIMING8,
+		AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+	};
+	static int chan_mask_reg[4] = {
+		AR_PHY_TIMING9, AR_PHY_TIMING10,
+		AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+	};
+	static int inc[4] = { 0, 100, 0, 0 };
+
+	cur_bin = -6000;
+	upper = bin + 100;
+	lower = bin - 100;
+
+	for (i = 0; i < 4; i++) {
+		int pilot_mask = 0;
+		int chan_mask = 0;
+		int bp = 0;
+
+		for (bp = 0; bp < 30; bp++) {
+			if ((cur_bin > lower) && (cur_bin < upper)) {
+				pilot_mask = pilot_mask | 0x1 << bp;
+				chan_mask = chan_mask | 0x1 << bp;
+			}
+			cur_bin += 100;
+		}
+		cur_bin += inc[i];
+		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+	}
+
+	cur_vit_mask = 6100;
+	upper = bin + 120;
+	lower = bin - 120;
+
+	for (i = 0; i < 123; i++) {
+		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+			/* workaround for gcc bug #37014 */
+			volatile int tmp_v = abs(cur_vit_mask - bin);
+
+			if (tmp_v < 75)
+				mask_amt = 1;
+			else
+				mask_amt = 0;
+			if (cur_vit_mask < 0)
+				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+			else
+				mask_p[cur_vit_mask / 100] = mask_amt;
+		}
+		cur_vit_mask -= 100;
+	}
+
+	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+		| (mask_m[48] << 26) | (mask_m[49] << 24)
+		| (mask_m[50] << 22) | (mask_m[51] << 20)
+		| (mask_m[52] << 18) | (mask_m[53] << 16)
+		| (mask_m[54] << 14) | (mask_m[55] << 12)
+		| (mask_m[56] << 10) | (mask_m[57] << 8)
+		| (mask_m[58] << 6) | (mask_m[59] << 4)
+		| (mask_m[60] << 2) | (mask_m[61] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+	tmp_mask = (mask_m[31] << 28)
+		| (mask_m[32] << 26) | (mask_m[33] << 24)
+		| (mask_m[34] << 22) | (mask_m[35] << 20)
+		| (mask_m[36] << 18) | (mask_m[37] << 16)
+		| (mask_m[48] << 14) | (mask_m[39] << 12)
+		| (mask_m[40] << 10) | (mask_m[41] << 8)
+		| (mask_m[42] << 6) | (mask_m[43] << 4)
+		| (mask_m[44] << 2) | (mask_m[45] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+		| (mask_m[18] << 26) | (mask_m[18] << 24)
+		| (mask_m[20] << 22) | (mask_m[20] << 20)
+		| (mask_m[22] << 18) | (mask_m[22] << 16)
+		| (mask_m[24] << 14) | (mask_m[24] << 12)
+		| (mask_m[25] << 10) | (mask_m[26] << 8)
+		| (mask_m[27] << 6) | (mask_m[28] << 4)
+		| (mask_m[29] << 2) | (mask_m[30] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+		| (mask_m[2] << 26) | (mask_m[3] << 24)
+		| (mask_m[4] << 22) | (mask_m[5] << 20)
+		| (mask_m[6] << 18) | (mask_m[7] << 16)
+		| (mask_m[8] << 14) | (mask_m[9] << 12)
+		| (mask_m[10] << 10) | (mask_m[11] << 8)
+		| (mask_m[12] << 6) | (mask_m[13] << 4)
+		| (mask_m[14] << 2) | (mask_m[15] << 0);
+	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+	tmp_mask = (mask_p[15] << 28)
+		| (mask_p[14] << 26) | (mask_p[13] << 24)
+		| (mask_p[12] << 22) | (mask_p[11] << 20)
+		| (mask_p[10] << 18) | (mask_p[9] << 16)
+		| (mask_p[8] << 14) | (mask_p[7] << 12)
+		| (mask_p[6] << 10) | (mask_p[5] << 8)
+		| (mask_p[4] << 6) | (mask_p[3] << 4)
+		| (mask_p[2] << 2) | (mask_p[1] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+	tmp_mask = (mask_p[30] << 28)
+		| (mask_p[29] << 26) | (mask_p[28] << 24)
+		| (mask_p[27] << 22) | (mask_p[26] << 20)
+		| (mask_p[25] << 18) | (mask_p[24] << 16)
+		| (mask_p[23] << 14) | (mask_p[22] << 12)
+		| (mask_p[21] << 10) | (mask_p[20] << 8)
+		| (mask_p[19] << 6) | (mask_p[18] << 4)
+		| (mask_p[17] << 2) | (mask_p[16] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+	tmp_mask = (mask_p[45] << 28)
+		| (mask_p[44] << 26) | (mask_p[43] << 24)
+		| (mask_p[42] << 22) | (mask_p[41] << 20)
+		| (mask_p[40] << 18) | (mask_p[39] << 16)
+		| (mask_p[38] << 14) | (mask_p[37] << 12)
+		| (mask_p[36] << 10) | (mask_p[35] << 8)
+		| (mask_p[34] << 6) | (mask_p[33] << 4)
+		| (mask_p[32] << 2) | (mask_p[31] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+		| (mask_p[59] << 26) | (mask_p[58] << 24)
+		| (mask_p[57] << 22) | (mask_p[56] << 20)
+		| (mask_p[55] << 18) | (mask_p[54] << 16)
+		| (mask_p[53] << 14) | (mask_p[52] << 12)
+		| (mask_p[51] << 10) | (mask_p[50] << 8)
+		| (mask_p[49] << 6) | (mask_p[48] << 4)
+		| (mask_p[47] << 2) | (mask_p[46] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 4a1b992..0086ad3 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
 <at>  <at>  -55,4 +55,7  <at>  <at>  enum ath9k_ant_div_comb_lna_conf {
 	ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2,
 };

+void phy_hw_spur_mitigate(struct ath_hw *ah,
+			  struct ath9k_channel *chan, int bin);
+
 #endif
--

-- 
1.9.1
Olivier Cervello | 14 May 19:08 2015
Picon

ath9k Power Saving Mode (PSM) support

Hello,

I wanted to know if Power Saving Mode (PSM), as defined in 802.11, was
implemented in ath9k and ath9k_htc.

If so, can you tell me in which files the code is located, and what would be
the procedure to modify the existing PSM implementation ? I want to
implement a new power saving algorithm.

Thank you,
O.C.
Alexis Green | 14 May 19:58 2015

ath9k: chance of failing to install unicast encryption key under heavy load

Good <time of day>,

When testing encrypted mesh functionality under heavy load (maxing out the channel), there is a strong possibility that unicast key does not get installed properly into hardware.

This test has been done using OpenWRT trunk <at> svn revision r45676
Repros on TP-Link WDR-4300 hardware, specifically 5Ghz phy ( Atheros AR9340 Rev:2 ). It also reproduces on another piece of hardware running earlier version of OpenWRT ( Atheros AR9280 Rev:2 )

To reproduce, set authsae "lifetime" to a small number of seconds (I've used 30 seconds) then initiate TCP iperf test across the mesh link. With iperf in the background, initiate ICMP ping between the two nodes. Observe pings stop at the rekeying and coming back on the next rekey. Loading ath9k with "nohwcrypt=1" resolves the issue at cost of greatly reduced throughput.

Instrumented code to print out key being installed at authsae, mac80211, and ath9k levels show that correct key is passed all the way down to hardware. Performing REG_READ on the installed key immediately after REGWRITE_BUFFER_FLUSH in ath_hw_set_keycache_entry() indicates that correct key is in the key register. Making authsae daemon instal same key again after waiting for one second reduces the occurrence of the problem, but does not eliminate it.

I can provide my openwrt build .config, image, and node configuration if that helps.

P.S. Possibly manifestation of the same problem - http://lists.shmoo.com/pipermail/hostap/2014-November/031377.html

Thank you all,
Alexis Green
_______________________________________________
ath9k-devel mailing list
ath9k-devel <at> lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel
Dan Carpenter | 14 May 10:34 2015
Picon

[patch] ath9k_htc: memory corruption calling set_bit()

In d8a2c51cdcae ('ath9k_htc: Use atomic operations for op_flags') we
changed things like this:

-	if (priv->op_flags & OP_TSF_RESET) {
+	if (test_bit(OP_TSF_RESET, &priv->op_flags)) {

The problem is that test_bit() takes a bit number and not a mask.  It
means that when we do:

	set_bit(OP_TSF_RESET, &priv->op_flags);

Then it sets the (1 << 6) bit instead of the 6 bit so we are setting a
bit which is past the end of the unsigned long.

Fixes: d8a2c51cdcae ('ath9k_htc: Use atomic operations for op_flags')
Signed-off-by: Dan Carpenter <dan.carpenter <at> oracle.com>
---
OP_TSF_RESET seems to be a write-only bit.  Maybe we should just delete
it?

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index e82a0d4..5dbc617 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
 <at>  <at>  -440,9 +440,9  <at>  <at>  static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
 }
 #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */

-#define OP_BT_PRIORITY_DETECTED    BIT(3)
-#define OP_BT_SCAN                 BIT(4)
-#define OP_TSF_RESET               BIT(6)
+#define OP_BT_PRIORITY_DETECTED    3
+#define OP_BT_SCAN                 4
+#define OP_TSF_RESET               6

 enum htc_op_flags {
 	HTC_FWFLAG_NO_RMW,
Saulo Queiroz | 14 May 04:43 2015
Picon

Question about nullifying OFDM subcarriers

Hi all,

Could someone give a point about the files/registers
I have to play with in order to null a given number of
Tx subcarriers in ath9k or ath5k?

thank you in advance.

--
Saulo Jorge bq
-
"In theory, there is no difference between practice and theory, in practice there is"
-- Someone
_______________________________________________
ath9k-devel mailing list
ath9k-devel <at> lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel
Juan Villa | 6 May 07:19 2015
Picon

Bluetooth 0489:e076 Foxconn / Hon Hai not working

Hi!

I've been trying to make my bluetooth adapter work with no luck,
basically I have this problem:
https://lists.ath9k.org/pipermail/ath9k-devel/2015-January/013578.html

Hardware:
Bus 002 Device 003: ID 0489:e076 Foxconn / Hon Hai

Kernel:
Linux 3.19.4-gentoo+ x86_64

I followed the documentation in
https://wireless.wiki.kernel.org/en/users/drivers/ath3k

It is an AR3011 so I added the VID/PID in the btusb.c blacklist and in
the ath3k.c support list.

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index de4c849..0321023 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
 <at>  <at>  -65,6 +65,7  <at>  <at>  static const struct usb_device_id ath3k_table[] = {
        /* Atheros AR3011 with sflash firmware*/
        { USB_DEVICE(0x0489, 0xE027) },
        { USB_DEVICE(0x0489, 0xE03D) },
+       { USB_DEVICE(0x0489, 0xE076) },
        { USB_DEVICE(0x0930, 0x0215) },
        { USB_DEVICE(0x0CF3, 0x3002) },
        { USB_DEVICE(0x0CF3, 0xE019) },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c91ec52..82fe8e6 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
 <at>  <at>  -153,6 +153,7  <at>  <at>  static const struct usb_device_id blacklist_table[] = {
        /* Atheros 3011 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
        { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
+       { USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_IGNORE },
        { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
        { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
        { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE },

But there is an error when booting:

[    8.529331] Bluetooth: Error in firmware loading err = -110,len =
0, size = 4096
[    8.529352] ath3k: probe of 2-5:1.0 failed with error -110

I have the firmware:

# pwd
/lib/firmware/ar3k
# ls -lh AthrBT_0x01020200.dfu ramps_0x01020200_26.dfu ramps_0x01020200_40.dfu
-rw-r--r-- 1 root root  40K Apr 13 19:17 AthrBT_0x01020200.dfu
-rw-r--r-- 1 root root 1.3K Apr 13 19:17 ramps_0x01020200_26.dfu
-rw-r--r-- 1 root root 1.2K Apr 13 19:17 ramps_0x01020200_40.dfu
# cd ..
# ls -lh ath3k-1.fw
-rw-r--r-- 1 root root 242K Apr 13 19:17 ath3k-1.fw

Thanks
Jeon | 5 May 08:28 2015
Picon

How can I handle ACK frames in ath9k_htc?

I am currently trying to get CPU timestamp counter (TSC) when some types of frames are transmitted or received, PRRQ/PRRP, DATA/ACK.

I am using TP-LINK TL722WN USB type WLAN card, which uses ath9k_htc module.

I've modified functions ath9k_htc_tx_start() and ath9k_rx_tasklet() in htc_drv_txrx.c of backports sources.I can get TSC for PRRQ/PRRP and DATA but not for ACK. And I've used printk for debugging.

With some googling, I've found a such post that ACK is processed at the hardware and not passed to the module (not sure):
https://www.mail-archive.com/ath9k-devel <at> lists.ath9k.org/msg12334.html
Additionally, ACK and Block ACK  is aggregated and there might be no way to handle an individual ACK in ath9k_htc module stage.

Is there a way to execute a function or operation every time when a ACK arrives? Could anyone give me some hints which source file and function I can start with?

Regards,
Jeon.
_______________________________________________
ath9k-devel mailing list
ath9k-devel <at> lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel
Mathieu Slabbinck | 29 Apr 08:26 2015
Picon

Using TX99

Hi,

we are having some troubles using TX99 for our wireless testing.
Our goal is to have a system that can modify:
- Tx gain
- data rate
- tx packet length
- tx mode (continuous/burst)
- specify tx antenna

Currently, we're using a 3.10 kernel with all patches needed to
provide tx99 functionality.
It seems to work fine to. Quick tests with different powers show
different occupation in the spectrum.

But changing for example the datarate seems to fail. It remains at 6.5M
command used: iw dev moni0 set bitrates legacy-5 24

Can anyone provide some pointers on how to change these things?
Is there a reference on how to use tx99 to accomplish all the above goals?

Kr

Mathieu
Louis Desfossez | 24 Apr 12:19 2015
Picon

Packet injection

While trying to inject packets on an Atheros Wireless card I had the  
following problem. It seems to work on an Atheros AR928x with  
driver=ath9k driverversion=2.6.38.7-1.0emulab, but it doesn?t work on  
an Atheros AR93xx with driver=ath9k driverversion=3.13.0-33-generic.
Are there changes in the newer driver that can explain the malfunctioning?
Melvin Chow | 24 Apr 15:10 2015

how to hack the ath9k code and disable 5GHz?

HI,

 

I have been given some hints by the developer to disable the ath9k 5GHz channel by hacking the init.c files

He mentioned I could change ath9k_init_softc() in init.c and find an appropriate place to set ah->disable_5ghz to true. A simple grep for disable_5ghz would have shown this easily.

 

Is there any one could help to find out where is an appropriate place in the init.c file to put the right code in?

I have been stop the project in here for almost a month…hope there is some expert could provide support.

Below is the original init.c code in the kernel 4.0

/////////////////////////////////////////

static int ath9k_init_softc(u16 devid, struct ath_softc *sc,

                                                    const struct ath_bus_ops *bus_ops)

{

                struct ath9k_platform_data *pdata = sc->dev->platform_data;

                struct ath_hw *ah = NULL;

                struct ath9k_hw_capabilities *pCap;

                struct ath_common *common;

                int ret = 0, i;

                int csz = 0;

 

                ah = devm_kzalloc(sc->dev, sizeof(struct ath_hw), GFP_KERNEL);

                if (!ah)

                                return -ENOMEM;

 

                ah->dev = sc->dev;

                ah->hw = sc->hw;

                ah->hw_version.devid = devid;

                ah->reg_ops.read = ath9k_ioread32;

                ah->reg_ops.write = ath9k_iowrite32;

                ah->reg_ops.rmw = ath9k_reg_rmw;

                pCap = &ah->caps;

 

                common = ath9k_hw_common(ah);

 

                /* Will be cleared in ath9k_start() */

                set_bit(ATH_OP_INVALID, &common->op_flags);

 

                sc->sc_ah = ah;

                sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);

                sc->tx99_power = MAX_RATE_POWER + 1;

                init_waitqueue_head(&sc->tx_wait);

                sc->cur_chan = &sc->chanctx[0];

                if (!ath9k_is_chanctx_enabled())

                                sc->cur_chan->hw_queue_base = 0;

 

                if (!pdata || pdata->use_eeprom) {

                                ah->ah_flags |= AH_USE_EEPROM;

                                sc->sc_ah->led_pin = -1;

                } else {

                                sc->sc_ah->gpio_mask = pdata->gpio_mask;

                                sc->sc_ah->gpio_val = pdata->gpio_val;

                                sc->sc_ah->led_pin = pdata->led_pin;

                                ah->is_clk_25mhz = pdata->is_clk_25mhz;

                                ah->get_mac_revision = pdata->get_mac_revision;

                                ah->external_reset = pdata->external_reset;

                                ah->disable_2ghz = pdata->disable_2ghz;

                                ah->disable_5ghz = pdata->disable_5ghz;

                                if (!pdata->endian_check)

                                                ah->ah_flags |= AH_NO_EEP_SWAP;

                }

 

                common->ops = &ah->reg_ops;

                common->bus_ops = bus_ops;

                common->ps_ops = &ath9k_ps_ops;

                common->ah = ah;

                common->hw = sc->hw;

                common->priv = sc;

                common->debug_mask = ath9k_debug;

                common->btcoex_enabled = ath9k_btcoex_enable == 1;

                common->disable_ani = false;

/////////////////////////////////////////////////////

Thanks

 

Best Regards,

 

Melvin Chow

 

Elecom Electronics Supply

ABN: 15 457 351 181

Tel AU: +61 3 9790 6259

Mobile: +61 468 468 128

Email: mailto:melvinc <at> elecomes.com

Web: http://www.elecomes.com

 

_______________________________________________
ath9k-devel mailing list
ath9k-devel <at> lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel

Gmane