diff --git a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c index cc7217c2..3c065e20 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c @@ -2449,15 +2449,18 @@ static int ether_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, { struct net_device *ndev = bus->priv; struct ether_priv_data *pdata = netdev_priv(ndev); + int ret = 0; if (!pdata->clks_enable) { dev_err(pdata->dev, "%s:No clks available, skipping PHY write\n", __func__); return -ENODEV; } + mutex_lock(&pdata->osi_mdio_lock); + ret = osi_write_phy_reg(pdata->osi_core, (unsigned int)phyaddr, (unsigned int)phyreg, phydata); + mutex_unlock(&pdata->osi_mdio_lock); - return osi_write_phy_reg(pdata->osi_core, (unsigned int)phyaddr, - (unsigned int)phyreg, phydata); + return ret; } /** @@ -2479,15 +2482,18 @@ static int ether_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) { struct net_device *ndev = bus->priv; struct ether_priv_data *pdata = netdev_priv(ndev); + int ret = 0; if (!pdata->clks_enable) { dev_err(pdata->dev, "%s:No clks available, skipping PHY read\n", __func__); return -ENODEV; } + mutex_lock(&pdata->osi_mdio_lock); + ret = osi_read_phy_reg(pdata->osi_core, (unsigned int)phyaddr, (unsigned int)phyreg); + mutex_unlock(&pdata->osi_mdio_lock); - return osi_read_phy_reg(pdata->osi_core, (unsigned int)phyaddr, - (unsigned int)phyreg); + return ret; } #if defined(NV_MII_BUS_STRUCT_HAS_WRITE_C45) /* Linux v6.3 */ @@ -3798,7 +3804,9 @@ static int ether_handle_priv_rmdio_ioctl(struct ether_priv_data *pdata, dev_dbg(pdata->dev, "%s: phy_id:%d regadd: %d devaddr:%d\n", __func__, mii_data->phy_id, prtad, devad); + mutex_lock(&pdata->osi_mdio_lock); ret = osi_read_phy_reg(pdata->osi_core, prtad, devad); + mutex_unlock(&pdata->osi_mdio_lock); if (ret < 0) { dev_err(pdata->dev, "%s: Data read failed\n", __func__); return -EFAULT; @@ -3826,6 +3834,7 @@ static int ether_handle_priv_wmdio_ioctl(struct ether_priv_data *pdata, { struct mii_ioctl_data *mii_data = if_mii(ifr); unsigned int prtad, devad; + int ret = 0; if (mdio_phy_id_is_c45(mii_data->phy_id)) { prtad = mdio_phy_id_prtad(mii_data->phy_id); @@ -3839,8 +3848,11 @@ static int ether_handle_priv_wmdio_ioctl(struct ether_priv_data *pdata, dev_dbg(pdata->dev, "%s: phy_id:%d regadd: %d devaddr:%d val:%d\n", __func__, mii_data->phy_id, prtad, devad, mii_data->val_in); - return osi_write_phy_reg(pdata->osi_core, prtad, devad, - mii_data->val_in); + mutex_lock(&pdata->osi_mdio_lock); + ret = osi_write_phy_reg(pdata->osi_core, prtad, devad, mii_data->val_in); + mutex_unlock(&pdata->osi_mdio_lock); + + return ret; } /** @@ -6548,6 +6560,8 @@ static int ether_probe(struct platform_device *pdev) osi_core->osd = pdata; osi_dma->osd = pdata; + mutex_init(&pdata->osi_mdio_lock); + osi_core->num_mtl_queues = num_mtl_queues; osi_dma->num_dma_chans = num_dma_chans; diff --git a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.h b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.h index 51aff9d6..68091fb0 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.h +++ b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.h @@ -670,6 +670,8 @@ struct ether_priv_data { struct ether_xtra_stat_counters xstats; /** wol configs */ struct ethtool_wolinfo wol; + /** MDIO lock for OSI function calls **/ + struct mutex osi_mdio_lock; }; /**