1 /*
2 * common.h - common code header
3 *
4 * Data and functions shared by ioctl and netlink implementation.
5 */
6
7 #include "internal.h"
8 #include "common.h"
9
10 #ifndef HAVE_NETIF_MSG
11 enum {
12 NETIF_MSG_DRV = 0x0001,
13 NETIF_MSG_PROBE = 0x0002,
14 NETIF_MSG_LINK = 0x0004,
15 NETIF_MSG_TIMER = 0x0008,
16 NETIF_MSG_IFDOWN = 0x0010,
17 NETIF_MSG_IFUP = 0x0020,
18 NETIF_MSG_RX_ERR = 0x0040,
19 NETIF_MSG_TX_ERR = 0x0080,
20 NETIF_MSG_TX_QUEUED = 0x0100,
21 NETIF_MSG_INTR = 0x0200,
22 NETIF_MSG_TX_DONE = 0x0400,
23 NETIF_MSG_RX_STATUS = 0x0800,
24 NETIF_MSG_PKTDATA = 0x1000,
25 NETIF_MSG_HW = 0x2000,
26 NETIF_MSG_WOL = 0x4000,
27 };
28 #endif
29
30 const struct flag_info flags_msglvl[] = {
31 { "drv", NETIF_MSG_DRV },
32 { "probe", NETIF_MSG_PROBE },
33 { "link", NETIF_MSG_LINK },
34 { "timer", NETIF_MSG_TIMER },
35 { "ifdown", NETIF_MSG_IFDOWN },
36 { "ifup", NETIF_MSG_IFUP },
37 { "rx_err", NETIF_MSG_RX_ERR },
38 { "tx_err", NETIF_MSG_TX_ERR },
39 { "tx_queued", NETIF_MSG_TX_QUEUED },
40 { "intr", NETIF_MSG_INTR },
41 { "tx_done", NETIF_MSG_TX_DONE },
42 { "rx_status", NETIF_MSG_RX_STATUS },
43 { "pktdata", NETIF_MSG_PKTDATA },
44 { "hw", NETIF_MSG_HW },
45 { "wol", NETIF_MSG_WOL },
46 {}
47 };
48 const unsigned int n_flags_msglvl = ARRAY_SIZE(flags_msglvl) - 1;
49
50 const struct off_flag_def off_flag_def[] = {
51 { "rx", "rx-checksumming", "rx-checksum",
52 ETHTOOL_GRXCSUM, ETHTOOL_SRXCSUM, ETH_FLAG_RXCSUM, 0 },
53 { "tx", "tx-checksumming", "tx-checksum-*",
54 ETHTOOL_GTXCSUM, ETHTOOL_STXCSUM, ETH_FLAG_TXCSUM, 0 },
55 { "sg", "scatter-gather", "tx-scatter-gather*",
56 ETHTOOL_GSG, ETHTOOL_SSG, ETH_FLAG_SG, 0 },
57 { "tso", "tcp-segmentation-offload", "tx-tcp*-segmentation",
58 ETHTOOL_GTSO, ETHTOOL_STSO, ETH_FLAG_TSO, 0 },
59 { "ufo", "udp-fragmentation-offload", "tx-udp-fragmentation",
60 ETHTOOL_GUFO, ETHTOOL_SUFO, ETH_FLAG_UFO, 0 },
61 { "gso", "generic-segmentation-offload", "tx-generic-segmentation",
62 ETHTOOL_GGSO, ETHTOOL_SGSO, ETH_FLAG_GSO, 0 },
63 { "gro", "generic-receive-offload", "rx-gro",
64 ETHTOOL_GGRO, ETHTOOL_SGRO, ETH_FLAG_GRO, 0 },
65 { "lro", "large-receive-offload", "rx-lro",
66 0, 0, ETH_FLAG_LRO,
67 KERNEL_VERSION(2,6,24) },
68 { "rxvlan", "rx-vlan-offload", "rx-vlan-hw-parse",
69 0, 0, ETH_FLAG_RXVLAN,
70 KERNEL_VERSION(2,6,37) },
71 { "txvlan", "tx-vlan-offload", "tx-vlan-hw-insert",
72 0, 0, ETH_FLAG_TXVLAN,
73 KERNEL_VERSION(2,6,37) },
74 { "ntuple", "ntuple-filters", "rx-ntuple-filter",
75 0, 0, ETH_FLAG_NTUPLE, 0 },
76 { "rxhash", "receive-hashing", "rx-hashing",
77 0, 0, ETH_FLAG_RXHASH, 0 },
78 };
79
print_flags(const struct flag_info * info,unsigned int n_info,u32 value)80 void print_flags(const struct flag_info *info, unsigned int n_info, u32 value)
81 {
82 const char *sep = "";
83
84 while (n_info) {
85 if (value & info->value) {
86 printf("%s%s", sep, info->name);
87 sep = " ";
88 value &= ~info->value;
89 }
90 ++info;
91 --n_info;
92 }
93
94 /* Print any unrecognised flags in hex */
95 if (value)
96 printf("%s%#x", sep, value);
97 }
98
unparse_wolopts(int wolopts)99 static char *unparse_wolopts(int wolopts)
100 {
101 static char buf[16];
102 char *p = buf;
103
104 memset(buf, 0, sizeof(buf));
105
106 if (wolopts) {
107 if (wolopts & WAKE_PHY)
108 *p++ = 'p';
109 if (wolopts & WAKE_UCAST)
110 *p++ = 'u';
111 if (wolopts & WAKE_MCAST)
112 *p++ = 'm';
113 if (wolopts & WAKE_BCAST)
114 *p++ = 'b';
115 if (wolopts & WAKE_ARP)
116 *p++ = 'a';
117 if (wolopts & WAKE_MAGIC)
118 *p++ = 'g';
119 if (wolopts & WAKE_MAGICSECURE)
120 *p++ = 's';
121 if (wolopts & WAKE_FILTER)
122 *p++ = 'f';
123 } else {
124 *p = 'd';
125 }
126
127 return buf;
128 }
129
dump_wol(struct ethtool_wolinfo * wol)130 int dump_wol(struct ethtool_wolinfo *wol)
131 {
132 fprintf(stdout, " Supports Wake-on: %s\n",
133 unparse_wolopts(wol->supported));
134 fprintf(stdout, " Wake-on: %s\n",
135 unparse_wolopts(wol->wolopts));
136 if (wol->supported & WAKE_MAGICSECURE) {
137 int i;
138 int delim = 0;
139
140 fprintf(stdout, " SecureOn password: ");
141 for (i = 0; i < SOPASS_MAX; i++) {
142 fprintf(stdout, "%s%02x", delim ? ":" : "",
143 wol->sopass[i]);
144 delim = 1;
145 }
146 fprintf(stdout, "\n");
147 }
148
149 return 0;
150 }
151
dump_mdix(u8 mdix,u8 mdix_ctrl)152 void dump_mdix(u8 mdix, u8 mdix_ctrl)
153 {
154 fprintf(stdout, " MDI-X: ");
155 if (mdix_ctrl == ETH_TP_MDI) {
156 fprintf(stdout, "off (forced)\n");
157 } else if (mdix_ctrl == ETH_TP_MDI_X) {
158 fprintf(stdout, "on (forced)\n");
159 } else {
160 switch (mdix) {
161 case ETH_TP_MDI:
162 fprintf(stdout, "off");
163 break;
164 case ETH_TP_MDI_X:
165 fprintf(stdout, "on");
166 break;
167 default:
168 fprintf(stdout, "Unknown");
169 break;
170 }
171 if (mdix_ctrl == ETH_TP_MDI_AUTO)
172 fprintf(stdout, " (auto)");
173 fprintf(stdout, "\n");
174 }
175 }
176
print_indir_table(struct cmd_context * ctx,u64 ring_count,u32 indir_size,u32 * indir)177 void print_indir_table(struct cmd_context *ctx, u64 ring_count,
178 u32 indir_size, u32 *indir)
179 {
180 u32 i;
181
182 printf("RX flow hash indirection table for %s with %llu RX ring(s):\n",
183 ctx->devname, ring_count);
184
185 if (!indir_size)
186 printf("Operation not supported\n");
187
188 for (i = 0; i < indir_size; i++) {
189 if (i % 8 == 0)
190 printf("%5u: ", i);
191 printf(" %5u", indir[i]);
192 if (i % 8 == 7 || i == indir_size - 1)
193 fputc('\n', stdout);
194 }
195 }
196
print_rss_hkey(u8 * hkey,u32 hkey_size)197 void print_rss_hkey(u8 *hkey, u32 hkey_size)
198 {
199 u32 i;
200
201 printf("RSS hash key:\n");
202 if (!hkey_size || !hkey)
203 printf("Operation not supported\n");
204
205 for (i = 0; i < hkey_size; i++) {
206 if (i == (hkey_size - 1))
207 printf("%02x\n", hkey[i]);
208 else
209 printf("%02x:", hkey[i]);
210 }
211 }
212