aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-09-30 05:24:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-30 13:17:48 -0400
commit315dd1149b6048cec805667f511726bbe8e5c975 (patch)
tree6bc8a44734b05bda1b501d820af8d3a675a9912b
parent4d9f634b02e4240f86719f30e4c9e62f6a4c4d36 (diff)
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 <lorenzo.bianconi83@gmail.com> Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/dynack.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c2
7 files changed, 49 insertions, 18 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 669cb3747208..2a93519f4bdf 100644
--- 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 ath_hw *ah, void *ds,
381 ts->evm1 = ads->AR_TxEVM1; 381 ts->evm1 = ads->AR_TxEVM1;
382 ts->evm2 = ads->AR_TxEVM2; 382 ts->evm2 = ads->AR_TxEVM2;
383 383
384 status = ACCESS_ONCE(ads->ds_ctl4);
385 ts->duration[0] = MS(status, AR_PacketDur0);
386 ts->duration[1] = MS(status, AR_PacketDur1);
387 status = ACCESS_ONCE(ads->ds_ctl5);
388 ts->duration[2] = MS(status, AR_PacketDur2);
389 ts->duration[3] = MS(status, AR_PacketDur3);
390
391 return 0; 384 return 0;
392} 385}
393 386
387static int ar9002_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
388{
389 struct ar5416_desc *ads = AR5416DESC(ds);
390
391 switch (index) {
392 case 0:
393 return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur0);
394 case 1:
395 return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur1);
396 case 2:
397 return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur2);
398 case 3:
399 return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur3);
400 default:
401 return -1;
402 }
403}
404
394void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 405void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
395 u32 size, u32 flags) 406 u32 size, u32 flags)
396{ 407{
@@ -413,4 +424,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
413 ops->get_isr = ar9002_hw_get_isr; 424 ops->get_isr = ar9002_hw_get_isr;
414 ops->set_txdesc = ar9002_set_txdesc; 425 ops->set_txdesc = ar9002_set_txdesc;
415 ops->proc_txdesc = ar9002_hw_proc_txdesc; 426 ops->proc_txdesc = ar9002_hw_proc_txdesc;
427 ops->get_duration = ar9002_hw_get_duration;
416} 428}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index e5f7c11fa144..057b1657c428 100644
--- 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 ath_hw *ah, void *ds,
355 struct ath_tx_status *ts) 355 struct ath_tx_status *ts)
356{ 356{
357 struct ar9003_txs *ads; 357 struct ar9003_txs *ads;
358 struct ar9003_txc *adc;
359 u32 status; 358 u32 status;
360 359
361 ads = &ah->ts_ring[ah->ts_tail]; 360 ads = &ah->ts_ring[ah->ts_tail];
362 adc = (struct ar9003_txc *)ads;
363 361
364 status = ACCESS_ONCE(ads->status8); 362 status = ACCESS_ONCE(ads->status8);
365 if ((status & AR_TxDone) == 0) 363 if ((status & AR_TxDone) == 0)
@@ -428,18 +426,29 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
428 ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); 426 ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
429 ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); 427 ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
430 428
431 status = ACCESS_ONCE(adc->ctl15);
432 ts->duration[0] = MS(status, AR_PacketDur0);
433 ts->duration[1] = MS(status, AR_PacketDur1);
434 status = ACCESS_ONCE(adc->ctl16);
435 ts->duration[2] = MS(status, AR_PacketDur2);
436 ts->duration[3] = MS(status, AR_PacketDur3);
437
438 memset(ads, 0, sizeof(*ads)); 429 memset(ads, 0, sizeof(*ads));
439 430
440 return 0; 431 return 0;
441} 432}
442 433
434static int ar9003_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
435{
436 const struct ar9003_txc *adc = ds;
437
438 switch (index) {
439 case 0:
440 return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur0);
441 case 1:
442 return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur1);
443 case 2:
444 return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur2);
445 case 3:
446 return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur3);
447 default:
448 return 0;
449 }
450}
451
443void ar9003_hw_attach_mac_ops(struct ath_hw *hw) 452void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
444{ 453{
445 struct ath_hw_ops *ops = ath9k_hw_ops(hw); 454 struct ath_hw_ops *ops = ath9k_hw_ops(hw);
@@ -449,6 +458,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
449 ops->get_isr = ar9003_hw_get_isr; 458 ops->get_isr = ar9003_hw_get_isr;
450 ops->set_txdesc = ar9003_set_txdesc; 459 ops->set_txdesc = ar9003_set_txdesc;
451 ops->proc_txdesc = ar9003_hw_proc_txdesc; 460 ops->proc_txdesc = ar9003_hw_proc_txdesc;
461 ops->get_duration = ar9003_hw_get_duration;
452} 462}
453 463
454void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) 464void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c
index 6ae8e0bc9e1f..22b3cc4c27cd 100644
--- 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_hw *ah, struct sk_buff *skb,
202 ridx = ts->ts_rateindex; 202 ridx = ts->ts_rateindex;
203 203
204 da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp; 204 da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp;
205 da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration[ts->ts_rateindex]; 205 da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration;
206 ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1); 206 ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1);
207 ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2); 207 ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2);
208 208
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index a47ea8423f1e..8e85efeaeffc 100644
--- 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(struct ath_hw *ah, void *ds,
67 return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts); 67 return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts);
68} 68}
69 69
70static inline int ath9k_hw_get_duration(struct ath_hw *ah, const void *ds,
71 int index)
72{
73 return ath9k_hw_ops(ah)->get_duration(ah, ds, index);
74}
75
70static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, 76static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
71 struct ath_hw_antcomb_conf *antconf) 77 struct ath_hw_antcomb_conf *antconf)
72{ 78{
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index b9eef3362fbb..975074fc11bc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -691,6 +691,7 @@ struct ath_hw_ops {
691 struct ath_tx_info *i); 691 struct ath_tx_info *i);
692 int (*proc_txdesc)(struct ath_hw *ah, void *ds, 692 int (*proc_txdesc)(struct ath_hw *ah, void *ds,
693 struct ath_tx_status *ts); 693 struct ath_tx_status *ts);
694 int (*get_duration)(struct ath_hw *ah, const void *ds, int index);
694 void (*antdiv_comb_conf_get)(struct ath_hw *ah, 695 void (*antdiv_comb_conf_get)(struct ath_hw *ah,
695 struct ath_hw_antcomb_conf *antconf); 696 struct ath_hw_antcomb_conf *antconf);
696 void (*antdiv_comb_conf_set)(struct ath_hw *ah, 697 void (*antdiv_comb_conf_set)(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index cd05a7791073..aa69ceaad0be 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -121,7 +121,7 @@ struct ath_tx_status {
121 u32 evm0; 121 u32 evm0;
122 u32 evm1; 122 u32 evm1;
123 u32 evm2; 123 u32 evm2;
124 u32 duration[4]; 124 u32 duration;
125}; 125};
126 126
127struct ath_rx_status { 127struct ath_rx_status {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 7193a00d3bca..151ae49fa57e 100644
--- 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 ath_softc *sc, struct ath_txq *txq,
683 if (bf_is_ampdu_not_probing(bf)) 683 if (bf_is_ampdu_not_probing(bf))
684 txq->axq_ampdu_depth--; 684 txq->axq_ampdu_depth--;
685 685
686 ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc,
687 ts->ts_rateindex);
686 if (!bf_isampdu(bf)) { 688 if (!bf_isampdu(bf)) {
687 if (!flush) { 689 if (!flush) {
688 info = IEEE80211_SKB_CB(bf->bf_mpdu); 690 info = IEEE80211_SKB_CB(bf->bf_mpdu);