mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
nvethernet: add PHY read/write support
Add a private ioctl for phy register read and write. This support is needed for accessing the PHY registers from user space when fixed link is enabled in SW even though PHY is directly connected to MAC. Bug 200733774 Change-Id: Ifd9b5dc7764363d897605c2370da419a863ddea4 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2554892 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Revanth Kumar Uppala
parent
3f0e18c74d
commit
56063f5983
@@ -3386,6 +3386,105 @@ void ether_set_rx_mode(struct net_device *dev)
|
||||
schedule_work(&pdata->set_rx_mode_work);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to handle PHY read private IOCTL
|
||||
*
|
||||
* Algorithm: This function is used to write the data
|
||||
* into the specified register.
|
||||
*
|
||||
* @param [in] pdata: Pointer to private data structure.
|
||||
* @param [in] ifr: Interface request structure used for socket ioctl
|
||||
*
|
||||
* @retval 0 on success.
|
||||
* @retval "negative value" on failure.
|
||||
*/
|
||||
|
||||
static int ether_handle_priv_rmdio_ioctl(struct ether_priv_data *pdata,
|
||||
struct ifreq *ifr)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 9, 0))
|
||||
struct mii_ioctl_data *mii_data = if_mii(ifr);
|
||||
unsigned int prtad, devad;
|
||||
int ret = 0;
|
||||
|
||||
if (!ifr->ifr_data) {
|
||||
dev_err(pdata->dev, "%s: Invalid data for priv ioctl\n",
|
||||
__func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (mdio_phy_id_is_c45(mii_data->phy_id)) {
|
||||
prtad = mdio_phy_id_prtad(mii_data->phy_id);
|
||||
devad = mdio_phy_id_devad(mii_data->phy_id);
|
||||
devad = mdiobus_c45_addr(devad, mii_data->reg_num);
|
||||
} else {
|
||||
prtad = mii_data->phy_id;
|
||||
devad = mii_data->reg_num;
|
||||
}
|
||||
|
||||
dev_dbg(pdata->dev, "%s: phy_id:%d regadd: %d devaddr:%d\n",
|
||||
__func__, mii_data->phy_id, prtad, devad);
|
||||
|
||||
ret = osi_read_phy_reg(pdata->osi_core, prtad, devad);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev, "%s: Data read failed\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
mii_data->val_out = ret;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
dev_err(pdata->dev, "Not supported for kernel versions less than 5.10");
|
||||
return -ENOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to handle PHY write private IOCTL
|
||||
*
|
||||
* Algorithm: This function is used to write the data
|
||||
* into the specified register.
|
||||
*
|
||||
* @param [in] pdata: Pointer to private data structure.
|
||||
* @param [in] ifr: Interface request structure used for socket ioctl
|
||||
*
|
||||
* @retval 0 on success.
|
||||
* @retval "negative value" on failure.
|
||||
*/
|
||||
static int ether_handle_priv_wmdio_ioctl(struct ether_priv_data *pdata,
|
||||
struct ifreq *ifr)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 9, 0))
|
||||
struct mii_ioctl_data *mii_data = if_mii(ifr);
|
||||
unsigned int prtad, devad;
|
||||
|
||||
if (!ifr->ifr_data) {
|
||||
dev_err(pdata->dev, "%s: Invalid data for priv ioctl\n",
|
||||
__func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (mdio_phy_id_is_c45(mii_data->phy_id)) {
|
||||
prtad = mdio_phy_id_prtad(mii_data->phy_id);
|
||||
devad = mdio_phy_id_devad(mii_data->phy_id);
|
||||
devad = mdiobus_c45_addr(devad, mii_data->reg_num);
|
||||
} else {
|
||||
prtad = mii_data->phy_id;
|
||||
devad = mii_data->reg_num;
|
||||
}
|
||||
|
||||
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);
|
||||
#else
|
||||
dev_err(pdata->dev, "Not supported for kernel versions less than 5.10");
|
||||
return -ENOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Network stack IOCTL hook to driver
|
||||
*
|
||||
@@ -3433,6 +3532,14 @@ static int ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||
ret = ether_handle_priv_ioctl(dev, rq);
|
||||
break;
|
||||
|
||||
case ETHER_PRV_RMDIO_IOCTL:
|
||||
ret = ether_handle_priv_rmdio_ioctl(pdata, rq);
|
||||
break;
|
||||
|
||||
case ETHER_PRV_WMDIO_IOCTL:
|
||||
ret = ether_handle_priv_wmdio_ioctl(pdata, rq);
|
||||
break;
|
||||
|
||||
case ETHER_PRV_TS_IOCTL:
|
||||
ret = ether_handle_priv_ts_ioctl(pdata, rq);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user