366 lines
11 KiB
C
366 lines
11 KiB
C
|
/* 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>
|
||
|
#include <net/if.h>
|
||
|
|
||
|
#define maybe_unused __attribute__((__unused__))
|
||
|
|
||
|
/* ethtool.h expects these to be defined by <linux/types.h> */
|
||
|
#ifndef HAVE_BE_TYPES
|
||
|
typedef uint16_t __be16;
|
||
|
typedef uint32_t __be32;
|
||
|
typedef unsigned long long __be64;
|
||
|
#endif
|
||
|
|
||
|
typedef unsigned long long u64;
|
||
|
typedef uint32_t u32;
|
||
|
typedef uint16_t u16;
|
||
|
typedef uint8_t u8;
|
||
|
typedef int32_t s32;
|
||
|
|
||
|
/* ethtool.h epxects __KERNEL_DIV_ROUND_UP to be defined by <linux/kernel.h> */
|
||
|
#include <linux/kernel.h>
|
||
|
#ifndef __KERNEL_DIV_ROUND_UP
|
||
|
#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||
|
#endif
|
||
|
|
||
|
#include "ethtool-copy.h"
|
||
|
#include "net_tstamp-copy.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
|
||
|
|
||
|
/* 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;
|
||
|
}
|
||
|
|
||
|
/* 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 */
|
||
|
int argc; /* number of arguments to the sub-command */
|
||
|
char **argp; /* arguments to the sub-command */
|
||
|
};
|
||
|
|
||
|
#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);
|
||
|
|
||
|
/* 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(const __u8 *id);
|
||
|
|
||
|
/* Optics diagnostics */
|
||
|
void sff8472_show_all(const __u8 *id);
|
||
|
|
||
|
/* QSFP Optics diagnostics */
|
||
|
void sff8636_show_all(const __u8 *id, __u32 eeprom_len);
|
||
|
|
||
|
/* 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);
|
||
|
|
||
|
#endif /* ETHTOOL_INTERNAL_H__ */
|