From: Sergej Bauer <sbauer@blackbox.su>
To: netdev@vger.kernel.org
Cc: andrew@lunn.ch, f.fainelli@gmail.com, sbauer@blackbox.su,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Bryan Whitehead <bryan.whitehead@microchip.com>,
UNGLinuxDriver@microchip.com,
Simon Horman <simon.horman@netronome.com>,
Mark Einon <mark.einon@gmail.com>,
Madalin Bucur <madalin.bucur@oss.nxp.com>,
Arnd Bergmann <arnd@arndb.de>,
Masahiro Yamada <masahiroy@kernel.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH v2] lan743x: add virtual PHY for PHY-less devices
Date: Sat, 23 Jan 2021 00:42:41 +0300 [thread overview]
Message-ID: <20210122214247.6536-1-sbauer@blackbox.su> (raw)
From: sbauer@blackbox.su
v1->v2:
switch to using of fixed_phy as was suggested by Andrew and Florian
also features-related parts are removed
Previous versions can be found at:
v1:
initial version
https://lkml.org/lkml/2020/9/17/1272
Signed-off-by: Sergej Bauer <sbauer@blackbox.su>
diff --git a/MAINTAINERS b/MAINTAINERS
index 650deb973913..86304efd7691 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11699,6 +11699,12 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/microchip/lan743x_*
+MICROCHIP LAN743X VIRTUAL PHY
+M: Sergej Bauer <sbauer@blackbox.su>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/microchip/lan743x_virtual_phy.*
+
MICROCHIP LCDFB DRIVER
M: Nicolas Ferre <nicolas.ferre@microchip.com>
L: linux-fbdev@vger.kernel.org
diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig
index d0f6dfe0dcf3..fbc94cf115bd 100644
--- a/drivers/net/ethernet/microchip/Kconfig
+++ b/drivers/net/ethernet/microchip/Kconfig
@@ -48,6 +48,7 @@ config LAN743X
select PHYLIB
select CRC16
select CRC32
+ select FIXED_PHY
help
Support for the Microchip LAN743x PCI Express Gigabit Ethernet chip
diff --git a/drivers/net/ethernet/microchip/Makefile b/drivers/net/ethernet/microchip/Makefile
index da603540ca57..dc3a2d66c286 100644
--- a/drivers/net/ethernet/microchip/Makefile
+++ b/drivers/net/ethernet/microchip/Makefile
@@ -7,4 +7,4 @@ obj-$(CONFIG_ENC28J60) += enc28j60.o
obj-$(CONFIG_ENCX24J600) += encx24j600.o encx24j600-regmap.o
obj-$(CONFIG_LAN743X) += lan743x.o
-lan743x-objs := lan743x_main.o lan743x_ethtool.o lan743x_ptp.o
+lan743x-objs := lan743x_main.o lan743x_ethtool.o lan743x_ptp.o lan743x_virtual_phy.o
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
index c5de8f46cdd3..22636366d0db 100644
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -816,6 +816,17 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev,
}
#endif /* CONFIG_PM */
+int lan743x_set_link_ksettings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *cmd)
+{
+ if (!netdev->phydev)
+ return -ENETDOWN;
+
+ return phy_is_pseudo_fixed_link(netdev->phydev) ?
+ lan743x_set_virtual_link_ksettings(netdev, cmd)
+ : phy_ethtool_set_link_ksettings(netdev, cmd);
+}
+
const struct ethtool_ops lan743x_ethtool_ops = {
.get_drvinfo = lan743x_ethtool_get_drvinfo,
.get_msglevel = lan743x_ethtool_get_msglevel,
@@ -839,7 +850,7 @@ const struct ethtool_ops lan743x_ethtool_ops = {
.get_eee = lan743x_ethtool_get_eee,
.set_eee = lan743x_ethtool_set_eee,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
- .set_link_ksettings = phy_ethtool_set_link_ksettings,
+ .set_link_ksettings = lan743x_set_link_ksettings,
#ifdef CONFIG_PM
.get_wol = lan743x_ethtool_get_wol,
.set_wol = lan743x_ethtool_set_wol,
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.h b/drivers/net/ethernet/microchip/lan743x_ethtool.h
index d0d11a777a58..7287474d4a5c 100644
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.h
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.h
@@ -8,4 +8,7 @@
extern const struct ethtool_ops lan743x_ethtool_ops;
+int lan743x_set_virtual_link_ksettings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *cmd);
+
#endif /* _LAN743X_ETHTOOL_H */
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index 3804310c853a..d8c00fa298d0 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -17,6 +17,11 @@
#include <linux/crc16.h>
#include "lan743x_main.h"
#include "lan743x_ethtool.h"
+#include "lan743x_virtual_phy.h"
+
+static char *mii_regs[32];
+static int mii_regs_count;
+module_param_array(mii_regs, charp, &mii_regs_count, 0644);
static void lan743x_pci_cleanup(struct lan743x_adapter *adapter)
{
@@ -821,7 +826,7 @@ static int lan743x_mac_init(struct lan743x_adapter *adapter)
return 0;
}
-static int lan743x_mac_open(struct lan743x_adapter *adapter)
+int lan743x_mac_open(struct lan743x_adapter *adapter)
{
u32 temp;
@@ -832,7 +837,7 @@ static int lan743x_mac_open(struct lan743x_adapter *adapter)
return 0;
}
-static void lan743x_mac_close(struct lan743x_adapter *adapter)
+void lan743x_mac_close(struct lan743x_adapter *adapter)
{
u32 temp;
@@ -1000,8 +1005,10 @@ static void lan743x_phy_close(struct lan743x_adapter *adapter)
struct net_device *netdev = adapter->netdev;
phy_stop(netdev->phydev);
- phy_disconnect(netdev->phydev);
- netdev->phydev = NULL;
+ if (phy_is_pseudo_fixed_link(netdev->phydev))
+ lan743x_virtual_phy_disconnect(netdev->phydev);
+ else
+ phy_disconnect(netdev->phydev);
}
static int lan743x_phy_open(struct lan743x_adapter *adapter)
@@ -1019,11 +1026,22 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter)
/* try internal phy */
phydev = phy_find_first(adapter->mdiobus);
if (!phydev)
+ phydev = lan743x_virtual_phy(adapter, mii_regs,
+ mii_regs_count);
+
+ if (!phydev || IS_ERR(phydev))
goto return_error;
- ret = phy_connect_direct(netdev, phydev,
- lan743x_phy_link_status_change,
- PHY_INTERFACE_MODE_GMII);
+ if (phy_is_pseudo_fixed_link(phydev)) {
+ ret = phy_connect_direct(netdev, phydev,
+ lan743x_virtual_phy_status_change,
+ PHY_INTERFACE_MODE_MII);
+ } else {
+ ret = phy_connect_direct(netdev, phydev,
+ lan743x_phy_link_status_change,
+ PHY_INTERFACE_MODE_GMII);
+ }
+
if (ret)
goto return_error;
}
@@ -1031,6 +1049,15 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter)
/* MAC doesn't support 1000T Half */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
+ if (phy_is_pseudo_fixed_link(phydev)) {
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_TP_BIT);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+ phydev->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+ phydev->supported);
+ phy_advertise_supported(phydev);
+ }
+
/* support both flow controls */
phy_support_asym_pause(phydev);
phy->fc_request_control = (FLOW_CTRL_RX | FLOW_CTRL_TX);
@@ -2580,11 +2607,20 @@ static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb,
static int lan743x_netdev_ioctl(struct net_device *netdev,
struct ifreq *ifr, int cmd)
{
+ int ret;
+
if (!netif_running(netdev))
return -EINVAL;
+
if (cmd == SIOCSHWTSTAMP)
return lan743x_ptp_ioctl(netdev, ifr, cmd);
- return phy_mii_ioctl(netdev->phydev, ifr, cmd);
+
+ if (phy_is_pseudo_fixed_link(netdev->phydev))
+ ret = lan743x_virtual_phy_mii_ioctl(netdev->phydev, ifr, cmd);
+ else
+ ret = phy_mii_ioctl(netdev->phydev, ifr, cmd);
+
+ return ret;
}
static void lan743x_netdev_set_multicast(struct net_device *netdev)
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
index 404af3f4635e..8e16fd0f166a 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.h
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -109,6 +109,7 @@
#define MAC_CR_EEE_EN_ BIT(17)
#define MAC_CR_ADD_ BIT(12)
#define MAC_CR_ASD_ BIT(11)
+#define MAC_CR_INT_LOOPBACK_ BIT(10)
#define MAC_CR_CNTR_RST_ BIT(5)
#define MAC_CR_DPX_ BIT(3)
#define MAC_CR_CFG_H_ BIT(2)
diff --git a/drivers/net/ethernet/microchip/lan743x_virtual_phy.c b/drivers/net/ethernet/microchip/lan743x_virtual_phy.c
new file mode 100644
index 000000000000..b6bf7c016448
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan743x_virtual_phy.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (C) 2021 Sergej Bauer
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
+#include <linux/ethtool.h>
+#include <linux/rtnetlink.h>
+#include "lan743x_main.h"
+#include "lan743x_ethtool.h"
+#include "lan743x_virtual_phy.h"
+
+static u16 regs802p3[32];
+
+int lan743x_virtual_phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr,
+ int cmd)
+{
+ struct ethtool_link_ksettings ksettings;
+ struct net_device *netdev = phydev->attached_dev;
+ struct mii_ioctl_data *mii_data = if_mii(ifr);
+ int ret = 0;
+ u16 val = mii_data->val_in;
+ u16 reg_num = mii_data->reg_num;
+
+ if (reg_num > 0x1f)
+ return -ERANGE;
+
+ memset(&ksettings, 0, sizeof(ksettings));
+ phy_ethtool_get_link_ksettings(netdev, &ksettings);
+ ksettings.base.autoneg = AUTONEG_ENABLE;
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ break;
+ case SIOCGMIIREG:
+ mii_data->val_out = regs802p3[reg_num];
+ break;
+ case SIOCSMIIREG:
+ switch (reg_num) {
+ case MII_BMCR:
+ val &= ~BMCR_RESET;
+ if (!(val & BMCR_FULLDPLX))
+ val |= BMCR_FULLDPLX;
+ val &= ~0x1f;
+
+ if (val & BMCR_ANRESTART)
+ val &= ~BMCR_ANRESTART;
+
+ if ((val & BMCR_SPEED1000) && (val & BMCR_SPEED100)) {
+ ret = -EINVAL;
+ netdev_err(netdev, "invalid bits 0.6 and 0.13");
+ break;
+ }
+
+ ksettings.base.duplex = DUPLEX_FULL;
+
+ if (val & BMCR_SPEED1000)
+ ksettings.base.speed = SPEED_1000;
+ else if (val & BMCR_SPEED100)
+ ksettings.base.speed = SPEED_100;
+ else
+ ksettings.base.speed = SPEED_10;
+
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ case 15:
+ default:
+ regs802p3[reg_num] = val;
+ break;
+ }
+ ret = lan743x_set_virtual_link_ksettings(netdev, &ksettings);
+ if (ret == 0)
+ regs802p3[reg_num] = val;
+
+ break;
+ default:
+ netdev_err(netdev, "not supported ioctl %X\n", cmd);
+ ret = -EOPNOTSUPP;
+ };
+
+ return ret;
+}
+
+void lan743x_virtual_phy_disconnect(struct phy_device *phydev)
+{
+ struct net_device *attached_dev = phydev->attached_dev;
+
+ if (phydev->sysfs_links) {
+ if (phydev->attached_dev)
+ sysfs_remove_link(&attached_dev->dev.kobj,
+ "phydev");
+ sysfs_remove_link(&phydev->mdio.dev.kobj,
+ "attached_dev");
+ }
+
+ fixed_phy_unregister(phydev);
+}
+
+void lan743x_virtual_phy_status_change(struct net_device *netdev)
+{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+ struct phy_device *phydev = netdev->phydev;
+ u32 data;
+
+ if (!netdev->phydev)
+ return;
+
+ if (phydev->state == PHY_RUNNING) {
+ data = lan743x_csr_read(adapter, MAC_CR);
+ data |= MAC_CR_INT_LOOPBACK_;
+ data &= ~MAC_CR_MII_EN_;
+ data |= MAC_CR_DPX_;
+
+ switch (phydev->speed) {
+ case SPEED_10:
+ data &= ~MAC_CR_CFG_H_;
+ data &= ~MAC_CR_CFG_L_;
+ break;
+ case SPEED_100:
+ data &= ~MAC_CR_CFG_H_;
+ data |= MAC_CR_CFG_L_;
+ break;
+ case SPEED_1000:
+ data |= MAC_CR_CFG_H_;
+ data &= ~MAC_CR_CFG_L_;
+ break;
+ }
+ lan743x_csr_write(adapter, MAC_CR, data);
+ }
+ phy_print_status(phydev);
+}
+
+struct phy_device *lan743x_virtual_phy(struct lan743x_adapter *adapter,
+ char *mii_regs[], int mii_regs_count)
+{
+ struct phy_device *phydev = NULL;
+ struct net_device *netdev = adapter->netdev;
+ struct mii_ioctl_data mii_data;
+ struct ifreq ifr;
+ long res;
+ int ret, i;
+
+ struct fixed_phy_status status = {
+ .link = 1,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+ .asym_pause = 1,
+ };
+
+ phydev = fixed_phy_register(PHY_POLL, &status, NULL);
+ if (!phydev || IS_ERR(phydev)) {
+ netif_err(adapter, ifup, adapter->netdev,
+ "failed to regiter fixed_phy\n");
+ goto out;
+ }
+ phydev->attached_dev = netdev;
+ netdev->phydev = phydev;
+
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+ phydev->supported);
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+ phydev->supported);
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+ phydev->supported);
+
+ if (mii_regs_count > 0) {
+ for (i = 0; i < mii_regs_count; i++) {
+ mii_data.reg_num = i;
+ ret = kstrtol(mii_regs[i], 16, &res);
+
+ if (ret == 0)
+ mii_data.val_in = res;
+ else
+ mii_data.val_in = 0xffff;
+
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data,
+ sizeof(mii_data));
+ ret = lan743x_virtual_phy_mii_ioctl(phydev, &ifr,
+ SIOCSMIIREG);
+ if (ret < 0)
+ return NULL;
+ }
+ } else {
+ mii_data.reg_num = MII_BMSR;
+ mii_data.val_in = BMSR_100FULL | BMSR_10FULL | BMSR_ESTATEN |
+ BMSR_ANEGCOMPLETE | BMSR_ANEGCAPABLE | BMSR_LSTATUS |
+ BMSR_ERCAP;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_PHYSID1;
+ mii_data.val_in = (adapter->csr.id_rev & ID_REV_ID_MASK_) >> 16;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_PHYSID2;
+ mii_data.val_in = adapter->csr.id_rev & ID_REV_CHIP_REV_MASK_;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_ADVERTISE;
+ mii_data.val_in = ADVERTISE_100FULL | ADVERTISE_10FULL |
+ ADVERTISE_LPACK;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_LPA;
+ mii_data.val_in = ADVERTISE_100FULL | ADVERTISE_10FULL |
+ ADVERTISE_LPACK;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_EXPANSION;
+ mii_data.val_in = EXPANSION_NWAY | EXPANSION_ENABLENPAGE |
+ EXPANSION_NPCAPABLE;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_CTRL1000;
+ mii_data.val_in = ADVERTISE_1000FULL;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_STAT1000;
+ mii_data.val_in = LPA_1000FULL | LPA_1000REMRXOK |
+ LPA_1000LOCALRXOK | LPA_1000MSRES;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_ESTATUS;
+ mii_data.val_in = ESTATUS_1000_TFULL;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+
+ mii_data.reg_num = MII_BMCR;
+ mii_data.val_in = BMCR_SPEED1000 | BMCR_FULLDPLX |
+ BMCR_LOOPBACK | BMCR_ANENABLE;
+ memcpy(&ifr.ifr_ifru.ifru_data, &mii_data, sizeof(mii_data));
+ lan743x_virtual_phy_mii_ioctl(phydev, &ifr, SIOCSMIIREG);
+ }
+
+ phydev->attached_dev = NULL;
+out:
+ return phydev;
+}
+
+int lan743x_set_virtual_link_ksettings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *cmd)
+{
+ struct ethtool_link_ksettings *cmd_ref =
+ (struct ethtool_link_ksettings *)cmd;
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+ u32 speed = cmd->base.speed;
+ u8 duplex = cmd->base.duplex;
+ u16 v = 0;
+ u32 data;
+
+ if (!netdev->phydev)
+ return -ENETDOWN;
+ if (speed &&
+ speed != SPEED_10 && speed != SPEED_100 && speed != SPEED_1000) {
+ netdev_err(netdev, "%s: unknown speed %d\n", netdev->name,
+ speed);
+ return -EINVAL;
+ }
+
+ v = regs802p3[0];
+ v &= ~(BMCR_SPEED1000 | BMCR_SPEED100);
+ data = lan743x_csr_read(adapter, MAC_CR);
+ duplex = DUPLEX_FULL;
+
+ if (speed != adapter->netdev->phydev->speed) {
+ lan743x_mac_close(adapter);
+ switch (speed) {
+ case 0:
+ break;
+ case SPEED_10:
+ data &= ~(MAC_CR_CFG_H_ | MAC_CR_CFG_L_);
+ lan743x_csr_write(adapter, MAC_CR, data);
+
+ regs802p3[MII_ADVERTISE] = ADVERTISE_10FULL |
+ ADVERTISE_100FULL |
+ ADVERTISE_LPACK;
+ regs802p3[MII_LPA] = LPA_10FULL | LPA_LPACK;
+ regs802p3[MII_EXPANSION] = ESTATUS_1000_TFULL;
+ regs802p3[MII_CTRL1000] = ADVERTISE_1000FULL;
+ regs802p3[MII_STAT1000] = 0;
+ break;
+ case SPEED_100:
+ v |= BMCR_SPEED100;
+ data &= ~MAC_CR_CFG_H_;
+ data |= MAC_CR_CFG_L_;
+ lan743x_csr_write(adapter, MAC_CR, data);
+
+ regs802p3[MII_ADVERTISE] = ADVERTISE_10FULL |
+ ADVERTISE_100FULL |
+ ADVERTISE_LPACK;
+ regs802p3[MII_LPA] = LPA_10FULL | LPA_100FULL |
+ LPA_LPACK;
+ regs802p3[MII_EXPANSION] = ESTATUS_1000_TFULL;
+ regs802p3[MII_CTRL1000] = ADVERTISE_1000FULL;
+ regs802p3[MII_STAT1000] = 0;
+ break;
+ case SPEED_1000:
+ v |= BMCR_SPEED1000;
+ data |= MAC_CR_CFG_H_;
+ data &= ~MAC_CR_CFG_L_;
+ lan743x_csr_write(adapter, MAC_CR, data);
+
+ regs802p3[MII_ADVERTISE] = ADVERTISE_10FULL |
+ ADVERTISE_100FULL |
+ ADVERTISE_LPACK;
+ regs802p3[MII_LPA] = LPA_10FULL | LPA_100FULL |
+ LPA_LPACK;
+ regs802p3[MII_EXPANSION] = ESTATUS_1000_TFULL;
+ regs802p3[MII_CTRL1000] = ADVERTISE_1000FULL;
+ regs802p3[MII_STAT1000] = LPA_1000FULL |
+ LPA_1000REMRXOK | LPA_1000LOCALRXOK |
+ LPA_1000MSRES;
+ break;
+ };
+ lan743x_mac_open(adapter);
+
+ v |= BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_ANENABLE;
+ regs802p3[0] = v;
+ }
+
+ cmd_ref->base.duplex = duplex;
+ cmd_ref->base.autoneg = AUTONEG_ENABLE;
+
+ return phy_ethtool_set_link_ksettings(netdev, cmd_ref);
+}
+
diff --git a/drivers/net/ethernet/microchip/lan743x_virtual_phy.h b/drivers/net/ethernet/microchip/lan743x_virtual_phy.h
new file mode 100644
index 000000000000..caef07d73d74
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan743x_virtual_phy.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (C) 2021 Sergej Bauer */
+#ifndef LAN743X_FAKE_PHY_H
+#define LAN743X_FAKE_PHY_H
+
+#include "lan743x_main.h"
+
+struct phy_device *lan743x_virtual_phy(struct lan743x_adapter *adapter,
+ char *mii_regs[], int mii_regs_count);
+void lan743x_virtual_phy_disconnect(struct phy_device *phydev);
+int lan743x_virtual_phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr,
+ int cmd);
+void lan743x_virtual_phy_status_change(struct net_device *netdev);
+int lan743x_set_virtual_link_ksettings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *cmd);
+
+int lan743x_mac_open(struct lan743x_adapter *adapter);
+void lan743x_mac_close(struct lan743x_adapter *adapter);
+
+#endif
next reply other threads:[~2021-01-22 21:55 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-22 21:42 Sergej Bauer [this message]
2021-01-22 21:52 ` [PATCH v2] lan743x: add virtual PHY for PHY-less devices Florian Fainelli
2021-01-22 22:11 ` Sergej Bauer
2021-01-22 22:08 ` Andrew Lunn
2021-01-22 23:09 ` Sergej Bauer
2021-01-22 23:23 ` Andrew Lunn
2021-01-22 23:58 ` Sergej Bauer
2021-01-23 0:01 ` Florian Fainelli
2021-01-23 1:01 ` Sergej Bauer
2021-01-23 1:32 ` Andrew Lunn
2021-01-23 4:01 ` Sergej Bauer
2021-01-25 8:57 ` Sergej Bauer
2021-01-23 1:39 ` Florian Fainelli
2021-01-25 8:57 ` Sergej Bauer
2021-01-25 10:23 ` Sergej Bauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210122214247.6536-1-sbauer@blackbox.su \
--to=sbauer@blackbox.su \
--cc=UNGLinuxDriver@microchip.com \
--cc=andrew@lunn.ch \
--cc=arnd@arndb.de \
--cc=bryan.whitehead@microchip.com \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=madalin.bucur@oss.nxp.com \
--cc=mark.einon@gmail.com \
--cc=masahiroy@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=simon.horman@netronome.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.