From 1161df826f91c97dc6ab302c16f5bfd19a5ceab9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 30 Sep 2014 21:36:04 +0000 Subject: [PATCH] ath9k: add a fix for dynack Signed-off-by: Felix Fietkau SVN-Revision: 42703 --- .../mac80211/patches/300-pending_work.patch | 175 ++++++++++++++++++ .../patches/501-ath9k-eeprom_endianess.patch | 2 +- .../patches/542-ath9k_debugfs_diag.patch | 4 +- ...w-to-disable-bands-via-platform-data.patch | 2 +- .../patches/550-ath9k_entropy_from_adc.patch | 4 +- 5 files changed, 181 insertions(+), 6 deletions(-) diff --git a/package/kernel/mac80211/patches/300-pending_work.patch b/package/kernel/mac80211/patches/300-pending_work.patch index 8548064a1f..cc97be8995 100644 --- a/package/kernel/mac80211/patches/300-pending_work.patch +++ b/package/kernel/mac80211/patches/300-pending_work.patch @@ -1,3 +1,18 @@ +commit 065e0b64f71632f5ad7f00c102fde09c534cfbf0 +Author: Felix Fietkau +Date: Tue Sep 30 11:00:33 2014 +0200 + + ath9k: fix getting tx duration for dynack + + On AR9003, tx control and tx status are in separate descriptor rings. + Tx duration is extracted from the tx control descriptor data, which + ar9003_hw_proc_txdesc cannot access. + + Fix getting the duration by adding a separate callback for it. + + Acked-by: Lorenzo Bianconi + Signed-off-by: Felix Fietkau + commit fdf9a4517b60d847b9bc0a30249efd96559fa450 Author: Felix Fietkau Date: Tue Sep 9 09:48:30 2014 +0200 @@ -683,3 +698,163 @@ Date: Sat Sep 27 15:57:09 2014 +0200 priv_ops->set_channel_regs = ar9003_hw_set_channel_regs; priv_ops->init_bb = ar9003_hw_init_bb; priv_ops->process_ini = ar9003_hw_process_ini; +--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c +@@ -381,16 +381,27 @@ static int ar9002_hw_proc_txdesc(struct + ts->evm1 = ads->AR_TxEVM1; + ts->evm2 = ads->AR_TxEVM2; + +- status = ACCESS_ONCE(ads->ds_ctl4); +- ts->duration[0] = MS(status, AR_PacketDur0); +- ts->duration[1] = MS(status, AR_PacketDur1); +- status = ACCESS_ONCE(ads->ds_ctl5); +- ts->duration[2] = MS(status, AR_PacketDur2); +- ts->duration[3] = MS(status, AR_PacketDur3); +- + return 0; + } + ++static int ar9002_hw_get_duration(struct ath_hw *ah, const void *ds, int index) ++{ ++ struct ar5416_desc *ads = AR5416DESC(ds); ++ ++ switch (index) { ++ case 0: ++ return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur0); ++ case 1: ++ return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur1); ++ case 2: ++ return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur2); ++ case 3: ++ return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur3); ++ default: ++ return -1; ++ } ++} ++ + void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, + u32 size, u32 flags) + { +@@ -413,4 +424,5 @@ void ar9002_hw_attach_mac_ops(struct ath + ops->get_isr = ar9002_hw_get_isr; + ops->set_txdesc = ar9002_set_txdesc; + ops->proc_txdesc = ar9002_hw_proc_txdesc; ++ ops->get_duration = ar9002_hw_get_duration; + } +--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c +@@ -355,11 +355,9 @@ static int ar9003_hw_proc_txdesc(struct + struct ath_tx_status *ts) + { + struct ar9003_txs *ads; +- struct ar9003_txc *adc; + u32 status; + + ads = &ah->ts_ring[ah->ts_tail]; +- adc = (struct ar9003_txc *)ads; + + status = ACCESS_ONCE(ads->status8); + if ((status & AR_TxDone) == 0) +@@ -428,18 +426,29 @@ static int ar9003_hw_proc_txdesc(struct + ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); + ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); + +- status = ACCESS_ONCE(adc->ctl15); +- ts->duration[0] = MS(status, AR_PacketDur0); +- ts->duration[1] = MS(status, AR_PacketDur1); +- status = ACCESS_ONCE(adc->ctl16); +- ts->duration[2] = MS(status, AR_PacketDur2); +- ts->duration[3] = MS(status, AR_PacketDur3); +- + memset(ads, 0, sizeof(*ads)); + + return 0; + } + ++static int ar9003_hw_get_duration(struct ath_hw *ah, const void *ds, int index) ++{ ++ const struct ar9003_txc *adc = ds; ++ ++ switch (index) { ++ case 0: ++ return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur0); ++ case 1: ++ return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur1); ++ case 2: ++ return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur2); ++ case 3: ++ return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur3); ++ default: ++ return 0; ++ } ++} ++ + void ar9003_hw_attach_mac_ops(struct ath_hw *hw) + { + struct ath_hw_ops *ops = ath9k_hw_ops(hw); +@@ -449,6 +458,7 @@ void ar9003_hw_attach_mac_ops(struct ath + ops->get_isr = ar9003_hw_get_isr; + ops->set_txdesc = ar9003_set_txdesc; + ops->proc_txdesc = ar9003_hw_proc_txdesc; ++ ops->get_duration = ar9003_hw_get_duration; + } + + void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -202,7 +202,7 @@ void ath_dynack_sample_tx_ts(struct ath_ + ridx = ts->ts_rateindex; + + da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp; +- da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration[ts->ts_rateindex]; ++ da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration; + ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1); + ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2); + +--- a/drivers/net/wireless/ath/ath9k/hw-ops.h ++++ b/drivers/net/wireless/ath/ath9k/hw-ops.h +@@ -67,6 +67,12 @@ static inline int ath9k_hw_txprocdesc(st + return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts); + } + ++static inline int ath9k_hw_get_duration(struct ath_hw *ah, const void *ds, ++ int index) ++{ ++ return ath9k_hw_ops(ah)->get_duration(ah, ds, index); ++} ++ + static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf) + { +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -691,6 +691,7 @@ struct ath_hw_ops { + struct ath_tx_info *i); + int (*proc_txdesc)(struct ath_hw *ah, void *ds, + struct ath_tx_status *ts); ++ int (*get_duration)(struct ath_hw *ah, const void *ds, int index); + void (*antdiv_comb_conf_get)(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf); + void (*antdiv_comb_conf_set)(struct ath_hw *ah, +--- a/drivers/net/wireless/ath/ath9k/mac.h ++++ b/drivers/net/wireless/ath/ath9k/mac.h +@@ -121,7 +121,7 @@ struct ath_tx_status { + u32 evm0; + u32 evm1; + u32 evm2; +- u32 duration[4]; ++ u32 duration; + }; + + struct ath_rx_status { +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -683,6 +683,8 @@ static void ath_tx_process_buffer(struct + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth--; + ++ ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, ++ ts->ts_rateindex); + if (!bf_isampdu(bf)) { + if (!flush) { + info = IEEE80211_SKB_CB(bf->bf_mpdu); diff --git a/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch index 8421429601..abf3914476 100644 --- a/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch +++ b/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch @@ -71,7 +71,7 @@ --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -725,6 +725,7 @@ enum ath_cal_list { +@@ -726,6 +726,7 @@ enum ath_cal_list { #define AH_USE_EEPROM 0x1 #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ #define AH_FASTCC 0x4 diff --git a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch index 365cf1a41e..62f5e8c732 100644 --- a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch +++ b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch @@ -75,7 +75,7 @@ struct ath9k_hw_version { u32 magic; u16 devid; -@@ -763,6 +769,8 @@ struct ath_hw { +@@ -764,6 +770,8 @@ struct ath_hw { u32 rfkill_polarity; u32 ah_flags; @@ -84,7 +84,7 @@ bool reset_power_on; bool htc_reset_init; -@@ -1017,6 +1025,7 @@ void ath9k_hw_check_nav(struct ath_hw *a +@@ -1018,6 +1026,7 @@ void ath9k_hw_check_nav(struct ath_hw *a bool ath9k_hw_check_alive(struct ath_hw *ah); bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); diff --git a/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch index fabe6e4846..e8cd5e65ce 100644 --- a/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch +++ b/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch @@ -47,7 +47,7 @@ AR_SREV_9285(ah) || --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -933,6 +933,8 @@ struct ath_hw { +@@ -934,6 +934,8 @@ struct ath_hw { bool is_clk_25mhz; int (*get_mac_revision)(void); int (*external_reset)(void); diff --git a/package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch index dd067de7a5..6ca9eaad66 100644 --- a/package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch +++ b/package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch @@ -8,7 +8,7 @@ * @spectral_scan_config: set parameters for spectral scan and enable/disable it * @spectral_scan_trigger: trigger a spectral scan run * @spectral_scan_wait: wait for a spectral scan run to finish -@@ -702,6 +703,7 @@ struct ath_hw_ops { +@@ -703,6 +704,7 @@ struct ath_hw_ops { struct ath_hw_antcomb_conf *antconf); void (*antdiv_comb_conf_set)(struct ath_hw *ah, struct ath_hw_antcomb_conf *antconf); @@ -95,7 +95,7 @@ if (error) --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h -@@ -95,6 +95,12 @@ static inline void ath9k_hw_tx99_set_txp +@@ -101,6 +101,12 @@ static inline void ath9k_hw_tx99_set_txp ath9k_hw_ops(ah)->tx99_set_txpower(ah, power); }