hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/net/wireless/ath/wil6210/debugfs.c
....@@ -1,18 +1,7 @@
1
+// SPDX-License-Identifier: ISC
12 /*
23 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4
- *
5
- * Permission to use, copy, modify, and/or distribute this software for any
6
- * purpose with or without fee is hereby granted, provided that the above
7
- * copyright notice and this permission notice appear in all copies.
8
- *
9
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
165 */
176
187 #include <linux/module.h>
....@@ -63,7 +52,9 @@
6352 &ring->va[idx].rx.enhanced;
6453 u16 buff_id = le16_to_cpu(rx_d->mac.buff_id);
6554
66
- has_skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb;
55
+ if (wil->rx_buff_mgmt.buff_arr &&
56
+ wil_val_in_range(buff_id, 0, wil->rx_buff_mgmt.size))
57
+ has_skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb;
6758 seq_printf(s, "%c", (has_skb) ? _h : _s);
6859 } else {
6960 struct wil_tx_enhanced_desc *d =
....@@ -71,9 +62,9 @@
7162 &ring->va[idx].tx.enhanced;
7263
7364 num_of_descs = (u8)d->mac.d[2];
74
- has_skb = ring->ctx[idx].skb;
65
+ has_skb = ring->ctx && ring->ctx[idx].skb;
7566 if (num_of_descs >= 1)
76
- seq_printf(s, "%c", ring->ctx[idx].skb ? _h : _s);
67
+ seq_printf(s, "%c", has_skb ? _h : _s);
7768 else
7869 /* num_of_descs == 0, it's a frag in a list of descs */
7970 seq_printf(s, "%c", has_skb ? 'h' : _s);
....@@ -84,7 +75,7 @@
8475 const char *name, struct wil_ring *ring,
8576 char _s, char _h)
8677 {
87
- void __iomem *x = wmi_addr(wil, ring->hwtail);
78
+ void __iomem *x;
8879 u32 v;
8980
9081 seq_printf(s, "RING %s = {\n", name);
....@@ -96,7 +87,21 @@
9687 else
9788 seq_printf(s, " swtail = %d\n", ring->swtail);
9889 seq_printf(s, " swhead = %d\n", ring->swhead);
90
+ if (wil->use_enhanced_dma_hw) {
91
+ int ring_id = ring->is_rx ?
92
+ WIL_RX_DESC_RING_ID : ring - wil->ring_tx;
93
+ /* SUBQ_CONS is a table of 32 entries, one for each Q pair.
94
+ * lower 16bits are for even ring_id and upper 16bits are for
95
+ * odd ring_id
96
+ */
97
+ x = wmi_addr(wil, RGF_DMA_SCM_SUBQ_CONS + 4 * (ring_id / 2));
98
+ v = readl_relaxed(x);
99
+
100
+ v = (ring_id % 2 ? (v >> 16) : (v & 0xffff));
101
+ seq_printf(s, " hwhead = %u\n", v);
102
+ }
99103 seq_printf(s, " hwtail = [0x%08x] -> ", ring->hwtail);
104
+ x = wmi_addr(wil, ring->hwtail);
100105 if (x) {
101106 v = readl(x);
102107 seq_printf(s, "0x%08x = %d\n", v, v);
....@@ -124,7 +129,7 @@
124129 seq_puts(s, "}\n");
125130 }
126131
127
-static int wil_ring_debugfs_show(struct seq_file *s, void *data)
132
+static int ring_show(struct seq_file *s, void *data)
128133 {
129134 uint i;
130135 struct wil6210_priv *wil = s->private;
....@@ -162,7 +167,7 @@
162167
163168 snprintf(name, sizeof(name), "tx_%2d", i);
164169
165
- if (cid < WIL6210_MAX_CID)
170
+ if (cid < wil->max_assoc_sta)
166171 seq_printf(s,
167172 "\n%pM CID %d TID %d 1x%s BACK([%u] %u TU A%s) [%3d|%3d] idle %s\n",
168173 wil->sta[cid].addr, cid, tid,
....@@ -183,23 +188,12 @@
183188
184189 return 0;
185190 }
186
-
187
-static int wil_ring_seq_open(struct inode *inode, struct file *file)
188
-{
189
- return single_open(file, wil_ring_debugfs_show, inode->i_private);
190
-}
191
-
192
-static const struct file_operations fops_ring = {
193
- .open = wil_ring_seq_open,
194
- .release = single_release,
195
- .read = seq_read,
196
- .llseek = seq_lseek,
197
-};
191
+DEFINE_SHOW_ATTRIBUTE(ring);
198192
199193 static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil,
200194 struct wil_status_ring *sring)
201195 {
202
- void __iomem *x = wmi_addr(wil, sring->hwtail);
196
+ void __iomem *x;
203197 int sring_idx = sring - wil->srings;
204198 u32 v;
205199
....@@ -210,7 +204,19 @@
210204 seq_printf(s, " size = %d\n", sring->size);
211205 seq_printf(s, " elem_size = %zu\n", sring->elem_size);
212206 seq_printf(s, " swhead = %d\n", sring->swhead);
207
+ if (wil->use_enhanced_dma_hw) {
208
+ /* COMPQ_PROD is a table of 32 entries, one for each Q pair.
209
+ * lower 16bits are for even ring_id and upper 16bits are for
210
+ * odd ring_id
211
+ */
212
+ x = wmi_addr(wil, RGF_DMA_SCM_COMPQ_PROD + 4 * (sring_idx / 2));
213
+ v = readl_relaxed(x);
214
+
215
+ v = (sring_idx % 2 ? (v >> 16) : (v & 0xffff));
216
+ seq_printf(s, " hwhead = %u\n", v);
217
+ }
213218 seq_printf(s, " hwtail = [0x%08x] -> ", sring->hwtail);
219
+ x = wmi_addr(wil, sring->hwtail);
214220 if (x) {
215221 v = readl_relaxed(x);
216222 seq_printf(s, "0x%08x = %d\n", v, v);
....@@ -218,6 +224,8 @@
218224 seq_puts(s, "???\n");
219225 }
220226 seq_printf(s, " desc_rdy_pol = %d\n", sring->desc_rdy_pol);
227
+ seq_printf(s, " invalid_buff_id_cnt = %d\n",
228
+ sring->invalid_buff_id_cnt);
221229
222230 if (sring->va && (sring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) {
223231 uint i;
....@@ -240,7 +248,7 @@
240248 seq_puts(s, "}\n");
241249 }
242250
243
-static int wil_srings_debugfs_show(struct seq_file *s, void *data)
251
+static int srings_show(struct seq_file *s, void *data)
244252 {
245253 struct wil6210_priv *wil = s->private;
246254 int i = 0;
....@@ -251,18 +259,7 @@
251259
252260 return 0;
253261 }
254
-
255
-static int wil_srings_seq_open(struct inode *inode, struct file *file)
256
-{
257
- return single_open(file, wil_srings_debugfs_show, inode->i_private);
258
-}
259
-
260
-static const struct file_operations fops_srings = {
261
- .open = wil_srings_seq_open,
262
- .release = single_release,
263
- .read = seq_read,
264
- .llseek = seq_lseek,
265
-};
262
+DEFINE_SHOW_ATTRIBUTE(srings);
266263
267264 static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
268265 const char *prefix)
....@@ -279,6 +276,11 @@
279276 uint i;
280277
281278 wil_halp_vote(wil);
279
+
280
+ if (wil_mem_access_lock(wil)) {
281
+ wil_halp_unvote(wil);
282
+ return;
283
+ }
282284
283285 wil_memcpy_fromio_32(&r, off, sizeof(r));
284286 wil_mbox_ring_le2cpus(&r);
....@@ -345,10 +347,11 @@
345347 }
346348 out:
347349 seq_puts(s, "}\n");
350
+ wil_mem_access_unlock(wil);
348351 wil_halp_unvote(wil);
349352 }
350353
351
-static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
354
+static int mbox_show(struct seq_file *s, void *data)
352355 {
353356 struct wil6210_priv *wil = s->private;
354357 int ret;
....@@ -366,18 +369,7 @@
366369
367370 return 0;
368371 }
369
-
370
-static int wil_mbox_seq_open(struct inode *inode, struct file *file)
371
-{
372
- return single_open(file, wil_mbox_debugfs_show, inode->i_private);
373
-}
374
-
375
-static const struct file_operations fops_mbox = {
376
- .open = wil_mbox_seq_open,
377
- .release = single_release,
378
- .read = seq_read,
379
- .llseek = seq_lseek,
380
-};
372
+DEFINE_SHOW_ATTRIBUTE(mbox);
381373
382374 static int wil_debugfs_iomem_x32_set(void *data, u64 val)
383375 {
....@@ -390,7 +382,8 @@
390382 if (ret < 0)
391383 return ret;
392384
393
- writel(val, (void __iomem *)d->offset);
385
+ writel_relaxed(val, (void __iomem *)d->offset);
386
+
394387 wmb(); /* make sure write propagated to HW */
395388
396389 wil_pm_runtime_put(wil);
....@@ -416,27 +409,21 @@
416409 return 0;
417410 }
418411
419
-DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get,
420
- wil_debugfs_iomem_x32_set, "0x%08llx\n");
412
+DEFINE_DEBUGFS_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get,
413
+ wil_debugfs_iomem_x32_set, "0x%08llx\n");
421414
422
-static struct dentry *wil_debugfs_create_iomem_x32(const char *name,
423
- umode_t mode,
424
- struct dentry *parent,
425
- void *value,
426
- struct wil6210_priv *wil)
415
+static void wil_debugfs_create_iomem_x32(const char *name, umode_t mode,
416
+ struct dentry *parent, void *value,
417
+ struct wil6210_priv *wil)
427418 {
428
- struct dentry *file;
429419 struct wil_debugfs_iomem_data *data = &wil->dbg_data.data_arr[
430420 wil->dbg_data.iomem_data_count];
431421
432422 data->wil = wil;
433423 data->offset = value;
434424
435
- file = debugfs_create_file(name, mode, parent, data, &fops_iomem_x32);
436
- if (!IS_ERR_OR_NULL(file))
437
- wil->dbg_data.iomem_data_count++;
438
-
439
- return file;
425
+ debugfs_create_file_unsafe(name, mode, parent, data, &fops_iomem_x32);
426
+ wil->dbg_data.iomem_data_count++;
440427 }
441428
442429 static int wil_debugfs_ulong_set(void *data, u64 val)
....@@ -451,22 +438,15 @@
451438 return 0;
452439 }
453440
454
-DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get,
455
- wil_debugfs_ulong_set, "0x%llx\n");
456
-
457
-static struct dentry *wil_debugfs_create_ulong(const char *name, umode_t mode,
458
- struct dentry *parent,
459
- ulong *value)
460
-{
461
- return debugfs_create_file(name, mode, parent, value, &wil_fops_ulong);
462
-}
441
+DEFINE_DEBUGFS_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get,
442
+ wil_debugfs_ulong_set, "0x%llx\n");
463443
464444 /**
465445 * wil6210_debugfs_init_offset - create set of debugfs files
466
- * @wil - driver's context, used for printing
467
- * @dbg - directory on the debugfs, where files will be created
468
- * @base - base address used in address calculation
469
- * @tbl - table with file descriptions. Should be terminated with empty element.
446
+ * @wil: driver's context, used for printing
447
+ * @dbg: directory on the debugfs, where files will be created
448
+ * @base: base address used in address calculation
449
+ * @tbl: table with file descriptions. Should be terminated with empty element.
470450 *
471451 * Creates files accordingly to the @tbl.
472452 */
....@@ -477,37 +457,30 @@
477457 int i;
478458
479459 for (i = 0; tbl[i].name; i++) {
480
- struct dentry *f;
481
-
482460 switch (tbl[i].type) {
483461 case doff_u32:
484
- f = debugfs_create_u32(tbl[i].name, tbl[i].mode, dbg,
485
- base + tbl[i].off);
462
+ debugfs_create_u32(tbl[i].name, tbl[i].mode, dbg,
463
+ base + tbl[i].off);
486464 break;
487465 case doff_x32:
488
- f = debugfs_create_x32(tbl[i].name, tbl[i].mode, dbg,
489
- base + tbl[i].off);
466
+ debugfs_create_x32(tbl[i].name, tbl[i].mode, dbg,
467
+ base + tbl[i].off);
490468 break;
491469 case doff_ulong:
492
- f = wil_debugfs_create_ulong(tbl[i].name, tbl[i].mode,
493
- dbg, base + tbl[i].off);
470
+ debugfs_create_file_unsafe(tbl[i].name, tbl[i].mode,
471
+ dbg, base + tbl[i].off,
472
+ &wil_fops_ulong);
494473 break;
495474 case doff_io32:
496
- f = wil_debugfs_create_iomem_x32(tbl[i].name,
497
- tbl[i].mode, dbg,
498
- base + tbl[i].off,
499
- wil);
475
+ wil_debugfs_create_iomem_x32(tbl[i].name, tbl[i].mode,
476
+ dbg, base + tbl[i].off,
477
+ wil);
500478 break;
501479 case doff_u8:
502
- f = debugfs_create_u8(tbl[i].name, tbl[i].mode, dbg,
503
- base + tbl[i].off);
480
+ debugfs_create_u8(tbl[i].name, tbl[i].mode, dbg,
481
+ base + tbl[i].off);
504482 break;
505
- default:
506
- f = ERR_PTR(-EINVAL);
507483 }
508
- if (IS_ERR_OR_NULL(f))
509
- wil_err(wil, "Create file \"%s\": err %ld\n",
510
- tbl[i].name, PTR_ERR(f));
511484 }
512485 }
513486
....@@ -522,19 +495,14 @@
522495 {},
523496 };
524497
525
-static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
526
- const char *name,
527
- struct dentry *parent, u32 off)
498
+static void wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
499
+ const char *name, struct dentry *parent,
500
+ u32 off)
528501 {
529502 struct dentry *d = debugfs_create_dir(name, parent);
530503
531
- if (IS_ERR_OR_NULL(d))
532
- return -ENODEV;
533
-
534504 wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr + off,
535505 isr_off);
536
-
537
- return 0;
538506 }
539507
540508 static const struct dbg_off pseudo_isr_off[] = {
....@@ -544,18 +512,13 @@
544512 {},
545513 };
546514
547
-static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil,
548
- struct dentry *parent)
515
+static void wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil,
516
+ struct dentry *parent)
549517 {
550518 struct dentry *d = debugfs_create_dir("PSEUDO_ISR", parent);
551519
552
- if (IS_ERR_OR_NULL(d))
553
- return -ENODEV;
554
-
555520 wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr,
556521 pseudo_isr_off);
557
-
558
- return 0;
559522 }
560523
561524 static const struct dbg_off lgc_itr_cnt_off[] = {
....@@ -603,13 +566,9 @@
603566 struct dentry *d, *dtx, *drx;
604567
605568 d = debugfs_create_dir("ITR_CNT", parent);
606
- if (IS_ERR_OR_NULL(d))
607
- return -ENODEV;
608569
609570 dtx = debugfs_create_dir("TX", d);
610571 drx = debugfs_create_dir("RX", d);
611
- if (IS_ERR_OR_NULL(dtx) || IS_ERR_OR_NULL(drx))
612
- return -ENODEV;
613572
614573 wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr,
615574 lgc_itr_cnt_off);
....@@ -622,7 +581,7 @@
622581 return 0;
623582 }
624583
625
-static int wil_memread_debugfs_show(struct seq_file *s, void *data)
584
+static int memread_show(struct seq_file *s, void *data)
626585 {
627586 struct wil6210_priv *wil = s->private;
628587 void __iomem *a;
....@@ -632,6 +591,12 @@
632591 if (ret < 0)
633592 return ret;
634593
594
+ ret = wil_mem_access_lock(wil);
595
+ if (ret) {
596
+ wil_pm_runtime_put(wil);
597
+ return ret;
598
+ }
599
+
635600 a = wmi_buffer(wil, cpu_to_le32(mem_addr));
636601
637602 if (a)
....@@ -639,22 +604,12 @@
639604 else
640605 seq_printf(s, "[0x%08x] = INVALID\n", mem_addr);
641606
607
+ wil_mem_access_unlock(wil);
642608 wil_pm_runtime_put(wil);
643609
644610 return 0;
645611 }
646
-
647
-static int wil_memread_seq_open(struct inode *inode, struct file *file)
648
-{
649
- return single_open(file, wil_memread_debugfs_show, inode->i_private);
650
-}
651
-
652
-static const struct file_operations fops_memread = {
653
- .open = wil_memread_seq_open,
654
- .release = single_release,
655
- .read = seq_read,
656
- .llseek = seq_lseek,
657
-};
612
+DEFINE_SHOW_ATTRIBUTE(memread);
658613
659614 static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
660615 size_t count, loff_t *ppos)
....@@ -667,10 +622,6 @@
667622 void *buf;
668623 size_t unaligned_bytes, aligned_count, ret;
669624 int rc;
670
-
671
- if (test_bit(wil_status_suspending, wil_blob->wil->status) ||
672
- test_bit(wil_status_suspended, wil_blob->wil->status))
673
- return 0;
674625
675626 if (pos < 0)
676627 return -EINVAL;
....@@ -698,11 +649,19 @@
698649 return rc;
699650 }
700651
652
+ rc = wil_mem_access_lock(wil);
653
+ if (rc) {
654
+ kfree(buf);
655
+ wil_pm_runtime_put(wil);
656
+ return rc;
657
+ }
658
+
701659 wil_memcpy_fromio_32(buf, (const void __iomem *)
702660 wil_blob->blob.data + aligned_pos, aligned_count);
703661
704662 ret = copy_to_user(user_buf, buf + unaligned_bytes, count);
705663
664
+ wil_mem_access_unlock(wil);
706665 wil_pm_runtime_put(wil);
707666
708667 kfree(buf);
....@@ -772,6 +731,44 @@
772731 .open = simple_open,
773732 };
774733
734
+static ssize_t wil_write_file_rbufcap(struct file *file,
735
+ const char __user *buf,
736
+ size_t count, loff_t *ppos)
737
+{
738
+ struct wil6210_priv *wil = file->private_data;
739
+ int val;
740
+ int rc;
741
+
742
+ rc = kstrtoint_from_user(buf, count, 0, &val);
743
+ if (rc) {
744
+ wil_err(wil, "Invalid argument\n");
745
+ return rc;
746
+ }
747
+ /* input value: negative to disable, 0 to use system default,
748
+ * 1..ring size to set descriptor threshold
749
+ */
750
+ wil_info(wil, "%s RBUFCAP, descriptors threshold - %d\n",
751
+ val < 0 ? "Disabling" : "Enabling", val);
752
+
753
+ if (!wil->ring_rx.va || val > wil->ring_rx.size) {
754
+ wil_err(wil, "Invalid descriptors threshold, %d\n", val);
755
+ return -EINVAL;
756
+ }
757
+
758
+ rc = wmi_rbufcap_cfg(wil, val < 0 ? 0 : 1, val < 0 ? 0 : val);
759
+ if (rc) {
760
+ wil_err(wil, "RBUFCAP config failed: %d\n", rc);
761
+ return rc;
762
+ }
763
+
764
+ return count;
765
+}
766
+
767
+static const struct file_operations fops_rbufcap = {
768
+ .write = wil_write_file_rbufcap,
769
+ .open = simple_open,
770
+};
771
+
775772 /* block ack control, write:
776773 * - "add <ringid> <agg_size> <timeout>" to trigger ADDBA
777774 * - "del_tx <ringid> <reason>" to trigger DELBA for Tx side
....@@ -834,14 +831,14 @@
834831 "BACK: del_rx require at least 2 params\n");
835832 return -EINVAL;
836833 }
837
- if (p1 < 0 || p1 >= WIL6210_MAX_CID) {
834
+ if (p1 < 0 || p1 >= wil->max_assoc_sta) {
838835 wil_err(wil, "BACK: invalid CID %d\n", p1);
839836 return -EINVAL;
840837 }
841838 if (rc < 4)
842839 p3 = WLAN_REASON_QSTA_LEAVE_QBSS;
843840 sta = &wil->sta[p1];
844
- wmi_delba_rx(wil, sta->mid, mk_cidxtid(p1, p2), p3);
841
+ wmi_delba_rx(wil, sta->mid, p1, p2, p3);
845842 } else {
846843 wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd);
847844 return -EINVAL;
....@@ -933,9 +930,8 @@
933930 " - \"alloc <num descriptors> <descriptor_size>\" to allocate pmc\n"
934931 " - \"free\" to free memory allocated for pmc\n";
935932
936
- sprintf(text, "Last command status: %d\n\n%s",
937
- wil_pmc_last_cmd_status(wil),
938
- help);
933
+ snprintf(text, sizeof(text), "Last command status: %d\n\n%s",
934
+ wil_pmc_last_cmd_status(wil), help);
939935
940936 return simple_read_from_buffer(user_buf, count, ppos, text,
941937 strlen(text) + 1);
....@@ -951,6 +947,18 @@
951947 .open = simple_open,
952948 .read = wil_pmc_read,
953949 .llseek = wil_pmc_llseek,
950
+};
951
+
952
+static int wil_pmcring_seq_open(struct inode *inode, struct file *file)
953
+{
954
+ return single_open(file, wil_pmcring_read, inode->i_private);
955
+}
956
+
957
+static const struct file_operations fops_pmcring = {
958
+ .open = wil_pmcring_seq_open,
959
+ .release = single_release,
960
+ .read = seq_read,
961
+ .llseek = seq_lseek,
954962 };
955963
956964 /*---tx_mgmt---*/
....@@ -1002,20 +1010,14 @@
10021010 void *cmd;
10031011 int cmdlen = len - sizeof(struct wmi_cmd_hdr);
10041012 u16 cmdid;
1005
- int rc, rc1;
1013
+ int rc1;
10061014
1007
- if (cmdlen < 0)
1015
+ if (cmdlen < 0 || *ppos != 0)
10081016 return -EINVAL;
10091017
1010
- wmi = kmalloc(len, GFP_KERNEL);
1011
- if (!wmi)
1012
- return -ENOMEM;
1013
-
1014
- rc = simple_write_to_buffer(wmi, len, ppos, buf, len);
1015
- if (rc < 0) {
1016
- kfree(wmi);
1017
- return rc;
1018
- }
1018
+ wmi = memdup_user(buf, len);
1019
+ if (IS_ERR(wmi))
1020
+ return PTR_ERR(wmi);
10191021
10201022 cmd = (cmdlen > 0) ? &wmi[1] : NULL;
10211023 cmdid = le16_to_cpu(wmi->command_id);
....@@ -1025,7 +1027,7 @@
10251027
10261028 wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1);
10271029
1028
- return rc;
1030
+ return len;
10291031 }
10301032
10311033 static const struct file_operations fops_wmi = {
....@@ -1046,8 +1048,7 @@
10461048 if (nr_frags) {
10471049 seq_printf(s, " nr_frags = %d\n", nr_frags);
10481050 for (i = 0; i < nr_frags; i++) {
1049
- const struct skb_frag_struct *frag =
1050
- &skb_shinfo(skb)->frags[i];
1051
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
10511052
10521053 len = skb_frag_size(frag);
10531054 p = skb_frag_address_safe(frag);
....@@ -1058,7 +1059,7 @@
10581059 }
10591060
10601061 /*---------Tx/Rx descriptor------------*/
1061
-static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
1062
+static int txdesc_show(struct seq_file *s, void *data)
10621063 {
10631064 struct wil6210_priv *wil = s->private;
10641065 struct wil_ring *ring;
....@@ -1114,19 +1115,18 @@
11141115
11151116 if (wil->use_enhanced_dma_hw) {
11161117 if (tx) {
1117
- skb = ring->ctx[txdesc_idx].skb;
1118
- } else {
1118
+ skb = ring->ctx ? ring->ctx[txdesc_idx].skb : NULL;
1119
+ } else if (wil->rx_buff_mgmt.buff_arr) {
11191120 struct wil_rx_enhanced_desc *rx_d =
11201121 (struct wil_rx_enhanced_desc *)
11211122 &ring->va[txdesc_idx].rx.enhanced;
11221123 u16 buff_id = le16_to_cpu(rx_d->mac.buff_id);
11231124
11241125 if (!wil_val_in_range(buff_id, 0,
1125
- wil->rx_buff_mgmt.size)) {
1126
+ wil->rx_buff_mgmt.size))
11261127 seq_printf(s, "invalid buff_id %d\n", buff_id);
1127
- return 0;
1128
- }
1129
- skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb;
1128
+ else
1129
+ skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb;
11301130 }
11311131 } else {
11321132 skb = ring->ctx[txdesc_idx].skb;
....@@ -1151,26 +1151,15 @@
11511151
11521152 return 0;
11531153 }
1154
-
1155
-static int wil_txdesc_seq_open(struct inode *inode, struct file *file)
1156
-{
1157
- return single_open(file, wil_txdesc_debugfs_show, inode->i_private);
1158
-}
1159
-
1160
-static const struct file_operations fops_txdesc = {
1161
- .open = wil_txdesc_seq_open,
1162
- .release = single_release,
1163
- .read = seq_read,
1164
- .llseek = seq_lseek,
1165
-};
1154
+DEFINE_SHOW_ATTRIBUTE(txdesc);
11661155
11671156 /*---------Tx/Rx status message------------*/
1168
-static int wil_status_msg_debugfs_show(struct seq_file *s, void *data)
1157
+static int status_msg_show(struct seq_file *s, void *data)
11691158 {
11701159 struct wil6210_priv *wil = s->private;
11711160 int sring_idx = dbg_sring_index;
11721161 struct wil_status_ring *sring;
1173
- bool tx = sring_idx == wil->tx_sring_idx ? 1 : 0;
1162
+ bool tx;
11741163 u32 status_msg_idx = dbg_status_msg_index;
11751164 u32 *u;
11761165
....@@ -1180,6 +1169,7 @@
11801169 }
11811170
11821171 sring = &wil->srings[sring_idx];
1172
+ tx = !sring->is_rx;
11831173
11841174 if (!sring->va) {
11851175 seq_printf(s, "No %cX status ring\n", tx ? 'T' : 'R');
....@@ -1207,19 +1197,7 @@
12071197
12081198 return 0;
12091199 }
1210
-
1211
-static int wil_status_msg_seq_open(struct inode *inode, struct file *file)
1212
-{
1213
- return single_open(file, wil_status_msg_debugfs_show,
1214
- inode->i_private);
1215
-}
1216
-
1217
-static const struct file_operations fops_status_msg = {
1218
- .open = wil_status_msg_seq_open,
1219
- .release = single_release,
1220
- .read = seq_read,
1221
- .llseek = seq_lseek,
1222
-};
1200
+DEFINE_SHOW_ATTRIBUTE(status_msg);
12231201
12241202 static int wil_print_rx_buff(struct seq_file *s, struct list_head *lh)
12251203 {
....@@ -1237,7 +1215,7 @@
12371215 return i;
12381216 }
12391217
1240
-static int wil_rx_buff_mgmt_debugfs_show(struct seq_file *s, void *data)
1218
+static int rx_buff_mgmt_show(struct seq_file *s, void *data)
12411219 {
12421220 struct wil6210_priv *wil = s->private;
12431221 struct wil_rx_buff_mgmt *rbm = &wil->rx_buff_mgmt;
....@@ -1262,19 +1240,7 @@
12621240
12631241 return 0;
12641242 }
1265
-
1266
-static int wil_rx_buff_mgmt_seq_open(struct inode *inode, struct file *file)
1267
-{
1268
- return single_open(file, wil_rx_buff_mgmt_debugfs_show,
1269
- inode->i_private);
1270
-}
1271
-
1272
-static const struct file_operations fops_rx_buff_mgmt = {
1273
- .open = wil_rx_buff_mgmt_seq_open,
1274
- .release = single_release,
1275
- .read = seq_read,
1276
- .llseek = seq_lseek,
1277
-};
1243
+DEFINE_SHOW_ATTRIBUTE(rx_buff_mgmt);
12781244
12791245 /*---------beamforming------------*/
12801246 static char *wil_bfstatus_str(u32 status)
....@@ -1304,7 +1270,7 @@
13041270 return true;
13051271 }
13061272
1307
-static int wil_bf_debugfs_show(struct seq_file *s, void *data)
1273
+static int bf_show(struct seq_file *s, void *data)
13081274 {
13091275 int rc;
13101276 int i;
....@@ -1320,14 +1286,14 @@
13201286
13211287 memset(&reply, 0, sizeof(reply));
13221288
1323
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1289
+ for (i = 0; i < wil->max_assoc_sta; i++) {
13241290 u32 status;
13251291
13261292 cmd.cid = i;
13271293 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid,
13281294 &cmd, sizeof(cmd),
13291295 WMI_NOTIFY_REQ_DONE_EVENTID, &reply,
1330
- sizeof(reply), 20);
1296
+ sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS);
13311297 /* if reply is all-0, ignore this CID */
13321298 if (rc || is_all_zeros(&reply.evt, sizeof(reply.evt)))
13331299 continue;
....@@ -1358,25 +1324,14 @@
13581324 }
13591325 return 0;
13601326 }
1361
-
1362
-static int wil_bf_seq_open(struct inode *inode, struct file *file)
1363
-{
1364
- return single_open(file, wil_bf_debugfs_show, inode->i_private);
1365
-}
1366
-
1367
-static const struct file_operations fops_bf = {
1368
- .open = wil_bf_seq_open,
1369
- .release = single_release,
1370
- .read = seq_read,
1371
- .llseek = seq_lseek,
1372
-};
1327
+DEFINE_SHOW_ATTRIBUTE(bf);
13731328
13741329 /*---------temp------------*/
13751330 static void print_temp(struct seq_file *s, const char *prefix, s32 t)
13761331 {
13771332 switch (t) {
13781333 case 0:
1379
- case ~(u32)0:
1334
+ case WMI_INVALID_TEMPERATURE:
13801335 seq_printf(s, "%s N/A\n", prefix);
13811336 break;
13821337 default:
....@@ -1386,61 +1341,63 @@
13861341 }
13871342 }
13881343
1389
-static int wil_temp_debugfs_show(struct seq_file *s, void *data)
1344
+static int temp_show(struct seq_file *s, void *data)
13901345 {
13911346 struct wil6210_priv *wil = s->private;
1392
- s32 t_m, t_r;
1393
- int rc = wmi_get_temperature(wil, &t_m, &t_r);
1347
+ int rc, i;
13941348
1395
- if (rc) {
1396
- seq_puts(s, "Failed\n");
1397
- return 0;
1349
+ if (test_bit(WMI_FW_CAPABILITY_TEMPERATURE_ALL_RF,
1350
+ wil->fw_capabilities)) {
1351
+ struct wmi_temp_sense_all_done_event sense_all_evt;
1352
+
1353
+ wil_dbg_misc(wil,
1354
+ "WMI_FW_CAPABILITY_TEMPERATURE_ALL_RF is supported");
1355
+ rc = wmi_get_all_temperatures(wil, &sense_all_evt);
1356
+ if (rc) {
1357
+ seq_puts(s, "Failed\n");
1358
+ return 0;
1359
+ }
1360
+ print_temp(s, "T_mac =",
1361
+ le32_to_cpu(sense_all_evt.baseband_t1000));
1362
+ seq_printf(s, "Connected RFs [0x%08x]\n",
1363
+ sense_all_evt.rf_bitmap);
1364
+ for (i = 0; i < WMI_MAX_XIF_PORTS_NUM; i++) {
1365
+ seq_printf(s, "RF[%d] = ", i);
1366
+ print_temp(s, "",
1367
+ le32_to_cpu(sense_all_evt.rf_t1000[i]));
1368
+ }
1369
+ } else {
1370
+ s32 t_m, t_r;
1371
+
1372
+ wil_dbg_misc(wil,
1373
+ "WMI_FW_CAPABILITY_TEMPERATURE_ALL_RF is not supported");
1374
+ rc = wmi_get_temperature(wil, &t_m, &t_r);
1375
+ if (rc) {
1376
+ seq_puts(s, "Failed\n");
1377
+ return 0;
1378
+ }
1379
+ print_temp(s, "T_mac =", t_m);
1380
+ print_temp(s, "T_radio =", t_r);
13981381 }
1399
-
1400
- print_temp(s, "T_mac =", t_m);
1401
- print_temp(s, "T_radio =", t_r);
1402
-
14031382 return 0;
14041383 }
1405
-
1406
-static int wil_temp_seq_open(struct inode *inode, struct file *file)
1407
-{
1408
- return single_open(file, wil_temp_debugfs_show, inode->i_private);
1409
-}
1410
-
1411
-static const struct file_operations fops_temp = {
1412
- .open = wil_temp_seq_open,
1413
- .release = single_release,
1414
- .read = seq_read,
1415
- .llseek = seq_lseek,
1416
-};
1384
+DEFINE_SHOW_ATTRIBUTE(temp);
14171385
14181386 /*---------freq------------*/
1419
-static int wil_freq_debugfs_show(struct seq_file *s, void *data)
1387
+static int freq_show(struct seq_file *s, void *data)
14201388 {
14211389 struct wil6210_priv *wil = s->private;
14221390 struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr;
1423
- u16 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0;
1391
+ u32 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0;
14241392
14251393 seq_printf(s, "Freq = %d\n", freq);
14261394
14271395 return 0;
14281396 }
1429
-
1430
-static int wil_freq_seq_open(struct inode *inode, struct file *file)
1431
-{
1432
- return single_open(file, wil_freq_debugfs_show, inode->i_private);
1433
-}
1434
-
1435
-static const struct file_operations fops_freq = {
1436
- .open = wil_freq_seq_open,
1437
- .release = single_release,
1438
- .read = seq_read,
1439
- .llseek = seq_lseek,
1440
-};
1397
+DEFINE_SHOW_ATTRIBUTE(freq);
14411398
14421399 /*---------link------------*/
1443
-static int wil_link_debugfs_show(struct seq_file *s, void *data)
1400
+static int link_show(struct seq_file *s, void *data)
14441401 {
14451402 struct wil6210_priv *wil = s->private;
14461403 struct station_info *sinfo;
....@@ -1450,7 +1407,7 @@
14501407 if (!sinfo)
14511408 return -ENOMEM;
14521409
1453
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1410
+ for (i = 0; i < wil->max_assoc_sta; i++) {
14541411 struct wil_sta_info *p = &wil->sta[i];
14551412 char *status = "unknown";
14561413 struct wil6210_vif *vif;
....@@ -1474,7 +1431,7 @@
14741431 if (p->status != wil_sta_connected)
14751432 continue;
14761433
1477
- vif = (mid < wil->max_vifs) ? wil->vifs[mid] : NULL;
1434
+ vif = (mid < GET_MAX_VIFS(wil)) ? wil->vifs[mid] : NULL;
14781435 if (vif) {
14791436 rc = wil_cid_fill_sinfo(vif, i, sinfo);
14801437 if (rc)
....@@ -1492,21 +1449,10 @@
14921449 kfree(sinfo);
14931450 return rc;
14941451 }
1495
-
1496
-static int wil_link_seq_open(struct inode *inode, struct file *file)
1497
-{
1498
- return single_open(file, wil_link_debugfs_show, inode->i_private);
1499
-}
1500
-
1501
-static const struct file_operations fops_link = {
1502
- .open = wil_link_seq_open,
1503
- .release = single_release,
1504
- .read = seq_read,
1505
- .llseek = seq_lseek,
1506
-};
1452
+DEFINE_SHOW_ATTRIBUTE(link);
15071453
15081454 /*---------info------------*/
1509
-static int wil_info_debugfs_show(struct seq_file *s, void *data)
1455
+static int info_show(struct seq_file *s, void *data)
15101456 {
15111457 struct wil6210_priv *wil = s->private;
15121458 struct net_device *ndev = wil->main_ndev;
....@@ -1541,18 +1487,7 @@
15411487 #undef CHECK_QSTATE
15421488 return 0;
15431489 }
1544
-
1545
-static int wil_info_seq_open(struct inode *inode, struct file *file)
1546
-{
1547
- return single_open(file, wil_info_debugfs_show, inode->i_private);
1548
-}
1549
-
1550
-static const struct file_operations fops_info = {
1551
- .open = wil_info_seq_open,
1552
- .release = single_release,
1553
- .read = seq_read,
1554
- .llseek = seq_lseek,
1555
-};
1490
+DEFINE_SHOW_ATTRIBUTE(info);
15561491
15571492 /*---------recovery------------*/
15581493 /* mode = [manual|auto]
....@@ -1668,17 +1603,18 @@
16681603 seq_puts(s, "\n");
16691604 }
16701605
1671
-static int wil_sta_debugfs_show(struct seq_file *s, void *data)
1606
+static int sta_show(struct seq_file *s, void *data)
16721607 __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
16731608 {
16741609 struct wil6210_priv *wil = s->private;
16751610 int i, tid, mcs;
16761611
1677
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1612
+ for (i = 0; i < wil->max_assoc_sta; i++) {
16781613 struct wil_sta_info *p = &wil->sta[i];
16791614 char *status = "unknown";
16801615 u8 aid = 0;
16811616 u8 mid;
1617
+ bool sta_connected = false;
16821618
16831619 switch (p->status) {
16841620 case wil_sta_unused:
....@@ -1693,8 +1629,20 @@
16931629 break;
16941630 }
16951631 mid = (p->status != wil_sta_unused) ? p->mid : U8_MAX;
1696
- seq_printf(s, "[%d] %pM %s MID %d AID %d\n", i, p->addr, status,
1697
- mid, aid);
1632
+ if (mid < GET_MAX_VIFS(wil)) {
1633
+ struct wil6210_vif *vif = wil->vifs[mid];
1634
+
1635
+ if (vif->wdev.iftype == NL80211_IFTYPE_STATION &&
1636
+ p->status == wil_sta_connected)
1637
+ sta_connected = true;
1638
+ }
1639
+ /* print roam counter only for connected stations */
1640
+ if (sta_connected)
1641
+ seq_printf(s, "[%d] %pM connected (roam counter %d) MID %d AID %d\n",
1642
+ i, p->addr, p->stats.ft_roams, mid, aid);
1643
+ else
1644
+ seq_printf(s, "[%d] %pM %s MID %d AID %d\n", i,
1645
+ p->addr, status, mid, aid);
16981646
16991647 if (p->status == wil_sta_connected) {
17001648 spin_lock_bh(&p->tid_rx_lock);
....@@ -1737,20 +1685,9 @@
17371685
17381686 return 0;
17391687 }
1688
+DEFINE_SHOW_ATTRIBUTE(sta);
17401689
1741
-static int wil_sta_seq_open(struct inode *inode, struct file *file)
1742
-{
1743
- return single_open(file, wil_sta_debugfs_show, inode->i_private);
1744
-}
1745
-
1746
-static const struct file_operations fops_sta = {
1747
- .open = wil_sta_seq_open,
1748
- .release = single_release,
1749
- .read = seq_read,
1750
- .llseek = seq_lseek,
1751
-};
1752
-
1753
-static int wil_mids_debugfs_show(struct seq_file *s, void *data)
1690
+static int mids_show(struct seq_file *s, void *data)
17541691 {
17551692 struct wil6210_priv *wil = s->private;
17561693 struct wil6210_vif *vif;
....@@ -1758,7 +1695,7 @@
17581695 int i;
17591696
17601697 mutex_lock(&wil->vif_mutex);
1761
- for (i = 0; i < wil->max_vifs; i++) {
1698
+ for (i = 0; i < GET_MAX_VIFS(wil); i++) {
17621699 vif = wil->vifs[i];
17631700
17641701 if (vif) {
....@@ -1773,18 +1710,7 @@
17731710
17741711 return 0;
17751712 }
1776
-
1777
-static int wil_mids_seq_open(struct inode *inode, struct file *file)
1778
-{
1779
- return single_open(file, wil_mids_debugfs_show, inode->i_private);
1780
-}
1781
-
1782
-static const struct file_operations fops_mids = {
1783
- .open = wil_mids_seq_open,
1784
- .release = single_release,
1785
- .read = seq_read,
1786
- .llseek = seq_lseek,
1787
-};
1713
+DEFINE_SHOW_ATTRIBUTE(mids);
17881714
17891715 static int wil_tx_latency_debugfs_show(struct seq_file *s, void *data)
17901716 __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
....@@ -1792,7 +1718,7 @@
17921718 struct wil6210_priv *wil = s->private;
17931719 int i, bin;
17941720
1795
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1721
+ for (i = 0; i < wil->max_assoc_sta; i++) {
17961722 struct wil_sta_info *p = &wil->sta[i];
17971723 char *status = "unknown";
17981724 u8 aid = 0;
....@@ -1881,7 +1807,7 @@
18811807 size_t sz = sizeof(u64) * WIL_NUM_LATENCY_BINS;
18821808
18831809 wil->tx_latency_res = val;
1884
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1810
+ for (i = 0; i < wil->max_assoc_sta; i++) {
18851811 struct wil_sta_info *sta = &wil->sta[i];
18861812
18871813 kfree(sta->tx_latency_bins);
....@@ -1966,7 +1892,7 @@
19661892 }
19671893
19681894 seq_printf(s, "TSF %lld\n", vif->fw_stats_tsf);
1969
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1895
+ for (i = 0; i < wil->max_assoc_sta; i++) {
19701896 if (wil->sta[i].status == wil_sta_unused)
19711897 continue;
19721898 if (wil->sta[i].mid != vif->mid)
....@@ -1990,7 +1916,7 @@
19901916 /* iterate over all MIDs and show per-cid statistics. Then show the
19911917 * global statistics
19921918 */
1993
- for (i = 0; i < wil->max_vifs; i++) {
1919
+ for (i = 0; i < GET_MAX_VIFS(wil); i++) {
19941920 vif = wil->vifs[i];
19951921
19961922 seq_printf(s, "MID %d ", i);
....@@ -2046,7 +1972,7 @@
20461972 if (rc)
20471973 return rc;
20481974
2049
- for (i = 0; i < wil->max_vifs; i++) {
1975
+ for (i = 0; i < GET_MAX_VIFS(wil); i++) {
20501976 vif = wil->vifs[i];
20511977 if (!vif)
20521978 continue;
....@@ -2428,23 +2354,24 @@
24282354 umode_t mode;
24292355 const struct file_operations *fops;
24302356 } dbg_files[] = {
2431
- {"mbox", 0444, &fops_mbox},
2432
- {"rings", 0444, &fops_ring},
2433
- {"stations", 0444, &fops_sta},
2434
- {"mids", 0444, &fops_mids},
2435
- {"desc", 0444, &fops_txdesc},
2436
- {"bf", 0444, &fops_bf},
2437
- {"mem_val", 0644, &fops_memread},
2357
+ {"mbox", 0444, &mbox_fops},
2358
+ {"rings", 0444, &ring_fops},
2359
+ {"stations", 0444, &sta_fops},
2360
+ {"mids", 0444, &mids_fops},
2361
+ {"desc", 0444, &txdesc_fops},
2362
+ {"bf", 0444, &bf_fops},
2363
+ {"mem_val", 0644, &memread_fops},
24382364 {"rxon", 0244, &fops_rxon},
24392365 {"tx_mgmt", 0244, &fops_txmgmt},
24402366 {"wmi_send", 0244, &fops_wmi},
24412367 {"back", 0644, &fops_back},
24422368 {"pmccfg", 0644, &fops_pmccfg},
24432369 {"pmcdata", 0444, &fops_pmcdata},
2444
- {"temp", 0444, &fops_temp},
2445
- {"freq", 0444, &fops_freq},
2446
- {"link", 0444, &fops_link},
2447
- {"info", 0444, &fops_info},
2370
+ {"pmcring", 0444, &fops_pmcring},
2371
+ {"temp", 0444, &temp_fops},
2372
+ {"freq", 0444, &freq_fops},
2373
+ {"link", 0444, &link_fops},
2374
+ {"info", 0444, &info_fops},
24482375 {"recovery", 0644, &fops_recovery},
24492376 {"led_cfg", 0644, &fops_led_cfg},
24502377 {"led_blink_time", 0644, &fops_led_blink_time},
....@@ -2452,12 +2379,13 @@
24522379 {"fw_version", 0444, &fops_fw_version},
24532380 {"suspend_stats", 0644, &fops_suspend_stats},
24542381 {"compressed_rx_status", 0644, &fops_compressed_rx_status},
2455
- {"srings", 0444, &fops_srings},
2456
- {"status_msg", 0444, &fops_status_msg},
2457
- {"rx_buff_mgmt", 0444, &fops_rx_buff_mgmt},
2382
+ {"srings", 0444, &srings_fops},
2383
+ {"status_msg", 0444, &status_msg_fops},
2384
+ {"rx_buff_mgmt", 0444, &rx_buff_mgmt_fops},
24582385 {"tx_latency", 0644, &fops_tx_latency},
24592386 {"link_stats", 0644, &fops_link_stats},
24602387 {"link_stats_global", 0644, &fops_link_stats_global},
2388
+ {"rbufcap", 0244, &fops_rbufcap},
24612389 };
24622390
24632391 static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
....@@ -2516,6 +2444,7 @@
25162444 {"RGF_MAC_MTRL_COUNTER_0", 0444, HOSTADDR(RGF_MAC_MTRL_COUNTER_0),
25172445 doff_io32},
25182446 {"RGF_USER_USAGE_1", 0444, HOSTADDR(RGF_USER_USAGE_1), doff_io32},
2447
+ {"RGF_USER_USAGE_2", 0444, HOSTADDR(RGF_USER_USAGE_2), doff_io32},
25192448 {},
25202449 };
25212450
....@@ -2527,6 +2456,7 @@
25272456 {"led_polarity", 0644, (ulong)&led_polarity, doff_u8},
25282457 {"status_index", 0644, (ulong)&dbg_status_msg_index, doff_u32},
25292458 {"sring_index", 0644, (ulong)&dbg_sring_index, doff_u32},
2459
+ {"drop_if_ring_full", 0644, (ulong)&drop_if_ring_full, doff_u8},
25302460 {},
25312461 };
25322462
....@@ -2580,7 +2510,7 @@
25802510 wil->debug = NULL;
25812511
25822512 kfree(wil->dbg_data.data_arr);
2583
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++)
2513
+ for (i = 0; i < wil->max_assoc_sta; i++)
25842514 kfree(wil->sta[i].tx_latency_bins);
25852515
25862516 /* free pmc memory without sending command to fw, as it will