diff --git a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c index 94a370b8..678cbb58 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c @@ -34,9 +34,11 @@ static inline void ether_stats_work_func(struct work_struct *work) struct ether_priv_data *pdata = container_of(dwork, struct ether_priv_data, ether_stats_work); struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; int ret; - ret = osi_read_mmc(osi_core); + ioctl_data.cmd = OSI_CMD_READ_MMC; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "failed to read MMC counters %s\n", __func__); @@ -240,6 +242,7 @@ int ether_conf_eee(struct ether_priv_data *pdata, unsigned int tx_lpi_enable) int ret = 0; struct phy_device *phydev = pdata->phydev; unsigned int enable = tx_lpi_enable; + struct osi_ioctl ioctl_data = {}; if (tx_lpi_enable) { /* phy_init_eee() returns 0 if EEE is supported by the PHY */ @@ -253,9 +256,11 @@ int ether_conf_eee(struct ether_priv_data *pdata, unsigned int tx_lpi_enable) } /* Enable EEE */ - ret = osi_configure_eee(pdata->osi_core, - enable, - pdata->tx_lpi_timer); + ioctl_data.cmd = OSI_CMD_CONFIG_EEE; + ioctl_data.arg1_u32 = enable; + ioctl_data.arg2_u32 = pdata->tx_lpi_timer; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); + /* Return current status of EEE based on OSI API success/failure */ if (ret != 0) { if (enable) { @@ -291,6 +296,7 @@ static void ether_adjust_link(struct net_device *dev) int new_state = 0, speed_changed = 0; unsigned long val; unsigned int eee_enable = OSI_DISABLE; + struct osi_ioctl ioctl_data = {}; int ret = 0; if (phydev == NULL) { @@ -300,20 +306,33 @@ static void ether_adjust_link(struct net_device *dev) if (phydev->link) { if ((pdata->osi_core->pause_frames == OSI_PAUSE_FRAMES_ENABLE) && (phydev->pause || phydev->asym_pause)) { - osi_configure_flow_control(pdata->osi_core, - pdata->osi_core->flow_ctrl); + ioctl_data.cmd = OSI_CMD_FLOW_CTRL; + ioctl_data.arg1_u32 = pdata->osi_core->flow_ctrl; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); + if (ret < 0) { + netdev_err(dev, "Failed to set pause frame\n"); + return; + } } if (phydev->duplex != pdata->oldduplex) { new_state = 1; - osi_set_mode(pdata->osi_core, phydev->duplex); + ioctl_data.cmd = OSI_CMD_SET_MODE; + ioctl_data.arg6_32 = phydev->duplex; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); + if (ret < 0) { + netdev_err(dev, "Failed to set mode\n"); + return; + } pdata->oldduplex = phydev->duplex; } if (phydev->speed != pdata->speed) { new_state = 1; speed_changed = 1; - ret = osi_set_speed(pdata->osi_core, phydev->speed); + ioctl_data.cmd = OSI_CMD_SET_SPEED; + ioctl_data.arg6_32 = phydev->speed; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); if (ret < 0) { netdev_err(dev, "Failed to set speed\n"); return; @@ -351,9 +370,12 @@ static void ether_adjust_link(struct net_device *dev) (phydev->speed == SPEED_100) ? 25000 * 1000 : 125000 * 1000); if (phydev->speed != SPEED_10) { - if (osi_pad_calibrate(pdata->osi_core) < 0) + ioctl_data.cmd = OSI_CMD_PAD_CALIBRATION; + if (osi_handle_ioctl(pdata->osi_core, &ioctl_data) < + 0) { dev_err(pdata->dev, "failed to do pad caliberation\n"); + } } } @@ -625,8 +647,15 @@ static irqreturn_t ether_rx_chan_isr(int irq, void *data) static irqreturn_t ether_common_isr(int irq, void *data) { struct ether_priv_data *pdata = (struct ether_priv_data *)data; + struct osi_ioctl ioctl_data = {}; + int ret; - osi_common_isr(pdata->osi_core); + ioctl_data.cmd = OSI_CMD_COMMON_ISR; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); + if (ret < 0) { + dev_err(pdata->dev, + "%s() failure in handling ISR\n", __func__); + } return IRQ_HANDLED; } @@ -1511,6 +1540,8 @@ static int ether_set_cur_therm_state(struct thermal_cooling_device *tcd, { struct ether_priv_data *pdata = tcd->devdata; struct device *dev = pdata->dev; + struct osi_ioctl ioctl_data = {}; + /* Thermal framework will take care of making sure state is within * valid bounds, based on the get_max_state callback. So no need @@ -1521,7 +1552,8 @@ static int ether_set_cur_therm_state(struct thermal_cooling_device *tcd, atomic_set(&pdata->therm_state, state); - if (osi_pad_calibrate(pdata->osi_core) < 0) { + ioctl_data.cmd = OSI_CMD_PAD_CALIBRATION; + if (osi_handle_ioctl(pdata->osi_core, &ioctl_data) < 0) { dev_err(dev, "Therm state changed, failed pad calibration\n"); return -1; } @@ -1693,6 +1725,7 @@ static int ether_open(struct net_device *dev) { struct ether_priv_data *pdata = netdev_priv(dev); struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; int ret = 0; /* Reset the PHY */ @@ -1722,7 +1755,8 @@ static int ether_open(struct net_device *dev) power_ungate(pdata); } - ret = osi_poll_for_mac_reset_complete(osi_core); + ioctl_data.cmd = OSI_CMD_POLL_FOR_MAC_RST; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(&dev->dev, "failed to poll MAC Software reset\n"); goto err_poll_swr; @@ -1828,8 +1862,14 @@ static int ether_open(struct net_device *dev) ether_init_eee_params(pdata); /* Start the MAC */ - osi_start_mac(pdata->osi_core); - + ioctl_data.cmd = OSI_CMD_START_MAC; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); + if (ret < 0) { + dev_err(&dev->dev, + "%s: failed to start MAC %d\n", + __func__, ret); + goto err_r_irq; + } /* start PHY */ phy_start(pdata->phydev); @@ -2395,7 +2435,7 @@ static int ether_start_xmit(struct sk_buff *skb, struct net_device *ndev) * @retval "negative value" on failure. */ static int ether_prepare_mc_list(struct net_device *dev, - struct osi_filter *filter) + struct osi_ioctl *ioctl_data) { struct ether_priv_data *pdata = netdev_priv(dev); struct osi_core_priv_data *osi_core = pdata->osi_core; @@ -2403,54 +2443,56 @@ static int ether_prepare_mc_list(struct net_device *dev, unsigned int i = 1; int ret = -1; - if (filter == NULL) { - dev_err(pdata->dev, "filter is NULL\n"); + if (ioctl_data == NULL) { + dev_err(pdata->dev, "ioctl_data is NULL\n"); return ret; } - memset(filter, 0x0, sizeof(struct osi_filter)); + memset(&ioctl_data->l2_filter, 0x0, sizeof(struct osi_filter)); if (pdata->l2_filtering_mode == OSI_HASH_FILTER_MODE) { dev_err(pdata->dev, "HASH FILTERING for mc addresses not Supported in SW\n"); - filter->oper_mode = (OSI_OPER_EN_PERFECT | - OSI_OPER_DIS_PROMISC | - OSI_OPER_DIS_ALLMULTI); - - return osi_l2_filter(osi_core, filter); + ioctl_data->l2_filter.oper_mode = (OSI_OPER_EN_PERFECT | + OSI_OPER_DIS_PROMISC | + OSI_OPER_DIS_ALLMULTI); + ioctl_data->cmd = OSI_CMD_L2_FILTER; + return osi_handle_ioctl(osi_core, ioctl_data); /* address 0 is used for DUT DA so compare with * pdata->num_mac_addr_regs - 1 */ } else if (netdev_mc_count(dev) > (pdata->num_mac_addr_regs - 1)) { /* switch to PROMISCUOUS mode */ - filter->oper_mode = (OSI_OPER_DIS_PERFECT | - OSI_OPER_EN_PROMISC | - OSI_OPER_DIS_ALLMULTI); + ioctl_data->l2_filter.oper_mode = (OSI_OPER_DIS_PERFECT | + OSI_OPER_EN_PROMISC | + OSI_OPER_DIS_ALLMULTI); dev_dbg(pdata->dev, "enabling Promiscuous mode\n"); - return osi_l2_filter(osi_core, filter); + ioctl_data->cmd = OSI_CMD_L2_FILTER; + return osi_handle_ioctl(osi_core, ioctl_data); } else { dev_dbg(pdata->dev, "select PERFECT FILTERING for mc addresses, mc_count = %d, num_mac_addr_regs = %d\n", netdev_mc_count(dev), pdata->num_mac_addr_regs); - filter->oper_mode = (OSI_OPER_EN_PERFECT | - OSI_OPER_ADDR_UPDATE | - OSI_OPER_DIS_PROMISC | - OSI_OPER_DIS_ALLMULTI); + ioctl_data->l2_filter.oper_mode = (OSI_OPER_EN_PERFECT | + OSI_OPER_ADDR_UPDATE | + OSI_OPER_DIS_PROMISC | + OSI_OPER_DIS_ALLMULTI); netdev_for_each_mc_addr(ha, dev) { dev_dbg(pdata->dev, "mc addr[%d] = %#x:%#x:%#x:%#x:%#x:%#x\n", i, ha->addr[0], ha->addr[1], ha->addr[2], ha->addr[3], ha->addr[4], ha->addr[5]); - filter->index = i; - memcpy(filter->mac_address, ha->addr, ETH_ALEN); - filter->dma_routing = OSI_DISABLE; - filter->dma_chan = 0x0; - filter->addr_mask = OSI_AMASK_DISABLE; - filter->src_dest = OSI_DA_MATCH; - filter->dma_chansel = osi_core->mc_dmasel; - ret = osi_l2_filter(osi_core, filter); + ioctl_data->l2_filter.index = i; + memcpy(ioctl_data->l2_filter.mac_address, ha->addr, + ETH_ALEN); + ioctl_data->l2_filter.dma_routing = OSI_DISABLE; + ioctl_data->l2_filter.dma_chan = 0x0; + ioctl_data->l2_filter.addr_mask = OSI_AMASK_DISABLE; + ioctl_data->l2_filter.src_dest = OSI_DA_MATCH; + ioctl_data->cmd = OSI_CMD_L2_FILTER; + ret = osi_handle_ioctl(osi_core, ioctl_data); if (ret < 0) { dev_err(pdata->dev, "issue in creating mc list\n"); pdata->last_filter_index = i - 1; @@ -2485,7 +2527,7 @@ static int ether_prepare_mc_list(struct net_device *dev, * @retval "negative value" on failure. */ static int ether_prepare_uc_list(struct net_device *dev, - struct osi_filter *filter) + struct osi_ioctl *ioctl_data) { struct ether_priv_data *pdata = netdev_priv(dev); struct osi_core_priv_data *osi_core = pdata->osi_core; @@ -2494,51 +2536,54 @@ static int ether_prepare_uc_list(struct net_device *dev, struct netdev_hw_addr *ha; int ret = -1; - if (filter == NULL) { - dev_err(pdata->dev, "filter is NULL\n"); + if (ioctl_data == NULL) { + dev_err(pdata->dev, "ioctl_data is NULL\n"); return ret; } - memset(filter, 0x0, sizeof(struct osi_filter)); + memset(&ioctl_data->l2_filter, 0x0, sizeof(struct osi_filter)); if (pdata->l2_filtering_mode == OSI_HASH_FILTER_MODE) { dev_err(pdata->dev, "HASH FILTERING for uc addresses not Supported in SW\n"); /* Perfect filtering for multicast */ - filter->oper_mode = (OSI_OPER_EN_PERFECT | - OSI_OPER_DIS_PROMISC | - OSI_OPER_DIS_ALLMULTI); - - return osi_l2_filter(osi_core, filter); + ioctl_data->l2_filter.oper_mode = (OSI_OPER_EN_PERFECT | + OSI_OPER_DIS_PROMISC | + OSI_OPER_DIS_ALLMULTI); + ioctl_data->cmd = OSI_CMD_L2_FILTER; + return osi_handle_ioctl(osi_core, ioctl_data); } else if (netdev_uc_count(dev) > (pdata->num_mac_addr_regs - i)) { /* switch to PROMISCUOUS mode */ - filter->oper_mode = (OSI_OPER_DIS_PERFECT | - OSI_OPER_EN_PROMISC | - OSI_OPER_DIS_ALLMULTI); + ioctl_data->l2_filter.oper_mode = (OSI_OPER_DIS_PERFECT | + OSI_OPER_EN_PROMISC | + OSI_OPER_DIS_ALLMULTI); dev_dbg(pdata->dev, "enabling Promiscuous mode\n"); - - return osi_l2_filter(osi_core, filter); + ioctl_data->cmd = OSI_CMD_L2_FILTER; + return osi_handle_ioctl(osi_core, ioctl_data); } else { dev_dbg(pdata->dev, "select PERFECT FILTERING for uc addresses: uc_count = %d\n", netdev_uc_count(dev)); - filter->oper_mode = (OSI_OPER_EN_PERFECT | - OSI_OPER_ADDR_UPDATE | - OSI_OPER_DIS_PROMISC | - OSI_OPER_DIS_ALLMULTI); + ioctl_data->l2_filter.oper_mode = (OSI_OPER_EN_PERFECT | + OSI_OPER_ADDR_UPDATE | + OSI_OPER_DIS_PROMISC | + OSI_OPER_DIS_ALLMULTI); netdev_for_each_uc_addr(ha, dev) { dev_dbg(pdata->dev, "uc addr[%d] = %#x:%#x:%#x:%#x:%#x:%#x\n", i, ha->addr[0], ha->addr[1], ha->addr[2], ha->addr[3], ha->addr[4], ha->addr[5]); - filter->index = i; - memcpy(filter->mac_address, ha->addr, ETH_ALEN); - filter->dma_routing = OSI_DISABLE; - filter->dma_chan = 0x0; - filter->addr_mask = OSI_AMASK_DISABLE; - filter->src_dest = OSI_DA_MATCH; - ret = osi_l2_filter(osi_core, filter); + ioctl_data->l2_filter.index = i; + memcpy(ioctl_data->l2_filter.mac_address, ha->addr, + ETH_ALEN); + ioctl_data->l2_filter.dma_routing = OSI_DISABLE; + ioctl_data->l2_filter.dma_chan = 0x0; + ioctl_data->l2_filter.addr_mask = OSI_AMASK_DISABLE; + ioctl_data->l2_filter.src_dest = OSI_DA_MATCH; + + ioctl_data->cmd = OSI_CMD_L2_FILTER; + ret = osi_handle_ioctl(osi_core, ioctl_data); if (ret < 0) { dev_err(pdata->dev, "issue in creating uc list\n"); pdata->last_filter_index = i - 1; @@ -2571,20 +2616,23 @@ void ether_set_rx_mode(struct net_device *dev) { struct ether_priv_data *pdata = netdev_priv(dev); struct osi_core_priv_data *osi_core = pdata->osi_core; - struct osi_filter filter; /* store last call last_uc_filter_index in temporary variable */ int last_index = pdata->last_filter_index; + struct osi_ioctl ioctl_data = {}; + int ret = -1; unsigned int i = 0; - memset(&filter, 0x0, sizeof(struct osi_filter)); + memset(&ioctl_data.l2_filter, 0x0, sizeof(struct osi_filter)); if ((dev->flags & IFF_PROMISC) == IFF_PROMISC) { if (pdata->promisc_mode == OSI_ENABLE) { - filter.oper_mode = (OSI_OPER_DIS_PERFECT | - OSI_OPER_EN_PROMISC | - OSI_OPER_DIS_ALLMULTI); + ioctl_data.l2_filter.oper_mode = + (OSI_OPER_DIS_PERFECT | + OSI_OPER_EN_PROMISC | + OSI_OPER_DIS_ALLMULTI); dev_dbg(pdata->dev, "enabling Promiscuous mode\n"); - ret = osi_l2_filter(osi_core, &filter); + ioctl_data.cmd = OSI_CMD_L2_FILTER; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "Setting Promiscuous mode failed\n"); @@ -2596,18 +2644,19 @@ void ether_set_rx_mode(struct net_device *dev) return; } else if ((dev->flags & IFF_ALLMULTI) == IFF_ALLMULTI) { - filter.oper_mode = (OSI_OPER_EN_ALLMULTI | - OSI_OPER_DIS_PERFECT | - OSI_OPER_DIS_PROMISC); + ioctl_data.l2_filter.oper_mode = (OSI_OPER_EN_ALLMULTI | + OSI_OPER_DIS_PERFECT | + OSI_OPER_DIS_PROMISC); dev_dbg(pdata->dev, "pass all multicast pkt\n"); - ret = osi_l2_filter(osi_core, &filter); + ioctl_data.cmd = OSI_CMD_L2_FILTER; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "Setting All Multicast allow mode failed\n"); } return; } else if (!netdev_mc_empty(dev)) { - if (ether_prepare_mc_list(dev, &filter) != 0) { + if (ether_prepare_mc_list(dev, &ioctl_data) != 0) { dev_err(pdata->dev, "Setting MC address failed\n"); } } else { @@ -2615,23 +2664,23 @@ void ether_set_rx_mode(struct net_device *dev) } if (!netdev_uc_empty(dev)) { - if (ether_prepare_uc_list(dev, &filter) != 0) { + if (ether_prepare_uc_list(dev, &ioctl_data) != 0) { dev_err(pdata->dev, "Setting UC address failed\n"); } } /* Reset the filter structure to avoid any old value */ - memset(&filter, 0x0, sizeof(struct osi_filter)); + memset(&ioctl_data.l2_filter, 0x0, sizeof(struct osi_filter)); /* invalidate remaining ealier address */ for (i = pdata->last_filter_index + 1; i <= last_index; i++) { - filter.oper_mode = OSI_OPER_ADDR_UPDATE; - filter.index = i; - filter.dma_routing = OSI_DISABLE; - filter.dma_chan = OSI_CHAN_ANY; - filter.addr_mask = OSI_AMASK_DISABLE; - filter.src_dest = OSI_DA_MATCH; - filter.dma_chansel = OSI_DISABLE; - ret = osi_l2_filter(osi_core, &filter); + ioctl_data.l2_filter.oper_mode = OSI_OPER_ADDR_DEL; + ioctl_data.l2_filter.index = i; + ioctl_data.l2_filter.dma_routing = OSI_DISABLE; + ioctl_data.l2_filter.dma_chan = OSI_CHAN_ANY; + ioctl_data.l2_filter.addr_mask = OSI_AMASK_DISABLE; + ioctl_data.l2_filter.src_dest = OSI_DA_MATCH; + ioctl_data.cmd = OSI_CMD_L2_FILTER; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "Invalidating expired L2 filter failed\n"); return; @@ -2803,6 +2852,7 @@ static int ether_set_features(struct net_device *ndev, netdev_features_t feat) struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; netdev_features_t hw_feat_cur_state = pdata->hw_feat_cur_state; + struct osi_ioctl ioctl_data = {}; if (pdata->hw_feat.rx_coe_sel == 0U) { return ret; @@ -2810,16 +2860,18 @@ static int ether_set_features(struct net_device *ndev, netdev_features_t feat) if ((feat & NETIF_F_RXCSUM) == NETIF_F_RXCSUM) { if (!(hw_feat_cur_state & NETIF_F_RXCSUM)) { - ret = osi_config_rxcsum_offload(osi_core, - OSI_ENABLE); + ioctl_data.cmd = OSI_CMD_RXCSUM_OFFLOAD; + ioctl_data.arg1_u32 = OSI_ENABLE; + ret = osi_handle_ioctl(osi_core, &ioctl_data); dev_info(pdata->dev, "Rx Csum offload: Enable: %s\n", ret ? "Failed" : "Success"); pdata->hw_feat_cur_state |= NETIF_F_RXCSUM; } } else { if ((hw_feat_cur_state & NETIF_F_RXCSUM)) { - ret = osi_config_rxcsum_offload(osi_core, - OSI_DISABLE); + ioctl_data.cmd = OSI_CMD_RXCSUM_OFFLOAD; + ioctl_data.arg1_u32 = OSI_DISABLE; + ret = osi_handle_ioctl(osi_core, &ioctl_data); dev_info(pdata->dev, "Rx Csum offload: Disable: %s\n", ret ? "Failed" : "Success"); pdata->hw_feat_cur_state &= ~NETIF_F_RXCSUM; @@ -2854,13 +2906,16 @@ static int ether_vlan_rx_add_vid(struct net_device *ndev, __be16 vlan_proto, struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; unsigned int vlan_id = (vid | OSI_VLAN_ACTION_ADD); + struct osi_ioctl ioctl_data = {}; int ret = -1; if (pdata->vlan_hash_filtering == OSI_HASH_FILTER_MODE) { dev_err(pdata->dev, "HASH FILTERING for VLAN tag is not supported in SW\n"); } else { - ret = osi_update_vlan_id(osi_core, vlan_id); + ioctl_data.cmd = OSI_CMD_UPDATE_VLAN_ID; + ioctl_data.arg1_u32 = vlan_id; + ret = osi_handle_ioctl(osi_core, &ioctl_data); } return ret; @@ -2891,6 +2946,7 @@ static int ether_vlan_rx_kill_vid(struct net_device *ndev, __be16 vlan_proto, struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; unsigned int vlan_id = (vid | OSI_VLAN_ACTION_DEL); + struct osi_ioctl ioctl_data = {}; int ret = -1; if (!netif_running(ndev)) { @@ -2901,10 +2957,9 @@ static int ether_vlan_rx_kill_vid(struct net_device *ndev, __be16 vlan_proto, dev_err(pdata->dev, "HASH FILTERING for VLAN tag is not supported in SW\n"); } else { - /* By default, receive only VLAN pkt with VID = 1 because - * writing 0 will pass all VLAN pkt - */ - ret = osi_update_vlan_id(osi_core, vlan_id); + ioctl_data.cmd = OSI_CMD_UPDATE_VLAN_ID; + ioctl_data.arg1_u32 = vlan_id; + ret = osi_handle_ioctl(osi_core, &ioctl_data); } return ret; @@ -3629,6 +3684,7 @@ static int ether_configure_car(struct platform_device *pdev, struct device_node *np = dev->of_node; struct osi_core_priv_data *osi_core = pdata->osi_core; unsigned long csr_clk_rate = 0; + struct osi_ioctl ioctl_data = {}; int ret = 0; if (osi_core->pre_si) { @@ -3698,10 +3754,19 @@ static int ether_configure_car(struct platform_device *pdev, } csr_clk_rate = clk_get_rate(pdata->axi_cbb_clk); - osi_set_mdc_clk_rate(pdata->osi_core, csr_clk_rate); + ioctl_data.cmd = OSI_CMD_MDC_CONFIG; + ioctl_data.arg5_u64 = csr_clk_rate; + ret = osi_handle_ioctl(osi_core, &ioctl_data); + if (ret < 0) { + dev_err(&pdev->dev, "failed to configure MDC\n"); + goto err_mdc; + } return ret; - +err_mdc: + if (pdata->mac_rst) { + reset_control_assert(pdata->mac_rst); + } err_rst: ether_disable_clks(pdata); err_enable_clks: @@ -4532,6 +4597,7 @@ static int ether_probe(struct platform_device *pdev) unsigned int num_dma_chans, mac, num_mtl_queues, chan; struct osi_core_priv_data *osi_core; struct osi_dma_priv_data *osi_dma; + struct osi_ioctl ioctl_data = {}; struct net_device *ndev; int ret = 0, i; @@ -4619,18 +4685,23 @@ static int ether_probe(struct platform_device *pdev) power_ungate(pdata); } - ret = osi_get_mac_version(osi_core, &osi_core->mac_ver); + ioctl_data.cmd = OSI_CMD_GET_MAC_VER; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(&pdev->dev, "failed to get MAC version (%u)\n", osi_core->mac_ver); goto err_dma_mask; } + osi_core->mac_ver = ioctl_data.arg1_u32; - ret = osi_get_hw_features(osi_core, &pdata->hw_feat); + ioctl_data.cmd = OSI_CMD_GET_HW_FEAT; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(&pdev->dev, "failed to get HW features\n"); goto err_dma_mask; } + memcpy(&pdata->hw_feat, &ioctl_data.hw_feat, + sizeof(struct osi_hw_features)); if (pdata->hw_feat.fpe_sel) { ret = ether_parse_residual_queue(pdata, "nvidia,residual-queue", @@ -4809,6 +4880,7 @@ static int ether_suspend_noirq(struct device *dev) struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_dma_priv_data *osi_dma = pdata->osi_dma; + struct osi_ioctl ioctl_data = {}; unsigned int i = 0, chan = 0; if (!netif_running(ndev)) @@ -4818,7 +4890,8 @@ static int ether_suspend_noirq(struct device *dev) * current configuration so that SW view of HW is maintained across * suspend/resume. */ - if (osi_save_registers(osi_core)) { + ioctl_data.cmd = OSI_CMD_SAVE_REGISTER; + if (osi_handle_ioctl(osi_core, &ioctl_data)) { dev_err(dev, "Failed to backup MAC core registers\n"); return -EBUSY; } @@ -4874,6 +4947,7 @@ static int ether_resume(struct ether_priv_data *pdata) struct osi_dma_priv_data *osi_dma = pdata->osi_dma; struct device *dev = pdata->dev; struct net_device *ndev = pdata->ndev; + struct osi_ioctl ioctl_data = {}; int ret = 0; if (pdata->mac_rst) { @@ -4884,13 +4958,15 @@ static int ether_resume(struct ether_priv_data *pdata) } } - ret = osi_poll_for_mac_reset_complete(osi_core); + ioctl_data.cmd = OSI_CMD_POLL_FOR_MAC_RST; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(dev, "failed to poll mac software reset\n"); return ret; } - ret = osi_pad_calibrate(osi_core); + ioctl_data.cmd = OSI_CMD_PAD_CALIBRATION; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(dev, "failed to do pad caliberation\n"); return ret; @@ -4927,7 +5003,14 @@ static int ether_resume(struct ether_priv_data *pdata) /* enable NAPI */ ether_napi_enable(pdata); /* start the mac */ - osi_start_mac(osi_core); + ioctl_data.cmd = OSI_CMD_START_MAC; + ret = osi_handle_ioctl(osi_core, &ioctl_data); + if (ret < 0) { + dev_err(dev, + "%s: failed to start MAC %d\n", __func__, ret); + goto err_start_mac; + } + if (pdata->phydev && !(device_may_wakeup(&ndev->dev))) { /* configure phy init */ phy_init_hw(pdata->phydev); @@ -4940,7 +5023,8 @@ static int ether_resume(struct ether_priv_data *pdata) ether_stats_work_queue_start(pdata); return 0; - +err_start_mac: + ether_napi_disable(pdata); err_dma: osi_hw_core_deinit(osi_core); err_core: @@ -4965,6 +5049,7 @@ static int ether_resume_noirq(struct device *dev) struct net_device *ndev = dev_get_drvdata(dev); struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; int ret = 0; if (!netif_running(ndev)) @@ -4990,7 +5075,8 @@ static int ether_resume_noirq(struct device *dev) * Restore the backup of the MAC configuration to maintain consistency * between SW/HW state. */ - if (osi_restore_registers(osi_core)) { + ioctl_data.cmd = OSI_CMD_RESTORE_REGISTER; + if (osi_handle_ioctl(osi_core, &ioctl_data)) { //TODO: Ideally, undo MAC init/resume & return. dev_err(dev, "Failed to restore MAC core registers\n"); return -EIO; diff --git a/drivers/net/ethernet/nvidia/nvethernet/ethtool.c b/drivers/net/ethernet/nvidia/nvethernet/ethtool.c index e56b46cb..512fe6c2 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ethtool.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ethtool.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -470,6 +470,7 @@ static void ether_get_ethtool_stats(struct net_device *dev, struct ether_priv_data *pdata = netdev_priv(dev); struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_dma_priv_data *osi_dma = pdata->osi_dma; + struct osi_ioctl ioctl_data = {}; int i, j = 0; int ret; @@ -479,7 +480,8 @@ static void ether_get_ethtool_stats(struct net_device *dev, } if (pdata->hw_feat.mmc_sel == 1U) { - ret = osi_read_mmc(osi_core); + ioctl_data.cmd = OSI_CMD_READ_MMC; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret == -1) { dev_err(pdata->dev, "Error in reading MMC counter\n"); return; @@ -750,6 +752,7 @@ static int ether_set_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause) { struct ether_priv_data *pdata = netdev_priv(ndev); + struct osi_ioctl ioctl_data = {}; struct phy_device *phydev = pdata->phydev; int curflow_ctrl = OSI_FLOW_CTRL_DISABLE; int ret; @@ -796,8 +799,13 @@ static int ether_set_pauseparam(struct net_device *ndev, } /* Configure current flow control settings */ - ret = osi_configure_flow_control(pdata->osi_core, - pdata->osi_core->flow_ctrl); + ioctl_data.cmd = OSI_CMD_FLOW_CTRL; + ioctl_data.arg1_u32 = pdata->osi_core->flow_ctrl; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); + if (ret < 0) { + dev_err(pdata->dev, "Setting flow control failed\n"); + return -EFAULT; + } return ret; } @@ -1416,6 +1424,7 @@ static int ether_set_rxfh(struct net_device *ndev, const u32 *indir, { struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; int i; if (!netif_running(ndev)) { @@ -1434,7 +1443,9 @@ static int ether_set_rxfh(struct net_device *ndev, const u32 *indir, if (key) memcpy(osi_core->rss.key, key, sizeof(osi_core->rss.key)); - return osi_config_rss(osi_core); + ioctl_data.cmd = OSI_CMD_CONFIG_RSS; + return osi_handle_ioctl(pdata->osi_core, &ioctl_data); + } /** diff --git a/drivers/net/ethernet/nvidia/nvethernet/ioctl.c b/drivers/net/ethernet/nvidia/nvethernet/ioctl.c index 82d08a9f..b2b11434 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ioctl.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ioctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -122,9 +122,9 @@ static int ether_set_avb_algo(struct net_device *ndev, { struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; - struct osi_core_avb_algorithm l_avb_struct; struct osi_dma_priv_data *osi_dma = pdata->osi_dma; struct osi_tx_ring *tx_ring = NULL; + struct osi_ioctl ioctl_data = {}; int ret = -1; if (ifdata->ptr == NULL) { @@ -133,7 +133,7 @@ static int ether_set_avb_algo(struct net_device *ndev, return ret; } - if (copy_from_user(&l_avb_struct, + if (copy_from_user(&ioctl_data.avb, (struct osi_core_avb_algorithm *)ifdata->ptr, sizeof(struct osi_core_avb_algorithm)) != 0U) { dev_err(pdata->dev, @@ -142,16 +142,17 @@ static int ether_set_avb_algo(struct net_device *ndev, } /* Check AVB mode disable on slot function enable */ - tx_ring = osi_dma->tx_ring[l_avb_struct.qindex]; + tx_ring = osi_dma->tx_ring[ioctl_data.avb.qindex]; if (tx_ring && tx_ring->slot_check == OSI_ENABLE && - l_avb_struct.oper_mode == OSI_MTL_QUEUE_ENABLE) { + ioctl_data.avb.oper_mode == OSI_MTL_QUEUE_ENABLE) { dev_err(pdata->dev, "Can't disable queue:%d AVB mode when slot is enabled", - l_avb_struct.qindex); + ioctl_data.avb.qindex); return -EINVAL; } - return osi_set_avb(osi_core, &l_avb_struct); + ioctl_data.cmd = OSI_CMD_SET_AVB; + return osi_handle_ioctl(osi_core, &ioctl_data); } /** @@ -174,7 +175,7 @@ static int ether_get_avb_algo(struct net_device *ndev, { struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; - struct osi_core_avb_algorithm avb_data; + struct osi_ioctl ioctl_data = {}; int ret; if (ifdata->ptr == NULL) { @@ -183,7 +184,7 @@ static int ether_get_avb_algo(struct net_device *ndev, return -EINVAL; } - if (copy_from_user(&avb_data, + if (copy_from_user(&ioctl_data.avb, (struct osi_core_avb_algorithm *)ifdata->ptr, sizeof(struct osi_core_avb_algorithm)) != 0U) { dev_err(pdata->dev, @@ -191,13 +192,14 @@ static int ether_get_avb_algo(struct net_device *ndev, return -EFAULT; } - ret = osi_get_avb(osi_core, &avb_data); + ioctl_data.cmd = OSI_CMD_GET_AVB; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret != 0) { dev_err(pdata->dev, "Failed to get AVB Struct info from registers\n"); return ret; } - if (copy_to_user(ifdata->ptr, &avb_data, + if (copy_to_user(ifdata->ptr, &ioctl_data.avb, sizeof(struct osi_core_avb_algorithm)) != 0U) { dev_err(pdata->dev, "%s: copy_to_user failed\n", __func__); return -EFAULT; @@ -224,7 +226,7 @@ static int ether_config_ptp_offload(struct ether_priv_data *pdata, struct ptp_offload_param param; unsigned int snap_type = 0x0; unsigned int master = 0x0; - struct osi_pto_config pto_config; + struct osi_ioctl ioctl_data = {}; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) struct timespec64 now; #else @@ -284,16 +286,15 @@ static int ether_config_ptp_offload(struct ether_priv_data *pdata, master = OSI_DISABLE; } - pto_config.en_dis = param.en_dis; - pto_config.snap_type = snap_type; - pto_config.master = master; - pto_config.domain_num = param.domain_num; - pto_config.mc_uc = param.mc_uc; + ioctl_data.pto_config.en_dis = param.en_dis; + ioctl_data.pto_config.snap_type = snap_type; + ioctl_data.pto_config.master = master; + ioctl_data.pto_config.domain_num = param.domain_num; + ioctl_data.pto_config.mc_uc = param.mc_uc; /* PTP port ID hard code to port 1 for POC */ - pto_config.portid = 0x1U; - - ret = osi_config_ptp_offload(pdata->osi_core, - &pto_config); + ioctl_data.pto_config.portid = 0x1U; + ioctl_data.cmd = OSI_CMD_CONFIG_PTP_OFFLOAD; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "%s: OSI function failed\n", __func__); } @@ -323,6 +324,8 @@ static int ether_config_arp_offload(struct ether_priv_data *pdata, { int ret = -EINVAL; struct arp_offload_param param; + struct osi_ioctl ioctl_data = {}; + /* TODO: Need Spin lock to prevent multiple apps from * requesting same ioctls to the same MAC instance */ @@ -343,8 +346,10 @@ static int ether_config_arp_offload(struct ether_priv_data *pdata, dev_err(pdata->dev, "%s: Invalid IP addr\n", __func__); return ret; } - ret = osi_config_arp_offload(pdata->osi_core, ifrd_p->if_flags, - param.ip_addr); + ioctl_data.cmd = OSI_CMD_ARP_OFFLOAD; + ioctl_data.arg1_u32 = ifrd_p->if_flags; + ioctl_data.arg7_u8_p = param.ip_addr; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); dev_err(pdata->dev, "ARP offload: %s : %s\n", ifrd_p->if_flags ? "Enable" : "Disable", ret ? "Failed" : "Success"); @@ -369,7 +374,7 @@ static int ether_config_frp_cmd(struct net_device *dev, { struct ether_priv_data *pdata = netdev_priv(dev); struct osi_core_priv_data *osi_core = pdata->osi_core; - struct osi_core_frp_cmd frp_cmd; + struct osi_ioctl ioctl_data = {}; int ret = -EINVAL; if (pdata->hw_feat.frp_sel == OSI_DISABLE) { @@ -383,14 +388,15 @@ static int ether_config_frp_cmd(struct net_device *dev, return ret; } - if (copy_from_user(&frp_cmd, + if (copy_from_user(&ioctl_data.frp_cmd, (struct osi_core_frp_cmd *)ifdata->ptr, sizeof(struct osi_core_frp_cmd)) != 0U) { dev_err(pdata->dev, "%s copy from user failed\n", __func__); return -EFAULT; } - return osi_configure_frp(osi_core, &frp_cmd); + ioctl_data.cmd = OSI_CMD_CONFIG_FRP; + return osi_handle_ioctl(osi_core, &ioctl_data); } /** @@ -447,7 +453,7 @@ static int ether_config_ip4_filters(struct net_device *dev, struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_l3_l4_filter *u_l3_filter = (struct osi_l3_l4_filter *)ifdata->ptr; - struct osi_l3_l4_filter l_l3_filter; + struct osi_ioctl ioctl_data = {}; unsigned int is_l4_filter = OSI_DISABLE; int ret = -EINVAL; @@ -462,20 +468,26 @@ static int ether_config_ip4_filters(struct net_device *dev, return ret; } - if (copy_from_user(&l_l3_filter, u_l3_filter, + if (copy_from_user(&ioctl_data.l3l4_filter, u_l3_filter, sizeof(struct osi_l3_l4_filter)) != 0U) { dev_err(pdata->dev, "%s copy from user failed\n", __func__); return -EFAULT; } - if (l_l3_filter.filter_no > (pdata->hw_feat.l3l4_filter_num - 1U)) { + if (ioctl_data.l3l4_filter.filter_no > + (pdata->hw_feat.l3l4_filter_num - 1U)) { dev_err(pdata->dev, "%d filter is not supported in the HW\n", - l_l3_filter.filter_no); + ioctl_data.l3l4_filter.filter_no); return ret; } - return osi_l3l4_filter(osi_core, l_l3_filter, OSI_IP4_FILTER, - OSI_DISABLE, OSI_CHAN_ANY, is_l4_filter); + ioctl_data.cmd = OSI_CMD_L3L4_FILTER; + ioctl_data.arg1_u32 = OSI_IP4_FILTER; + ioctl_data.arg2_u32 = OSI_DISABLE; + ioctl_data.arg3_u32 = OSI_CHAN_ANY; + ioctl_data.arg4_u32 = is_l4_filter; + + return osi_handle_ioctl(osi_core, &ioctl_data); } /** @@ -503,7 +515,7 @@ static int ether_config_ip6_filters(struct net_device *dev, struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_l3_l4_filter *u_l3_filter = (struct osi_l3_l4_filter *)ifdata->ptr; - struct osi_l3_l4_filter l_l3_filter; + struct osi_ioctl ioctl_data = {}; unsigned int is_l4_filter = OSI_DISABLE; int ret = -EINVAL; @@ -518,20 +530,26 @@ static int ether_config_ip6_filters(struct net_device *dev, return ret; } - if (copy_from_user(&l_l3_filter, u_l3_filter, + if (copy_from_user(&ioctl_data.l3l4_filter, u_l3_filter, sizeof(struct osi_l3_l4_filter)) != 0U) { dev_err(pdata->dev, "%s copy from user failed\n", __func__); return -EFAULT; } - if (l_l3_filter.filter_no > (pdata->hw_feat.l3l4_filter_num - 1U)) { + if (ioctl_data.l3l4_filter.filter_no > + (pdata->hw_feat.l3l4_filter_num - 1U)) { dev_err(pdata->dev, "%d filter is not supported in the HW\n", - l_l3_filter.filter_no); + ioctl_data.l3l4_filter.filter_no); return ret; } - return osi_l3l4_filter(osi_core, l_l3_filter, OSI_IP6_FILTER, - OSI_DISABLE, OSI_CHAN_ANY, is_l4_filter); + ioctl_data.cmd = OSI_CMD_L3L4_FILTER; + ioctl_data.arg1_u32 = OSI_IP6_FILTER; + ioctl_data.arg2_u32 = OSI_DISABLE; + ioctl_data.arg3_u32 = OSI_CHAN_ANY; + ioctl_data.arg4_u32 = is_l4_filter; + + return osi_handle_ioctl(osi_core, &ioctl_data); } /** @@ -562,7 +580,7 @@ static int ether_config_tcp_udp_filters(struct net_device *dev, struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_l3_l4_filter *u_l4_filter = (struct osi_l3_l4_filter *)ifdata->ptr; - struct osi_l3_l4_filter l_l4_filter; + struct osi_ioctl ioctl_data = {}; unsigned int is_l4_filter = OSI_ENABLE; int ret = -EINVAL; @@ -578,20 +596,26 @@ static int ether_config_tcp_udp_filters(struct net_device *dev, return ret; } - if (copy_from_user(&l_l4_filter, u_l4_filter, + if (copy_from_user(&ioctl_data.l3l4_filter, u_l4_filter, sizeof(struct osi_l3_l4_filter)) != 0U) { dev_err(pdata->dev, "%s copy from user failed", __func__); return -EFAULT; } - if (l_l4_filter.filter_no > (pdata->hw_feat.l3l4_filter_num - 1U)) { + if (ioctl_data.l3l4_filter.filter_no > + (pdata->hw_feat.l3l4_filter_num - 1U)) { dev_err(pdata->dev, "%d filter is not supported in the HW\n", - l_l4_filter.filter_no); + ioctl_data.l3l4_filter.filter_no); return ret; } - return osi_l3l4_filter(osi_core, l_l4_filter, tcp_udp, - OSI_DISABLE, OSI_CHAN_ANY, is_l4_filter); + ioctl_data.cmd = OSI_CMD_L3L4_FILTER; + ioctl_data.arg1_u32 = tcp_udp; + ioctl_data.arg2_u32 = OSI_DISABLE; + ioctl_data.arg3_u32 = OSI_CHAN_ANY; + ioctl_data.arg4_u32 = is_l4_filter; + + return osi_handle_ioctl(osi_core, &ioctl_data); } /** @@ -617,7 +641,7 @@ static int ether_config_vlan_filter(struct net_device *dev, struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_vlan_filter *u_vlan_filter = (struct osi_vlan_filter *)ifdata->ptr; - struct osi_vlan_filter l_vlan_filter; + struct osi_ioctl ioctl_data = {}; int ret = -EINVAL; if (ifdata->ptr == NULL) { @@ -626,23 +650,23 @@ static int ether_config_vlan_filter(struct net_device *dev, return ret; } - if (copy_from_user(&l_vlan_filter, u_vlan_filter, + if (copy_from_user(&ioctl_data.vlan_filter, u_vlan_filter, sizeof(struct osi_vlan_filter)) != 0U) { dev_err(pdata->dev, "%s copy from user failed", __func__); return -EFAULT; } /*0 - perfect and 1 - hash filtering */ - if (l_vlan_filter.perfect_hash == OSI_HASH_FILTER_MODE) { + if (ioctl_data.vlan_filter.perfect_hash == OSI_HASH_FILTER_MODE) { dev_err(pdata->dev, "VLAN HASH filtering is not supported\n"); return ret; } - ret = osi_config_vlan_filtering(osi_core, l_vlan_filter.filter_enb_dis, - l_vlan_filter.perfect_hash, - l_vlan_filter.perfect_inverse_match); + ioctl_data.cmd = OSI_CMD_VLAN_FILTER; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret == 0) { - pdata->vlan_hash_filtering = l_vlan_filter.perfect_hash; + pdata->vlan_hash_filtering = + ioctl_data.vlan_filter.perfect_hash; } return ret; @@ -718,10 +742,10 @@ static int ether_config_l2_da_filter(struct net_device *dev, struct osi_l2_da_filter *u_l2_da_filter = (struct osi_l2_da_filter *)ifdata->ptr; struct osi_l2_da_filter l_l2_da_filter; - struct osi_filter filter; + struct osi_ioctl ioctl_data = {}; int ret = -EINVAL; - memset(&filter, 0x0, sizeof(struct osi_filter)); + memset(&ioctl_data.l2_filter, 0x0, sizeof(struct osi_filter)); if (ifdata->ptr == NULL) { dev_err(pdata->dev, "%s: Invalid data for priv ioctl %d\n", @@ -747,12 +771,13 @@ static int ether_config_l2_da_filter(struct net_device *dev, /* configure L2 DA perfect/inverse_matching */ if (l_l2_da_filter.perfect_inverse_match == OSI_ENABLE) { - filter.oper_mode |= OSI_OPER_EN_L2_DA_INV; + ioctl_data.l2_filter.oper_mode |= OSI_OPER_EN_L2_DA_INV; } else { - filter.oper_mode |= OSI_OPER_DIS_L2_DA_INV; + ioctl_data.l2_filter.oper_mode |= OSI_OPER_DIS_L2_DA_INV; } - ret = osi_l2_filter(osi_core, &filter); + ioctl_data.cmd = OSI_CMD_L2_FILTER; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret != 0) { dev_err(pdata->dev, "setting L2_DA_INV failed\n"); } @@ -780,14 +805,17 @@ static int ether_reg_save_restore(struct net_device *ndev, { struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; if (flags == OSI_ENABLE) { - if (osi_restore_registers(osi_core)) { + ioctl_data.cmd = OSI_CMD_RESTORE_REGISTER; + if (osi_handle_ioctl(osi_core, &ioctl_data)) { dev_err(pdata->dev, "Restore MAC registers fail\n"); return -EBUSY; } } else if (flags == OSI_DISABLE) { - if (osi_save_registers(osi_core)) { + ioctl_data.cmd = OSI_CMD_SAVE_REGISTER; + if (osi_handle_ioctl(osi_core, &ioctl_data)) { dev_err(pdata->dev, "Save MAC registers fail\n"); return -EBUSY; } @@ -822,6 +850,7 @@ static int ether_config_loopback_mode(struct net_device *ndev, struct ether_priv_data *pdata = netdev_priv(ndev); struct phy_device *phydev = ndev->phydev; struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; int ret = 0; if ((flags && (pdata->mac_loopback_mode == OSI_ENABLE)) || @@ -839,7 +868,10 @@ static int ether_config_loopback_mode(struct net_device *ndev, */ netif_carrier_on(ndev); } - ret = osi_config_mac_loopback(osi_core, OSI_ENABLE); + + ioctl_data.arg1_u32 = OSI_ENABLE; + ioctl_data.cmd = OSI_CMD_MAC_LB; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "Failed to enable MAC Loopback\n"); @@ -856,7 +888,10 @@ static int ether_config_loopback_mode(struct net_device *ndev, */ netif_carrier_off(ndev); } - ret = osi_config_mac_loopback(osi_core, OSI_DISABLE); + + ioctl_data.arg1_u32 = OSI_DISABLE; + ioctl_data.cmd = OSI_CMD_MAC_LB; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "Failed to disable MAC Loopback\n"); @@ -889,13 +924,14 @@ static int ether_config_ptp_rxq(struct net_device *ndev, { struct ether_priv_data *pdata = netdev_priv(ndev); struct osi_core_priv_data *osi_core = pdata->osi_core; - struct osi_rxq_route rxq_route; + struct osi_ioctl ioctl_data = {}; /* Fill PTP RX queue route values and call osi_rxq_route */ - rxq_route.route_type = OSI_RXQ_ROUTE_PTP; - rxq_route.enable = OSI_ENABLE; - rxq_route.idx = flags; - return osi_rxq_route(osi_core, &rxq_route); + ioctl_data.rxq_route.route_type = OSI_RXQ_ROUTE_PTP; + ioctl_data.rxq_route.enable = OSI_ENABLE; + ioctl_data.rxq_route.idx = flags; + ioctl_data.cmd = OSI_CMD_PTP_RXQ_ROUTE; + return osi_handle_ioctl(osi_core, &ioctl_data); } /** @@ -920,7 +956,7 @@ static int ether_config_est(struct net_device *dev, struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_est_config *u_est_cfg = (struct osi_est_config *)ifdata->ptr; - struct osi_est_config l_est_cfg; + struct osi_ioctl ioctl_data = {}; int ret = -EINVAL; if (ifdata->ptr == NULL) { @@ -929,7 +965,7 @@ static int ether_config_est(struct net_device *dev, return ret; } - if (copy_from_user(&l_est_cfg, u_est_cfg, + if (copy_from_user(&ioctl_data.est, u_est_cfg, sizeof(struct osi_est_config)) != 0U) { return -EFAULT; } @@ -938,7 +974,8 @@ static int ether_config_est(struct net_device *dev, dev_err(pdata->dev, "HW doesn't support EST\n"); } else { - ret = osi_hw_config_est(osi_core, &l_est_cfg); + ioctl_data.cmd = OSI_CMD_CONFIG_EST; + ret = osi_handle_ioctl(osi_core, &ioctl_data); } return ret; @@ -966,7 +1003,7 @@ static int ether_config_fpe(struct net_device *dev, struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_fpe_config *u_fpe_cfg = (struct osi_fpe_config *)ifdata->ptr; - struct osi_fpe_config l_fpe_cfg; + struct osi_ioctl ioctl_data = {}; int ret = -EINVAL; if (ifdata->ptr == NULL) { @@ -975,7 +1012,7 @@ static int ether_config_fpe(struct net_device *dev, return ret; } - if (copy_from_user(&l_fpe_cfg, u_fpe_cfg, + if (copy_from_user(&ioctl_data.fpe, u_fpe_cfg, sizeof(struct osi_fpe_config)) != 0U) { return -EFAULT; } @@ -984,7 +1021,8 @@ static int ether_config_fpe(struct net_device *dev, dev_err(pdata->dev, "HW doesn't support FPE\n"); } else { - ret = osi_hw_config_fpe(osi_core, &l_fpe_cfg); + ioctl_data.cmd = OSI_CMD_CONFIG_FPE; + ret = osi_handle_ioctl(osi_core, &ioctl_data); } return ret; diff --git a/drivers/net/ethernet/nvidia/nvethernet/ptp.c b/drivers/net/ethernet/nvidia/nvethernet/ptp.c index cb649254..2206d23a 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ptp.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ptp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -75,12 +75,15 @@ static int ether_adjust_time(struct ptp_clock_info *ptp, s64 nsec_delta) struct ether_priv_data, ptp_clock_ops); struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; unsigned long flags; int ret = -1; raw_spin_lock_irqsave(&pdata->ptp_lock, flags); - ret = osi_adjust_time(osi_core, nsec_delta); + ioctl_data.cmd = OSI_CMD_ADJ_TIME; + ioctl_data.arg8_64 = nsec_delta; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "%s:failed to adjust time with reason %d\n", @@ -110,12 +113,15 @@ static int ether_adjust_freq(struct ptp_clock_info *ptp, s32 ppb) struct ether_priv_data, ptp_clock_ops); struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; unsigned long flags; int ret = -1; raw_spin_lock_irqsave(&pdata->ptp_lock, flags); - ret = osi_adjust_freq(osi_core, ppb); + ioctl_data.cmd = OSI_CMD_ADJ_FREQ; + ioctl_data.arg6_32 = ppb; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "%s:failed to adjust frequency with reason code %d\n", @@ -185,12 +191,16 @@ static int ether_set_time(struct ptp_clock_info *ptp, struct ether_priv_data, ptp_clock_ops); struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; unsigned long flags; int ret = -1; raw_spin_lock_irqsave(&pdata->ptp_lock, flags); - ret = osi_set_systime_to_mac(osi_core, ts->tv_sec, ts->tv_nsec); + ioctl_data.cmd = OSI_CMD_SET_SYSTOHW_TIME; + ioctl_data.arg1_u32 = ts->tv_sec; + ioctl_data.arg2_u32 = ts->tv_nsec; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "%s:failed to set system time with reason %d\n", @@ -270,21 +280,24 @@ static void ether_config_slot_function(struct ether_priv_data *pdata, u32 set) struct osi_dma_priv_data *osi_dma = pdata->osi_dma; struct osi_core_priv_data *osi_core = pdata->osi_core; unsigned int ret, i, chan, qinx; - struct osi_core_avb_algorithm avb; + struct osi_ioctl ioctl_data = {}; /* Configure TXQ AVB mode */ for (i = 0; i < osi_dma->num_dma_chans; i++) { chan = osi_dma->dma_chans[i]; if (osi_dma->slot_enabled[chan] == OSI_ENABLE) { /* Set TXQ AVB info */ - memset(&avb, 0, sizeof(struct osi_core_avb_algorithm)); + memset(&ioctl_data.avb, 0, + sizeof(struct osi_core_avb_algorithm)); qinx = osi_core->mtl_queues[i]; - avb.qindex = qinx; - avb.algo = OSI_MTL_TXQ_AVALG_SP; - avb.oper_mode = (set == OSI_ENABLE) ? - OSI_MTL_QUEUE_AVB : - OSI_MTL_QUEUE_ENABLE; - ret = osi_set_avb(osi_core, &avb); + ioctl_data.avb.qindex = qinx; + ioctl_data.avb.algo = OSI_MTL_TXQ_AVALG_SP; + ioctl_data.avb.oper_mode = (set == OSI_ENABLE) ? + OSI_MTL_QUEUE_AVB : + OSI_MTL_QUEUE_ENABLE; + + ioctl_data.cmd = OSI_CMD_SET_AVB; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret != 0) { dev_err(pdata->dev, "Failed to set TXQ:%d AVB info\n", @@ -303,8 +316,10 @@ int ether_handle_hwtstamp_ioctl(struct ether_priv_data *pdata, { struct osi_core_priv_data *osi_core = pdata->osi_core; struct osi_dma_priv_data *osi_dma = pdata->osi_dma; + struct osi_ioctl ioctl_data = {}; struct hwtstamp_config config; unsigned int hwts_rx_en = 1; + int ret; #if KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE struct timespec now; #else @@ -456,7 +471,13 @@ int ether_handle_hwtstamp_ioctl(struct ether_priv_data *pdata, if (!pdata->hwts_tx_en && !hwts_rx_en) { /* disable the PTP configuration */ - osi_ptp_configuration(osi_core, OSI_DISABLE); + ioctl_data.arg1_u32 = OSI_DISABLE; + ioctl_data.cmd = OSI_CMD_CONFIG_PTP; + ret = osi_handle_ioctl(osi_core, &ioctl_data); + if (ret < 0) { + dev_err(pdata->dev, "Failure to disable CONFIG_PTP\n"); + return -EFAULT; + } ether_config_slot_function(pdata, OSI_DISABLE); } else { /* Store default PTP clock frequency, so that we @@ -474,7 +495,13 @@ int ether_handle_hwtstamp_ioctl(struct ether_priv_data *pdata, /* one nsec accuracy */ osi_core->ptp_config.one_nsec_accuracy = OSI_ENABLE; /* Enable the PTP configuration */ - osi_ptp_configuration(osi_core, OSI_ENABLE); + ioctl_data.arg1_u32 = OSI_ENABLE; + ioctl_data.cmd = OSI_CMD_CONFIG_PTP; + ret = osi_handle_ioctl(osi_core, &ioctl_data); + if (ret < 0) { + dev_err(pdata->dev, "Failure to enable CONFIG_PTP\n"); + return -EFAULT; + } #ifdef CONFIG_TEGRA_PTP_NOTIFIER /* Register broadcasting MAC timestamp to clients */ tegra_register_hwtime_source(ether_get_ptptime, pdata); diff --git a/drivers/net/ethernet/nvidia/nvethernet/selftests.c b/drivers/net/ethernet/nvidia/nvethernet/selftests.c index 5140b00c..1844566b 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/selftests.c +++ b/drivers/net/ethernet/nvidia/nvethernet/selftests.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -309,13 +309,15 @@ static int ether_test_phy_loopback(struct ether_priv_data *pdata) static int ether_test_mmc_counters(struct ether_priv_data *pdata) { struct osi_core_priv_data *osi_core = pdata->osi_core; + struct osi_ioctl ioctl_data = {}; unsigned int mmc_tx_framecount_g = 0; unsigned int mmc_rx_framecount_gb = 0; unsigned int mmc_rx_ipv4_gd = 0; unsigned int mmc_rx_udp_gd = 0; int ret = 0; - ret = osi_read_mmc(osi_core); + ioctl_data.cmd = OSI_CMD_READ_MMC; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) return ret; @@ -327,8 +329,8 @@ static int ether_test_mmc_counters(struct ether_priv_data *pdata) ret = ether_test_mac_loopback(pdata); if (ret < 0) return ret; - - ret = osi_read_mmc(osi_core); + ioctl_data.cmd = OSI_CMD_READ_MMC; + ret = osi_handle_ioctl(osi_core, &ioctl_data); if (ret < 0) return ret; @@ -382,6 +384,7 @@ void ether_selftest_run(struct net_device *dev, struct ethtool_test *etest, u64 *buf) { struct ether_priv_data *pdata = netdev_priv(dev); + struct osi_ioctl ioctl_data = {}; int count = ether_selftest_get_count(pdata); int carrier = netif_carrier_ok(dev); int i, ret; @@ -407,9 +410,12 @@ void ether_selftest_run(struct net_device *dev, break; /* Fallthrough */ case ETHER_LOOPBACK_MAC: - if (pdata->osi_core) - ret = osi_config_mac_loopback(pdata->osi_core, - OSI_ENABLE); + if (pdata->osi_core) { + ioctl_data.cmd = OSI_CMD_MAC_LB; + ioctl_data.arg1_u32 = OSI_ENABLE; + ret = osi_handle_ioctl(pdata->osi_core, + &ioctl_data); + } break; default: ret = -EOPNOTSUPP; @@ -436,9 +442,12 @@ void ether_selftest_run(struct net_device *dev, break; /* Fallthrough */ case ETHER_LOOPBACK_MAC: - if (pdata->osi_core) - ret = osi_config_mac_loopback(pdata->osi_core, - OSI_DISABLE); + if (pdata->osi_core) { + ioctl_data.cmd = OSI_CMD_MAC_LB; + ioctl_data.arg1_u32 = OSI_DISABLE; + ret = osi_handle_ioctl(pdata->osi_core, + &ioctl_data); + } if (!ret) break; default: diff --git a/drivers/net/ethernet/nvidia/nvethernet/sysfs.c b/drivers/net/ethernet/nvidia/nvethernet/sysfs.c index 7c62e081..5d56dbe4 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/sysfs.c +++ b/drivers/net/ethernet/nvidia/nvethernet/sysfs.c @@ -63,6 +63,7 @@ static ssize_t ether_mac_loopback_store(struct device *dev, struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev); struct phy_device *phydev = ndev->phydev; struct ether_priv_data *pdata = netdev_priv(ndev); + struct osi_ioctl ioctl_data = {}; int ret = -1; /* Interface is not up so LB mode can't be set */ @@ -81,7 +82,9 @@ static ssize_t ether_mac_loopback_store(struct device *dev, netif_carrier_on(ndev); } /* Enabling the MAC Loopback Mode */ - ret = osi_config_mac_loopback(pdata->osi_core, OSI_ENABLE); + ioctl_data.arg1_u32 = OSI_ENABLE; + ioctl_data.cmd = OSI_CMD_MAC_LB; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "Enabling MAC Loopback failed\n"); } else { @@ -98,7 +101,9 @@ static ssize_t ether_mac_loopback_store(struct device *dev, netif_carrier_off(ndev); } /* Disabling the MAC Loopback Mode */ - ret = osi_config_mac_loopback(pdata->osi_core, OSI_DISABLE); + ioctl_data.arg1_u32 = OSI_DISABLE; + ioctl_data.cmd = OSI_CMD_MAC_LB; + ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data); if (ret < 0) { dev_err(pdata->dev, "Disabling MAC Loopback failed\n"); } else {