blob: 42650f364a267f5048ad97cb220936012c02cedb [file] [log] [blame]
developer43a264f2024-03-26 14:09:54 +08001From f55be6f6596db120b2e48a7c87fcacf9d9df25ef Mon Sep 17 00:00:00 2001
2From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
3Date: Thu, 11 Jan 2024 08:55:13 +0800
4Subject: [PATCH 2027/2032] mtk: wifi: mt76: mt7992: add support to enable
5 index FW log for ConsysPlanet
6
7Add support to enable and record index FW log, which is the input for ConsysPlanet, via mt76-test command.
8
9Usage:
101. Foreground logging
11 1) Start: mt76-test phy0 idxlog
12 2) Stop: Ctrl + C
132. Background logging
14 1) Start: mt76-test phy0 idxlog &
15 2) Stop: killall mt76-test
163. Logging with FW Parser
17 1) Start Ethernet recording of FW Parser.
18 2) Start: mt76-test phy0 idxlog <PC's IP Address>
19 3) Stop: Ctrl + C
20 4) Stop FW Parser.
21
22Log Files
23- FW Log: FW text message
24 - Location: /tmp/log/clog_(timestamp)/WIFI_FW_(timestamp).clog
25- Driver Log: log message printed at driver layer
26 - Location: /tmp/log/clog_(timestamp)/WIFI_KERNEL_(timestamp).clog
27
28Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
29---
30 mt7996/debugfs.c | 90 +++++++++++++++++--
31 mt7996/mac.c | 10 ++-
32 mt7996/mcu.c | 34 +++++++-
33 mt7996/mcu.h | 4 +-
34 mt7996/mt7996.h | 3 +
35 tools/fwlog.c | 218 ++++++++++++++++++++++++++++++++++------------
36 tools/main.c | 2 +
37 tools/mt76-test.h | 3 +
38 8 files changed, 295 insertions(+), 69 deletions(-)
39
40diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
41index 6ccf0827..c236ec98 100644
42--- a/mt7996/debugfs.c
43+++ b/mt7996/debugfs.c
44@@ -425,8 +425,8 @@ create_buf_file_cb(const char *filename, struct dentry *parent, umode_t mode,
45 {
46 struct dentry *f;
47
48- f = debugfs_create_file("fwlog_data", mode, parent, buf,
49- &relay_file_operations);
50+ f = debugfs_create_file(filename[0] == 'f' ? "fwlog_data" : "idxlog_data",
51+ mode, parent, buf, &relay_file_operations);
52 if (IS_ERR(f))
53 return NULL;
54
55@@ -517,6 +517,53 @@ mt7996_fw_debug_bin_get(void *data, u64 *val)
56 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_bin, mt7996_fw_debug_bin_get,
57 mt7996_fw_debug_bin_set, "%lld\n");
58
59+static int
60+mt7996_idxlog_enable_get(void *data, u64 *val)
61+{
62+ struct mt7996_dev *dev = data;
63+
64+ *val = dev->idxlog_enable;
65+
66+ return 0;
67+}
68+
69+static int
70+mt7996_idxlog_enable_set(void *data, u64 val)
71+{
72+ static struct rchan_callbacks relay_cb = {
73+ .create_buf_file = create_buf_file_cb,
74+ .remove_buf_file = remove_buf_file_cb,
75+ };
76+ struct mt7996_dev *dev = data;
77+
78+ if (dev->idxlog_enable == !!val)
79+ return 0;
80+
81+ if (!dev->relay_idxlog) {
82+ dev->relay_idxlog = relay_open("idxlog_data", dev->debugfs_dir,
83+ 1500, 512, &relay_cb, NULL);
84+ if (!dev->relay_idxlog)
85+ return -ENOMEM;
86+ }
87+
88+ dev->idxlog_enable = !!val;
89+
90+ if (val) {
91+ int ret = mt7996_mcu_fw_time_sync(&dev->mt76);
92+ if (ret)
93+ return ret;
94+
95+ /* Reset relay channel only when it is not being written to. */
96+ relay_reset(dev->relay_idxlog);
97+ }
98+
99+ return mt7996_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM,
100+ val ? MCU_FW_LOG_RELAY_IDX : 0);
101+}
102+
103+DEFINE_DEBUGFS_ATTRIBUTE(fops_idxlog_enable, mt7996_idxlog_enable_get,
104+ mt7996_idxlog_enable_set, "%llu\n");
105+
106 static int
107 mt7996_fw_util_wa_show(struct seq_file *file, void *data)
108 {
109@@ -1037,6 +1084,7 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
110 debugfs_create_file("fw_debug_wm", 0600, dir, dev, &fops_fw_debug_wm);
111 debugfs_create_file("fw_debug_wa", 0600, dir, dev, &fops_fw_debug_wa);
112 debugfs_create_file("fw_debug_bin", 0600, dir, dev, &fops_fw_debug_bin);
113+ debugfs_create_file("idxlog_enable", 0600, dir, dev, &fops_idxlog_enable);
114 /* TODO: wm fw cpu utilization */
115 debugfs_create_file("fw_util_wa", 0400, dir, dev,
116 &mt7996_fw_util_wa_fops);
117@@ -1103,6 +1151,32 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
118 spin_unlock_irqrestore(&lock, flags);
119 }
120
121+static void
122+mt7996_debugfs_write_idxlog(struct mt7996_dev *dev, const void *data, int len)
123+{
124+ static DEFINE_SPINLOCK(lock);
125+ unsigned long flags;
126+ void *dest;
127+
128+ if (!dev->relay_idxlog)
129+ return;
130+
131+ spin_lock_irqsave(&lock, flags);
132+
133+ dest = relay_reserve(dev->relay_idxlog, len + 4);
134+ if (!dest)
135+ dev_err(dev->mt76.dev, "Failed to reserve slot in %s\n",
136+ dev->relay_idxlog->base_filename);
137+ else {
138+ *(u32 *)dest = len;
139+ dest += 4;
140+ memcpy(dest, data, len);
141+ relay_flush(dev->relay_idxlog);
142+ }
143+
144+ spin_unlock_irqrestore(&lock, flags);
145+}
146+
147 void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int len)
148 {
149 struct {
150@@ -1127,11 +1201,15 @@ void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int
151
152 bool mt7996_debugfs_rx_log(struct mt7996_dev *dev, const void *data, int len)
153 {
154- if (get_unaligned_le32(data) != FW_BIN_LOG_MAGIC)
155- return false;
156+ bool is_fwlog = get_unaligned_le32(data) == FW_BIN_LOG_MAGIC;
157
158- if (dev->relay_fwlog)
159- mt7996_debugfs_write_fwlog(dev, NULL, 0, data, len);
160+ if (is_fwlog) {
161+ if (dev->relay_fwlog)
162+ mt7996_debugfs_write_fwlog(dev, NULL, 0, data, len);
163+ } else if (dev->relay_idxlog)
164+ mt7996_debugfs_write_idxlog(dev, data, len);
165+ else
166+ return false;
167
168 return true;
169 }
170diff --git a/mt7996/mac.c b/mt7996/mac.c
171index 88e1fd14..c2a8e752 100644
172--- a/mt7996/mac.c
173+++ b/mt7996/mac.c
174@@ -2283,11 +2283,9 @@ void mt7996_mac_work(struct work_struct *work)
175 mutex_lock(&mdev->mutex);
176
177 mt76_update_survey(mphy);
178- if (++mphy->mac_work_count == 5) {
179+ if (++mphy->mac_work_count % 5 == 0) {
180 int i;
181
182- mphy->mac_work_count = 0;
183-
184 mt7996_mac_update_stats(phy);
185
186 /* Update DEV-wise information only in
187@@ -2306,6 +2304,12 @@ void mt7996_mac_work(struct work_struct *work)
188 if (mt7996_mcu_wa_cmd(phy->dev, MCU_WA_PARAM_CMD(QUERY), MCU_WA_PARAM_BSS_ACQ_PKT_CNT,
189 BSS_ACQ_PKT_CNT_BSS_BITMAP_ALL | BSS_ACQ_PKT_CNT_READ_CLR, 0))
190 dev_err(mdev->dev, "Failed to query per-AC-queue packet counts.\n");
191+
192+ if (mphy->mac_work_count == 100) {
193+ if (phy->dev->idxlog_enable && mt7996_mcu_fw_time_sync(mdev))
194+ dev_err(mdev->dev, "Failed to synchronize time with FW.\n");
195+ mphy->mac_work_count = 0;
196+ }
197 } else if (mt7996_band_valid(phy->dev, i) &&
198 test_bit(MT76_STATE_RUNNING, &mdev->phys[i]->state))
199 break;
200diff --git a/mt7996/mcu.c b/mt7996/mcu.c
201index 9e04ea2b..0cb4cfa5 100644
202--- a/mt7996/mcu.c
203+++ b/mt7996/mcu.c
204@@ -397,6 +397,7 @@ static void
205 mt7996_mcu_rx_log_message(struct mt7996_dev *dev, struct sk_buff *skb)
206 {
207 #define UNI_EVENT_FW_LOG_FORMAT 0
208+#define UNI_EVENT_FW_LOG_MEMORY 1
209 struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;
210 const char *data = (char *)&rxd[1] + 4, *type;
211 struct tlv *tlv = (struct tlv *)data;
212@@ -408,7 +409,8 @@ mt7996_mcu_rx_log_message(struct mt7996_dev *dev, struct sk_buff *skb)
213 goto out;
214 }
215
216- if (le16_to_cpu(tlv->tag) != UNI_EVENT_FW_LOG_FORMAT)
217+ if (le16_to_cpu(tlv->tag) != UNI_EVENT_FW_LOG_FORMAT &&
218+ le16_to_cpu(tlv->tag) != UNI_EVENT_FW_LOG_MEMORY)
219 return;
220
221 data += sizeof(*tlv) + 4;
222@@ -3444,6 +3446,36 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level)
223 sizeof(data), false);
224 }
225
226+int mt7996_mcu_fw_time_sync(struct mt76_dev *dev)
227+{
228+ struct {
229+ u8 _rsv[4];
230+
231+ __le16 tag;
232+ __le16 len;
233+ __le32 sec;
234+ __le32 usec;
235+ } data = {
236+ .tag = cpu_to_le16(UNI_WSYS_CONFIG_FW_TIME_SYNC),
237+ .len = cpu_to_le16(sizeof(data) - 4),
238+ };
239+ struct timespec64 ts;
240+ struct tm tm;
241+
242+ ktime_get_real_ts64(&ts);
243+ data.sec = cpu_to_le32((u32)ts.tv_sec);
244+ data.usec = cpu_to_le32((u32)(ts.tv_nsec / 1000));
245+
246+ /* Dump synchronized time for ConsysPlanet to parse. */
247+ time64_to_tm(ts.tv_sec, 0, &tm);
248+ dev_info(dev->dev, "%ld-%02d-%02d %02d:%02d:%02d.%ld UTC\n",
249+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
250+ tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec / 1000);
251+
252+ return mt76_mcu_send_msg(dev, MCU_WM_UNI_CMD(WSYS_CONFIG), &data,
253+ sizeof(data), true);
254+}
255+
256 static int mt7996_mcu_set_mwds(struct mt7996_dev *dev, bool enabled)
257 {
258 struct {
259diff --git a/mt7996/mcu.h b/mt7996/mcu.h
260index 7721a01b..826cf204 100644
261--- a/mt7996/mcu.h
262+++ b/mt7996/mcu.h
263@@ -357,7 +357,8 @@ enum {
264 MCU_FW_LOG_WM,
265 MCU_FW_LOG_WA,
266 MCU_FW_LOG_TO_HOST,
267- MCU_FW_LOG_RELAY = 16
268+ MCU_FW_LOG_RELAY = 16,
269+ MCU_FW_LOG_RELAY_IDX = 40
270 };
271
272 enum {
273@@ -949,6 +950,7 @@ enum {
274 UNI_WSYS_CONFIG_FW_LOG_CTRL,
275 UNI_WSYS_CONFIG_FW_DBG_CTRL,
276 UNI_CMD_CERT_CFG = 6,
277+ UNI_WSYS_CONFIG_FW_TIME_SYNC, /* UNI_CMD_FW_TIME_SYNC in FW */
278 };
279
280 enum {
281diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
282index f172eea2..10886cb1 100644
283--- a/mt7996/mt7996.h
284+++ b/mt7996/mt7996.h
285@@ -642,9 +642,11 @@ struct mt7996_dev {
286 u8 fw_debug_bin;
287 u16 fw_debug_seq;
288 bool fw_debug_muru_disable;
289+ bool idxlog_enable;
290
291 struct dentry *debugfs_dir;
292 struct rchan *relay_fwlog;
293+ struct rchan *relay_idxlog;
294
295 void *cal;
296 u32 cur_prek_offset;
297@@ -896,6 +898,7 @@ int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
298 int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
299 int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
300 int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
301+int mt7996_mcu_fw_time_sync(struct mt76_dev *dev);
302 int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
303 void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
304 void mt7996_mcu_exit(struct mt7996_dev *dev);
305diff --git a/tools/fwlog.c b/tools/fwlog.c
306index 3c6a61d7..0e2de2dc 100644
307--- a/tools/fwlog.c
308+++ b/tools/fwlog.c
309@@ -29,10 +29,9 @@ static const char *debugfs_path(const char *phyname, const char *file)
310 static int mt76_set_fwlog_en(const char *phyname, bool en, char *val)
311 {
312 FILE *f = fopen(debugfs_path(phyname, "fw_debug_bin"), "w");
313-
314 if (!f) {
315- fprintf(stderr, "Could not open fw_debug_bin file\n");
316- return 1;
317+ perror("fopen");
318+ return -1;
319 }
320
321 if (en && val)
322@@ -47,6 +46,21 @@ static int mt76_set_fwlog_en(const char *phyname, bool en, char *val)
323 return 0;
324 }
325
326+static int mt76_set_idxlog_enable(const char *phyname, bool enable)
327+{
328+ FILE *f = fopen(debugfs_path(phyname, "idxlog_enable"), "w");
329+ if (!f) {
330+ perror("fopen");
331+ return -1;
332+ }
333+
334+ fprintf(f, "%hhu", enable);
335+
336+ fclose(f);
337+
338+ return 0;
339+}
340+
341 int read_retry(int fd, void *buf, int len)
342 {
343 int out_len = 0;
344@@ -80,105 +94,193 @@ static void handle_signal(int sig)
345 done = true;
346 }
347
348-int mt76_fwlog(const char *phyname, int argc, char **argv)
349+static int mt76_log_socket(struct sockaddr_in *remote, char *ip)
350 {
351-#define BUF_SIZE 1504
352 struct sockaddr_in local = {
353 .sin_family = AF_INET,
354 .sin_addr.s_addr = INADDR_ANY,
355 };
356- struct sockaddr_in remote = {
357- .sin_family = AF_INET,
358- .sin_port = htons(55688),
359- };
360- char *buf = calloc(BUF_SIZE, sizeof(char));
361- int ret = 0;
362- /* int yes = 1; */
363- int s, fd;
364-
365- if (argc < 1) {
366- fprintf(stderr, "need destination address\n");
367- return 1;
368- }
369+ int s, ret;
370
371- if (!inet_aton(argv[0], &remote.sin_addr)) {
372- fprintf(stderr, "invalid destination address\n");
373- return 1;
374+ remote->sin_family = AF_INET;
375+ remote->sin_port = htons(55688);
376+ if (!inet_aton(ip, &remote->sin_addr)) {
377+ fprintf(stderr, "Invalid destination IP address: %s\n", ip);
378+ return -EINVAL;
379 }
380
381 s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
382 if (s < 0) {
383 perror("socket");
384- return 1;
385+ return s;
386 }
387
388- /* setsockopt(s, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes)); */
389- if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) {
390+ ret = bind(s, (struct sockaddr *)&local, sizeof(local));
391+ if (ret) {
392 perror("bind");
393- return 1;
394+ close(s);
395+ return ret;
396 }
397
398- if (mt76_set_fwlog_en(phyname, true, argv[1]))
399- return 1;
400+ return s;
401+}
402+
403+static int mt76_log_relay(int in_fd, int out_fd, struct sockaddr_in *remote)
404+{
405+ char *buf = malloc(FWLOG_BUF_SIZE);
406+ int ret = 0;
407
408- fd = open(debugfs_path(phyname, "fwlog_data"), O_RDONLY);
409- if (fd < 0) {
410- fprintf(stderr, "Could not open fwlog_data file: %s\n", strerror(errno));
411- ret = 1;
412- goto out;
413+ if (!buf) {
414+ perror("malloc");
415+ return -ENOMEM;
416 }
417
418 signal(SIGTERM, handle_signal);
419 signal(SIGINT, handle_signal);
420 signal(SIGQUIT, handle_signal);
421
422- while (1) {
423+ while (!done) {
424 struct pollfd pfd = {
425- .fd = fd,
426- .events = POLLIN | POLLHUP | POLLERR,
427+ .fd = in_fd,
428+ .events = POLLIN,
429 };
430 uint32_t len;
431- int r;
432-
433- if (done)
434- break;
435+ int rc;
436
437 poll(&pfd, 1, -1);
438
439- r = read_retry(fd, &len, sizeof(len));
440- if (r < 0)
441+ rc = read_retry(in_fd, &len, sizeof(len));
442+ if (rc < 0) {
443+ if (!done) {
444+ fprintf(stderr, "Failed to read relay file.\n");
445+ ret = -1;
446+ }
447 break;
448-
449- if (!r)
450+ }
451+ if (!rc)
452 continue;
453
454- if (len > BUF_SIZE) {
455- fprintf(stderr, "Length error: %d > %d\n", len, BUF_SIZE);
456- ret = 1;
457+ if (len > FWLOG_BUF_SIZE) {
458+ fprintf(stderr, "Log size was too large: %u bytes\n", len);
459+ ret = -ENOMEM;
460 break;
461 }
462
463- if (done)
464+ rc = read_retry(in_fd, buf, len);
465+ if (rc < 0) {
466+ if (!done) {
467+ fprintf(stderr, "Failed to read relay file.\n");
468+ ret = -1;
469+ }
470 break;
471-
472- r = read_retry(fd, buf, len);
473- if (done)
474+ }
475+ if (rc != len) {
476+ fprintf(stderr, "Expected log size: %u bytes\n", len);
477+ fprintf(stderr, "Read log size: %u bytes\n", rc);
478+ ret = -EIO;
479 break;
480+ }
481
482- if (r != len) {
483- fprintf(stderr, "Short read: %d < %d\n", r, len);
484- ret = 1;
485+ if (remote)
486+ rc = sendto(out_fd, buf, len, 0, (struct sockaddr *)remote, sizeof(*remote));
487+ else
488+ rc = write(out_fd, buf, len);
489+ if (rc < 0) {
490+ perror("sendto/write");
491+ ret = -1;
492 break;
493 }
494+ }
495+
496+ free(buf);
497+
498+ return ret;
499+}
500+
501+int mt76_fwlog(const char *phyname, int argc, char **argv)
502+{
503+ struct sockaddr_in remote;
504+ int in_fd, out_fd, ret;
505+
506+ if (argc < 1) {
507+ fprintf(stderr, "need destination address\n");
508+ return -EINVAL;
509+ }
510+
511+ out_fd = mt76_log_socket(&remote, argv[0]);
512+ if (out_fd < 0)
513+ return out_fd;
514+
515+ ret = mt76_set_fwlog_en(phyname, true, argv[1]);
516+ if (ret)
517+ goto close;
518
519- /* send buf */
520- sendto(s, buf, len, 0, (struct sockaddr *)&remote, sizeof(remote));
521+ in_fd = open(debugfs_path(phyname, "fwlog_data"), O_RDONLY);
522+ if (in_fd < 0) {
523+ perror("open");
524+ goto disable;
525 }
526
527- close(fd);
528+ if (mt76_log_relay(in_fd, out_fd, &remote))
529+ fprintf(stderr, "Failed to relay FW log.\n");
530
531-out:
532- mt76_set_fwlog_en(phyname, false, NULL);
533+ close(in_fd);
534+disable:
535+ ret = mt76_set_fwlog_en(phyname, false, NULL);
536+close:
537+ close(out_fd);
538+
539+ return ret;
540+}
541+
542+int mt76_idxlog(const char *phyname, int argc, char **argv)
543+{
544+#define IDXLOG_FILE_PATH "/tmp/log/WIFI_FW.clog"
545+ struct sockaddr_in remote;
546+ int in_fd, out_fd, ret;
547+
548+ if (argc) {
549+ out_fd = mt76_log_socket(&remote, argv[0]);
550+ if (out_fd < 0)
551+ return out_fd;
552+ } else {
553+ out_fd = open(IDXLOG_FILE_PATH, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR);
554+ if (out_fd < 0) {
555+ perror("open");
556+ return -1;
557+ }
558+ }
559+
560+ ret = mt76_set_idxlog_enable(phyname, true);
561+ if (ret)
562+ goto close;
563+
564+ in_fd = open(debugfs_path(phyname, "idxlog_data"), O_RDONLY);
565+ if (in_fd < 0) {
566+ perror("open");
567+ goto disable;
568+ }
569+
570+ if (mt76_log_relay(in_fd, out_fd, argc ? &remote : NULL))
571+ fprintf(stderr, "Failed to relay index log.\n");
572+
573+ close(in_fd);
574+disable:
575+ ret = mt76_set_idxlog_enable(phyname, false);
576+close:
577+ close(out_fd);
578+
579+ if (argc)
580+ system("timestamp=$(date +\"%y%m%d_%H%M%S\");"
581+ "clog_dir=/tmp/log/clog_${timestamp};"
582+ "mkdir ${clog_dir};"
583+ "dmesg > ${clog_dir}/WIFI_KERNEL_${timestamp}.clog");
584+ else
585+ system("timestamp=$(date +\"%y%m%d_%H%M%S\");"
586+ "clog_dir=/tmp/log/clog_${timestamp};"
587+ "mkdir ${clog_dir};"
588+ "mv /tmp/log/WIFI_FW.clog ${clog_dir}/WIFI_FW_${timestamp}.clog;"
589+ "dmesg > ${clog_dir}/WIFI_KERNEL_${timestamp}.clog");
590
591 return ret;
592 }
593diff --git a/tools/main.c b/tools/main.c
594index 699a9eea..e9e25567 100644
595--- a/tools/main.c
596+++ b/tools/main.c
597@@ -198,6 +198,8 @@ int main(int argc, char **argv)
598 ret = mt76_eeprom(phy, argc, argv);
599 else if (!strcmp(cmd, "fwlog"))
600 ret = mt76_fwlog(phyname, argc, argv);
601+ else if (!strcmp(cmd, "idxlog"))
602+ ret = mt76_idxlog(phyname, argc, argv);
603 else
604 usage();
605
606diff --git a/tools/mt76-test.h b/tools/mt76-test.h
607index d2fafa86..b9d508c5 100644
608--- a/tools/mt76-test.h
609+++ b/tools/mt76-test.h
610@@ -22,6 +22,8 @@
611 #define EEPROM_FILE_PATH_FMT "/tmp/mt76-test-%s"
612 #define EEPROM_PART_SIZE 20480
613
614+#define FWLOG_BUF_SIZE 1504
615+
616 struct nl_msg;
617 struct nlattr;
618
619@@ -61,5 +63,6 @@ extern unsigned char *eeprom_data;
620 void usage(void);
621 int mt76_eeprom(int phy, int argc, char **argv);
622 int mt76_fwlog(const char *phyname, int argc, char **argv);
623+int mt76_idxlog(const char *phyname, int argc, char **argv);
624
625 #endif
626--
6272.18.0
628