[PATCH 2/2] ath9k: Fix ack SIFS time for quarter/half channels
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?
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?
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
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
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
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 Kinskiwrites: 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
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
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
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
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
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
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
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
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
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
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