forked from openwrt/mt76
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tools: add support for sending firmware debug data via udp
Signed-off-by: Felix Fietkau <[email protected]>
- Loading branch information
Showing
4 changed files
with
194 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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(); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters