From d3cdce84ecc7bf1e9372a1e9e7af9a719040e240 Mon Sep 17 00:00:00 2001 From: Narayan Reddy Date: Thu, 28 Nov 2024 06:54:59 +0000 Subject: [PATCH] nvethernet: IOCTL handling of HSIs 1) Add IOCTL support for below HSIs T264-EQOS_HSIv2-30 T264-EQOS_HSIv2-9 T264-MGBE_HSIv2-8 T264-MGBE_HSIv2-7 T264-MGBE_HSIv2-6 2) Add support for T26x Err Injection JIRA NET-1946 JIRA NET-1948 Bug 4778785 Signed-off-by: Narayan Reddy Change-Id: Idd479983c39a7f15c875dac93c86d5bf4fd5e04c Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3258754 Tested-by: mobile promotions Reviewed-by: Srinivas Ramachandran Reviewed-by: mobile promotions --- .../ethernet/nvidia/nvethernet/ether_export.h | 8 ++++ .../net/ethernet/nvidia/nvethernet/ioctl.c | 45 +++++++++++++++++++ .../net/ethernet/nvidia/nvethernet/sysfs.c | 45 +++++++------------ 3 files changed, 70 insertions(+), 28 deletions(-) diff --git a/drivers/net/ethernet/nvidia/nvethernet/ether_export.h b/drivers/net/ethernet/nvidia/nvethernet/ether_export.h index abf9e4ac..70e317f6 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ether_export.h +++ b/drivers/net/ethernet/nvidia/nvethernet/ether_export.h @@ -51,6 +51,12 @@ #define ETHER_M2M_TSYNC 59 /** Configure L2 Filter (Only with Ethernet virtualization) */ #define ETHER_L2_ADDR 61 +/** To get the AVB performance */ +#define ETHER_GET_AVB_PERF 62 +/** To get timestamp status */ +#define ETHER_VERIFY_TS 63 +/** To get regsiter status */ +#define ETHER_GET_STATUS 64 /** @} */ /** @@ -190,6 +196,8 @@ struct ether_exported_ifr_data { /** IOCTL cmd specific structure pointer * - Valid range: A valid pointer to the IOCTL private structure data */ void *ptr; + /** MAC instance ID (eqos:0 mgbe0:1 mgbe1:2 mgbe2:3 mgbe3:4) */ + nve32_t mac_id; }; enum nv_macsec_nl_commands { diff --git a/drivers/net/ethernet/nvidia/nvethernet/ioctl.c b/drivers/net/ethernet/nvidia/nvethernet/ioctl.c index a4cef008..c9726f54 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ioctl.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ioctl.c @@ -1073,6 +1073,7 @@ int ether_handle_priv_ioctl(struct net_device *ndev, struct osi_ioctl ioctl_data = {}; struct osi_core_priv_data *osi_core = pdata->osi_core; #endif /* !OSI_STRIPPED_LIB */ + ivc_msg_common_t *ivc_buf; struct ether_exported_ifr_data ifdata; #ifdef OSI_DEBUG struct osi_dma_priv_data *osi_dma = pdata->osi_dma; @@ -1086,6 +1087,15 @@ int ether_handle_priv_ioctl(struct net_device *ndev, return -EFAULT; } + if (ifdata.ifcmd == ETHER_GET_AVB_PERF || ifdata.ifcmd == ETHER_VERIFY_TS || + ifdata.ifcmd == ETHER_GET_STATUS) { + ivc_buf = kzalloc(sizeof(*ivc_buf), GFP_KERNEL); + if (!ivc_buf) { + ret = -ENOMEM; + goto err; + } + } + /* Enforce admin permission check */ switch (ifdata.ifcmd) { case ETHER_AVB_ALGORITHM: @@ -1134,6 +1144,39 @@ int ether_handle_priv_ioctl(struct net_device *ndev, case ETHER_GET_AVB_ALGORITHM: ret = ether_get_avb_algo(ndev, &ifdata); break; + case ETHER_GET_AVB_PERF: + ivc_buf->cmd = nvethmgr_get_avb_perf; + ivc_buf->args.arguments[0] = ifdata.mac_id; + ivc_buf->args.arguments[1] = ifdata.qinx; + ret = osd_ivc_send_cmd(pdata->osi_core, ivc_buf, sizeof(*ivc_buf)); + if (ret != 0) { + dev_err(pdata->dev, "Failed to get AVB perf info\n"); + goto err; + } + ret = ivc_buf->status; + break; + case ETHER_VERIFY_TS: + ivc_buf->cmd = nvethmgr_verify_ts; + ivc_buf->args.arguments[0] = ifdata.mac_id; + ivc_buf->args.arguments[1] = ifdata.qinx; + ret = osd_ivc_send_cmd(pdata->osi_core, ivc_buf, sizeof(*ivc_buf)); + if (ret != 0) { + dev_err(pdata->dev, "Failed to verify timestamp\n"); + goto err; + } + ret = ivc_buf->status; + break; + case ETHER_GET_STATUS: + ivc_buf->cmd = nvethmgr_get_status; + ivc_buf->args.arguments[0] = ifdata.mac_id; + ret = osd_ivc_send_cmd(pdata->osi_core, ivc_buf, sizeof(*ivc_buf)); + if (ret != 0) { + dev_err(pdata->dev, "Failed to get status for registers\n"); + goto err; + } + ret = ivc_buf->status; + break; + #ifndef OSI_STRIPPED_LIB case ETHER_CONFIG_ARP_OFFLOAD: ret = ether_config_arp_offload(pdata, &ifdata); @@ -1242,6 +1285,8 @@ int ether_handle_priv_ioctl(struct net_device *ndev, break; } err: + kfree(ivc_buf); + ifdata.command_error = ret; if (copy_to_user(ifr->ifr_data, &ifdata, sizeof(ifdata)) != 0U) { dev_err(pdata->dev, "%s: copy_to_user failed\n", __func__); diff --git a/drivers/net/ethernet/nvidia/nvethernet/sysfs.c b/drivers/net/ethernet/nvidia/nvethernet/sysfs.c index 0409e504..1f202f08 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/sysfs.c +++ b/drivers/net/ethernet/nvidia/nvethernet/sysfs.c @@ -3366,11 +3366,6 @@ static ssize_t hsi_enable_show(struct device *dev, struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; - if (osi_core->use_virtualization == OSI_ENABLE) { - dev_err(pdata->dev, "Not supported with Ethernet virtualization enabled\n"); - return 0; - } - return scnprintf(buf, PAGE_SIZE, "%s\n", (osi_core->hsi.enabled == OSI_ENABLE) ? "enabled" : "disabled"); @@ -3398,12 +3393,7 @@ static ssize_t hsi_enable_store(struct device *dev, struct osi_ioctl ioctl_data = {}; int ret = 0; u32 inst_id = osi_core->instance_id; - u32 ip_type[2] = {IP_EQOS, IP_MGBE}; - - if (osi_core->use_virtualization == OSI_ENABLE) { - dev_err(pdata->dev, "Not supported with Ethernet virtualization enabled\n"); - return size; - } + u32 ip_type[3] = {IP_EQOS, IP_MGBE, IP_MGBE}; if (!netif_running(ndev)) { dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n"); @@ -3412,17 +3402,16 @@ static ssize_t hsi_enable_store(struct device *dev, ioctl_data.cmd = OSI_CMD_HSI_CONFIGURE; if (strncmp(buf, "enable", 6) == OSI_NONE) { - ioctl_data.arg1_u32 = OSI_ENABLE; - ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); - if (ret < 0) { - dev_err(pdata->dev, - "Failed to enable HSI\n"); - } else { + if (osi_core->use_virtualization != OSI_ENABLE) { + ioctl_data.arg1_u32 = OSI_ENABLE; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); + if (ret < 0) { + dev_err(pdata->dev, "Failed to enable HSI\n"); + } + } + if (ret == 0) { osi_core->hsi.enabled = OSI_ENABLE; dev_info(pdata->dev, "HSI Enabled\n"); - if (osi_core->instance_id == OSI_INSTANCE_ID_EQOS) - inst_id = 0; - ret = hsierrrpt_reg_cb(ip_type[osi_core->mac], inst_id, hsi_inject_err_fsi, pdata); if (ret != 0) { @@ -3431,16 +3420,16 @@ static ssize_t hsi_enable_store(struct device *dev, } } } else if (strncmp(buf, "disable", 7) == OSI_NONE) { - ioctl_data.arg1_u32 = OSI_DISABLE; - ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); - if (ret < 0) { - dev_err(pdata->dev, - "Failed to disable HSI\n"); - } else { + if (osi_core->use_virtualization != OSI_ENABLE) { + ioctl_data.arg1_u32 = OSI_DISABLE; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); + if (ret < 0) { + dev_err(pdata->dev, "Failed to disable HSI\n"); + } + } + if (ret == 0) { osi_core->hsi.enabled = OSI_DISABLE; dev_info(pdata->dev, "HSI Disabled\n"); - if (osi_core->instance_id == OSI_INSTANCE_ID_EQOS) - inst_id = 0; ret = hsierrrpt_dereg_cb(ip_type[osi_core->mac], inst_id); if (ret != 0) {