diff --git a/drivers/net/ethernet/microchip/5.15/Makefile b/drivers/net/ethernet/microchip/5.15/Makefile deleted file mode 100644 index 077212df..00000000 --- a/drivers/net/ethernet/microchip/5.15/Makefile +++ /dev/null @@ -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 diff --git a/drivers/net/ethernet/microchip/5.15/lan743x_main.c b/drivers/net/ethernet/microchip/5.15/lan743x_main.c index d64ce65a..29892c0e 100644 --- a/drivers/net/ethernet/microchip/5.15/lan743x_main.c +++ b/drivers/net/ethernet/microchip/5.15/lan743x_main.c @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* Copyright (C) 2018 Microchip Technology Inc. */ +/* + * Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + */ #include #include @@ -1039,6 +1042,45 @@ return_error: 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) { 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); } +/** + * @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, 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; - if (cmd == SIOCSHWTSTAMP) - return lan743x_ptp_ioctl(netdev, ifr, cmd); - return phy_mii_ioctl(netdev->phydev, ifr, cmd); + } + adapter = netdev_priv(netdev); + 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) @@ -2808,6 +2969,10 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev, 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); if (ret) goto return_error; diff --git a/drivers/net/ethernet/microchip/5.15/lan743x_main.h b/drivers/net/ethernet/microchip/5.15/lan743x_main.h index 6080028c..b23cce4e 100644 --- a/drivers/net/ethernet/microchip/5.15/lan743x_main.h +++ b/drivers/net/ethernet/microchip/5.15/lan743x_main.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* Copyright (C) 2018 Microchip Technology Inc. */ +/* + * Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + */ #ifndef _LAN743X_H #define _LAN743X_H @@ -626,6 +629,8 @@ struct lan743x_intr { struct lan743x_phy { bool fc_autoneg; u8 fc_request_control; + bool fixed; + u32 mdio_addr; }; /* TX */ @@ -706,6 +711,7 @@ struct lan743x_rx { struct lan743x_adapter { struct net_device *netdev; struct mii_bus *mdiobus; + phy_interface_t phy_mode; int msg_enable; #ifdef CONFIG_PM u32 wolopts;