Revert "nvethernet: use single API for ioctl"

This reverts commit 5bbeaa61e89ee6375a15020f2ef533b5ed66d628.
This commit is contained in:
Bhadram Varka
2021-03-26 16:54:06 +05:30
committed by Revanth Kumar Uppala
parent 8c8eceeeb7
commit 93924a32f3
6 changed files with 177 additions and 352 deletions

View File

@@ -34,11 +34,9 @@ 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;
ioctl_data.cmd = OSI_CMD_READ_MMC;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_read_mmc(osi_core);
if (ret < 0) {
dev_err(pdata->dev, "failed to read MMC counters %s\n",
__func__);
@@ -242,7 +240,6 @@ 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 */
@@ -256,11 +253,9 @@ int ether_conf_eee(struct ether_priv_data *pdata, unsigned int tx_lpi_enable)
}
/* Enable EEE */
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);
ret = osi_configure_eee(pdata->osi_core,
enable,
pdata->tx_lpi_timer);
/* Return current status of EEE based on OSI API success/failure */
if (ret != 0) {
if (enable) {
@@ -296,7 +291,6 @@ 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) {
@@ -306,33 +300,20 @@ 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)) {
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;
}
osi_configure_flow_control(pdata->osi_core,
pdata->osi_core->flow_ctrl);
}
if (phydev->duplex != pdata->oldduplex) {
new_state = 1;
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;
}
osi_set_mode(pdata->osi_core, phydev->duplex);
pdata->oldduplex = phydev->duplex;
}
if (phydev->speed != pdata->speed) {
new_state = 1;
speed_changed = 1;
ioctl_data.cmd = OSI_CMD_SET_SPEED;
ioctl_data.arg6_32 = phydev->speed;
ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data);
ret = osi_set_speed(pdata->osi_core, phydev->speed);
if (ret < 0) {
netdev_err(dev, "Failed to set speed\n");
return;
@@ -370,12 +351,9 @@ static void ether_adjust_link(struct net_device *dev)
(phydev->speed ==
SPEED_100) ? 25000 * 1000 : 125000 * 1000);
if (phydev->speed != SPEED_10) {
ioctl_data.cmd = OSI_CMD_PAD_CALIBRATION;
if (osi_handle_ioctl(pdata->osi_core, &ioctl_data) <
0) {
if (osi_pad_calibrate(pdata->osi_core) < 0)
dev_err(pdata->dev,
"failed to do pad caliberation\n");
}
}
}
@@ -647,15 +625,8 @@ 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;
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__);
}
osi_common_isr(pdata->osi_core);
return IRQ_HANDLED;
}
@@ -1536,8 +1507,6 @@ 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
@@ -1548,8 +1517,7 @@ static int ether_set_cur_therm_state(struct thermal_cooling_device *tcd,
atomic_set(&pdata->therm_state, state);
ioctl_data.cmd = OSI_CMD_PAD_CALIBRATION;
if (osi_handle_ioctl(pdata->osi_core, &ioctl_data) < 0) {
if (osi_pad_calibrate(pdata->osi_core) < 0) {
dev_err(dev, "Therm state changed, failed pad calibration\n");
return -1;
}
@@ -1648,7 +1616,6 @@ 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 */
@@ -1674,8 +1641,7 @@ static int ether_open(struct net_device *dev)
}
}
ioctl_data.cmd = OSI_CMD_POLL_FOR_MAC_RST;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_poll_for_mac_reset_complete(osi_core);
if (ret < 0) {
dev_err(&dev->dev, "failed to poll MAC Software reset\n");
goto err_poll_swr;
@@ -1757,14 +1723,8 @@ static int ether_open(struct net_device *dev)
ether_init_eee_params(pdata);
/* Start the MAC */
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;
}
osi_start_mac(pdata->osi_core);
/* start PHY */
phy_start(pdata->phydev);
@@ -2309,7 +2269,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_ioctl *ioctl_data)
struct osi_filter *filter)
{
struct ether_priv_data *pdata = netdev_priv(dev);
struct osi_core_priv_data *osi_core = pdata->osi_core;
@@ -2317,56 +2277,53 @@ static int ether_prepare_mc_list(struct net_device *dev,
unsigned int i = 1;
int ret = -1;
if (ioctl_data == NULL) {
dev_err(pdata->dev, "ioctl_data is NULL\n");
if (filter == NULL) {
dev_err(pdata->dev, "filter is NULL\n");
return ret;
}
memset(&ioctl_data->l2_filter, 0x0, sizeof(struct osi_filter));
memset(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");
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);
filter->oper_mode = (OSI_OPER_EN_PERFECT |
OSI_OPER_DIS_PROMISC |
OSI_OPER_DIS_ALLMULTI);
return osi_l2_filter(osi_core, filter);
/* 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 */
ioctl_data->l2_filter.oper_mode = (OSI_OPER_DIS_PERFECT |
OSI_OPER_EN_PROMISC |
OSI_OPER_DIS_ALLMULTI);
filter->oper_mode = (OSI_OPER_DIS_PERFECT |
OSI_OPER_EN_PROMISC |
OSI_OPER_DIS_ALLMULTI);
dev_dbg(pdata->dev, "enabling Promiscuous mode\n");
ioctl_data->cmd = OSI_CMD_L2_FILTER;
return osi_handle_ioctl(osi_core, ioctl_data);
return osi_l2_filter(osi_core, filter);
} 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);
ioctl_data->l2_filter.oper_mode = (OSI_OPER_EN_PERFECT |
OSI_OPER_ADDR_UPDATE |
OSI_OPER_DIS_PROMISC |
OSI_OPER_DIS_ALLMULTI);
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]);
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);
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);
if (ret < 0) {
dev_err(pdata->dev, "issue in creating mc list\n");
pdata->last_filter_index = i - 1;
@@ -2401,7 +2358,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_ioctl *ioctl_data)
struct osi_filter *filter)
{
struct ether_priv_data *pdata = netdev_priv(dev);
struct osi_core_priv_data *osi_core = pdata->osi_core;
@@ -2410,54 +2367,51 @@ static int ether_prepare_uc_list(struct net_device *dev,
struct netdev_hw_addr *ha;
int ret = -1;
if (ioctl_data == NULL) {
dev_err(pdata->dev, "ioctl_data is NULL\n");
if (filter == NULL) {
dev_err(pdata->dev, "filter is NULL\n");
return ret;
}
memset(&ioctl_data->l2_filter, 0x0, sizeof(struct osi_filter));
memset(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 */
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);
filter->oper_mode = (OSI_OPER_EN_PERFECT |
OSI_OPER_DIS_PROMISC |
OSI_OPER_DIS_ALLMULTI);
return osi_l2_filter(osi_core, filter);
} else if (netdev_uc_count(dev) > (pdata->num_mac_addr_regs - i)) {
/* switch to PROMISCUOUS mode */
ioctl_data->l2_filter.oper_mode = (OSI_OPER_DIS_PERFECT |
OSI_OPER_EN_PROMISC |
OSI_OPER_DIS_ALLMULTI);
filter->oper_mode = (OSI_OPER_DIS_PERFECT |
OSI_OPER_EN_PROMISC |
OSI_OPER_DIS_ALLMULTI);
dev_dbg(pdata->dev, "enabling Promiscuous mode\n");
ioctl_data->cmd = OSI_CMD_L2_FILTER;
return osi_handle_ioctl(osi_core, ioctl_data);
return osi_l2_filter(osi_core, filter);
} else {
dev_dbg(pdata->dev,
"select PERFECT FILTERING for uc addresses: uc_count = %d\n",
netdev_uc_count(dev));
ioctl_data->l2_filter.oper_mode = (OSI_OPER_EN_PERFECT |
OSI_OPER_ADDR_UPDATE |
OSI_OPER_DIS_PROMISC |
OSI_OPER_DIS_ALLMULTI);
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]);
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);
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);
if (ret < 0) {
dev_err(pdata->dev, "issue in creating uc list\n");
pdata->last_filter_index = i - 1;
@@ -2490,23 +2444,20 @@ static 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(&ioctl_data.l2_filter, 0x0, sizeof(struct osi_filter));
memset(&filter, 0x0, sizeof(struct osi_filter));
if ((dev->flags & IFF_PROMISC) == IFF_PROMISC) {
if (pdata->promisc_mode == OSI_ENABLE) {
ioctl_data.l2_filter.oper_mode =
(OSI_OPER_DIS_PERFECT |
OSI_OPER_EN_PROMISC |
OSI_OPER_DIS_ALLMULTI);
filter.oper_mode = (OSI_OPER_DIS_PERFECT |
OSI_OPER_EN_PROMISC |
OSI_OPER_DIS_ALLMULTI);
dev_dbg(pdata->dev, "enabling Promiscuous mode\n");
ioctl_data.cmd = OSI_CMD_L2_FILTER;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_l2_filter(osi_core, &filter);
if (ret < 0) {
dev_err(pdata->dev,
"Setting Promiscuous mode failed\n");
@@ -2518,19 +2469,18 @@ static void ether_set_rx_mode(struct net_device *dev)
return;
} else if ((dev->flags & IFF_ALLMULTI) == IFF_ALLMULTI) {
ioctl_data.l2_filter.oper_mode = (OSI_OPER_EN_ALLMULTI |
OSI_OPER_DIS_PERFECT |
OSI_OPER_DIS_PROMISC);
filter.oper_mode = (OSI_OPER_EN_ALLMULTI |
OSI_OPER_DIS_PERFECT |
OSI_OPER_DIS_PROMISC);
dev_dbg(pdata->dev, "pass all multicast pkt\n");
ioctl_data.cmd = OSI_CMD_L2_FILTER;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_l2_filter(osi_core, &filter);
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, &ioctl_data) != 0) {
if (ether_prepare_mc_list(dev, &filter) != 0) {
dev_err(pdata->dev, "Setting MC address failed\n");
}
} else {
@@ -2538,23 +2488,22 @@ static void ether_set_rx_mode(struct net_device *dev)
}
if (!netdev_uc_empty(dev)) {
if (ether_prepare_uc_list(dev, &ioctl_data) != 0) {
if (ether_prepare_uc_list(dev, &filter) != 0) {
dev_err(pdata->dev, "Setting UC address failed\n");
}
}
/* Reset the filter structure to avoid any old value */
memset(&ioctl_data.l2_filter, 0x0, sizeof(struct osi_filter));
memset(&filter, 0x0, sizeof(struct osi_filter));
/* invalidate remaining ealier address */
for (i = pdata->last_filter_index + 1; i <= last_index; i++) {
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);
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;
ret = osi_l2_filter(osi_core, &filter);
if (ret < 0) {
dev_err(pdata->dev, "Invalidating expired L2 filter failed\n");
return;
@@ -2726,7 +2675,6 @@ 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;
@@ -2734,18 +2682,16 @@ 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)) {
ioctl_data.cmd = OSI_CMD_RXCSUM_OFFLOAD;
ioctl_data.arg1_u32 = OSI_ENABLE;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_config_rxcsum_offload(osi_core,
OSI_ENABLE);
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)) {
ioctl_data.cmd = OSI_CMD_RXCSUM_OFFLOAD;
ioctl_data.arg1_u32 = OSI_DISABLE;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_config_rxcsum_offload(osi_core,
OSI_DISABLE);
dev_info(pdata->dev, "Rx Csum offload: Disable: %s\n",
ret ? "Failed" : "Success");
pdata->hw_feat_cur_state &= ~NETIF_F_RXCSUM;
@@ -2779,16 +2725,13 @@ 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;
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 {
ioctl_data.cmd = OSI_CMD_UPDATE_VLAN_ID;
ioctl_data.arg1_u32 = vid;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_update_vlan_id(osi_core, vid);
}
return ret;
@@ -2818,7 +2761,6 @@ 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;
struct osi_ioctl ioctl_data = {};
int ret = -1;
if (!netif_running(ndev)) {
@@ -2829,12 +2771,10 @@ 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 {
ioctl_data.cmd = OSI_CMD_UPDATE_VLAN_ID;
/* By default, receive only VLAN pkt with VID = 1 because
* writing 0 will pass all VLAN pkt
*/
ioctl_data.arg1_u32 = 0x1U;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_update_vlan_id(osi_core, 0x1U);
}
return ret;
@@ -3557,7 +3497,6 @@ 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) {
@@ -3627,19 +3566,10 @@ static int ether_configure_car(struct platform_device *pdev,
}
csr_clk_rate = clk_get_rate(pdata->axi_cbb_clk);
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;
}
osi_set_mdc_clk_rate(pdata->osi_core, csr_clk_rate);
return ret;
err_mdc:
if (pdata->mac_rst) {
reset_control_assert(pdata->mac_rst);
}
err_rst:
ether_disable_clks(pdata);
err_enable_clks:
@@ -4314,7 +4244,6 @@ 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;
@@ -4391,23 +4320,18 @@ static int ether_probe(struct platform_device *pdev)
goto err_init_res;
}
ioctl_data.cmd = OSI_CMD_GET_MAC_VER;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_get_mac_version(osi_core, &osi_core->mac_ver);
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;
ioctl_data.cmd = OSI_CMD_GET_HW_FEAT;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_get_hw_features(osi_core, &pdata->hw_feat);
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));
/* Set netdev features based on hw features */
ether_set_ndev_features(ndev, pdata);
@@ -4550,7 +4474,6 @@ 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))
@@ -4560,8 +4483,7 @@ static int ether_suspend_noirq(struct device *dev)
* current configuration so that SW view of HW is maintained across
* suspend/resume.
*/
ioctl_data.cmd = OSI_CMD_SAVE_REGISTER;
if (osi_handle_ioctl(osi_core, &ioctl_data)) {
if (osi_save_registers(osi_core)) {
dev_err(dev, "Failed to backup MAC core registers\n");
return -EBUSY;
}
@@ -4617,7 +4539,6 @@ 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) {
@@ -4628,15 +4549,13 @@ static int ether_resume(struct ether_priv_data *pdata)
}
}
ioctl_data.cmd = OSI_CMD_POLL_FOR_MAC_RST;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_poll_for_mac_reset_complete(osi_core);
if (ret < 0) {
dev_err(dev, "failed to poll mac software reset\n");
return ret;
}
ioctl_data.cmd = OSI_CMD_PAD_CALIBRATION;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_pad_calibrate(osi_core);
if (ret < 0) {
dev_err(dev, "failed to do pad caliberation\n");
return ret;
@@ -4673,14 +4592,7 @@ static int ether_resume(struct ether_priv_data *pdata)
/* enable NAPI */
ether_napi_enable(pdata);
/* start the mac */
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;
}
osi_start_mac(osi_core);
if (pdata->phydev && !(device_may_wakeup(&ndev->dev))) {
/* configure phy init */
phy_init_hw(pdata->phydev);
@@ -4693,8 +4605,7 @@ 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:
@@ -4719,7 +4630,6 @@ 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))
@@ -4745,8 +4655,7 @@ static int ether_resume_noirq(struct device *dev)
* Restore the backup of the MAC configuration to maintain consistency
* between SW/HW state.
*/
ioctl_data.cmd = OSI_CMD_RESTORE_REGISTER;
if (osi_handle_ioctl(osi_core, &ioctl_data)) {
if (osi_restore_registers(osi_core)) {
//TODO: Ideally, undo MAC init/resume & return.
dev_err(dev, "Failed to restore MAC core registers\n");
return -EIO;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2020, 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,
@@ -313,7 +313,6 @@ 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;
@@ -323,8 +322,7 @@ static void ether_get_ethtool_stats(struct net_device *dev,
}
if (pdata->hw_feat.mmc_sel == 1U) {
ioctl_data.cmd = OSI_CMD_READ_MMC;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_read_mmc(osi_core);
if (ret == -1) {
dev_err(pdata->dev, "Error in reading MMC counter\n");
return;
@@ -542,7 +540,6 @@ 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;
@@ -589,13 +586,8 @@ static int ether_set_pauseparam(struct net_device *ndev,
}
/* Configure current flow control settings */
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;
}
ret = osi_configure_flow_control(pdata->osi_core,
pdata->osi_core->flow_ctrl);
return ret;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2019-2020, 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(&ioctl_data.avb,
if (copy_from_user(&l_avb_struct,
(struct osi_core_avb_algorithm *)ifdata->ptr,
sizeof(struct osi_core_avb_algorithm)) != 0U) {
dev_err(pdata->dev,
@@ -142,17 +142,16 @@ static int ether_set_avb_algo(struct net_device *ndev,
}
/* Check AVB mode disable on slot function enable */
tx_ring = osi_dma->tx_ring[ioctl_data.avb.qindex];
tx_ring = osi_dma->tx_ring[l_avb_struct.qindex];
if (tx_ring && tx_ring->slot_check == OSI_ENABLE &&
ioctl_data.avb.oper_mode == OSI_MTL_QUEUE_ENABLE) {
l_avb_struct.oper_mode == OSI_MTL_QUEUE_ENABLE) {
dev_err(pdata->dev,
"Can't disable queue:%d AVB mode when slot is enabled",
ioctl_data.avb.qindex);
l_avb_struct.qindex);
return -EINVAL;
}
ioctl_data.cmd = OSI_CMD_SET_AVB;
return osi_handle_ioctl(osi_core, &ioctl_data);
return osi_set_avb(osi_core, &l_avb_struct);
}
/**
@@ -175,7 +174,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_ioctl ioctl_data = {};
struct osi_core_avb_algorithm avb_data;
int ret;
if (ifdata->ptr == NULL) {
@@ -184,7 +183,7 @@ static int ether_get_avb_algo(struct net_device *ndev,
return -EINVAL;
}
if (copy_from_user(&ioctl_data.avb,
if (copy_from_user(&avb_data,
(struct osi_core_avb_algorithm *)ifdata->ptr,
sizeof(struct osi_core_avb_algorithm)) != 0U) {
dev_err(pdata->dev,
@@ -192,14 +191,13 @@ static int ether_get_avb_algo(struct net_device *ndev,
return -EFAULT;
}
ioctl_data.cmd = OSI_CMD_GET_AVB;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_get_avb(osi_core, &avb_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, &ioctl_data.avb,
if (copy_to_user(ifdata->ptr, &avb_data,
sizeof(struct osi_core_avb_algorithm)) != 0U) {
dev_err(pdata->dev, "%s: copy_to_user failed\n", __func__);
return -EFAULT;
@@ -230,8 +228,6 @@ 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
*/
@@ -252,10 +248,8 @@ static int ether_config_arp_offload(struct ether_priv_data *pdata,
dev_err(pdata->dev, "%s: Invalid IP addr\n", __func__);
return ret;
}
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);
ret = osi_config_arp_offload(pdata->osi_core, ifrd_p->if_flags,
param.ip_addr);
dev_err(pdata->dev, "ARP offload: %s : %s\n",
ifrd_p->if_flags ? "Enable" : "Disable",
ret ? "Failed" : "Success");
@@ -316,7 +310,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_ioctl ioctl_data = {};
struct osi_l3_l4_filter l_l3_filter;
unsigned int is_l4_filter = OSI_DISABLE;
int ret = -EINVAL;
@@ -331,26 +325,20 @@ static int ether_config_ip4_filters(struct net_device *dev,
return ret;
}
if (copy_from_user(&ioctl_data.l3l4_filter, u_l3_filter,
if (copy_from_user(&l_l3_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 (ioctl_data.l3l4_filter.filter_no >
(pdata->hw_feat.l3l4_filter_num - 1U)) {
if (l_l3_filter.filter_no > (pdata->hw_feat.l3l4_filter_num - 1U)) {
dev_err(pdata->dev, "%d filter is not supported in the HW\n",
ioctl_data.l3l4_filter.filter_no);
l_l3_filter.filter_no);
return ret;
}
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);
return osi_l3l4_filter(osi_core, l_l3_filter, OSI_IP4_FILTER,
OSI_DISABLE, OSI_CHAN_ANY, is_l4_filter);
}
/**
@@ -378,7 +366,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_ioctl ioctl_data = {};
struct osi_l3_l4_filter l_l3_filter;
unsigned int is_l4_filter = OSI_DISABLE;
int ret = -EINVAL;
@@ -393,26 +381,20 @@ static int ether_config_ip6_filters(struct net_device *dev,
return ret;
}
if (copy_from_user(&ioctl_data.l3l4_filter, u_l3_filter,
if (copy_from_user(&l_l3_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 (ioctl_data.l3l4_filter.filter_no >
(pdata->hw_feat.l3l4_filter_num - 1U)) {
if (l_l3_filter.filter_no > (pdata->hw_feat.l3l4_filter_num - 1U)) {
dev_err(pdata->dev, "%d filter is not supported in the HW\n",
ioctl_data.l3l4_filter.filter_no);
l_l3_filter.filter_no);
return ret;
}
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);
return osi_l3l4_filter(osi_core, l_l3_filter, OSI_IP6_FILTER,
OSI_DISABLE, OSI_CHAN_ANY, is_l4_filter);
}
/**
@@ -443,7 +425,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_ioctl ioctl_data = {};
struct osi_l3_l4_filter l_l4_filter;
unsigned int is_l4_filter = OSI_ENABLE;
int ret = -EINVAL;
@@ -459,26 +441,20 @@ static int ether_config_tcp_udp_filters(struct net_device *dev,
return ret;
}
if (copy_from_user(&ioctl_data.l3l4_filter, u_l4_filter,
if (copy_from_user(&l_l4_filter, u_l4_filter,
sizeof(struct osi_l3_l4_filter)) != 0U) {
dev_err(pdata->dev, "%s copy from user failed", __func__);
return -EFAULT;
}
if (ioctl_data.l3l4_filter.filter_no >
(pdata->hw_feat.l3l4_filter_num - 1U)) {
if (l_l4_filter.filter_no > (pdata->hw_feat.l3l4_filter_num - 1U)) {
dev_err(pdata->dev, "%d filter is not supported in the HW\n",
ioctl_data.l3l4_filter.filter_no);
l_l4_filter.filter_no);
return ret;
}
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);
return osi_l3l4_filter(osi_core, l_l4_filter, tcp_udp,
OSI_DISABLE, OSI_CHAN_ANY, is_l4_filter);
}
/**
@@ -504,7 +480,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_ioctl ioctl_data = {};
struct osi_vlan_filter l_vlan_filter;
int ret = -EINVAL;
if (ifdata->ptr == NULL) {
@@ -513,23 +489,23 @@ static int ether_config_vlan_filter(struct net_device *dev,
return ret;
}
if (copy_from_user(&ioctl_data.vlan_filter, u_vlan_filter,
if (copy_from_user(&l_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 (ioctl_data.vlan_filter.perfect_hash == OSI_HASH_FILTER_MODE) {
if (l_vlan_filter.perfect_hash == OSI_HASH_FILTER_MODE) {
dev_err(pdata->dev, "VLAN HASH filtering is not supported\n");
return ret;
}
ioctl_data.cmd = OSI_CMD_VLAN_FILTER;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_config_vlan_filtering(osi_core, l_vlan_filter.filter_enb_dis,
l_vlan_filter.perfect_hash,
l_vlan_filter.perfect_inverse_match);
if (ret == 0) {
pdata->vlan_hash_filtering =
ioctl_data.vlan_filter.perfect_hash;
pdata->vlan_hash_filtering = l_vlan_filter.perfect_hash;
}
return ret;
@@ -559,10 +535,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_ioctl ioctl_data = {};
struct osi_filter filter;
int ret = -EINVAL;
memset(&ioctl_data.l2_filter, 0x0, sizeof(struct osi_filter));
memset(&filter, 0x0, sizeof(struct osi_filter));
if (ifdata->ptr == NULL) {
dev_err(pdata->dev, "%s: Invalid data for priv ioctl %d\n",
@@ -588,13 +564,12 @@ 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) {
ioctl_data.l2_filter.oper_mode |= OSI_OPER_EN_L2_DA_INV;
filter.oper_mode |= OSI_OPER_EN_L2_DA_INV;
} else {
ioctl_data.l2_filter.oper_mode |= OSI_OPER_DIS_L2_DA_INV;
filter.oper_mode |= OSI_OPER_DIS_L2_DA_INV;
}
ioctl_data.cmd = OSI_CMD_L2_FILTER;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_l2_filter(osi_core, &filter);
if (ret != 0) {
dev_err(pdata->dev, "setting L2_DA_INV failed\n");
}
@@ -622,17 +597,14 @@ 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) {
ioctl_data.cmd = OSI_CMD_RESTORE_REGISTER;
if (osi_handle_ioctl(osi_core, &ioctl_data)) {
if (osi_restore_registers(osi_core)) {
dev_err(pdata->dev, "Restore MAC registers fail\n");
return -EBUSY;
}
} else if (flags == OSI_DISABLE) {
ioctl_data.cmd = OSI_CMD_SAVE_REGISTER;
if (osi_handle_ioctl(osi_core, &ioctl_data)) {
if (osi_save_registers(osi_core)) {
dev_err(pdata->dev, "Save MAC registers fail\n");
return -EBUSY;
}
@@ -667,7 +639,6 @@ 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)) ||
@@ -685,10 +656,7 @@ static int ether_config_loopback_mode(struct net_device *ndev,
*/
netif_carrier_on(ndev);
}
ioctl_data.arg1_u32 = OSI_ENABLE;
ioctl_data.cmd = OSI_CMD_MAC_LB;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_config_mac_loopback(osi_core, OSI_ENABLE);
if (ret < 0) {
dev_err(pdata->dev,
"Failed to enable MAC Loopback\n");
@@ -705,10 +673,7 @@ static int ether_config_loopback_mode(struct net_device *ndev,
*/
netif_carrier_off(ndev);
}
ioctl_data.arg1_u32 = OSI_DISABLE;
ioctl_data.cmd = OSI_CMD_MAC_LB;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_config_mac_loopback(osi_core, OSI_DISABLE);
if (ret < 0) {
dev_err(pdata->dev,
"Failed to disable MAC Loopback\n");

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2020, 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,15 +75,12 @@ 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);
ioctl_data.cmd = OSI_CMD_ADJ_TIME;
ioctl_data.arg8_64 = nsec_delta;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_adjust_time(osi_core, nsec_delta);
if (ret < 0) {
dev_err(pdata->dev,
"%s:failed to adjust time with reason %d\n",
@@ -113,15 +110,12 @@ 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);
ioctl_data.cmd = OSI_CMD_ADJ_FREQ;
ioctl_data.arg6_32 = ppb;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_adjust_freq(osi_core, ppb);
if (ret < 0) {
dev_err(pdata->dev,
"%s:failed to adjust frequency with reason code %d\n",
@@ -191,16 +185,12 @@ 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);
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);
ret = osi_set_systime_to_mac(osi_core, ts->tv_sec, ts->tv_nsec);
if (ret < 0) {
dev_err(pdata->dev,
"%s:failed to set system time with reason %d\n",
@@ -280,24 +270,21 @@ 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_ioctl ioctl_data = {};
struct osi_core_avb_algorithm avb;
/* 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(&ioctl_data.avb, 0,
sizeof(struct osi_core_avb_algorithm));
memset(&avb, 0, sizeof(struct osi_core_avb_algorithm));
qinx = osi_core->mtl_queues[i];
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);
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);
if (ret != 0) {
dev_err(pdata->dev,
"Failed to set TXQ:%d AVB info\n",
@@ -315,10 +302,8 @@ int ether_handle_hwtstamp_ioctl(struct ether_priv_data *pdata,
struct ifreq *ifr)
{
struct osi_core_priv_data *osi_core = pdata->osi_core;
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
@@ -455,13 +440,7 @@ int ether_handle_hwtstamp_ioctl(struct ether_priv_data *pdata,
if (!pdata->hwts_tx_en && !hwts_rx_en) {
/* disable the PTP configuration */
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;
}
osi_ptp_configuration(osi_core, OSI_DISABLE);
ether_config_slot_function(pdata, OSI_DISABLE);
} else {
/* Store default PTP clock frequency, so that we
@@ -479,13 +458,7 @@ 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 */
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;
}
osi_ptp_configuration(osi_core, OSI_ENABLE);
#ifdef CONFIG_TEGRA_PTP_NOTIFIER
/* Register broadcasting MAC timestamp to clients */
tegra_register_hwtime_source(ether_get_ptptime, pdata);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2020, 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,15 +309,13 @@ 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;
ioctl_data.cmd = OSI_CMD_READ_MMC;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_read_mmc(osi_core);
if (ret < 0)
return ret;
@@ -329,8 +327,8 @@ static int ether_test_mmc_counters(struct ether_priv_data *pdata)
ret = ether_test_mac_loopback(pdata);
if (ret < 0)
return ret;
ioctl_data.cmd = OSI_CMD_READ_MMC;
ret = osi_handle_ioctl(osi_core, &ioctl_data);
ret = osi_read_mmc(osi_core);
if (ret < 0)
return ret;
@@ -384,7 +382,6 @@ 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;
@@ -410,12 +407,9 @@ void ether_selftest_run(struct net_device *dev,
break;
/* Fallthrough */
case ETHER_LOOPBACK_MAC:
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);
}
if (pdata->osi_core)
ret = osi_config_mac_loopback(pdata->osi_core,
OSI_ENABLE);
break;
default:
ret = -EOPNOTSUPP;
@@ -442,12 +436,9 @@ void ether_selftest_run(struct net_device *dev,
break;
/* Fallthrough */
case ETHER_LOOPBACK_MAC:
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 (pdata->osi_core)
ret = osi_config_mac_loopback(pdata->osi_core,
OSI_DISABLE);
if (!ret)
break;
default:

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2019-2020, 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,
@@ -64,7 +64,6 @@ 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 */
@@ -83,9 +82,7 @@ static ssize_t ether_mac_loopback_store(struct device *dev,
netif_carrier_on(ndev);
}
/* Enabling the MAC Loopback Mode */
ioctl_data.arg1_u32 = OSI_ENABLE;
ioctl_data.cmd = OSI_CMD_MAC_LB;
ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data);
ret = osi_config_mac_loopback(pdata->osi_core, OSI_ENABLE);
if (ret < 0) {
dev_err(pdata->dev, "Enabling MAC Loopback failed\n");
} else {
@@ -102,9 +99,7 @@ static ssize_t ether_mac_loopback_store(struct device *dev,
netif_carrier_off(ndev);
}
/* Disabling the MAC Loopback Mode */
ioctl_data.arg1_u32 = OSI_DISABLE;
ioctl_data.cmd = OSI_CMD_MAC_LB;
ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data);
ret = osi_config_mac_loopback(pdata->osi_core, OSI_DISABLE);
if (ret < 0) {
dev_err(pdata->dev, "Disabling MAC Loopback failed\n");
} else {