Lan743/6.1 include nvidia specific changes

Updating Lan7431 nvidia-oot driver for kernel 6.1
to include NV specific changes

Include changes from:
    https://git-master.nvidia.com/r/c/linux-nv-oot/+/2924162
    https://git-master.nvidia.com/r/c/linux-nv-oot/+/2932422
for userland phy and SC7 support

Bug 4330040
Bug 4270736

Change-Id: I20e052f24757d0ac17501906b267bc746c3d43d2
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3000975
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
Tested-by: Jeremy Alves <jalves@nvidia.com>
Reviewed-by: Jeremy Alves <jalves@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
This commit is contained in:
Jeremy Alves
2023-10-19 19:06:06 -07:00
committed by mobile promotions
parent 7cf41996cb
commit b8fca78022
2 changed files with 188 additions and 7 deletions

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>
@@ -1488,11 +1491,17 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct lan743x_phy *phy = &adapter->phy; struct lan743x_phy *phy = &adapter->phy;
struct phy_device *phydev; struct phy_device *phydev;
struct device_node *phynode;
int ret = -EIO; int ret = -EIO;
/* try devicetree phy, or fixed link */ phynode = of_node_get(adapter->pdev->dev.of_node);
phydev = of_phy_get_and_connect(netdev, adapter->pdev->dev.of_node,
lan743x_phy_link_status_change); if (phynode) {
phydev = of_phy_connect(netdev, phynode,
lan743x_phy_link_status_change, 0,
adapter->phy_mode);
}
if (!phydev) { if (!phydev) {
/* try internal phy */ /* try internal phy */
@@ -1512,6 +1521,10 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter)
goto return_error; goto return_error;
} }
/*phydev is assigned by now*/
/*Skip the device resume via mdio bus */
phydev->mac_managed_pm = true;
/* MAC doesn't support 1000T Half */ /* MAC doesn't support 1000T Half */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
@@ -1529,6 +1542,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,
@@ -3083,14 +3135,133 @@ static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb,
return lan743x_tx_xmit_frame(&adapter->tx[ch], skb); return lan743x_tx_xmit_frame(&adapter->tx[ch], 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)
@@ -3374,6 +3545,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
@@ -914,6 +917,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 */
@@ -1009,6 +1014,7 @@ enum lan743x_sgmii_lsd {
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;