Lan7431- NVIDIA specific changes to Lan7431 drv

Adding NVIDIA specific changes to Lan7431
for K515 driver

These changes support "userland phy driver"

Bug 3956901

Change-Id: I0f11e3cb95742bb0bac9bec7638d03552074dd23
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2924162
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
Tested-by: Jeremy Alves <jalves@nvidia.com>
Reviewed-by: Jeremy Alves <jalves@nvidia.com>
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
This commit is contained in:
Jeremy Alves
2023-06-21 21:05:07 +00:00
committed by mobile promotions
parent c2c17e16c9
commit ee70adda3e
3 changed files with 175 additions and 15 deletions

View File

@@ -1,11 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for the Microchip network device drivers.
#
obj-m += lan743x.o
lan743x-objs := lan743x_main.o lan743x_ethtool.o lan743x_ptp.o
all:
make W=1 -C /lib/modules/`uname -r`/build M=`pwd` modules

View File

@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0+ */ /* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (C) 2018 Microchip Technology Inc. */ /* Copyright (C) 2018 Microchip Technology Inc. */
/*
* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
@@ -1039,6 +1042,45 @@ return_error:
return ret; return ret;
} }
static int lan743x_phy_dt_init(struct lan743x_adapter *adapter,
struct pci_dev *pdev)
{
struct lan743x_phy *phy = &adapter->phy;
struct device_node *phynode;
struct net_device *netdev;
int ret = -EIO;
netdev = adapter->netdev;
phynode = of_node_get(pdev->dev.of_node);
if (phynode) {
/* try devicetree phy, or fixed link */
of_get_phy_mode(phynode, &adapter->phy_mode);
if (of_phy_is_fixed_link(phynode)) {
ret = of_phy_register_fixed_link(phynode);
phy->fixed = true;
if (ret) {
netdev_err(netdev,
"cannot register fixed PHY\n");
of_node_put(phynode);
goto return_error;
}
ret = of_property_read_u32(phynode, "nvidia,mdio_addr",
&phy->mdio_addr);
if (ret) {
netdev_warn(netdev,
"Unable to read mdio address\n");
}
}
of_node_put(phynode);
}
return 0;
return_error:
return ret;
}
static void lan743x_rfe_open(struct lan743x_adapter *adapter) static void lan743x_rfe_open(struct lan743x_adapter *adapter)
{ {
lan743x_csr_write(adapter, RFE_RSS_CFG, lan743x_csr_write(adapter, RFE_RSS_CFG,
@@ -2579,14 +2621,133 @@ static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb,
return lan743x_tx_xmit_frame(&adapter->tx[0], skb); return lan743x_tx_xmit_frame(&adapter->tx[0], skb);
} }
/**
* @brief Function to handle MDIO IOCTL in phyless move
*
* 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 lan7431_handle_priv_rmdio_ioctl(struct lan743x_adapter *adapter,
struct ifreq *ifr)
{
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);
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;
}
netif_dbg(adapter, drv, adapter->netdev, "%s: phy_id:%d regadd: %d devaddr:%d\n",
__func__, mii_data->phy_id, prtad, devad);
ret = lan743x_mdiobus_read(adapter->mdiobus, prtad, devad);
if (ret < 0) {
netif_err(adapter, drv, adapter->netdev, "%s: Data read failed\n", __func__);
return -EFAULT;
}
mii_data->val_out = ret;
return 0;
}
/**
* @brief Function to handle MDIO IOCTL in phyless move
*
* 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 lan7431_handle_priv_wmdio_ioctl(struct lan743x_adapter *adapter,
struct ifreq *ifr)
{
struct mii_ioctl_data *mii_data = if_mii(ifr);
unsigned int prtad, devad;
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;
}
netif_dbg(adapter, drv, adapter->netdev, "%s: phy_id:%d regadd: %d devaddr:%d val:%04x\n",
__func__, mii_data->phy_id, prtad, devad, mii_data->val_in);
return lan743x_mdiobus_write(adapter->mdiobus, prtad, devad, mii_data->val_in);
}
static int lan743x_netdev_ioctl(struct net_device *netdev, static int lan743x_netdev_ioctl(struct net_device *netdev,
struct ifreq *ifr, int cmd) struct ifreq *ifr, int cmd)
{ {
if (!netif_running(netdev)) int ret = -EINVAL;
struct lan743x_adapter *adapter = NULL;
if (!netdev || !ifr) {
netif_err(adapter, drv, adapter->netdev, "%s: Invalid arg\n", __func__);
return -EINVAL; return -EINVAL;
if (cmd == SIOCSHWTSTAMP) }
return lan743x_ptp_ioctl(netdev, ifr, cmd); adapter = netdev_priv(netdev);
return phy_mii_ioctl(netdev->phydev, ifr, cmd); if (!adapter) {
netif_err(adapter, drv, adapter->netdev, "%s: bad priv\n", __func__);
return -EINVAL;
}
if (netif_running(netdev)) {
switch (cmd) {
case SIOCSHWTSTAMP:
ret = lan743x_ptp_ioctl(netdev, ifr, cmd);
break;
case SIOCGMIIPHY:
case SIOCGMIIREG:
case SIOCSMIIREG:
if (!netdev->phydev) {
ret = -EINVAL;
break;
}
if (adapter->phy.fixed) {
if (cmd == SIOCGMIIPHY) {
struct mii_ioctl_data *mii_data = if_mii(ifr);
mii_data->phy_id = adapter->phy.mdio_addr;
ret = 0;
} else if (cmd == SIOCGMIIREG) {
ret = lan7431_handle_priv_rmdio_ioctl(adapter, ifr);
} else if (cmd == SIOCSMIIREG) {
ret = lan7431_handle_priv_wmdio_ioctl(adapter, ifr);
} else {
netif_err(adapter, drv, adapter->netdev,
"%s: impossible case\n", __func__);
}
} else {
ret = phy_mii_ioctl(netdev->phydev, ifr, cmd);
}
break;
default:
ret = (!netdev->phydev) ? -EINVAL : phy_mii_ioctl(netdev->phydev, ifr, cmd);
break;
}
} else {
netif_err(adapter, drv, adapter->netdev, "%s: Interface not up\n", __func__);
ret = -EINVAL;
}
return ret;
} }
static void lan743x_netdev_set_multicast(struct net_device *netdev) static void lan743x_netdev_set_multicast(struct net_device *netdev)
@@ -2808,6 +2969,10 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
of_get_mac_address(pdev->dev.of_node, adapter->mac_address); of_get_mac_address(pdev->dev.of_node, adapter->mac_address);
ret = lan743x_phy_dt_init(adapter, pdev);
if (ret)
goto return_error;
ret = lan743x_pci_init(adapter, pdev); ret = lan743x_pci_init(adapter, pdev);
if (ret) if (ret)
goto return_error; goto return_error;

View File

@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0+ */ /* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (C) 2018 Microchip Technology Inc. */ /* Copyright (C) 2018 Microchip Technology Inc. */
/*
* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#ifndef _LAN743X_H #ifndef _LAN743X_H
#define _LAN743X_H #define _LAN743X_H
@@ -626,6 +629,8 @@ struct lan743x_intr {
struct lan743x_phy { struct lan743x_phy {
bool fc_autoneg; bool fc_autoneg;
u8 fc_request_control; u8 fc_request_control;
bool fixed;
u32 mdio_addr;
}; };
/* TX */ /* TX */
@@ -706,6 +711,7 @@ struct lan743x_rx {
struct lan743x_adapter { struct lan743x_adapter {
struct net_device *netdev; struct net_device *netdev;
struct mii_bus *mdiobus; struct mii_bus *mdiobus;
phy_interface_t phy_mode;
int msg_enable; int msg_enable;
#ifdef CONFIG_PM #ifdef CONFIG_PM
u32 wolopts; u32 wolopts;