mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
tools: add support for sending firmware debug data via udp
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8)
|
||||
PROJECT(mt76-test C)
|
||||
ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3)
|
||||
|
||||
ADD_EXECUTABLE(mt76-test main.c fields.c eeprom.c)
|
||||
ADD_EXECUTABLE(mt76-test main.c fields.c eeprom.c fwlog.c)
|
||||
TARGET_LINK_LIBRARIES(mt76-test nl-tiny)
|
||||
|
||||
SET(CMAKE_INSTALL_PREFIX /usr)
|
||||
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
// SPDX-License-Identifier: ISC
|
||||
/* Copyright (C) 2022 Felix Fietkau <[email protected]> */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include "mt76-test.h"
|
||||
|
||||
bool done = false;
|
||||
|
||||
static const char *debugfs_path(const char *phyname, const char *file)
|
||||
{
|
||||
static char path[256];
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/kernel/debug/ieee80211/%s/mt76/%s", phyname, file);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static int mt76_set_fwlog_en(const char *phyname, bool en)
|
||||
{
|
||||
FILE *f = fopen(debugfs_path(phyname, "fw_debug_bin"), "w");
|
||||
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open fw_debug_bin file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(f, "7");
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_retry(int fd, void *buf, int len)
|
||||
{
|
||||
int out_len = 0;
|
||||
int r;
|
||||
|
||||
while (len > 0) {
|
||||
if (done)
|
||||
return -1;
|
||||
|
||||
r = read(fd, buf, len);
|
||||
if (r < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!r)
|
||||
return 0;
|
||||
|
||||
out_len += r;
|
||||
len -= r;
|
||||
buf += r;
|
||||
}
|
||||
|
||||
return out_len;
|
||||
}
|
||||
|
||||
static void handle_signal(int sig)
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
|
||||
int mt76_fwlog(const char *phyname, int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_in local = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = INADDR_ANY,
|
||||
};
|
||||
struct sockaddr_in remote = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons(55688),
|
||||
};
|
||||
char buf[1504];
|
||||
int ret = 0;
|
||||
int yes = 1;
|
||||
int s, fd;
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "need destination address\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!inet_aton(argv[0], &remote.sin_addr)) {
|
||||
fprintf(stderr, "invalid destination address\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (s < 0) {
|
||||
perror("socket");
|
||||
return 1;
|
||||
}
|
||||
|
||||
setsockopt(s, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
|
||||
if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) {
|
||||
perror("bind");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mt76_set_fwlog_en(phyname, true))
|
||||
return 1;
|
||||
|
||||
fd = open(debugfs_path(phyname, "fwlog_data"), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Could not open fwlog_data file: %s\n", strerror(errno));
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
signal(SIGTERM, handle_signal);
|
||||
signal(SIGINT, handle_signal);
|
||||
signal(SIGQUIT, handle_signal);
|
||||
|
||||
while (1) {
|
||||
struct pollfd pfd = {
|
||||
.fd = fd,
|
||||
.events = POLLIN | POLLHUP | POLLERR,
|
||||
};
|
||||
uint32_t len;
|
||||
int r;
|
||||
|
||||
if (done)
|
||||
break;
|
||||
|
||||
poll(&pfd, 1, -1);
|
||||
|
||||
r = read_retry(fd, &len, sizeof(len));
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
if (!r)
|
||||
continue;
|
||||
|
||||
if (len > sizeof(buf)) {
|
||||
fprintf(stderr, "Length error: %d > %d\n", len, (int)sizeof(buf));
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (done)
|
||||
break;
|
||||
|
||||
r = read_retry(fd, buf, len);
|
||||
if (done)
|
||||
break;
|
||||
|
||||
if (r != len) {
|
||||
fprintf(stderr, "Short read: %d < %d\n", r, len);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send buf */
|
||||
sendto(s, buf, len, 0, (struct sockaddr *)&remote, sizeof(remote));
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
out:
|
||||
mt76_set_fwlog_en(phyname, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+15
-2
@@ -2,7 +2,17 @@
|
||||
/* Copyright (C) 2020 Felix Fietkau <[email protected]> */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include "mt76-test.h"
|
||||
|
||||
struct unl unl;
|
||||
@@ -156,7 +166,7 @@ static int mt76_set(int phy, int argc, char **argv)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *cmd;
|
||||
const char *cmd, *phyname;
|
||||
int phy;
|
||||
int ret = 0;
|
||||
|
||||
@@ -169,7 +179,8 @@ int main(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
|
||||
phy = phy_lookup_idx(argv[1]);
|
||||
phyname = argv[1];
|
||||
phy = phy_lookup_idx(phyname);
|
||||
if (phy < 0) {
|
||||
fprintf(stderr, "Could not find phy '%s'\n", argv[1]);
|
||||
return 2;
|
||||
@@ -185,6 +196,8 @@ int main(int argc, char **argv)
|
||||
ret = mt76_set(phy, argc, argv);
|
||||
else if (!strcmp(cmd, "eeprom"))
|
||||
ret = mt76_eeprom(phy, argc, argv);
|
||||
else if (!strcmp(cmd, "fwlog"))
|
||||
ret = mt76_fwlog(phyname, argc, argv);
|
||||
else
|
||||
usage();
|
||||
|
||||
|
||||
@@ -60,5 +60,6 @@ extern unsigned char *eeprom_data;
|
||||
|
||||
void usage(void);
|
||||
int mt76_eeprom(int phy, int argc, char **argv);
|
||||
int mt76_fwlog(const char *phyname, int argc, char **argv);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user