1 From 8db6c1ca64664ef9b071e6eeb646023ac5b240a8 Mon Sep 17 00:00:00 2001
2 From: Ping-Ke Shih <pkshih@realtek.com>
3 Date: Thu, 18 Jul 2024 14:41:55 +0800
4 Subject: [PATCH] wifi: rtw88: debugfs: support multiple adapters debugging
6 Originally in order to read partial registers from large area, we write
7 a range value stored into a static variable and read registers according
8 to the static variable.
10 However, if we install more than one adapters supported by this driver,
11 the static variables will be overwritten by latter adapters. To resolve
12 the problem, move the static variables to struct rtw_dev for each adapter.
14 With changes, smatch spends too much time to parse rtw_debugfs_init():
15 debug.c:1289 rtw_debugfs_init() parse error: turning off implications
17 Move stuffs of adding debugfs entries to three rtw_debugfs_add_xxx()
20 Reported-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
21 Closes: https://lore.kernel.org/linux-wireless/cd6a2acf3c2c36d938b40140b52a779516f446a9.camel@realtek.com/T/#m27662022c70d9f893ba96f6c6a8dd8fce2434dfe
22 Tested-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
23 Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
24 Link: https://patch.msgid.link/20240718064155.38955-1-pkshih@realtek.com
26 drivers/net/wireless/realtek/rtw88/debug.c | 303 ++++++++++++---------
27 drivers/net/wireless/realtek/rtw88/debug.h | 2 +
28 drivers/net/wireless/realtek/rtw88/main.c | 1 +
29 drivers/net/wireless/realtek/rtw88/main.h | 3 +-
30 4 files changed, 180 insertions(+), 129 deletions(-)
32 --- a/drivers/net/wireless/realtek/rtw88/debug.c
33 +++ b/drivers/net/wireless/realtek/rtw88/debug.c
34 @@ -43,6 +43,62 @@ struct rtw_debugfs_priv {
39 + struct rtw_debugfs_priv mac_0;
40 + struct rtw_debugfs_priv mac_1;
41 + struct rtw_debugfs_priv mac_2;
42 + struct rtw_debugfs_priv mac_3;
43 + struct rtw_debugfs_priv mac_4;
44 + struct rtw_debugfs_priv mac_5;
45 + struct rtw_debugfs_priv mac_6;
46 + struct rtw_debugfs_priv mac_7;
47 + struct rtw_debugfs_priv mac_10;
48 + struct rtw_debugfs_priv mac_11;
49 + struct rtw_debugfs_priv mac_12;
50 + struct rtw_debugfs_priv mac_13;
51 + struct rtw_debugfs_priv mac_14;
52 + struct rtw_debugfs_priv mac_15;
53 + struct rtw_debugfs_priv mac_16;
54 + struct rtw_debugfs_priv mac_17;
55 + struct rtw_debugfs_priv bb_8;
56 + struct rtw_debugfs_priv bb_9;
57 + struct rtw_debugfs_priv bb_a;
58 + struct rtw_debugfs_priv bb_b;
59 + struct rtw_debugfs_priv bb_c;
60 + struct rtw_debugfs_priv bb_d;
61 + struct rtw_debugfs_priv bb_e;
62 + struct rtw_debugfs_priv bb_f;
63 + struct rtw_debugfs_priv bb_18;
64 + struct rtw_debugfs_priv bb_19;
65 + struct rtw_debugfs_priv bb_1a;
66 + struct rtw_debugfs_priv bb_1b;
67 + struct rtw_debugfs_priv bb_1c;
68 + struct rtw_debugfs_priv bb_1d;
69 + struct rtw_debugfs_priv bb_1e;
70 + struct rtw_debugfs_priv bb_1f;
71 + struct rtw_debugfs_priv bb_2c;
72 + struct rtw_debugfs_priv bb_2d;
73 + struct rtw_debugfs_priv bb_40;
74 + struct rtw_debugfs_priv bb_41;
75 + struct rtw_debugfs_priv rf_dump;
76 + struct rtw_debugfs_priv tx_pwr_tbl;
77 + struct rtw_debugfs_priv write_reg;
78 + struct rtw_debugfs_priv h2c;
79 + struct rtw_debugfs_priv rf_write;
80 + struct rtw_debugfs_priv rf_read;
81 + struct rtw_debugfs_priv read_reg;
82 + struct rtw_debugfs_priv fix_rate;
83 + struct rtw_debugfs_priv dump_cam;
84 + struct rtw_debugfs_priv rsvd_page;
85 + struct rtw_debugfs_priv phy_info;
86 + struct rtw_debugfs_priv coex_enable;
87 + struct rtw_debugfs_priv coex_info;
88 + struct rtw_debugfs_priv edcca_enable;
89 + struct rtw_debugfs_priv fw_crash;
90 + struct rtw_debugfs_priv force_lowest_basic_rate;
91 + struct rtw_debugfs_priv dm_cap;
94 static const char * const rtw_dm_cap_strs[] = {
95 [RTW_DM_CAP_NA] = "NA",
96 [RTW_DM_CAP_TXGAPK] = "TXGAPK",
97 @@ -524,7 +580,7 @@ static int rtw_debug_get_bb_page(struct
101 -static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
102 +static int rtw_debugfs_get_rf_dump(struct seq_file *m, void *v)
104 struct rtw_debugfs_priv *debugfs_priv = m->private;
105 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
106 @@ -1074,139 +1130,102 @@ static int rtw_debugfs_get_dm_cap(struct
110 -#define rtw_debug_impl_mac(page, addr) \
111 -static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \
112 +#define rtw_debug_priv_mac(addr) \
114 .cb_read = rtw_debug_get_mac_page, \
118 -rtw_debug_impl_mac(0, 0x0000);
119 -rtw_debug_impl_mac(1, 0x0100);
120 -rtw_debug_impl_mac(2, 0x0200);
121 -rtw_debug_impl_mac(3, 0x0300);
122 -rtw_debug_impl_mac(4, 0x0400);
123 -rtw_debug_impl_mac(5, 0x0500);
124 -rtw_debug_impl_mac(6, 0x0600);
125 -rtw_debug_impl_mac(7, 0x0700);
126 -rtw_debug_impl_mac(10, 0x1000);
127 -rtw_debug_impl_mac(11, 0x1100);
128 -rtw_debug_impl_mac(12, 0x1200);
129 -rtw_debug_impl_mac(13, 0x1300);
130 -rtw_debug_impl_mac(14, 0x1400);
131 -rtw_debug_impl_mac(15, 0x1500);
132 -rtw_debug_impl_mac(16, 0x1600);
133 -rtw_debug_impl_mac(17, 0x1700);
135 -#define rtw_debug_impl_bb(page, addr) \
136 -static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \
137 +#define rtw_debug_priv_bb(addr) \
139 .cb_read = rtw_debug_get_bb_page, \
143 -rtw_debug_impl_bb(8, 0x0800);
144 -rtw_debug_impl_bb(9, 0x0900);
145 -rtw_debug_impl_bb(a, 0x0a00);
146 -rtw_debug_impl_bb(b, 0x0b00);
147 -rtw_debug_impl_bb(c, 0x0c00);
148 -rtw_debug_impl_bb(d, 0x0d00);
149 -rtw_debug_impl_bb(e, 0x0e00);
150 -rtw_debug_impl_bb(f, 0x0f00);
151 -rtw_debug_impl_bb(18, 0x1800);
152 -rtw_debug_impl_bb(19, 0x1900);
153 -rtw_debug_impl_bb(1a, 0x1a00);
154 -rtw_debug_impl_bb(1b, 0x1b00);
155 -rtw_debug_impl_bb(1c, 0x1c00);
156 -rtw_debug_impl_bb(1d, 0x1d00);
157 -rtw_debug_impl_bb(1e, 0x1e00);
158 -rtw_debug_impl_bb(1f, 0x1f00);
159 -rtw_debug_impl_bb(2c, 0x2c00);
160 -rtw_debug_impl_bb(2d, 0x2d00);
161 -rtw_debug_impl_bb(40, 0x4000);
162 -rtw_debug_impl_bb(41, 0x4100);
164 -static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = {
165 - .cb_read = rtw_debug_get_rf_dump,
168 -static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = {
169 - .cb_read = rtw_debugfs_get_tx_pwr_tbl,
172 -static struct rtw_debugfs_priv rtw_debug_priv_write_reg = {
173 - .cb_write = rtw_debugfs_set_write_reg,
176 -static struct rtw_debugfs_priv rtw_debug_priv_h2c = {
177 - .cb_write = rtw_debugfs_set_h2c,
180 -static struct rtw_debugfs_priv rtw_debug_priv_rf_write = {
181 - .cb_write = rtw_debugfs_set_rf_write,
184 -static struct rtw_debugfs_priv rtw_debug_priv_rf_read = {
185 - .cb_write = rtw_debugfs_set_rf_read,
186 - .cb_read = rtw_debugfs_get_rf_read,
189 -static struct rtw_debugfs_priv rtw_debug_priv_read_reg = {
190 - .cb_write = rtw_debugfs_set_read_reg,
191 - .cb_read = rtw_debugfs_get_read_reg,
194 -static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = {
195 - .cb_write = rtw_debugfs_set_fix_rate,
196 - .cb_read = rtw_debugfs_get_fix_rate,
199 -static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = {
200 - .cb_write = rtw_debugfs_set_single_input,
201 - .cb_read = rtw_debugfs_get_dump_cam,
204 -static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = {
205 - .cb_write = rtw_debugfs_set_rsvd_page,
206 - .cb_read = rtw_debugfs_get_rsvd_page,
209 -static struct rtw_debugfs_priv rtw_debug_priv_phy_info = {
210 - .cb_read = rtw_debugfs_get_phy_info,
213 -static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = {
214 - .cb_write = rtw_debugfs_set_coex_enable,
215 - .cb_read = rtw_debugfs_get_coex_enable,
218 -static struct rtw_debugfs_priv rtw_debug_priv_coex_info = {
219 - .cb_read = rtw_debugfs_get_coex_info,
222 -static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = {
223 - .cb_write = rtw_debugfs_set_edcca_enable,
224 - .cb_read = rtw_debugfs_get_edcca_enable,
227 -static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = {
228 - .cb_write = rtw_debugfs_set_fw_crash,
229 - .cb_read = rtw_debugfs_get_fw_crash,
232 -static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = {
233 - .cb_write = rtw_debugfs_set_force_lowest_basic_rate,
234 - .cb_read = rtw_debugfs_get_force_lowest_basic_rate,
237 -static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
238 - .cb_write = rtw_debugfs_set_dm_cap,
239 - .cb_read = rtw_debugfs_get_dm_cap,
240 +#define rtw_debug_priv_get(name) \
242 + .cb_read = rtw_debugfs_get_ ##name, \
245 +#define rtw_debug_priv_set(name) \
247 + .cb_write = rtw_debugfs_set_ ##name, \
250 +#define rtw_debug_priv_set_and_get(name) \
252 + .cb_write = rtw_debugfs_set_ ##name, \
253 + .cb_read = rtw_debugfs_get_ ##name, \
256 +#define rtw_debug_priv_set_single_and_get(name) \
258 + .cb_write = rtw_debugfs_set_single_input, \
259 + .cb_read = rtw_debugfs_get_ ##name, \
262 +static const struct rtw_debugfs rtw_debugfs_templ = {
263 + .mac_0 = rtw_debug_priv_mac(0x0000),
264 + .mac_1 = rtw_debug_priv_mac(0x0100),
265 + .mac_2 = rtw_debug_priv_mac(0x0200),
266 + .mac_3 = rtw_debug_priv_mac(0x0300),
267 + .mac_4 = rtw_debug_priv_mac(0x0400),
268 + .mac_5 = rtw_debug_priv_mac(0x0500),
269 + .mac_6 = rtw_debug_priv_mac(0x0600),
270 + .mac_7 = rtw_debug_priv_mac(0x0700),
271 + .mac_10 = rtw_debug_priv_mac(0x1000),
272 + .mac_11 = rtw_debug_priv_mac(0x1100),
273 + .mac_12 = rtw_debug_priv_mac(0x1200),
274 + .mac_13 = rtw_debug_priv_mac(0x1300),
275 + .mac_14 = rtw_debug_priv_mac(0x1400),
276 + .mac_15 = rtw_debug_priv_mac(0x1500),
277 + .mac_16 = rtw_debug_priv_mac(0x1600),
278 + .mac_17 = rtw_debug_priv_mac(0x1700),
279 + .bb_8 = rtw_debug_priv_bb(0x0800),
280 + .bb_9 = rtw_debug_priv_bb(0x0900),
281 + .bb_a = rtw_debug_priv_bb(0x0a00),
282 + .bb_b = rtw_debug_priv_bb(0x0b00),
283 + .bb_c = rtw_debug_priv_bb(0x0c00),
284 + .bb_d = rtw_debug_priv_bb(0x0d00),
285 + .bb_e = rtw_debug_priv_bb(0x0e00),
286 + .bb_f = rtw_debug_priv_bb(0x0f00),
287 + .bb_18 = rtw_debug_priv_bb(0x1800),
288 + .bb_19 = rtw_debug_priv_bb(0x1900),
289 + .bb_1a = rtw_debug_priv_bb(0x1a00),
290 + .bb_1b = rtw_debug_priv_bb(0x1b00),
291 + .bb_1c = rtw_debug_priv_bb(0x1c00),
292 + .bb_1d = rtw_debug_priv_bb(0x1d00),
293 + .bb_1e = rtw_debug_priv_bb(0x1e00),
294 + .bb_1f = rtw_debug_priv_bb(0x1f00),
295 + .bb_2c = rtw_debug_priv_bb(0x2c00),
296 + .bb_2d = rtw_debug_priv_bb(0x2d00),
297 + .bb_40 = rtw_debug_priv_bb(0x4000),
298 + .bb_41 = rtw_debug_priv_bb(0x4100),
299 + .rf_dump = rtw_debug_priv_get(rf_dump),
300 + .tx_pwr_tbl = rtw_debug_priv_get(tx_pwr_tbl),
301 + .write_reg = rtw_debug_priv_set(write_reg),
302 + .h2c = rtw_debug_priv_set(h2c),
303 + .rf_write = rtw_debug_priv_set(rf_write),
304 + .rf_read = rtw_debug_priv_set_and_get(rf_read),
305 + .read_reg = rtw_debug_priv_set_and_get(read_reg),
306 + .fix_rate = rtw_debug_priv_set_and_get(fix_rate),
307 + .dump_cam = rtw_debug_priv_set_single_and_get(dump_cam),
308 + .rsvd_page = rtw_debug_priv_set_and_get(rsvd_page),
309 + .phy_info = rtw_debug_priv_get(phy_info),
310 + .coex_enable = rtw_debug_priv_set_and_get(coex_enable),
311 + .coex_info = rtw_debug_priv_get(coex_info),
312 + .edcca_enable = rtw_debug_priv_set_and_get(edcca_enable),
313 + .fw_crash = rtw_debug_priv_set_and_get(fw_crash),
314 + .force_lowest_basic_rate = rtw_debug_priv_set_and_get(force_lowest_basic_rate),
315 + .dm_cap = rtw_debug_priv_set_and_get(dm_cap),
318 #define rtw_debugfs_add_core(name, mode, fopname, parent) \
320 - rtw_debug_priv_ ##name.rtwdev = rtwdev; \
321 + struct rtw_debugfs_priv *priv = &rtwdev->debugfs->name; \
322 + priv->rtwdev = rtwdev; \
323 if (IS_ERR(debugfs_create_file(#name, mode, \
324 - parent, &rtw_debug_priv_ ##name,\
326 &file_ops_ ##fopname))) \
327 pr_debug("Unable to initialize debugfs:%s\n", \
329 @@ -1219,12 +1238,9 @@ static struct rtw_debugfs_priv rtw_debug
330 #define rtw_debugfs_add_r(name) \
331 rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir)
333 -void rtw_debugfs_init(struct rtw_dev *rtwdev)
335 +void rtw_debugfs_add_basic(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
337 - struct dentry *debugfs_topdir;
339 - debugfs_topdir = debugfs_create_dir("rtw88",
340 - rtwdev->hw->wiphy->debugfsdir);
341 rtw_debugfs_add_w(write_reg);
342 rtw_debugfs_add_rw(read_reg);
343 rtw_debugfs_add_w(rf_write);
344 @@ -1236,6 +1252,17 @@ void rtw_debugfs_init(struct rtw_dev *rt
345 rtw_debugfs_add_r(coex_info);
346 rtw_debugfs_add_rw(coex_enable);
347 rtw_debugfs_add_w(h2c);
348 + rtw_debugfs_add_r(rf_dump);
349 + rtw_debugfs_add_r(tx_pwr_tbl);
350 + rtw_debugfs_add_rw(edcca_enable);
351 + rtw_debugfs_add_rw(fw_crash);
352 + rtw_debugfs_add_rw(force_lowest_basic_rate);
353 + rtw_debugfs_add_rw(dm_cap);
357 +void rtw_debugfs_add_sec0(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
359 rtw_debugfs_add_r(mac_0);
360 rtw_debugfs_add_r(mac_1);
361 rtw_debugfs_add_r(mac_2);
362 @@ -1252,6 +1279,11 @@ void rtw_debugfs_init(struct rtw_dev *rt
363 rtw_debugfs_add_r(bb_d);
364 rtw_debugfs_add_r(bb_e);
365 rtw_debugfs_add_r(bb_f);
369 +void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
371 rtw_debugfs_add_r(mac_10);
372 rtw_debugfs_add_r(mac_11);
373 rtw_debugfs_add_r(mac_12);
374 @@ -1274,14 +1306,29 @@ void rtw_debugfs_init(struct rtw_dev *rt
375 rtw_debugfs_add_r(bb_40);
376 rtw_debugfs_add_r(bb_41);
378 - rtw_debugfs_add_r(rf_dump);
379 - rtw_debugfs_add_r(tx_pwr_tbl);
380 - rtw_debugfs_add_rw(edcca_enable);
381 - rtw_debugfs_add_rw(fw_crash);
382 - rtw_debugfs_add_rw(force_lowest_basic_rate);
383 - rtw_debugfs_add_rw(dm_cap);
386 +void rtw_debugfs_init(struct rtw_dev *rtwdev)
388 + struct dentry *debugfs_topdir;
390 + rtwdev->debugfs = kmemdup(&rtw_debugfs_templ, sizeof(rtw_debugfs_templ),
392 + if (!rtwdev->debugfs)
395 + debugfs_topdir = debugfs_create_dir("rtw88",
396 + rtwdev->hw->wiphy->debugfsdir);
398 + rtw_debugfs_add_basic(rtwdev, debugfs_topdir);
399 + rtw_debugfs_add_sec0(rtwdev, debugfs_topdir);
400 + rtw_debugfs_add_sec1(rtwdev, debugfs_topdir);
403 +void rtw_debugfs_deinit(struct rtw_dev *rtwdev)
405 + kfree(rtwdev->debugfs);
407 #endif /* CPTCFG_RTW88_DEBUGFS */
409 #ifdef CPTCFG_RTW88_DEBUG
410 --- a/drivers/net/wireless/realtek/rtw88/debug.h
411 +++ b/drivers/net/wireless/realtek/rtw88/debug.h
412 @@ -34,11 +34,13 @@ enum rtw_debug_mask {
413 #ifdef CPTCFG_RTW88_DEBUGFS
415 void rtw_debugfs_init(struct rtw_dev *rtwdev);
416 +void rtw_debugfs_deinit(struct rtw_dev *rtwdev);
417 void rtw_debugfs_get_simple_phy_info(struct seq_file *m);
421 static inline void rtw_debugfs_init(struct rtw_dev *rtwdev) {}
422 +static inline void rtw_debugfs_deinit(struct rtw_dev *rtwdev) {}
424 #endif /* CPTCFG_RTW88_DEBUGFS */
426 --- a/drivers/net/wireless/realtek/rtw88/main.c
427 +++ b/drivers/net/wireless/realtek/rtw88/main.c
428 @@ -2300,6 +2300,7 @@ void rtw_unregister_hw(struct rtw_dev *r
430 ieee80211_unregister_hw(hw);
431 rtw_unset_supported_band(hw, chip);
432 + rtw_debugfs_deinit(rtwdev);
434 EXPORT_SYMBOL(rtw_unregister_hw);
436 --- a/drivers/net/wireless/realtek/rtw88/main.h
437 +++ b/drivers/net/wireless/realtek/rtw88/main.h
438 @@ -50,6 +50,7 @@ extern const struct ieee80211_ops rtw_op
439 #define RTW_MAX_CHANNEL_NUM_5G 49
446 @@ -2053,7 +2054,7 @@ struct rtw_dev {
448 struct completion lps_leave_check;
450 - struct dentry *debugfs;
451 + struct rtw_debugfs *debugfs;