summaryrefslogtreecommitdiffstats
path: root/internal.h
blob: 4b994f541f7ef6341465501a6dcbd9d3f7ba5810 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
/* Portions Copyright 2001 Sun Microsystems (thockin@sun.com) */
/* Portions Copyright 2002 Intel (scott.feldman@intel.com) */
#ifndef ETHTOOL_INTERNAL_H__
#define ETHTOOL_INTERNAL_H__

/* Some platforms (eg. ppc64) need __SANE_USERSPACE_TYPES__ before
 * <linux/types.h> to select 'int-ll64.h' and avoid compile warnings
 * when printing __u64 with %llu.
 */
#define __SANE_USERSPACE_TYPES__

#ifdef HAVE_CONFIG_H
#include "ethtool-config.h"
#endif
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <endian.h>
#include <sys/ioctl.h>
#define __UAPI_DEF_IF_IFNAMSIZ	1
#define __UAPI_DEF_IF_IFMAP	1
#define __UAPI_DEF_IF_IFREQ	1
#include <linux/if.h>

#include "json_writer.h"
#include "json_print.h"

#define __maybe_unused __attribute__((__unused__))

/* internal for netlink interface */
#ifdef ETHTOOL_ENABLE_NETLINK
struct nl_context;
#endif

typedef unsigned long long u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int32_t s32;

#include <linux/ethtool.h>
#include <linux/net_tstamp.h>

#if __BYTE_ORDER == __BIG_ENDIAN
static inline u16 cpu_to_be16(u16 value)
{
	return value;
}
static inline u32 cpu_to_be32(u32 value)
{
	return value;
}
static inline u64 cpu_to_be64(u64 value)
{
	return value;
}
#else
static inline u16 cpu_to_be16(u16 value)
{
	return (value >> 8) | (value << 8);
}
static inline u32 cpu_to_be32(u32 value)
{
	return cpu_to_be16(value >> 16) | (cpu_to_be16(value) << 16);
}
static inline u64 cpu_to_be64(u64 value)
{
	return cpu_to_be32(value >> 32) | ((u64)cpu_to_be32(value) << 32);
}
#endif

#define ntohll cpu_to_be64
#define htonll cpu_to_be64

#define BITS_PER_BYTE		8
#define BITS_PER_LONG		(BITS_PER_BYTE * sizeof(long))
#define DIV_ROUND_UP(n, d)	(((n) + (d) - 1) / (d))
#define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_LONG)

static inline void set_bit(unsigned int nr, unsigned long *addr)
{
	addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
}

static inline void clear_bit(unsigned int nr, unsigned long *addr)
{
	addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
}

static inline int test_bit(unsigned int nr, const unsigned long *addr)
{
	return !!((1UL << (nr % BITS_PER_LONG)) &
		  (((unsigned long *)addr)[nr / BITS_PER_LONG]));
}

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif

#ifndef SIOCETHTOOL
#define SIOCETHTOOL     0x8946
#endif

/* debugging flags */
enum {
	DEBUG_PARSE,
	DEBUG_NL_MSGS,		/* incoming/outgoing netlink messages */
	DEBUG_NL_DUMP_SND,	/* dump outgoing netlink messages */
	DEBUG_NL_DUMP_RCV,	/* dump incoming netlink messages */
	DEBUG_NL_PRETTY_MSG,	/* pretty print of messages and errors */
};

static inline bool debug_on(unsigned long debug, unsigned int bit)
{
	return (debug & (1 << bit));
}

/* Internal values for old-style offload flags.  Values and names
 * must not clash with the flags defined for ETHTOOL_{G,S}FLAGS.
 */
#define ETH_FLAG_RXCSUM		(1 << 0)
#define ETH_FLAG_TXCSUM		(1 << 1)
#define ETH_FLAG_SG		(1 << 2)
#define ETH_FLAG_TSO		(1 << 3)
#define ETH_FLAG_UFO		(1 << 4)
#define ETH_FLAG_GSO		(1 << 5)
#define ETH_FLAG_GRO		(1 << 6)
#define ETH_FLAG_INT_MASK	(ETH_FLAG_RXCSUM | ETH_FLAG_TXCSUM |	\
				 ETH_FLAG_SG | ETH_FLAG_TSO | ETH_FLAG_UFO | \
				 ETH_FLAG_GSO | ETH_FLAG_GRO),
/* Mask of all flags defined for ETHTOOL_{G,S}FLAGS. */
#define ETH_FLAG_EXT_MASK	(ETH_FLAG_LRO | ETH_FLAG_RXVLAN |	\
				 ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |	\
				 ETH_FLAG_RXHASH)

/* internal API for link mode bitmap interaction with kernel. */

#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32		\
	(SCHAR_MAX)
#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS		\
	(32 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32)
#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES	\
	(4 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32)
#define ETHTOOL_DECLARE_LINK_MODE_MASK(name)		\
	u32 name[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32]

struct ethtool_link_usettings {
	struct {
		__u8 transceiver;
	} deprecated;
	struct ethtool_link_settings base;
	struct {
		ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
		ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
		ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
	} link_modes;
};

#define ethtool_link_mode_for_each_u32(index)			\
	for ((index) = 0;					\
	     (index) < ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32;	\
	     ++(index))

static inline void ethtool_link_mode_zero(u32 *dst)
{
	memset(dst, 0, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES);
}

static inline bool ethtool_link_mode_is_empty(const u32 *mask)
{
	unsigned int i;

	ethtool_link_mode_for_each_u32(i) {
		if (mask[i] != 0)
			return false;
	}

	return true;
}

static inline void ethtool_link_mode_copy(u32 *dst, const u32 *src)
{
	memcpy(dst, src, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES);
}

static inline int ethtool_link_mode_test_bit(unsigned int nr, const u32 *mask)
{
	if (nr >= ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS)
		return !!0;
	return !!(mask[nr / 32] & (1 << (nr % 32)));
}

static inline int ethtool_link_mode_set_bit(unsigned int nr, u32 *mask)
{
	if (nr >= ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS)
		return -1;
	mask[nr / 32] |= (1 << (nr % 32));
	return 0;
}

/* Struct for managing module EEPROM pages */
struct ethtool_module_eeprom {
	u32	offset;
	u32	length;
	u8	page;
	u8	bank;
	u8	i2c_address;
	u8	*data;
};

/* Context for sub-commands */
struct cmd_context {
	const char *devname;	/* net device name */
	int fd;			/* socket suitable for ethtool ioctl */
	struct ifreq ifr;	/* ifreq suitable for ethtool ioctl */
	unsigned int argc;	/* number of arguments to the sub-command */
	char **argp;		/* arguments to the sub-command */
	unsigned long debug;	/* debugging mask */
	bool json;		/* Output JSON, if supported */
	bool show_stats;	/* include command-specific stats */
#ifdef ETHTOOL_ENABLE_NETLINK
	struct nl_context *nlctx;	/* netlink context (opaque) */
#endif
};

#ifdef TEST_ETHTOOL
int test_cmdline(const char *args);

struct cmd_expect {
	const void *cmd;	/* expected command; NULL at end of list */
	size_t cmd_len;		/* length to match (might be < sizeof struct) */
	int rc;			/* kernel return code */
	const void *resp;	/* response to write back; may be NULL */
	size_t resp_len;	/* length to write back */
};
int test_ioctl(const struct cmd_expect *expect, void *cmd);
#define TEST_IOCTL_MISMATCH (-2)

int test_main(int argc, char **argp);
void test_exit(int rc) __attribute__((noreturn));

#ifndef TEST_NO_WRAPPERS
#define main(...) test_main(__VA_ARGS__)
#undef exit
#define exit(rc) test_exit(rc)
void *test_malloc(size_t size);
#undef malloc
#define malloc(size) test_malloc(size)
void *test_calloc(size_t nmemb, size_t size);
#undef calloc
#define calloc(nmemb, size) test_calloc(nmemb, size)
char *test_strdup(const char *s);
#undef strdup
#define strdup(s) test_strdup(s)
void test_free(void *ptr);
#undef free
#define free(ptr) test_free(ptr)
void *test_realloc(void *ptr, size_t size);
#undef realloc
#define realloc(ptr, size) test_realloc(ptr, size)
int test_open(const char *pathname, int flag, ...);
#undef open
#define open(...) test_open(__VA_ARGS__)
int test_socket(int domain, int type, int protocol);
#undef socket
#define socket(...) test_socket(__VA_ARGS__)
int test_close(int fd);
#undef close
#define close(fd) test_close(fd)
FILE *test_fopen(const char *path, const char *mode);
#undef fopen
#define fopen(path, mode) test_fopen(path, mode)
int test_fclose(FILE *fh);
#undef fclose
#define fclose(fh) test_fclose(fh)
#endif
#endif

int send_ioctl(struct cmd_context *ctx, void *cmd);

void dump_hex(FILE *f, const u8 *data, int len, int offset);

/* National Semiconductor DP83815, DP83816 */
int natsemi_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
int natsemi_dump_eeprom(struct ethtool_drvinfo *info,
	struct ethtool_eeprom *ee);

/* Digital/Intel 21040 and 21041 */
int de2104x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Intel(R) PRO/1000 Gigabit Adapter Family */
int e1000_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

int igb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* RealTek PCI */
int realtek_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Intel(R) PRO/100 Fast Ethernet Adapter Family */
int e100_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Tigon3 */
int tg3_dump_eeprom(struct ethtool_drvinfo *info, struct ethtool_eeprom *ee);

/* Advanced Micro Devices  AMD8111 based Adapter */
int amd8111e_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Advanced Micro Devices PCnet32 Adapter */
int pcnet32_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Motorola 8xx FEC Ethernet controller */
int fec_8xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* PowerPC 4xx on-chip Ethernet controller */
int ibm_emac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Intel(R) PRO/10GBe Gigabit Adapter Family */
int ixgb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

int ixgbe_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

int ixgbevf_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Broadcom Tigon3 Ethernet controller */
int tg3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* SysKonnect Gigabit (Genesis and Yukon) */
int skge_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* SysKonnect Gigabit (Yukon2) */
int sky2_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Fabric7 VIOC */
int vioc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* SMSC LAN911x/LAN921x embedded ethernet controller */
int smsc911x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

int at76c50x_usb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Solarflare Solarstorm controllers */
int sfc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* STMMAC embedded ethernet controller */
int st_mac100_dump_regs(struct ethtool_drvinfo *info,
			struct ethtool_regs *regs);
int st_gmac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Et131x ethernet controller */
int et131x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Altera TSE 10/100/1000 ethernet controller */
int altera_tse_dump_regs(struct ethtool_drvinfo *info,
			 struct ethtool_regs *regs);

/* VMware vmxnet3 ethernet controller */
int vmxnet3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* hns3 ethernet controller */
int hns3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Rx flow classification */
int rxclass_parse_ruleopts(struct cmd_context *ctx,
			   struct ethtool_rx_flow_spec *fsp, __u32 *rss_context);
int rxclass_rule_getall(struct cmd_context *ctx);
int rxclass_rule_get(struct cmd_context *ctx, __u32 loc);
int rxclass_rule_ins(struct cmd_context *ctx,
		     struct ethtool_rx_flow_spec *fsp, __u32 rss_context);
int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);

/* Module EEPROM parsing code */
void sff8079_show_all_ioctl(const __u8 *id);
int sff8079_show_all_nl(struct cmd_context *ctx);

/* Optics diagnostics */
void sff8472_show_all(const __u8 *id);

/* QSFP Optics diagnostics */
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
int sff8636_show_all_nl(struct cmd_context *ctx);

/* FUJITSU Extended Socket network device */
int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* MICROCHIP LAN78XX USB ETHERNET Controller */
int lan78xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Distributed Switch Architecture */
int dsa_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* i.MX Fast Ethernet Controller */
int fec_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Freescale/NXP ENETC Ethernet Controller */
int fsl_enetc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Intel(R) Ethernet Controller I225-LM/I225-V adapter family */
int igc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Broadcom Ethernet Controller */
int bnxt_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* TI CPSW Ethernet Switch */
int cpsw_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

/* Microchip Ethernet Controller */
int lan743x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);

#endif /* ETHTOOL_INTERNAL_H__ */