/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef _ETHTOOL_COMMON_H #define _ETHTOOL_COMMON_H #include #include #define ETHTOOL_DEV_FEATURE_WORDS DIV_ROUND_UP(NETDEV_FEATURE_COUNT, 32) /* compose link mode index from speed, type and duplex */ #define ETHTOOL_LINK_MODE(speed, type, duplex) \ ETHTOOL_LINK_MODE_ ## speed ## base ## type ## _ ## duplex ## _BIT #define __SOF_TIMESTAMPING_CNT (const_ilog2(SOF_TIMESTAMPING_LAST) + 1) #define __HWTSTAMP_FLAG_CNT (const_ilog2(HWTSTAMP_FLAG_LAST) + 1) struct genl_info; struct hwtstamp_provider_desc; extern const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]; extern const char rss_hash_func_strings[ETH_RSS_HASH_FUNCS_COUNT][ETH_GSTRING_LEN]; extern const char tunable_strings[__ETHTOOL_TUNABLE_COUNT][ETH_GSTRING_LEN]; extern const char phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN]; extern const char link_mode_names[][ETH_GSTRING_LEN]; extern const char netif_msg_class_names[][ETH_GSTRING_LEN]; extern const char wol_mode_names[][ETH_GSTRING_LEN]; extern const char sof_timestamping_names[][ETH_GSTRING_LEN]; extern const char ts_tx_type_names[][ETH_GSTRING_LEN]; extern const char ts_rx_filter_names[][ETH_GSTRING_LEN]; extern const char ts_flags_names[][ETH_GSTRING_LEN]; extern const char udp_tunnel_type_names[][ETH_GSTRING_LEN]; int __ethtool_get_link(struct net_device *dev); bool convert_legacy_settings_to_link_ksettings( struct ethtool_link_ksettings *link_ksettings, const struct ethtool_cmd *legacy_settings); int ethtool_check_max_channel(struct net_device *dev, struct ethtool_channels channels, struct genl_info *info); struct ethtool_rxfh_context * ethtool_rxfh_ctx_alloc(const struct ethtool_ops *ops, u32 indir_size, u32 key_size); int ethtool_check_rss_ctx_busy(struct net_device *dev, u32 rss_context); int ethtool_rxfh_config_is_sym(u64 rxfh); void ethtool_ringparam_get_cfg(struct net_device *dev, struct ethtool_ringparam *param, struct kernel_ethtool_ringparam *kparam, struct netlink_ext_ack *extack); int ethtool_get_rx_ring_count(struct net_device *dev); int __ethtool_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info); int ethtool_get_ts_info_by_phc(struct net_device *dev, struct kernel_ethtool_ts_info *info, struct hwtstamp_provider_desc *hwprov_desc); int ethtool_net_get_ts_info_by_phc(struct net_device *dev, struct kernel_ethtool_ts_info *info, struct hwtstamp_provider_desc *hwprov_desc); struct phy_device * ethtool_phy_get_ts_info_by_phc(struct net_device *dev, struct kernel_ethtool_ts_info *info, struct hwtstamp_provider_desc *hwprov_desc); bool net_support_hwtstamp_qualifier(struct net_device *dev, enum hwtstamp_provider_qualifier qualifier); extern const struct ethtool_phy_ops *ethtool_phy_ops; extern const struct ethtool_pse_ops *ethtool_pse_ops; int ethtool_get_module_info_call(struct net_device *dev, struct ethtool_modinfo *modinfo); int ethtool_get_module_eeprom_call(struct net_device *dev, struct ethtool_eeprom *ee, u8 *data); bool __ethtool_dev_mm_supported(struct net_device *dev); /** * ethtool_nl_msg_needs_rtnl() - does this Netlink cmd need rtnl_lock? * @dev: target device * @cmd: ETHTOOL_MSG_* Netlink command value * * Return: true if @cmd is a command for which @dev has opted-in to * keeping rtnl_lock held across the call (via op_needs_rtnl). */ static inline bool ethtool_nl_msg_needs_rtnl(const struct net_device *dev, u8 cmd) { const struct ethtool_ops *ops = dev->ethtool_ops; switch (cmd) { case ETHTOOL_MSG_LINKINFO_GET: case ETHTOOL_MSG_LINKINFO_SET: case ETHTOOL_MSG_LINKMODES_GET: case ETHTOOL_MSG_LINKMODES_SET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_LINKSETTINGS; case ETHTOOL_MSG_PRIVFLAGS_SET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SPFLAGS; case ETHTOOL_MSG_RINGS_SET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM; case ETHTOOL_MSG_CHANNELS_SET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SCHANNELS; case ETHTOOL_MSG_COALESCE_SET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SCOALESCE; case ETHTOOL_MSG_PAUSE_GET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_GPAUSEPARAM; case ETHTOOL_MSG_PAUSE_SET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM; case ETHTOOL_MSG_RSS_SET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_RSS; case ETHTOOL_MSG_LINKSTATE_GET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_GLINK; case ETHTOOL_MSG_TSCONFIG_GET: case ETHTOOL_MSG_TSCONFIG_SET: /* tsconfig calls ndos (ndo_hwtstamp_set/get), not ethtool ops. * Also, there is no corresponding ethtool ioctl, therefore * these cases are Netlink-only. */ return true; } return false; } /** * ethtool_ioctl_needs_rtnl() - does this legacy ioctl cmd need rtnl_lock? * @dev: target device * @ethcmd: ETHTOOL_* ioctl command value * * Return: true if @ethcmd is a command for which @dev has opted-in to * keeping rtnl_lock held across the call (via op_needs_rtnl). */ static inline bool ethtool_ioctl_needs_rtnl(const struct net_device *dev, u32 ethcmd) { const struct ethtool_ops *ops = dev->ethtool_ops; switch (ethcmd) { case ETHTOOL_GLINKSETTINGS: case ETHTOOL_GSET: case ETHTOOL_SLINKSETTINGS: case ETHTOOL_SSET: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_LINKSETTINGS; case ETHTOOL_SPFLAGS: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SPFLAGS; case ETHTOOL_SRINGPARAM: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM; case ETHTOOL_SCHANNELS: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SCHANNELS; case ETHTOOL_SCOALESCE: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SCOALESCE; case ETHTOOL_GPAUSEPARAM: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_GPAUSEPARAM; case ETHTOOL_SPAUSEPARAM: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM; case ETHTOOL_SRSSH: case ETHTOOL_SRXFH: case ETHTOOL_SRXFHINDIR: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_RSS; case ETHTOOL_GLINK: return ops->op_needs_rtnl & ETHTOOL_OP_NEEDS_RTNL_GLINK; } return false; } #if IS_ENABLED(CONFIG_ETHTOOL_NETLINK) void ethtool_rss_notify(struct net_device *dev, u32 type, u32 rss_context); #else static inline void ethtool_rss_notify(struct net_device *dev, u32 type, u32 rss_context) { } #endif #endif /* _ETHTOOL_COMMON_H */