[PATCH 2/2] ath9k: Fix ack SIFS time for quarter/half channels

2018-02-20 Thread Wojciech Dubowik
Ack timing generation has to be adapted for 5/10 MHz channels.
Do it by properly initializing ack shift field in TXSIFS
register. Ack shift assumes channel width of 2.5 Hhz so
value zero means 2.5 MHz, 1 is 5 MHz and so on.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/hw.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c 
b/drivers/net/wireless/ath/ath9k/hw.c
index 3017078..6b37036 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1038,7 +1038,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
int acktimeout, ctstimeout, ack_offset = 0;
int slottime;
int sifstime;
-   int rx_lat = 0, tx_lat = 0, eifs = 0;
+   int rx_lat = 0, tx_lat = 0, eifs = 0, ack_shift = 0;
u32 reg;
 
ath_dbg(ath9k_hw_common(ah), RESET, "ah->misc_mode 0x%x\n",
@@ -1070,6 +1070,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
 
sifstime = 32;
ack_offset = 16;
+   ack_shift = 3;
slottime = 13;
} else if (IS_CHAN_QUARTER_RATE(chan)) {
eifs = 340;
@@ -1080,6 +1081,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
 
sifstime = 64;
ack_offset = 32;
+   ack_shift = 1;
slottime = 21;
} else {
if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
@@ -1136,6 +1138,10 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
SM(tx_lat, AR_USEC_TX_LAT),
AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC);
 
+   if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
+   REG_RMW(ah, AR_TXSIFS,
+   sifstime | SM(ack_shift, AR_TXSIFS_ACK_SHIFT),
+   (AR_TXSIFS_TIME | AR_TXSIFS_ACK_SHIFT));
 }
 EXPORT_SYMBOL(ath9k_hw_init_global_settings);
 
-- 
2.7.4



[PATCH 1/2] ath9k: Fix airtime calculation for quarter/half channels

2018-02-20 Thread Wojciech Dubowik
The bitrate value for airtime calculation is specified for
full rates. We need to divide it for 5 and 10MHz channels to
get correct result.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/hw.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c 
b/drivers/net/wireless/ath/ath9k/hw.c
index cd0f023..3017078 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -184,7 +184,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
break;
case WLAN_RC_PHY_OFDM:
if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
-   bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 
1000;
+   bitsPerSymbol =
+   ((kbps >> 2) * OFDM_SYMBOL_TIME_QUARTER) / 1000;
numBits = OFDM_PLCP_BITS + (frameLen << 3);
numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
txTime = OFDM_SIFS_TIME_QUARTER
@@ -192,7 +193,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
+ (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
} else if (ah->curchan &&
   IS_CHAN_HALF_RATE(ah->curchan)) {
-   bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
+   bitsPerSymbol =
+   ((kbps >> 1) * OFDM_SYMBOL_TIME_HALF) / 1000;
numBits = OFDM_PLCP_BITS + (frameLen << 3);
numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
txTime = OFDM_SIFS_TIME_HALF +
-- 
2.7.4



[PATCH] ath9k: Fix get channel default noise floor

2018-01-26 Thread Wojciech Dubowik
Commit 8da58553cc63 ("ath9k: Use calibrated noise floor value
when available") introduced regression in ath9k_hw_getchan_noise
where per chain nominal noise floor has been taken instead default
for channel.
Revert to original default channel noise floor.

Reported-by: Sebastian Gottschall <s.gottsch...@dd-wrt.com>
Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/calib.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c 
b/drivers/net/wireless/ath/ath9k/calib.c
index 3d9447e..695c779 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -72,7 +72,7 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan,
   s16 nf)
 {
-   s8 noise = ath9k_hw_get_default_nf(ah, chan, 0);
+   s8 noise = ATH_DEFAULT_NOISE_FLOOR;
 
if (nf) {
s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH -
-- 
2.7.4



Re: [PATCH 0/4] ath9k: AR9003 noise floor calibration support

2018-01-26 Thread Wojciech Dubowik



On 26/01/18 12:42, Sebastian Gottschall wrote:

i have a idea what one cause could ne

+    nfval =
+    ath9k_hw_get_nf_limits(ah, chan)->cal[i];
+    if (nfval > -60 || nfval < -127)
+    nfval = default_nf;

This is just a check to make sure we have sane calibrated values. 
Anything above -60 or under -127 will not work so

we take nominal value.
this code here will allways return the default_nf since all possible 
returned values are within that range
and the || is likelly wrong too and must be replaced with &&. but the 
range itself looks bogus. can't be right


so please do me a favor and test your code against 9280 chipsets too 
and check if its working. right now its a full regression incidence

and should be reverted



Am 26.01.2018 um 12:07 schrieb Wojciech Dubowik:
Are you sure you have applied path 4 in the series. You should see 
calibration piers. Sth like:


Calibration data
Chain 0
Freq     ref    volt    temp    nf_cal    nf_pow    rx_temp
2412    14    0    136    0    0    0
2437    13    0    136    0    0    0
2472    11    0    136    0    0    0
Chain 1
Freq     ref    volt    temp    nf_cal    nf_pow    rx_temp
2412    11    0    137    0    0    0
2437    11    0    139    0    0    0
2472    10    0    137    0    0    0
Chain 2
Freq     ref    volt    temp    nf_cal    nf_pow    rx_temp
2412    13    0    138    0    0    0
2437    14    0    139    0    0    0
2472    14    0    139    0    0    0

I have just done backports from ath.git and I can see these entries 
with my Compex card.


Wojtek


On 26/01/18 11:36, Sebastian Gottschall wrote:

Am 26.01.2018 um 11:27 schrieb Wojciech Dubowik:

I will try it with again with couple of OEM cards.
this is no card. the eeprom is stored in flash memory. so the chip 
is a 9280 pcie chip which is connected on board, but has no own 
flash memory for calibration data. this is stored in system flash 
memory


Is nanostation calibrated for noisefloor? You can see it with 
modal_eeprom in debugfs.

root@TRO2:/sys/kernel/debug/ieee80211/phy0/ath9k# cat modal_eeprom
   2GHz modal Header :
 Chain0 Ant. Control :  0
 Chain1 Ant. Control :  0
 Chain2 Ant. Control :  0
 Ant. Common Control :  0
    Chain0 Ant. Gain :  0
    Chain1 Ant. Gain :  0
    Chain2 Ant. Gain :  0
   Switch Settle : 45
    Chain0 TxRxAtten : 11
    Chain1 TxRxAtten : 11
    Chain2 TxRxAtten : 11
   Chain0 RxTxMargin : 11
   Chain1 RxTxMargin : 11
   Chain2 RxTxMargin : 11
    ADC Desired size :    224
    PGA Desired size :  0
    Chain0 xlna Gain : 14
    Chain1 xlna Gain : 14
    Chain2 xlna Gain : 14
   txEndToXpaOff :  0
 txEndToRxOn :  2
  txFrameToXpaOn : 14
  CCA Threshold) :  0
 Chain0 NF Threshold :    202
 Chain1 NF Threshold :    202
 Chain2 NF Threshold :    202
 xpdGain :  9
 External PD :  1
Chain0 I Coefficient :  0
Chain1 I Coefficient :  0
Chain2 I Coefficient :  0
Chain0 Q Coefficient :  0
Chain1 Q Coefficient :  0
Chain2 Q Coefficient :  0
   pdGainOverlap :  6
   Chain0 OutputBias :  2
   Chain0 DriverBias :  2
  xPA Bias Level :  0
 2chain pwr decrease :  0
 3chain pwr decrease :  0
  txFrameToDataStart : 14
   txFrameToPaOn : 14
 HT40 Power Inc. :  2
 Chain0 bswAtten : 21
 Chain1 bswAtten : 21
 Chain2 bswAtten :  0
    Chain0 bswMargin : 31
    Chain1 bswMargin : 31
    Chain2 bswMargin :  0
  HT40 Switch Settle : 44
    Chain0 xatten2Db :  0
    Chain1 xatten2Db :  0
    Chain2 xatten2Db :  0
Chain0 xatten2Margin :  0
Chain1 xatten2Margin :  0
Chain2 xatten2Margin :  0
   Chain1 OutputBias :  2
   Chain1 DriverBias :  2
 LNA Control : 13
  XPA Bias Freq0 :  0
  XPA Bias Freq1 :  0
  XPA Bias Freq2 :  0
   5GHz modal Header :
 Chain0 Ant. Control : 16
 Chain1 Ant. Control : 16
 Chain2 Ant. Control :  0
 Ant. Common Control :    288
    Chain0 Ant. Gain :  0
    Chain1 Ant. Gain :  0
    Chain2 Ant. Gain :  0
   Switch Settle : 45
    Chain0 TxRxAtten : 32
    Chain1 TxRxAtten : 32
    Chain2 TxRxAtten : 11
   Chain0 RxTxMargin :  0
   Chain1 RxTxMargin :  0
   Chain2 RxTxMargin : 16
    ADC Desired size :    226
    PGA Desired size :  0
    Chain0 xlna Gain : 13
    Chain1 xlna Gain : 13
    Chain2 xlna Gain : 13
   txEndToXpaOff :  0
 txEndTo

Re: [PATCH 0/4] ath9k: AR9003 noise floor calibration support

2018-01-26 Thread Wojciech Dubowik



On 26/01/18 12:35, Sebastian Gottschall wrote:

after reverting your patches all looks normal again. noise is -95

root@TRO2:/sys/kernel/debug/ieee80211/phy0/ath9k# cat dump_nfcal
Channel Noise Floor : -95
Chain | privNF | # Readings | NF Readings
 0   -108    5   -108 -108 -107 -108 -108
 1   -106    5   -106 -106 -106 -105 -106
I will send a patch which fixes it. I have been taking per chain nominal 
noise

which is not the same as per channel noise.



root@TRO2:/sys/kernel/debug/ieee80211/phy0/ath9k# cat modal_eeprom
   2GHz modal Header :
 Chain0 Ant. Control :  0
 Chain1 Ant. Control :  0
 Chain2 Ant. Control :  0
 Ant. Common Control :  0
    Chain0 Ant. Gain :  0
    Chain1 Ant. Gain :  0
    Chain2 Ant. Gain :  0
   Switch Settle : 45
    Chain0 TxRxAtten : 11
    Chain1 TxRxAtten : 11
    Chain2 TxRxAtten : 11
   Chain0 RxTxMargin : 11
   Chain1 RxTxMargin : 11
   Chain2 RxTxMargin : 11
    ADC Desired size :    224
    PGA Desired size :  0
    Chain0 xlna Gain : 14
    Chain1 xlna Gain : 14
    Chain2 xlna Gain : 14
   txEndToXpaOff :  0
 txEndToRxOn :  2
  txFrameToXpaOn : 14
  CCA Threshold) :  0
 Chain0 NF Threshold :    202
 Chain1 NF Threshold :    202
 Chain2 NF Threshold :    202
 xpdGain :  9
 External PD :  1
Chain0 I Coefficient :  0
Chain1 I Coefficient :  0
Chain2 I Coefficient :  0
Chain0 Q Coefficient :  0
Chain1 Q Coefficient :  0
Chain2 Q Coefficient :  0
   pdGainOverlap :  6
   Chain0 OutputBias :  2
   Chain0 DriverBias :  2
  xPA Bias Level :  0
 2chain pwr decrease :  0
 3chain pwr decrease :  0
  txFrameToDataStart : 14
   txFrameToPaOn : 14
 HT40 Power Inc. :  2
 Chain0 bswAtten : 21
 Chain1 bswAtten : 21
 Chain2 bswAtten :  0
    Chain0 bswMargin : 31
    Chain1 bswMargin : 31
    Chain2 bswMargin :  0
  HT40 Switch Settle : 44
    Chain0 xatten2Db :  0
    Chain1 xatten2Db :  0
    Chain2 xatten2Db :  0
Chain0 xatten2Margin :  0
Chain1 xatten2Margin :  0
Chain2 xatten2Margin :  0
   Chain1 OutputBias :  2
   Chain1 DriverBias :  2
 LNA Control : 13
  XPA Bias Freq0 :  0
  XPA Bias Freq1 :  0
  XPA Bias Freq2 :  0
   5GHz modal Header :
 Chain0 Ant. Control : 16
 Chain1 Ant. Control : 16
 Chain2 Ant. Control :  0
 Ant. Common Control :    288
    Chain0 Ant. Gain :  0
    Chain1 Ant. Gain :  0
    Chain2 Ant. Gain :  0
   Switch Settle : 45
    Chain0 TxRxAtten : 32
    Chain1 TxRxAtten : 32
    Chain2 TxRxAtten : 11
   Chain0 RxTxMargin :  0
   Chain1 RxTxMargin :  0
   Chain2 RxTxMargin : 16
    ADC Desired size :    226
    PGA Desired size :  0
    Chain0 xlna Gain : 13
    Chain1 xlna Gain : 13
    Chain2 xlna Gain : 13
   txEndToXpaOff :  0
 txEndToRxOn :  2
  txFrameToXpaOn : 14
  CCA Threshold) : 28
 Chain0 NF Threshold :    255
 Chain1 NF Threshold :    255
 Chain2 NF Threshold :    255
 xpdGain :  1
 External PD :  1
Chain0 I Coefficient :  0
Chain1 I Coefficient :  0
Chain2 I Coefficient :  0
Chain0 Q Coefficient :  0
Chain1 Q Coefficient :  0
Chain2 Q Coefficient :  0
   pdGainOverlap :  6
   Chain0 OutputBias :  3
   Chain0 DriverBias :  3
  xPA Bias Level :  2
 2chain pwr decrease :  0
 3chain pwr decrease :  0
  txFrameToDataStart : 14
   txFrameToPaOn : 14
 HT40 Power Inc. :  0
 Chain0 bswAtten : 34
 Chain1 bswAtten : 34
 Chain2 bswAtten :  0
    Chain0 bswMargin : 22
    Chain1 bswMargin : 22
    Chain2 bswMargin :  0
  HT40 Switch Settle : 45
    Chain0 xatten2Db :  0
    Chain1 xatten2Db :  0
    Chain2 xatten2Db :  0
Chain0 xatten2Margin :  0
Chain1 xatten2Margin :  0
Chain2 xatten2Margin :  0
   Chain1 OutputBias :  3
   Chain1 DriverBias :  3
 LNA Control : 13
  XPA Bias Freq0 :  0
  XPA Bias Freq1 :  0
  XPA Bias Freq2 :  0


Am 26.01.2018 um 12:07 schrieb Wojciech Dubowik:
Are you sure you have applied path 4 in the series. You should see 
calibration piers. Sth like:


Calibration data
Chain 0

Re: [PATCH 0/4] ath9k: AR9003 noise floor calibration support

2018-01-26 Thread Wojciech Dubowik
Are you sure you have applied path 4 in the series. You should see 
calibration piers. Sth like:


Calibration data
Chain 0
Freq     ref    volt    temp    nf_cal    nf_pow    rx_temp
2412    14    0    136    0    0    0
2437    13    0    136    0    0    0
2472    11    0    136    0    0    0
Chain 1
Freq     ref    volt    temp    nf_cal    nf_pow    rx_temp
2412    11    0    137    0    0    0
2437    11    0    139    0    0    0
2472    10    0    137    0    0    0
Chain 2
Freq     ref    volt    temp    nf_cal    nf_pow    rx_temp
2412    13    0    138    0    0    0
2437    14    0    139    0    0    0
2472    14    0    139    0    0    0

I have just done backports from ath.git and I can see these entries with 
my Compex card.


Wojtek


On 26/01/18 11:36, Sebastian Gottschall wrote:

Am 26.01.2018 um 11:27 schrieb Wojciech Dubowik:

I will try it with again with couple of OEM cards.
this is no card. the eeprom is stored in flash memory. so the chip is 
a 9280 pcie chip which is connected on board, but has no own flash 
memory for calibration data. this is stored in system flash memory


Is nanostation calibrated for noisefloor? You can see it with 
modal_eeprom in debugfs.

root@TRO2:/sys/kernel/debug/ieee80211/phy0/ath9k# cat modal_eeprom
   2GHz modal Header :
 Chain0 Ant. Control :  0
 Chain1 Ant. Control :  0
 Chain2 Ant. Control :  0
 Ant. Common Control :  0
    Chain0 Ant. Gain :  0
    Chain1 Ant. Gain :  0
    Chain2 Ant. Gain :  0
   Switch Settle : 45
    Chain0 TxRxAtten : 11
    Chain1 TxRxAtten : 11
    Chain2 TxRxAtten : 11
   Chain0 RxTxMargin : 11
   Chain1 RxTxMargin : 11
   Chain2 RxTxMargin : 11
    ADC Desired size :    224
    PGA Desired size :  0
    Chain0 xlna Gain : 14
    Chain1 xlna Gain : 14
    Chain2 xlna Gain : 14
   txEndToXpaOff :  0
 txEndToRxOn :  2
  txFrameToXpaOn : 14
  CCA Threshold) :  0
 Chain0 NF Threshold :    202
 Chain1 NF Threshold :    202
 Chain2 NF Threshold :    202
 xpdGain :  9
 External PD :  1
Chain0 I Coefficient :  0
Chain1 I Coefficient :  0
Chain2 I Coefficient :  0
Chain0 Q Coefficient :  0
Chain1 Q Coefficient :  0
Chain2 Q Coefficient :  0
   pdGainOverlap :  6
   Chain0 OutputBias :  2
   Chain0 DriverBias :  2
  xPA Bias Level :  0
 2chain pwr decrease :  0
 3chain pwr decrease :  0
  txFrameToDataStart : 14
   txFrameToPaOn : 14
 HT40 Power Inc. :  2
 Chain0 bswAtten : 21
 Chain1 bswAtten : 21
 Chain2 bswAtten :  0
    Chain0 bswMargin : 31
    Chain1 bswMargin : 31
    Chain2 bswMargin :  0
  HT40 Switch Settle : 44
    Chain0 xatten2Db :  0
    Chain1 xatten2Db :  0
    Chain2 xatten2Db :  0
Chain0 xatten2Margin :  0
Chain1 xatten2Margin :  0
Chain2 xatten2Margin :  0
   Chain1 OutputBias :  2
   Chain1 DriverBias :  2
 LNA Control : 13
  XPA Bias Freq0 :  0
  XPA Bias Freq1 :  0
  XPA Bias Freq2 :  0
   5GHz modal Header :
 Chain0 Ant. Control : 16
 Chain1 Ant. Control : 16
 Chain2 Ant. Control :  0
 Ant. Common Control :    288
    Chain0 Ant. Gain :  0
    Chain1 Ant. Gain :  0
    Chain2 Ant. Gain :  0
   Switch Settle : 45
    Chain0 TxRxAtten : 32
    Chain1 TxRxAtten : 32
    Chain2 TxRxAtten : 11
   Chain0 RxTxMargin :  0
   Chain1 RxTxMargin :  0
   Chain2 RxTxMargin : 16
    ADC Desired size :    226
    PGA Desired size :  0
    Chain0 xlna Gain : 13
    Chain1 xlna Gain : 13
    Chain2 xlna Gain : 13
   txEndToXpaOff :  0
 txEndToRxOn :  2
  txFrameToXpaOn : 14
  CCA Threshold) : 28
 Chain0 NF Threshold :    255
 Chain1 NF Threshold :    255
 Chain2 NF Threshold :    255
 xpdGain :  1
 External PD :  1
Chain0 I Coefficient :  0
Chain1 I Coefficient :  0
Chain2 I Coefficient :  0
Chain0 Q Coefficient :  0
Chain1 Q Coefficient :  0
Chain2 Q Coefficient :  0
   pdGainOverlap :  6
   Chain0 OutputBias :  3
   Chain0 DriverBias :  3
  xPA Bias Level :  2
 2chain pwr decrease :  0
 3chain pwr decrease :  0
  txFrameToDataStart : 14
   txFrameToPaOn : 14
 HT40 Power Inc. :  0
 Chain0 bswAtten : 34
 Chain1 bswAtten : 34
 Chain2 bswAtten :  0

Re: [PATCH 0/4] ath9k: AR9003 noise floor calibration support

2018-01-26 Thread Wojciech Dubowik

I will try it with again with couple of OEM cards.

Is nanostation calibrated for noisefloor? You can see it with 
modal_eeprom in debugfs.


Wojtek
On 26/01/18 10:59, Sebastian Gottschall wrote:
i dont know if this is a coincidence. but after testing your patch on 
a standard ubiquiti nanostation m2 the noise floor looks wrong.
it will stay on -112 which is clearly impossible in 2.4 (before it was 
around -96)




[PATCH v2 0/4] ath9k: AR9003 noise floor calibration support

2018-01-24 Thread Wojciech Dubowik
AR9003 series allows to calibrate noise floor for different frequency
bins. Once it's done it's possible to get more accurate rssi/signal
values over whole frequency band at a given temperature.
The RSSI/signal accuracy reported by calibrated RF cards improves
from 6 to up to 2dB.

This could be interesting for application which require good signal
accuracy like roaming or mesh protocols.

V2: Copied cover letter feature description to patch 3 in the series.

Wojciech Dubowik (4):
  ath9k: Alternative EEPROM size for AR9003
  ath9k: Read noise floor calibration data from eeprom
  ath9k: Use calibrated noise floor value when available
  ath9k: Display calibration data piers in debugfs

 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 133 +++--
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h |  10 ++
 drivers/net/wireless/ath/ath9k/calib.c |  38 ---
 drivers/net/wireless/ath/ath9k/hw.h|   2 +
 4 files changed, 160 insertions(+), 23 deletions(-)

-- 
2.7.4



[PATCH v2 4/4] ath9k: Display calibration data piers in debugfs

2018-01-24 Thread Wojciech Dubowik
Display per frequency calibration data in dump_modal
debugfs entry including reference power, voltage,
tx temperature and noise floor.

Example of chain 0 of OEM card (dump from modal_eeprom):
Chain 0
Freq refvolttempnf_Cal  nf_Pow  rx_temp
5180-30 0   137 0   0   0
5320-24 0   137 0   0   0
5500-15 0   137 0   0   0
5620-10 0   137 0   0   0
5700-15 0   137 0   0   0
5745-16 0   135 0   0   0
5785-19 0   136 0   0   0
5825-22 0   136 0   0   0

Example of a card with calibrated noise floor.
Chain 0
Freq refvolttempnf_Cal  nf_Pow  rx_temp
4890-49 0   128 -107-97 124
5100-23 0   128 -101-96 124
5180-18 0   128 -101-96 124
5300-12 0   128 -102-97 124
5500-9  0   128 -101-97 125
5640-17 0   128 -101-98 124
5785-25 0   128 -101-98 124
5940-33 0   128 -106-99 124

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 64 +-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index de2e503..f019a20 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3436,6 +3436,60 @@ static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, 
u32 size,
return len;
 }
 
+static u32 ar9003_dump_cal_data(struct ath_hw *ah, char *buf, u32 len, u32 
size,
+   bool is_2g)
+{
+   struct ar9300_eeprom *eep = >eeprom.ar9300_eep;
+   struct ar9300_base_eep_hdr *pBase;
+   struct ar9300_cal_data_per_freq_op_loop *cal_pier;
+   int cal_pier_nr;
+   int freq;
+   int i, j;
+
+   pBase = >baseEepHeader;
+
+   if (is_2g)
+   cal_pier_nr = AR9300_NUM_2G_CAL_PIERS;
+   else
+   cal_pier_nr = AR9300_NUM_5G_CAL_PIERS;
+
+   for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+   if (!((pBase->txrxMask >> i) & 1))
+   continue;
+
+   len += snprintf(buf + len, size - len, "Chain %d\n", i);
+
+   len += snprintf(buf + len, size - len,
+   "Freq\t ref\tvolt\ttemp\tnf_cal\tnf_pow\trx_temp\n");
+
+   for (j = 0; j < cal_pier_nr; j++) {
+   if (is_2g) {
+   cal_pier = >calPierData2G[i][j];
+   freq = 2300 + eep->calFreqPier2G[j];
+   } else {
+   cal_pier = >calPierData5G[i][j];
+   freq = 4800 + eep->calFreqPier5G[j] * 5;
+   }
+
+   len += snprintf(buf + len, size - len,
+   "%d\t", freq);
+
+   len += snprintf(buf + len, size - len,
+   "%d\t%d\t%d\t%d\t%d\t%d\n",
+   cal_pier->refPower,
+   cal_pier->voltMeas,
+   cal_pier->tempMeas,
+   cal_pier->rxTempMeas ?
+   N2DBM(cal_pier->rxNoisefloorCal) : 0,
+   cal_pier->rxTempMeas ?
+   N2DBM(cal_pier->rxNoisefloorPower) : 0,
+   cal_pier->rxTempMeas);
+   }
+   }
+
+   return len;
+}
+
 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
   u8 *buf, u32 len, u32 size)
 {
@@ -3447,10 +3501,18 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw 
*ah, bool dump_base_hdr,
 "%20s :\n", "2GHz modal Header");
len = ar9003_dump_modal_eeprom(buf, len, size,
>modalHeader2G);
-   len += scnprintf(buf + len, size - len,
+
+   len += scnprintf(buf + len, size - len, "Calibration data\n");
+   len = ar9003_dump_cal_data(ah, buf, len, size, true);
+
+   len +=  snprintf(buf + len, size - len,
 "%20s :\n", "5GHz modal Header");
len = ar9003_dump_modal_eeprom(buf, len, size,
>modalHeader5G);
+
+   len += snprintf(buf + len, size - len, "Calibration data\n");
+   len = ar9003_dump_cal_data(ah, buf, len, size, false);
+
goto out;
}
 
-- 
2.7.4



[PATCH v2 3/4] ath9k: Use calibrated noise floor value when available

2018-01-24 Thread Wojciech Dubowik
AR9003 series allows to calibrate noise floor for different frequency
bins. Once it's done it's possible to get more accurate rssi/signal
values over whole frequency band at a given temperature.
The RSSI/signal accuracy reported by calibrated RF cards improves
from 6 to up to 2dB.

This could be interesting for application which require good signal
accuracy like roaming or mesh protocols.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/calib.c | 38 +-
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c 
b/drivers/net/wireless/ath/ath9k/calib.c
index 13ab6bc..3d9447e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -58,19 +58,25 @@ static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct 
ath_hw *ah,
 }
 
 static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
-  struct ath9k_channel *chan)
+  struct ath9k_channel *chan,
+  int chain)
 {
-   return ath9k_hw_get_nf_limits(ah, chan)->nominal;
+   s16 calib_nf = ath9k_hw_get_nf_limits(ah, chan)->cal[chain];
+
+   if (calib_nf)
+   return calib_nf;
+   else
+   return ath9k_hw_get_nf_limits(ah, chan)->nominal;
 }
 
 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan,
   s16 nf)
 {
-   s8 noise = ATH_DEFAULT_NOISE_FLOOR;
+   s8 noise = ath9k_hw_get_default_nf(ah, chan, 0);
 
if (nf) {
s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH -
-  ath9k_hw_get_default_nf(ah, chan);
+  ath9k_hw_get_default_nf(ah, chan, 0);
if (delta > 0)
noise += delta;
}
@@ -240,7 +246,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel 
*chan)
unsigned i, j;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
struct ath_common *common = ath9k_hw_common(ah);
-   s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
+   s16 default_nf = ath9k_hw_get_nf_limits(ah, chan)->nominal;
u32 bb_agc_ctl = REG_READ(ah, AR_PHY_AGC_CONTROL);
 
if (ah->caldata)
@@ -258,8 +264,13 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct 
ath9k_channel *chan)
nfval = ah->nf_override;
else if (h)
nfval = h[i].privNF;
-   else
-   nfval = default_nf;
+   else {
+   /* Try to get calibrated noise floor value */
+   nfval =
+   ath9k_hw_get_nf_limits(ah, chan)->cal[i];
+   if (nfval > -60 || nfval < -127)
+   nfval = default_nf;
+   }
 
REG_RMW(ah, ah->nf_regs[i],
(((u32) nfval << 1) & 0x1ff), 0x1ff);
@@ -429,20 +440,19 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
  struct ath9k_channel *chan)
 {
struct ath9k_nfcal_hist *h;
-   s16 default_nf;
-   int i, j;
+   int i, j, k = 0;
 
ah->caldata->channel = chan->channel;
ah->caldata->channelFlags = chan->channelFlags;
h = ah->caldata->nfCalHist;
-   default_nf = ath9k_hw_get_default_nf(ah, chan);
for (i = 0; i < NUM_NF_READINGS; i++) {
h[i].currIndex = 0;
-   h[i].privNF = default_nf;
+   h[i].privNF = ath9k_hw_get_default_nf(ah, chan, k);
h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH;
-   for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
-   h[i].nfCalBuffer[j] = default_nf;
-   }
+   for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++)
+   h[i].nfCalBuffer[j] = h[i].privNF;
+   if (++k >= AR5416_MAX_CHAINS)
+   k = 0;
}
 }
 
-- 
2.7.4



[PATCH v2 1/4] ath9k: Alternative EEPROM size for AR9003

2018-01-24 Thread Wojciech Dubowik
AR9003 factory calibration allows to use bigger EEPROM than
standard 1k without changing the default layout. Allow
probing of EEPROM at alternative address if initial check
for default fails.
The original ar9003 eeprom ops are still be used.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c2e210c..23bb677 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3310,6 +3310,12 @@ static int ar9300_eeprom_restore_internal(struct ath_hw 
*ah,
if (ar9300_check_eeprom_header(ah, read, cptr))
goto found;
 
+   cptr = AR9300_BASE_ADDR_4K;
+   ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
+   cptr);
+   if (ar9300_check_eeprom_header(ah, read, cptr))
+   goto found;
+
cptr = AR9300_BASE_ADDR_512;
ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
cptr);
-- 
2.7.4



[PATCH v2 2/4] ath9k: Read noise floor calibration data from eeprom

2018-01-24 Thread Wojciech Dubowik
AR9003 devices can have calibrated noise floor values
which can be used instead of hard coded one. Read them
from eeprom and save interpolated value in nf limits for
the current channel.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 63 ++
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 10 
 drivers/net/wireless/ath/ath9k/hw.h|  2 +
 3 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 23bb677..de2e503 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4689,7 +4689,8 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
  int ichain,
  int *pfrequency,
  int *pcorrection,
- int *ptemperature, int *pvoltage)
+ int *ptemperature, int *pvoltage,
+ int *pnf_cal, int *pnf_power)
 {
u8 *pCalPier;
struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
@@ -4731,6 +4732,10 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
*pcorrection = pCalPierStruct->refPower;
*ptemperature = pCalPierStruct->tempMeas;
*pvoltage = pCalPierStruct->voltMeas;
+   *pnf_cal = pCalPierStruct->rxTempMeas ?
+   N2DBM(pCalPierStruct->rxNoisefloorCal) : 0;
+   *pnf_power = pCalPierStruct->rxTempMeas ?
+   N2DBM(pCalPierStruct->rxNoisefloorPower) : 0;
 
return 0;
 }
@@ -4895,14 +4900,18 @@ static int ar9003_hw_calibration_apply(struct ath_hw 
*ah, int frequency)
int mode;
int lfrequency[AR9300_MAX_CHAINS],
lcorrection[AR9300_MAX_CHAINS],
-   ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
+   ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS],
+   lnf_cal[AR9300_MAX_CHAINS], lnf_pwr[AR9300_MAX_CHAINS];
int hfrequency[AR9300_MAX_CHAINS],
hcorrection[AR9300_MAX_CHAINS],
-   htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
+   htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS],
+   hnf_cal[AR9300_MAX_CHAINS], hnf_pwr[AR9300_MAX_CHAINS];
int fdiff;
int correction[AR9300_MAX_CHAINS],
-   voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
-   int pfrequency, pcorrection, ptemperature, pvoltage;
+   voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS],
+   nf_cal[AR9300_MAX_CHAINS], nf_pwr[AR9300_MAX_CHAINS];
+   int pfrequency, pcorrection, ptemperature, pvoltage,
+   pnf_cal, pnf_pwr;
struct ath_common *common = ath9k_hw_common(ah);
 
mode = (frequency >= 4000);
@@ -4920,7 +4929,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
for (ipier = 0; ipier < npier; ipier++) {
if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
, ,
-   , )) {
+   , ,
+   _cal, _pwr)) {
fdiff = frequency - pfrequency;
 
/*
@@ -4942,6 +4952,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
htemperature[ichain] =
ptemperature;
hvoltage[ichain] = pvoltage;
+   hnf_cal[ichain] = pnf_cal;
+   hnf_pwr[ichain] = pnf_pwr;
}
}
if (fdiff >= 0) {
@@ -4958,6 +4970,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
ltemperature[ichain] =
ptemperature;
lvoltage[ichain] = pvoltage;
+   lnf_cal[ichain] = pnf_cal;
+   lnf_pwr[ichain] = pnf_pwr;
}
}
}
@@ -4966,15 +4980,20 @@ static int ar9003_hw_calibration_apply(struct ath_hw 
*ah, int frequency)
 
/* interpolate  */
for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
-   ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %

[PATCH 2/4] ath9k: Read noise floor calibration data from eeprom

2018-01-22 Thread Wojciech Dubowik
AR9003 devices can have calibrated noise floor values
which can be used instead of hard coded one. Read them
from eeprom and save interpolated value in nf limits for
the current channel.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 63 ++
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 10 
 drivers/net/wireless/ath/ath9k/hw.h|  2 +
 3 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 23bb677..de2e503 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4689,7 +4689,8 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
  int ichain,
  int *pfrequency,
  int *pcorrection,
- int *ptemperature, int *pvoltage)
+ int *ptemperature, int *pvoltage,
+ int *pnf_cal, int *pnf_power)
 {
u8 *pCalPier;
struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
@@ -4731,6 +4732,10 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
*pcorrection = pCalPierStruct->refPower;
*ptemperature = pCalPierStruct->tempMeas;
*pvoltage = pCalPierStruct->voltMeas;
+   *pnf_cal = pCalPierStruct->rxTempMeas ?
+   N2DBM(pCalPierStruct->rxNoisefloorCal) : 0;
+   *pnf_power = pCalPierStruct->rxTempMeas ?
+   N2DBM(pCalPierStruct->rxNoisefloorPower) : 0;
 
return 0;
 }
@@ -4895,14 +4900,18 @@ static int ar9003_hw_calibration_apply(struct ath_hw 
*ah, int frequency)
int mode;
int lfrequency[AR9300_MAX_CHAINS],
lcorrection[AR9300_MAX_CHAINS],
-   ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
+   ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS],
+   lnf_cal[AR9300_MAX_CHAINS], lnf_pwr[AR9300_MAX_CHAINS];
int hfrequency[AR9300_MAX_CHAINS],
hcorrection[AR9300_MAX_CHAINS],
-   htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
+   htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS],
+   hnf_cal[AR9300_MAX_CHAINS], hnf_pwr[AR9300_MAX_CHAINS];
int fdiff;
int correction[AR9300_MAX_CHAINS],
-   voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
-   int pfrequency, pcorrection, ptemperature, pvoltage;
+   voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS],
+   nf_cal[AR9300_MAX_CHAINS], nf_pwr[AR9300_MAX_CHAINS];
+   int pfrequency, pcorrection, ptemperature, pvoltage,
+   pnf_cal, pnf_pwr;
struct ath_common *common = ath9k_hw_common(ah);
 
mode = (frequency >= 4000);
@@ -4920,7 +4929,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
for (ipier = 0; ipier < npier; ipier++) {
if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
, ,
-   , )) {
+   , ,
+   _cal, _pwr)) {
fdiff = frequency - pfrequency;
 
/*
@@ -4942,6 +4952,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
htemperature[ichain] =
ptemperature;
hvoltage[ichain] = pvoltage;
+   hnf_cal[ichain] = pnf_cal;
+   hnf_pwr[ichain] = pnf_pwr;
}
}
if (fdiff >= 0) {
@@ -4958,6 +4970,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
ltemperature[ichain] =
ptemperature;
lvoltage[ichain] = pvoltage;
+   lnf_cal[ichain] = pnf_cal;
+   lnf_pwr[ichain] = pnf_pwr;
}
}
}
@@ -4966,15 +4980,20 @@ static int ar9003_hw_calibration_apply(struct ath_hw 
*ah, int frequency)
 
/* interpolate  */
for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
-   ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %

[PATCH 0/4] ath9k: AR9003 noise floor calibration support

2018-01-22 Thread Wojciech Dubowik
AR9003 series allows to calibrate noise floor for different frequency
bins. Once it's done it's possible to get more accurate rssi/signal
values over whole frequency band at a given temperature.
The RSSI/signal accuracy reported by calibrated RF cards improves
from 6 to up to 2dB.

This could be interesting for application which require good signal
accuracy like roaming or mesh protocols.

Wojciech Dubowik (4):
  ath9k: Alternative EEPROM size for AR9003
  ath9k: Read noise floor calibration data from eeprom
  ath9k: Use calibrated noise floor value when available
  ath9k: Display calibration data piers in debugfs

 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 133 +++--
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h |  10 ++
 drivers/net/wireless/ath/ath9k/calib.c |  38 ---
 drivers/net/wireless/ath/ath9k/hw.h|   2 +
 4 files changed, 160 insertions(+), 23 deletions(-)

-- 
2.7.4



[PATCH 3/4] ath9k: Use calibrated noise floor value when available

2018-01-22 Thread Wojciech Dubowik
Use calibrated noise floor value to improve rssi/signal reporting.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/calib.c | 38 +-
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c 
b/drivers/net/wireless/ath/ath9k/calib.c
index 13ab6bc..3d9447e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -58,19 +58,25 @@ static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct 
ath_hw *ah,
 }
 
 static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
-  struct ath9k_channel *chan)
+  struct ath9k_channel *chan,
+  int chain)
 {
-   return ath9k_hw_get_nf_limits(ah, chan)->nominal;
+   s16 calib_nf = ath9k_hw_get_nf_limits(ah, chan)->cal[chain];
+
+   if (calib_nf)
+   return calib_nf;
+   else
+   return ath9k_hw_get_nf_limits(ah, chan)->nominal;
 }
 
 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan,
   s16 nf)
 {
-   s8 noise = ATH_DEFAULT_NOISE_FLOOR;
+   s8 noise = ath9k_hw_get_default_nf(ah, chan, 0);
 
if (nf) {
s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH -
-  ath9k_hw_get_default_nf(ah, chan);
+  ath9k_hw_get_default_nf(ah, chan, 0);
if (delta > 0)
noise += delta;
}
@@ -240,7 +246,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel 
*chan)
unsigned i, j;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
struct ath_common *common = ath9k_hw_common(ah);
-   s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
+   s16 default_nf = ath9k_hw_get_nf_limits(ah, chan)->nominal;
u32 bb_agc_ctl = REG_READ(ah, AR_PHY_AGC_CONTROL);
 
if (ah->caldata)
@@ -258,8 +264,13 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct 
ath9k_channel *chan)
nfval = ah->nf_override;
else if (h)
nfval = h[i].privNF;
-   else
-   nfval = default_nf;
+   else {
+   /* Try to get calibrated noise floor value */
+   nfval =
+   ath9k_hw_get_nf_limits(ah, chan)->cal[i];
+   if (nfval > -60 || nfval < -127)
+   nfval = default_nf;
+   }
 
REG_RMW(ah, ah->nf_regs[i],
(((u32) nfval << 1) & 0x1ff), 0x1ff);
@@ -429,20 +440,19 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
  struct ath9k_channel *chan)
 {
struct ath9k_nfcal_hist *h;
-   s16 default_nf;
-   int i, j;
+   int i, j, k = 0;
 
ah->caldata->channel = chan->channel;
ah->caldata->channelFlags = chan->channelFlags;
h = ah->caldata->nfCalHist;
-   default_nf = ath9k_hw_get_default_nf(ah, chan);
for (i = 0; i < NUM_NF_READINGS; i++) {
h[i].currIndex = 0;
-   h[i].privNF = default_nf;
+   h[i].privNF = ath9k_hw_get_default_nf(ah, chan, k);
h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH;
-   for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
-   h[i].nfCalBuffer[j] = default_nf;
-   }
+   for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++)
+   h[i].nfCalBuffer[j] = h[i].privNF;
+   if (++k >= AR5416_MAX_CHAINS)
+   k = 0;
}
 }
 
-- 
2.7.4



[PATCH 1/4] ath9k: Alternative EEPROM size for AR9003

2018-01-22 Thread Wojciech Dubowik
AR9003 factory calibration allows to use bigger EEPROM than
standard 1k without changing the default layout. Allow
probing of EEPROM at alternative address if initial check
for default fails.
The original ar9003 eeprom ops are still be used.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c2e210c..23bb677 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3310,6 +3310,12 @@ static int ar9300_eeprom_restore_internal(struct ath_hw 
*ah,
if (ar9300_check_eeprom_header(ah, read, cptr))
goto found;
 
+   cptr = AR9300_BASE_ADDR_4K;
+   ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
+   cptr);
+   if (ar9300_check_eeprom_header(ah, read, cptr))
+   goto found;
+
cptr = AR9300_BASE_ADDR_512;
ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
cptr);
-- 
2.7.4



[PATCH 4/4] ath9k: Display calibration data piers in debugfs

2018-01-22 Thread Wojciech Dubowik
Display per frequency calibration data in dump_modal
debugfs entry including reference power, voltage,
tx temperature and noise floor.

Example of chain 0 of OEM card (dump from modal_eeprom):
Chain 0
Freq refvolttempnf_Cal  nf_Pow  rx_temp
5180-30 0   137 0   0   0
5320-24 0   137 0   0   0
5500-15 0   137 0   0   0
5620-10 0   137 0   0   0
5700-15 0   137 0   0   0
5745-16 0   135 0   0   0
5785-19 0   136 0   0   0
5825-22 0   136 0   0   0

Example of a card with calibrated noise floor.
Chain 0
Freq refvolttempnf_Cal  nf_Pow  rx_temp
4890-49 0   128 -107-97 124
5100-23 0   128 -101-96 124
5180-18 0   128 -101-96 124
5300-12 0   128 -102-97 124
5500-9  0   128 -101-97 125
5640-17 0   128 -101-98 124
5785-25 0   128 -101-98 124
5940-33 0   128 -106-99 124

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 64 +-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index de2e503..f019a20 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3436,6 +3436,60 @@ static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, 
u32 size,
return len;
 }
 
+static u32 ar9003_dump_cal_data(struct ath_hw *ah, char *buf, u32 len, u32 
size,
+   bool is_2g)
+{
+   struct ar9300_eeprom *eep = >eeprom.ar9300_eep;
+   struct ar9300_base_eep_hdr *pBase;
+   struct ar9300_cal_data_per_freq_op_loop *cal_pier;
+   int cal_pier_nr;
+   int freq;
+   int i, j;
+
+   pBase = >baseEepHeader;
+
+   if (is_2g)
+   cal_pier_nr = AR9300_NUM_2G_CAL_PIERS;
+   else
+   cal_pier_nr = AR9300_NUM_5G_CAL_PIERS;
+
+   for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+   if (!((pBase->txrxMask >> i) & 1))
+   continue;
+
+   len += snprintf(buf + len, size - len, "Chain %d\n", i);
+
+   len += snprintf(buf + len, size - len,
+   "Freq\t ref\tvolt\ttemp\tnf_cal\tnf_pow\trx_temp\n");
+
+   for (j = 0; j < cal_pier_nr; j++) {
+   if (is_2g) {
+   cal_pier = >calPierData2G[i][j];
+   freq = 2300 + eep->calFreqPier2G[j];
+   } else {
+   cal_pier = >calPierData5G[i][j];
+   freq = 4800 + eep->calFreqPier5G[j] * 5;
+   }
+
+   len += snprintf(buf + len, size - len,
+   "%d\t", freq);
+
+   len += snprintf(buf + len, size - len,
+   "%d\t%d\t%d\t%d\t%d\t%d\n",
+   cal_pier->refPower,
+   cal_pier->voltMeas,
+   cal_pier->tempMeas,
+   cal_pier->rxTempMeas ?
+   N2DBM(cal_pier->rxNoisefloorCal) : 0,
+   cal_pier->rxTempMeas ?
+   N2DBM(cal_pier->rxNoisefloorPower) : 0,
+   cal_pier->rxTempMeas);
+   }
+   }
+
+   return len;
+}
+
 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
   u8 *buf, u32 len, u32 size)
 {
@@ -3447,10 +3501,18 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw 
*ah, bool dump_base_hdr,
 "%20s :\n", "2GHz modal Header");
len = ar9003_dump_modal_eeprom(buf, len, size,
>modalHeader2G);
-   len += scnprintf(buf + len, size - len,
+
+   len += scnprintf(buf + len, size - len, "Calibration data\n");
+   len = ar9003_dump_cal_data(ah, buf, len, size, true);
+
+   len +=  snprintf(buf + len, size - len,
 "%20s :\n", "5GHz modal Header");
len = ar9003_dump_modal_eeprom(buf, len, size,
>modalHeader5G);
+
+   len += snprintf(buf + len, size - len, "Calibration data\n");
+   len = ar9003_dump_cal_data(ah, buf, len, size, false);
+
goto out;
}
 
-- 
2.7.4



Re: Wifi-Event for when initial 4-way completes?

2017-06-09 Thread Wojciech Dubowik

Hello Ben,

Yes, you are right. There is a case when wpa supplicant is in connected 
state


but the last EAPOL to AP was lost. Client won't be able to communicate 
and AP will


deauthenticate after a while or not. It's easily reproducible with a 
frame corrupter


patch I have sent some time ago. The worst case is when last EAPOL is 
lost and


deauthentication frame from AP as well. It can leave client in dead 
state for


minutes.


I have been debugging such case reported by our customers and it turns out

that supplicant is using L2 send for EAPOL messages without any feedback 
from


mac80211 layer. It means that client has no idea whether these frames have

been acked or not. AP (in mac80211) is using nl command and gets the 
status of the ack


although it's not the last message in the chain.

I have made a patch to send EAPOL on the station with same command as AP

and check for this case i.e. deauthenticate immediately when client is in

connected state but last EAPOL hasn't been acked.

I will try to send it upstream as soon as it's cleaned up a bit.

Br,

Wojtek


On 08/06/17 17:41, Ben Greear wrote:

On 06/08/2017 08:21 AM, Ben Greear wrote:

On 06/07/2017 12:25 AM, Wojciech Dubowik wrote:

Hello Ben,

I have been using this part of wpa_supplicant to notify that 4-Way 
handshake is completed.


around line 868 in wpa_supplicant.c

#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- 
Connection to "

MACSTR " completed [id=%d id_str=%s%s]",
MAC2STR(wpa_s->bssid),
ssid ? ssid->id : -1,
ssid && ssid->id_str ? ssid->id_str : "",
fils_hlp_sent ? " FILS_HLP_SENT" : "");
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */

You can pack whatever notification message inside the if statement.


I'm not sure that actually is correct?  For instance, I see this in a 
case where

WPA-2 was not succesfully negotiated (note the reason-2 disconnect)

IFNAME=sta9 <3>SME: Trying to authenticate with 00:0e:8e:f8:73:96 
(SSID='ota-9k-2 space' freq=5180 MHz)
IFNAME=sta9 <3>Trying to associate with 00:0e:8e:f8:73:96 
(SSID='ota-9k-2 space' freq=5180 MHz)

IFNAME=sta9 <3>Associated with 00:0e:8e:f8:73:96
IFNAME=sta9 <3>CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
IFNAME=sta9 <3>WPA: Key negotiation completed with 00:0e:8e:f8:73:96 
[PTK=CCMP GTK=CCMP]
IFNAME=sta9 <3>CTRL-EVENT-CONNECTED - Connection to 00:0e:8e:f8:73:96 
completed [id=0 id_str=]
IFNAME=sta9 <3>WPA: Key negotiation completed with 00:0e:8e:f8:73:96 
[PTK=CCMP GTK=CCMP]
IFNAME=sta9 <3>WPA: Key negotiation completed with 00:0e:8e:f8:73:96 
[PTK=CCMP GTK=CCMP]
IFNAME=sta9 <3>WPA: Key negotiation completed with 00:0e:8e:f8:73:96 
[PTK=CCMP GTK=CCMP]

IFNAME=sta9 <3>CTRL-EVENT-DISCONNECTED bssid=00:0e:8e:f8:73:96 reason=2


Looks like I might need to add another message about EAPOL 4-way 
completing?


Based on a sniff, it seems that the 3/4 was sent in this case, but the 
4/4 was not
received from the AP.  Maybe the 3/4 is (re)sent incorrectly 
sometimesI have run into similar

bugs in the past.

Thanks,
Ben






Re: Wifi-Event for when initial 4-way completes?

2017-06-07 Thread Wojciech Dubowik

Hello Ben,

I have been using this part of wpa_supplicant to notify that 4-Way 
handshake is completed.


around line 868 in wpa_supplicant.c

#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- 
Connection to "

MACSTR " completed [id=%d id_str=%s%s]",
MAC2STR(wpa_s->bssid),
ssid ? ssid->id : -1,
ssid && ssid->id_str ? ssid->id_str : "",
fils_hlp_sent ? " FILS_HLP_SENT" : "");
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */

You can pack whatever notification message inside the if statement.

Br,

Wojtek


On 07/06/17 02:46, Ben Greear wrote:
I have been tracking down a nasty EAPOL related bug in ath10k, and 
found something that may be peripheral, or maybe

it is significant.

My logic is basically to kick supplicant, watch 'iw events', and then 
when I see something
like "sta62 (phy #5): connected to 00:0e:8e:f8:73:96", I consider it 
connected and start

dhcpd.

But, it appears that the 'connected' message comes out before the 
EAPOL 4-way completes, so
I am starting dhclient before the encryption is really set up 
properly.  At best, this slows

things down and makes dhclient have to retry.

Is there some existing event or state I can probe to determine when 
the initial 4-way is complete?


In case there is not, maybe that event would be worth adding?

Or, should I hack on supplicant instead and grab the info out of it 
somehow?


Thanks,
Ben





Re: Packet throughput (and those iperf data rate) with mac80211/ath9k is 20% worse than net80211/madwifi

2017-01-31 Thread Wojciech Dubowik



On 31/01/17 10:46, Klaus Kinski wrote:
BTW, if I read the sources correctly, than IBSS mode uses the TXQ 
parameters from ieee80211_set_wmm_default with enable_qos = false 
which means that qparam.txop = 0, e.g. bursting is disabled. Am I right?
I guess so. But you need to look also at contention window sizes because 
it make a big impact on throughout with retries and collisions.


Jörg Pommnitz <jpo...@outlook.de <mailto:jpo...@outlook.de>> schrieb 
am Di., 31. Jan. 2017 um 10:37 Uhr:


I'm mostly interested in Ad-Hoc mode, e.g. IBSS.

    Wojciech Dubowik <wojciech.dubo...@neratec.com
<mailto:wojciech.dubo...@neratec.com>> schrieb am Di., 31. Jan.
2017 um 10:35 Uhr:

That's tricky but look at
http://w1.fi/cgit/hostap/tree/hostapd/hostapd.conf
<http://w1.fi/cgit/hostap/tree/hostapd/hostapd.conf>

tx_queue... are for AP and wmm_... for STA (over beacons).

These should be default parameters. You can also enable CONFIG
debug flag

for ath9k and it prints wme parameters when it starts.

Wojtek


On 31/01/17 10:18, Klaus Kinski wrote:

It seems that bursting can be controlled over nl80211 (see ,
specifically with NL80211_ATTR_WIPHY_TXQ_PARAMS.
Unfortunately this seems not to be exposed in iw. It's an
attribute of NL80211_CMD_SET_WIPHY.
Is there another tool that exposes txq params? If not, has
anybody thought about exposing it in iw? I might take a stab
at it...

Regards
      Joerg

Wojciech Dubowik <wojciech.dubo...@neratec.com
<mailto:wojciech.dubo...@neratec.com>> schrieb am Di., 31.
Jan. 2017 um 08:55 Uhr:

Madwifi has default best effort queue "tuned" for throughout

and its parameters are different from mac80211 defaults when

qos  (WME) is disabled.

You would have to dump qos settings for both systems before

comparing them. I guess the easiest way is to make sure QoS

is enabled and send video type of packets with iperf ...
-S 0xa0

Wojtek


On 30/01/17 20:43, Toke Høiland-Jørgensen wrote:
> Klaus Kinski <jpo...@outlook.de
<mailto:jpo...@outlook.de>> writes:
>
>> The captures I used to create the statistics are here:
>>
https://drive.google.com/open?id=0ByFGz3ZH6JcYMGp0a05lYzBPNzA
>>
>> An obvious difference is, that Madwifi sends 5 packets
in a row
>> without waiting for an ACK whereas ath9k/mac80211
always seems to wait
>> for an ACK. This seems to point to the "net80211
aggressive mode
>> theory" https://wiki.freebsd.org/WifiAggressiveMode
<https://wiki.freebsd.org/WifiAggressiveMode>, IMHO.
> I'm not too familiar with that part of the stack, but
that seems
> reasonable, yeah. AFAIK the "aggresive mode" is a
pre-802.11n feature,
> though, which is why you won't see that in ath9k. In
802.11n this kind
> of bursting was replaced by aggregation, which you're
not getting any of
> since you're running in 802.11a mode, obviously.
>
> The lack of bursting will translate to slightly lower
throughput, which
> will be why you see fewer packets transmitted by ath9k.
Of course, if
> your receiver supported aggregation, the numbers would
look dramatically
> better in ath9k's favour... ;)
>
> -Toke





Re: Packet throughput (and those iperf data rate) with mac80211/ath9k is 20% worse than net80211/madwifi

2017-01-31 Thread Wojciech Dubowik

Then you need to use CONFIG debug flag. WMM parameters are not set when

MESH compile flag is enabled. At least I have had once such problem.

Wojtek

PS It would be actually nice to have sth like madwifi's wlanconfig ... 
list wme to


print QoS settings in current systems.


On 31/01/17 10:38, Klaus Kinski wrote:

I'm mostly interested in Ad-Hoc mode, e.g. IBSS.

Wojciech Dubowik <wojciech.dubo...@neratec.com 
<mailto:wojciech.dubo...@neratec.com>> schrieb am Di., 31. Jan. 2017 
um 10:35 Uhr:


That's tricky but look at
http://w1.fi/cgit/hostap/tree/hostapd/hostapd.conf
<http://w1.fi/cgit/hostap/tree/hostapd/hostapd.conf>

tx_queue... are for AP and wmm_... for STA (over beacons).

These should be default parameters. You can also enable CONFIG
debug flag

for ath9k and it prints wme parameters when it starts.

Wojtek


On 31/01/17 10:18, Klaus Kinski wrote:

It seems that bursting can be controlled over nl80211 (see ,
specifically with NL80211_ATTR_WIPHY_TXQ_PARAMS. Unfortunately
this seems not to be exposed in iw. It's an attribute of
NL80211_CMD_SET_WIPHY.
Is there another tool that exposes txq params? If not, has
anybody thought about exposing it in iw? I might take a stab at it...

Regards
  Joerg

    Wojciech Dubowik <wojciech.dubo...@neratec.com
<mailto:wojciech.dubo...@neratec.com>> schrieb am Di., 31. Jan.
2017 um 08:55 Uhr:

Madwifi has default best effort queue "tuned" for throughout

and its parameters are different from mac80211 defaults when

qos  (WME) is disabled.

You would have to dump qos settings for both systems before

comparing them. I guess the easiest way is to make sure QoS

is enabled and send video type of packets with iperf ... -S 0xa0

Wojtek


On 30/01/17 20:43, Toke Høiland-Jørgensen wrote:
> Klaus Kinski <jpo...@outlook.de <mailto:jpo...@outlook.de>>
writes:
>
>> The captures I used to create the statistics are here:
>> https://drive.google.com/open?id=0ByFGz3ZH6JcYMGp0a05lYzBPNzA
>>
>> An obvious difference is, that Madwifi sends 5 packets in
a row
>> without waiting for an ACK whereas ath9k/mac80211 always
seems to wait
>> for an ACK. This seems to point to the "net80211
aggressive mode
>> theory" https://wiki.freebsd.org/WifiAggressiveMode
<https://wiki.freebsd.org/WifiAggressiveMode>, IMHO.
> I'm not too familiar with that part of the stack, but that
seems
> reasonable, yeah. AFAIK the "aggresive mode" is a
pre-802.11n feature,
> though, which is why you won't see that in ath9k. In
802.11n this kind
> of bursting was replaced by aggregation, which you're not
getting any of
> since you're running in 802.11a mode, obviously.
>
> The lack of bursting will translate to slightly lower
throughput, which
> will be why you see fewer packets transmitted by ath9k. Of
course, if
> your receiver supported aggregation, the numbers would look
dramatically
> better in ath9k's favour... ;)
>
> -Toke





Re: Packet throughput (and those iperf data rate) with mac80211/ath9k is 20% worse than net80211/madwifi

2017-01-30 Thread Wojciech Dubowik

Madwifi has default best effort queue "tuned" for throughout

and its parameters are different from mac80211 defaults when

qos  (WME) is disabled.

You would have to dump qos settings for both systems before

comparing them. I guess the easiest way is to make sure QoS

is enabled and send video type of packets with iperf ... -S 0xa0

Wojtek


On 30/01/17 20:43, Toke Høiland-Jørgensen wrote:

Klaus Kinski  writes:


The captures I used to create the statistics are here:
https://drive.google.com/open?id=0ByFGz3ZH6JcYMGp0a05lYzBPNzA

An obvious difference is, that Madwifi sends 5 packets in a row
without waiting for an ACK whereas ath9k/mac80211 always seems to wait
for an ACK. This seems to point to the "net80211 aggressive mode
theory" https://wiki.freebsd.org/WifiAggressiveMode, IMHO.

I'm not too familiar with that part of the stack, but that seems
reasonable, yeah. AFAIK the "aggresive mode" is a pre-802.11n feature,
though, which is why you won't see that in ath9k. In 802.11n this kind
of bursting was replaced by aggregation, which you're not getting any of
since you're running in 802.11a mode, obviously.

The lack of bursting will translate to slightly lower throughput, which
will be why you see fewer packets transmitted by ath9k. Of course, if
your receiver supported aggregation, the numbers would look dramatically
better in ath9k's favour... ;)

-Toke




Re: [RFC 0/1] ath9k: Frame corruption simulator

2017-01-20 Thread Wojciech Dubowik



On 20/01/17 15:45, Ben Greear wrote:



On 01/20/2017 06:29 AM, Wojciech Dubowik wrote:

I have been debugging customer reported timeout and loss of
communication and I have relaized that I don't have such a lossy
environment available in the lab. To speed up debugging I have
written frame corruption simulator which will allow me to
totally loose specific types of packets. I have been mostly
using it with the mask 0x5000 which drops some EAPOL
and deauthentication frames. This way I was able to test better
timeouts and fail paths.
At the moment only management, null function and EAPOL frames
are supported. One can add more if necessary.


Would it be worth having a unique percentage configurable for each
of the selected packet types?
I wanted to keep it simple. I have been just repeating test when I 
didn't have
luck with specific frame loss sequence. In real life conditions frame 
are not lost

more or less depending on the type. Unless there is a hacker behind;o)


How about moving this up into mac80211 so other drivers could
be supported as well?  Couldn't you just drop the frames instead
of corrupting their checksum?  That would work with things like ath10k
as well.

I have started so but then:
 1) no more tx flags available
 2) how other drivers can handle tx frame corruption in HW so it is 
eqivalent

  to frame corruption in the air
 3) info.control.flags are being freed at some point in ath9k and I 
don't know

   how it works in other drivers
 4) dropping is not equal tx failed with no ack as status for tx drop 
status is always ok

seen from mac layer.
  For example it makes a difference for hostapd with EAPOL TX Status. 
There, mlme
 sends an event when no ack is received and whole series failed. 
Actually one could

specify whether to drop, to corrupt or just add random data.

Wojtek


I would like to have something like this, but with the added ability
to corrupt specific things like information-elements in management
frames to better test the receiver's packet parsing and error checking
logic.  For this feature, checksum would not be corrupted.

Thanks,
Ben




Re: [RFC 2/2] ath9k: Add frame corruption simulator

2017-01-20 Thread Wojciech Dubowik


On 20/01/17 16:07, Kalle Valo wrote:

+config ATH9K_FRAME_LOSS_SIMULATOR
+   bool "Atheros ath9k frame loss simulator"
+   depends on ATH9K && ATH9K_DEBUGFS && DEBUG_FS
+   default n
+   ---help---
+ Say N. This option should be used only to test fail paths
+  and timeouts by inverting fcs field of selected frames to
+ be transmitted.
+ Which frames are corrupted is marked by bitfield in
+ corrupt_fcs_frame_mask debug entry and probability of
+ of corruption in corrupt_fcs_prob (0-255). Zero means
+ disabled and writing 255 makes all selected frames fail.
+ Management, EAPOL, and Null function frames are
+ supported.

Why a separate Kconfig option? Does this significantly increase memory
consumption or something? I ask because we should be conservative when
adding new Kconfig options.

It shouldn't so I could drop it.
Wojtek






[RFC 1/2] ath9k: Add tx descriptor flag to corrupt frame fcs

2017-01-20 Thread Wojciech Dubowik
When this flag is present the transmitted frame fcs field
bits are inverted in hardware so the frame is being treated
as corrupted on the recevieng node.
It's used by frame corruption simulator coming on the following
patch.

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c | 3 ++-
 drivers/net/wireless/ath/ath9k/mac.h| 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c 
b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index da84b70..0b7fbfd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -114,7 +114,8 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct 
ath_tx_info *i)
| SM(i->type, AR_FrameType)
| (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
| (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
-   | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
+   | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0)
+   | (i->flags & ATH9K_TXDESC_CORRUPT_FCS ? AR_CorruptFCS : 0);
 
ctl17 |= (i->flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
switch (i->aggr) {
diff --git a/drivers/net/wireless/ath/ath9k/mac.h 
b/drivers/net/wireless/ath/ath9k/mac.h
index 3bab014..1c30dfd 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -265,6 +265,8 @@ struct ath_desc {
 #define ATH9K_TXDESC_PAPRD 0x7
 #define ATH9K_TXDESC_PAPRD_S   16
 
+#define ATH9K_TXDESC_CORRUPT_FCS   0x8
+
 #define ATH9K_RXDESC_INTREQ0x0020
 
 struct ar5416_desc {
-- 
2.7.4



[RFC 0/1] ath9k: Frame corruption simulator

2017-01-20 Thread Wojciech Dubowik
I have been debugging customer reported timeout and loss of
communication and I have relaized that I don't have such a lossy
environment available in the lab. To speed up debugging I have
written frame corruption simulator which will allow me to
totally loose specific types of packets. I have been mostly
using it with the mask 0x5000 which drops some EAPOL
and deauthentication frames. This way I was able to test better
timeouts and fail paths.
At the moment only management, null function and EAPOL frames
are supported. One can add more if necessary.

Wojciech Dubowik (1):
  ath9k: Add frame corruption simulator

 drivers/net/wireless/ath/ath9k/Kconfig |  15 +
 drivers/net/wireless/ath/ath9k/ath9k.h |   7 +++
 drivers/net/wireless/ath/ath9k/debug.c |  49 +++
 drivers/net/wireless/ath/ath9k/xmit.c  | 106 +
 4 files changed, 177 insertions(+)

-- 
2.7.4



[RFC 2/2] ath9k: Add frame corruption simulator

2017-01-20 Thread Wojciech Dubowik
Add debugfs entries to corrupt specified frame types
by invering fcs field upon transmissionm with given probability.

Select frames to be corrupted.
/corrupt_fcs_fram_mask:
 Bit 16 - Null function
 Bit 15 - QoS Null function
 Bit 14 - EAPOL
 Bit 13 - Action
 Bit 12 - Deauthentication
 Bit 11 - Authentication
 Bit 10 - Disassociation
 Bit 9  - ATIM
 Bit 8  - Beacon
 Bit 5  - Probe response
 Bit 4  - Probe request
 Bit 3  - Reassociation response
 Bit 2  - Reassociation request
 Bit 1  - Association response
 Bit 0  - Association request

Select corruption probability:
/corrupt_fcs_prob: 0(0%) to 255(100%)

Signed-off-by: Wojciech Dubowik <wojciech.dubo...@neratec.com>
---
 drivers/net/wireless/ath/ath9k/Kconfig |  15 +
 drivers/net/wireless/ath/ath9k/ath9k.h |   7 ++
 drivers/net/wireless/ath/ath9k/debug.c |  51 ++
 drivers/net/wireless/ath/ath9k/xmit.c  | 117 +
 4 files changed, 190 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/Kconfig 
b/drivers/net/wireless/ath/ath9k/Kconfig
index 8f231c6..ca50f0f 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -95,6 +95,21 @@ config ATH9K_TX99
  be evaluated to meet the RF exposure limits set forth in the
  governmental SAR regulations.
 
+config ATH9K_FRAME_LOSS_SIMULATOR
+   bool "Atheros ath9k frame loss simulator"
+   depends on ATH9K && ATH9K_DEBUGFS && DEBUG_FS
+   default n
+   ---help---
+ Say N. This option should be used only to test fail paths
+  and timeouts by inverting fcs field of selected frames to
+ be transmitted.
+ Which frames are corrupted is marked by bitfield in
+ corrupt_fcs_frame_mask debug entry and probability of
+ of corruption in corrupt_fcs_prob (0-255). Zero means
+ disabled and writing 255 makes all selected frames fail.
+ Management, EAPOL, and Null function frames are
+ supported.
+
 config ATH9K_DFS_CERTIFIED
bool "Atheros DFS support for certified platforms"
depends on ATH9K && CFG80211_CERTIFICATION_ONUS
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h 
b/drivers/net/wireless/ath/ath9k/ath9k.h
index 331947b..e5ae8f2 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -183,6 +183,9 @@ struct ath_frame_info {
u8 baw_tracked : 1;
u8 tx_power;
enum ath9k_key_type keytype:2;
+#ifdef CONFIG_ATH9K_FRAME_LOSS_SIMULATOR
+   u8 corrupt_fcs : 1;
+#endif
 };
 
 struct ath_rxbuf {
@@ -1087,6 +1090,10 @@ struct ath_softc {
u32 rng_last;
struct task_struct *rng_task;
 #endif
+#ifdef CONFIG_ATH9K_FRAME_LOSS_SIMULATOR
+   u16 corrupt_fcs_prob;
+   u32 corrupt_fcs_frame_mask;
+#endif
 };
 
 //
diff --git a/drivers/net/wireless/ath/ath9k/debug.c 
b/drivers/net/wireless/ath/ath9k/debug.c
index 43930c3..15ccf52 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1315,6 +1315,50 @@ void ath9k_deinit_debug(struct ath_softc *sc)
ath9k_cmn_spectral_deinit_debug(>spec_priv);
 }
 
+#ifdef CONFIG_ATH9K_FRAME_LOSS_SIMULATOR
+static ssize_t read_file_corrupt_fcs_frame_mask(struct file *file,
+   char __user *user_buf,
+   size_t count, loff_t *ppos)
+{
+   struct ath_softc *sc = file->private_data;
+   char buf[4];
+   unsigned int len;
+
+   len = sprintf(buf, "0x%08x\n", sc->corrupt_fcs_frame_mask);
+   return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_corrupt_fcs_frame_mask(struct file *file,
+const char __user *user_buf,
+size_t count, loff_t *ppos)
+{
+   struct ath_softc *sc = file->private_data;
+   unsigned long corrupt_fcs_frame_mask;
+   char buf[32];
+   ssize_t len;
+
+   len = min(count, sizeof(buf) - 1);
+   if (copy_from_user(buf, user_buf, len))
+   return -EFAULT;
+
+   buf[len] = '\0';
+   if (kstrtoul(buf, 0, _fcs_frame_mask))
+   return -EINVAL;
+
+   sc->corrupt_fcs_frame_mask = corrupt_fcs_frame_mask;
+
+   return count;
+}
+
+static const struct file_operations fops_corrupt_fcs_frame_mask = {
+   .read = read_file_corrupt_fcs_frame_mask,
+   .write = write_file_corrupt_fcs_frame_mask,
+   .open = simple_open,
+   .owner = THIS_MODULE,
+   .llseek = default_llseek,
+};
+#endif
+
 int ath9k_init_debug(struct ath_hw *ah)
 {
struct ath_common *common = ath9k_hw_common(ah);
@@ -1402,5 +1446,12 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_u16("airtime_flags", S_IRUSR | S_IWUSR,
 

[PATCH v3] mac80211: Avoid unnecessary locking on CSA counter update

2015-06-10 Thread Wojciech Dubowik
v2: Use splitted functions instead of direct counter decrement.
v3: Changed subject and commit message

Signed-off-by: Wojciech Dubowik wojciech.dubo...@neratec.com
---
 net/mac80211/tx.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7fe528a..7425803 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3211,6 +3211,16 @@ static void ieee80211_set_csa(struct 
ieee80211_sub_if_data *sdata,
rcu_read_unlock();
 }
 
+static u8 __ieee80211_csa_update_counter(struct beacon_data *beacon)
+{
+   beacon-csa_current_counter--;
+
+   /* the counter should never reach 0 */
+   WARN_ON_ONCE(!beacon-csa_current_counter);
+
+   return beacon-csa_current_counter;
+}
+
 u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
 {
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -3229,11 +3239,7 @@ u8 ieee80211_csa_update_counter(struct ieee80211_vif 
*vif)
if (!beacon)
goto unlock;
 
-   beacon-csa_current_counter--;
-
-   /* the counter should never reach 0 */
-   WARN_ON_ONCE(!beacon-csa_current_counter);
-   count = beacon-csa_current_counter;
+   count = __ieee80211_csa_update_counter(beacon);
 
 unlock:
rcu_read_unlock();
@@ -,7 +3339,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
if (beacon) {
if (beacon-csa_counter_offsets[0]) {
if (!is_template)
-   ieee80211_csa_update_counter(vif);
+   __ieee80211_csa_update_counter(beacon);
 
ieee80211_set_csa(sdata, beacon);
}
@@ -3379,7 +3385,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
 
if (beacon-csa_counter_offsets[0]) {
if (!is_template)
-   ieee80211_csa_update_counter(vif);
+   __ieee80211_csa_update_counter(beacon);
 
ieee80211_set_csa(sdata, beacon);
}
@@ -3409,7 +3415,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
 * for now we leave it consistent with overall
 * mac80211's behavior.
 */
-   ieee80211_csa_update_counter(vif);
+   __ieee80211_csa_update_counter(beacon);
 
ieee80211_set_csa(sdata, beacon);
}
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mac80211: Fix double locking on CSA counter update

2015-06-01 Thread Wojciech Dubowik
We call rcu locked ieee80211_csa_update_counter from
already locked section. Fix it by decrementing counter
directly instead of calling ieee80211_csa_update_counter.

Signed-off-by: Wojciech Dubowik wojciech.dubo...@neratec.com
---
 net/mac80211/tx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8df1342..9233559 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3338,7 +3338,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
if (beacon) {
if (beacon-csa_counter_offsets[0]) {
if (!is_template)
-   ieee80211_csa_update_counter(vif);
+   
WARN_ON_ONCE(beacon-csa_current_counter--);
 
ieee80211_set_csa(sdata, beacon);
}
@@ -3384,7 +3384,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
 
if (beacon-csa_counter_offsets[0]) {
if (!is_template)
-   ieee80211_csa_update_counter(vif);
+   WARN_ON_ONCE(beacon-csa_current_counter--);
 
ieee80211_set_csa(sdata, beacon);
}
@@ -3414,7 +3414,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
 * for now we leave it consistent with overall
 * mac80211's behavior.
 */
-   ieee80211_csa_update_counter(vif);
+   WARN_ON_ONCE(beacon-csa_current_counter--);
 
ieee80211_set_csa(sdata, beacon);
}
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mac80211: Fix double locking on CSA counter update

2015-06-01 Thread Wojciech Dubowik

On 01/06/15 16:13, Julian Calaby wrote:

Hi Wojciech,

On Mon, Jun 1, 2015 at 11:54 PM, Wojciech Dubowik
wojciech.dubo...@neratec.com wrote:

We call rcu locked ieee80211_csa_update_counter from
already locked section. Fix it by decrementing counter
directly instead of calling ieee80211_csa_update_counter.

Stupid question: wouldn't it be better to split the work from
ieee80211_csa_update_counter() into a separate function without
locking and call that instead?

Yes. It would be better for maintenance. It's just that they will
have different input parameters

ieee80211_csa_update_counter(struct ieee80211_vif *
__ieee80211_csa_update_counter(struct beacon_data *

as it doesn't make sense to dereference beacon twice.

I guess it's not a problem?
Wojtek


Thanks,



--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] mac80211: Fix double locking on CSA counter update

2015-06-01 Thread Wojciech Dubowik
We call rcu locked ieee80211_csa_update_counter from already locked
section. Fix it by splitting ieee80211_csa_update_counter into
locked and unlocked variants and use the latter in rcu locked section.

v2: Use splitted functions instead of direct counter decrement.

Signed-off-by: Wojciech Dubowik wojciech.dubo...@neratec.com
---
 net/mac80211/tx.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8df1342..312b199 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3216,6 +3216,16 @@ static void ieee80211_set_csa(struct 
ieee80211_sub_if_data *sdata,
rcu_read_unlock();
 }
 
+static u8 __ieee80211_csa_update_counter(struct beacon_data *beacon)
+{
+   beacon-csa_current_counter--;
+
+   /* the counter should never reach 0 */
+   WARN_ON_ONCE(!beacon-csa_current_counter);
+
+   return beacon-csa_current_counter;
+}
+
 u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
 {
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -3234,11 +3244,7 @@ u8 ieee80211_csa_update_counter(struct ieee80211_vif 
*vif)
if (!beacon)
goto unlock;
 
-   beacon-csa_current_counter--;
-
-   /* the counter should never reach 0 */
-   WARN_ON_ONCE(!beacon-csa_current_counter);
-   count = beacon-csa_current_counter;
+   count = __ieee80211_csa_update_counter(beacon);
 
 unlock:
rcu_read_unlock();
@@ -3338,7 +3344,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
if (beacon) {
if (beacon-csa_counter_offsets[0]) {
if (!is_template)
-   ieee80211_csa_update_counter(vif);
+   __ieee80211_csa_update_counter(beacon);
 
ieee80211_set_csa(sdata, beacon);
}
@@ -3384,7 +3390,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
 
if (beacon-csa_counter_offsets[0]) {
if (!is_template)
-   ieee80211_csa_update_counter(vif);
+   __ieee80211_csa_update_counter(beacon);
 
ieee80211_set_csa(sdata, beacon);
}
@@ -3414,7 +3420,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
 * for now we leave it consistent with overall
 * mac80211's behavior.
 */
-   ieee80211_csa_update_counter(vif);
+   __ieee80211_csa_update_counter(beacon);
 
ieee80211_set_csa(sdata, beacon);
}
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath9k: Fix NULL pointer dereference on early irq

2014-09-18 Thread Wojciech Dubowik
The ah struct might not have been initialized when
interrupt comes so check for it.

Signed-off-by: Wojciech Dubowik wojciech.dubo...@neratec.com
---
 drivers/net/wireless/ath/ath9k/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index 3e485f7..fbf23ac 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -504,7 +504,7 @@ irqreturn_t ath_isr(int irq, void *dev)
 * touch anything. Note this can happen early
 * on if the IRQ is shared.
 */
-   if (test_bit(ATH_OP_INVALID, common-op_flags))
+   if (!ah || test_bit(ATH_OP_INVALID, common-op_flags))
return IRQ_NONE;
 
/* shared irq, not for us */
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html