linux/net/ethtool/ioctl.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * net/core/ethtool.c - Ethtool ioctl handler
 * Copyright (c) 2003 Matthew Wilcox <[email protected]>
 *
 * This file is where we call all the ethtool_ops commands to get
 * the information ethtool needs.
 */

#include <linux/compat.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/net_tstamp.h>
#include <linux/phy.h>
#include <linux/bitops.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/sfp.h>
#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/sched/signal.h>
#include <linux/net.h>
#include <linux/pm_runtime.h>
#include <linux/utsname.h>
#include <net/devlink.h>
#include <net/ipv6.h>
#include <net/xdp_sock_drv.h>
#include <net/flow_offload.h>
#include <linux/ethtool_netlink.h>
#include "common.h"

/* State held across locks and calls for commands which have devlink fallback */
struct ethtool_devlink_compat {};

static struct devlink *netdev_to_devlink_get(struct net_device *dev)
{}

/*
 * Some useful ethtool_ops methods that're device independent.
 * If we find that all drivers want to do the same thing here,
 * we can turn these into dev_() function calls.
 */

u32 ethtool_op_get_link(struct net_device *dev)
{}
EXPORT_SYMBOL();

int ethtool_op_get_ts_info(struct net_device *dev,
			   struct kernel_ethtool_ts_info *info)
{}
EXPORT_SYMBOL();

/* Handlers for each ethtool command */

static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
{}

static int __ethtool_get_sset_count(struct net_device *dev, int sset)
{}

static void __ethtool_get_strings(struct net_device *dev,
	u32 stringset, u8 *data)
{}

static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
{}

static int ethtool_get_one_feature(struct net_device *dev,
	char __user *useraddr, u32 ethcmd)
{}

static int ethtool_set_one_feature(struct net_device *dev,
	void __user *useraddr, u32 ethcmd)
{}

#define ETH_ALL_FLAGS
#define ETH_ALL_FEATURES

static u32 __ethtool_get_flags(struct net_device *dev)
{}

static int __ethtool_set_flags(struct net_device *dev, u32 data)
{}

/* Given two link masks, AND them together and save the result in dst. */
void ethtool_intersect_link_masks(struct ethtool_link_ksettings *dst,
				  struct ethtool_link_ksettings *src)
{}
EXPORT_SYMBOL();

void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst,
					     u32 legacy_u32)
{}
EXPORT_SYMBOL();

/* return false if src had higher bits set. lower bits always updated. */
bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
					     const unsigned long *src)
{}
EXPORT_SYMBOL();

/* return false if ksettings link modes had higher bits
 * set. legacy_settings always updated (best effort)
 */
static bool
convert_link_ksettings_to_legacy_settings(
	struct ethtool_cmd *legacy_settings,
	const struct ethtool_link_ksettings *link_ksettings)
{}

/* number of 32-bit words to store the user's link mode bitmaps */
#define __ETHTOOL_LINK_MODE_MASK_NU32

/* layout of the struct passed from/to userland */
struct ethtool_link_usettings {};

/* Internal kernel helper to query a device ethtool_link_settings. */
int __ethtool_get_link_ksettings(struct net_device *dev,
				 struct ethtool_link_ksettings *link_ksettings)
{}
EXPORT_SYMBOL();

/* convert ethtool_link_usettings in user space to a kernel internal
 * ethtool_link_ksettings. return 0 on success, errno on error.
 */
static int load_link_ksettings_from_user(struct ethtool_link_ksettings *to,
					 const void __user *from)
{}

/* Check if the user is trying to change anything besides speed/duplex */
bool ethtool_virtdev_validate_cmd(const struct ethtool_link_ksettings *cmd)
{}

/* convert a kernel internal ethtool_link_ksettings to
 * ethtool_link_usettings in user space. return 0 on success, errno on
 * error.
 */
static int
store_link_ksettings_for_user(void __user *to,
			      const struct ethtool_link_ksettings *from)
{}

/* Query device for its ethtool_link_settings. */
static int ethtool_get_link_ksettings(struct net_device *dev,
				      void __user *useraddr)
{}

/* Update device ethtool_link_settings. */
static int ethtool_set_link_ksettings(struct net_device *dev,
				      void __user *useraddr)
{}

int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
				       const struct ethtool_link_ksettings *cmd,
				       u32 *dev_speed, u8 *dev_duplex)
{}
EXPORT_SYMBOL();

/* Query device for its ethtool_cmd settings.
 *
 * Backward compatibility note: for compatibility with legacy ethtool, this is
 * now implemented via get_link_ksettings. When driver reports higher link mode
 * bits, a kernel warning is logged once (with name of 1st driver/device) to
 * recommend user to upgrade ethtool, but the command is successful (only the
 * lower link mode bits reported back to user). Deprecated fields from
 * ethtool_cmd (transceiver/maxrxpkt/maxtxpkt) are always set to zero.
 */
static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
{}

/* Update device link settings with given ethtool_cmd.
 *
 * Backward compatibility note: for compatibility with legacy ethtool, this is
 * now always implemented via set_link_settings. When user's request updates
 * deprecated ethtool_cmd fields (transceiver/maxrxpkt/maxtxpkt), a kernel
 * warning is logged once (with name of 1st driver/device) to recommend user to
 * upgrade ethtool, and the request is rejected.
 */
static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
{}

static int
ethtool_get_drvinfo(struct net_device *dev, struct ethtool_devlink_compat *rsp)
{}

static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
						    void __user *useraddr)
{}

static noinline_for_stack int
ethtool_rxnfc_copy_from_compat(struct ethtool_rxnfc *rxnfc,
			       const struct compat_ethtool_rxnfc __user *useraddr,
			       size_t size)
{}

static int ethtool_rxnfc_copy_from_user(struct ethtool_rxnfc *rxnfc,
					const void __user *useraddr,
					size_t size)
{}

static int ethtool_rxnfc_copy_to_compat(void __user *useraddr,
					const struct ethtool_rxnfc *rxnfc,
					size_t size, const u32 *rule_buf)
{}

static int ethtool_rxnfc_copy_struct(u32 cmd, struct ethtool_rxnfc *info,
				     size_t *info_size, void __user *useraddr)
{}

static int ethtool_rxnfc_copy_to_user(void __user *useraddr,
				      const struct ethtool_rxnfc *rxnfc,
				      size_t size, const u32 *rule_buf)
{}

static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev,
						u32 cmd, void __user *useraddr)
{}

static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
						u32 cmd, void __user *useraddr)
{}

static int ethtool_copy_validate_indir(u32 *indir, void __user *useraddr,
					struct ethtool_rxnfc *rx_rings,
					u32 size)
{}

u8 netdev_rss_key[NETDEV_RSS_KEY_LEN] __read_mostly;

void netdev_rss_key_fill(void *buffer, size_t len)
{}
EXPORT_SYMBOL();

static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
						     void __user *useraddr)
{}

static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
						     void __user *useraddr)
{}

static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
					       void __user *useraddr)
{}

static struct ethtool_rxfh_context *
ethtool_rxfh_ctx_alloc(const struct ethtool_ops *ops,
		       u32 indir_size, u32 key_size)
{}

static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
					       void __user *useraddr)
{}

static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
{}

static int ethtool_reset(struct net_device *dev, char __user *useraddr)
{}

static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
{}

static int ethtool_set_wol(struct net_device *dev, char __user *useraddr)
{}

static void eee_to_keee(struct ethtool_keee *keee,
			const struct ethtool_eee *eee)
{}

static void keee_to_eee(struct ethtool_eee *eee,
			const struct ethtool_keee *keee)
{}

static int ethtool_get_eee(struct net_device *dev, char __user *useraddr)
{}

static int ethtool_set_eee(struct net_device *dev, char __user *useraddr)
{}

static int ethtool_nway_reset(struct net_device *dev)
{}

static int ethtool_get_link(struct net_device *dev, char __user *useraddr)
{}

static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr,
				  int (*getter)(struct net_device *,
						struct ethtool_eeprom *, u8 *),
				  u32 total_len)
{}

static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
{}

static noinline_for_stack int ethtool_get_coalesce(struct net_device *dev,
						   void __user *useraddr)
{}

static bool
ethtool_set_coalesce_supported(struct net_device *dev,
			       struct ethtool_coalesce *coalesce)
{}

static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev,
						   void __user *useraddr)
{}

static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr)
{}

static noinline_for_stack int ethtool_get_channels(struct net_device *dev,
						   void __user *useraddr)
{}

static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
						   void __user *useraddr)
{}

static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
{}

static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
{}

__printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...)
{}
EXPORT_SYMBOL();

void ethtool_puts(u8 **data, const char *str)
{}
EXPORT_SYMBOL();

static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_vzalloc_stats_array(int n_stats, u64 **data)
{}

static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
					 struct ethtool_stats *stats,
					 u64 **data)
 {}

static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
					  struct ethtool_stats *stats,
					  u64 **data)
{}

static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_get_value(struct net_device *dev, char __user *useraddr,
			     u32 cmd, u32 (*actor)(struct net_device *))
{}

static int ethtool_set_value_void(struct net_device *dev, char __user *useraddr,
			     void (*actor)(struct net_device *, u32))
{}

static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
			     int (*actor)(struct net_device *, u32))
{}

static int
ethtool_flash_device(struct net_device *dev, struct ethtool_devlink_compat *req)
{}

static int ethtool_set_dump(struct net_device *dev,
			void __user *useraddr)
{}

static int ethtool_get_dump_flag(struct net_device *dev,
				void __user *useraddr)
{}

static int ethtool_get_dump_data(struct net_device *dev,
				void __user *useraddr)
{}

static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)
{}

int ethtool_get_module_info_call(struct net_device *dev,
				 struct ethtool_modinfo *modinfo)
{}

static int ethtool_get_module_info(struct net_device *dev,
				   void __user *useraddr)
{}

int ethtool_get_module_eeprom_call(struct net_device *dev,
				   struct ethtool_eeprom *ee, u8 *data)
{}

static int ethtool_get_module_eeprom(struct net_device *dev,
				     void __user *useraddr)
{}

static int ethtool_tunable_valid(const struct ethtool_tunable *tuna)
{}

static int ethtool_get_tunable(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_set_tunable(struct net_device *dev, void __user *useraddr)
{}

static noinline_for_stack int
ethtool_get_per_queue_coalesce(struct net_device *dev,
			       void __user *useraddr,
			       struct ethtool_per_queue_op *per_queue_opt)
{}

static noinline_for_stack int
ethtool_set_per_queue_coalesce(struct net_device *dev,
			       void __user *useraddr,
			       struct ethtool_per_queue_op *per_queue_opt)
{}

static int noinline_for_stack ethtool_set_per_queue(struct net_device *dev,
				 void __user *useraddr, u32 sub_cmd)
{}

static int ethtool_phy_tunable_valid(const struct ethtool_tunable *tuna)
{}

static int get_phy_tunable(struct net_device *dev, void __user *useraddr)
{}

static int set_phy_tunable(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_get_fecparam(struct net_device *dev, void __user *useraddr)
{}

static int ethtool_set_fecparam(struct net_device *dev, void __user *useraddr)
{}

/* The main entry point in this file.  Called from net/core/dev_ioctl.c */

static int
__dev_ethtool(struct net *net, struct ifreq *ifr, void __user *useraddr,
	      u32 ethcmd, struct ethtool_devlink_compat *devlink_state)
{}

int dev_ethtool(struct net *net, struct ifreq *ifr, void __user *useraddr)
{}

struct ethtool_rx_flow_key {} __aligned(); /* Ensure that we can do comparisons as longs. */

struct ethtool_rx_flow_match {};

struct ethtool_rx_flow_rule *
ethtool_rx_flow_rule_create(const struct ethtool_rx_flow_spec_input *input)
{}
EXPORT_SYMBOL();

void ethtool_rx_flow_rule_destroy(struct ethtool_rx_flow_rule *flow)
{}
EXPORT_SYMBOL();