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