mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
nvethernet: add mutex lock for osi mdio
There is chance to hit race condition when doing mdio read/write from different application. This would lead to PHY not work properly intermittently. Bug 5211090 Change-Id: I62afbc1d206fd4cf02a0b58036e8d38ca84968ac Signed-off-by: Wayne Wang(SW-TEGRA) <waywang@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/3453343 (cherry picked from commit 1442bbd24a8fe0423fc67b5b004b2a07d604c109) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3477850 GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Revanth Kumar Uppala <ruppala@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
1d659b240c
commit
2f7421c40b
@@ -2449,15 +2449,18 @@ static int ether_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
|
|||||||
{
|
{
|
||||||
struct net_device *ndev = bus->priv;
|
struct net_device *ndev = bus->priv;
|
||||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!pdata->clks_enable) {
|
if (!pdata->clks_enable) {
|
||||||
dev_err(pdata->dev,
|
dev_err(pdata->dev,
|
||||||
"%s:No clks available, skipping PHY write\n", __func__);
|
"%s:No clks available, skipping PHY write\n", __func__);
|
||||||
return -ENODEV;
|
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,
|
return ret;
|
||||||
(unsigned int)phyreg, phydata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2479,15 +2482,18 @@ static int ether_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
|
|||||||
{
|
{
|
||||||
struct net_device *ndev = bus->priv;
|
struct net_device *ndev = bus->priv;
|
||||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!pdata->clks_enable) {
|
if (!pdata->clks_enable) {
|
||||||
dev_err(pdata->dev,
|
dev_err(pdata->dev,
|
||||||
"%s:No clks available, skipping PHY read\n", __func__);
|
"%s:No clks available, skipping PHY read\n", __func__);
|
||||||
return -ENODEV;
|
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,
|
return ret;
|
||||||
(unsigned int)phyreg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(NV_MII_BUS_STRUCT_HAS_WRITE_C45) /* Linux v6.3 */
|
#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",
|
dev_dbg(pdata->dev, "%s: phy_id:%d regadd: %d devaddr:%d\n",
|
||||||
__func__, mii_data->phy_id, prtad, devad);
|
__func__, mii_data->phy_id, prtad, devad);
|
||||||
|
|
||||||
|
mutex_lock(&pdata->osi_mdio_lock);
|
||||||
ret = osi_read_phy_reg(pdata->osi_core, prtad, devad);
|
ret = osi_read_phy_reg(pdata->osi_core, prtad, devad);
|
||||||
|
mutex_unlock(&pdata->osi_mdio_lock);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(pdata->dev, "%s: Data read failed\n", __func__);
|
dev_err(pdata->dev, "%s: Data read failed\n", __func__);
|
||||||
return -EFAULT;
|
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);
|
struct mii_ioctl_data *mii_data = if_mii(ifr);
|
||||||
unsigned int prtad, devad;
|
unsigned int prtad, devad;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (mdio_phy_id_is_c45(mii_data->phy_id)) {
|
if (mdio_phy_id_is_c45(mii_data->phy_id)) {
|
||||||
prtad = mdio_phy_id_prtad(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",
|
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);
|
__func__, mii_data->phy_id, prtad, devad, mii_data->val_in);
|
||||||
|
|
||||||
return osi_write_phy_reg(pdata->osi_core, prtad, devad,
|
mutex_lock(&pdata->osi_mdio_lock);
|
||||||
mii_data->val_in);
|
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_core->osd = pdata;
|
||||||
osi_dma->osd = pdata;
|
osi_dma->osd = pdata;
|
||||||
|
|
||||||
|
mutex_init(&pdata->osi_mdio_lock);
|
||||||
|
|
||||||
osi_core->num_mtl_queues = num_mtl_queues;
|
osi_core->num_mtl_queues = num_mtl_queues;
|
||||||
osi_dma->num_dma_chans = num_dma_chans;
|
osi_dma->num_dma_chans = num_dma_chans;
|
||||||
|
|
||||||
|
|||||||
@@ -670,6 +670,8 @@ struct ether_priv_data {
|
|||||||
struct ether_xtra_stat_counters xstats;
|
struct ether_xtra_stat_counters xstats;
|
||||||
/** wol configs */
|
/** wol configs */
|
||||||
struct ethtool_wolinfo wol;
|
struct ethtool_wolinfo wol;
|
||||||
|
/** MDIO lock for OSI function calls **/
|
||||||
|
struct mutex osi_mdio_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user