blob: 9e187ab3be20529795624d22f6809fae2ff57b23 [file] [log] [blame]
developer8692bae2023-11-13 11:10:17 +08001From a7e24be75b6a05bc06073163c124f4d17eb1e963 Mon Sep 17 00:00:00 2001
developerb31fa0a2023-09-19 06:32:06 +08002From: Evelyn Tsai <evelyn.tsai@mediatek.com>
3Date: Sun, 17 Sep 2023 12:28:35 +0800
developer91418b82023-11-08 20:39:00 +08004Subject: [PATCH] netifd: revert: commit can't work for Kernel5.4
developerb31fa0a2023-09-19 06:32:06 +08005
6Revert "make_ethtool_modes_h.sh: apply anti-bashism"
7This reverts commit 1a07f1dff32b3af49e39533e33e8964b59535662.
8Revert "system-linux: switch to new ETHTOOL_xLINKSETTINGS API"
9This reverts commit f429bd94f99e55548bf4fa8156c165017ce3c41c.
10---
11 CMakeLists.txt | 8 -
12 device.c | 35 ----
13 device.h | 15 --
14 make_ethtool_modes_h.sh | 66 -------
developer8692bae2023-11-13 11:10:17 +080015 system-linux.c | 406 +++++++++-------------------------------
16 5 files changed, 87 insertions(+), 443 deletions(-)
developerb31fa0a2023-09-19 06:32:06 +080017 delete mode 100755 make_ethtool_modes_h.sh
18
19diff --git a/CMakeLists.txt b/CMakeLists.txt
20index 8064485..5ad8695 100644
21--- a/CMakeLists.txt
22+++ b/CMakeLists.txt
23@@ -49,13 +49,6 @@ IF (NOT DEFINED LIBNL_LIBS)
24 ENDIF()
25 ENDIF()
26
27-ADD_CUSTOM_COMMAND(
28- OUTPUT ethtool-modes.h
29- COMMAND ./make_ethtool_modes_h.sh ${CMAKE_C_COMPILER} > ./ethtool-modes.h
30- DEPENDS ./make_ethtool_modes_h.sh
31-)
32-ADD_CUSTOM_TARGET(ethtool-modes-h DEPENDS ethtool-modes.h)
33-
34 IF("${CMAKE_SYSTEM_NAME}" MATCHES "Linux" AND NOT DUMMY_MODE)
35 SET(SOURCES ${SOURCES} system-linux.c)
36 SET(LIBS ${LIBS} ${LIBNL_LIBS})
37@@ -79,4 +72,3 @@ TARGET_LINK_LIBRARIES(netifd ${LIBS})
38 INSTALL(TARGETS netifd
39 RUNTIME DESTINATION sbin
40 )
41-ADD_DEPENDENCIES(netifd ethtool-modes-h)
42diff --git a/device.c b/device.c
developer8692bae2023-11-13 11:10:17 +080043index 1370335..0474c65 100644
developerb31fa0a2023-09-19 06:32:06 +080044--- a/device.c
45+++ b/device.c
developer91418b82023-11-08 20:39:00 +080046@@ -67,11 +67,6 @@ static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = {
developerb31fa0a2023-09-19 06:32:06 +080047 [DEV_ATTR_SPEED] = { .name = "speed", .type = BLOBMSG_TYPE_INT32 },
48 [DEV_ATTR_DUPLEX] = { .name = "duplex", .type = BLOBMSG_TYPE_BOOL },
49 [DEV_ATTR_VLAN] = { .name = "vlan", .type = BLOBMSG_TYPE_ARRAY },
50- [DEV_ATTR_PAUSE] = { .name = "pause", .type = BLOBMSG_TYPE_BOOL },
51- [DEV_ATTR_ASYM_PAUSE] = { .name = "asym_pause", .type = BLOBMSG_TYPE_BOOL },
52- [DEV_ATTR_RXPAUSE] = { .name = "rxpause", .type = BLOBMSG_TYPE_BOOL },
53- [DEV_ATTR_TXPAUSE] = { .name = "txpause", .type = BLOBMSG_TYPE_BOOL },
54- [DEV_ATTR_AUTONEG] = { .name = "autoneg", .type = BLOBMSG_TYPE_BOOL },
developer8692bae2023-11-13 11:10:17 +080055 [DEV_ATTR_GRO] = { .name = "gro", .type = BLOBMSG_TYPE_BOOL },
56 [DEV_ATTR_MASTER] = { .name = "conduit", .type = BLOBMSG_TYPE_STRING },
57 [DEV_ATTR_EEE] = { .name = "eee", .type = BLOBMSG_TYPE_BOOL },
58@@ -294,11 +289,6 @@ device_merge_settings(struct device *dev, struct device_settings *n)
developerb31fa0a2023-09-19 06:32:06 +080059 n->auth = s->flags & DEV_OPT_AUTH ? s->auth : os->auth;
60 n->speed = s->flags & DEV_OPT_SPEED ? s->speed : os->speed;
61 n->duplex = s->flags & DEV_OPT_DUPLEX ? s->duplex : os->duplex;
62- n->pause = s->flags & DEV_OPT_PAUSE ? s->pause : os->pause;
63- n->asym_pause = s->flags & DEV_OPT_ASYM_PAUSE ? s->asym_pause : os->asym_pause;
64- n->rxpause = s->flags & DEV_OPT_RXPAUSE ? s->rxpause : os->rxpause;
65- n->txpause = s->flags & DEV_OPT_TXPAUSE ? s->txpause : os->txpause;
66- n->autoneg = s->flags & DEV_OPT_AUTONEG ? s->autoneg : os->autoneg;
developer8692bae2023-11-13 11:10:17 +080067 n->gro = s->flags & DEV_OPT_GRO ? s->gro : os->gro;
68 n->eee = s->flags & DEV_OPT_EEE ? s->eee : os->eee;
69 n->master_ifindex = s->flags & DEV_OPT_MASTER ? s->master_ifindex : os->master_ifindex;
70@@ -527,31 +517,6 @@ device_init_settings(struct device *dev, struct blob_attr **tb)
developerb31fa0a2023-09-19 06:32:06 +080071 s->flags |= DEV_OPT_DUPLEX;
72 }
developer91418b82023-11-08 20:39:00 +080073
developerb31fa0a2023-09-19 06:32:06 +080074- if ((cur = tb[DEV_ATTR_PAUSE])) {
75- s->pause = blobmsg_get_bool(cur);
76- s->flags |= DEV_OPT_PAUSE;
77- }
78-
79- if ((cur = tb[DEV_ATTR_ASYM_PAUSE])) {
80- s->asym_pause = blobmsg_get_bool(cur);
81- s->flags |= DEV_OPT_ASYM_PAUSE;
82- }
83-
84- if ((cur = tb[DEV_ATTR_RXPAUSE])) {
85- s->rxpause = blobmsg_get_bool(cur);
86- s->flags |= DEV_OPT_RXPAUSE;
87- }
88-
89- if ((cur = tb[DEV_ATTR_TXPAUSE])) {
90- s->txpause = blobmsg_get_bool(cur);
91- s->flags |= DEV_OPT_TXPAUSE;
92- }
93-
94- if ((cur = tb[DEV_ATTR_AUTONEG])) {
95- s->autoneg = blobmsg_get_bool(cur);
96- s->flags |= DEV_OPT_AUTONEG;
97- }
developer91418b82023-11-08 20:39:00 +080098-
developer8692bae2023-11-13 11:10:17 +080099 if ((cur = tb[DEV_ATTR_GRO])) {
100 s->gro = blobmsg_get_bool(cur);
101 s->flags |= DEV_OPT_GRO;
developerb31fa0a2023-09-19 06:32:06 +0800102diff --git a/device.h b/device.h
developer8692bae2023-11-13 11:10:17 +0800103index b2ea0fa..9a77015 100644
developerb31fa0a2023-09-19 06:32:06 +0800104--- a/device.h
105+++ b/device.h
developer91418b82023-11-08 20:39:00 +0800106@@ -64,11 +64,6 @@ enum {
developerb31fa0a2023-09-19 06:32:06 +0800107 DEV_ATTR_SPEED,
108 DEV_ATTR_DUPLEX,
109 DEV_ATTR_VLAN,
110- DEV_ATTR_PAUSE,
111- DEV_ATTR_ASYM_PAUSE,
112- DEV_ATTR_RXPAUSE,
113- DEV_ATTR_TXPAUSE,
114- DEV_ATTR_AUTONEG,
developer8692bae2023-11-13 11:10:17 +0800115 DEV_ATTR_GRO,
116 DEV_ATTR_MASTER,
117 DEV_ATTR_EEE,
118@@ -136,11 +131,6 @@ enum {
developerb31fa0a2023-09-19 06:32:06 +0800119 DEV_OPT_ARP_ACCEPT = (1ULL << 29),
120 DEV_OPT_SPEED = (1ULL << 30),
121 DEV_OPT_DUPLEX = (1ULL << 31),
122- DEV_OPT_PAUSE = (1ULL << 32),
123- DEV_OPT_ASYM_PAUSE = (1ULL << 33),
124- DEV_OPT_RXPAUSE = (1ULL << 34),
125- DEV_OPT_TXPAUSE = (1ULL << 35),
126- DEV_OPT_AUTONEG = (1ULL << 36),
developer8692bae2023-11-13 11:10:17 +0800127 DEV_OPT_GRO = (1ULL << 37),
128 DEV_OPT_MASTER = (1ULL << 38),
129 DEV_OPT_EEE = (1ULL << 39),
130@@ -221,11 +211,6 @@ struct device_settings {
developerb31fa0a2023-09-19 06:32:06 +0800131 bool auth;
132 unsigned int speed;
133 bool duplex;
134- bool pause;
135- bool asym_pause;
136- bool rxpause;
137- bool txpause;
138- bool autoneg;
developer8692bae2023-11-13 11:10:17 +0800139 bool gro;
140 int master_ifindex;
141 bool eee;
developerb31fa0a2023-09-19 06:32:06 +0800142diff --git a/make_ethtool_modes_h.sh b/make_ethtool_modes_h.sh
143deleted file mode 100755
144index 7f5ac7b..0000000
145--- a/make_ethtool_modes_h.sh
146+++ /dev/null
147@@ -1,66 +0,0 @@
148-#!/bin/sh
149-
150-CC="$1"
151-[ -n "$TARGET_CC_NOCACHE" ] && CC="$TARGET_CC_NOCACHE"
152-
153-cat <<EOF
154-#include <linux/ethtool.h>
155-
156-#define ETHTOOL_MODE_FULL(_speed, _mode) { \\
157- .speed = (_speed), \\
158- .bit_half = -1, \\
159- .bit_full = ETHTOOL_LINK_MODE_ ## _speed ## base ## _mode ## _Full_BIT, \\
160- .name = #_speed "base" #_mode, \\
161-}
162-
163-#define ETHTOOL_MODE_HALF(_speed, _mode) { \\
164- .speed = (_speed), \\
165- .bit_half = ETHTOOL_LINK_MODE_ ## _speed ## base ## _mode ## _Half_BIT, \\
166- .bit_full = -1, \\
167- .name = #_speed "base" #_mode, \\
168-}
169-
170-#define ETHTOOL_MODE_BOTH(_speed, _mode) { \\
171- .speed = (_speed), \\
172- .bit_half = ETHTOOL_LINK_MODE_ ## _speed ## base ## _mode ## _Half_BIT, \\
173- .bit_full = ETHTOOL_LINK_MODE_ ## _speed ## base ## _mode ## _Full_BIT, \\
174- .name = #_speed "base" #_mode, \\
175-}
176-
177-static const struct {
178- unsigned int speed;
179- int bit_half;
180- int bit_full;
181- const char *name;
182-} ethtool_modes[] = {
183-EOF
184-
185-echo "#include <linux/ethtool.h>" | "$CC" -E - | \
186- grep "ETHTOOL_LINK_MODE_[0-9]*base[A-Za-z0-9]*_...._BIT.*" | \
187- sed -r 's/.*ETHTOOL_LINK_MODE_([0-9]*)base([A-Za-z0-9]*)_(....)_BIT.*/\1 \2 \3/' | \
188- sort -u | LC_ALL=C sort -r -g | ( gothalf=0 ; while read -r speed mode duplex; do
189- if [ "$duplex" = "Half" ]; then
190- if [ "$gothalf" = "1" ]; then
191- printf "%s" "$speed \tETHTOOL_MODE_HALF($p_speed, $p_mode),\n"
192- fi
193- gothalf=1
194- elif [ "$duplex" = "Full" ]; then
195- if [ "$gothalf" = "1" ]; then
196- if [ "$p_speed" = "$speed" ] && [ "$p_mode" = "$mode" ]; then
197- printf "%d \t%s\n" "$speed" "ETHTOOL_MODE_BOTH($speed, $mode),"
198- else
199- printf "%d \t%s\n" "$p_speed" "ETHTOOL_MODE_HALF($p_speed, $p_mode),"
200- printf "%d \t%s\n" "$speed" "ETHTOOL_MODE_FULL($speed, $mode),"
201- fi
202- gothalf=0
203- else
204- printf "%d \t%s\n" "$speed" "ETHTOOL_MODE_FULL($speed, $mode),"
205- fi
206- else
207- continue
208- fi
209- p_speed="$speed"
210- p_mode="$mode"
211- done ; [ "$gothalf" = "1" ] && printf "%d \t%s\n" "$p_speed" "ETHTOOL_MODE_HALF($p_speed, $p_mode)," ) | \
212- LC_ALL=C sort -g | sed -r 's/[0-9]* (.*)/\1/'
213-echo "};"
214diff --git a/system-linux.c b/system-linux.c
developer8692bae2023-11-13 11:10:17 +0800215index cc1b5e9..5b97d86 100644
developerb31fa0a2023-09-19 06:32:06 +0800216--- a/system-linux.c
217+++ b/system-linux.c
218@@ -48,8 +48,6 @@
219
220 #include <sched.h>
221
222-#include "ethtool-modes.h"
223-
224 #ifndef RTN_FAILED_POLICY
225 #define RTN_FAILED_POLICY 12
226 #endif
developer8692bae2023-11-13 11:10:17 +0800227@@ -1888,28 +1886,6 @@ failure:
developerb31fa0a2023-09-19 06:32:06 +0800228 }
developer8692bae2023-11-13 11:10:17 +0800229 #endif
developerb31fa0a2023-09-19 06:32:06 +0800230
231-static void ethtool_link_mode_clear_bit(__s8 nwords, int nr, __u32 *mask)
232-{
233- if (nr < 0)
234- return;
235-
236- if (nr >= (nwords * 32))
237- return;
238-
239- mask[nr / 32] &= ~(1U << (nr % 32));
240-}
241-
242-static bool ethtool_link_mode_test_bit(__s8 nwords, int nr, const __u32 *mask)
243-{
244- if (nr < 0)
245- return false;
246-
247- if (nr >= (nwords * 32))
248- return false;
249-
250- return !!(mask[nr / 32] & (1U << (nr % 32)));
251-}
252-
developer8692bae2023-11-13 11:10:17 +0800253 static int
254 system_get_ethtool_gro(struct device *dev)
255 {
256@@ -1944,55 +1920,6 @@ system_set_ethtool_gro(struct device *dev, struct device_settings *s)
257 ioctl(sock_ioctl, SIOCETHTOOL, &ifr);
258 }
259
developerb31fa0a2023-09-19 06:32:06 +0800260-static void
261-system_set_ethtool_pause(struct device *dev, struct device_settings *s)
262-{
263- struct ethtool_pauseparam pp;
264- struct ifreq ifr = {
265- .ifr_data = (caddr_t)&pp,
266- };
267-
268- strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
269- memset(&pp, 0, sizeof(pp));
270- pp.cmd = ETHTOOL_GPAUSEPARAM;
271- if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr))
272- return;
273-
274- if (s->flags & DEV_OPT_RXPAUSE || s->flags & DEV_OPT_TXPAUSE) {
275- pp.autoneg = AUTONEG_DISABLE;
276-
277- if (s->flags & DEV_OPT_PAUSE) {
278- if (s->flags & DEV_OPT_RXPAUSE)
279- pp.rx_pause = s->rxpause && s->pause;
280- else
281- pp.rx_pause = s->pause;
282-
283- if (s->flags & DEV_OPT_TXPAUSE)
284- pp.tx_pause = s->txpause && s->pause;
285- else
286- pp.tx_pause = s->pause;
287- } else {
288- if (s->flags & DEV_OPT_RXPAUSE)
289- pp.rx_pause = s->rxpause;
290-
291- if (s->flags & DEV_OPT_TXPAUSE)
292- pp.tx_pause = s->txpause;
293- }
294-
295- if (s->flags & DEV_OPT_ASYM_PAUSE &&
296- !s->asym_pause && (pp.rx_pause != pp.tx_pause))
297- pp.rx_pause = pp.tx_pause = false;
298- } else {
299- pp.autoneg = AUTONEG_ENABLE;
300- /* Pause and Asym_Pause advertising bits will be set via
301- * ETHTOOL_SLINKSETTINGS in system_set_ethtool_settings()
302- */
303- }
304-
305- pp.cmd = ETHTOOL_SPAUSEPARAM;
306- ioctl(sock_ioctl, SIOCETHTOOL, &ifr);
307-}
308-
309 static void
developer8692bae2023-11-13 11:10:17 +0800310 system_set_ethtool_eee_settings(struct device *dev, struct device_settings *s)
311 {
312@@ -2013,78 +1940,52 @@ system_set_ethtool_eee_settings(struct device *dev, struct device_settings *s)
313 static void
developerb31fa0a2023-09-19 06:32:06 +0800314 system_set_ethtool_settings(struct device *dev, struct device_settings *s)
315 {
316- struct {
317- struct ethtool_link_settings req;
318- __u32 link_mode_data[3 * 127];
319- } ecmd;
320+ struct ethtool_cmd ecmd = {
321+ .cmd = ETHTOOL_GSET,
322+ };
323 struct ifreq ifr = {
324 .ifr_data = (caddr_t)&ecmd,
325 };
326+ static const struct {
327+ unsigned int speed;
328+ uint8_t bit_half;
329+ uint8_t bit_full;
330+ } speed_mask[] = {
331+ { 10, ETHTOOL_LINK_MODE_10baseT_Half_BIT, ETHTOOL_LINK_MODE_10baseT_Full_BIT },
332+ { 100, ETHTOOL_LINK_MODE_100baseT_Half_BIT, ETHTOOL_LINK_MODE_100baseT_Full_BIT },
333+ { 1000, ETHTOOL_LINK_MODE_1000baseT_Half_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT },
334+ };
335+ uint32_t adv;
336 size_t i;
337- __s8 nwords;
338- __u32 *supported, *advertising;
developerb31fa0a2023-09-19 06:32:06 +0800339-
developer8692bae2023-11-13 11:10:17 +0800340- system_set_ethtool_pause(dev, s);
341
342 if (s->flags & DEV_OPT_EEE)
343 system_set_ethtool_eee_settings(dev, s);
344
developerb31fa0a2023-09-19 06:32:06 +0800345- memset(&ecmd, 0, sizeof(ecmd));
346- ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
347 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
348
349- if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 ||
350- ecmd.req.link_mode_masks_nwords >= 0 ||
351- ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
352- return;
353-
354- ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
355-
356- if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 ||
357- ecmd.req.link_mode_masks_nwords <= 0 ||
358- ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
359+ if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0)
360 return;
361
362- nwords = ecmd.req.link_mode_masks_nwords;
363- supported = &ecmd.link_mode_data[0];
364- advertising = &ecmd.link_mode_data[nwords];
365- memcpy(advertising, supported, sizeof(__u32) * nwords);
366-
367- for (i = 0; i < ARRAY_SIZE(ethtool_modes); i++) {
368+ adv = ecmd.supported;
369+ for (i = 0; i < ARRAY_SIZE(speed_mask); i++) {
370 if (s->flags & DEV_OPT_DUPLEX) {
371- if (s->duplex)
372- ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_half, advertising);
373- else
374- ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_full, advertising);
375+ int bit = s->duplex ? speed_mask[i].bit_half : speed_mask[i].bit_full;
376+ adv &= ~(1 << bit);
377 }
developerb31fa0a2023-09-19 06:32:06 +0800378 if (!(s->flags & DEV_OPT_SPEED) ||
379- s->speed == ethtool_modes[i].speed)
380+ s->speed == speed_mask[i].speed)
381 continue;
382
383- ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_full, advertising);
384- ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_half, advertising);
385+ adv &= ~(1 << speed_mask[i].bit_full);
386+ adv &= ~(1 << speed_mask[i].bit_half);
387 }
388
389- if (s->flags & DEV_OPT_PAUSE)
390- if (!s->pause)
391- ethtool_link_mode_clear_bit(nwords, ETHTOOL_LINK_MODE_Pause_BIT, advertising);
developer8692bae2023-11-13 11:10:17 +0800392-
developerb31fa0a2023-09-19 06:32:06 +0800393- if (s->flags & DEV_OPT_ASYM_PAUSE)
394- if (!s->asym_pause)
395- ethtool_link_mode_clear_bit(nwords, ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising);
396-
397- if (s->flags & DEV_OPT_AUTONEG) {
398- ecmd.req.autoneg = s->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
399- if (!s->autoneg) {
400- if (s->flags & DEV_OPT_SPEED)
401- ecmd.req.speed = s->speed;
402-
403- if (s->flags & DEV_OPT_DUPLEX)
404- ecmd.req.duplex = s->duplex ? DUPLEX_FULL : DUPLEX_HALF;
405- }
406- }
407+ if (ecmd.autoneg && ecmd.advertising == adv)
408+ return;
409
410- ecmd.req.cmd = ETHTOOL_SLINKSETTINGS;
411+ ecmd.autoneg = 1;
412+ ecmd.advertising = adv;
413+ ecmd.cmd = ETHTOOL_SSET;
414 ioctl(sock_ioctl, SIOCETHTOOL, &ifr);
415 }
416
developer8692bae2023-11-13 11:10:17 +0800417@@ -2695,6 +2596,45 @@ read_uint64_file(int dir_fd, const char *file, uint64_t *val)
developerb31fa0a2023-09-19 06:32:06 +0800418 return ret;
419 }
420
421+/* Assume advertised flags == supported flags */
422+static const struct {
423+ uint32_t mask;
424+ const char *name;
425+} ethtool_link_modes[] = {
426+ { ADVERTISED_10baseT_Half, "10baseT-H" },
427+ { ADVERTISED_10baseT_Full, "10baseT-F" },
428+ { ADVERTISED_100baseT_Half, "100baseT-H" },
429+ { ADVERTISED_100baseT_Full, "100baseT-F" },
430+ { ADVERTISED_1000baseT_Half, "1000baseT-H" },
431+ { ADVERTISED_1000baseT_Full, "1000baseT-F" },
432+ { ADVERTISED_1000baseKX_Full, "1000baseKX-F" },
433+ { ADVERTISED_2500baseX_Full, "2500baseX-F" },
434+ { ADVERTISED_10000baseT_Full, "10000baseT-F" },
435+ { ADVERTISED_10000baseKX4_Full, "10000baseKX4-F" },
436+ { ADVERTISED_10000baseKR_Full, "10000baseKR-F" },
437+ { ADVERTISED_20000baseMLD2_Full, "20000baseMLD2-F" },
438+ { ADVERTISED_20000baseKR2_Full, "20000baseKR2-F" },
439+ { ADVERTISED_40000baseKR4_Full, "40000baseKR4-F" },
440+ { ADVERTISED_40000baseCR4_Full, "40000baseCR4-F" },
441+ { ADVERTISED_40000baseSR4_Full, "40000baseSR4-F" },
442+ { ADVERTISED_40000baseLR4_Full, "40000baseLR4-F" },
443+#ifdef ADVERTISED_56000baseKR4_Full
444+ { ADVERTISED_56000baseKR4_Full, "56000baseKR4-F" },
445+ { ADVERTISED_56000baseCR4_Full, "56000baseCR4-F" },
446+ { ADVERTISED_56000baseSR4_Full, "56000baseSR4-F" },
447+ { ADVERTISED_56000baseLR4_Full, "56000baseLR4-F" },
448+#endif
449+};
450+
451+static void system_add_link_modes(struct blob_buf *b, __u32 mask)
452+{
453+ size_t i;
454+ for (i = 0; i < ARRAY_SIZE(ethtool_link_modes); i++) {
455+ if (mask & ethtool_link_modes[i].mask)
456+ blobmsg_add_string(b, NULL, ethtool_link_modes[i].name);
457+ }
458+}
459+
460 bool
461 system_if_force_external(const char *ifname)
462 {
developer8692bae2023-11-13 11:10:17 +0800463@@ -2869,213 +2809,41 @@ ethtool_feature_value(const char *ifname, const char *keyname)
developerb31fa0a2023-09-19 06:32:06 +0800464 return active;
465 }
466
467-static void
468-system_add_link_mode_name(struct blob_buf *b, int i, bool half)
469-{
470- char *buf;
471-
472- /* allocate string buffer large enough for the mode name and a suffix
473- * "-F" or "-H" indicating full duplex or half duplex.
474- */
475- buf = blobmsg_alloc_string_buffer(b, NULL, strlen(ethtool_modes[i].name) + 3);
476- if (!buf)
477- return;
478-
479- strcpy(buf, ethtool_modes[i].name);
480- if (half)
481- strcat(buf, "-H");
482- else
483- strcat(buf, "-F");
484-
485- blobmsg_add_string_buffer(b);
486-}
487-
488-static void
489-system_add_link_modes(__s8 nwords, struct blob_buf *b, __u32 *mask)
490-{
491- size_t i;
492-
493- for (i = 0; i < ARRAY_SIZE(ethtool_modes); i++) {
494- if (ethtool_link_mode_test_bit(nwords, ethtool_modes[i].bit_half, mask))
495- system_add_link_mode_name(b, i, true);
496-
497- if (ethtool_link_mode_test_bit(nwords, ethtool_modes[i].bit_full, mask))
498- system_add_link_mode_name(b, i, false);
499- }
500-}
501-
502-static void
503-system_add_pause_modes(__s8 nwords, struct blob_buf *b, __u32 *mask)
504-{
505- if (ethtool_link_mode_test_bit(nwords, ETHTOOL_LINK_MODE_Pause_BIT, mask))
506- blobmsg_add_string(b, NULL, "pause");
507-
508- if (ethtool_link_mode_test_bit(nwords, ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask))
509- blobmsg_add_string(b, NULL, "asym_pause");
510-}
511-
512-
513-static void
514-system_add_ethtool_pause_an(struct blob_buf *b, __s8 nwords,
515- __u32 *advertising, __u32 *lp_advertising)
516-{
517- bool an_rx = false, an_tx = false;
518- void *d;
519-
520- d = blobmsg_open_array(b, "negotiated");
521-
522- /* Work out negotiated pause frame usage per
523- * IEEE 802.3-2005 table 28B-3.
524- */
525- if (ethtool_link_mode_test_bit(nwords,
526- ETHTOOL_LINK_MODE_Pause_BIT,
527- advertising) &&
528- ethtool_link_mode_test_bit(nwords,
529- ETHTOOL_LINK_MODE_Pause_BIT,
530- lp_advertising)) {
531- an_tx = true;
532- an_rx = true;
533- } else if (ethtool_link_mode_test_bit(nwords,
534- ETHTOOL_LINK_MODE_Asym_Pause_BIT,
535- advertising) &&
536- ethtool_link_mode_test_bit(nwords,
537- ETHTOOL_LINK_MODE_Asym_Pause_BIT,
538- lp_advertising)) {
539- if (ethtool_link_mode_test_bit(nwords,
540- ETHTOOL_LINK_MODE_Pause_BIT,
541- advertising))
542- an_rx = true;
543- else if (ethtool_link_mode_test_bit(nwords,
544- ETHTOOL_LINK_MODE_Pause_BIT,
545- lp_advertising))
546- an_tx = true;
547- }
548- if (an_tx)
549- blobmsg_add_string(b, NULL, "rx");
550-
551- if (an_rx)
552- blobmsg_add_string(b, NULL, "tx");
553-
554- blobmsg_close_array(b, d);
555-}
556-
557-static void
558-system_get_ethtool_pause(struct device *dev, bool *rx_pause, bool *tx_pause, bool *pause_autoneg)
559-{
560- struct ethtool_pauseparam pp;
561- struct ifreq ifr = {
562- .ifr_data = (caddr_t)&pp,
563- };
564-
565- strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
566- memset(&pp, 0, sizeof(pp));
567- pp.cmd = ETHTOOL_GPAUSEPARAM;
568-
569- /* may fail */
570- if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == -1) {
571- *pause_autoneg = true;
572- return;
573- }
574-
575- *rx_pause = pp.rx_pause;
576- *tx_pause = pp.tx_pause;
577- *pause_autoneg = pp.autoneg;
578-}
579-
580 int
581 system_if_dump_info(struct device *dev, struct blob_buf *b)
582 {
583- __u32 *supported, *advertising, *lp_advertising;
584- bool rx_pause, tx_pause, pause_autoneg;
585- struct {
586- struct ethtool_link_settings req;
587- __u32 link_mode_data[3 * 127];
588- } ecmd;
589- struct ifreq ifr = {
590- .ifr_data = (caddr_t)&ecmd,
591- };
592- __s8 nwords;
593- void *c, *d;
594+ struct ethtool_cmd ecmd;
595+ struct ifreq ifr;
596 char *s;
597-
598- system_get_ethtool_pause(dev, &rx_pause, &tx_pause, &pause_autoneg);
599+ void *c;
600
601 memset(&ecmd, 0, sizeof(ecmd));
602- ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
603+ memset(&ifr, 0, sizeof(ifr));
604 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
605+ ifr.ifr_data = (caddr_t) &ecmd;
606+ ecmd.cmd = ETHTOOL_GSET;
607
608- if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 ||
609- ecmd.req.link_mode_masks_nwords >= 0 ||
610- ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
611- return -EOPNOTSUPP;
612-
613- ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
614-
615- if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 ||
616- ecmd.req.link_mode_masks_nwords <= 0 ||
617- ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
618- return -EIO;
619-
620- nwords = ecmd.req.link_mode_masks_nwords;
621- supported = &ecmd.link_mode_data[0];
622- advertising = &ecmd.link_mode_data[nwords];
623- lp_advertising = &ecmd.link_mode_data[2 * nwords];
624-
625- c = blobmsg_open_array(b, "link-advertising");
626- system_add_link_modes(nwords, b, advertising);
627- blobmsg_close_array(b, c);
628-
629- c = blobmsg_open_array(b, "link-partner-advertising");
630- system_add_link_modes(nwords, b, lp_advertising);
631- blobmsg_close_array(b, c);
632-
633- c = blobmsg_open_array(b, "link-supported");
634- system_add_link_modes(nwords, b, supported);
635- blobmsg_close_array(b, c);
636-
637- if (ethtool_validate_speed(ecmd.req.speed) &&
638- (ecmd.req.speed != (__u32)SPEED_UNKNOWN) &&
639- (ecmd.req.speed != 0)) {
640- s = blobmsg_alloc_string_buffer(b, "speed", 10);
641- snprintf(s, 8, "%d%c", ecmd.req.speed,
642- ecmd.req.duplex == DUPLEX_HALF ? 'H' : 'F');
643- blobmsg_add_string_buffer(b);
644- }
645- blobmsg_add_u8(b, "autoneg", !!ecmd.req.autoneg);
646+ if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == 0) {
647+ c = blobmsg_open_array(b, "link-advertising");
648+ system_add_link_modes(b, ecmd.advertising);
649+ blobmsg_close_array(b, c);
650
651- c = blobmsg_open_table(b, "flow-control");
652- blobmsg_add_u8(b, "autoneg", pause_autoneg);
653+ c = blobmsg_open_array(b, "link-partner-advertising");
654+ system_add_link_modes(b, ecmd.lp_advertising);
655+ blobmsg_close_array(b, c);
656
657- d = blobmsg_open_array(b, "supported");
658- system_add_pause_modes(nwords, b, supported);
659- blobmsg_close_array(b, d);
660+ c = blobmsg_open_array(b, "link-supported");
661+ system_add_link_modes(b, ecmd.supported);
662+ blobmsg_close_array(b, c);
663
664- if (pause_autoneg) {
665- d = blobmsg_open_array(b, "link-advertising");
666- system_add_pause_modes(nwords, b, advertising);
667- blobmsg_close_array(b, d);
668- }
669-
670- d = blobmsg_open_array(b, "link-partner-advertising");
671- system_add_pause_modes(nwords, b, lp_advertising);
672- blobmsg_close_array(b, d);
673-
674- if (pause_autoneg) {
675- system_add_ethtool_pause_an(b, nwords, advertising,
676- lp_advertising);
677- } else {
678- d = blobmsg_open_array(b, "selected");
679- if (rx_pause)
680- blobmsg_add_string(b, NULL, "rx");
681-
682- if (tx_pause)
683- blobmsg_add_string(b, NULL, "tx");
684+ s = blobmsg_alloc_string_buffer(b, "speed", 8);
685+ snprintf(s, 8, "%d%c", ethtool_cmd_speed(&ecmd),
686+ ecmd.duplex == DUPLEX_HALF ? 'H' : 'F');
687+ blobmsg_add_string_buffer(b);
688
689- blobmsg_close_array(b, d);
690+ blobmsg_add_u8(b, "autoneg", !!ecmd.autoneg);
691 }
692
693- blobmsg_close_table(b, c);
694-
695 blobmsg_add_u8(b, "hw-tc-offload",
696 ethtool_feature_value(dev->ifname, "hw-tc-offload"));
697
developer8692bae2023-11-13 11:10:17 +0800698@@ -4203,7 +3971,7 @@ static void system_vxlan_map_bool_attr(struct nl_msg *msg, struct blob_attr **tb
699
700 if ((attrtype == IFLA_VXLAN_GBP) && val)
701 nla_put_flag(msg, attrtype);
702- else
703+ else
704 nla_put_u8(msg, attrtype, val);
705
706 }
developerb31fa0a2023-09-19 06:32:06 +0800707--
7082.18.0
709