Skip to content

Commit a81b104

Browse files
committed
wifi: ath9k: Add PTP patch from wifi-ptp project
Applies and updates the patch from https://github.com/zlab-pub/wifi-ptp/blob/main/ath9k.diff
1 parent 95309fc commit a81b104

File tree

14 files changed

+449
-22
lines changed

14 files changed

+449
-22
lines changed

drivers/net/wireless/ath/ath9k/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ath9k-y += beacon.o \
1010
channel.o
1111

1212
ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
13-
ath9k-$(CONFIG_ATH9K_PCI) += pci.o
13+
ath9k-$(CONFIG_ATH9K_PCI) += pci.o ptp.o
1414
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
1515
ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
1616
ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o

drivers/net/wireless/ath/ath9k/ath9k.h

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@
2424
#include <linux/leds.h>
2525
#include <linux/completion.h>
2626
#include <linux/time.h>
27+
#include <linux/ktime.h>
28+
#include <linux/timecounter.h>
2729
#include <linux/hw_random.h>
30+
#include <linux/ptp_clock_kernel.h>
31+
#include <linux/ptp_classify.h>
32+
#include <linux/hrtimer.h>
2833

2934
#include "common.h"
3035
#include "debug.h"
@@ -109,7 +114,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
109114
/* minimum h/w qdepth to be sustained to maximize aggregation */
110115
#define ATH_AGGR_MIN_QDEPTH 2
111116
/* minimum h/w qdepth for non-aggregated traffic */
112-
#define ATH_NON_AGGR_MIN_QDEPTH 8
117+
#define ATH_NON_AGGR_MIN_QDEPTH 32
113118
#define ATH_HW_CHECK_POLL_INT 1000
114119
#define ATH_TXFIFO_DEPTH 8
115120
#define ATH_TX_ERROR 0x01
@@ -579,7 +584,7 @@ bool ath_stoprecv(struct ath_softc *sc);
579584
u32 ath_calcrxfilter(struct ath_softc *sc);
580585
int ath_rx_init(struct ath_softc *sc, int nbufs);
581586
void ath_rx_cleanup(struct ath_softc *sc);
582-
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
587+
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp, ktime_t *tstamp);
583588
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
584589
void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq);
585590
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
@@ -601,7 +606,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
601606
void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
602607
struct sk_buff *skb);
603608
void ath_tx_tasklet(struct ath_softc *sc);
604-
void ath_tx_edma_tasklet(struct ath_softc *sc);
609+
void ath_tx_edma_tasklet(struct ath_softc *sc, ktime_t *tstamp);
605610
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
606611
u16 tid, u16 *ssn);
607612
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
@@ -1018,12 +1023,27 @@ struct ath_softc {
10181023

10191024
u8 gtt_cnt;
10201025
u32 intrstatus;
1021-
u16 ps_flags; /* PS_* */
1026+
ktime_t intrtstamp;
1027+
u16 ps_flags; /* PS_* */
10221028
bool ps_enabled;
10231029
bool ps_idle;
10241030
short nbcnvifs;
10251031
unsigned long ps_usecount;
10261032

1033+
spinlock_t systim_lock;
1034+
struct cyclecounter cc;
1035+
struct timecounter tc;
1036+
struct ptp_clock *ptp_clock;
1037+
struct ptp_clock_info ptp_clock_info;
1038+
u32 cc_mult;
1039+
struct hrtimer off_timer;
1040+
ktime_t off_interval;
1041+
u32 off_counter;
1042+
s64 off_last;
1043+
u64 off_base_time;
1044+
1045+
u64 ptp_dirtyts;
1046+
10271047
struct ath_rx rx;
10281048
struct ath_tx tx;
10291049
struct ath_beacon beacon;
@@ -1152,4 +1172,9 @@ static inline int ath_ahb_init(void) { return 0; };
11521172
static inline void ath_ahb_exit(void) {};
11531173
#endif
11541174

1175+
void ath9k_ptp_init(struct ath_softc *sc);
1176+
void ath9k_ptp_remove(struct ath_softc *sc);
1177+
void ath9k_cyc2hwtstamp(struct ath_softc *sc, struct skb_shared_hwtstamps *hwtstamps, u32 cycle);
1178+
#define ATH9K_PTP_FAKE_SHIFT 21
1179+
11551180
#endif /* ATH9K_H */

drivers/net/wireless/ath/ath9k/beacon.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ static int ath9k_beacon_choose_slot(struct ath_softc *sc)
314314

315315
if (sc->sc_ah->opmode != NL80211_IFTYPE_AP &&
316316
sc->sc_ah->opmode != NL80211_IFTYPE_MESH_POINT) {
317-
ath_dbg(common, BEACON, "slot 0, tsf: %llu\n",
318-
ath9k_hw_gettsf64(sc->sc_ah));
317+
// ath_dbg(common, BEACON, "slot 0, tsf: %llu\n",
318+
// ath9k_hw_gettsf64(sc->sc_ah));
319319
return 0;
320320
}
321321

drivers/net/wireless/ath/ath9k/debug.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,91 @@ static const struct file_operations fops_debug = {
121121

122122
#endif
123123

124+
static ssize_t read_file_dirtyts(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) {
125+
struct ath_softc *sc = file->private_data;
126+
u8 buf[sizeof(u64)];
127+
128+
memcpy(buf, &sc->ptp_dirtyts, sizeof buf);
129+
return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof buf);
130+
}
131+
132+
static ssize_t write_file_dirtyts(struct file *file, const char __user *user_buf,
133+
size_t count, loff_t *ppos) {
134+
struct ath_softc *sc = file->private_data;
135+
u8 buf[sizeof(u64)];
136+
ssize_t len;
137+
u64 dirty_cycle;
138+
u32 raw_tsf;
139+
s64 delta;
140+
s64 dirty_ns;
141+
unsigned long flags;
142+
u32 remain;
143+
144+
len = simple_write_to_buffer(buf, sizeof buf, ppos, user_buf, count);
145+
if (len < 0) {
146+
return len;
147+
}
148+
if (len < sizeof buf) {
149+
return -EINVAL;
150+
}
151+
152+
memcpy(&dirty_cycle, buf, sizeof buf);
153+
raw_tsf = (dirty_cycle >> 32);
154+
remain = dirty_cycle & 0xffffffffU;
155+
156+
spin_lock_irqsave(&sc->systim_lock, flags);
157+
dirty_ns = timecounter_cyc2time(&sc->tc, raw_tsf);
158+
delta = 0;
159+
if (remain) {
160+
u64 frac = 0;
161+
delta = cyclecounter_cyc2ns(&sc->cc, 1, sc->cc.mask, &frac);
162+
delta = delta * remain / 1000;
163+
}
164+
spin_unlock_irqrestore(&sc->systim_lock, flags);
165+
166+
dirty_ns += delta;
167+
sc->ptp_dirtyts = dirty_ns;
168+
169+
return len;
170+
}
171+
172+
static const struct file_operations fops_dirtyts = {
173+
.read = read_file_dirtyts,
174+
.write = write_file_dirtyts,
175+
.open = simple_open,
176+
.owner = THIS_MODULE,
177+
.llseek = default_llseek,
178+
};
179+
180+
static ssize_t read_file_trigger_cbr(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) {
181+
return -EINVAL;
182+
}
183+
184+
static ssize_t write_file_trigger_cbr(struct file *file, const char __user *user_buf,
185+
size_t count, loff_t *ppos) {
186+
struct ath_softc *sc = file->private_data;
187+
struct ath_hw *ah = sc->sc_ah;
188+
189+
if (count & 1) {
190+
printk("ath9k: cbr open\n");
191+
// REG_RMW(ah, AR_QMISC(ATH_TXQ_AC_VI), AR_Q_MISC_FSP_CBR, AR_Q_MISC_FSP);
192+
REG_WRITE(ah, AR_QCBRCFG(ATH_TXQ_AC_VI), 0xc350);
193+
} else {
194+
printk("ath9k: cbr gated\n");
195+
// REG_RMW(ah, AR_QMISC(ATH_TXQ_AC_VI), 0x4, AR_Q_MISC_FSP);
196+
}
197+
198+
return count;
199+
}
200+
201+
static const struct file_operations fops_trigger_cbr = {
202+
.read = read_file_trigger_cbr,
203+
.write = write_file_trigger_cbr,
204+
.open = simple_open,
205+
.owner = THIS_MODULE,
206+
.llseek = default_llseek,
207+
};
208+
124209
#define DMA_BUF_LEN 1024
125210

126211

@@ -1427,6 +1512,12 @@ int ath9k_init_debug(struct ath_hw *ah)
14271512
sc->debug.debugfs_phy,
14281513
read_file_dump_nfcal);
14291514

1515+
debugfs_create_file("dirtyts", 0600, sc->debug.debugfs_phy,
1516+
sc, &fops_dirtyts);
1517+
1518+
debugfs_create_file("trigger_cbr", 0600, sc->debug.debugfs_phy,
1519+
sc, &fops_trigger_cbr);
1520+
14301521
ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
14311522
ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
14321523

drivers/net/wireless/ath/ath9k/hw.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3035,8 +3035,8 @@ EXPORT_SYMBOL(ath9k_hw_gettsf64);
30353035

30363036
void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
30373037
{
3038-
REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
3039-
REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
3038+
// REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
3039+
// REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
30403040
}
30413041
EXPORT_SYMBOL(ath9k_hw_settsf64);
30423042

@@ -3056,6 +3056,7 @@ void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set)
30563056
if (set)
30573057
ah->misc_mode |= AR_PCU_TX_ADD_TSF;
30583058
else
3059+
// ;
30593060
ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
30603061
}
30613062
EXPORT_SYMBOL(ath9k_hw_set_tsfadjust);

drivers/net/wireless/ath/ath9k/hw.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@
236236
enum ath_hw_txq_subtype {
237237
ATH_TXQ_AC_BK = 0,
238238
ATH_TXQ_AC_BE = 1,
239-
ATH_TXQ_AC_VI = 2,
239+
ATH_TXQ_AC_VI = 5,
240240
ATH_TXQ_AC_VO = 3,
241241
};
242242

drivers/net/wireless/ath/ath9k/init.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,16 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
197197
spin_lock_irqsave(&sc->sc_serial_rw, flags);
198198
val = ioread32(sc->mem + reg_offset);
199199
spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
200-
} else
200+
} else {
201+
/*
202+
if (reg_offset == AR_TSF_L32) {
203+
printk("ath9k: ioread32 unlock L32");
204+
} else if (reg_offset == AR_TSF_U32) {
205+
printk("ath9k: ioread32 unlock U32");
206+
}
207+
*/
201208
val = ioread32(sc->mem + reg_offset);
209+
}
202210
return val;
203211
}
204212

drivers/net/wireless/ath/ath9k/mac.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
369369
struct ath_common *common = ath9k_hw_common(ah);
370370
struct ath9k_tx_queue_info *qi;
371371
u32 cwMin, chanCwMin, value;
372+
int hcfenabled = 0;
372373

373374
qi = &ah->txq[q];
374375
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
@@ -378,6 +379,14 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
378379

379380
ath_dbg(common, QUEUE, "Reset TX queue: %u\n", q);
380381

382+
if (q == ATH_TXQ_AC_VI) {
383+
qi->tqi_cwmin = qi->tqi_cwmax = 0;
384+
qi->tqi_aifs = 0;
385+
qi->tqi_cbrPeriod = 5000;
386+
qi->tqi_cbrOverflowLimit = 0;
387+
// hcfenabled = 1;
388+
}
389+
381390
if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
382391
chanCwMin = INIT_CWMIN;
383392

@@ -413,8 +422,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
413422
REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR |
414423
(qi->tqi_cbrOverflowLimit ?
415424
AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
425+
// REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_ONE_SHOT_EN);
416426
}
417427
if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
428+
printk("ath9k: tqi set rdytime: %d\n", q);
418429
REG_WRITE(ah, AR_QRDYTIMECFG(q),
419430
SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
420431
AR_Q_RDYTIMECFG_EN);
@@ -494,6 +505,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
494505
break;
495506
}
496507

508+
if (hcfenabled) {
509+
REG_SET_BIT(ah, AR_QMISC(q), 0x00000016);
510+
}
497511
if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
498512
REG_SET_BIT(ah, AR_DMISC(q),
499513
SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,

drivers/net/wireless/ath/ath9k/main.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <linux/nl80211.h>
1818
#include <linux/delay.h>
19+
#include <linux/ktime.h>
1920
#include "ath9k.h"
2021
#include "btcoex.h"
2122

@@ -384,10 +385,12 @@ void ath9k_tasklet(struct tasklet_struct *t)
384385
unsigned long flags;
385386
u32 status;
386387
u32 rxmask;
388+
ktime_t tstamp;
387389

388390
spin_lock_irqsave(&sc->intr_lock, flags);
389391
status = sc->intrstatus;
390392
sc->intrstatus = 0;
393+
tstamp = sc->intrtstamp;
391394
spin_unlock_irqrestore(&sc->intr_lock, flags);
392395

393396
ath9k_ps_wakeup(sc);
@@ -436,7 +439,7 @@ void ath9k_tasklet(struct tasklet_struct *t)
436439
* the next Beacon.
437440
*/
438441
ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n");
439-
sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
442+
// sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
440443
}
441444
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
442445

@@ -450,9 +453,9 @@ void ath9k_tasklet(struct tasklet_struct *t)
450453
/* Check for high priority Rx first */
451454
if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
452455
(status & ATH9K_INT_RXHP))
453-
ath_rx_tasklet(sc, 0, true);
456+
ath_rx_tasklet(sc, 0, true, &tstamp);
454457

455-
ath_rx_tasklet(sc, 0, false);
458+
ath_rx_tasklet(sc, 0, false, &tstamp);
456459
}
457460

458461
if (status & ATH9K_INT_TX) {
@@ -465,7 +468,7 @@ void ath9k_tasklet(struct tasklet_struct *t)
465468
*/
466469
sc->gtt_cnt = 0;
467470

468-
ath_tx_edma_tasklet(sc);
471+
ath_tx_edma_tasklet(sc, &tstamp);
469472
} else {
470473
ath_tx_tasklet(sc);
471474
}
@@ -509,6 +512,9 @@ irqreturn_t ath_isr(int irq, void *dev)
509512
enum ath9k_int status;
510513
u32 sync_cause = 0;
511514
bool sched = false;
515+
ktime_t isr_tstamp = ktime_get_real();
516+
517+
//printk("ath9k: ath_isr isr_tstamp=%lld, tsf64=%u\n", isr_tstamp, ath9k_hw_gettsf32(ah));
512518

513519
/*
514520
* The hardware is not ready/present, don't
@@ -547,6 +553,7 @@ irqreturn_t ath_isr(int irq, void *dev)
547553
/* Cache the status */
548554
spin_lock(&sc->intr_lock);
549555
sc->intrstatus |= status;
556+
sc->intrtstamp = isr_tstamp;
550557
spin_unlock(&sc->intr_lock);
551558

552559
if (status & SCHED_INTR)
@@ -760,6 +767,8 @@ static void ath9k_tx(struct ieee80211_hw *hw,
760767
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
761768
unsigned long flags;
762769

770+
ath_warn(common, "ath9k_tx skb=%p, skb->sk=%p\n", skb, skb->sk);
771+
763772
if (sc->ps_enabled) {
764773
/*
765774
* mac80211 does not set PM field for normal data frames, so we
@@ -2837,3 +2846,16 @@ struct ieee80211_ops ath9k_ops = {
28372846
.get_txpower = ath9k_get_txpower,
28382847
.wake_tx_queue = ath9k_wake_tx_queue,
28392848
};
2849+
2850+
void ath9k_cyc2hwtstamp(struct ath_softc *sc, struct skb_shared_hwtstamps *hwtstamps, u32 cycle) {
2851+
u64 ns;
2852+
unsigned long flags;
2853+
2854+
spin_lock_irqsave(&sc->systim_lock, flags);
2855+
ns = timecounter_cyc2time(&sc->tc, (u64)cycle);
2856+
spin_unlock_irqrestore(&sc->systim_lock, flags);
2857+
2858+
memset(hwtstamps, 0, sizeof(*hwtstamps));
2859+
hwtstamps->hwtstamp = ns_to_ktime(ns);
2860+
}
2861+

0 commit comments

Comments
 (0)