1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
6 #include <linux/vmalloc.h>
13 ath11k_accumulate_per_peer_tx_stats(struct ath11k_sta
*arsta
,
14 struct ath11k_per_peer_tx_stats
*peer_stats
,
17 struct rate_info
*txrate
= &arsta
->txrate
;
18 struct ath11k_htt_tx_stats
*tx_stats
;
24 tx_stats
= arsta
->tx_stats
;
25 gi
= FIELD_GET(RATE_INFO_FLAGS_SHORT_GI
, arsta
->txrate
.flags
);
28 nss
= txrate
->nss
- 1;
30 #define STATS_OP_FMT(name) tx_stats->stats[ATH11K_STATS_TYPE_##name]
32 if (txrate
->flags
& RATE_INFO_FLAGS_HE_MCS
) {
33 STATS_OP_FMT(SUCC
).he
[0][mcs
] += peer_stats
->succ_bytes
;
34 STATS_OP_FMT(SUCC
).he
[1][mcs
] += peer_stats
->succ_pkts
;
35 STATS_OP_FMT(FAIL
).he
[0][mcs
] += peer_stats
->failed_bytes
;
36 STATS_OP_FMT(FAIL
).he
[1][mcs
] += peer_stats
->failed_pkts
;
37 STATS_OP_FMT(RETRY
).he
[0][mcs
] += peer_stats
->retry_bytes
;
38 STATS_OP_FMT(RETRY
).he
[1][mcs
] += peer_stats
->retry_pkts
;
39 } else if (txrate
->flags
& RATE_INFO_FLAGS_VHT_MCS
) {
40 STATS_OP_FMT(SUCC
).vht
[0][mcs
] += peer_stats
->succ_bytes
;
41 STATS_OP_FMT(SUCC
).vht
[1][mcs
] += peer_stats
->succ_pkts
;
42 STATS_OP_FMT(FAIL
).vht
[0][mcs
] += peer_stats
->failed_bytes
;
43 STATS_OP_FMT(FAIL
).vht
[1][mcs
] += peer_stats
->failed_pkts
;
44 STATS_OP_FMT(RETRY
).vht
[0][mcs
] += peer_stats
->retry_bytes
;
45 STATS_OP_FMT(RETRY
).vht
[1][mcs
] += peer_stats
->retry_pkts
;
46 } else if (txrate
->flags
& RATE_INFO_FLAGS_MCS
) {
47 STATS_OP_FMT(SUCC
).ht
[0][mcs
] += peer_stats
->succ_bytes
;
48 STATS_OP_FMT(SUCC
).ht
[1][mcs
] += peer_stats
->succ_pkts
;
49 STATS_OP_FMT(FAIL
).ht
[0][mcs
] += peer_stats
->failed_bytes
;
50 STATS_OP_FMT(FAIL
).ht
[1][mcs
] += peer_stats
->failed_pkts
;
51 STATS_OP_FMT(RETRY
).ht
[0][mcs
] += peer_stats
->retry_bytes
;
52 STATS_OP_FMT(RETRY
).ht
[1][mcs
] += peer_stats
->retry_pkts
;
54 mcs
= legacy_rate_idx
;
56 STATS_OP_FMT(SUCC
).legacy
[0][mcs
] += peer_stats
->succ_bytes
;
57 STATS_OP_FMT(SUCC
).legacy
[1][mcs
] += peer_stats
->succ_pkts
;
58 STATS_OP_FMT(FAIL
).legacy
[0][mcs
] += peer_stats
->failed_bytes
;
59 STATS_OP_FMT(FAIL
).legacy
[1][mcs
] += peer_stats
->failed_pkts
;
60 STATS_OP_FMT(RETRY
).legacy
[0][mcs
] += peer_stats
->retry_bytes
;
61 STATS_OP_FMT(RETRY
).legacy
[1][mcs
] += peer_stats
->retry_pkts
;
64 if (peer_stats
->is_ampdu
) {
65 tx_stats
->ba_fails
+= peer_stats
->ba_fails
;
67 if (txrate
->flags
& RATE_INFO_FLAGS_HE_MCS
) {
68 STATS_OP_FMT(AMPDU
).he
[0][mcs
] +=
69 peer_stats
->succ_bytes
+ peer_stats
->retry_bytes
;
70 STATS_OP_FMT(AMPDU
).he
[1][mcs
] +=
71 peer_stats
->succ_pkts
+ peer_stats
->retry_pkts
;
72 } else if (txrate
->flags
& RATE_INFO_FLAGS_MCS
) {
73 STATS_OP_FMT(AMPDU
).ht
[0][mcs
] +=
74 peer_stats
->succ_bytes
+ peer_stats
->retry_bytes
;
75 STATS_OP_FMT(AMPDU
).ht
[1][mcs
] +=
76 peer_stats
->succ_pkts
+ peer_stats
->retry_pkts
;
78 STATS_OP_FMT(AMPDU
).vht
[0][mcs
] +=
79 peer_stats
->succ_bytes
+ peer_stats
->retry_bytes
;
80 STATS_OP_FMT(AMPDU
).vht
[1][mcs
] +=
81 peer_stats
->succ_pkts
+ peer_stats
->retry_pkts
;
83 STATS_OP_FMT(AMPDU
).bw
[0][bw
] +=
84 peer_stats
->succ_bytes
+ peer_stats
->retry_bytes
;
85 STATS_OP_FMT(AMPDU
).nss
[0][nss
] +=
86 peer_stats
->succ_bytes
+ peer_stats
->retry_bytes
;
87 STATS_OP_FMT(AMPDU
).gi
[0][gi
] +=
88 peer_stats
->succ_bytes
+ peer_stats
->retry_bytes
;
89 STATS_OP_FMT(AMPDU
).bw
[1][bw
] +=
90 peer_stats
->succ_pkts
+ peer_stats
->retry_pkts
;
91 STATS_OP_FMT(AMPDU
).nss
[1][nss
] +=
92 peer_stats
->succ_pkts
+ peer_stats
->retry_pkts
;
93 STATS_OP_FMT(AMPDU
).gi
[1][gi
] +=
94 peer_stats
->succ_pkts
+ peer_stats
->retry_pkts
;
96 tx_stats
->ack_fails
+= peer_stats
->ba_fails
;
99 STATS_OP_FMT(SUCC
).bw
[0][bw
] += peer_stats
->succ_bytes
;
100 STATS_OP_FMT(SUCC
).nss
[0][nss
] += peer_stats
->succ_bytes
;
101 STATS_OP_FMT(SUCC
).gi
[0][gi
] += peer_stats
->succ_bytes
;
103 STATS_OP_FMT(SUCC
).bw
[1][bw
] += peer_stats
->succ_pkts
;
104 STATS_OP_FMT(SUCC
).nss
[1][nss
] += peer_stats
->succ_pkts
;
105 STATS_OP_FMT(SUCC
).gi
[1][gi
] += peer_stats
->succ_pkts
;
107 STATS_OP_FMT(FAIL
).bw
[0][bw
] += peer_stats
->failed_bytes
;
108 STATS_OP_FMT(FAIL
).nss
[0][nss
] += peer_stats
->failed_bytes
;
109 STATS_OP_FMT(FAIL
).gi
[0][gi
] += peer_stats
->failed_bytes
;
111 STATS_OP_FMT(FAIL
).bw
[1][bw
] += peer_stats
->failed_pkts
;
112 STATS_OP_FMT(FAIL
).nss
[1][nss
] += peer_stats
->failed_pkts
;
113 STATS_OP_FMT(FAIL
).gi
[1][gi
] += peer_stats
->failed_pkts
;
115 STATS_OP_FMT(RETRY
).bw
[0][bw
] += peer_stats
->retry_bytes
;
116 STATS_OP_FMT(RETRY
).nss
[0][nss
] += peer_stats
->retry_bytes
;
117 STATS_OP_FMT(RETRY
).gi
[0][gi
] += peer_stats
->retry_bytes
;
119 STATS_OP_FMT(RETRY
).bw
[1][bw
] += peer_stats
->retry_pkts
;
120 STATS_OP_FMT(RETRY
).nss
[1][nss
] += peer_stats
->retry_pkts
;
121 STATS_OP_FMT(RETRY
).gi
[1][gi
] += peer_stats
->retry_pkts
;
123 tx_stats
->tx_duration
+= peer_stats
->duration
;
126 void ath11k_update_per_peer_stats_from_txcompl(struct ath11k
*ar
,
127 struct sk_buff
*msdu
,
128 struct hal_tx_status
*ts
)
130 struct ath11k_base
*ab
= ar
->ab
;
131 struct ath11k_per_peer_tx_stats
*peer_stats
= &ar
->cached_stats
;
132 enum hal_tx_rate_stats_pkt_type pkt_type
;
133 enum hal_tx_rate_stats_sgi sgi
;
134 enum hal_tx_rate_stats_bw bw
;
135 struct ath11k_peer
*peer
;
136 struct ath11k_sta
*arsta
;
137 struct ieee80211_sta
*sta
;
144 spin_lock_bh(&ab
->base_lock
);
145 peer
= ath11k_peer_find_by_id(ab
, ts
->peer_id
);
146 if (!peer
|| !peer
->sta
) {
147 ath11k_warn(ab
, "failed to find the peer\n");
148 spin_unlock_bh(&ab
->base_lock
);
154 arsta
= (struct ath11k_sta
*)sta
->drv_priv
;
156 memset(&arsta
->txrate
, 0, sizeof(arsta
->txrate
));
157 pkt_type
= FIELD_GET(HAL_TX_RATE_STATS_INFO0_PKT_TYPE
,
159 mcs
= FIELD_GET(HAL_TX_RATE_STATS_INFO0_MCS
,
161 sgi
= FIELD_GET(HAL_TX_RATE_STATS_INFO0_SGI
,
163 bw
= FIELD_GET(HAL_TX_RATE_STATS_INFO0_BW
, ts
->rate_stats
);
165 if (pkt_type
== HAL_TX_RATE_STATS_PKT_TYPE_11A
||
166 pkt_type
== HAL_TX_RATE_STATS_PKT_TYPE_11B
) {
167 ret
= ath11k_mac_hw_ratecode_to_legacy_rate(mcs
,
173 arsta
->txrate
.legacy
= rate
;
174 } else if (pkt_type
== HAL_TX_RATE_STATS_PKT_TYPE_11N
) {
176 ath11k_warn(ab
, "Invalid HT mcs index %d\n", mcs
);
180 arsta
->txrate
.mcs
= mcs
+ 8 * (arsta
->last_txrate
.nss
- 1);
181 arsta
->txrate
.flags
= RATE_INFO_FLAGS_MCS
;
183 arsta
->txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
184 } else if (pkt_type
== HAL_TX_RATE_STATS_PKT_TYPE_11AC
) {
186 ath11k_warn(ab
, "Invalid VHT mcs index %d\n", mcs
);
190 arsta
->txrate
.mcs
= mcs
;
191 arsta
->txrate
.flags
= RATE_INFO_FLAGS_VHT_MCS
;
193 arsta
->txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
194 } else if (pkt_type
== HAL_TX_RATE_STATS_PKT_TYPE_11AX
) {
198 arsta
->txrate
.nss
= arsta
->last_txrate
.nss
;
199 arsta
->txrate
.bw
= ath11k_mac_bw_to_mac80211_bw(bw
);
201 ath11k_accumulate_per_peer_tx_stats(arsta
, peer_stats
, rate_idx
);
203 spin_unlock_bh(&ab
->base_lock
);
207 static ssize_t
ath11k_dbg_sta_dump_tx_stats(struct file
*file
,
208 char __user
*user_buf
,
209 size_t count
, loff_t
*ppos
)
211 struct ieee80211_sta
*sta
= file
->private_data
;
212 struct ath11k_sta
*arsta
= (struct ath11k_sta
*)sta
->drv_priv
;
213 struct ath11k
*ar
= arsta
->arvif
->ar
;
214 struct ath11k_htt_data_stats
*stats
;
215 static const char *str_name
[ATH11K_STATS_TYPE_MAX
] = {"succ", "fail",
217 static const char *str
[ATH11K_COUNTER_TYPE_MAX
] = {"bytes", "packets"};
218 int len
= 0, i
, j
, k
, retval
= 0;
219 const int size
= 2 * 4096;
222 buf
= kzalloc(size
, GFP_KERNEL
);
226 mutex_lock(&ar
->conf_mutex
);
228 spin_lock_bh(&ar
->data_lock
);
229 for (k
= 0; k
< ATH11K_STATS_TYPE_MAX
; k
++) {
230 for (j
= 0; j
< ATH11K_COUNTER_TYPE_MAX
; j
++) {
231 stats
= &arsta
->tx_stats
->stats
[k
];
232 len
+= scnprintf(buf
+ len
, size
- len
, "%s_%s\n",
235 len
+= scnprintf(buf
+ len
, size
- len
,
238 for (i
= 0; i
< ATH11K_HE_MCS_NUM
; i
++)
239 len
+= scnprintf(buf
+ len
, size
- len
,
242 len
+= scnprintf(buf
+ len
, size
- len
, "\n");
243 len
+= scnprintf(buf
+ len
, size
- len
,
246 for (i
= 0; i
< ATH11K_VHT_MCS_NUM
; i
++)
247 len
+= scnprintf(buf
+ len
, size
- len
,
250 len
+= scnprintf(buf
+ len
, size
- len
, "\n");
251 len
+= scnprintf(buf
+ len
, size
- len
, " HT MCS %s\n",
253 for (i
= 0; i
< ATH11K_HT_MCS_NUM
; i
++)
254 len
+= scnprintf(buf
+ len
, size
- len
,
255 " %llu ", stats
->ht
[j
][i
]);
256 len
+= scnprintf(buf
+ len
, size
- len
, "\n");
257 len
+= scnprintf(buf
+ len
, size
- len
,
258 " BW %s (20,40,80,160 MHz)\n", str
[j
]);
259 len
+= scnprintf(buf
+ len
, size
- len
,
260 " %llu %llu %llu %llu\n",
261 stats
->bw
[j
][0], stats
->bw
[j
][1],
262 stats
->bw
[j
][2], stats
->bw
[j
][3]);
263 len
+= scnprintf(buf
+ len
, size
- len
,
264 " NSS %s (1x1,2x2,3x3,4x4)\n", str
[j
]);
265 len
+= scnprintf(buf
+ len
, size
- len
,
266 " %llu %llu %llu %llu\n",
267 stats
->nss
[j
][0], stats
->nss
[j
][1],
268 stats
->nss
[j
][2], stats
->nss
[j
][3]);
269 len
+= scnprintf(buf
+ len
, size
- len
,
270 " GI %s (0.4us,0.8us,1.6us,3.2us)\n",
272 len
+= scnprintf(buf
+ len
, size
- len
,
273 " %llu %llu %llu %llu\n",
274 stats
->gi
[j
][0], stats
->gi
[j
][1],
275 stats
->gi
[j
][2], stats
->gi
[j
][3]);
276 len
+= scnprintf(buf
+ len
, size
- len
,
277 " legacy rate %s (1,2 ... Mbps)\n ",
279 for (i
= 0; i
< ATH11K_LEGACY_NUM
; i
++)
280 len
+= scnprintf(buf
+ len
, size
- len
, "%llu ",
281 stats
->legacy
[j
][i
]);
282 len
+= scnprintf(buf
+ len
, size
- len
, "\n");
286 len
+= scnprintf(buf
+ len
, size
- len
,
287 "\nTX duration\n %llu usecs\n",
288 arsta
->tx_stats
->tx_duration
);
289 len
+= scnprintf(buf
+ len
, size
- len
,
290 "BA fails\n %llu\n", arsta
->tx_stats
->ba_fails
);
291 len
+= scnprintf(buf
+ len
, size
- len
,
292 "ack fails\n %llu\n", arsta
->tx_stats
->ack_fails
);
293 spin_unlock_bh(&ar
->data_lock
);
297 retval
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
300 mutex_unlock(&ar
->conf_mutex
);
304 static const struct file_operations fops_tx_stats
= {
305 .read
= ath11k_dbg_sta_dump_tx_stats
,
307 .owner
= THIS_MODULE
,
308 .llseek
= default_llseek
,
311 static ssize_t
ath11k_dbg_sta_dump_rx_stats(struct file
*file
,
312 char __user
*user_buf
,
313 size_t count
, loff_t
*ppos
)
315 struct ieee80211_sta
*sta
= file
->private_data
;
316 struct ath11k_sta
*arsta
= (struct ath11k_sta
*)sta
->drv_priv
;
317 struct ath11k
*ar
= arsta
->arvif
->ar
;
318 struct ath11k_rx_peer_stats
*rx_stats
= arsta
->rx_stats
;
319 int len
= 0, i
, retval
= 0;
320 const int size
= 4096;
326 buf
= kzalloc(size
, GFP_KERNEL
);
330 mutex_lock(&ar
->conf_mutex
);
331 spin_lock_bh(&ar
->ab
->base_lock
);
333 len
+= scnprintf(buf
+ len
, size
- len
, "RX peer stats:\n");
334 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MSDUs: %llu\n",
336 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MSDUs with TCP L4: %llu\n",
337 rx_stats
->tcp_msdu_count
);
338 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MSDUs with UDP L4: %llu\n",
339 rx_stats
->udp_msdu_count
);
340 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MSDUs part of AMPDU: %llu\n",
341 rx_stats
->ampdu_msdu_count
);
342 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MSDUs not part of AMPDU: %llu\n",
343 rx_stats
->non_ampdu_msdu_count
);
344 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MSDUs using STBC: %llu\n",
345 rx_stats
->stbc_count
);
346 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MSDUs beamformed: %llu\n",
347 rx_stats
->beamformed_count
);
348 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MPDUs with FCS ok: %llu\n",
349 rx_stats
->num_mpdu_fcs_ok
);
350 len
+= scnprintf(buf
+ len
, size
- len
, "Num of MPDUs with FCS error: %llu\n",
351 rx_stats
->num_mpdu_fcs_err
);
352 len
+= scnprintf(buf
+ len
, size
- len
,
353 "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n",
354 rx_stats
->gi_count
[0], rx_stats
->gi_count
[1],
355 rx_stats
->gi_count
[2], rx_stats
->gi_count
[3]);
356 len
+= scnprintf(buf
+ len
, size
- len
,
357 "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n",
358 rx_stats
->bw_count
[0], rx_stats
->bw_count
[1],
359 rx_stats
->bw_count
[2], rx_stats
->bw_count
[3]);
360 len
+= scnprintf(buf
+ len
, size
- len
, "BCC %llu LDPC %llu\n",
361 rx_stats
->coding_count
[0], rx_stats
->coding_count
[1]);
362 len
+= scnprintf(buf
+ len
, size
- len
,
363 "preamble: 11A %llu 11B %llu 11N %llu 11AC %llu 11AX %llu\n",
364 rx_stats
->pream_cnt
[0], rx_stats
->pream_cnt
[1],
365 rx_stats
->pream_cnt
[2], rx_stats
->pream_cnt
[3],
366 rx_stats
->pream_cnt
[4]);
367 len
+= scnprintf(buf
+ len
, size
- len
,
368 "reception type: SU %llu MU_MIMO %llu MU_OFDMA %llu MU_OFDMA_MIMO %llu\n",
369 rx_stats
->reception_type
[0], rx_stats
->reception_type
[1],
370 rx_stats
->reception_type
[2], rx_stats
->reception_type
[3]);
371 len
+= scnprintf(buf
+ len
, size
- len
, "TID(0-15) Legacy TID(16):");
372 for (i
= 0; i
<= IEEE80211_NUM_TIDS
; i
++)
373 len
+= scnprintf(buf
+ len
, size
- len
, "%llu ", rx_stats
->tid_count
[i
]);
374 len
+= scnprintf(buf
+ len
, size
- len
, "\nMCS(0-11) Legacy MCS(12):");
375 for (i
= 0; i
< HAL_RX_MAX_MCS
+ 1; i
++)
376 len
+= scnprintf(buf
+ len
, size
- len
, "%llu ", rx_stats
->mcs_count
[i
]);
377 len
+= scnprintf(buf
+ len
, size
- len
, "\nNSS(1-8):");
378 for (i
= 0; i
< HAL_RX_MAX_NSS
; i
++)
379 len
+= scnprintf(buf
+ len
, size
- len
, "%llu ", rx_stats
->nss_count
[i
]);
380 len
+= scnprintf(buf
+ len
, size
- len
, "\nRX Duration:%llu ",
381 rx_stats
->rx_duration
);
382 len
+= scnprintf(buf
+ len
, size
- len
, "\n");
384 spin_unlock_bh(&ar
->ab
->base_lock
);
388 retval
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
391 mutex_unlock(&ar
->conf_mutex
);
395 static const struct file_operations fops_rx_stats
= {
396 .read
= ath11k_dbg_sta_dump_rx_stats
,
398 .owner
= THIS_MODULE
,
399 .llseek
= default_llseek
,
403 ath11k_dbg_sta_open_htt_peer_stats(struct inode
*inode
, struct file
*file
)
405 struct ieee80211_sta
*sta
= inode
->i_private
;
406 struct ath11k_sta
*arsta
= (struct ath11k_sta
*)sta
->drv_priv
;
407 struct ath11k
*ar
= arsta
->arvif
->ar
;
408 struct debug_htt_stats_req
*stats_req
;
411 stats_req
= vzalloc(sizeof(*stats_req
) + ATH11K_HTT_STATS_BUF_SIZE
);
415 mutex_lock(&ar
->conf_mutex
);
416 ar
->debug
.htt_stats
.stats_req
= stats_req
;
417 stats_req
->type
= ATH11K_DBG_HTT_EXT_STATS_PEER_INFO
;
418 memcpy(stats_req
->peer_addr
, sta
->addr
, ETH_ALEN
);
419 ret
= ath11k_dbg_htt_stats_req(ar
);
420 mutex_unlock(&ar
->conf_mutex
);
424 file
->private_data
= stats_req
;
432 ath11k_dbg_sta_release_htt_peer_stats(struct inode
*inode
, struct file
*file
)
434 vfree(file
->private_data
);
438 static ssize_t
ath11k_dbg_sta_read_htt_peer_stats(struct file
*file
,
439 char __user
*user_buf
,
440 size_t count
, loff_t
*ppos
)
442 struct debug_htt_stats_req
*stats_req
= file
->private_data
;
446 buf
= stats_req
->buf
;
447 length
= min_t(u32
, stats_req
->buf_len
, ATH11K_HTT_STATS_BUF_SIZE
);
448 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, length
);
451 static const struct file_operations fops_htt_peer_stats
= {
452 .open
= ath11k_dbg_sta_open_htt_peer_stats
,
453 .release
= ath11k_dbg_sta_release_htt_peer_stats
,
454 .read
= ath11k_dbg_sta_read_htt_peer_stats
,
455 .owner
= THIS_MODULE
,
456 .llseek
= default_llseek
,
459 static ssize_t
ath11k_dbg_sta_write_peer_pktlog(struct file
*file
,
460 const char __user
*buf
,
461 size_t count
, loff_t
*ppos
)
463 struct ieee80211_sta
*sta
= file
->private_data
;
464 struct ath11k_sta
*arsta
= (struct ath11k_sta
*)sta
->drv_priv
;
465 struct ath11k
*ar
= arsta
->arvif
->ar
;
468 mutex_lock(&ar
->conf_mutex
);
470 if (ar
->state
!= ATH11K_STATE_ON
) {
475 ret
= kstrtoint_from_user(buf
, count
, 0, &enable
);
479 ar
->debug
.pktlog_peer_valid
= enable
;
480 memcpy(ar
->debug
.pktlog_peer_addr
, sta
->addr
, ETH_ALEN
);
482 /* Send peer based pktlog enable/disable */
483 ret
= ath11k_wmi_pdev_peer_pktlog_filter(ar
, sta
->addr
, enable
);
485 ath11k_warn(ar
->ab
, "failed to set peer pktlog filter %pM: %d\n",
490 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "peer pktlog filter set to %d\n",
495 mutex_unlock(&ar
->conf_mutex
);
499 static ssize_t
ath11k_dbg_sta_read_peer_pktlog(struct file
*file
,
501 size_t count
, loff_t
*ppos
)
503 struct ieee80211_sta
*sta
= file
->private_data
;
504 struct ath11k_sta
*arsta
= (struct ath11k_sta
*)sta
->drv_priv
;
505 struct ath11k
*ar
= arsta
->arvif
->ar
;
509 mutex_lock(&ar
->conf_mutex
);
510 len
= scnprintf(buf
, sizeof(buf
), "%08x %pM\n",
511 ar
->debug
.pktlog_peer_valid
,
512 ar
->debug
.pktlog_peer_addr
);
513 mutex_unlock(&ar
->conf_mutex
);
515 return simple_read_from_buffer(ubuf
, count
, ppos
, buf
, len
);
518 static const struct file_operations fops_peer_pktlog
= {
519 .write
= ath11k_dbg_sta_write_peer_pktlog
,
520 .read
= ath11k_dbg_sta_read_peer_pktlog
,
522 .owner
= THIS_MODULE
,
523 .llseek
= default_llseek
,
526 void ath11k_sta_add_debugfs(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
527 struct ieee80211_sta
*sta
, struct dentry
*dir
)
529 struct ath11k
*ar
= hw
->priv
;
531 if (ath11k_debug_is_extd_tx_stats_enabled(ar
))
532 debugfs_create_file("tx_stats", 0400, dir
, sta
,
534 if (ath11k_debug_is_extd_rx_stats_enabled(ar
))
535 debugfs_create_file("rx_stats", 0400, dir
, sta
,
538 debugfs_create_file("htt_peer_stats", 0400, dir
, sta
,
539 &fops_htt_peer_stats
);
541 debugfs_create_file("peer_pktlog", 0644, dir
, sta
,