From 730d86aee7fdc0f8e45d181294889318c345ec8d Mon Sep 17 00:00:00 2001 From: liujie_answer Date: Thu, 23 Oct 2025 09:47:41 +0800 Subject: [PATCH] test Signed-off-by: liujie_answer --- drivers/net/ethernet/linkdata/sxe/Makefile | 3 +- .../linkdata/sxe/base/trace/sxe_trace.c | 2 +- .../linkdata/sxe/include/sxe/sxe_cli.h | 24 + .../linkdata/sxe/include/sxe/sxe_hdc.h | 2 - .../linkdata/sxe/include/sxe/sxe_regs.h | 2 +- .../linkdata/sxe/include/sxe_version.h | 8 +- drivers/net/ethernet/linkdata/sxe/sxepf/sxe.h | 10 +- .../ethernet/linkdata/sxe/sxepf/sxe_debugfs.c | 3 +- .../ethernet/linkdata/sxe/sxepf/sxe_ethtool.c | 98 ++- .../linkdata/sxe/sxepf/sxe_host_hdc.c | 61 ++ .../linkdata/sxe/sxepf/sxe_host_hdc.h | 1 + .../net/ethernet/linkdata/sxe/sxepf/sxe_hw.c | 218 +++++- .../net/ethernet/linkdata/sxe/sxepf/sxe_hw.h | 491 ++++++------ .../net/ethernet/linkdata/sxe/sxepf/sxe_irq.c | 38 +- .../net/ethernet/linkdata/sxe/sxepf/sxe_irq.h | 4 + .../ethernet/linkdata/sxe/sxepf/sxe_main.c | 19 +- .../ethernet/linkdata/sxe/sxepf/sxe_monitor.c | 116 ++- .../ethernet/linkdata/sxe/sxepf/sxe_monitor.h | 6 +- .../ethernet/linkdata/sxe/sxepf/sxe_netdev.c | 8 +- .../net/ethernet/linkdata/sxe/sxepf/sxe_pci.c | 1 - .../net/ethernet/linkdata/sxe/sxepf/sxe_phy.c | 443 +++++++++-- .../net/ethernet/linkdata/sxe/sxepf/sxe_phy.h | 34 +- .../ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c | 15 +- .../ethernet/linkdata/sxe/sxepf/sxe_sriov.c | 2 +- .../ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c | 4 + .../ethernet/linkdata/sxe/sxepf/sxe_upgrade.c | 723 ++++++++++++++++++ .../ethernet/linkdata/sxe/sxepf/sxe_upgrade.h | 256 +++++++ .../net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c | 22 +- .../linkdata/sxevf/base/trace/sxe_trace.c | 2 +- .../linkdata/sxevf/include/sxe/sxe_cli.h | 24 + .../linkdata/sxevf/include/sxe/sxe_hdc.h | 2 - .../linkdata/sxevf/include/sxe/sxe_regs.h | 2 +- .../linkdata/sxevf/include/sxe_version.h | 8 +- .../net/ethernet/linkdata/sxevf/sxevf/sxevf.h | 7 + .../linkdata/sxevf/sxevf/sxevf_debug.h | 1 - .../linkdata/sxevf/sxevf/sxevf_ethtool.c | 38 +- .../ethernet/linkdata/sxevf/sxevf/sxevf_hw.c | 23 +- .../ethernet/linkdata/sxevf/sxevf/sxevf_hw.h | 48 +- .../ethernet/linkdata/sxevf/sxevf/sxevf_irq.c | 10 +- .../ethernet/linkdata/sxevf/sxevf/sxevf_irq.h | 4 + .../linkdata/sxevf/sxevf/sxevf_main.c | 16 +- .../linkdata/sxevf/sxevf/sxevf_netdev.c | 8 +- .../linkdata/sxevf/sxevf/sxevf_rx_proc.c | 2 +- .../linkdata/sxevf/sxevf/sxevf_tx_proc.c | 4 +- 44 files changed, 2360 insertions(+), 453 deletions(-) create mode 100644 drivers/net/ethernet/linkdata/sxe/sxepf/sxe_upgrade.c create mode 100644 drivers/net/ethernet/linkdata/sxe/sxepf/sxe_upgrade.h diff --git a/drivers/net/ethernet/linkdata/sxe/Makefile b/drivers/net/ethernet/linkdata/sxe/Makefile index 177c51ff4ede..40f21f6ef596 100644 --- a/drivers/net/ethernet/linkdata/sxe/Makefile +++ b/drivers/net/ethernet/linkdata/sxe/Makefile @@ -34,7 +34,8 @@ sxe-objs += base/log/sxe_log.o \ sxepf/sxe_ring.o \ sxepf/sxe_rx_proc.o \ sxepf/sxe_sriov.o \ - sxepf/sxe_tx_proc.o + sxepf/sxe_tx_proc.o \ + sxepf/sxe_upgrade.o # add compile ccflags and macro ccflags-y += -Werror diff --git a/drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c b/drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c index 496b483c0cbf..476a37ae2b6e 100644 --- a/drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c +++ b/drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c @@ -30,7 +30,7 @@ do { \ struct sxe_trace_tx_ring g_sxe_trace_tx[SXE_TXRX_RING_NUM_MAX] = { { 0 } }; struct sxe_trace_rx_ring g_sxe_trace_rx[SXE_TXRX_RING_NUM_MAX] = { { 0 } }; -void sxe_file_close(struct file **file) +static void sxe_file_close(struct file **file) { filp_close(*file, NULL); *file = NULL; diff --git a/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_cli.h b/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_cli.h index 562cf42120e3..4fca000a69c3 100644 --- a/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_cli.h +++ b/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_cli.h @@ -27,6 +27,8 @@ #define MGC_TERMLOG_INFO_MAX_LEN (12 * 1024) #define SXE_REGS_DUMP_MAX_LEN (12 * 1024) #define SXE_PRODUCT_NAME_LEN (32) +#define SXE_USER_SET_QUIRK_COUNT (4) +#define SXE_DEFAULT_QUIRK_COUNT (12) enum sxe_led_mode { SXE_IDENTIFY_LED_BLINK_ON = 0, @@ -221,4 +223,26 @@ struct sxe_an_cap { struct sxe_phy_an_cap local; struct sxe_phy_an_cap peer; }; + +struct sxecfgquirkinfo { + union { + u32 index; + u32 isvalid; + } type; + u8 vendor[SXE_MFG_SERIAL_NUMBER_LEN]; + u8 vendorpn[SXE_MFG_SERIAL_NUMBER_LEN]; + u8 wait10gfri; + u8 wait10gsec; + u8 wait1g; + u8 losblockflag; +}; + +struct sxecfguserquirklist { + struct sxecfgquirkinfo list[SXE_USER_SET_QUIRK_COUNT]; +}; + +struct sxecfgdefquirklist { + struct sxecfgquirkinfo list[SXE_DEFAULT_QUIRK_COUNT]; +}; + #endif diff --git a/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_hdc.h b/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_hdc.h index 1c48b903dc3f..d8715fc2851e 100644 --- a/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_hdc.h +++ b/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_hdc.h @@ -44,6 +44,4 @@ union hdcheader { } head; u32 dw0; }; - #endif - diff --git a/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_regs.h b/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_regs.h index ec81d6a8a5aa..a90eafaaa581 100644 --- a/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_regs.h +++ b/drivers/net/ethernet/linkdata/sxe/include/sxe/sxe_regs.h @@ -191,7 +191,7 @@ #define SXE_SPP_PROC_DELAY_US 0x00000007 #define SXE_SPP_PROC_DELAY_MS 0x00003A98 -#define SXE_SPP2_STATE 0x00000004 +#define SXE_SFP_STATE_PRESENT 0x00000004 #define SXE_IRQ_CLEAR_MASK 0xFFFFFFFF diff --git a/drivers/net/ethernet/linkdata/sxe/include/sxe_version.h b/drivers/net/ethernet/linkdata/sxe/include/sxe_version.h index ab1fce0ead18..acc15c60a07b 100644 --- a/drivers/net/ethernet/linkdata/sxe/include/sxe_version.h +++ b/drivers/net/ethernet/linkdata/sxe/include/sxe_version.h @@ -11,10 +11,10 @@ #ifndef __SXE_VER_H__ #define __SXE_VER_H__ -#define SXE_VERSION "1.5.0.27" -#define SXE_COMMIT_ID "e7a9699" -#define SXE_BRANCH "develop/rc/sagitta-1.5.0_B027-openEuler" -#define SXE_BUILD_TIME "2025-04-01 10:54:47" +#define SXE_VERSION "0.0.0.0" +#define SXE_COMMIT_ID "369cabe" +#define SXE_BRANCH "feature/sagitta-trunk-P8-open-linux" +#define SXE_BUILD_TIME "2025-10-22 22:25:33" #define SXE_DRV_NAME "sxe" #define SXEVF_DRV_NAME "sxevf" diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe.h b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe.h index da31cc6f86d5..b940afcbe49d 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe.h +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe.h @@ -50,6 +50,12 @@ #define SXE_MAX_MACVLANS 63 #endif +#ifdef HAVE_STRSCPY +#define SXE_STRCPY strscpy +#else +#define SXE_STRCPY strlcpy +#endif + #define SXE_KFREE(addr) \ do { \ void *_addr = (addr); \ @@ -94,7 +100,9 @@ enum sxe_nic_state { SXE_PTP_RUNNING, SXE_PTP_TX_IN_PROGRESS, SXE_IN_SFP_INIT, - SXE_SFP_MULTI_SPEED_SETTING, + SXE_SFP_LOS_DISABLED, + SXE_SFP_MULTI_SPEED_QUIRKS, + SXE_IRQ_REQUESTED, }; struct sxe_sw_stats { diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c index 51c02502af66..9e940fc88fdd 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c @@ -15,6 +15,7 @@ #include "sxe_netdev.h" #include "sxe_version.h" #include "sxe_phy.h" +#include "sxe_debugfs.h" #define SXE_HW_STATS_LEN ARRAY_SIZE(hw_stats) @@ -411,7 +412,7 @@ static ssize_t sxe_debugfs_sfp_info_read(struct file *filp, char __user *buffer, ret = sxe_sfp_vendor_pn_cmp(sfp_vendor_pn); if (!ret) { - LOG_DEV_WARN("an supported SFP module type was detected\n"); + LOG_DEV_WARN("a supported SFP module type was detected\n"); goto l_end; } diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c index 3b54d8dd842d..3fa07de0d65f 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c @@ -22,6 +22,7 @@ #include "sxe_host_hdc.h" #include "sxe_phy.h" #include "sxe_cli.h" +#include "sxe_upgrade.h" enum sxe_diag_test_case { SXE_DIAG_REGS_TEST = 0, @@ -343,15 +344,15 @@ static void sxe_get_drvinfo(struct net_device *netdev, { struct sxe_adapter *adapter = netdev_priv(netdev); - strlcpy(drvinfo->driver, SXE_DRV_NAME, sizeof(drvinfo->driver)); - strlcpy(drvinfo->version, SXE_VERSION, sizeof(drvinfo->version)); + SXE_STRCPY(drvinfo->driver, SXE_DRV_NAME, sizeof(drvinfo->driver)); + SXE_STRCPY(drvinfo->version, SXE_VERSION, sizeof(drvinfo->version)); sxe_fw_version_get(adapter); - strlcpy(drvinfo->fw_version, (s8 *)adapter->fw_info.fw_version, - sizeof(drvinfo->fw_version)); + SXE_STRCPY(drvinfo->fw_version, (s8 *)adapter->fw_info.fw_version, + sizeof(drvinfo->fw_version)); - strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), - sizeof(drvinfo->bus_info)); + SXE_STRCPY(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); drvinfo->n_priv_flags = SXE_PRIV_FLAGS_STR_LEN; } @@ -1221,6 +1222,68 @@ static void sxe_rss_redir_tbl_get(struct sxe_adapter *adapter, u32 *indir) indir[i] = adapter->rss_indir_tbl[i] & rss_m; } +#ifdef HAVE_ETHTOOL_RXFH_PARAM +static int sxe_get_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh) +{ + struct sxe_adapter *adapter = netdev_priv(netdev); + + rxfh->hfunc = ETH_RSS_HASH_TOP; + + if (rxfh->indir) + sxe_rss_redir_tbl_get(adapter, rxfh->indir); + + if (rxfh->key) + memcpy(rxfh->key, adapter->rss_key, sxe_get_rxfh_key_size(netdev)); + + return 0; +} + +static int sxe_set_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + u16 i, max_queues; + struct sxe_adapter *adapter = netdev_priv(netdev); + u16 rss = sxe_rss_num_get(adapter); + u32 tbl_entries = sxe_rss_redir_tbl_size_get(); + struct sxe_hw *hw = &adapter->hw; + + LOG_DEBUG_BDF("rss=%u, tbl_entries=%u\n", rss, tbl_entries); + if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && + rxfh->hfunc != ETH_RSS_HASH_TOP) { + LOG_ERROR_BDF("sxe unsupport hfunc[%d]\n", rxfh->hfunc); + return -EOPNOTSUPP; + } + + if (rxfh->indir) { + max_queues = min_t(int, adapter->rx_ring_ctxt.num, rss); + + if ((adapter->cap & SXE_SRIOV_ENABLE) && max_queues < 2) + max_queues = 2; + + for (i = 0; i < tbl_entries; i++) { + if (rxfh->indir[i] >= max_queues) { + LOG_ERROR_BDF("indir[%u]=%u > max_que=%u\n", + i, rxfh->indir[i], max_queues); + return -EINVAL; + } + } + + for (i = 0; i < tbl_entries; i++) + adapter->rss_indir_tbl[i] = rxfh->indir[i]; + + hw->dbu.ops->rss_redir_tbl_set_all(hw, adapter->rss_indir_tbl); + } + + if (rxfh->key) { + memcpy(adapter->rss_key, rxfh->key, sxe_get_rxfh_key_size(netdev)); + hw->dbu.ops->rss_key_set_all(hw, adapter->rss_key); + } + + return 0; +} +#else static int sxe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc) { @@ -1280,6 +1343,7 @@ static int sxe_set_rxfh(struct net_device *netdev, const u32 *redir, return 0; } +#endif #ifdef HAVE_ETHTOOL_EXTENDED_RINGPARAMS static void @@ -1672,6 +1736,7 @@ sxe_set_link_ksettings_proto(struct net_device *netdev, { int ret = 0; u32 advertised, old; + unsigned long timeout; u32 supported, advertising; struct sxe_adapter *adapter = netdev_priv(netdev); struct sxe_phy_context *phy_ctxt = &adapter->phy_ctxt; @@ -1716,15 +1781,18 @@ sxe_set_link_ksettings_proto(struct net_device *netdev, goto l_end; } - set_bit(SXE_SFP_MULTI_SPEED_SETTING, &adapter->state); - adapter->link.sfp_multispeed_time = jiffies; while (test_and_set_bit(SXE_IN_SFP_INIT, &adapter->state)) { usleep_range(SXE_SFP_INIT_WAIT_ITR_MIN, SXE_SFP_INIT_WAIT_ITR_MAX); } + timeout = sxe_los_disable_timeout_get(); + adapter->link.sfp_los_disable_timeout = jiffies + timeout; /* in order to force CPU ordering */ smp_wmb(); + + set_bit(SXE_SFP_LOS_DISABLED, &adapter->state); + clear_bit(SXE_SFP_MULTI_SPEED_QUIRKS, &adapter->state); clear_bit(SXE_LINK_NEED_CONFIG, &adapter->monitor_ctxt.state); set_bit(SXE_LINK_SPEED_CHANGE, &adapter->monitor_ctxt.state); adapter->hw.mac.auto_restart = true; @@ -2019,7 +2087,7 @@ static s32 sxe_irq_test(struct sxe_adapter *adapter) return ret; } -int sxe_reg_test(struct sxe_adapter *adapter) +static int sxe_reg_test(struct sxe_adapter *adapter) { s32 ret; struct sxe_hw *hw = &adapter->hw; @@ -2641,7 +2709,7 @@ static s32 sxe_identify_led_ctrl(struct sxe_adapter *adapter, bool is_blink) return ret; } -int sxe_phys_id_set(struct net_device *netdev, enum ethtool_phys_id_state state) +static int sxe_phys_id_set(struct net_device *netdev, enum ethtool_phys_id_state state) { int ret = 0; struct sxe_adapter *adapter = netdev_priv(netdev); @@ -2763,6 +2831,15 @@ static int sxe_set_coalesce(struct net_device *netdev, return sxe_irq_coalesce_set(netdev, ec); } +static s32 sxe_flash_device(struct net_device *dev, + struct ethtool_flash *flash) +{ + if (flash->region == ETHTOOL_FLASH_ALL_REGIONS) + return sxe_flash_package_from_file(dev, flash->data); + else + return -EPERM; +} + static const struct ethtool_ops sxe_ethtool_ops = { #ifdef ETHTOOL_COALESCE_USECS .supported_coalesce_params = ETHTOOL_COALESCE_USECS, @@ -2802,6 +2879,7 @@ static const struct ethtool_ops sxe_ethtool_ops = { .get_regs = sxe_regs_get, .get_module_info = sxe_get_module_info, .get_module_eeprom = sxe_get_module_eeprom, + .flash_device = sxe_flash_device, }; void sxe_ethtool_ops_set(struct net_device *netdev) diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c index 43bcfa9eb7b1..26fd6d4ebafa 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c @@ -896,6 +896,67 @@ s32 sxe_driver_cmd_trans(struct sxe_hw *hw, struct sxe_driver_cmd *cmd) return ret; } +s32 sxe_ethtool_fw_trans(struct sxe_adapter *adapter, struct sxe_driver_cmd *cmd) +{ + s32 ret = SXE_SUCCESS; + struct sxe_hw *hw = &adapter->hw; + struct sxe_hdc_cmd_hdr *cmd_hdr; + struct sxe_hdc_trans_info trans_info; + u64 trace_id = cmd->trace_id; + u16 in_len = cmd->req_len; + u16 out_len = cmd->resp_len; + u8 *in_data = cmd->req; + + u8 *in_data_buf; + u8 *out_data_buf; + u16 in_buf_len = in_len + SXE_HDC_CMD_HDR_SIZE; + u16 out_buf_len = out_len + SXE_HDC_CMD_HDR_SIZE; + + in_data_buf = kzalloc(in_buf_len, GFP_KERNEL); + if (!in_data_buf) { + LOG_ERROR_BDF("cmd trace_id=0x%llx kzalloc indata\n" + "\tmem len[%u] failed\n", + trace_id, in_buf_len); + ret = -ENOMEM; + goto l_ret; + } + + out_data_buf = kzalloc(out_buf_len, GFP_KERNEL); + if (!out_data_buf) { + LOG_ERROR_BDF("cmd trace_id=0x%llx kzalloc out_data\n" + "\tmem len[%u] failed\n", + trace_id, out_buf_len); + ret = -ENOMEM; + goto l_in_buf_free; + } + + memcpy(in_data_buf + SXE_HDC_CMD_HDR_SIZE, in_data, in_len); + + cmd_hdr = (struct sxe_hdc_cmd_hdr *)in_data_buf; + sxe_cmd_hdr_init(cmd_hdr, SXE_CMD_TYPE_CLI); + + LOG_DEBUG_BDF("trans cli cmd:trace_id=0x%llx,, inlen=%u,\n" + "\tout_len=%u\n", + trace_id, in_len, out_len); + sxe_hdc_trans_info_init(&trans_info, in_data_buf, in_buf_len, out_data_buf, + out_buf_len); + + ret = sxe_hdc_cmd_process(hw, trace_id, &trans_info, false, + cmd->is_interruptible); + if (ret) { + LOG_DEV_DEBUG("hdc cmd trace_id=0x%llx hdc packet trans failed,\n" + "\tret=%d\n", trace_id, ret); + goto l_out_buf_free; + } + +l_out_buf_free: + kfree(out_data_buf); +l_in_buf_free: + kfree(in_data_buf); +l_ret: + return ret; +} + s32 sxe_cli_cmd_trans(struct sxe_hw *hw, struct sxe_driver_cmd *cmd) { s32 ret = SXE_SUCCESS; diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.h b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.h index bee9cb753634..3b999ae4e0da 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.h +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.h @@ -89,4 +89,5 @@ void sxe_hdc_available_set(s32 value); void sxe_time_sync_handler(struct work_struct *work); +s32 sxe_ethtool_fw_trans(struct sxe_adapter *adapter, struct sxe_driver_cmd *cmd); #endif diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c index b5114a2413a7..ad701c840589 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c @@ -22,9 +22,8 @@ #include "sxe_errno.h" #include "sxe_logs.h" #include "sxe.h" - -#include "sxe_hw.h" #endif +#include "sxe_hw.h" #define SXE_PFMSG_MASK (0xFF00) @@ -113,7 +112,7 @@ static u32 sxe_hw_fault_check(struct sxe_hw *hw, u32 reg) u8 __iomem *base_addr = hw->reg_base_addr; struct sxe_adapter *adapter = hw->adapter; - if (sxe_is_hw_fault(hw)) + if (sxe_is_hw_fault(hw) || pci_channel_offline(adapter->pdev)) goto l_out; for (i = 0; i < SXE_REG_READ_RETRY; i++) { @@ -124,7 +123,7 @@ static u32 sxe_hw_fault_check(struct sxe_hw *hw, u32 reg) mdelay(3); } - if (value == SXE_REG_READ_FAIL) { + if (value == SXE_REG_READ_FAIL && !pci_channel_offline(adapter->pdev)) { LOG_ERROR_BDF("read registers multiple times failed, ret=%#x\n", value); sxe_hw_fault_handle(hw); @@ -850,12 +849,12 @@ void sxe_hw_specific_irq_enable(struct sxe_hw *hw, u32 value) SXE_REG_WRITE(hw, SXE_EIMS, value); } -static u32 sxe_hw_spp_state_get(struct sxe_hw *hw) +u32 sxe_hw_spp_state_get(struct sxe_hw *hw) { return SXE_REG_READ(hw, SXE_SPP_STATE); } -static void sxe_hw_rx_los_disable(struct sxe_hw *hw) +void sxe_hw_rx_los_disable(struct sxe_hw *hw) { u32 value; @@ -864,7 +863,7 @@ static void sxe_hw_rx_los_disable(struct sxe_hw *hw) SXE_REG_WRITE(hw, SXE_EIMS, value); } -static void sxe_hw_rx_los_enable(struct sxe_hw *hw) +void sxe_hw_rx_los_enable(struct sxe_hw *hw) { u32 value; @@ -883,7 +882,7 @@ void sxe_hw_all_irq_disable(struct sxe_hw *hw) SXE_WRITE_FLUSH(hw); } -static void sxe_hw_spp_configure(struct sxe_hw *hw, u32 hw_spp_proc_delay_us) +void sxe_hw_spp_configure(struct sxe_hw *hw, u32 hw_spp_proc_delay_us) { u32 reg = SXE_REG_READ(hw, SXE_SPP_PROC); @@ -3688,8 +3687,8 @@ static void sxe_hw_tx_tph_update(struct sxe_hw *hw, u8 ring_idx, u8 cpu) value <<= SXE_TPH_TXCTRL_CPUID_SHIFT; - value |= SXE_TPH_TXCTRL_DESC_RRO_EN | SXE_TPH_TXCTRL_DATA_RRO_EN | - SXE_TPH_TXCTRL_DESC_TPH_EN; + value |= SXE_TPH_TXCTRL_DESC_TPH_EN | SXE_TPH_TXCTRL_DESC_RRO_EN | + SXE_TPH_TXCTRL_DESC_WRO_EN | SXE_TPH_TXCTRL_DATA_RRO_EN; SXE_REG_WRITE(hw, SXE_TPH_TXCTRL(ring_idx), value); } @@ -3700,8 +3699,8 @@ static void sxe_hw_rx_tph_update(struct sxe_hw *hw, u8 ring_idx, u8 cpu) value <<= SXE_TPH_RXCTRL_CPUID_SHIFT; - value |= SXE_TPH_RXCTRL_DESC_RRO_EN | SXE_TPH_RXCTRL_DATA_TPH_EN | - SXE_TPH_RXCTRL_DESC_TPH_EN; + value |= SXE_TPH_RXCTRL_DESC_TPH_EN | SXE_TPH_RXCTRL_DESC_RRO_EN | + SXE_TPH_RXCTRL_DATA_WRO_EN | SXE_TPH_RXCTRL_HEAD_WRO_EN; SXE_REG_WRITE(hw, SXE_TPH_RXCTRL(ring_idx), value); } @@ -3714,6 +3713,28 @@ static void sxe_hw_tph_switch(struct sxe_hw *hw, bool is_enable) SXE_REG_WRITE(hw, SXE_TPH_CTRL, SXE_TPH_CTRL_DISABLE); } +void sxe_hw_rx_ro_enable(struct sxe_hw *hw, u8 ring_idx) +{ + u32 value = SXE_REG_READ(hw, SXE_TPH_RXCTRL(ring_idx)); + + value |= SXE_TPH_RXCTRL_DESC_RRO_EN | + SXE_TPH_RXCTRL_DATA_WRO_EN | + SXE_TPH_RXCTRL_HEAD_WRO_EN; + + SXE_REG_WRITE(hw, SXE_TPH_RXCTRL(ring_idx), value); +} + +void sxe_hw_tx_ro_enable(struct sxe_hw *hw, u8 ring_idx) +{ + u32 value = SXE_REG_READ(hw, SXE_TPH_TXCTRL(ring_idx)); + + value |= SXE_TPH_TXCTRL_DESC_RRO_EN | + SXE_TPH_TXCTRL_DESC_WRO_EN | + SXE_TPH_TXCTRL_DATA_RRO_EN; + + SXE_REG_WRITE(hw, SXE_TPH_TXCTRL(ring_idx), value); +} + static const struct sxe_dma_operations sxe_dma_ops = { .rx_dma_ctrl_init = sxe_hw_rx_dma_ctrl_init, .rx_ring_switch = sxe_hw_rx_ring_switch, @@ -3727,6 +3748,7 @@ static const struct sxe_dma_operations sxe_dma_ops = { .rx_drop_switch = sxe_hw_rx_drop_switch, .pool_rx_ring_drop_enable = sxe_hw_pool_rx_ring_drop_enable, .rx_tph_update = sxe_hw_rx_tph_update, + .rx_ro_enable = sxe_hw_rx_ro_enable, .tx_enable = sxe_hw_tx_enable, .tx_multi_ring_configure = sxe_hw_tx_multi_ring_configure, @@ -3739,6 +3761,7 @@ static const struct sxe_dma_operations sxe_dma_ops = { .tx_desc_ctrl_get = sxe_hw_tx_desc_ctrl_get, .tx_ring_info_get = sxe_hw_tx_ring_info_get, .tx_tph_update = sxe_hw_tx_tph_update, + .tx_ro_enable = sxe_hw_tx_ro_enable, .tph_switch = sxe_hw_tph_switch, @@ -4372,7 +4395,9 @@ static bool sxe_hw_mbx_lock(struct sxe_hw *hw, u8 vf_idx) u32 retry = hw->mbx.retry; while (retry--) { - SXE_REG_WRITE(hw, SXE_PFMAILBOX(vf_idx), SXE_PFMAILBOX_PFU); + value = SXE_REG_READ(hw, SXE_PFMAILBOX(vf_idx)); + value |= SXE_PFMAILBOX_PFU; + SXE_REG_WRITE(hw, SXE_PFMAILBOX(vf_idx), value); value = SXE_REG_READ(hw, SXE_PFMAILBOX(vf_idx)); if (value & SXE_PFMAILBOX_PFU) { @@ -4386,7 +4411,8 @@ static bool sxe_hw_mbx_lock(struct sxe_hw *hw, u8 vf_idx) return ret; } -s32 sxe_hw_rcv_msg_from_vf(struct sxe_hw *hw, u32 *msg, u16 msg_len, u16 index) +static s32 sxe_hw_rcv_msg_from_vf(struct sxe_hw *hw, u32 *msg, + u16 msg_len, u16 index) { struct sxe_mbx_info *mbx = &hw->mbx; u8 i; @@ -4416,7 +4442,8 @@ s32 sxe_hw_rcv_msg_from_vf(struct sxe_hw *hw, u32 *msg, u16 msg_len, u16 index) return ret; } -s32 sxe_hw_send_msg_to_vf(struct sxe_hw *hw, u32 *msg, u16 msg_len, u16 index) +static s32 sxe_hw_send_msg_to_vf(struct sxe_hw *hw, u32 *msg, + u16 msg_len, u16 index) { struct sxe_mbx_info *mbx = &hw->mbx; u8 i; @@ -4928,8 +4955,20 @@ bool sxe_hw_is_rss_enabled(struct sxe_hw *hw) bool rss_enable = false; u32 mrqc = SXE_REG_READ(hw, SXE_MRQC); +#if defined DPDK_23_11_3 || defined DPDK_24_11_1 + u32 mrqe_val = mrqc & SXE_MRQC_MRQE_MASK; + + if (mrqe_val == SXE_MRQC_RSSEN || + mrqe_val == SXE_MRQC_RTRSS8TCEN || + mrqe_val == SXE_MRQC_RTRSS4TCEN || + mrqe_val == SXE_MRQC_VMDQRSS32EN || + mrqe_val == SXE_MRQC_VMDQRSS64EN) { + rss_enable = true; + } +#else if (mrqc & SXE_MRQC_RSSEN) rss_enable = true; +#endif return rss_enable; } @@ -5000,6 +5039,123 @@ void sxe_hw_dcb_vmdq_mq_configure(struct sxe_hw *hw, u8 num_pools) SXE_REG_WRITE(hw, SXE_RTRPCS, SXE_RTRPCS_RRM); } +static bool sxe_mbx_lock(struct sxe_hw *hw, u8 vf_idx) +{ + u32 value = 0; + bool ret = false; + u32 retry = hw->mbx.retry; + struct sxe_adapter *adapter = hw->adapter; + + rte_spinlock_lock(&adapter->vt_ctxt.vfs_lock); + while (retry--) { + value = SXE_REG_READ(hw, SXE_PFMAILBOX(vf_idx)); + if (value & SXE_PFMAILBOX_PFU) { + udelay(hw->mbx.interval); + continue; + } + break; + } + + if (!retry) { + LOG_ERROR_BDF("get lock mailbox fail retry %d.(err:%d)\n", + hw->mbx.retry, ret); + goto end; + } + + retry = hw->mbx.retry; + while (retry--) { + value |= SXE_PFMAILBOX_PFU; + SXE_REG_WRITE(hw, SXE_PFMAILBOX(vf_idx), value); + + value = SXE_REG_READ(hw, SXE_PFMAILBOX(vf_idx)); + if (value & SXE_PFMAILBOX_PFU) { + ret = true; + break; + } + udelay(hw->mbx.interval); + } + +end: + rte_spinlock_unlock(&adapter->vt_ctxt.vfs_lock); + + return ret; +} + +s32 sxe_rcv_msg_from_vf_lock(struct sxe_hw *hw, u32 *msg, + u16 msg_len, u16 index) +{ + struct sxe_mbx_info *mbx = &hw->mbx; + u8 i; + s32 ret = 0; + u16 msg_entry; + struct sxe_adapter *adapter = hw->adapter; + + msg_entry = (msg_len > mbx->msg_len) ? mbx->msg_len : msg_len; + + if (!sxe_mbx_lock(hw, index)) { + ret = -SXE_ERR_MBX_LOCK_FAIL; + LOG_ERROR_BDF("vf idx:%d msg_len:%d rcv lock mailbox fail.(err:%d)\n", + index, msg_len, ret); + goto l_out; + } + + for (i = 0; i < msg_entry; i++) { + msg[i] = SXE_REG_READ(hw, (SXE_PFMBMEM(index) + (i << 2))); + LOG_DEBUG_BDF("vf_idx:%u read mbx mem[%u]:0x%x.\n", + index, i, msg[i]); + } + + SXE_REG_WRITE(hw, SXE_PFMAILBOX(index), SXE_PFMAILBOX_ACK); + mbx->stats.rcv_msgs++; + +l_out: + return ret; +} + +s32 sxe_send_msg_to_vf_lock(struct sxe_hw *hw, u32 *msg, + u16 msg_len, u16 index) +{ + struct sxe_mbx_info *mbx = &hw->mbx; + u8 i; + s32 ret = 0; + u32 old; + struct sxe_adapter *adapter = hw->adapter; + + if (msg_len > mbx->msg_len) { + ret = -EINVAL; + LOG_ERROR_BDF("pf reply msg num:%d exceed limit:%d reply fail.\n" + "\t(err:%d)\n", msg_len, mbx->msg_len, ret); + goto l_out; + } + + if (!sxe_mbx_lock(hw, index)) { + ret = -SXE_ERR_MBX_LOCK_FAIL; + LOG_ERROR_BDF("send msg len:%u to vf idx:%u msg[0]:0x%x\n" + "\tlock mailbox fail.(err:%d)\n", + msg_len, index, msg[0], ret); + goto l_out; + } + + old = SXE_REG_READ(hw, (SXE_PFMBMEM(index))); + LOG_DEBUG_BDF("original send msg:0x%x. mbx mem[0]:0x%x\n", *msg, old); + if (msg[0] & SXE_CTRL_MSG_MASK) + msg[0] |= (old & SXE_MSGID_MASK); + else + msg[0] |= (old & SXE_PFMSG_MASK); + + for (i = 0; i < msg_len; i++) { + SXE_REG_WRITE(hw, (SXE_PFMBMEM(index) + (i << 2)), msg[i]); + LOG_DEBUG_BDF("vf_idx:%u write mbx mem[%u]:0x%x.\n", + index, i, msg[i]); + } + + SXE_REG_WRITE(hw, SXE_PFMAILBOX(index), SXE_PFMAILBOX_STS); + mbx->stats.send_msgs++; + +l_out: + return ret; +} + static const struct sxe_reg_info sxe_regs_general_group[] = { { SXE_CTRL, 1, 1, "SXE_CTRL" }, { SXE_STATUS, 1, 1, "SXE_STATUS" }, @@ -5450,10 +5606,42 @@ void sxe_hw_rss_cap_switch(struct sxe_hw *hw, bool is_on) { u32 mrqc = SXE_REG_READ(hw, SXE_MRQC); +#if defined DPDK_23_11_3 || defined DPDK_24_11_1 + u32 mrqe_val; + + mrqe_val = mrqc & SXE_MRQC_MRQE_MASK; + if (is_on) { + mrqe_val = SXE_MRQC_RSSEN; + } else { + switch (mrqe_val) { + case SXE_MRQC_RSSEN: + mrqe_val = 0; + break; + case SXE_MRQC_RTRSS8TCEN: + mrqe_val = SXE_MRQC_RT8TCEN; + break; + case SXE_MRQC_RTRSS4TCEN: + mrqe_val = SXE_MRQC_RT4TCEN; + break; + case SXE_MRQC_VMDQRSS64EN: + mrqe_val = SXE_MRQC_VMDQEN; + break; + case SXE_MRQC_VMDQRSS32EN: + PMD_LOG_WARN(DRV, "\tThree is no regression for virtualizatic\n" + "\t and RSS with 32 polls among the MRQE configuration\n" + "\t after disable RSS and left it unchanged.\n"); + break; + default: + break; + } + } + mrqc = (mrqc & ~SXE_MRQC_MRQE_MASK) | mrqe_val; +#else if (is_on) mrqc |= SXE_MRQC_RSSEN; else mrqc &= ~SXE_MRQC_RSSEN; +#endif SXE_REG_WRITE(hw, SXE_MRQC, mrqc); } diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.h b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.h index 7b0382625d99..77638d2ee409 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.h +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.h @@ -703,7 +703,7 @@ struct sxe_dbu_operations { }; struct sxe_dbu_info { - const struct sxe_dbu_operations *ops; + const struct sxe_dbu_operations *ops; }; struct sxe_dma_operations { @@ -721,6 +721,7 @@ struct sxe_dma_operations { void (*rx_dma_lro_ctl_set)(struct sxe_hw *hw); void (*rx_drop_switch)(struct sxe_hw *hw, u8 idx, bool is_enable); void (*rx_tph_update)(struct sxe_hw *hw, u8 ring_idx, u8 cpu); + void (*rx_ro_enable)(struct sxe_hw *hw, u8 ring_idx); void (*tx_enable)(struct sxe_hw *hw); void (*tx_multi_ring_configure)(struct sxe_hw *hw, u8 tcs, @@ -744,6 +745,7 @@ struct sxe_dma_operations { void (*tx_vlan_tag_set)(struct sxe_hw *hw, u16 vid, u16 qos, u32 vf); void (*tx_vlan_tag_clear)(struct sxe_hw *hw, u32 vf); void (*tx_tph_update)(struct sxe_hw *hw, u8 ring_idx, u8 cpu); + void (*tx_ro_enable)(struct sxe_hw *hw, u8 ring_idx); void (*tph_switch)(struct sxe_hw *hw, bool is_enable); @@ -996,37 +998,29 @@ static inline void sxe_hw_reg_handle_init(struct sxe_hw *hw, hw->reg_write = write; } -#ifdef SXE_DPDK - -void sxe_hw_crc_strip_config(struct sxe_hw *hw, bool keep_crc); - -void sxe_hw_stats_seq_clean(struct sxe_hw *hw, struct sxe_mac_stats *stats); - -void sxe_hw_hdc_drv_status_set(struct sxe_hw *hw, u32 value); - -s32 sxe_hw_nic_reset(struct sxe_hw *hw); +void sxe_hw_fc_requested_mode_set(struct sxe_hw *hw, enum sxe_fc_mode mode); -u16 sxe_hw_fc_pause_time_get(struct sxe_hw *hw); +void sxe_hw_vt_pool_loopback_switch(struct sxe_hw *hw, bool is_enable); -void sxe_hw_fc_pause_time_set(struct sxe_hw *hw, u16 pause_time); +u32 sxe_hw_hdc_fw_status_get(struct sxe_hw *hw); -void sxe_fc_autoneg_localcap_set(struct sxe_hw *hw); +void sxe_hw_no_snoop_disable(struct sxe_hw *hw); -u32 sxe_hw_fc_tc_high_water_mark_get(struct sxe_hw *hw, u8 tc_idx); +void sxe_hw_uc_addr_pool_del(struct sxe_hw *hw, u32 rar_idx, u32 pool_idx); -u32 sxe_hw_fc_tc_low_water_mark_get(struct sxe_hw *hw, u8 tc_idx); +s32 sxe_hw_uc_addr_pool_enable(struct sxe_hw *hw, u8 rar_idx, u8 pool_idx); -u16 sxe_hw_fc_send_xon_get(struct sxe_hw *hw); +s32 sxe_hw_nic_reset(struct sxe_hw *hw); -void sxe_hw_fc_send_xon_set(struct sxe_hw *hw, u16 send_xon); +void sxe_hw_pf_rst_done_set(struct sxe_hw *hw); -u32 sxe_hw_rx_mode_get(struct sxe_hw *hw); +u32 sxe_hw_pending_irq_read_clear(struct sxe_hw *hw); -void sxe_hw_rx_mode_set(struct sxe_hw *hw, u32 filter_ctrl); +void sxe_hw_pending_irq_write_clear(struct sxe_hw *hw, u32 value); -void sxe_hw_specific_irq_enable(struct sxe_hw *hw, u32 value); +void sxe_hw_ring_irq_auto_disable(struct sxe_hw *hw, bool is_msix); -void sxe_hw_specific_irq_disable(struct sxe_hw *hw, u32 value); +u32 sxe_hw_irq_cause_get(struct sxe_hw *hw); void sxe_hw_irq_general_reg_set(struct sxe_hw *hw, u32 value); @@ -1041,34 +1035,90 @@ void sxe_hw_ring_irq_interval_set(struct sxe_hw *hw, u16 irq_idx, u32 interval); void sxe_hw_event_irq_auto_clear_set(struct sxe_hw *hw, u32 value); +void sxe_hw_specific_irq_enable(struct sxe_hw *hw, u32 value); + +void sxe_hw_specific_irq_disable(struct sxe_hw *hw, u32 value); + +u32 sxe_hw_spp_state_get(struct sxe_hw *hw); + +void sxe_hw_rx_los_disable(struct sxe_hw *hw); + +void sxe_hw_rx_los_enable(struct sxe_hw *hw); + void sxe_hw_all_irq_disable(struct sxe_hw *hw); -void sxe_hw_ring_irq_auto_disable(struct sxe_hw *hw, bool is_msix); +void sxe_hw_spp_configure(struct sxe_hw *hw, u32 hw_spp_proc_delay_us); -u32 sxe_hw_irq_cause_get(struct sxe_hw *hw); +bool sxe_hw_is_link_state_up(struct sxe_hw *hw); -void sxe_hw_pending_irq_write_clear(struct sxe_hw *hw, u32 value); +u32 sxe_hw_link_speed_get(struct sxe_hw *hw); -u32 sxe_hw_ring_irq_switch_get(struct sxe_hw *hw, u8 idx); +void sxe_hw_link_speed_set(struct sxe_hw *hw, u32 speed); -void sxe_hw_ring_irq_switch_set(struct sxe_hw *hw, u8 idx, u32 value); +void sxe_hw_mac_pad_enable(struct sxe_hw *hw); -s32 sxe_hw_uc_addr_add(struct sxe_hw *hw, u32 rar_idx, u8 *addr, u32 pool_idx); +s32 sxe_hw_fc_enable(struct sxe_hw *hw); -s32 sxe_hw_uc_addr_del(struct sxe_hw *hw, u32 index); +void sxe_fc_autoneg_localcap_set(struct sxe_hw *hw); -void sxe_hw_uc_addr_pool_del(struct sxe_hw *hw, u32 rar_idx, u32 pool_idx); +s32 sxe_hw_pfc_enable(struct sxe_hw *hw, u8 tc_idx); -u32 sxe_hw_uta_hash_table_get(struct sxe_hw *hw, u8 reg_idx); +void sxe_hw_crc_configure(struct sxe_hw *hw); -void sxe_hw_uta_hash_table_set(struct sxe_hw *hw, u8 reg_idx, u32 value); +void sxe_hw_mac_txrx_enable(struct sxe_hw *hw); -u32 sxe_hw_mc_filter_get(struct sxe_hw *hw); +void sxe_hw_mac_max_frame_set(struct sxe_hw *hw, u32 max_frame); + +u32 sxe_hw_mac_max_frame_get(struct sxe_hw *hw); + +void sxe_hw_fc_tc_high_water_mark_set(struct sxe_hw *hw, u8 tc_idx, u32 mark); + +void sxe_hw_fc_tc_low_water_mark_set(struct sxe_hw *hw, u8 tc_idx, u32 mark); + +bool sxe_hw_is_fc_autoneg_disabled(struct sxe_hw *hw); + +void sxe_hw_fc_autoneg_disable_set(struct sxe_hw *hw, bool is_disabled); + +u32 sxe_hw_rx_mode_get(struct sxe_hw *hw); + +void sxe_hw_rx_ro_enable(struct sxe_hw *hw, u8 ring_idx); + +void sxe_hw_tx_ro_enable(struct sxe_hw *hw, u8 ring_idx); + +void sxe_hw_rx_mode_set(struct sxe_hw *hw, u32 filter_ctrl); + +u32 sxe_hw_pool_rx_mode_get(struct sxe_hw *hw, u16 pool_idx); + +void sxe_hw_pool_rx_mode_set(struct sxe_hw *hw, u32 vmolr, u16 pool_idx); + +void sxe_hw_rx_lro_enable(struct sxe_hw *hw, bool is_enable); + +void sxe_hw_rx_nfs_filter_disable(struct sxe_hw *hw); + +void sxe_hw_rx_udp_frag_checksum_disable(struct sxe_hw *hw); + +void sxe_hw_fc_mac_addr_set(struct sxe_hw *hw, u8 *mac_addr); + +s32 sxe_hw_uc_addr_add(struct sxe_hw *hw, u32 rar_idx, u8 *addr, u32 pool_idx); + +s32 sxe_hw_uc_addr_del(struct sxe_hw *hw, u32 index); void sxe_hw_mta_hash_table_set(struct sxe_hw *hw, u8 index, u32 value); +void sxe_hw_mta_hash_table_update(struct sxe_hw *hw, u8 reg_idx, u8 bit_idx); + +u32 sxe_hw_mc_filter_get(struct sxe_hw *hw); + void sxe_hw_mc_filter_enable(struct sxe_hw *hw); +void sxe_hw_uc_addr_clear(struct sxe_hw *hw); + +void sxe_hw_vt_ctrl_cfg(struct sxe_hw *hw, u8 num_vfs); + +void sxe_hw_vt_disable(struct sxe_hw *hw); + +u32 sxe_hw_vlan_pool_filter_read(struct sxe_hw *hw, u16 reg_index); + void sxe_hw_vlan_filter_array_write(struct sxe_hw *hw, u16 reg_index, u32 value); @@ -1076,127 +1126,190 @@ u32 sxe_hw_vlan_filter_array_read(struct sxe_hw *hw, u16 reg_index); void sxe_hw_vlan_filter_switch(struct sxe_hw *hw, bool is_enable); -u32 sxe_hw_vlan_type_get(struct sxe_hw *hw); +s32 sxe_hw_vlvf_slot_find(struct sxe_hw *hw, u32 vlan, bool vlvf_bypass); -void sxe_hw_vlan_type_set(struct sxe_hw *hw, u32 value); +s32 sxe_hw_vlan_filter_configure(struct sxe_hw *hw, u32 vid, u32 pool, + bool vlan_on, bool vlvf_bypass); -void sxe_hw_vlan_ext_vet_write(struct sxe_hw *hw, u32 value); +void sxe_hw_vlan_filter_array_clear(struct sxe_hw *hw); -void sxe_hw_vlan_tag_strip_switch(struct sxe_hw *hw, u16 reg_index, - bool is_enable); +u32 sxe_hw_rx_pkt_buf_size_get(struct sxe_hw *hw, u8 pb); -void sxe_hw_txctl_vlan_type_set(struct sxe_hw *hw, u32 value); +void sxe_hw_rx_multi_ring_configure(struct sxe_hw *hw, u8 tcs, bool is_4Q, + bool sriov_enable); -u32 sxe_hw_txctl_vlan_type_get(struct sxe_hw *hw); +void sxe_hw_rss_key_set_all(struct sxe_hw *hw, u32 *rss_key); -u32 sxe_hw_ext_vlan_get(struct sxe_hw *hw); +void sxe_hw_rss_redir_tbl_reg_write(struct sxe_hw *hw, u16 reg_idx, u32 value); -void sxe_hw_ext_vlan_set(struct sxe_hw *hw, u32 value); +void sxe_hw_rss_redir_tbl_set_all(struct sxe_hw *hw, u8 *redir_tbl); -void sxe_hw_pf_rst_done_set(struct sxe_hw *hw); +void sxe_hw_rx_cap_switch_on(struct sxe_hw *hw); -u32 sxe_hw_all_regs_group_num_get(void); +void sxe_hw_rx_cap_switch_off(struct sxe_hw *hw); -void sxe_hw_all_regs_group_read(struct sxe_hw *hw, u32 *data); +void sxe_hw_tx_pkt_buf_switch(struct sxe_hw *hw, bool is_on); -s32 sxe_hw_fc_enable(struct sxe_hw *hw); +void sxe_hw_tx_pkt_buf_size_configure(struct sxe_hw *hw, u8 num_pb); -bool sxe_hw_is_fc_autoneg_disabled(struct sxe_hw *hw); +void sxe_hw_rx_lro_ack_switch(struct sxe_hw *hw, bool is_on); -void sxe_hw_fc_status_get(struct sxe_hw *hw, bool *rx_pause_on, - bool *tx_pause_on); +void sxe_hw_fnav_enable(struct sxe_hw *hw, u32 fnavctrl); -void sxe_hw_fc_requested_mode_set(struct sxe_hw *hw, enum sxe_fc_mode mode); +u32 sxe_hw_fnav_port_mask_get(__be16 src_port_mask, __be16 dst_port_mask); -void sxe_hw_fc_tc_high_water_mark_set(struct sxe_hw *hw, u8 tc_idx, u32 mark); +s32 sxe_hw_fnav_specific_rule_mask_set(struct sxe_hw *hw, + union sxe_fnav_rule_info *input_mask); -void sxe_hw_fc_tc_low_water_mark_set(struct sxe_hw *hw, u8 tc_idx, u32 mark); +s32 sxe_hw_fnav_specific_rule_add(struct sxe_hw *hw, + union sxe_fnav_rule_info *input, + u16 soft_id, u8 queue); -void sxe_hw_fc_autoneg_disable_set(struct sxe_hw *hw, bool is_disabled); +s32 sxe_hw_fnav_specific_rule_del(struct sxe_hw *hw, + union sxe_fnav_rule_info *input, + u16 soft_id); -u32 sxe_hw_rx_pkt_buf_size_get(struct sxe_hw *hw, u8 pb); +void sxe_hw_fnav_sample_rule_configure(struct sxe_hw *hw, u8 flow_type, + u32 hash_value, u8 queue); -void sxe_hw_ptp_init(struct sxe_hw *hw); +s32 sxe_hw_fnav_sample_rules_table_reinit(struct sxe_hw *hw); -void sxe_hw_ptp_timestamp_mode_set(struct sxe_hw *hw, bool is_l2, u32 tsctl, - u32 tses); +u64 sxe_hw_ptp_systime_get(struct sxe_hw *hw); -void sxe_hw_ptp_timestamp_enable(struct sxe_hw *hw); +void sxe_hw_ptp_systime_init(struct sxe_hw *hw); -void sxe_hw_ptp_time_inc_stop(struct sxe_hw *hw); +void sxe_hw_ptp_init(struct sxe_hw *hw); void sxe_hw_ptp_rx_timestamp_clear(struct sxe_hw *hw); -void sxe_hw_ptp_timestamp_disable(struct sxe_hw *hw); - bool sxe_hw_ptp_is_rx_timestamp_valid(struct sxe_hw *hw); u64 sxe_hw_ptp_rx_timestamp_get(struct sxe_hw *hw); void sxe_hw_ptp_tx_timestamp_get(struct sxe_hw *hw, u32 *ts_sec, u32 *ts_ns); -u64 sxe_hw_ptp_systime_get(struct sxe_hw *hw); +void sxe_hw_ptp_timestamp_mode_set(struct sxe_hw *hw, bool is_l2, u32 tsctl, + u32 tses); -void sxe_hw_rss_cap_switch(struct sxe_hw *hw, bool is_on); +void sxe_hw_ptp_timestamp_enable(struct sxe_hw *hw); -void sxe_hw_rss_key_set_all(struct sxe_hw *hw, u32 *rss_key); +void sxe_hw_rx_dma_ctrl_init(struct sxe_hw *hw); -void sxe_hw_rss_field_set(struct sxe_hw *hw, u32 rss_field); +void sxe_hw_rx_dma_lro_ctrl_set(struct sxe_hw *hw); -void sxe_hw_rss_redir_tbl_set_all(struct sxe_hw *hw, u8 *redir_tbl); +void sxe_hw_rx_ring_switch(struct sxe_hw *hw, u8 reg_idx, bool is_on); -u32 sxe_hw_rss_redir_tbl_get_by_idx(struct sxe_hw *hw, u16 reg_idx); +void sxe_hw_rx_desc_thresh_set(struct sxe_hw *hw, u8 reg_idx); -void sxe_hw_rss_redir_tbl_set_by_idx(struct sxe_hw *hw, u16 reg_idx, u32 value); +void sxe_hw_rx_ring_switch_not_polling(struct sxe_hw *hw, u8 reg_idx, bool is_on); -void sxe_hw_rx_dma_ctrl_init(struct sxe_hw *hw); +void sxe_hw_rx_queue_desc_reg_configure(struct sxe_hw *hw, + u8 reg_idx, u32 rdh_value, + u32 rdt_value); -void sxe_hw_mac_max_frame_set(struct sxe_hw *hw, u32 max_frame); +void sxe_hw_rx_ring_desc_configure(struct sxe_hw *hw, + u32 desc_mem_len, u64 desc_dma_addr, + u8 reg_idx); -void sxe_hw_rx_udp_frag_checksum_disable(struct sxe_hw *hw); +void sxe_hw_rx_rcv_ctl_configure(struct sxe_hw *hw, u8 reg_idx, + u32 header_buf_len, u32 pkg_buf_len); -void sxe_hw_rx_ip_checksum_offload_switch(struct sxe_hw *hw, bool is_on); +void sxe_hw_rx_lro_ctl_configure(struct sxe_hw *hw, u8 reg_idx, u32 max_desc); -void sxe_hw_rx_ring_switch(struct sxe_hw *hw, u8 reg_idx, bool is_on); +void sxe_hw_tx_ring_head_init(struct sxe_hw *hw, u8 reg_idx); -void sxe_hw_rx_ring_switch_not_polling(struct sxe_hw *hw, u8 reg_idx, - bool is_on); +void sxe_hw_tx_ring_tail_init(struct sxe_hw *hw, u8 reg_idx); -void sxe_hw_rx_ring_desc_configure(struct sxe_hw *hw, u32 desc_mem_len, +void sxe_hw_tx_ring_desc_configure(struct sxe_hw *hw, u32 desc_mem_len, u64 desc_dma_addr, u8 reg_idx); -void sxe_hw_rx_rcv_ctl_configure(struct sxe_hw *hw, u8 reg_idx, - u32 header_buf_len, u32 pkg_buf_len); +void sxe_hw_tx_desc_thresh_set(struct sxe_hw *hw, u8 reg_idx, u32 wb_thresh, + u32 host_thresh, u32 prefech_thresh); -void sxe_hw_rx_drop_switch(struct sxe_hw *hw, u8 idx, bool is_enable); +void sxe_hw_all_ring_disable(struct sxe_hw *hw, u32 ring_max); -void sxe_hw_rx_desc_thresh_set(struct sxe_hw *hw, u8 reg_idx); +void sxe_hw_tx_ring_switch(struct sxe_hw *hw, u8 reg_idx, bool is_on); -void sxe_hw_rx_lro_ack_switch(struct sxe_hw *hw, bool is_on); +void sxe_hw_tx_ring_switch_not_polling(struct sxe_hw *hw, u8 reg_idx, bool is_on); -void sxe_hw_rx_dma_lro_ctrl_set(struct sxe_hw *hw); +void sxe_hw_tx_pkt_buf_thresh_configure(struct sxe_hw *hw, + u8 num_pb, bool dcb_enable); -void sxe_hw_rx_nfs_filter_disable(struct sxe_hw *hw); +void sxe_hw_tx_enable(struct sxe_hw *hw); -void sxe_hw_rx_lro_enable(struct sxe_hw *hw, bool is_enable); +void sxe_hw_vlan_tag_strip_switch(struct sxe_hw *hw, u16 reg_index, + bool is_enable); -void sxe_hw_rx_lro_ctl_configure(struct sxe_hw *hw, u8 reg_idx, u32 max_desc); +void sxe_hw_tx_vlan_tag_clear(struct sxe_hw *hw, u32 vf); + +u32 sxe_hw_tx_vlan_insert_get(struct sxe_hw *hw, u32 vf); + +void sxe_hw_tx_ring_info_get(struct sxe_hw *hw, u8 idx, u32 *head, u32 *tail); + +void sxe_hw_dcb_rx_bw_alloc_configure(struct sxe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type, + u8 *prio_tc, + u8 max_priority); + +void sxe_hw_dcb_tx_desc_bw_alloc_configure(struct sxe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type); + +void sxe_hw_dcb_tx_data_bw_alloc_configure(struct sxe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type, + u8 *prio_tc, + u8 max_priority); + +void sxe_hw_dcb_pfc_configure(struct sxe_hw *hw, u8 pfc_en, u8 *prio_tc, + u8 max_priority); void sxe_hw_loopback_switch(struct sxe_hw *hw, bool is_enable); -void sxe_hw_rx_cap_switch_off(struct sxe_hw *hw); +void sxe_hw_pool_rx_ring_drop_enable(struct sxe_hw *hw, u8 vf_idx, + u16 pf_vlan, u8 ring_per_pool); -void sxe_hw_tx_ring_info_get(struct sxe_hw *hw, u8 idx, u32 *head, u32 *tail); +u32 sxe_hw_rx_pool_bitmap_get(struct sxe_hw *hw, u8 reg_idx); -void sxe_hw_tx_ring_switch(struct sxe_hw *hw, u8 reg_idx, bool is_on); +u32 sxe_hw_tx_pool_bitmap_get(struct sxe_hw *hw, u8 reg_idx); -void sxe_hw_tx_ring_switch_not_polling(struct sxe_hw *hw, u8 reg_idx, - bool is_on); +void sxe_hw_tx_pool_bitmap_set(struct sxe_hw *hw, u8 reg_idx, u32 bitmap); -void sxe_hw_rx_queue_desc_reg_configure(struct sxe_hw *hw, u8 reg_idx, - u32 rdh_value, u32 rdt_value); +void sxe_hw_rx_pool_bitmap_set(struct sxe_hw *hw, u8 reg_idx, u32 bitmap); -u32 sxe_hw_hdc_fw_status_get(struct sxe_hw *hw); +void sxe_hw_dcb_max_mem_window_set(struct sxe_hw *hw, u32 value); + +void sxe_hw_dcb_tx_ring_rate_factor_set(struct sxe_hw *hw, u32 ring_idx, + u32 rate); + +void sxe_hw_spoof_count_enable(struct sxe_hw *hw, u8 reg_idx, u8 bit_index); + +void sxe_hw_pool_mac_anti_spoof_set(struct sxe_hw *hw, u8 vf_idx, bool status); + +void sxe_hw_rx_drop_switch(struct sxe_hw *hw, u8 idx, bool is_enable); + +void sxe_hw_dcb_rate_limiter_clear(struct sxe_hw *hw, u8 ring_max); + +void sxe_hw_stats_get(struct sxe_hw *hw, struct sxe_mac_stats *stats); + +void sxe_hw_mbx_init(struct sxe_hw *hw); + +bool sxe_hw_vf_rst_check(struct sxe_hw *hw, u8 vf_idx); + +bool sxe_hw_vf_req_check(struct sxe_hw *hw, u8 vf_idx); + +bool sxe_hw_vf_ack_check(struct sxe_hw *hw, u8 vf_idx); + +void sxe_hw_mbx_mem_clear(struct sxe_hw *hw, u8 vf_idx); + +void sxe_hw_pcie_vt_mode_set(struct sxe_hw *hw, u32 value); s32 sxe_hw_hdc_lock_get(struct sxe_hw *hw, u32 trylock); @@ -1206,79 +1319,98 @@ bool sxe_hw_hdc_is_fw_over_set(struct sxe_hw *hw); void sxe_hw_hdc_fw_ov_clear(struct sxe_hw *hw); -u32 sxe_hw_hdc_fw_ack_header_get(struct sxe_hw *hw); - void sxe_hw_hdc_packet_send_done(struct sxe_hw *hw); void sxe_hw_hdc_packet_header_send(struct sxe_hw *hw, u32 value); +u32 sxe_hw_hdc_fw_ack_header_get(struct sxe_hw *hw); + void sxe_hw_hdc_packet_data_dword_send(struct sxe_hw *hw, u16 dword_index, u32 value); u32 sxe_hw_hdc_packet_data_dword_rcv(struct sxe_hw *hw, u16 dword_index); +void sxe_hw_hdc_drv_status_set(struct sxe_hw *hw, u32 value); + u32 sxe_hw_hdc_channel_state_get(struct sxe_hw *hw); -u32 sxe_hw_pending_irq_read_clear(struct sxe_hw *hw); +void sxe_hw_stats_seq_clean(struct sxe_hw *hw, struct sxe_mac_stats *stats); -void sxe_hw_all_ring_disable(struct sxe_hw *hw, u32 ring_max); +void sxe_hw_stats_regs_clean(struct sxe_hw *hw); -void sxe_hw_tx_ring_head_init(struct sxe_hw *hw, u8 reg_idx); +#ifdef SXE_DPDK -void sxe_hw_tx_ring_tail_init(struct sxe_hw *hw, u8 reg_idx); +void sxe_hw_crc_strip_config(struct sxe_hw *hw, bool keep_crc); -void sxe_hw_tx_enable(struct sxe_hw *hw); +s32 sxe_rcv_msg_from_vf_lock(struct sxe_hw *hw, u32 *msg, u16 msg_len, + u16 index); -void sxe_hw_tx_desc_thresh_set(struct sxe_hw *hw, u8 reg_idx, u32 wb_thresh, - u32 host_thresh, u32 prefech_thresh); +s32 sxe_send_msg_to_vf_lock(struct sxe_hw *hw, u32 *msg, u16 msg_len, + u16 index); -void sxe_hw_tx_pkt_buf_switch(struct sxe_hw *hw, bool is_on); +u16 sxe_hw_fc_pause_time_get(struct sxe_hw *hw); -void sxe_hw_tx_pkt_buf_size_configure(struct sxe_hw *hw, u8 num_pb); +void sxe_hw_fc_pause_time_set(struct sxe_hw *hw, u16 pause_time); -void sxe_hw_tx_pkt_buf_thresh_configure(struct sxe_hw *hw, u8 num_pb, - bool dcb_enable); +u32 sxe_hw_fc_tc_high_water_mark_get(struct sxe_hw *hw, u8 tc_idx); -void sxe_hw_tx_ring_desc_configure(struct sxe_hw *hw, u32 desc_mem_len, - u64 desc_dma_addr, u8 reg_idx); +u32 sxe_hw_fc_tc_low_water_mark_get(struct sxe_hw *hw, u8 tc_idx); -void sxe_hw_mac_txrx_enable(struct sxe_hw *hw); +u16 sxe_hw_fc_send_xon_get(struct sxe_hw *hw); -void sxe_hw_rx_cap_switch_on(struct sxe_hw *hw); +void sxe_hw_fc_send_xon_set(struct sxe_hw *hw, u16 send_xon); -void sxe_hw_mac_pad_enable(struct sxe_hw *hw); +u32 sxe_hw_ring_irq_switch_get(struct sxe_hw *hw, u8 idx); -bool sxe_hw_is_link_state_up(struct sxe_hw *hw); +void sxe_hw_ring_irq_switch_set(struct sxe_hw *hw, u8 idx, u32 value); -u32 sxe_hw_link_speed_get(struct sxe_hw *hw); +u32 sxe_hw_uta_hash_table_get(struct sxe_hw *hw, u8 reg_idx); -void sxe_hw_fc_base_init(struct sxe_hw *hw); +void sxe_hw_uta_hash_table_set(struct sxe_hw *hw, u8 reg_idx, u32 value); -void sxe_hw_stats_get(struct sxe_hw *hw, struct sxe_mac_stats *stats); +u32 sxe_hw_vlan_type_get(struct sxe_hw *hw); -void sxe_hw_rxq_stat_map_set(struct sxe_hw *hw, u8 idx, u32 value); +void sxe_hw_vlan_type_set(struct sxe_hw *hw, u32 value); -void sxe_hw_txq_stat_map_set(struct sxe_hw *hw, u8 idx, u32 value); +void sxe_hw_vlan_ext_vet_write(struct sxe_hw *hw, u32 value); -void sxe_hw_uc_addr_clear(struct sxe_hw *hw); +void sxe_hw_txctl_vlan_type_set(struct sxe_hw *hw, u32 value); -void sxe_hw_vt_disable(struct sxe_hw *hw); +u32 sxe_hw_txctl_vlan_type_get(struct sxe_hw *hw); -void sxe_hw_stats_regs_clean(struct sxe_hw *hw); +u32 sxe_hw_ext_vlan_get(struct sxe_hw *hw); -void sxe_hw_vlan_ext_type_set(struct sxe_hw *hw, u32 value); +void sxe_hw_ext_vlan_set(struct sxe_hw *hw, u32 value); -void sxe_hw_link_speed_set(struct sxe_hw *hw, u32 speed); +u32 sxe_hw_all_regs_group_num_get(void); -void sxe_hw_crc_configure(struct sxe_hw *hw); +void sxe_hw_all_regs_group_read(struct sxe_hw *hw, u32 *data); -void sxe_hw_vlan_filter_array_clear(struct sxe_hw *hw); +void sxe_hw_fc_status_get(struct sxe_hw *hw, bool *rx_pause_on, + bool *tx_pause_on); -void sxe_hw_no_snoop_disable(struct sxe_hw *hw); +void sxe_hw_ptp_time_inc_stop(struct sxe_hw *hw); -void sxe_hw_dcb_rate_limiter_clear(struct sxe_hw *hw, u8 ring_max); +void sxe_hw_ptp_timestamp_disable(struct sxe_hw *hw); -s32 sxe_hw_pfc_enable(struct sxe_hw *hw, u8 tc_idx); +void sxe_hw_rss_cap_switch(struct sxe_hw *hw, bool is_on); + +void sxe_hw_rss_field_set(struct sxe_hw *hw, u32 rss_field); + +u32 sxe_hw_rss_redir_tbl_get_by_idx(struct sxe_hw *hw, u16 reg_idx); + +void sxe_hw_rss_redir_tbl_set_by_idx(struct sxe_hw *hw, u16 reg_idx, + u32 value); + +void sxe_hw_rx_ip_checksum_offload_switch(struct sxe_hw *hw, bool is_on); + +void sxe_hw_fc_base_init(struct sxe_hw *hw); + +void sxe_hw_rxq_stat_map_set(struct sxe_hw *hw, u8 idx, u32 value); + +void sxe_hw_txq_stat_map_set(struct sxe_hw *hw, u8 idx, u32 value); + +void sxe_hw_vlan_ext_type_set(struct sxe_hw *hw, u32 value); void sxe_hw_dcb_vmdq_mq_configure(struct sxe_hw *hw, u8 num_pools); @@ -1305,20 +1437,6 @@ void sxe_hw_rx_pkt_buf_size_set(struct sxe_hw *hw, u8 tc_idx, u16 pbsize); void sxe_hw_dcb_tc_stats_configure(struct sxe_hw *hw, u8 tc_count, bool vmdq_active); -void sxe_hw_dcb_rx_bw_alloc_configure(struct sxe_hw *hw, u16 *refill, u16 *max, - u8 *bwg_id, u8 *prio_type, u8 *prio_tc, - u8 max_priority); - -void sxe_hw_dcb_tx_desc_bw_alloc_configure(struct sxe_hw *hw, u16 *refill, - u16 *max, u8 *bwg_id, u8 *prio_type); - -void sxe_hw_dcb_tx_data_bw_alloc_configure(struct sxe_hw *hw, u16 *refill, - u16 *max, u8 *bwg_id, u8 *prio_type, - u8 *prio_tc, u8 max_priority); - -void sxe_hw_dcb_pfc_configure(struct sxe_hw *hw, u8 pfc_en, u8 *prio_tc, - u8 max_priority); - void sxe_hw_vmdq_mq_configure(struct sxe_hw *hw); void sxe_hw_vmdq_default_pool_configure(struct sxe_hw *hw, @@ -1335,76 +1453,19 @@ void sxe_hw_vmdq_loopback_configure(struct sxe_hw *hw); void sxe_hw_tx_multi_queue_configure(struct sxe_hw *hw, bool vmdq_enable, bool sriov_enable, u16 pools_num); -void sxe_hw_dcb_max_mem_window_set(struct sxe_hw *hw, u32 value); - -void sxe_hw_dcb_tx_ring_rate_factor_set(struct sxe_hw *hw, u32 ring_idx, - u32 rate); - -void sxe_hw_mbx_init(struct sxe_hw *hw); - -void sxe_hw_vt_ctrl_cfg(struct sxe_hw *hw, u8 num_vfs); - -void sxe_hw_tx_pool_bitmap_set(struct sxe_hw *hw, u8 reg_idx, u32 bitmap); - -void sxe_hw_rx_pool_bitmap_set(struct sxe_hw *hw, u8 reg_idx, u32 bitmap); - -void sxe_hw_vt_pool_loopback_switch(struct sxe_hw *hw, bool is_enable); - void sxe_hw_mac_pool_clear(struct sxe_hw *hw, u8 rar_idx); -s32 sxe_hw_uc_addr_pool_enable(struct sxe_hw *hw, u8 rar_idx, u8 pool_idx); - s32 sxe_hw_uc_addr_single_pool_disable(struct sxe_hw *hw, u8 rar_idx, u8 pool_idx); -void sxe_hw_pcie_vt_mode_set(struct sxe_hw *hw, u32 value); - u32 sxe_hw_pcie_vt_mode_get(struct sxe_hw *hw); -void sxe_hw_pool_mac_anti_spoof_set(struct sxe_hw *hw, u8 vf_idx, bool status); - void sxe_rx_fc_threshold_set(struct sxe_hw *hw); -void sxe_hw_rx_multi_ring_configure(struct sxe_hw *hw, u8 tcs, bool is_4Q, - bool sriov_enable); - void sxe_hw_rx_queue_mode_set(struct sxe_hw *hw, u32 mrqc); -bool sxe_hw_vf_rst_check(struct sxe_hw *hw, u8 vf_idx); - -bool sxe_hw_vf_req_check(struct sxe_hw *hw, u8 vf_idx); - -bool sxe_hw_vf_ack_check(struct sxe_hw *hw, u8 vf_idx); - -s32 sxe_hw_rcv_msg_from_vf(struct sxe_hw *hw, u32 *msg, u16 msg_len, u16 index); - -s32 sxe_hw_send_msg_to_vf(struct sxe_hw *hw, u32 *msg, u16 msg_len, u16 index); - -void sxe_hw_mbx_mem_clear(struct sxe_hw *hw, u8 vf_idx); - -u32 sxe_hw_pool_rx_mode_get(struct sxe_hw *hw, u16 pool_idx); - -void sxe_hw_pool_rx_mode_set(struct sxe_hw *hw, u32 vmolr, u16 pool_idx); - -void sxe_hw_tx_vlan_tag_clear(struct sxe_hw *hw, u32 vf); - -u32 sxe_hw_rx_pool_bitmap_get(struct sxe_hw *hw, u8 reg_idx); - -u32 sxe_hw_tx_pool_bitmap_get(struct sxe_hw *hw, u8 reg_idx); - -void sxe_hw_pool_rx_ring_drop_enable(struct sxe_hw *hw, u8 vf_idx, u16 pf_vlan, - u8 ring_per_pool); - -void sxe_hw_spoof_count_enable(struct sxe_hw *hw, u8 reg_idx, u8 bit_index); - -u32 sxe_hw_tx_vlan_insert_get(struct sxe_hw *hw, u32 vf); - bool sxe_hw_vt_status(struct sxe_hw *hw); -s32 sxe_hw_vlvf_slot_find(struct sxe_hw *hw, u32 vlan, bool vlvf_bypass); - -u32 sxe_hw_vlan_pool_filter_read(struct sxe_hw *hw, u16 reg_index); - void sxe_hw_mirror_vlan_set(struct sxe_hw *hw, u8 idx, u32 lsb, u32 msb); void sxe_hw_mirror_virtual_pool_set(struct sxe_hw *hw, u8 idx, u32 lsb, @@ -1420,13 +1481,8 @@ void sxe_hw_mac_reuse_add(struct rte_eth_dev *dev, u8 *mac_addr, u8 rar_idx); void sxe_hw_mac_reuse_del(struct rte_eth_dev *dev, u8 *mac_addr, u8 pool_idx, u8 rar_idx); -u32 sxe_hw_mac_max_frame_get(struct sxe_hw *hw); - -void sxe_hw_mta_hash_table_update(struct sxe_hw *hw, u8 reg_idx, u8 bit_idx); - void sxe_hw_vf_queue_drop_enable(struct sxe_hw *hw, u8 vf_idx, u8 ring_per_pool); -void sxe_hw_fc_mac_addr_set(struct sxe_hw *hw, u8 *mac_addr); void sxe_hw_macsec_enable(struct sxe_hw *hw, bool is_up, u32 tx_mode, u32 rx_mode, u32 pn_trh); @@ -1443,8 +1499,6 @@ void sxe_hw_macsec_tx_sa_configure(struct sxe_hw *hw, u8 sa_idx, u8 an, u32 pn, void sxe_hw_macsec_rx_sa_configure(struct sxe_hw *hw, u8 sa_idx, u8 an, u32 pn, u32 *keys); -void sxe_hw_vt_pool_loopback_switch(struct sxe_hw *hw, bool is_enable); - #if defined SXE_DPDK_L4_FEATURES && defined SXE_DPDK_FILTER_CTRL void sxe_hw_fnav_rx_pkt_buf_size_reset(struct sxe_hw *hw, u32 pbsize); @@ -1467,35 +1521,6 @@ void sxe_hw_ethertype_filter_del(struct sxe_hw *hw, u8 filter_type); void sxe_hw_syn_filter_add(struct sxe_hw *hw, u16 queue, u8 priority); void sxe_hw_syn_filter_del(struct sxe_hw *hw); - -void sxe_hw_rss_key_set_all(struct sxe_hw *hw, u32 *rss_key); #endif - -void sxe_hw_fnav_enable(struct sxe_hw *hw, u32 fnavctrl); - -s32 sxe_hw_fnav_sample_rules_table_reinit(struct sxe_hw *hw); - -s32 sxe_hw_fnav_specific_rule_add(struct sxe_hw *hw, - union sxe_fnav_rule_info *input, - u16 soft_id, u8 queue); - -s32 sxe_hw_fnav_specific_rule_del(struct sxe_hw *hw, - union sxe_fnav_rule_info *input, u16 soft_id); - -void sxe_hw_fnav_sample_rule_configure(struct sxe_hw *hw, u8 flow_type, - u32 hash_value, u8 queue); - -void sxe_hw_rss_redir_tbl_reg_write(struct sxe_hw *hw, u16 reg_idx, u32 value); - -u32 sxe_hw_fnav_port_mask_get(__be16 src_port_mask, __be16 dst_port_mask); - -s32 sxe_hw_fnav_specific_rule_mask_set(struct sxe_hw *hw, - union sxe_fnav_rule_info *input_mask); - -s32 sxe_hw_vlan_filter_configure(struct sxe_hw *hw, u32 vid, u32 pool, - bool vlan_on, bool vlvf_bypass); - -void sxe_hw_ptp_systime_init(struct sxe_hw *hw); - #endif #endif diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c index fadf0b2fe4bf..2aa8a098ba25 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c @@ -56,6 +56,9 @@ static inline void netif_napi_add_compat(struct net_device *dev, netif_napi_add(dev, napi, poll); } +#ifdef netif_napi_add +#undef netif_napi_add +#endif #define netif_napi_add(dev, napi, poll, weight) \ netif_napi_add_compat(dev, napi, poll, weight) #endif @@ -133,7 +136,7 @@ static void sxe_irq_num_reinit(struct sxe_adapter *adapter) adapter->irq_ctxt.ring_irq_num); } -int sxe_msi_irq_init(struct sxe_adapter *adapter) +static int sxe_msi_irq_init(struct sxe_adapter *adapter) { int ret; @@ -179,7 +182,7 @@ s32 sxe_config_space_irq_num_get(struct sxe_adapter *adapter) return ret; } -void sxe_disable_dcb(struct sxe_adapter *adapter) +static void sxe_disable_dcb(struct sxe_adapter *adapter) { if (sxe_dcb_tc_get(adapter) > 1) { LOG_DEV_WARN("number of DCB TCs exceeds number of available queues.\n" @@ -209,7 +212,7 @@ static int sxe_disable_sriov(struct sxe_adapter *adapter) return 0; } -void sxe_disable_rss(struct sxe_adapter *adapter) +static void sxe_disable_rss(struct sxe_adapter *adapter) { LOG_DEV_WARN("disabling RSS support.\n"); @@ -628,6 +631,9 @@ void sxe_irq_release(struct sxe_adapter *adapter) u16 irq_idx; struct sxe_irq_context *irq_ctxt = &adapter->irq_ctxt; + if (!test_bit(SXE_IRQ_REQUESTED, &adapter->state)) + return; + if (!irq_ctxt->ring_irq_num) goto l_out; @@ -656,6 +662,7 @@ void sxe_irq_release(struct sxe_adapter *adapter) free_irq(irq_ctxt->msix_entries[irq_idx].vector, adapter); l_out: + clear_bit(SXE_IRQ_REQUESTED, &adapter->state); LOG_INFO_BDF("adapter cap:0x%x ring_irq_num:%u irq unregister done.", adapter->cap, irq_ctxt->ring_irq_num); } @@ -726,7 +733,7 @@ static irqreturn_t sxe_msix_ring_irq_handler(int irq, void *data) return IRQ_HANDLED; } -void sxe_lsc_irq_handler(struct sxe_adapter *adapter) +static void sxe_lsc_irq_handler(struct sxe_adapter *adapter) { struct sxe_hw *hw = &adapter->hw; @@ -742,7 +749,7 @@ void sxe_lsc_irq_handler(struct sxe_adapter *adapter) } } -void sxe_mailbox_irq_handler(struct sxe_adapter *adapter) +static void sxe_mailbox_irq_handler(struct sxe_adapter *adapter) { struct sxe_hw *hw = &adapter->hw; unsigned long flags; @@ -802,28 +809,30 @@ static void sxe_sfp_irq_handler(struct sxe_adapter *adapter, u32 eicr) hw->irq.ops->pending_irq_write_clear(hw, SXE_EICR_GPI_SPP2); if (!test_bit(SXE_DOWN, &adapter->state)) { state = hw->irq.ops->spp_state_get(hw); - if (!(state & SXE_SPP2_STATE)) { + if (!(state & SXE_SFP_STATE_PRESENT)) { hw->irq.ops->rx_los_disable(hw); hw->irq.ops->spp_configure(&adapter->hw, SXE_SPP_PROC_DELAY_US); adapter->phy_ctxt.sfp_info.inserted = false; + set_bit(SXE_SFP_NEED_DOWN, &adapter->monitor_ctxt.state); LOG_INFO_BDF("sfp is extracted, disable rxlos,\n" "\tspp_configure is default 7us\n"); } else { + clear_bit(SXE_SFP_NEED_DOWN, &adapter->monitor_ctxt.state); set_bit(SXE_SFP_NEED_RESET, &adapter->monitor_ctxt.state); adapter->link.sfp_reset_timeout = 0; LOG_DEV_WARN("sfp is inserted into slot,\n" "\ttrigger sfp_reset subtask\n"); - sxe_monitor_work_schedule(adapter); } + sxe_monitor_work_schedule(adapter); } } if (eicr & SXE_EICR_GPI_SPP1) { hw->irq.ops->pending_irq_write_clear(hw, SXE_EICR_GPI_SPP1); if (!test_bit(SXE_DOWN, &adapter->state) && - !test_bit(SXE_SFP_MULTI_SPEED_SETTING, &adapter->state)) { + !test_bit(SXE_SFP_LOS_DISABLED, &adapter->state)) { if (time_after(jiffies, adapter->link.last_lkcfg_time + #ifdef SXE_SFP_DEBUG (HZ * sw_sfp_los_delay_ms) / SXE_HZ_TRANSTO_MS)) { @@ -977,7 +986,7 @@ static int sxe_msix_request_irqs(struct sxe_adapter *adapter) irq_set_affinity_hint(adapter->irq_ctxt.msix_entries[irq_idx].vector, NULL); free_irq(irq_ctxt->msix_entries[irq_idx].vector, - irq_ctxt->irq_data[irq_idx]); + irq_ctxt->irq_data[irq_idx]); } adapter->cap &= ~SXE_MSIX_ENABLED; @@ -1119,8 +1128,13 @@ void sxe_hw_irq_configure(struct sxe_adapter *adapter) else sxe_configure_non_msix_hw(adapter); - if (adapter->phy_ctxt.ops->sfp_tx_laser_enable) - adapter->phy_ctxt.ops->sfp_tx_laser_enable(adapter); + if (adapter->phy_ctxt.ops->sfp_tx_laser_enable) { + if (adapter->phy_ctxt.sfp_info.sfp_link_cfg_info.los_block_flag && + adapter->phy_ctxt.sfp_info.slow_skip) + LOG_INFO("The sfp do not need to laser enable\n"); + else + adapter->phy_ctxt.ops->sfp_tx_laser_enable(adapter); + } /* in order to force CPU ordering */ smp_mb__before_atomic(); @@ -1155,6 +1169,8 @@ int sxe_irq_configure(struct sxe_adapter *adapter) sxe_hw_irq_configure(adapter); + set_bit(SXE_IRQ_REQUESTED, &adapter->state); + l_out: return ret; } diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.h b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.h index 14f1a0a787c5..aeaa86ef6251 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.h +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.h @@ -92,7 +92,11 @@ struct sxe_irq_data { s32 numa_node; struct rcu_head rcu; s8 name[IFNAMSIZ + 16]; +#ifdef HAVE_REPLACE_ZERO_ARRAY_WITH_FLEXIBLE + struct sxe_ring ring[] ____cacheline_internodealigned_in_smp; +#else struct sxe_ring ring[0] ____cacheline_internodealigned_in_smp; +#endif }; struct sxe_irq_context { diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c index 12a8fa12aa15..0956a756299b 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c @@ -67,7 +67,7 @@ module_param(allow_inval_mac, bool, false); MODULE_PARM_DESC(allow_inval_mac, "Indicates device can be probed successfully or not when mac addr invalid."); -bool sxe_allow_inval_mac(void) +static bool sxe_allow_inval_mac(void) { return !!allow_inval_mac; } @@ -591,6 +591,9 @@ static int sxe_hw_base_init(struct sxe_adapter *adapter) LOG_ERROR_BDF("phy init failed, ret=%d\n", ret); } + if (adapter->phy_ctxt.sfp_info.sfp_link_cfg_info.los_block_flag) + adapter->phy_ctxt.sfp_info.slow_skip = true; + ret = sxe_default_mac_addr_get(adapter); if (ret) { LOG_ERROR_BDF("get valid default mac addr failed, ret=%d\n", @@ -801,8 +804,8 @@ static int sxe_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto l_adapter_create_failed; } - strlcpy(adapter->dev_name, device_name, - min_t(u32, strlen(device_name) + 1, DEV_NAME_LEN)); + SXE_STRCPY(adapter->dev_name, device_name, + min_t(u32, strlen(device_name) + 1, DEV_NAME_LEN)); ret = sxe_pci_init(adapter); if (ret) { @@ -897,6 +900,7 @@ static void sxe_fuc_exit(struct sxe_adapter *adapter) { cancel_work_sync(&adapter->monitor_ctxt.work); cancel_work_sync(&adapter->hdc_ctxt.time_sync_work); + clear_bit(SXE_MONITOR_WORK_SCHED, &adapter->monitor_ctxt.state); #ifdef SXE_PHY_CONFIGURE sxe_mdiobus_exit(adapter); @@ -1047,6 +1051,7 @@ static int sxe_suspend(struct device *dev) cancel_work_sync(&adapter->monitor_ctxt.work); cancel_work_sync(&adapter->hdc_ctxt.time_sync_work); + clear_bit(SXE_MONITOR_WORK_SCHED, &adapter->monitor_ctxt.state); sxe_hdc_channel_destroy(hw); if (ret) { @@ -1530,8 +1535,8 @@ static void sxe_driver_remove_file(void) #endif #ifdef SXE_DRIVER_TRACE -ssize_t trace_dump_store(struct device_driver *dd, const char *buf, - size_t count) +static ssize_t trace_dump_store(struct device_driver *dd, const char *buf, + size_t count) { ssize_t ret = count; @@ -1551,7 +1556,7 @@ static inline ssize_t trace_dump_show(struct device_driver *dd, char *buf) static DRIVER_ATTR_RW(trace_dump); -s32 sxe_trace_dump_create_file(void) +static s32 sxe_trace_dump_create_file(void) { s32 ret; @@ -1563,7 +1568,7 @@ s32 sxe_trace_dump_create_file(void) return ret; } -void sxe_trace_dump_remove_file(void) +static void sxe_trace_dump_remove_file(void) { driver_remove_file(&sxe_pci_driver.driver, &driver_attr_trace_dump); } diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c index e55881c65302..3d70a9d375d1 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c @@ -29,6 +29,10 @@ extern struct workqueue_struct *sxe_fnav_workqueue; #define SXE_CHECK_LINK_TIMER_PERIOD (HZ / 10) #define SXE_NORMAL_TIMER_PERIOD (HZ * 2) +#define SXE_DELAY_TIME_3 (3) +#define SXE_DELAY_TIME_6 (6) +static u8 sxe_delay_time = SXE_DELAY_TIME_3; + #ifdef SXE_SFP_DEBUG static unsigned int sw_sfp_multi_gb_ms = SXE_SW_SFP_MULTI_GB_MS; #ifndef SXE_TEST @@ -40,15 +44,24 @@ MODULE_PARM_DESC(sw_sfp_multi_gb_ms, void sxe_task_timer_trigger(struct sxe_adapter *adapter) { + u8 wait_time = 0; + set_bit(SXE_LINK_CHECK_REQUESTED, &adapter->monitor_ctxt.state); LOG_DEBUG_BDF("trigger link_check subtask, state=%lx,\n" "\tmonitor_state=%lx, is_up=%d\n", adapter->state, adapter->monitor_ctxt.state, adapter->link.is_up); - adapter->link.check_timeout = jiffies; + if (adapter->phy_ctxt.sfp_info.sfp_link_cfg_info.los_block_flag && + adapter->phy_ctxt.sfp_info.slow_skip) { + wait_time = sxe_delay_time; + sxe_delay_time += SXE_DELAY_TIME_3; + if (sxe_delay_time > SXE_DELAY_TIME_6) + sxe_delay_time = SXE_DELAY_TIME_3; + } - mod_timer(&adapter->monitor_ctxt.timer, jiffies); + adapter->link.check_timeout = jiffies + wait_time * HZ; + mod_timer(&adapter->monitor_ctxt.timer, jiffies + wait_time * HZ); } void sxe_sfp_reset_task_submit(struct sxe_adapter *adapter) @@ -57,7 +70,8 @@ void sxe_sfp_reset_task_submit(struct sxe_adapter *adapter) LOG_INFO("trigger sfp_reset subtask\n"); adapter->link.sfp_reset_timeout = 0; adapter->link.last_lkcfg_time = 0; - adapter->link.sfp_multispeed_time = 0; + adapter->link.sfp_los_disable_timeout = 0; + adapter->link.link_quirks_timeout = 0; } void sxe_monitor_work_schedule(struct sxe_adapter *adapter) @@ -68,6 +82,12 @@ void sxe_monitor_work_schedule(struct sxe_adapter *adapter) !test_bit(SXE_REMOVING, &adapter->state) && !test_and_set_bit(SXE_MONITOR_WORK_SCHED, &adapter->monitor_ctxt.state)) { + if (adapter->phy_ctxt.sfp_info.sfp_link_cfg_info.los_block_flag && + adapter->phy_ctxt.sfp_info.slow_skip) { + clear_bit(SXE_MONITOR_WORK_SCHED, &adapter->monitor_ctxt.state); + return; + } + queue_work(wq, &adapter->monitor_ctxt.work); } } @@ -81,7 +101,7 @@ static void sxe_timer_cb(struct timer_list *timer) unsigned long period; if (test_bit(SXE_LINK_CHECK_REQUESTED, &adapter->monitor_ctxt.state) || - test_bit(SXE_SFP_MULTI_SPEED_SETTING, &adapter->state)) { + test_bit(SXE_SFP_LOS_DISABLED, &adapter->state)) { period = SXE_CHECK_LINK_TIMER_PERIOD; } else { period = SXE_NORMAL_TIMER_PERIOD; @@ -89,6 +109,10 @@ static void sxe_timer_cb(struct timer_list *timer) mod_timer(&adapter->monitor_ctxt.timer, period + jiffies); + if (adapter->phy_ctxt.sfp_info.sfp_link_cfg_info.los_block_flag && + adapter->phy_ctxt.sfp_info.slow_skip) + adapter->phy_ctxt.sfp_info.slow_skip = false; + sxe_monitor_work_schedule(adapter); } @@ -224,8 +248,12 @@ static void sxe_link_update(struct sxe_adapter *adapter) LOG_DEBUG_BDF("link update, speed=%x, is_up=%d\n", adapter->link.speed, adapter->link.is_up); - if (adapter->link.is_up) + if (adapter->link.is_up) { sxe_vmac_configure(adapter); + clear_bit(SXE_SFP_MULTI_SPEED_QUIRKS, &adapter->state); + if (!(adapter->phy_ctxt.sfp_info.sfp_link_cfg_info.disable_los_wait_timeout)) + clear_bit(SXE_SFP_LOS_DISABLED, &adapter->state); + } if (adapter->link.is_up || time_after(jiffies, (adapter->link.check_timeout + @@ -487,6 +515,9 @@ static void sxe_sfp_reset_work(struct sxe_adapter *adapter) clear_bit(SXE_SFP_NEED_RESET, &monitor->state); + clear_bit(SXE_SFP_LOS_DISABLED, &adapter->state); + clear_bit(SXE_SFP_MULTI_SPEED_QUIRKS, &adapter->state); + set_bit(SXE_LINK_NEED_CONFIG, &monitor->state); LOG_MSG_INFO(probe, "SFP+ reset done, trigger link_config subtask\n"); @@ -506,26 +537,76 @@ static void sxe_sfp_reset_work(struct sxe_adapter *adapter) ; } -static void sxe_sfp_link_config_work(struct sxe_adapter *adapter) +static void sxe_sfp_out_work(struct sxe_adapter *adapter) { - s32 ret; - u32 speed; - bool autoneg; struct sxe_monitor_context *monitor = &adapter->monitor_ctxt; + struct net_device *netdev = adapter->netdev; + + if (!test_bit(SXE_SFP_NEED_DOWN, &monitor->state)) + return; + + adapter->link.is_up = false; + adapter->link.speed = 0; + + carrier_lock(adapter); + if (test_bit(SXE_DOWN, &adapter->state) || + test_bit(SXE_REMOVING, &adapter->state) || + test_bit(SXE_RESETTING, &adapter->state)) { + carrier_unlock(adapter); + goto l_end; + } + + if (netif_carrier_ok(netdev)) { + LOG_MSG_WARN(drv, "nic link is down\n"); + netif_carrier_off(netdev); + sxe_link_update_notify_vf_all(adapter); + } else { + carrier_unlock(adapter); + goto l_end; + } + + if (sxe_tx_ring_pending(adapter) || sxe_vf_tx_pending(adapter)) { + LOG_MSG_WARN(drv, "initiating reset to clear Tx work after link loss\n"); + set_bit(SXE_RESET_REQUESTED, &adapter->monitor_ctxt.state); + } + carrier_unlock(adapter); + + LOG_DEBUG("sfp is out, set dev down\n"); +l_end: + clear_bit(SXE_SFP_NEED_DOWN, &monitor->state); +} + +unsigned long sxe_los_disable_timeout_get(void) +{ + unsigned long timeout; - if (time_after(jiffies, adapter->link.sfp_multispeed_time + #ifdef SXE_SFP_DEBUG - (HZ * sw_sfp_multi_gb_ms) / SXE_HZ_TRANSTO_MS)) { + timeout = ((HZ * sw_sfp_multi_gb_ms) / SXE_HZ_TRANSTO_MS); #else - (HZ * SXE_SW_SFP_MULTI_GB_MS) / - SXE_HZ_TRANSTO_MS)) { + timeout = ((HZ * SXE_SW_SFP_MULTI_GB_MS) / SXE_HZ_TRANSTO_MS); #endif - clear_bit(SXE_SFP_MULTI_SPEED_SETTING, &adapter->state); - } + + return timeout; +} + +static void sxe_sfp_link_config_work(struct sxe_adapter *adapter) +{ + s32 ret; + u32 speed; + bool autoneg; + struct sxe_monitor_context *monitor = &adapter->monitor_ctxt; if (test_and_set_bit(SXE_IN_SFP_INIT, &adapter->state)) goto l_sfp_end; + if (test_bit(SXE_SFP_MULTI_SPEED_QUIRKS, &adapter->state)) { + ret = sxe_link_multispeed_quirks_configure(adapter); + if (ret) + goto l_sfp_end; + + goto l_quirks_out; + } + if (!test_bit(SXE_LINK_NEED_CONFIG, &monitor->state)) goto l_sfp_uninit; @@ -539,6 +620,7 @@ static void sxe_sfp_link_config_work(struct sxe_adapter *adapter) clear_bit(SXE_LINK_NEED_CONFIG, &monitor->state); +l_quirks_out: set_bit(SXE_LINK_CHECK_REQUESTED, &monitor->state); LOG_DEBUG("link_config subtask done, trigger link_check subtask\n"); adapter->link.check_timeout = jiffies; @@ -547,7 +629,8 @@ static void sxe_sfp_link_config_work(struct sxe_adapter *adapter) clear_bit(SXE_IN_SFP_INIT, &adapter->state); l_sfp_end: - ; + if (time_after(jiffies, adapter->link.sfp_los_disable_timeout)) + clear_bit(SXE_SFP_LOS_DISABLED, &adapter->state); } static void sxe_fc_tx_xoff_check(struct sxe_adapter *adapter) @@ -639,6 +722,7 @@ void sxe_work_cb(struct work_struct *work) sxe_sfp_link_config_work(adapter); sxe_detect_link_work(adapter); + sxe_sfp_out_work(adapter); sxe_stats_update_work(adapter); sxe_tx_xoff_check_work(adapter); diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.h b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.h index c8a35dfa428a..28393c3d693c 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.h +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.h @@ -28,6 +28,7 @@ enum sxe_monitor_task_state { SXE_FNAV_REQUIRES_REINIT, SXE_SFP_NEED_RESET, + SXE_SFP_NEED_DOWN, SXE_LINK_NEED_CONFIG, @@ -49,9 +50,12 @@ struct sxe_link_info { unsigned long check_timeout; unsigned long sfp_reset_timeout; unsigned long last_lkcfg_time; - unsigned long sfp_multispeed_time; + unsigned long sfp_los_disable_timeout; + unsigned long link_quirks_timeout; }; +unsigned long sxe_los_disable_timeout_get(void); + void sxe_monitor_init(struct sxe_adapter *adapter); void sxe_monitor_work_schedule(struct sxe_adapter *adapter); diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c index 487f6fe38f02..c49264d037ad 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c @@ -73,6 +73,7 @@ void sxe_reset(struct sxe_adapter *adapter) clear_bit(SXE_SFP_NEED_RESET, &adapter->monitor_ctxt.state); clear_bit(SXE_LINK_NEED_CONFIG, &adapter->monitor_ctxt.state); + clear_bit(SXE_SFP_NEED_DOWN, &adapter->monitor_ctxt.state); ret = sxe_hw_reset(adapter); if (ret < 0) @@ -1897,6 +1898,11 @@ static void sxe_netdev_feature_init(struct net_device *netdev) NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX; +#ifdef HAVE_NETDEV_XDP_FEATURES + netdev->xdp_features |= NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT | + NETDEV_XDP_ACT_XSK_ZEROCOPY; +#endif + adapter = netdev_priv(netdev); adapter->cap |= SXE_LRO_CAPABLE; } @@ -1904,7 +1910,7 @@ static void sxe_netdev_feature_init(struct net_device *netdev) static void sxe_netdev_name_init(struct net_device *netdev, struct pci_dev *pdev) { - strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); + SXE_STRCPY(netdev->name, pci_name(pdev), sizeof(netdev->name)); } #ifndef NO_NETDEVICE_MIN_MAX_MTU diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c index ebfe5cc399dc..d9b94c345aec 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c @@ -127,4 +127,3 @@ unsigned long sxe_get_completion_timeout(struct sxe_adapter *adapter) return 32000ul; } - diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c index 361012f5cca5..e7752156f28b 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c @@ -17,9 +17,17 @@ #include "sxe_version.h" #include "sxe_host_hdc.h" #include "sxe_errno.h" +#include "sxe_phy.h" + +#define SXE_10G_WAIT_4_TIME (4) +#define SXE_10G_WAIT_5_TIME (5) +#define SXE_1G_WAIT_1_TIME (1) +#define SXE_SFP_LOS_FILTER_DELAY_1_US (1) +#define SXE_SINGLE_SFP_WAIT_TIME_DFLT (0) +#define SXE_SINGLE_SFP_WAIT_TIME_5 (5) #define SXE_COMPAT_SFP_NUM ARRAY_SIZE(sfp_vendor_pn_list) -#define SXE_COMPAT_SFP_AOC_NUM ARRAY_SIZE(sfp_aoc_vendor_pn_list) +#define SXE_COMPAT_SFP_QUIRK_LIST_NUM ARRAY_SIZE(sfp_quirk_info_list) static u8 sfp_vendor_pn_list[][SXE_SFP_VENDOR_PN_SIZE] = { {0x58, 0x50, 0x2d, 0x33, 0x47, 0x31, 0x30, 0x2d, @@ -98,12 +106,82 @@ static u8 sfp_vendor_pn_list[][SXE_SFP_VENDOR_PN_SIZE] = { 0x30, 0x30, 0x2d, 0x30, 0x30, 0x37, 0x43, 0x20}, }; -static u8 sfp_aoc_vendor_pn_list[][SXE_SFP_VENDOR_PN_SIZE] = { - {0x47, 0x53, 0x53, 0x2d, 0x4d, 0x44, 0x4f, 0x31, - 0x30, 0x30, 0x2d, 0x30, 0x30, 0x37, 0x43, 0x20}, +static struct sxe_sfp_link_cfg sfp_link_cfg_default = { + .filter_time = SXE_SPP_PROC_DELAY_US, + .waitloop10g_fir = SXE_10G_WAIT_5_TIME, + .waitloop10g_sec = SXE_10G_WAIT_5_TIME, + .waitloop1g = SXE_1G_WAIT_1_TIME, + .waitloop_single_spd = SXE_SINGLE_SFP_WAIT_TIME_DFLT, + .los_block_flag = false, + .disable_los_wait_timeout = false, +}; - {0x49, 0x4e, 0x2d, 0x53, 0x50, 0x31, 0x30, 0x31, - 0x53, 0x52, 0x4c, 0x43, 0x20, 0x20, 0x20, 0x20}, +static struct sxe_sfp_quirk sfp_quirk_info_list[] = { + { + .vendor_name = {0x46, 0x41, 0x53, 0x54, 0x50, 0x48, 0x4f, 0x54, + 0x4f, 0x4e, 0x49, 0x43, 0x53, 0x20, 0x20, 0x20}, + .vendor_pn = {0x53, 0x50, 0x4c, 0x5a, 0x2d, 0x38, 0x35, 0x53, + 0x52, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, + .filter_time = SXE_SPP_PROC_DELAY_US, + .waitloop10g_fir = SXE_10G_WAIT_4_TIME, + .waitloop10g_sec = SXE_10G_WAIT_4_TIME, + .waitloop1g = SXE_1G_WAIT_1_TIME, + .waitloop_single_spd = SXE_SINGLE_SFP_WAIT_TIME_DFLT, + .los_block_flag = true, + .disable_los_wait_timeout = false, + }, + { + .vendor_name = {0x53, 0x4f, 0x4e, 0x54, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, + .vendor_pn = {0x58, 0x50, 0x2d, 0x38, 0x47, 0x31, 0x30, 0x2d, + 0x30, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, + .filter_time = SXE_SFP_LOS_FILTER_DELAY_1_US, + .waitloop10g_fir = SXE_10G_WAIT_5_TIME, + .waitloop10g_sec = SXE_10G_WAIT_5_TIME, + .waitloop1g = SXE_1G_WAIT_1_TIME, + .waitloop_single_spd = SXE_SINGLE_SFP_WAIT_TIME_DFLT, + .los_block_flag = true, + .disable_los_wait_timeout = true, + }, + { + .vendor_name = {0x47, 0x69, 0x67, 0x61, 0x6c, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, + .vendor_pn = {0x47, 0x53, 0x53, 0x2d, 0x4d, 0x44, 0x4f, 0x31, + 0x30, 0x30, 0x2d, 0x30, 0x30, 0x37, 0x43, 0x20}, + .filter_time = SXE_SPP_PROC_DELAY_MS, + .waitloop10g_fir = SXE_10G_WAIT_5_TIME, + .waitloop10g_sec = SXE_10G_WAIT_5_TIME, + .waitloop1g = SXE_1G_WAIT_1_TIME, + .waitloop_single_spd = SXE_SINGLE_SFP_WAIT_TIME_DFLT, + .los_block_flag = false, + .disable_los_wait_timeout = false, + }, + { + .vendor_name = {0x49, 0x4e, 0x53, 0x50, 0x55, 0x52, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, + .vendor_pn = {0x49, 0x4e, 0x2d, 0x53, 0x50, 0x31, 0x30, 0x31, + 0x53, 0x52, 0x4c, 0x43, 0x20, 0x20, 0x20, 0x20}, + .filter_time = SXE_SPP_PROC_DELAY_MS, + .waitloop10g_fir = SXE_10G_WAIT_5_TIME, + .waitloop10g_sec = SXE_10G_WAIT_5_TIME, + .waitloop1g = SXE_1G_WAIT_1_TIME, + .waitloop_single_spd = SXE_SINGLE_SFP_WAIT_TIME_DFLT, + .los_block_flag = false, + .disable_los_wait_timeout = false, + }, + { + .vendor_name = {0x59, 0x69, 0x20, 0x56, 0x61, 0x6c, 0x6c, 0x65, + 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, + .vendor_pn = {0x59, 0x56, 0x30, 0x32, 0x2d, 0x43, 0x30, 0x31, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, + .filter_time = SXE_SPP_PROC_DELAY_US, + .waitloop10g_fir = SXE_10G_WAIT_5_TIME, + .waitloop10g_sec = SXE_10G_WAIT_5_TIME, + .waitloop1g = SXE_1G_WAIT_1_TIME, + .waitloop_single_spd = SXE_SINGLE_SFP_WAIT_TIME_5, + .los_block_flag = false, + .disable_los_wait_timeout = false, + }, }; #ifdef SXE_PHY_CONFIGURE @@ -730,46 +808,181 @@ s32 sxe_pcs_sds_init(struct sxe_adapter *adapter, enum sxe_pcs_mode mode, return ret; } -s32 sxe_multispeed_sfp_link_configure(struct sxe_adapter *adapter, u32 speed) +static s32 sxe_link_multispeed_to_10g(struct sxe_adapter *adapter) +{ + s32 ret; + u32 max_frame = sxe_sw_mtu_get(adapter); + + ret = sxe_sfp_rate_select(adapter, SXE_SFP_RATE_10G); + if (ret) { + LOG_ERROR_BDF("set sfp rate failed, ret=%d\n", ret); + goto l_end; + } + + msleep(SXE_RATE_SEL_WAIT); + + ret = sxe_pcs_sds_init(adapter, SXE_PCS_MODE_10GBASE_KR_WO, max_frame); + if (ret) + LOG_ERROR_BDF("set pcs sds to 10g failed, ret=%d\n", ret); + +l_end: + return ret; +} + +static s32 sxe_link_multispeed_to_1g(struct sxe_adapter *adapter) +{ + s32 ret; + u32 max_frame = sxe_sw_mtu_get(adapter); + + ret = sxe_sfp_rate_select(adapter, SXE_SFP_RATE_1G); + if (ret) { + LOG_ERROR_BDF("set sfp rate failed, ret=%d\n", ret); + goto l_end; + } + + msleep(SXE_RATE_SEL_WAIT); + + ret = sxe_pcs_sds_init(adapter, SXE_PCS_MODE_1000BASE_KX_W, + max_frame); + if (ret) + LOG_ERROR_BDF("set pcs sds to 1g failed, ret=%d\n", ret); + +l_end: + return ret; +} + +s32 sxe_link_multispeed_quirks_configure(struct sxe_adapter *adapter) +{ + s32 ret = 0; + bool link_up; + u32 link_speed, retry_cnt, i; + struct sxe_hw *hw = &adapter->hw; + struct sxe_sfp_info *sfp = &adapter->phy_ctxt.sfp_info; + + LOG_WARN_BDF("quirks 10G link check...\n"); + + sxe_link_info_get(adapter, &link_speed, &link_up); + if (link_up) { + LOG_INFO_BDF("link cfg end, link up, speed is 10G\n"); + goto l_link_up; + } + + if (time_after(jiffies, adapter->link.link_quirks_timeout)) { + LOG_WARN_BDF("quirks 10G link cfg failed, start 1g cfg\n"); + + ret = sxe_link_multispeed_to_1g(adapter); + if (ret) { + LOG_INFO_BDF("link cfg 1g failed, ret=%d\n", ret); + goto l_end; + } + + retry_cnt = sfp->sfp_link_cfg_info.waitloop1g; + for (i = 0; i < retry_cnt; i++) { + msleep(SXE_SFP_RESET_WAIT); + + link_up = hw->mac.ops->link_up_1g_check(hw); + if (link_up) { + LOG_INFO_BDF("link cfg end, link up, speed is 1G\n"); + goto l_link_up; + } + } + + LOG_WARN_BDF("quirks 1G link cfg failed, retry...\n"); + + ret = sxe_link_multispeed_to_10g(adapter); + if (ret) + LOG_INFO_BDF("link cfg 10g failed, ret=%d\n", ret); + + LOG_WARN_BDF("quirks 10G link cfg...\n"); + } else { + goto l_end; + } + +l_link_up: + clear_bit(SXE_SFP_LOS_DISABLED, &adapter->state); + clear_bit(SXE_SFP_MULTI_SPEED_QUIRKS, &adapter->state); + adapter->phy_ctxt.autoneg_advertised = 0; + adapter->phy_ctxt.autoneg_advertised |= SXE_LINK_SPEED_10GB_FULL | + SXE_LINK_SPEED_1GB_FULL; + +l_end: + return ret; +} + +static s32 sxe_link_multispeed_quirks_trigger(struct sxe_adapter *adapter) +{ + s32 ret = 0; + bool link_up; + u32 i, link_speed, retry_cnt; + struct sxe_sfp_info *sfp = &adapter->phy_ctxt.sfp_info; + + LOG_INFO_BDF("10G link cfg start\n"); + ret = sxe_link_multispeed_to_10g(adapter); + if (ret) { + LOG_ERROR_BDF("link cfg 10g failed, ret=%d\n", ret); + goto l_end; + } + + retry_cnt = sfp->sfp_link_cfg_info.waitloop10g_sec; + for (i = 0; i < retry_cnt; i++) { + msleep(SXE_LINK_UP_RETRY_ITR); + + sxe_link_info_get(adapter, &link_speed, &link_up); + if (link_up) { + LOG_INFO_BDF("link cfg end, link up, speed is 10G\n"); + goto l_end; + } + } + + LOG_WARN_BDF("10G link cfg failed, retry...\n"); + + if (!adapter->phy_ctxt.sfp_info.sfp_link_cfg_info.los_block_flag) + goto l_end; + + LOG_WARN_BDF("mutispeed quirks trigger\n"); + + adapter->link.link_quirks_timeout = jiffies + + (SXE_MUTISPEED_QUIRKS_TIMEOUT_S * HZ); + adapter->link.sfp_los_disable_timeout = jiffies + + (SXE_QUIRKS_LOS_BLOCK_TIMEOUT_S * HZ); + + set_bit(SXE_SFP_MULTI_SPEED_QUIRKS, &adapter->state); + set_bit(SXE_SFP_LOS_DISABLED, &adapter->state); + +l_end: + return ret; +} + +static s32 sxe_multispeed_sfp_link_configure(struct sxe_adapter *adapter, + u32 speed) { s32 ret = 0; bool autoneg, link_up; - u32 i, speed_cap, link_speed, speedcnt = 0; struct sxe_hw *hw = &adapter->hw; - u32 highest_link_speed = SXE_LINK_SPEED_UNKNOWN; - u32 max_frame = sxe_sw_mtu_get(adapter); + u32 i, speed_cap, link_speed, retry_cnt; + struct sxe_sfp_info *sfp = &adapter->phy_ctxt.sfp_info; sxe_sfp_link_capabilities_get(adapter, &speed_cap, &autoneg); - speed &= speed_cap; sxe_link_info_get(adapter, &link_speed, &link_up); if (link_up && (speed & link_speed)) { LOG_INFO_BDF("link cfg dont changed , dont need cfp pcs,\n" - "\tspeed=%x, mtu=%u\n", speed, max_frame); + "\tspeed=%x\n", speed); goto l_end; } if (speed & SXE_LINK_SPEED_10GB_FULL) { LOG_INFO_BDF("10G link cfg start\n"); - speedcnt++; - highest_link_speed = SXE_LINK_SPEED_10GB_FULL; - - ret = sxe_sfp_rate_select(adapter, SXE_SFP_RATE_10G); + ret = sxe_link_multispeed_to_10g(adapter); if (ret) { - LOG_ERROR_BDF("set sfp rate failed, ret=%d\n", ret); + LOG_ERROR_BDF("link cfg 10g failed, ret=%d\n", ret); goto l_end; } - msleep(SXE_RATE_SEL_WAIT); - - ret = sxe_pcs_sds_init(adapter, SXE_PCS_MODE_10GBASE_KR_WO, - max_frame); - if (ret) - goto l_end; - - for (i = 0; i < SXE_LINK_UP_RETRY_CNT; i++) { + retry_cnt = sfp->sfp_link_cfg_info.waitloop10g_fir; + for (i = 0; i < retry_cnt; i++) { msleep(SXE_LINK_UP_RETRY_ITR); sxe_link_info_get(adapter, &link_speed, &link_up); @@ -785,40 +998,31 @@ s32 sxe_multispeed_sfp_link_configure(struct sxe_adapter *adapter, u32 speed) if (speed & SXE_LINK_SPEED_1GB_FULL) { LOG_INFO_BDF("1G link cfg start\n"); - speedcnt++; - if (highest_link_speed == SXE_LINK_SPEED_UNKNOWN) - highest_link_speed = SXE_LINK_SPEED_1GB_FULL; - - ret = sxe_sfp_rate_select(adapter, SXE_SFP_RATE_1G); + ret = sxe_link_multispeed_to_1g(adapter); if (ret) { - LOG_ERROR_BDF("set sfp rate failed, ret=%d\n", ret); + LOG_ERROR_BDF("link cfg 1g failed, ret=%d\n", ret); goto l_end; } - msleep(SXE_RATE_SEL_WAIT); + retry_cnt = sfp->sfp_link_cfg_info.waitloop1g; - ret = sxe_pcs_sds_init(adapter, SXE_PCS_MODE_1000BASE_KX_W, - max_frame); - if (ret) - goto l_end; - - msleep(SXE_SFP_RESET_WAIT); + for (i = 0; i < retry_cnt; i++) { + msleep(SXE_SFP_RESET_WAIT); - link_up = hw->mac.ops->link_up_1g_check(hw); - if (link_up) { - LOG_INFO_BDF("link cfg end, link up, speed is 1G\n"); - goto l_out; + link_up = hw->mac.ops->link_up_1g_check(hw); + if (link_up) { + LOG_INFO_BDF("link cfg end, link up, speed is 1G\n"); + goto l_out; + } } LOG_WARN_BDF("1G link cfg failed, retry...\n"); } - if (speedcnt > 1) { - ret = sxe_multispeed_sfp_link_configure(adapter, - highest_link_speed); - } -l_out: + if (speed == speed_cap) + ret = sxe_link_multispeed_quirks_trigger(adapter); +l_out: adapter->phy_ctxt.autoneg_advertised = 0; if (speed & SXE_LINK_SPEED_10GB_FULL) @@ -979,6 +1183,7 @@ static s32 sxe_sfp_link_configure(struct sxe_adapter *adapter, u32 speed) u32 link_speed; u32 pcs_mode = SXE_PCS_MODE_BUTT; u32 max_frame = sxe_sw_mtu_get(adapter); + u32 i; sxe_sfp_link_capabilities_get(adapter, &speed, &an); @@ -998,13 +1203,24 @@ static s32 sxe_sfp_link_configure(struct sxe_adapter *adapter, u32 speed) } ret = sxe_pcs_sds_init(adapter, pcs_mode, max_frame); - if (ret) + if (ret) { LOG_ERROR_BDF("pcs sds init failed, ret=%d\n", ret); + goto l_end; + } - LOG_INFO_BDF("link :cfg speed=%x, pcs_mode=%x, atuoreg=%d, mtu=%u\n", - speed, pcs_mode, an, max_frame); + for (i = 0; i < adapter->phy_ctxt.sfp_info.sfp_link_cfg_info.waitloop_single_spd; i++) { + msleep(SXE_LINK_UP_RETRY_ITR); + sxe_link_info_get(adapter, &link_speed, &link_up); + if (link_up) { + LOG_INFO_BDF("link cfg end, link up, speed 0x%x\n", + link_speed); + break; + } + } l_end: + LOG_INFO_BDF("link :cfg speed=%x, pcs_mode=%x, atuoreg=%d, mtu=%u\n", + speed, pcs_mode, an, max_frame); return ret; } @@ -1036,20 +1252,108 @@ s32 sxe_sfp_vendor_pn_cmp(u8 *sfp_vendor_pn) return ret; } -s32 sxe_sfp_aoc_vendor_pn_cmp(u8 *sfp_vendor_pn) +static struct sxe_sfp_quirk *sxe_sfp_quirk_info_get(u8 *vendor_name, u8 *vendor_pn) { - s32 ret = -EINVAL; + s32 ret_name; + s32 ret_pn; u32 i; + struct sxe_sfp_quirk *sfp_quirk_info = NULL; - for (i = 0; i < SXE_COMPAT_SFP_AOC_NUM; i++) { - ret = memcmp(sfp_vendor_pn, sfp_aoc_vendor_pn_list[i], - SXE_SFP_VENDOR_PN_SIZE); - if (!ret) - goto l_end; + for (i = 0; i < SXE_COMPAT_SFP_QUIRK_LIST_NUM; i++) { + ret_name = memcmp(vendor_name, sfp_quirk_info_list[i].vendor_name, + SXE_SFP_VENDOR_NAME_SIZE); + ret_pn = memcmp(vendor_pn, sfp_quirk_info_list[i].vendor_pn, + SXE_SFP_VENDOR_PN_SIZE); + + if (!ret_name && !ret_pn) { + sfp_quirk_info = &sfp_quirk_info_list[i]; + break; + } + } + + LOG_INFO("sfp quirk info list num=%ld, i=%d quirk_info %p", + SXE_COMPAT_SFP_QUIRK_LIST_NUM, i, sfp_quirk_info); + return sfp_quirk_info; +} + +static void sxe_sfp_cfg_info_set(struct sxe_adapter *adapter) +{ + s32 ret; + u8 vendor_name[SXE_SFP_VENDOR_NAME_SIZE]; + u8 vendor_pn[SXE_SFP_VENDOR_PN_SIZE]; + struct sxe_sfp_info *sfp = &adapter->phy_ctxt.sfp_info; + struct sxe_sfp_quirk *sfp_quirk_info; + + LOG_INFO_BDF("sfp cfg set start\n"); + + ret = sxe_sfp_eeprom_read(adapter, SXE_SFF_VENDOR_NAME, + SXE_SFP_VENDOR_NAME_SIZE, vendor_name); + if (ret) { + LOG_ERROR_BDF("get sfp vendor name, ret=%d\n", ret); + goto l_default; } + LOG_INFO_BDF("sfp vendor name is:\n" + "\t0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x,\n" + "\t0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", + vendor_name[0], vendor_name[1], vendor_name[2], + vendor_name[3], vendor_name[4], vendor_name[5], + vendor_name[6], vendor_name[7], vendor_name[8], + vendor_name[9], vendor_name[10], vendor_name[11], + vendor_name[12], vendor_name[13], vendor_name[14], + vendor_name[15]); + + ret = sxe_sfp_eeprom_read(adapter, SXE_SFF_VENDOR_PN, + SXE_SFP_VENDOR_PN_SIZE, vendor_pn); + if (ret) { + LOG_ERROR_BDF("get sfp vendor pn, ret=%d\n", ret); + goto l_default; + } + LOG_INFO_BDF("sfp vendor pn is:\n" + "\t0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x,\n" + "\t0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", + vendor_pn[0], vendor_pn[1], vendor_pn[2], vendor_pn[3], + vendor_pn[4], vendor_pn[5], vendor_pn[6], vendor_pn[7], + vendor_pn[8], vendor_pn[9], vendor_pn[10], vendor_pn[11], + vendor_pn[12], vendor_pn[13], vendor_pn[14], + vendor_pn[15]); + + LOG_INFO_BDF("sfp quirk info get end\n"); + + sfp_quirk_info = sxe_sfp_quirk_info_get(vendor_name, vendor_pn); + if (sfp_quirk_info) { + sfp->sfp_link_cfg_info.filter_time = + sfp_quirk_info->filter_time; + sfp->sfp_link_cfg_info.waitloop10g_fir = + sfp_quirk_info->waitloop10g_fir; + sfp->sfp_link_cfg_info.waitloop10g_sec = + sfp_quirk_info->waitloop10g_sec; + sfp->sfp_link_cfg_info.waitloop1g = sfp_quirk_info->waitloop1g; + sfp->sfp_link_cfg_info.waitloop_single_spd = + sfp_quirk_info->waitloop_single_spd; + sfp->sfp_link_cfg_info.los_block_flag = + sfp_quirk_info->los_block_flag; + sfp->sfp_link_cfg_info.disable_los_wait_timeout = + sfp_quirk_info->disable_los_wait_timeout; + goto l_end; + } + +l_default: + memcpy(&sfp->sfp_link_cfg_info, &sfp_link_cfg_default, + sizeof(struct sxe_sfp_link_cfg)); l_end: - return ret; + LOG_INFO_BDF("sfp cfg, filter_time=%d, waitloop10g_fri=%d,\n" + "\twaitloop10g_sec=%d, waitloop1g=%d,\n" + "\twaitloop_single_spd %u, los_block_flag %s,\n" + "\tdisable_los_wait_timeout %s\n", + sfp->sfp_link_cfg_info.filter_time, + sfp->sfp_link_cfg_info.waitloop10g_fir, + sfp->sfp_link_cfg_info.waitloop10g_sec, + sfp->sfp_link_cfg_info.waitloop1g, + sfp->sfp_link_cfg_info.waitloop_single_spd, + sfp->sfp_link_cfg_info.los_block_flag ? "true" : "false", + sfp->sfp_link_cfg_info.disable_los_wait_timeout ? + "true" : "false"); } s32 sxe_sfp_identify(struct sxe_adapter *adapter) @@ -1058,7 +1362,6 @@ s32 sxe_sfp_identify(struct sxe_adapter *adapter) enum sxe_sfp_type sfp_type; u8 sfp_comp_code[SXE_SFP_COMP_CODE_SIZE]; struct sxe_sfp_info *sfp = &adapter->phy_ctxt.sfp_info; - u8 sfp_vendor_pn[SXE_SFP_VENDOR_PN_SIZE + 1] = { 0 }; unsigned long flags; LOG_INFO_BDF("sfp identify start\n"); @@ -1118,27 +1421,9 @@ s32 sxe_sfp_identify(struct sxe_adapter *adapter) LOG_INFO_BDF("identify sfp, sfp is multispeed\n"); } - ret = sxe_sfp_eeprom_read(adapter, SXE_SFF_VENDOR_PN, - SXE_SFP_VENDOR_PN_SIZE, sfp_vendor_pn); - if (ret) { - LOG_DEV_ERR("get sfp vendor pn failed, ret=%d\n", ret); - goto l_end; - } adapter->phy_ctxt.sfp_info.inserted = true; - - ret = sxe_sfp_aoc_vendor_pn_cmp(sfp_vendor_pn); - if (!ret) { - adapter->hw.irq.ops->spp_configure(&adapter->hw, - SXE_SPP_PROC_DELAY_MS); - LOG_INFO_BDF("an supported AOC SFP module type was detected,\n" - "\tspp_configure is 15ms\n"); - } else { - adapter->hw.irq.ops->spp_configure(&adapter->hw, - SXE_SPP_PROC_DELAY_US); - LOG_INFO_BDF("an unsupported AOC SFP module type was detected,\n" - "\tspp_configure is default 7us\n"); - ret = 0; - } + sxe_sfp_cfg_info_set(adapter); + adapter->hw.irq.ops->spp_configure(&adapter->hw, sfp->sfp_link_cfg_info.filter_time); spin_lock_irqsave(&adapter->irq_ctxt.event_irq_lock, flags); adapter->hw.irq.ops->rx_los_enable(&adapter->hw); diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.h b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.h index b72fc886b8c6..349ebda8861f 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.h +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.h @@ -28,6 +28,7 @@ #define SXE_SFF_10GBE_COMP_CODES 0x3 #define SXE_SFF_1GBE_COMP_CODES 0x6 #define SXE_SFF_CABLE_TECHNOLOGY 0x8 +#define SXE_SFF_VENDOR_NAME 0x14 #define SXE_SFF_VENDOR_PN 0x28 #define SXE_SFF_8472_DIAG_MONITOR_TYPE 0x5C #define SXE_SFF_8472_COMPLIANCE 0x5E @@ -46,6 +47,7 @@ #define SXE_SFF_10GBASELR_CAPABLE 0x20 #define SXE_SFP_COMP_CODE_SIZE 10 +#define SXE_SFP_VENDOR_NAME_SIZE 16 #define SXE_SFP_VENDOR_PN_SIZE 16 #define SXE_SFP_EEPROM_SIZE_MAX 512 @@ -53,6 +55,9 @@ #define SXE_SW_SFP_MULTI_GB_MS 4000 +#define SXE_MUTISPEED_QUIRKS_TIMEOUT_S 5 +#define SXE_QUIRKS_LOS_BLOCK_TIMEOUT_S (SXE_MUTISPEED_QUIRKS_TIMEOUT_S + 2) + #define SXE_PHY_ADDR_MAX 32 #define SXE_MARVELL_88X3310_PHY_ID 0x2002B @@ -119,10 +124,35 @@ struct sxe_phy_info { }; #endif +struct sxe_sfp_quirk { + u8 vendor_name[SXE_SFP_VENDOR_NAME_SIZE]; + u8 vendor_pn[SXE_SFP_VENDOR_PN_SIZE]; + u32 filter_time; + u8 waitloop10g_fir; + u8 waitloop10g_sec; + u8 waitloop1g; + u8 waitloop_single_spd; + bool los_block_flag; + bool disable_los_wait_timeout; +}; + +struct sxe_sfp_link_cfg { + u32 filter_time; + u8 waitloop10g_fir; + u8 waitloop10g_sec; + u8 waitloop1g; + u8 waitloop_single_spd; + bool los_block_flag; + bool disable_los_wait_timeout; +}; + struct sxe_sfp_info { enum sxe_sfp_type type; bool inserted; bool multispeed_fiber; + bool slow_skip; + bool slow_wait; + struct sxe_sfp_link_cfg sfp_link_cfg_info; }; struct sxe_phy_context { @@ -178,8 +208,6 @@ void sxe_sfp_tx_laser_disable(struct sxe_adapter *adapter); s32 sxe_sfp_vendor_pn_cmp(u8 *sfp_vendor_pn); -s32 sxe_sfp_aoc_vendor_pn_cmp(u8 *sfp_vendor_pn); - s32 sxe_sfp_identify(struct sxe_adapter *adapter); s32 sxe_link_configure(struct sxe_adapter *adapter, u32 speed); @@ -194,4 +222,6 @@ s32 sxe_pcs_sds_init(struct sxe_adapter *adapter, enum sxe_pcs_mode mode, void sxe_fc_enable(struct sxe_adapter *adapter); +s32 sxe_link_multispeed_quirks_configure(struct sxe_adapter *adapter); + #endif diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c index b107e03c3e8d..733f07f47fa8 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c @@ -814,6 +814,10 @@ static void sxe_rx_ring_reg_configure(struct sxe_adapter *adapter, hw->dma.ops->rx_ring_desc_configure(hw, desc_mem_len, desc_dma_addr, reg_idx); +#ifndef SXE_TPH_CONFIGURE + hw->dma.ops->rx_ro_enable(hw, reg_idx); +#endif + ring->desc.tail = adapter->hw.reg_base_addr + SXE_RDT(reg_idx); #ifdef HAVE_AF_XDP_ZERO_COPY @@ -1428,6 +1432,7 @@ static void sxe_tail_pull(struct sxe_ring *rx_ring, struct sk_buff *skb) skb->tail += pull_len; } +static bool sxe_headers_cleanup(struct sxe_ring *rx_ring, union sxe_rx_data_desc *rx_desc, struct sk_buff *skb) { @@ -1440,7 +1445,7 @@ bool sxe_headers_cleanup(struct sxe_ring *rx_ring, if (!skb_headlen(skb)) { LOG_DEBUG("ring[%u] place header in linear portion in skb\n", - rx_ring->idx); + rx_ring->idx); sxe_tail_pull(rx_ring, skb); } @@ -1566,6 +1571,7 @@ static inline u32 sxe_rx_frame_truesize(struct sxe_ring *rx_ring, u32 size) return truesize; } +static void sxe_rx_buffer_page_offset_update(struct sxe_ring *rx_ring, struct sxe_rx_buffer *rx_buffer, u32 size) { @@ -1729,8 +1735,13 @@ u32 sxe_rx_ring_irq_clean(struct sxe_irq_data *irq_data, } #ifdef HAVE_XDP_SUPPORT - if (xdp_xmit & SXE_XDP_REDIR) + if (xdp_xmit & SXE_XDP_REDIR) { +#ifdef HAVE_XDP_DO_FLUSH + xdp_do_flush(); +#else xdp_do_flush_map(); +#endif + } if (xdp_xmit & SXE_XDP_TX) { struct sxe_ring *ring = sxe_xdp_tx_ring_pick(adapter); diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c index fcd79433933e..ac017502c8f9 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c @@ -1549,6 +1549,7 @@ s32 sxe_get_vf_config(struct net_device *dev, s32 vf_idx, } #ifdef HAVE_NDO_SET_VF_LINK_STATE +static void sxe_set_vf_link_enable(struct sxe_adapter *adapter, s32 vf_idx, s32 state) { u32 msg; @@ -2384,4 +2385,3 @@ s32 sxe_sriov_configure(struct pci_dev *pdev, s32 num_vfs) return ret; } - diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c index 6b9294cc1bcb..29ac6e845c00 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c @@ -316,6 +316,10 @@ void sxe_tx_ring_reg_configure(struct sxe_adapter *adapter, reg_idx); ring->desc.tail = adapter->hw.reg_base_addr + SXE_TDT(reg_idx); +#ifndef SXE_TPH_CONFIGURE + hw->dma.ops->tx_ro_enable(hw, reg_idx); +#endif + if (!ring->irq_data || ring->irq_data->irq_interval < SXE_IRQ_ITR_100K) { if (adapter->irq_ctxt.rx_irq_interval) diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_upgrade.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_upgrade.c new file mode 100644 index 000000000000..305001a9ec9a --- /dev/null +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_upgrade.c @@ -0,0 +1,723 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * Copyright (C), 2020, Linkdata Technologies Co., Ltd. + * + * @file: sxe_upgrade.c + * @author: Linkdata + * @date: 2025.02.16 + * @brief: + * @note: + */ + +#include +#include + +#include "sxe_ethtool.h" +#include "sxe_upgrade.h" +#include "sxe_netdev.h" +#include "sxe_msg.h" +#include "sxe_host_hdc.h" + +static s32 sxe_upgd_calc_check_sum(u32 *check_sum, u8 *data, u32 data_len) +{ + s32 ret = 0; + u32 per_len = sizeof(u16); + + while (data_len >= per_len) { + *check_sum += *((u16 *)data); + data += per_len; + data_len -= per_len; + } + *check_sum = ~(*check_sum); + + return ret; +} + +static s32 sxe_upgd_do_check_sum(u32 pack_check_sum, u8 *data, u32 data_len) +{ + s32 ret = 0; + u32 check_sum = 0; + + sxe_upgd_calc_check_sum(&check_sum, data, data_len); + + if (pack_check_sum != check_sum) { + ret = -EINVAL; + LOG_ERROR("upgrade check_sum check failed: check_sum:%u,\n" + "\texpect:%u\n", + check_sum, pack_check_sum); + } + + return ret; +} + +static s32 sxe_updg_package_check(u8 *pack_data, u32 pack_len) +{ + s32 ret = 0; + struct sxe_pkg_header *pack_header = NULL; + u8 *data_pos = NULL; + u32 hdr_len = 0; + + if (pack_len <= sizeof(struct sxe_pkg_header)) { + ret = -EINVAL; + LOG_INFO("pack_len %d less than package header:%zu\n", + pack_len, sizeof(struct sxe_pkg_header)); + goto l_end; + } + + data_pos = pack_data; + pack_header = (struct sxe_pkg_header *)data_pos; + + if (pack_header->magic != SXE_PACK_DATA_BEGIN_NUM) { + LOG_INFO("magic(%d) failed\n", pack_header->magic); + ret = -EINVAL; + goto l_end; + } + + hdr_len = sizeof(struct sxe_pkg_header); + ret = sxe_upgd_do_check_sum(pack_header->pkg_check_sum, data_pos + hdr_len, + pack_len - hdr_len); + if (ret) { + LOG_INFO("sxe_upgd_do_check_sum failed\n"); + goto l_end; + } + +l_end: + return ret; +} + +static s32 sxe_region_image_check(u8 *pack_data, u32 region_len, u32 pack_len) +{ + s32 ret = 0; + struct sxe_region_header *region_hdr = NULL; + u32 hdr_len = 0; + u8 *data_pos = NULL; + u32 hdr_chk_len = 0; + u32 magic_offset = 0; + + data_pos = pack_data; + region_hdr = (struct sxe_region_header *)data_pos; + + if (region_len > pack_len || region_hdr->image_len > + (pack_len - sizeof(struct sxe_region_header))) { + ret = -EINVAL; + LOG_INFO("region_len:%u > pack_len:%u\n", + region_len, pack_len); + goto l_end; + } + + if (region_hdr->magic != SXE_DATABEGIN_NUM) { + LOG_INFO("image magic(%d) check failed\n", region_hdr->magic); + goto l_end; + } + + data_pos = pack_data; + hdr_len = sizeof(struct sxe_region_header); + magic_offset = sizeof(region_hdr->magic); + hdr_chk_len = + hdr_len - magic_offset - sizeof(region_hdr->check_sum_header); + ret = sxe_upgd_do_check_sum(region_hdr->check_sum_header, + data_pos + magic_offset, hdr_chk_len); + if (ret) { + LOG_INFO("sxe_upgd_do_check_sum header failed\n"); + goto l_end; + } + + data_pos = pack_data; + ret = sxe_upgd_do_check_sum(region_hdr->check_sum_file, + data_pos + hdr_len, region_hdr->image_len); + if (ret) { + LOG_INFO("sxe_upgd_do_check_sum file failed\n"); + goto l_end; + } + +l_end: + return ret; +} + +static s32 sxe_upgd_fw_arr_get(struct sxe_adapter *adapter, u8 *pkg_data, + u32 pkg_len, + struct sxe_upgrade_fw_array *fw_arr) +{ + s32 ret = 0; + struct sxe_pkg_header *pkg_header; + struct sxe_region_header *region_header; + u8 *data_pos = NULL; + u32 index = 0; + u32 offset = 0; + u32 fw_len = 0; + + pkg_header = (struct sxe_pkg_header *)pkg_data; + + ret = sxe_updg_package_check(pkg_data, pkg_len); + if (ret) { + LOG_INFO_BDF("sxe_updg_package_check failed\n"); + goto l_end; + } + + fw_arr->fw_cnt = pkg_header->fw_count; + offset += sizeof(struct sxe_pkg_header); + for (index = 0; index < fw_arr->fw_cnt; index++) { + if (offset >= pkg_len || + offset + sizeof(struct sxe_region_header) >= pkg_len) { + ret = -EINVAL; + LOG_INFO_BDF("offset:%d large than pkg_len:%d,\n" + "\tsum:%lu,\n" + "\tit may occur visit invalid memory\n", + offset, pkg_len, + offset + sizeof(struct sxe_region_header)); + goto l_end; + } + + data_pos = pkg_data + offset; + region_header = (struct sxe_region_header *)data_pos; + fw_len = region_header->image_len + + (u32)sizeof(struct sxe_region_header); + + if (offset + fw_len > pkg_len) { + ret = EINVAL; + LOG_INFO_BDF("(offset large than pkg_len, %s\n", + "\t it may occur visit invalid memory\n"); + goto l_end; + } + + ret = sxe_region_image_check(data_pos, fw_len, pkg_len); + if (ret) { + LOG_INFO_BDF("sxe_region_image_check failed\n"); + goto l_end; + } + + fw_arr->fw_arr[index].offset = offset; + fw_arr->fw_arr[index].image_len = fw_len; + fw_arr->fw_arr[index].fw_type = (u32)SXE_FWHEADER_IMAGETYPE(region_header); + + offset += fw_len; + } + +l_end: + return ret; +} + +static s32 sxe_upgd_64bit_set(u64 *value, u8 bit) +{ + s32 ret = 0; + + LOG_DEBUG("bit=%d\n", bit); + + if (bit >= SXE_BIT_MAP_64) { + ret = -EINVAL; + LOG_DEBUG("upgrade u64 bit set failed. bit=%d > 64\n", bit); + goto l_end; + } else { + SXE_SET_BIT64(*value, bit); + } + +l_end: + return ret; +} + +static s32 sxe_upgd_prep_info_fill(struct sxe_upgrade_prepare_cmd *prepare_info, + struct sxe_upgrade_fw_array *fw_array, u64 uuid, + bool ispack, struct sxe_pkg_header *pkg_hdr) +{ + s32 ret = 0; + u32 fw_index = 0; + + prepare_info->fw_type_cnt = fw_array->fw_cnt; + prepare_info->uuid = uuid; + prepare_info->is_pkg = ispack; + + for (fw_index = 0; fw_index < fw_array->fw_cnt; fw_index++) { + ret = sxe_upgd_64bit_set(&prepare_info->fw_type_bitmap, + fw_array->fw_arr[fw_index].fw_type); + if (ret) { + LOG_INFO("sxe_upgd_64bit_set failed, imageType=%d\n", + fw_array->fw_arr[fw_index].fw_type); + goto l_end; + } + } + + memcpy(&prepare_info->pkg_hdr_info, pkg_hdr, sizeof(*pkg_hdr)); + +l_end: + return ret; +} + +static void sxe_cmd_params_dflt_fill(struct sxe_driver_cmd *cmd, + struct sxe_mgr_msg_info *msg_info, + u32 opc, void *req_data, u32 req_len) +{ + msg_info->magic = SXE_MSG_MAGIC_CODE; + msg_info->opcode = opc; + msg_info->error = 0; + msg_info->timeout = 0; + msg_info->starttime = 0; + msg_info->runver = 0; + msg_info->uuid = 0; + msg_info->servtype = 1; + msg_info->traceid = 0; + msg_info->length = req_len + sizeof(*msg_info); + msg_info->funcid = 0; + + cmd->opcode = SXE_CMD_MAX; + cmd->req = msg_info; + cmd->req_len = msg_info->length; + cmd->resp = NULL; + cmd->resp_len = sizeof(*msg_info); + cmd->is_interruptible = false; + cmd->trace_id = 0; +} + +static s32 sxe_upgrade_prepare(struct sxe_adapter *adapter, + struct sxe_upgrade_fw_array *fw_arr, + u64 uuid, struct sxe_pkg_header *pkg_hdr) +{ + s32 ret = 0; + struct sxe_upgrade_prepare_cmd *prep_info; + struct sxe_mgr_msg_info *msg_info; + struct sxe_driver_cmd cmd = {}; + + LOG_DEBUG_BDF("fw_cnt:%d\n", fw_arr->fw_cnt); + msg_info = kzalloc(sizeof(*msg_info) + + sizeof(struct sxe_upgrade_prepare_cmd), GFP_KERNEL); + if (!msg_info) { + LOG_INFO_BDF("sxe_upgd_prep_info_fill alloc memory failed\n"); + goto l_end; + } + prep_info = (struct sxe_upgrade_prepare_cmd *)msg_info->body; + + ret = sxe_upgd_prep_info_fill(prep_info, fw_arr, uuid, true, pkg_hdr); + if (ret) { + LOG_INFO_BDF("sxe_upgd_prep_info_fill failed\n"); + goto l_end; + } + + sxe_cmd_params_dflt_fill(&cmd, msg_info, SXE_CMD_FW_DOWNLOAD_PREPARE, + &prep_info, sizeof(*prep_info)); + + ret = sxe_ethtool_fw_trans(adapter, &cmd); + if (ret) { + LOG_ERROR_BDF("upgrade pkg failed, ret=%d\n", ret); + ret = -EIO; + goto l_end; + } + +l_end: + kfree(msg_info); + return ret; +} + +static void sxe_upgd_open_info_fill(struct sxe_upgrade_open_cmd *open_info, + u32 frag_num, + u32 pack_len, u32 fw_type, u64 uuid) +{ + open_info->dev_type = SXE_ETH_UPGRADE_DEV_TYPE_CTRL; + open_info->fw_type = fw_type; + + open_info->uuid = uuid; + open_info->frag_num = frag_num; + open_info->frag_len = SXE_FRAG_LEN; + open_info->fw_len = pack_len; + open_info->force = false; + open_info->no_reset = false; + open_info->forcehcb = false; + open_info->ispacket = false; + open_info->resetnow = false; + open_info->forceclose = false; + open_info->all = false; + open_info->backup = false; + open_info->no_sign_chk = false; + open_info->no_ver_chk = true; + open_info->is_fw_head = false; +} + +static s32 sxe_upgrade_open(struct sxe_adapter *adapter, u32 frag_num, + u32 pack_len, u32 fw_type, u64 uuid) +{ + s32 ret = 0; + struct sxe_upgrade_open_cmd *open_info; + struct sxe_mgr_msg_info *msg_info; + struct sxe_driver_cmd cmd = {}; + + msg_info = kzalloc(sizeof(*msg_info) + + sizeof(struct sxe_upgrade_open_cmd), GFP_KERNEL); + if (!msg_info) { + LOG_INFO_BDF("sxe_upgd_open_info_fill alloc memory failed\n"); + goto l_end; + } + open_info = (struct sxe_upgrade_open_cmd *)msg_info->body; + + sxe_upgd_open_info_fill(open_info, frag_num, pack_len, fw_type, uuid); + + sxe_cmd_params_dflt_fill(&cmd, msg_info, SXE_CMD_FW_DOWNLOAD_OPEN, + &open_info, sizeof(*open_info)); + + ret = sxe_ethtool_fw_trans(adapter, &cmd); + if (ret) { + LOG_ERROR_BDF("upgrade pkg failed, ret=%d\n", ret); + ret = -EIO; + } + +l_end: + kfree(msg_info); + return ret; +} + +static u32 sxe_upgradefrag_num_get(u32 pack_len, u32 frag_len) +{ + u32 frag_num = 0; + + frag_num = DIV_ROUND_UP(pack_len, frag_len); + + return frag_num; +} + +static s32 sxe_upgd_pkg_div_frag(u8 *pack_data, u32 pack_len, u32 frag_id, + u8 *frag_data) +{ + s32 ret = 0; + u32 frag_num = 0; + u32 frag_len = SXE_FRAG_LEN; + u32 offset = frag_id * SXE_FRAG_LEN; + + frag_num = sxe_upgradefrag_num_get(pack_len, SXE_FRAG_LEN); + + LOG_DEBUG("frag_num = %d\n", frag_num); + + if (frag_num - 1 == frag_id) { + frag_len = pack_len - frag_id * SXE_FRAG_LEN; + LOG_DEBUG("last frag_len = %d\n", frag_len); + } + + memcpy(frag_data, &pack_data[offset], frag_len); + + return ret; +} + +static s32 sxe_upgd_frag_head_init(struct sxe_frag_head *frag_head, + u32 frag_id, u8 *frag_data, + u32 pack_len, u64 uuid) +{ + s32 ret = 0; + u32 frag_num = 0; + u32 check_sum = 0; + + frag_num = sxe_upgradefrag_num_get(pack_len, SXE_FRAG_LEN); + + frag_head->frag_sid = frag_id; + frag_head->uuid = uuid; + frag_head->frag_len = SXE_FRAG_LEN; + frag_head->version = SXE_UPGRADE_PROTOCAL_VERSION; + frag_head->symbol_enable = SXE_FRAG_ENABLE; + frag_head->symbol_more = (frag_num - 1 == frag_id) ? 0 : 1; + + if (!frag_head->symbol_more) + frag_head->frag_len = pack_len - frag_id * SXE_FRAG_LEN; + + sxe_upgd_calc_check_sum(&check_sum, frag_data, frag_head->frag_len); + + frag_head->checksum = check_sum; + + return ret; +} + +static s32 sxe_upgrade_flash(struct sxe_adapter *adapter, + struct sxe_update_flash_param *upgd_flash_obj, + struct sxe_mgr_msg_info *msg_info) +{ + s32 ret = 0; + struct sxe_upgrade_flash_cmd *download_info; + struct sxe_driver_cmd cmd = {}; + + download_info = + (struct sxe_upgrade_flash_cmd *)upgd_flash_obj->raw_data; + memset(download_info, 0, sizeof(struct sxe_upgrade_flash_cmd)); + + ret = sxe_upgd_pkg_div_frag(upgd_flash_obj->pack_data, + upgd_flash_obj->pack_len, + upgd_flash_obj->frag_index, + download_info->raw_data); + if (ret) { + LOG_INFO_BDF("sxe_upgd_pkg_div_frag failed, pack_len = %d,\n", + "\tfrag_index =%d\n", + upgd_flash_obj->pack_len, + upgd_flash_obj->frag_index); + goto l_end; + } + + ret = sxe_upgd_frag_head_init(&download_info->frag_head, + upgd_flash_obj->frag_index, + download_info->raw_data, + upgd_flash_obj->pack_len, + upgd_flash_obj->uuid); + if (ret) { + LOG_INFO_BDF("sxe_upgd_frag_head_init failed,\n", + "\t pack_len = %d, frag_index =%d\n", + upgd_flash_obj->pack_len, + upgd_flash_obj->frag_index); + goto l_end; + } + + memcpy(msg_info->body, download_info, + sizeof(struct sxe_upgrade_flash_cmd)); + + sxe_cmd_params_dflt_fill(&cmd, msg_info, SXE_CMD_FW_DOWNLOAD_FLASH, + download_info, sizeof(*download_info)); + + ret = sxe_ethtool_fw_trans(adapter, &cmd); + if (ret) { + LOG_ERROR_BDF("upgrade pkg failed, ret=%d\n", ret); + ret = -EIO; + } + +l_end: + return ret; +} + +static s32 sxe_upgrade_close(struct sxe_adapter *adapter, u64 uuid, u32 err) +{ + s32 ret = 0; + struct sxe_upgrade_close_cmd *close_info; + struct sxe_mgr_msg_info *msg_info; + struct sxe_driver_cmd cmd = {}; + + msg_info = kzalloc(sizeof(*msg_info) + + sizeof(struct sxe_upgrade_close_cmd), GFP_KERNEL); + if (!msg_info) { + LOG_INFO_BDF("sxe_upgd_close_info_fill alloc memory failed\n"); + goto l_end; + } + close_info = (struct sxe_upgrade_close_cmd *)msg_info->body; + + close_info->err_code = err; + close_info->reset_now = false; + close_info->uuid = uuid; + + sxe_cmd_params_dflt_fill(&cmd, msg_info, SXE_CMD_FW_DOWNLOAD_CLOSE, + &close_info, sizeof(*close_info)); + + ret = sxe_ethtool_fw_trans(adapter, &cmd); + if (ret) { + LOG_ERROR_BDF("upgrade pkg failed, ret=%d\n", ret); + ret = -EIO; + } + +l_end: + kfree(msg_info); + return ret; +} + +static s32 sxe_upgrade_end(struct sxe_adapter *adapter, u32 err, u64 uuid) +{ + s32 ret = 0; + struct sxe_upgrade_end_cmd *end_info; + struct sxe_mgr_msg_info *msg_info; + struct sxe_driver_cmd cmd = {}; + + msg_info = kzalloc(sizeof(*msg_info) + + sizeof(struct sxe_upgrade_end_cmd), GFP_KERNEL); + if (!msg_info) { + LOG_INFO_BDF("sxe_upgd_end_info_fill alloc memory failed\n"); + goto l_end; + } + end_info = (struct sxe_upgrade_end_cmd *)msg_info->body; + + end_info->uuid = uuid; + end_info->fw_type = SXE_UPGRADE_FW_TYPE; + end_info->err_code = err; + LOG_ERROR_BDF("upgrade pkg failed, end_info.fw_type=%d\n", + end_info->fw_type); + + sxe_cmd_params_dflt_fill(&cmd, msg_info, SXE_CMD_FW_DOWNLOAD_END, + &end_info, sizeof(*end_info)); + + ret = sxe_ethtool_fw_trans(adapter, &cmd); + if (ret) { + LOG_ERROR_BDF("upgrade pkg failed, ret=%d\n", ret); + ret = -EIO; + } + +l_end: + kfree(msg_info); + return ret; +} + +static s32 sxe_upgrade_data_trans(struct sxe_adapter *adapter, u8 *pack_data, + u32 pack_len, u32 fw_type, u64 uuid) +{ + s32 ret = 0; + u32 err = 0; + u32 frag_num = 0; + u32 frag_index = 0; + u32 flash_cmd_len = sizeof(struct sxe_upgrade_flash_cmd); + struct sxe_update_flash_param upgd_flash_obj = {}; + struct sxe_mgr_msg_info *msg_info = NULL; + + upgd_flash_obj.raw_data = kzalloc(flash_cmd_len, GFP_KERNEL); + if (!upgd_flash_obj.raw_data) { + ret = -ENOMEM; + LOG_INFO_BDF("sxe_upgrade_flash memory not enough,\n", + "\t 2k is needed."); + goto l_end; + } + + msg_info = kzalloc(sizeof(*msg_info) + flash_cmd_len, GFP_KERNEL); + if (!msg_info) { + LOG_INFO_BDF("sxe_upgrade_flash alloc memory failed\n"); + goto l_end; + } + + frag_num = sxe_upgradefrag_num_get(pack_len, SXE_FRAG_LEN); + + ret = sxe_upgrade_open(adapter, frag_num, pack_len, fw_type, uuid); + if (ret) { + LOG_INFO_BDF("sxe_upgrade_open failed,ret = [%d]\n", ret); + goto l_close; + } + + upgd_flash_obj.uuid = uuid; + upgd_flash_obj.pack_len = pack_len; + upgd_flash_obj.frag_num = frag_num; + upgd_flash_obj.fw_type = fw_type; + upgd_flash_obj.pack_data = pack_data; + + for (frag_index = 0; frag_index < frag_num; frag_index++) { + upgd_flash_obj.frag_index = frag_index; + ret = sxe_upgrade_flash(adapter, &upgd_flash_obj, msg_info); + if (ret) { + LOG_INFO_BDF("sxe_upgrade_flash frag[%d] failed\n", + frag_index); + goto l_close; + } + } + +l_close: + err = (u32)ret; + ret = sxe_upgrade_close(adapter, uuid, err); + if (ret && !err) { + LOG_INFO_BDF("sxe_upgrade_close failed, ret = [%d],err = [%d]", + ret, err); + goto l_end; + } else { + ret = (s32)err; + } + +l_end: + kfree(msg_info); + kfree(upgd_flash_obj.raw_data); + return ret; +} + +static s32 sxe_upgd_pkg_header_info_get(struct sxe_adapter *adapter, + struct sxe_pkg_header *pkg_hdr, + u8 *pack_data, u32 pack_len) +{ + s32 ret = 0; + + if (pack_len <= sizeof(struct sxe_pkg_header)) { + ret = -EINVAL; + LOG_INFO_BDF("pack_len[%d] <= pack_header[%zd]\n", + pack_len, sizeof(struct sxe_pkg_header)); + goto l_end; + } + memcpy(pkg_hdr, pack_data, sizeof(*pkg_hdr)); + +l_end: + return ret; +} + +static s32 sxe_upgrade_image(struct sxe_adapter *adapter, u8 *pkg_data, + u32 pkg_len, u64 uuid) +{ + s32 ret = 0; + u32 err = 0; + u8 *data_pos = NULL; + u8 *pfwdata = NULL; + u32 index = 0; + u32 fw_len = 0; + u32 region_type = 0; + struct sxe_upgrade_fw_array fw_arr = {}; + struct sxe_pkg_header pkg_hdr = {}; + + data_pos = pkg_data; + ret = sxe_upgd_fw_arr_get(adapter, data_pos, pkg_len, &fw_arr); + if (ret) { + LOG_INFO_BDF("sxe_upgd_fw_arr_get failed\n"); + goto final; + } + + data_pos = pkg_data; + ret = sxe_upgd_pkg_header_info_get(adapter, &pkg_hdr, data_pos, + pkg_len); + if (ret) { + LOG_INFO_BDF("sxe_upgd_pkg_header_info_get failed(%d)\n", ret); + goto final; + } + + ret = sxe_upgrade_prepare(adapter, &fw_arr, uuid, &pkg_hdr); + if (ret) { + LOG_INFO_BDF("sxe_upgrade_prepare failed(%d)\n", ret); + goto l_end; + } + + data_pos = pkg_data; + for (index = 0; index < fw_arr.fw_cnt; index++) { + pfwdata = data_pos + fw_arr.fw_arr[index].offset; + fw_len = fw_arr.fw_arr[index].image_len; + region_type = fw_arr.fw_arr[index].fw_type; + + ret = sxe_upgrade_data_trans(adapter, pfwdata, fw_len, + region_type, uuid); + if (ret) { + LOG_INFO_BDF("sxe_upgrade_data_trans failed(%d)\n", + ret); + goto l_end; + } + } + +l_end: + err = (u32)ret; + ret = sxe_upgrade_end(adapter, err, uuid); + + if (ret && !err) { + LOG_INFO_BDF("sxe_upgrade_end failed"); + goto final; + } else { + ret = (s32)err; + } + +final: + return ret; +} + +s32 sxe_flash_package_from_file(struct net_device *dev, const char *file_name) +{ + s32 ret; + struct sxe_adapter *adapter = netdev_priv(dev); + const struct firmware *fw; + u64 uuid; + + get_random_bytes(&uuid, sizeof(uuid)); + + ret = request_firmware_direct(&fw, file_name, &adapter->pdev->dev); + if (ret) { + LOG_INFO_BDF("pkg error %d requesting file: %s\n", ret, file_name); + goto l_end; + } + + dev_hold(dev); + rtnl_unlock(); + + ret = sxe_upgrade_image(adapter, (u8 *)fw->data, fw->size, uuid); + if (ret) + LOG_ERROR_BDF("sxe update image failed, ret = %d\n", ret); + else + LOG_DEV_INFO("sxe update image done!\n"); + + release_firmware(fw); + + rtnl_lock(); + dev_put(dev); + +l_end: + return ret; +} diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_upgrade.h b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_upgrade.h new file mode 100644 index 000000000000..7c44f1de3d3c --- /dev/null +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_upgrade.h @@ -0,0 +1,256 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/** + * Copyright (C), 2020, Linkdata Technologies Co., Ltd. + * + * @file: sxe_upgrade.h + * @author: Linkdata + * @date: 2025.02.16 + * @brief: + * @note: + */ + +#ifndef __SXE_UPGRADE_H__ +#define __SXE_UPGRADE_H__ + +#include "sxe.h" +#include "sxe_netdev.h" +#include "sxe_log.h" + +#define SXE_INVAL_U16 (0xFFFF) +#define SXE_MAX_UPDATE_FWTYPE (8) +#define SXE_UPGRADE_PKGS_NAME_LEN (256) +#define SXE_FRAG_LEN (2048) +#define SXE_FW_VENDOR_LEN (8U) +#define SXE_FW_SIGN_LEN (64U) +#define SXE_FW_PKEY_LEN (68U) +#define SXE_BIT_MAP_64 (64) + +#define SXE_PAD_1_K (1024U) +#define SXE_PACK_DATA_BEGIN_NUM (0x327f68cd) +#define SXE_DATABEGIN_NUM (0x327f68ab) + +#define SXE_UPGRADE_PROTOCAL_VERSION (0x00000001) +#define SXE_FRAG_ENABLE (1) +#define SXE_ETH_UPGRADE_DEV_TYPE_CTRL (1) +#define SXE_UPGRADE_FW_TYPE (36) +#define SXE_MSG_MAGIC_CODE (0x12345678) + +#define SXE_FWHEADER_IMAGETYPE(fw_header) ((fw_header)->image_type_append) +#define SXE_SET_BIT64(x, y) ((x) |= ((u64)1 << (y))) + +#define SXE_CMD_LIMIT_OFFSET (24) +#define SXE_CMD_OBJECT_OFFSET (16) +#define SXE_CMD_TYPE_OFFSET (8) +#define SXE_CMD_CODE_OFFSET (0) + +#define SXE_MK_LIMIT(limit, object, type, code) \ + ({ \ + (((limit) & 0xff) << SXE_CMD_LIMIT_OFFSET) | \ + (((object) & 0xff) << SXE_CMD_OBJECT_OFFSET) | \ + (((type) & 0xff) << SXE_CMD_TYPE_OFFSET) | \ + (((code) & 0xff) << SXE_CMD_CODE_OFFSET); \ + }) + +#define SXE_CMD_LIMIT_RAID (0b0001) +#define SXE_CMD_LIMIT_HBA (0b0010) +#define SXE_CMD_LIMIT_SWITCH (0b0100) +#define SXE_CMD_NO_LIMIT \ + ((s32)SXE_CMD_LIMIT_RAID | SXE_CMD_LIMIT_HBA | SXE_CMD_LIMIT_SWITCH) + +#define SXE_CMD_CHANNEL_IOCTL (0b00100000) +#define SXE_CMD_UPDATE (0xb) +#define SXE_CMD_DOWNLOAD (0xa) + +#define SXE_CMD_FW_DOWNLOAD_PREPARE \ + SXE_MK_LIMIT(SXE_CMD_NO_LIMIT | SXE_CMD_CHANNEL_IOCTL, \ + SXE_CMD_UPDATE, SXE_CMD_DOWNLOAD, 2) +#define SXE_CMD_FW_DOWNLOAD_OPEN \ + SXE_MK_LIMIT(SXE_CMD_NO_LIMIT | SXE_CMD_CHANNEL_IOCTL, \ + SXE_CMD_UPDATE, SXE_CMD_DOWNLOAD, 3) +#define SXE_CMD_FW_DOWNLOAD_FLASH \ + SXE_MK_LIMIT(SXE_CMD_NO_LIMIT | SXE_CMD_CHANNEL_IOCTL, \ + SXE_CMD_UPDATE, SXE_CMD_DOWNLOAD, 4) +#define SXE_CMD_FW_DOWNLOAD_CLOSE \ + SXE_MK_LIMIT(SXE_CMD_NO_LIMIT | SXE_CMD_CHANNEL_IOCTL, \ + SXE_CMD_UPDATE, SXE_CMD_DOWNLOAD, 5) +#define SXE_CMD_FW_DOWNLOAD_END \ + SXE_MK_LIMIT(SXE_CMD_NO_LIMIT | SXE_CMD_CHANNEL_IOCTL, \ + SXE_CMD_UPDATE, SXE_CMD_DOWNLOAD, 6) + +struct sxe_pd_position { + u8 enclid; + u8 pad; + u16 slotid; +}; + +struct sxe_phy_position { + u64 enclsasaddr; + u64 physasaddr; + u8 enclid; + u8 phyid; + u8 pad[6]; +}; + +struct sxe_mgl_id_group { + u8 type; + u8 pad[7]; + union { + u16 deviceid; + struct sxe_pd_position pdposition; + u16 vdid; + u16 dgid; + struct sxe_phy_position phyposition; + u16 laneid; + }; +}; + +struct sxe_mgr_msg_info { + u32 magic; + u32 opcode; + u32 error; + u32 timeout; + u32 starttime; + u32 runver; + u32 length; + u32 ackoffset; + u32 acklength; + u32 leftmsgcount; + u32 msgindex; + u8 reserved[4]; + u64 uuid; + u8 servtype; + struct { + u8 ack : 4; + u8 tlv : 4; + } index; + u8 funcid : 1; + u8 pad : 7; + u8 reserved2[5]; + struct sxe_mgl_id_group id; + u64 traceid; +#ifdef HAVE_REPLACE_ZERO_ARRAY_WITH_FLEXIBLE + u8 body[]; +#else + u8 body[0]; +#endif +}; + +struct sxe_update_flash_param { + u64 uuid; + u32 frag_index; + u32 pack_len; + u32 frag_num; + u32 fw_type; + u8 *pack_data; + u8 *raw_data; +}; + +struct sxe_upgd_image_info { + __le32 offset; + __le32 image_len; + __le32 fw_type; +}; + +struct sxe_upgrade_fw_array { + __le32 fw_cnt; + struct sxe_upgd_image_info fw_arr[SXE_MAX_UPDATE_FWTYPE]; +}; + +struct sxe_pkg_header { + __le32 magic; + __le32 fw_count; + __le32 pack_time; + __le32 pack_len; + __le32 pkg_check_sum; + __le32 pkg_version; + s8 pkg_name[SXE_UPGRADE_PKGS_NAME_LEN]; + u8 reserved[4]; +}; + +struct sxe_region_header { + __le32 magic; + u8 vendor[SXE_FW_VENDOR_LEN]; + __le32 timestamp; + __le32 image_len; + __le32 image_type_append; + u8 signature[SXE_FW_SIGN_LEN]; + u8 publickey[SXE_FW_PKEY_LEN]; + __le32 check_sum_file; + __le32 image_type; + __le32 image_format; + __le32 entry_point; + __le32 load_addr; + __le32 reserved2; + __le32 image_version; + u8 reserved[68]; + __le32 check_sum_header; +}; + +struct sxe_upgrade_prepare_cmd { + __le64 uuid; + __le32 fw_type_cnt; + u8 pad[4]; + __le64 fw_type_bitmap; + bool is_pkg; + u8 pad2[4]; + struct sxe_pkg_header pkg_hdr_info; + u8 pad3[4]; +}; + +struct sxe_upgrade_open_cmd { + __le32 dev_type; + __le32 fw_type; + u8 pad1[SXE_PAD_1_K]; + __le32 pad2[2]; + u64 uuid; + __le32 frag_num; + __le32 frag_len; + __le32 fw_len; + __le32 no_sign_chk : 1; + __le32 no_ver_chk : 1; + __le32 force : 1; + __le32 all : 1; + __le32 backup : 1; + __le32 is_fw_head : 1; + __le32 no_reset : 1; + __le32 forcehcb : 1; + __le32 resetnow : 1; + __le32 forceclose: 1; + __le32 ispacket : 1; + __le32 reserved : 21; +}; + +struct sxe_frag_head { + __le64 uuid; + __le32 version; + __le32 frag_sid; + __le32 frag_len; + __le32 checksum; + __le32 symbol_enable : 1; + __le32 symbol_more : 1; + __le32 symbol_reserve : 6; + __le32 reserved : 24; + u8 pad[4]; +}; + +struct sxe_upgrade_flash_cmd { + struct sxe_frag_head frag_head; + u8 raw_data[SXE_FRAG_LEN]; +}; + +struct sxe_upgrade_close_cmd { + __le64 uuid; + __le32 err_code; + __le32 reset_now : 1; + __le32 reserved : 31; +}; + +struct sxe_upgrade_end_cmd { + __le64 uuid; + __le32 err_code; + __le32 fw_type; +}; + +s32 sxe_flash_package_from_file(struct net_device *dev, const char *filename); + +#endif diff --git a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c index 99350b946bd5..edcc60eed1b9 100644 --- a/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c +++ b/drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c @@ -84,6 +84,10 @@ static s32 sxe_xdp_setup(struct net_device *dev, struct bpf_prog *prog) ret = -EINVAL; goto l_ret; } +#ifdef HAVE_NETDEV_XDP_FEATURES + if (!prog) + xdp_features_clear_redirect_target(dev); +#endif } else { for (i = 0; i < adapter->rx_ring_ctxt.num; i++) { (void)xchg(&adapter->rx_ring_ctxt.ring[i]->xdp_prog, @@ -106,6 +110,9 @@ static s32 sxe_xdp_setup(struct net_device *dev, struct bpf_prog *prog) #endif } } +#ifdef HAVE_NETDEV_XDP_FEATURES + xdp_features_set_redirect_target(dev, true); +#endif } #endif l_ret: @@ -400,7 +407,7 @@ static void sxe_txrx_ring_disable(struct sxe_adapter *adapter, u32 ring_idx) sxe_rx_ring_stats_reset(rx_ring); } -void sxe_txrx_ring_enable(struct sxe_adapter *adapter, u32 ring_idx) +static void sxe_txrx_ring_enable(struct sxe_adapter *adapter, u32 ring_idx) { struct sxe_ring *rx_ring, *tx_ring, *xdp_ring; @@ -862,9 +869,14 @@ static struct sk_buff *sxe_zc_skb_construct(struct sxe_ring *rx_ring, u32 datasize = xdp->data_end - xdp->data; struct sk_buff *skb; +#ifdef NEED_NAPI_SKB_ALLOC + skb = napi_alloc_skb(&rx_ring->irq_data->napi, + xdp->data_end - xdp->data_hard_start); +#else skb = __napi_alloc_skb(&rx_ring->irq_data->napi, xdp->data_end - xdp->data_hard_start, GFP_ATOMIC | __GFP_NOWARN); +#endif if (unlikely(!skb)) { LOG_ERROR("[xdp] zc skb alloc failed\n"); goto l_ret; @@ -1051,7 +1063,11 @@ int sxe_zc_rx_ring_irq_clean(struct sxe_irq_data *irq_data, if (xdp_xmit & SXE_XDP_REDIR) { LOG_DEBUG_BDF("ring[%u] do xdp redir\n", rx_ring->idx); +#ifdef HAVE_XDP_DO_FLUSH + xdp_do_flush(); +#else xdp_do_flush_map(); +#endif } if (xdp_xmit & SXE_XDP_TX) { @@ -1424,12 +1440,12 @@ int sxe_xdp(struct net_device *dev, struct netdev_bpf *xdp) #ifdef HAVE_AF_XDP_ZERO_COPY case XDP_SETUP_XSK_POOL: #ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL - LOG_DEBUG_BDF("xdp setup xsk pool pool=%p, queue_id=%u\n", + LOG_DEBUG_BDF("xdp setup xsk pool=%p, queue_id=%u\n", xdp->xsk.pool, xdp->xsk.queue_id); ret = sxe_xsk_pool_setup(adapter, xdp->xsk.pool, xdp->xsk.queue_id); #else - LOG_DEBUG_BDF("xdp setup xsk umem umem=%p, queue_id=%u\n", + LOG_DEBUG_BDF("xdp setup xsk umem=%p, queue_id=%u\n", xdp->xsk.umem, xdp->xsk.queue_id); ret = sxe_xsk_pool_setup(adapter, xdp->xsk.umem, xdp->xsk.queue_id); diff --git a/drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c b/drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c index 496b483c0cbf..476a37ae2b6e 100644 --- a/drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c +++ b/drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c @@ -30,7 +30,7 @@ do { \ struct sxe_trace_tx_ring g_sxe_trace_tx[SXE_TXRX_RING_NUM_MAX] = { { 0 } }; struct sxe_trace_rx_ring g_sxe_trace_rx[SXE_TXRX_RING_NUM_MAX] = { { 0 } }; -void sxe_file_close(struct file **file) +static void sxe_file_close(struct file **file) { filp_close(*file, NULL); *file = NULL; diff --git a/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_cli.h b/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_cli.h index 562cf42120e3..4fca000a69c3 100644 --- a/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_cli.h +++ b/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_cli.h @@ -27,6 +27,8 @@ #define MGC_TERMLOG_INFO_MAX_LEN (12 * 1024) #define SXE_REGS_DUMP_MAX_LEN (12 * 1024) #define SXE_PRODUCT_NAME_LEN (32) +#define SXE_USER_SET_QUIRK_COUNT (4) +#define SXE_DEFAULT_QUIRK_COUNT (12) enum sxe_led_mode { SXE_IDENTIFY_LED_BLINK_ON = 0, @@ -221,4 +223,26 @@ struct sxe_an_cap { struct sxe_phy_an_cap local; struct sxe_phy_an_cap peer; }; + +struct sxecfgquirkinfo { + union { + u32 index; + u32 isvalid; + } type; + u8 vendor[SXE_MFG_SERIAL_NUMBER_LEN]; + u8 vendorpn[SXE_MFG_SERIAL_NUMBER_LEN]; + u8 wait10gfri; + u8 wait10gsec; + u8 wait1g; + u8 losblockflag; +}; + +struct sxecfguserquirklist { + struct sxecfgquirkinfo list[SXE_USER_SET_QUIRK_COUNT]; +}; + +struct sxecfgdefquirklist { + struct sxecfgquirkinfo list[SXE_DEFAULT_QUIRK_COUNT]; +}; + #endif diff --git a/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_hdc.h b/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_hdc.h index 1c48b903dc3f..d8715fc2851e 100644 --- a/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_hdc.h +++ b/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_hdc.h @@ -44,6 +44,4 @@ union hdcheader { } head; u32 dw0; }; - #endif - diff --git a/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_regs.h b/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_regs.h index ec81d6a8a5aa..a90eafaaa581 100644 --- a/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_regs.h +++ b/drivers/net/ethernet/linkdata/sxevf/include/sxe/sxe_regs.h @@ -191,7 +191,7 @@ #define SXE_SPP_PROC_DELAY_US 0x00000007 #define SXE_SPP_PROC_DELAY_MS 0x00003A98 -#define SXE_SPP2_STATE 0x00000004 +#define SXE_SFP_STATE_PRESENT 0x00000004 #define SXE_IRQ_CLEAR_MASK 0xFFFFFFFF diff --git a/drivers/net/ethernet/linkdata/sxevf/include/sxe_version.h b/drivers/net/ethernet/linkdata/sxevf/include/sxe_version.h index ab1fce0ead18..acc15c60a07b 100644 --- a/drivers/net/ethernet/linkdata/sxevf/include/sxe_version.h +++ b/drivers/net/ethernet/linkdata/sxevf/include/sxe_version.h @@ -11,10 +11,10 @@ #ifndef __SXE_VER_H__ #define __SXE_VER_H__ -#define SXE_VERSION "1.5.0.27" -#define SXE_COMMIT_ID "e7a9699" -#define SXE_BRANCH "develop/rc/sagitta-1.5.0_B027-openEuler" -#define SXE_BUILD_TIME "2025-04-01 10:54:47" +#define SXE_VERSION "0.0.0.0" +#define SXE_COMMIT_ID "369cabe" +#define SXE_BRANCH "feature/sagitta-trunk-P8-open-linux" +#define SXE_BUILD_TIME "2025-10-22 22:25:33" #define SXE_DRV_NAME "sxe" #define SXEVF_DRV_NAME "sxevf" diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h index 0a513360da14..f27e41bfd09b 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h @@ -34,6 +34,12 @@ #define SXEVF_HZ_TRANSTO_MS 1000 +#ifdef HAVE_STRSCPY +#define SXE_STRCPY strscpy +#else +#define SXE_STRCPY strlcpy +#endif + #define SXEVF_KFREE(addr) \ do { \ void *_addr = (addr); \ @@ -72,6 +78,7 @@ enum sxevf_nic_state { SXEVF_DOWN, SXEVF_DISABLED, SXEVF_REMOVING, + SXEVF_IRQ_REQUESTED, }; struct sxevf_mac_filter_context { diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.h b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.h index f06a117c4482..d1a7295159aa 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.h +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.h @@ -24,4 +24,3 @@ void sxevf_dump_skb(struct sk_buff *skb); #endif #endif - diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c index 4f767e5645b2..35a4eddf7f9e 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c @@ -99,11 +99,11 @@ static void sxevf_get_drvinfo(struct net_device *netdev, { struct sxevf_adapter *adapter = netdev_priv(netdev); - strlcpy(drvinfo->driver, SXEVF_DRV_NAME, sizeof(drvinfo->driver)); - strlcpy(drvinfo->version, SXE_VERSION, sizeof(drvinfo->version)); + SXE_STRCPY(drvinfo->driver, SXEVF_DRV_NAME, sizeof(drvinfo->driver)); + SXE_STRCPY(drvinfo->version, SXE_VERSION, sizeof(drvinfo->version)); - strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), - sizeof(drvinfo->bus_info)); + SXE_STRCPY(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); drvinfo->n_priv_flags = SXEVF_PRIV_FLAGS_STR_LEN; } @@ -503,6 +503,35 @@ static u32 sxevf_get_rss_hash_key_size(struct net_device *netdev) return SXEVF_RSS_HASH_KEY_SIZE; } +#ifdef HAVE_ETHTOOL_RXFH_PARAM +static int sxevf_get_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh) +{ + int err = 0; + struct sxevf_adapter *adapter = netdev_priv(netdev); + + rxfh->hfunc = ETH_RSS_HASH_TOP; + + if (!rxfh->indir && !rxfh->key) { + LOG_DEBUG_BDF("param err, indir=%p, key=%p\n", + rxfh->indir, rxfh->key); + return 0; + } + + spin_lock_bh(&adapter->mbx_lock); + if (rxfh->indir) + err = sxevf_redir_tbl_get(&adapter->hw, + adapter->rx_ring_ctxt.num, + rxfh->indir); + + if (!err && rxfh->key) + err = sxevf_rss_hash_key_get(&adapter->hw, rxfh->key); + + spin_unlock_bh(&adapter->mbx_lock); + + return err; +} +#else static int sxevf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc) { @@ -528,6 +557,7 @@ static int sxevf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, return err; } +#endif static int sxevf_get_regs_len(struct net_device *netdev) { diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c index ee12aa5340b9..86232112c50c 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c @@ -25,8 +25,8 @@ #include "sxe_dpdk_version.h" #include "sxe_compat_version.h" #include "sxevf.h" -#include "sxevf_hw.h" #endif +#include "sxevf_hw.h" #if defined SXE_DPDK_L4_FEATURES && defined SXE_DPDK_SRIOV struct sxevf_adapter; @@ -69,6 +69,9 @@ static void sxevf_hw_fault_check(struct sxevf_hw *hw, u32 reg) struct sxevf_adapter *adapter = hw->adapter; u8 i; + if (pci_channel_offline(adapter->pdev)) + return; + if (reg == SXE_VFSTATUS) { sxevf_hw_fault_handle(hw); return; @@ -85,7 +88,7 @@ static void sxevf_hw_fault_check(struct sxevf_hw *hw, u32 reg) LOG_INFO_BDF("retry done i:%d value:0x%x\n", i, value); - if (value == SXEVF_REG_READ_FAIL) + if (value == SXEVF_REG_READ_FAIL && !pci_channel_offline(adapter->pdev)) sxevf_hw_fault_handle(hw); } @@ -674,8 +677,8 @@ static const struct sxevf_dma_operations sxevf_dma_ops = { }; #ifdef SXE_DPDK -void sxevf_32bit_counter_update(struct sxevf_hw *hw, - u32 reg, u64 *last, u64 *cur) +static void sxevf_32bit_counter_update(struct sxevf_hw *hw, + u32 reg, u64 *last, u64 *cur) { u32 latest = SXEVF_REG_READ(hw, reg); @@ -683,8 +686,8 @@ void sxevf_32bit_counter_update(struct sxevf_hw *hw, *last = latest; } -void sxevf_36bit_counter_update(struct sxevf_hw *hw, - u32 lsb, u32 msb, u64 *last, u64 *cur) +static void sxevf_36bit_counter_update(struct sxevf_hw *hw, u32 lsb, + u32 msb, u64 *last, u64 *cur) { u64 new_lsb = SXEVF_REG_READ(hw, lsb); u64 new_msb = SXEVF_REG_READ(hw, msb); @@ -694,8 +697,8 @@ void sxevf_36bit_counter_update(struct sxevf_hw *hw, *last = latest; } #else -void sxevf_32bit_counter_update(struct sxevf_hw *hw, - u32 reg, u64 *last, u64 *cur) +static void sxevf_32bit_counter_update(struct sxevf_hw *hw, + u32 reg, u64 *last, u64 *cur) { u32 current_counter = SXEVF_REG_READ(hw, reg); @@ -707,8 +710,8 @@ void sxevf_32bit_counter_update(struct sxevf_hw *hw, *cur |= current_counter; } -void sxevf_36bit_counter_update(struct sxevf_hw *hw, - u32 lsb, u32 msb, u64 *last, u64 *cur) +static void sxevf_36bit_counter_update(struct sxevf_hw *hw, u32 lsb, + u32 msb, u64 *last, u64 *cur) { u64 current_counter_lsb = SXEVF_REG_READ(hw, lsb); u64 current_counter_msb = SXEVF_REG_READ(hw, msb); diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.h b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.h index 5b7b77f644a5..16a681fc4f90 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.h +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.h @@ -269,14 +269,8 @@ static inline void sxevf_hw_reg_handle_init(struct sxevf_hw *hw, hw->reg_write = write; } -#ifdef SXE_DPDK - -void sxevf_irq_disable(struct sxevf_hw *hw); - void sxevf_hw_stop(struct sxevf_hw *hw); -void sxevf_hw_reset(struct sxevf_hw *hw); - void sxevf_msg_write(struct sxevf_hw *hw, u8 index, u32 msg); u32 sxevf_msg_read(struct sxevf_hw *hw, u8 index); @@ -289,22 +283,26 @@ void sxevf_pf_req_irq_trigger(struct sxevf_hw *hw); void sxevf_pf_ack_irq_trigger(struct sxevf_hw *hw); -void sxevf_rxtx_reg_init(struct sxevf_hw *hw); +void sxevf_event_irq_map(struct sxevf_hw *hw, u16 vector); -void sxevf_irq_enable(struct sxevf_hw *hw, u32 mask); +void sxevf_specific_irq_enable(struct sxevf_hw *hw, u32 value); -u32 sxevf_irq_cause_get(struct sxevf_hw *hw); +void sxevf_irq_enable(struct sxevf_hw *hw, u32 mask); -void sxevf_event_irq_map(struct sxevf_hw *hw, u16 vector); +void sxevf_irq_disable(struct sxevf_hw *hw); void sxevf_hw_ring_irq_map(struct sxevf_hw *hw, bool is_tx, u16 hw_ring_idx, u16 vector); void sxevf_ring_irq_interval_set(struct sxevf_hw *hw, u16 irq_idx, u32 interval); +void sxevf_hw_reset(struct sxevf_hw *hw); -void sxevf_tx_desc_configure(struct sxevf_hw *hw, u32 desc_mem_len, - u64 desc_dma_addr, u8 reg_idx); +u32 sxevf_link_state_get(struct sxevf_hw *hw); + +void sxevf_tx_ring_switch(struct sxevf_hw *hw, u8 reg_idx, bool is_on); + +void sxevf_rx_ring_switch(struct sxevf_hw *hw, u8 reg_idx, bool is_on); void sxevf_rx_ring_desc_configure(struct sxevf_hw *hw, u32 desc_mem_len, u64 desc_dma_addr, u8 reg_idx); @@ -313,6 +311,19 @@ void sxevf_rx_rcv_ctl_configure(struct sxevf_hw *hw, u8 reg_idx, u32 header_buf_len, u32 pkg_buf_len, bool drop_en); +void sxevf_packet_stats_get(struct sxevf_hw *hw, struct sxevf_hw_stats *stats); + +void sxevf_stats_init_value_get(struct sxevf_hw *hw, + struct sxevf_hw_stats *stats); + +#ifdef SXE_DPDK +void sxevf_rxtx_reg_init(struct sxevf_hw *hw); + +u32 sxevf_irq_cause_get(struct sxevf_hw *hw); + +void sxevf_tx_desc_configure(struct sxevf_hw *hw, u32 desc_mem_len, + u64 desc_dma_addr, u8 reg_idx); + void sxevf_rss_bit_num_set(struct sxevf_hw *hw, u32 value); void sxevf_hw_vlan_tag_strip_switch(struct sxevf_hw *hw, u16 reg_index, @@ -322,19 +333,8 @@ void sxevf_tx_queue_thresh_set(struct sxevf_hw *hw, u8 reg_idx, u32 prefech_thresh, u32 host_thresh, u32 wb_thresh); -void sxevf_tx_ring_switch(struct sxevf_hw *hw, u8 reg_idx, bool is_on); - -void sxevf_rx_ring_switch(struct sxevf_hw *hw, u8 reg_idx, bool is_on); - void sxevf_rx_desc_tail_set(struct sxevf_hw *hw, u8 reg_idx, u32 value); -void sxevf_specific_irq_enable(struct sxevf_hw *hw, u32 value); - -void sxevf_packet_stats_get(struct sxevf_hw *hw, struct sxevf_hw_stats *stats); - -void sxevf_stats_init_value_get(struct sxevf_hw *hw, - struct sxevf_hw_stats *stats); - u32 sxevf_hw_rss_redir_tbl_get(struct sxevf_hw *hw, u16 reg_idx); void sxevf_hw_rss_redir_tbl_set(struct sxevf_hw *hw, u16 reg_idx, u32 value); @@ -351,8 +351,6 @@ void sxevf_hw_rss_key_set_all(struct sxevf_hw *hw, u32 *rss_key); bool sxevf_hw_is_rss_enabled(struct sxevf_hw *hw); -u32 sxevf_link_state_get(struct sxevf_hw *hw); - u32 sxevf_hw_regs_group_read(struct sxevf_hw *hw, const struct sxevf_reg_info *regs, u32 *reg_buf); diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c index 4b1bc788688c..244273a29d9a 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c @@ -36,6 +36,9 @@ static inline void netif_napi_add_compat(struct net_device *dev, netif_napi_add(dev, napi, poll); } +#ifdef netif_napi_add +#undef netif_napi_add +#endif #define netif_napi_add(dev, napi, poll, weight) \ netif_napi_add_compat(dev, napi, poll, weight) #endif @@ -480,6 +483,9 @@ void sxevf_irq_release(struct sxevf_adapter *adapter) u16 irq_idx; struct sxevf_irq_context *irq_ctxt = &adapter->irq_ctxt; + if (!test_bit(SXEVF_IRQ_REQUESTED, &adapter->state)) + return; + if (!irq_ctxt->msix_entries) goto l_out; @@ -497,7 +503,7 @@ void sxevf_irq_release(struct sxevf_adapter *adapter) free_irq(irq_ctxt->msix_entries[irq_idx].vector, adapter); l_out: - ; + clear_bit(SXEVF_IRQ_REQUESTED, &adapter->state); } s32 sxevf_irq_ctxt_init(struct sxevf_adapter *adapter) @@ -741,6 +747,8 @@ s32 sxevf_irq_configure(struct sxevf_adapter *adapter) sxevf_hw_irq_configure(adapter); + set_bit(SXEVF_IRQ_REQUESTED, &adapter->state); + l_out: return ret; } diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.h b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.h index ebc842c72428..3bd11549ce52 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.h +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.h @@ -77,7 +77,11 @@ struct sxevf_irq_data { struct napi_struct napi; struct rcu_head rcu; s8 name[IFNAMSIZ + SXEVF_IRQ_NAME_EXT_LEN]; +#ifdef HAVE_REPLACE_ZERO_ARRAY_WITH_FLEXIBLE + struct sxevf_ring ring[] ____cacheline_internodealigned_in_smp; +#else struct sxevf_ring ring[0] ____cacheline_internodealigned_in_smp; +#endif }; struct sxevf_irq_context { diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c index 137832a60d42..4b4f6fb53186 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c @@ -83,8 +83,10 @@ s32 sxevf_dev_reset(struct sxevf_hw *hw) msg.msg_type = SXEVF_RESET; + spin_lock_bh(&adapter->mbx_lock); ret = sxevf_send_and_rcv_msg(hw, (u32 *)&msg, SXEVF_MSG_NUM(sizeof(msg))); + spin_unlock_bh(&adapter->mbx_lock); if (ret) { LOG_ERROR_BDF("vf reset msg:%d len:%zu mailbox fail.(err:%d)\n", @@ -401,8 +403,8 @@ static int sxevf_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto l_adapter_create_failed; } - strlcpy(adapter->dev_name, device_name, - min_t(u32, strlen(device_name) + 1, DEV_NAME_LEN)); + SXE_STRCPY(adapter->dev_name, device_name, + min_t(u32, strlen(device_name) + 1, DEV_NAME_LEN)); adapter->hw.board_type = id ? id->driver_data : SXE_BOARD_VF; ret = sxevf_pci_init(adapter); @@ -470,6 +472,7 @@ static int sxevf_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void sxevf_fuc_exit(struct sxevf_adapter *adapter) { cancel_work_sync(&adapter->monitor_ctxt.work); + clear_bit(SXEVF_MONITOR_WORK_SCHED, &adapter->monitor_ctxt.state); } static void sxevf_remove(struct pci_dev *pdev) @@ -607,8 +610,7 @@ static void sxevf_io_resume(struct pci_dev *pdev) static pci_ers_result_t sxevf_io_slot_reset(struct pci_dev *pdev) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct sxevf_adapter *adapter = netdev_priv(netdev); + struct sxevf_adapter *adapter = pci_get_drvdata(pdev); pci_ers_result_t ret; LOG_INFO_BDF("oops, vf pci dev[%p] got io slot reset\n", pdev); @@ -636,14 +638,14 @@ static pci_ers_result_t sxevf_io_slot_reset(struct pci_dev *pdev) static pci_ers_result_t sxevf_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct sxevf_adapter *adapter = netdev_priv(netdev); + struct sxevf_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; pci_ers_result_t ret; LOG_DEBUG_BDF("oops,vf pci dev[%p] got io error detect, state=0x%x\n", pdev, (u32)state); - if (!test_bit(SXEVF_MONITOR_WORK_INITED, &adapter->state)) { + if (!test_bit(SXEVF_MONITOR_WORK_INITED, &adapter->monitor_ctxt.state)) { LOG_ERROR_BDF("vf monitor not inited\n"); ret = PCI_ERS_RESULT_DISCONNECT; goto l_out; diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c index 29aade26472e..dfc970bcdc53 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c @@ -243,8 +243,10 @@ static s32 sxevf_get_link_enable(struct sxevf_adapter *adapter) bool enable = adapter->link.link_enable; msg.msg_type = SXEVF_LINK_ENABLE_GET; + spin_lock_bh(&adapter->mbx_lock); ret = sxevf_send_and_rcv_msg(hw, (u32 *)&msg, SXEVF_MSG_NUM(sizeof(msg))); + spin_unlock_bh(&adapter->mbx_lock); if (!ret && msg.msg_type == (SXEVF_LINK_ENABLE_GET | SXEVF_MSGTYPE_ACK)) { adapter->link.link_enable = msg.link_enable; @@ -723,12 +725,16 @@ static void sxevf_netdev_feature_init(struct net_device *netdev) netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX; + +#ifdef HAVE_NETDEV_XDP_FEATURES + netdev->xdp_features |= NETDEV_XDP_ACT_BASIC; +#endif } static void sxevf_netdev_name_init(struct net_device *netdev, struct pci_dev *pdev) { - strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); + SXE_STRCPY(netdev->name, pci_name(pdev), sizeof(netdev->name)); } #ifndef NO_NETDEVICE_MIN_MAX_MTU diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c index 03913ecef62c..330ab80d159f 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c @@ -359,7 +359,7 @@ static bool sxevf_mapped_page_alloc(struct sxevf_ring *rx_ring, return ret; } -void sxevf_rx_ring_buffers_alloc(struct sxevf_ring *rx_ring, u16 cleaned_count) +static void sxevf_rx_ring_buffers_alloc(struct sxevf_ring *rx_ring, u16 cleaned_count) { union sxevf_rx_data_desc *rx_desc; struct sxevf_rx_buffer *rx_buffer; diff --git a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c index 270d42b4f44f..7d2e37ecfe33 100644 --- a/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c +++ b/drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c @@ -85,7 +85,7 @@ void sxevf_tx_ring_buffer_clean(struct sxevf_ring *ring) ring->next_to_clean = 0; } -void sxevf_tx_ring_free(struct sxevf_ring *ring) +static void sxevf_tx_ring_free(struct sxevf_ring *ring) { sxevf_tx_ring_buffer_clean(ring); @@ -124,7 +124,7 @@ static inline void sxevf_tx_buffer_init(struct sxevf_ring *ring) sizeof(struct sxevf_tx_buffer) * ring->depth); } -s32 sxevf_tx_ring_alloc(struct sxevf_ring *ring) +static s32 sxevf_tx_ring_alloc(struct sxevf_ring *ring) { s32 ret; u32 size = sizeof(struct sxevf_tx_buffer) * ring->depth; -- Gitee