From c3ed68143b9e553bdcf8bc93758dd98a7dc14be1 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran Date: Thu, 1 Aug 2019 11:42:57 -0700 Subject: [PATCH] nvethernet: Add IOCTL handler to config loopback mode MODS tests use private IOCTL to configure MAC loopback mode. Add a priv ioctl handler to support this in nvethernet driver. nvethernet driver also has a sysfs knob to configure loopback. Bug 2665785 Change-Id: I7f488fe81a0772a0881dbba48592bbcd11205dbf Signed-off-by: Srinivas Ramachandran Reviewed-on: https://git-master.nvidia.com/r/2166181 Reviewed-by: mobile promotions Tested-by: mobile promotions --- .../net/ethernet/nvidia/nvethernet/ioctl.c | 59 +++++++++++++++++++ .../net/ethernet/nvidia/nvethernet/ioctl.h | 1 + 2 files changed, 60 insertions(+) diff --git a/drivers/net/ethernet/nvidia/nvethernet/ioctl.c b/drivers/net/ethernet/nvidia/nvethernet/ioctl.c index 20c5ae4f..085de6ad 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ioctl.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ioctl.c @@ -564,6 +564,62 @@ static int ether_config_l2_da_filter(struct net_device *dev, return ret; } +/** + * ether_config_loopback_mode- This function is invoked by ioctl + * when user issues an ioctl command to enable/disable MAC loopback mode. + * + * @dev: pointer to net device structure. + * @flags: flag to indicate whether MAC loopback mode to be enabled or + * disabled. + * + * Algorithm: + * 1) check if loopback mode enalbed/disable already and return success. + * 2) OSI call to configure loopback mode in HW. + * + * Dependencies: MAC and PHY need to be initialized. + * + * Protection: None. + * + * Return 0- sucessful, Negative - error + */ +static int ether_config_loopback_mode(struct net_device *ndev, + unsigned int flags) +{ + struct ether_priv_data *pdata = netdev_priv(ndev); + struct osi_core_priv_data *osi_core = pdata->osi_core; + int ret = 0; + + if ((flags && (pdata->mac_loopback_mode == OSI_ENABLE)) || + (!flags && (pdata->mac_loopback_mode == OSI_DISABLE))) { + dev_info(pdata->dev, "Loopback mode is already configured\n"); + return ret; + } + + if (flags) { + netif_carrier_on(ndev); + ret = osi_config_mac_loopback(osi_core, OSI_ENABLE); + if (ret < 0) { + dev_err(pdata->dev, + "Failed to enable MAC Loopback\n"); + } else { + pdata->mac_loopback_mode = OSI_ENABLE; + dev_info(pdata->dev, "MAC loopback enabled\n"); + } + } else { + netif_carrier_off(ndev); + ret = osi_config_mac_loopback(osi_core, OSI_DISABLE); + if (ret < 0) { + dev_err(pdata->dev, + "Failed to disable MAC Loopback\n"); + } else { + pdata->mac_loopback_mode = OSI_DISABLE; + dev_info(pdata->dev, "MAC loopback disabled\n"); + } + } + + return ret; +} + /** * ether_priv_ioctl - Handle private IOCTLs * @ndev: network device structure @@ -641,6 +697,9 @@ int ether_handle_priv_ioctl(struct net_device *ndev, case EQOS_L2_DA_FILTERING_CMD: ret = ether_config_l2_da_filter(ndev, &ifdata); break; + case ETHER_CONFIG_LOOPBACK_MODE: + ret = ether_config_loopback_mode(ndev, ifdata.if_flags); + break; default: break; } diff --git a/drivers/net/ethernet/nvidia/nvethernet/ioctl.h b/drivers/net/ethernet/nvidia/nvethernet/ioctl.h index 09de4e7f..f027bbb2 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ioctl.h +++ b/drivers/net/ethernet/nvidia/nvethernet/ioctl.h @@ -37,6 +37,7 @@ /* L2 DA filtering */ #define EQOS_L2_DA_FILTERING_CMD 35 #define ETHER_CONFIG_ARP_OFFLOAD 36 +#define ETHER_CONFIG_LOOPBACK_MODE 40 #define ETHER_GET_AVB_ALGORITHM 46 /**