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 <narayanr@nvidia.com>
Change-Id: Idd479983c39a7f15c875dac93c86d5bf4fd5e04c
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3258754
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Narayan Reddy
2024-11-28 06:54:59 +00:00
committed by Jon Hunter
parent 7ae5bc1873
commit d3cdce84ec
3 changed files with 70 additions and 28 deletions

View File

@@ -51,6 +51,12 @@
#define ETHER_M2M_TSYNC 59 #define ETHER_M2M_TSYNC 59
/** Configure L2 Filter (Only with Ethernet virtualization) */ /** Configure L2 Filter (Only with Ethernet virtualization) */
#define ETHER_L2_ADDR 61 #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 /** IOCTL cmd specific structure pointer
* - Valid range: A valid pointer to the IOCTL private structure data */ * - Valid range: A valid pointer to the IOCTL private structure data */
void *ptr; void *ptr;
/** MAC instance ID (eqos:0 mgbe0:1 mgbe1:2 mgbe2:3 mgbe3:4) */
nve32_t mac_id;
}; };
enum nv_macsec_nl_commands { enum nv_macsec_nl_commands {

View File

@@ -1073,6 +1073,7 @@ int ether_handle_priv_ioctl(struct net_device *ndev,
struct osi_ioctl ioctl_data = {}; struct osi_ioctl ioctl_data = {};
struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_core_priv_data *osi_core = pdata->osi_core;
#endif /* !OSI_STRIPPED_LIB */ #endif /* !OSI_STRIPPED_LIB */
ivc_msg_common_t *ivc_buf;
struct ether_exported_ifr_data ifdata; struct ether_exported_ifr_data ifdata;
#ifdef OSI_DEBUG #ifdef OSI_DEBUG
struct osi_dma_priv_data *osi_dma = pdata->osi_dma; 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; 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 */ /* Enforce admin permission check */
switch (ifdata.ifcmd) { switch (ifdata.ifcmd) {
case ETHER_AVB_ALGORITHM: case ETHER_AVB_ALGORITHM:
@@ -1134,6 +1144,39 @@ int ether_handle_priv_ioctl(struct net_device *ndev,
case ETHER_GET_AVB_ALGORITHM: case ETHER_GET_AVB_ALGORITHM:
ret = ether_get_avb_algo(ndev, &ifdata); ret = ether_get_avb_algo(ndev, &ifdata);
break; 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 #ifndef OSI_STRIPPED_LIB
case ETHER_CONFIG_ARP_OFFLOAD: case ETHER_CONFIG_ARP_OFFLOAD:
ret = ether_config_arp_offload(pdata, &ifdata); ret = ether_config_arp_offload(pdata, &ifdata);
@@ -1242,6 +1285,8 @@ int ether_handle_priv_ioctl(struct net_device *ndev,
break; break;
} }
err: err:
kfree(ivc_buf);
ifdata.command_error = ret; ifdata.command_error = ret;
if (copy_to_user(ifr->ifr_data, &ifdata, sizeof(ifdata)) != 0U) { if (copy_to_user(ifr->ifr_data, &ifdata, sizeof(ifdata)) != 0U) {
dev_err(pdata->dev, "%s: copy_to_user failed\n", __func__); dev_err(pdata->dev, "%s: copy_to_user failed\n", __func__);

View File

@@ -3366,11 +3366,6 @@ static ssize_t hsi_enable_show(struct device *dev,
struct ether_priv_data *pdata = netdev_priv(ndev); struct ether_priv_data *pdata = netdev_priv(ndev);
struct osi_core_priv_data *osi_core = pdata->osi_core; 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", return scnprintf(buf, PAGE_SIZE, "%s\n",
(osi_core->hsi.enabled == OSI_ENABLE) ? (osi_core->hsi.enabled == OSI_ENABLE) ?
"enabled" : "disabled"); "enabled" : "disabled");
@@ -3398,12 +3393,7 @@ static ssize_t hsi_enable_store(struct device *dev,
struct osi_ioctl ioctl_data = {}; struct osi_ioctl ioctl_data = {};
int ret = 0; int ret = 0;
u32 inst_id = osi_core->instance_id; u32 inst_id = osi_core->instance_id;
u32 ip_type[2] = {IP_EQOS, IP_MGBE}; u32 ip_type[3] = {IP_EQOS, IP_MGBE, IP_MGBE};
if (osi_core->use_virtualization == OSI_ENABLE) {
dev_err(pdata->dev, "Not supported with Ethernet virtualization enabled\n");
return size;
}
if (!netif_running(ndev)) { if (!netif_running(ndev)) {
dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n"); 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; ioctl_data.cmd = OSI_CMD_HSI_CONFIGURE;
if (strncmp(buf, "enable", 6) == OSI_NONE) { if (strncmp(buf, "enable", 6) == OSI_NONE) {
if (osi_core->use_virtualization != OSI_ENABLE) {
ioctl_data.arg1_u32 = OSI_ENABLE; ioctl_data.arg1_u32 = OSI_ENABLE;
ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data);
if (ret < 0) { if (ret < 0) {
dev_err(pdata->dev, dev_err(pdata->dev, "Failed to enable HSI\n");
"Failed to enable HSI\n"); }
} else { }
if (ret == 0) {
osi_core->hsi.enabled = OSI_ENABLE; osi_core->hsi.enabled = OSI_ENABLE;
dev_info(pdata->dev, "HSI Enabled\n"); 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, ret = hsierrrpt_reg_cb(ip_type[osi_core->mac], inst_id,
hsi_inject_err_fsi, pdata); hsi_inject_err_fsi, pdata);
if (ret != 0) { if (ret != 0) {
@@ -3431,16 +3420,16 @@ static ssize_t hsi_enable_store(struct device *dev,
} }
} }
} else if (strncmp(buf, "disable", 7) == OSI_NONE) { } else if (strncmp(buf, "disable", 7) == OSI_NONE) {
if (osi_core->use_virtualization != OSI_ENABLE) {
ioctl_data.arg1_u32 = OSI_DISABLE; ioctl_data.arg1_u32 = OSI_DISABLE;
ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data);
if (ret < 0) { if (ret < 0) {
dev_err(pdata->dev, dev_err(pdata->dev, "Failed to disable HSI\n");
"Failed to disable HSI\n"); }
} else { }
if (ret == 0) {
osi_core->hsi.enabled = OSI_DISABLE; osi_core->hsi.enabled = OSI_DISABLE;
dev_info(pdata->dev, "HSI Disabled\n"); 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); ret = hsierrrpt_dereg_cb(ip_type[osi_core->mac], inst_id);
if (ret != 0) { if (ret != 0) {