From e1a9fa83f9821d0b04c8da94d6f355c54a307541 Mon Sep 17 00:00:00 2001 From: Algernon Date: Wed, 15 Nov 2023 11:08:12 +0800 Subject: [PATCH 278/283] net: hns3: Fallback ethtool's modification of lane driver inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EN49 -------------------------------- Signed-off-by: Xiaodong Li --- Documentation/networking/ethtool-netlink.rst | 26 - drivers/net/ethernet/hisilicon/hns3/hnae3.h | 11 +- .../hns3/hns3_common/hclge_comm_cmd.c | 1 - .../hns3/hns3_common/hclge_comm_cmd.h | 1 - .../ethernet/hisilicon/hns3/hns3_debugfs.c | 3 - .../ethernet/hisilicon/hns3/hns3_ethtool.c | 27 +- .../hisilicon/hns3/hns3pf/hclge_main.c | 22 +- .../hisilicon/hns3/hns3pf/hclge_main.h | 3 +- .../hisilicon/hns3/hns3pf/hclge_mdio.c | 2 +- .../hisilicon/hns3/hns3pf/hclge_sysfs.c | 3 - .../hisilicon/hns3/hns3vf/hclgevf_main.c | 2 +- include/linux/ethtool.h | 6 - include/net/netlink.h | 7 - include/uapi/linux/ethtool.h | 14 - include/uapi/linux/ethtool_netlink.h | 3 - net/ethtool/Makefile | 2 +- net/ethtool/linkmodes.c | 512 ------------------ net/ethtool/netlink.h | 2 - 18 files changed, 24 insertions(+), 623 deletions(-) delete mode 100644 net/ethtool/linkmodes.c diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst index 01da978de86d..c0c33704aa96 100644 --- a/Documentation/networking/ethtool-netlink.rst +++ b/Documentation/networking/ethtool-netlink.rst @@ -224,32 +224,6 @@ an ``ACT_REPLY`` message. Performing an action also triggers a notification Later sections describe the format and semantics of these messages. -LINKMODES_SET -============= - -Request contents: - - ========================================== ====== ========================== - ``ETHTOOL_A_LINKMODES_HEADER`` nested request header - ``ETHTOOL_A_LINKMODES_AUTONEG`` u8 autonegotiation status - ``ETHTOOL_A_LINKMODES_OURS`` bitset advertised link modes - ``ETHTOOL_A_LINKMODES_PEER`` bitset partner link modes - ``ETHTOOL_A_LINKMODES_SPEED`` u32 link speed (Mb/s) - ``ETHTOOL_A_LINKMODES_DUPLEX`` u8 duplex mode - ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG`` u8 Master/slave port mode - ``ETHTOOL_A_LINKMODES_LANES`` u32 lanes - ========================================== ====== ========================== - -``ETHTOOL_A_LINKMODES_OURS`` bit set allows setting advertised link modes. If -autonegotiation is on (either set now or kept from before), advertised modes -are not changed (no ``ETHTOOL_A_LINKMODES_OURS`` attribute) and at least one -of speed, duplex and lanes is specified, kernel adjusts advertised modes to all -supported modes matching speed, duplex, lanes or all (whatever is specified). -This autoselection is done on ethtool side with ioctl interface, netlink -interface is supposed to allow requesting changes without knowing what exactly -kernel supports. - - RINGS_GET ========= diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 422f50b36c22..a4353ef510dd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -104,7 +104,6 @@ enum HNAE3_DEV_CAP_BITS { HNAE3_DEV_SUPPORT_MC_MAC_MNG_B, HNAE3_DEV_SUPPORT_CQ_B, HNAE3_DEV_SUPPORT_FEC_STATS_B, - HNAE3_DEV_SUPPORT_LANE_NUM_B, HNAE3_DEV_SUPPORT_WOL_B, HNAE3_DEV_SUPPORT_VF_FAULT_B, HNAE3_DEV_SUPPORT_NOTIFY_PKT_B, @@ -177,17 +176,12 @@ enum HNAE3_DEV_CAP_BITS { #define hnae3_ae_dev_cq_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_CQ_B, (ae_dev)->caps) -#define hnae3_ae_dev_lane_num_supported(ae_dev) \ - test_bit(HNAE3_DEV_SUPPORT_LANE_NUM_B, (ae_dev)->caps) - #define hnae3_ae_dev_wol_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_WOL_B, (ae_dev)->caps) #define hnae3_ae_dev_notify_pkt_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_NOTIFY_PKT_B, (ae_dev)->caps) -#define hnae3_ae_dev_lane_num_supported(ae_dev) \ - test_bit(HNAE3_DEV_SUPPORT_LANE_NUM_B, (ae_dev)->caps) #define hnae3_ae_dev_fec_stats_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_FEC_STATS_B, (ae_dev)->caps) #define hnae3_ae_dev_tm_flush_supported(hdev) \ @@ -626,10 +620,9 @@ struct hnae3_ae_ops { void (*client_stop)(struct hnae3_handle *handle); int (*get_status)(struct hnae3_handle *handle); void (*get_ksettings_an_result)(struct hnae3_handle *handle, - u8 *auto_neg, u32 *speed, u8 *duplex, - u32 *lane_num); + u8 *auto_neg, u32 *speed, u8 *duplex); int (*cfg_mac_speed_dup_h)(struct hnae3_handle *handle, int speed, - u8 duplex, u8 lane_num); + u8 duplex); void (*get_media_type)(struct hnae3_handle *handle, u8 *media_type, u8 *module_type); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index 78321511798a..756627abd5fe 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -155,7 +155,6 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = { {HCLGE_COMM_CAP_GRO_B, HNAE3_DEV_SUPPORT_GRO_B}, {HCLGE_COMM_CAP_FD_B, HNAE3_DEV_SUPPORT_FD_B}, {HCLGE_COMM_CAP_FEC_STATS_B, HNAE3_DEV_SUPPORT_FEC_STATS_B}, - {HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B}, {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, {HCLGE_COMM_CAP_NOTIFY_PKT_B, HNAE3_DEV_SUPPORT_NOTIFY_PKT_B}, {HCLGE_COMM_CAP_TM_FLUSH_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B}, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h index 8477e9f1a3d7..248fab27931b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h @@ -344,7 +344,6 @@ enum HCLGE_COMM_CAP_BITS { HCLGE_COMM_CAP_GRO_B = 20, HCLGE_COMM_CAP_FD_B = 21, HCLGE_COMM_CAP_FEC_STATS_B = 25, - HCLGE_COMM_CAP_LANE_NUM_B = 27, HCLGE_COMM_CAP_WOL_B = 28, HCLGE_COMM_CAP_NOTIFY_PKT_B = 29, HCLGE_COMM_CAP_TM_FLUSH_B = 31, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index c5234d1d078f..23fc3897a662 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -391,9 +391,6 @@ static struct hns3_dbg_cap_info hns3_dbg_cap[] = { }, { .name = "support FEC statistics", .cap_bit = HNAE3_DEV_SUPPORT_FEC_STATS_B, - }, { - .name = "support lane num", - .cap_bit = HNAE3_DEV_SUPPORT_LANE_NUM_B, }, { .name = "support tm flush", .cap_bit = HNAE3_DEV_SUPPORT_TM_FLUSH_B, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 21675ff52380..c951f7c4eea9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -766,8 +766,7 @@ static void hns3_get_ksettings(struct hnae3_handle *h, ops->get_ksettings_an_result(h, &cmd->base.autoneg, &cmd->base.speed, - &cmd->base.duplex, - &cmd->lanes); + &cmd->base.duplex); /* 2.get link mode */ if (ops->get_link_mode) @@ -849,7 +848,6 @@ static int hns3_check_ksettings_param(const struct net_device *netdev, const struct hnae3_ae_ops *ops = handle->ae_algo->ops; u8 module_type = HNAE3_MODULE_TYPE_UNKNOWN; u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN; - u32 lane_num; u8 autoneg; u32 speed; u8 duplex; @@ -862,10 +860,9 @@ static int hns3_check_ksettings_param(const struct net_device *netdev, return 0; if (ops->get_ksettings_an_result) { - ops->get_ksettings_an_result(handle, &autoneg, &speed, - &duplex, &lane_num); + ops->get_ksettings_an_result(handle, &autoneg, &speed, &duplex); if (cmd->base.autoneg == autoneg && cmd->base.speed == speed && - cmd->base.duplex == duplex && cmd->lanes == lane_num) + cmd->base.duplex == duplex) return 0; } @@ -902,14 +899,12 @@ static int hns3_set_link_ksettings(struct net_device *netdev, if (cmd->base.speed == SPEED_1000 && cmd->base.duplex == DUPLEX_HALF) return -EINVAL; - if (cmd->lanes && !hnae3_ae_dev_lane_num_supported(ae_dev)) - return -EOPNOTSUPP; - - netif_dbg(handle, drv, netdev, - "set link(%s): autoneg=%u, speed=%u, duplex=%u, lanes=%u\n", - netdev->phydev ? "phy" : "mac", - cmd->base.autoneg, cmd->base.speed, cmd->base.duplex, - cmd->lanes); + if (netif_msg_ifdown(handle)) + netdev_info(netdev, + "set link(%s): autoneg=%u, speed=%u, duplex=%u\n", + netdev->phydev ? "phy" : "mac", + cmd->base.autoneg, cmd->base.speed, + cmd->base.duplex); /* Only support ksettings_set for netdev with phy attached for now */ if (netdev->phydev) { @@ -947,8 +942,7 @@ static int hns3_set_link_ksettings(struct net_device *netdev, if (ops->cfg_mac_speed_dup_h) ret = ops->cfg_mac_speed_dup_h(handle, cmd->base.speed, - cmd->base.duplex, - (u8)(cmd->lanes)); + cmd->base.duplex); return ret; } @@ -2050,7 +2044,6 @@ static const struct ethtool_ops hns3vf_ethtool_ops = { static const struct ethtool_ops hns3_ethtool_ops = { .supported_coalesce_params = HNS3_ETHTOOL_COALESCE, .supported_ring_params = HNS3_ETHTOOL_RING, - .cap_link_lanes_supported = true, .self_test = hns3_self_test, .get_drvinfo = hns3_get_drvinfo, .get_link = hns3_get_link, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index bcc28501475d..0e24115ad161 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -2792,37 +2792,33 @@ int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed, return 0; } -int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, - u8 duplex, u8 lane_num) +int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex) { struct hclge_mac *mac = &hdev->hw.mac; int ret; duplex = hclge_check_speed_dup(duplex, speed); if (!mac->support_autoneg && mac->speed == speed && - mac->duplex == duplex && - (mac->lane_num == lane_num || lane_num == 0)) + mac->duplex == duplex) return 0; - ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex, lane_num); + ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex, 0); if (ret) return ret; hdev->hw.mac.speed = speed; hdev->hw.mac.duplex = duplex; - if (!lane_num) - hdev->hw.mac.lane_num = lane_num; return 0; } static int hclge_cfg_mac_speed_dup_h(struct hnae3_handle *handle, int speed, - u8 duplex, u8 lane_num) + u8 duplex) { struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; - return hclge_cfg_mac_speed_dup(hdev, speed, duplex, lane_num); + return hclge_cfg_mac_speed_dup(hdev, speed, duplex); } static int hclge_set_autoneg_en(struct hclge_dev *hdev, bool enable) @@ -3633,13 +3629,13 @@ static int hclge_update_port_info(struct hclge_dev *hdev) return 0; } return hclge_cfg_mac_speed_dup(hdev, mac->speed, - HCLGE_MAC_FULL, mac->lane_num); + HCLGE_MAC_FULL); } else { if (speed == HCLGE_MAC_SPEED_UNKNOWN) return 0; /* do nothing if no SFP */ /* must config full duplex for SFP */ - return hclge_cfg_mac_speed_dup(hdev, speed, HCLGE_MAC_FULL, 0); + return hclge_cfg_mac_speed_dup(hdev, speed, HCLGE_MAC_FULL); } } @@ -11139,7 +11135,7 @@ static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg, static void hclge_get_ksettings_an_result(struct hnae3_handle *handle, u8 *auto_neg, u32 *speed, - u8 *duplex, u32 *lane_num) + u8 *duplex) { struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -11150,8 +11146,6 @@ static void hclge_get_ksettings_an_result(struct hnae3_handle *handle, *duplex = hdev->hw.mac.duplex; if (auto_neg) *auto_neg = hdev->hw.mac.autoneg; - if (lane_num) - *lane_num = hdev->hw.mac.lane_num; } void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 2311dc45ff6e..be2f888209f3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -1153,8 +1153,7 @@ static inline bool hclge_is_reset_pending(struct hclge_dev *hdev) } int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport); -int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, - u8 duplex, u8 lane_num); +int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex); int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, u16 vlan_id, bool is_kill); int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c index 11723c13c96a..79e6760b3fc7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c @@ -187,7 +187,7 @@ static void hclge_mac_adjust_link(struct net_device *netdev) speed = netdev->phydev->speed; duplex = netdev->phydev->duplex; - ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex, 0); + ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); if (ret) netdev_err(netdev, "failed to adjust link.\n"); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_sysfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_sysfs.c index 6840d7bda82e..3bbc33761254 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_sysfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_sysfs.c @@ -78,9 +78,6 @@ int hclge_register_sysfs(struct hclge_dev *hdev) { int ret; - if (!hnae3_ae_dev_lane_num_supported(hdev->ae_dev)) - return 0; - ret = device_create_file(&hdev->pdev->dev, hclge_hw_attrs_list[0]); if (ret) dev_err(&hdev->pdev->dev, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 22f8dfe86df8..091240208893 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -3649,7 +3649,7 @@ static int hclgevf_get_status(struct hnae3_handle *handle) static void hclgevf_get_ksettings_an_result(struct hnae3_handle *handle, u8 *auto_neg, u32 *speed, - u8 *duplex, u32 *lane_num) + u8 *duplex) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 4bc3cd4060da..bf14a439afc2 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -149,9 +149,6 @@ struct ethtool_link_ksettings { __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising); } link_modes; -#ifndef __GENKSYMS__ - u32 lanes; -#endif }; /** @@ -295,8 +292,6 @@ struct ethtool_fec_stats { /** * struct ethtool_ops - optional netdev operations - * @cap_link_lanes_supported: indicates if the driver supports lanes - * parameter. * @supported_coalesce_params: supported types of interrupt coalescing. * @supported_ring_params: supported ring params. * @get_drvinfo: Report driver/device information. Should only set the @@ -442,7 +437,6 @@ struct ethtool_fec_stats { */ struct ethtool_ops { #ifndef __GENKSYMS__ - u32 cap_link_lanes_supported:1; u32 supported_coalesce_params; u32 supported_ring_params; #endif diff --git a/include/net/netlink.h b/include/net/netlink.h index e91076f81d3e..d9c642558255 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -278,13 +278,6 @@ struct nla_policy { tp == NLA_MSECS || \ tp == NLA_BINARY) + tp) -#define NLA_POLICY_RANGE(tp, _min, _max) { \ - .type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \ - .validation_type = NLA_VALIDATE_RANGE, \ - .min = _min, \ - .max = _max \ -} - #define NLA_POLICY_MIN(tp, _min) { \ .type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \ .validation_type = NLA_VALIDATE_MIN, \ diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 4f19dca5fcfa..0649b8295feb 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1742,8 +1742,6 @@ enum ethtool_link_mode_bit_indices { #define SPEED_50000 50000 #define SPEED_56000 56000 #define SPEED_100000 100000 -#define SPEED_200000 200000 -#define SPEED_400000 400000 #define SPEED_UNKNOWN -1 @@ -1769,18 +1767,6 @@ static inline int ethtool_validate_duplex(__u8 duplex) return 0; } -#define MASTER_SLAVE_CFG_UNSUPPORTED 0 -#define MASTER_SLAVE_CFG_UNKNOWN 1 -#define MASTER_SLAVE_CFG_MASTER_PREFERRED 2 -#define MASTER_SLAVE_CFG_SLAVE_PREFERRED 3 -#define MASTER_SLAVE_CFG_MASTER_FORCE 4 -#define MASTER_SLAVE_CFG_SLAVE_FORCE 5 -#define MASTER_SLAVE_STATE_UNSUPPORTED 0 -#define MASTER_SLAVE_STATE_UNKNOWN 1 -#define MASTER_SLAVE_STATE_MASTER 2 -#define MASTER_SLAVE_STATE_SLAVE 3 -#define MASTER_SLAVE_STATE_ERR 4 - /* Which connector port. */ #define PORT_TP 0x00 #define PORT_AUI 0x01 diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index 3b7ed0fe545a..a616a033c5be 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -203,9 +203,6 @@ enum { ETHTOOL_A_LINKMODES_PEER, /* bitset */ ETHTOOL_A_LINKMODES_SPEED, /* u32 */ ETHTOOL_A_LINKMODES_DUPLEX, /* u8 */ - ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, /* u8 */ - ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, /* u8 */ - ETHTOOL_A_LINKMODES_LANES, /* u32 */ /* add new constants above here */ __ETHTOOL_A_LINKMODES_CNT, diff --git a/net/ethtool/Makefile b/net/ethtool/Makefile index 8900e8ff22f8..892eb657f722 100644 --- a/net/ethtool/Makefile +++ b/net/ethtool/Makefile @@ -4,4 +4,4 @@ obj-y += ioctl.o common.o obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o -ethtool_nl-y := netlink.o rings.o linkmodes.o bitset.o fec.o \ No newline at end of file +ethtool_nl-y := netlink.o rings.o bitset.o fec.o diff --git a/net/ethtool/linkmodes.c b/net/ethtool/linkmodes.c deleted file mode 100644 index f8f3fc74ac78..000000000000 --- a/net/ethtool/linkmodes.c +++ /dev/null @@ -1,512 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include "netlink.h" -#include "common.h" -#include "bitset.h" - -struct linkmodes_req_info { - struct ethnl_req_info base; -}; - -struct linkmodes_reply_data { - struct ethnl_reply_data base; - struct ethtool_link_ksettings ksettings; - struct ethtool_link_settings *lsettings; - bool peer_empty; -}; - -#define LINKMODES_REPDATA(__reply_base) \ - container_of(__reply_base, struct linkmodes_reply_data, base) - -const struct nla_policy ethnl_linkmodes_get_policy[] = { - [ETHTOOL_A_LINKMODES_HEADER] = - NLA_POLICY_NESTED(ethnl_header_policy), -}; - -static int linkmodes_prepare_data(const struct ethnl_req_info *req_base, - struct ethnl_reply_data *reply_base, - struct genl_info *info) -{ - struct linkmodes_reply_data *data = LINKMODES_REPDATA(reply_base); - struct net_device *dev = reply_base->dev; - int ret; - - data->lsettings = &data->ksettings.base; - - ret = ethnl_ops_begin(dev); - if (ret < 0) - return ret; - - ret = __ethtool_get_link_ksettings(dev, &data->ksettings); - if (ret < 0 && info) { - GENL_SET_ERR_MSG(info, "failed to retrieve link settings"); - goto out; - } - - data->peer_empty = - bitmap_empty(data->ksettings.link_modes.lp_advertising, - __ETHTOOL_LINK_MODE_MASK_NBITS); - -out: - ethnl_ops_complete(dev); - return ret; -} - -static int linkmodes_reply_size(const struct ethnl_req_info *req_base, - const struct ethnl_reply_data *reply_base) -{ - const struct linkmodes_reply_data *data = LINKMODES_REPDATA(reply_base); - const struct ethtool_link_ksettings *ksettings = &data->ksettings; - const struct ethtool_link_settings *lsettings = &ksettings->base; - bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS; - int len, ret; - - len = nla_total_size(sizeof(u8)) /* LINKMODES_AUTONEG */ - + nla_total_size(sizeof(u32)) /* LINKMODES_SPEED */ - + nla_total_size(sizeof(u8)) /* LINKMODES_DUPLEX */ - + 0; - ret = ethnl_bitset_size(ksettings->link_modes.advertising, - ksettings->link_modes.supported, - __ETHTOOL_LINK_MODE_MASK_NBITS, - link_mode_names, compact); - if (ret < 0) - return ret; - len += ret; - if (!data->peer_empty) { - ret = ethnl_bitset_size(ksettings->link_modes.lp_advertising, - NULL, __ETHTOOL_LINK_MODE_MASK_NBITS, - link_mode_names, compact); - if (ret < 0) - return ret; - len += ret; - } - - if (lsettings->master_slave_cfg != MASTER_SLAVE_CFG_UNSUPPORTED) - len += nla_total_size(sizeof(u8)); - - if (lsettings->master_slave_state != MASTER_SLAVE_STATE_UNSUPPORTED) - len += nla_total_size(sizeof(u8)); - - return len; -} - -static int linkmodes_fill_reply(struct sk_buff *skb, - const struct ethnl_req_info *req_base, - const struct ethnl_reply_data *reply_base) -{ - const struct linkmodes_reply_data *data = LINKMODES_REPDATA(reply_base); - const struct ethtool_link_ksettings *ksettings = &data->ksettings; - const struct ethtool_link_settings *lsettings = &ksettings->base; - bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS; - int ret; - - if (nla_put_u8(skb, ETHTOOL_A_LINKMODES_AUTONEG, lsettings->autoneg)) - return -EMSGSIZE; - - ret = ethnl_put_bitset(skb, ETHTOOL_A_LINKMODES_OURS, - ksettings->link_modes.advertising, - ksettings->link_modes.supported, - __ETHTOOL_LINK_MODE_MASK_NBITS, link_mode_names, - compact); - if (ret < 0) - return -EMSGSIZE; - if (!data->peer_empty) { - ret = ethnl_put_bitset(skb, ETHTOOL_A_LINKMODES_PEER, - ksettings->link_modes.lp_advertising, - NULL, __ETHTOOL_LINK_MODE_MASK_NBITS, - link_mode_names, compact); - if (ret < 0) - return -EMSGSIZE; - } - - if (nla_put_u32(skb, ETHTOOL_A_LINKMODES_SPEED, lsettings->speed) || - nla_put_u8(skb, ETHTOOL_A_LINKMODES_DUPLEX, lsettings->duplex)) - return -EMSGSIZE; - - if (lsettings->master_slave_cfg != MASTER_SLAVE_CFG_UNSUPPORTED && - nla_put_u8(skb, ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, - lsettings->master_slave_cfg)) - return -EMSGSIZE; - - if (lsettings->master_slave_state != MASTER_SLAVE_STATE_UNSUPPORTED && - nla_put_u8(skb, ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, - lsettings->master_slave_state)) - return -EMSGSIZE; - - return 0; -} - -const struct ethnl_request_ops ethnl_linkmodes_request_ops = { - .request_cmd = ETHTOOL_MSG_LINKMODES_GET, - .reply_cmd = ETHTOOL_MSG_LINKMODES_GET_REPLY, - .hdr_attr = ETHTOOL_A_LINKMODES_HEADER, - .req_info_size = sizeof(struct linkmodes_req_info), - .reply_data_size = sizeof(struct linkmodes_reply_data), - - .prepare_data = linkmodes_prepare_data, - .reply_size = linkmodes_reply_size, - .fill_reply = linkmodes_fill_reply, -}; - -/* LINKMODES_SET */ - -struct link_mode_info { - int speed; - u8 lanes; - u8 duplex; -}; - -#define __LINK_MODE_LANES_CR 1 -#define __LINK_MODE_LANES_CR2 2 -#define __LINK_MODE_LANES_CR4 4 -#define __LINK_MODE_LANES_CR8 8 -#define __LINK_MODE_LANES_DR 1 -#define __LINK_MODE_LANES_DR2 2 -#define __LINK_MODE_LANES_DR4 4 -#define __LINK_MODE_LANES_DR8 8 -#define __LINK_MODE_LANES_KR 1 -#define __LINK_MODE_LANES_KR2 2 -#define __LINK_MODE_LANES_KR4 4 -#define __LINK_MODE_LANES_KR8 8 -#define __LINK_MODE_LANES_SR 1 -#define __LINK_MODE_LANES_SR2 2 -#define __LINK_MODE_LANES_SR4 4 -#define __LINK_MODE_LANES_SR8 8 -#define __LINK_MODE_LANES_ER 1 -#define __LINK_MODE_LANES_KX 1 -#define __LINK_MODE_LANES_KX4 4 -#define __LINK_MODE_LANES_LR 1 -#define __LINK_MODE_LANES_LR4 4 -#define __LINK_MODE_LANES_LR4_ER4 4 -#define __LINK_MODE_LANES_LR_ER_FR 1 -#define __LINK_MODE_LANES_LR2_ER2_FR2 2 -#define __LINK_MODE_LANES_LR4_ER4_FR4 4 -#define __LINK_MODE_LANES_LR8_ER8_FR8 8 -#define __LINK_MODE_LANES_LRM 1 -#define __LINK_MODE_LANES_MLD2 2 -#define __LINK_MODE_LANES_T 1 -#define __LINK_MODE_LANES_T1 1 -#define __LINK_MODE_LANES_X 1 -#define __LINK_MODE_LANES_FX 1 - -#define __DEFINE_LINK_MODE_PARAMS(_speed, _type, _duplex) \ - [ETHTOOL_LINK_MODE(_speed, _type, _duplex)] = { \ - .speed = SPEED_ ## _speed, \ - .lanes = __LINK_MODE_LANES_ ## _type, \ - .duplex = __DUPLEX_ ## _duplex \ - } -#define __DUPLEX_Half DUPLEX_HALF -#define __DUPLEX_Full DUPLEX_FULL -#define __DEFINE_SPECIAL_MODE_PARAMS(_mode) \ - [ETHTOOL_LINK_MODE_ ## _mode ## _BIT] = { \ - .speed = SPEED_UNKNOWN, \ - .lanes = 0, \ - .duplex = DUPLEX_UNKNOWN, \ - } - -static const struct link_mode_info link_mode_params[] = { - __DEFINE_LINK_MODE_PARAMS(10, T, Half), - __DEFINE_LINK_MODE_PARAMS(10, T, Full), - __DEFINE_LINK_MODE_PARAMS(100, T, Half), - __DEFINE_LINK_MODE_PARAMS(100, T, Full), - __DEFINE_LINK_MODE_PARAMS(1000, T, Half), - __DEFINE_LINK_MODE_PARAMS(1000, T, Full), - __DEFINE_SPECIAL_MODE_PARAMS(Autoneg), - __DEFINE_SPECIAL_MODE_PARAMS(TP), - __DEFINE_SPECIAL_MODE_PARAMS(AUI), - __DEFINE_SPECIAL_MODE_PARAMS(MII), - __DEFINE_SPECIAL_MODE_PARAMS(FIBRE), - __DEFINE_SPECIAL_MODE_PARAMS(BNC), - __DEFINE_LINK_MODE_PARAMS(10000, T, Full), - __DEFINE_SPECIAL_MODE_PARAMS(Pause), - __DEFINE_SPECIAL_MODE_PARAMS(Asym_Pause), - __DEFINE_LINK_MODE_PARAMS(2500, X, Full), - __DEFINE_SPECIAL_MODE_PARAMS(Backplane), - __DEFINE_LINK_MODE_PARAMS(1000, KX, Full), - __DEFINE_LINK_MODE_PARAMS(10000, KX4, Full), - __DEFINE_LINK_MODE_PARAMS(10000, KR, Full), - [ETHTOOL_LINK_MODE_10000baseR_FEC_BIT] = { - .speed = SPEED_10000, - .duplex = DUPLEX_FULL, - }, - __DEFINE_LINK_MODE_PARAMS(20000, MLD2, Full), - __DEFINE_LINK_MODE_PARAMS(20000, KR2, Full), - __DEFINE_LINK_MODE_PARAMS(40000, KR4, Full), - __DEFINE_LINK_MODE_PARAMS(40000, CR4, Full), - __DEFINE_LINK_MODE_PARAMS(40000, SR4, Full), - __DEFINE_LINK_MODE_PARAMS(40000, LR4, Full), - __DEFINE_LINK_MODE_PARAMS(56000, KR4, Full), - __DEFINE_LINK_MODE_PARAMS(56000, CR4, Full), - __DEFINE_LINK_MODE_PARAMS(56000, SR4, Full), - __DEFINE_LINK_MODE_PARAMS(56000, LR4, Full), - __DEFINE_LINK_MODE_PARAMS(25000, CR, Full), - __DEFINE_LINK_MODE_PARAMS(25000, KR, Full), - __DEFINE_LINK_MODE_PARAMS(25000, SR, Full), - __DEFINE_LINK_MODE_PARAMS(50000, CR2, Full), - __DEFINE_LINK_MODE_PARAMS(50000, KR2, Full), - __DEFINE_LINK_MODE_PARAMS(100000, KR4, Full), - __DEFINE_LINK_MODE_PARAMS(100000, SR4, Full), - __DEFINE_LINK_MODE_PARAMS(100000, CR4, Full), - __DEFINE_LINK_MODE_PARAMS(100000, LR4_ER4, Full), - __DEFINE_LINK_MODE_PARAMS(50000, SR2, Full), - __DEFINE_LINK_MODE_PARAMS(1000, X, Full), - __DEFINE_LINK_MODE_PARAMS(10000, CR, Full), - __DEFINE_LINK_MODE_PARAMS(10000, SR, Full), - __DEFINE_LINK_MODE_PARAMS(10000, LR, Full), - __DEFINE_LINK_MODE_PARAMS(10000, LRM, Full), - __DEFINE_LINK_MODE_PARAMS(10000, ER, Full), - __DEFINE_LINK_MODE_PARAMS(2500, T, Full), - __DEFINE_LINK_MODE_PARAMS(5000, T, Full), - __DEFINE_SPECIAL_MODE_PARAMS(FEC_NONE), - __DEFINE_SPECIAL_MODE_PARAMS(FEC_RS), - __DEFINE_SPECIAL_MODE_PARAMS(FEC_BASER), - __DEFINE_LINK_MODE_PARAMS(50000, KR, Full), - __DEFINE_LINK_MODE_PARAMS(50000, SR, Full), - __DEFINE_LINK_MODE_PARAMS(50000, CR, Full), - __DEFINE_LINK_MODE_PARAMS(50000, LR_ER_FR, Full), - __DEFINE_LINK_MODE_PARAMS(50000, DR, Full), - __DEFINE_LINK_MODE_PARAMS(100000, KR2, Full), - __DEFINE_LINK_MODE_PARAMS(100000, SR2, Full), - __DEFINE_LINK_MODE_PARAMS(100000, CR2, Full), - __DEFINE_LINK_MODE_PARAMS(100000, LR2_ER2_FR2, Full), - __DEFINE_LINK_MODE_PARAMS(100000, DR2, Full), - __DEFINE_LINK_MODE_PARAMS(200000, KR4, Full), - __DEFINE_LINK_MODE_PARAMS(200000, SR4, Full), - __DEFINE_LINK_MODE_PARAMS(200000, LR4_ER4_FR4, Full), - __DEFINE_LINK_MODE_PARAMS(200000, DR4, Full), - __DEFINE_LINK_MODE_PARAMS(200000, CR4, Full), - __DEFINE_LINK_MODE_PARAMS(100, T1, Full), - __DEFINE_LINK_MODE_PARAMS(1000, T1, Full), - __DEFINE_LINK_MODE_PARAMS(400000, KR8, Full), - __DEFINE_LINK_MODE_PARAMS(400000, SR8, Full), - __DEFINE_LINK_MODE_PARAMS(400000, LR8_ER8_FR8, Full), - __DEFINE_LINK_MODE_PARAMS(400000, DR8, Full), - __DEFINE_LINK_MODE_PARAMS(400000, CR8, Full), - __DEFINE_SPECIAL_MODE_PARAMS(FEC_LLRS), - __DEFINE_LINK_MODE_PARAMS(100000, KR, Full), - __DEFINE_LINK_MODE_PARAMS(100000, SR, Full), - __DEFINE_LINK_MODE_PARAMS(100000, LR_ER_FR, Full), - __DEFINE_LINK_MODE_PARAMS(100000, DR, Full), - __DEFINE_LINK_MODE_PARAMS(100000, CR, Full), - __DEFINE_LINK_MODE_PARAMS(200000, KR2, Full), - __DEFINE_LINK_MODE_PARAMS(200000, SR2, Full), - __DEFINE_LINK_MODE_PARAMS(200000, LR2_ER2_FR2, Full), - __DEFINE_LINK_MODE_PARAMS(200000, DR2, Full), - __DEFINE_LINK_MODE_PARAMS(200000, CR2, Full), - __DEFINE_LINK_MODE_PARAMS(400000, KR4, Full), - __DEFINE_LINK_MODE_PARAMS(400000, SR4, Full), - __DEFINE_LINK_MODE_PARAMS(400000, LR4_ER4_FR4, Full), - __DEFINE_LINK_MODE_PARAMS(400000, DR4, Full), - __DEFINE_LINK_MODE_PARAMS(400000, CR4, Full), - __DEFINE_LINK_MODE_PARAMS(100, FX, Half), - __DEFINE_LINK_MODE_PARAMS(100, FX, Full), -}; - -const struct nla_policy ethnl_linkmodes_set_policy[] = { - [ETHTOOL_A_LINKMODES_HEADER] = - NLA_POLICY_NESTED(ethnl_header_policy), - [ETHTOOL_A_LINKMODES_AUTONEG] = { .type = NLA_U8 }, - [ETHTOOL_A_LINKMODES_OURS] = { .type = NLA_NESTED }, - [ETHTOOL_A_LINKMODES_SPEED] = { .type = NLA_U32 }, - [ETHTOOL_A_LINKMODES_DUPLEX] = { .type = NLA_U8 }, - [ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG] = { .type = NLA_U8 }, - [ETHTOOL_A_LINKMODES_LANES] = - NLA_POLICY_RANGE(NLA_U32, 1, 8), -}; - -/* Set advertised link modes to all supported modes matching requested speed, - * lanes and duplex values. Called when autonegotiation is on, speed, lanes or - * duplex is requested but no link mode change. This is done in userspace with - * ioctl() interface, move it into kernel for netlink. - * Returns true if advertised modes bitmap was modified. - */ -static bool ethnl_auto_linkmodes(struct ethtool_link_ksettings *ksettings, - bool req_speed, bool req_lanes, - bool req_duplex) -{ - unsigned long *advertising = ksettings->link_modes.advertising; - unsigned long *supported = ksettings->link_modes.supported; - DECLARE_BITMAP(old_adv, __ETHTOOL_LINK_MODE_MASK_NBITS); - unsigned int i; - - BUILD_BUG_ON(ARRAY_SIZE(link_mode_params) != - __ETHTOOL_LINK_MODE_MASK_NBITS); - - bitmap_copy(old_adv, advertising, __ETHTOOL_LINK_MODE_MASK_NBITS); - - for (i = 0; i < __ETHTOOL_LINK_MODE_MASK_NBITS; i++) { - const struct link_mode_info *info = &link_mode_params[i]; - - if (info->speed == SPEED_UNKNOWN) - continue; - if (test_bit(i, supported) && - (!req_speed || info->speed == ksettings->base.speed) && - (!req_lanes || info->lanes == ksettings->lanes) && - (!req_duplex || info->duplex == ksettings->base.duplex)) - set_bit(i, advertising); - else - clear_bit(i, advertising); - } - - return !bitmap_equal(old_adv, advertising, - __ETHTOOL_LINK_MODE_MASK_NBITS); -} - -static bool ethnl_validate_master_slave_cfg(u8 cfg) -{ - switch (cfg) { - case MASTER_SLAVE_CFG_MASTER_PREFERRED: - case MASTER_SLAVE_CFG_SLAVE_PREFERRED: - case MASTER_SLAVE_CFG_MASTER_FORCE: - case MASTER_SLAVE_CFG_SLAVE_FORCE: - return true; - } - - return false; -} - -static int ethnl_check_linkmodes(struct genl_info *info, struct nlattr **tb) -{ - const struct nlattr *master_slave_cfg, *lanes_cfg; - - master_slave_cfg = tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG]; - if (master_slave_cfg && - !ethnl_validate_master_slave_cfg(nla_get_u8(master_slave_cfg))) { - NL_SET_ERR_MSG_ATTR(info->extack, master_slave_cfg, - "master/slave value is invalid"); - return -EOPNOTSUPP; - } - - lanes_cfg = tb[ETHTOOL_A_LINKMODES_LANES]; - if (lanes_cfg && !is_power_of_2(nla_get_u32(lanes_cfg))) { - NL_SET_ERR_MSG_ATTR(info->extack, lanes_cfg, - "lanes value is invalid"); - return -EINVAL; - } - - return 0; -} - -static int ethnl_update_linkmodes(struct genl_info *info, struct nlattr **tb, - struct ethtool_link_ksettings *ksettings, - bool *mod, const struct net_device *dev) -{ - struct ethtool_link_settings *lsettings = &ksettings->base; - bool req_speed, req_lanes, req_duplex; - const struct nlattr *master_slave_cfg, *lanes_cfg; - int ret; - - master_slave_cfg = tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG]; - if (master_slave_cfg) { - if (lsettings->master_slave_cfg == MASTER_SLAVE_CFG_UNSUPPORTED) { - NL_SET_ERR_MSG_ATTR(info->extack, master_slave_cfg, - "master/slave configuration not supported by device"); - return -EOPNOTSUPP; - } - } - - *mod = false; - req_speed = tb[ETHTOOL_A_LINKMODES_SPEED]; - req_lanes = tb[ETHTOOL_A_LINKMODES_LANES]; - req_duplex = tb[ETHTOOL_A_LINKMODES_DUPLEX]; - - ethnl_update_u8(&lsettings->autoneg, tb[ETHTOOL_A_LINKMODES_AUTONEG], - mod); - - lanes_cfg = tb[ETHTOOL_A_LINKMODES_LANES]; - if (lanes_cfg) { - /* If autoneg is off and lanes parameter is - * not supported by the driver, - * return an error. - */ - if (!lsettings->autoneg && - !dev->ethtool_ops->cap_link_lanes_supported) { - NL_SET_ERR_MSG_ATTR(info->extack, lanes_cfg, - "lanes configuration not supported by device"); - return -EOPNOTSUPP; - } - } else if (!lsettings->autoneg && ksettings->lanes) { - /* If autoneg is off and lanes parameter is not passed from user but - * it was defined previously then set the lanes parameter to 0. - */ - ksettings->lanes = 0; - *mod = true; - } - - ret = ethnl_update_bitset(ksettings->link_modes.advertising, - __ETHTOOL_LINK_MODE_MASK_NBITS, - tb[ETHTOOL_A_LINKMODES_OURS], link_mode_names, - info->extack, mod); - if (ret < 0) - return ret; - ethnl_update_u32(&lsettings->speed, tb[ETHTOOL_A_LINKMODES_SPEED], - mod); - ethnl_update_u32(&ksettings->lanes, lanes_cfg, mod); - ethnl_update_u8(&lsettings->duplex, tb[ETHTOOL_A_LINKMODES_DUPLEX], - mod); - ethnl_update_u8(&lsettings->master_slave_cfg, master_slave_cfg, mod); - - if (!tb[ETHTOOL_A_LINKMODES_OURS] && lsettings->autoneg && - (req_speed || req_lanes || req_duplex) && - ethnl_auto_linkmodes(ksettings, req_speed, req_lanes, req_duplex)) - *mod = true; - - return 0; -} - -int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info) -{ - struct ethtool_link_ksettings ksettings = {}; - struct ethnl_req_info req_info = {}; - struct nlattr **tb = info->attrs; - struct net_device *dev; - bool mod = false; - int ret; - - ret = ethnl_check_linkmodes(info, tb); - if (ret < 0) - return ret; - - ret = ethnl_parse_header_dev_get(&req_info, - tb[ETHTOOL_A_LINKMODES_HEADER], - genl_info_net(info), info->extack, - true); - if (ret < 0) - return ret; - dev = req_info.dev; - ret = -EOPNOTSUPP; - if (!dev->ethtool_ops->get_link_ksettings || - !dev->ethtool_ops->set_link_ksettings) - goto out_dev; - - rtnl_lock(); - ret = ethnl_ops_begin(dev); - if (ret < 0) - goto out_rtnl; - - ret = __ethtool_get_link_ksettings(dev, &ksettings); - if (ret < 0) { - GENL_SET_ERR_MSG(info, "failed to retrieve link settings"); - goto out_ops; - } - - ret = ethnl_update_linkmodes(info, tb, &ksettings, &mod, dev); - if (ret < 0) - goto out_ops; - - if (mod) { - ret = dev->ethtool_ops->set_link_ksettings(dev, &ksettings); - if (ret < 0) - GENL_SET_ERR_MSG(info, "link settings update failed"); - else - ethtool_notify(dev, ETHTOOL_MSG_LINKMODES_NTF, NULL); - } - -out_ops: - ethnl_ops_complete(dev); -out_rtnl: - rtnl_unlock(); -out_dev: - dev_put(dev); - return ret; -} diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h index 17155d446f2d..ebecf06a5a6e 100644 --- a/net/ethtool/netlink.h +++ b/net/ethtool/netlink.h @@ -339,8 +339,6 @@ extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_COUNTS_O extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1]; extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1]; extern const struct nla_policy ethnl_linkmodes_get_policy[ETHTOOL_A_LINKMODES_HEADER + 1]; -extern const struct nla_policy - ethnl_linkmodes_set_policy[ETHTOOL_A_LINKMODES_LANES + 1]; extern const struct nla_policy ethnl_linkstate_get_policy[ETHTOOL_A_LINKSTATE_HEADER + 1]; extern const struct nla_policy ethnl_debug_get_policy[ETHTOOL_A_DEBUG_HEADER + 1]; extern const struct nla_policy ethnl_debug_set_policy[ETHTOOL_A_DEBUG_MSGMASK + 1]; -- 2.34.1