mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-10-26 10:57:38 +08:00
r8169: add support for phylink
Transfer old framework to phylink. Phylink can support fiber mode card which can not get link status or link speed from standard phy registers. Signed-off-by: Javen Xu <javen_xu@realsil.com.cn> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Link: https://patch.msgid.link/20260831053745.1197-4-javen_xu@realsil.com.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
1 parent
9f8cb9cbcd
commit
8a3c76523e
2 files changed
+222
-78
No files matched your search
@@ -86,8 +86,8 @@ config R8169
|
||||
depends on PCI
|
||||
select FW_LOADER
|
||||
select CRC32
|
||||
select PHYLIB
|
||||
select REALTEK_PHY
|
||||
select PHYLINK
|
||||
help
|
||||
Say Y here if you have a Realtek Ethernet adapter belonging to
|
||||
the following families:
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/unaligned.h>
|
||||
@@ -775,6 +776,8 @@ struct rtl8169_private {
|
||||
struct r8169_led_classdev *leds;
|
||||
|
||||
u32 ocp_base;
|
||||
struct phylink *phylink;
|
||||
struct phylink_config phylink_config;
|
||||
};
|
||||
|
||||
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
|
||||
@@ -2253,7 +2256,7 @@ static int rtl8169_get_eee(struct net_device *dev, struct ethtool_keee *data)
|
||||
if (!rtl_supports_eee(tp))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = phy_ethtool_get_eee(tp->phydev, data);
|
||||
ret = phylink_ethtool_get_eee(tp->phylink, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -2269,7 +2272,7 @@ static int rtl8169_set_eee(struct net_device *dev, struct ethtool_keee *data)
|
||||
if (!rtl_supports_eee(tp))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return phy_ethtool_set_eee(tp->phydev, data);
|
||||
return phylink_ethtool_set_eee(tp->phylink, data);
|
||||
}
|
||||
|
||||
static void rtl8169_get_ringparam(struct net_device *dev,
|
||||
@@ -2300,13 +2303,8 @@ static void rtl8169_get_pauseparam(struct net_device *dev,
|
||||
struct ethtool_pauseparam *data)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
bool tx_pause, rx_pause;
|
||||
|
||||
phy_get_pause(tp->phydev, &tx_pause, &rx_pause);
|
||||
|
||||
data->autoneg = tp->phydev->autoneg;
|
||||
data->tx_pause = tx_pause ? 1 : 0;
|
||||
data->rx_pause = rx_pause ? 1 : 0;
|
||||
phylink_ethtool_get_pauseparam(tp->phylink, data);
|
||||
}
|
||||
|
||||
static int rtl8169_set_pauseparam(struct net_device *dev,
|
||||
@@ -2314,12 +2312,10 @@ static int rtl8169_set_pauseparam(struct net_device *dev,
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
|
||||
if (dev->mtu > ETH_DATA_LEN)
|
||||
if (dev->mtu > ETH_DATA_LEN || data->autoneg == AUTONEG_DISABLE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
phy_set_asym_pause(tp->phydev, data->rx_pause, data->tx_pause);
|
||||
|
||||
return 0;
|
||||
return phylink_ethtool_set_pauseparam(tp->phylink, data);
|
||||
}
|
||||
|
||||
static void rtl8169_get_eth_mac_stats(struct net_device *dev,
|
||||
@@ -2385,6 +2381,14 @@ static void rtl8169_get_eth_ctrl_stats(struct net_device *dev,
|
||||
le32_to_cpu(tp->counters->rx_unknown_opcode);
|
||||
}
|
||||
|
||||
static int rtl8169_get_link_ksettings(struct net_device *ndev,
|
||||
struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(ndev);
|
||||
|
||||
return phylink_ethtool_ksettings_get(tp->phylink, cmd);
|
||||
}
|
||||
|
||||
static int rtl8169_set_link_ksettings(struct net_device *ndev,
|
||||
const struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
@@ -2394,7 +2398,7 @@ static int rtl8169_set_link_ksettings(struct net_device *ndev,
|
||||
int speed = cmd->base.speed;
|
||||
|
||||
if (!tp->sfp_mode)
|
||||
return phy_ethtool_ksettings_set(phydev, cmd);
|
||||
return phylink_ethtool_ksettings_set(tp->phylink, cmd);
|
||||
|
||||
if (cmd->base.autoneg != AUTONEG_DISABLE)
|
||||
return -EINVAL;
|
||||
@@ -2415,6 +2419,13 @@ static int rtl8169_set_link_ksettings(struct net_device *ndev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8169_nway_reset(struct net_device *dev)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
|
||||
return phylink_ethtool_nway_reset(tp->phylink);
|
||||
}
|
||||
|
||||
static const struct ethtool_ops rtl8169_ethtool_ops = {
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_MAX_FRAMES,
|
||||
@@ -2430,10 +2441,10 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
|
||||
.get_sset_count = rtl8169_get_sset_count,
|
||||
.get_ethtool_stats = rtl8169_get_ethtool_stats,
|
||||
.get_ts_info = ethtool_op_get_ts_info,
|
||||
.nway_reset = phy_ethtool_nway_reset,
|
||||
.nway_reset = rtl8169_nway_reset,
|
||||
.get_eee = rtl8169_get_eee,
|
||||
.set_eee = rtl8169_set_eee,
|
||||
.get_link_ksettings = phy_ethtool_get_link_ksettings,
|
||||
.get_link_ksettings = rtl8169_get_link_ksettings,
|
||||
.set_link_ksettings = rtl8169_set_link_ksettings,
|
||||
.get_ringparam = rtl8169_get_ringparam,
|
||||
.get_pause_stats = rtl8169_get_pause_stats,
|
||||
@@ -2656,15 +2667,6 @@ static void rtl_jumbo_config(struct rtl8169_private *tp)
|
||||
|
||||
if (pci_is_pcie(tp->pci_dev) && tp->supports_gmii)
|
||||
pcie_set_readrq(tp->pci_dev, readrq);
|
||||
|
||||
/* Chip doesn't support pause in jumbo mode */
|
||||
if (jumbo) {
|
||||
linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
|
||||
tp->phydev->advertising);
|
||||
linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
|
||||
tp->phydev->advertising);
|
||||
phy_start_aneg(tp->phydev);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_RTL_COND(rtl_chipcmd_cond)
|
||||
@@ -2779,7 +2781,7 @@ static void rtl_prepare_power_down(struct rtl8169_private *tp)
|
||||
rtl_ephy_write(tp, 0x19, 0xff64);
|
||||
|
||||
if (device_may_wakeup(tp_to_dev(tp))) {
|
||||
phy_speed_down(tp->phydev, false);
|
||||
phylink_speed_down(tp->phylink, false);
|
||||
rtl_wol_enable_rx(tp);
|
||||
}
|
||||
}
|
||||
@@ -2831,6 +2833,16 @@ static void rtl8169_set_magic_reg(struct rtl8169_private *tp)
|
||||
RTL_W32(tp, 0x7c, val);
|
||||
}
|
||||
|
||||
static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
|
||||
if (!netif_running(dev))
|
||||
return -ENODEV;
|
||||
|
||||
return phylink_mii_ioctl(tp->phylink, ifr, cmd);
|
||||
}
|
||||
|
||||
static void rtl_set_rx_mode(struct net_device *dev)
|
||||
{
|
||||
u32 rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
|
||||
@@ -4138,12 +4150,23 @@ static void rtl_hw_start(struct rtl8169_private *tp)
|
||||
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
bool jumbo_before = dev->mtu > ETH_DATA_LEN;
|
||||
bool jumbo_after = new_mtu > ETH_DATA_LEN;
|
||||
|
||||
WRITE_ONCE(dev->mtu, new_mtu);
|
||||
netdev_update_features(dev);
|
||||
rtl_jumbo_config(tp);
|
||||
rtl_set_eee_txidle_timer(tp);
|
||||
|
||||
if (jumbo_before != jumbo_after) {
|
||||
unsigned long caps = 0;
|
||||
|
||||
if (!jumbo_after)
|
||||
caps |= (MAC_SYM_PAUSE | MAC_ASYM_PAUSE);
|
||||
|
||||
phylink_update_mac_pause_capabilities(tp->phylink, caps);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4929,9 +4952,6 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
|
||||
|
||||
static void rtl_enable_tx_lpi(struct rtl8169_private *tp, bool enable)
|
||||
{
|
||||
if (!rtl_supports_eee(tp))
|
||||
return;
|
||||
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_52:
|
||||
/* Adjust EEE LED frequency */
|
||||
@@ -4962,41 +4982,15 @@ static void rtl_enable_tx_lpi(struct rtl8169_private *tp, bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
static void r8169_phylink_handler(struct net_device *ndev)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(ndev);
|
||||
struct device *d = tp_to_dev(tp);
|
||||
|
||||
tp->speed = tp->phydev->speed;
|
||||
if (netif_carrier_ok(ndev)) {
|
||||
rtl_link_chg_patch(tp, tp->speed);
|
||||
rtl_enable_tx_lpi(tp, tp->phydev->enable_tx_lpi);
|
||||
pm_request_resume(d);
|
||||
} else {
|
||||
pm_runtime_idle(d);
|
||||
}
|
||||
|
||||
phy_print_status(tp->phydev);
|
||||
}
|
||||
|
||||
static int r8169_phy_connect(struct rtl8169_private *tp)
|
||||
{
|
||||
struct phy_device *phydev = tp->phydev;
|
||||
phy_interface_t phy_mode;
|
||||
int ret;
|
||||
|
||||
phy_mode = tp->supports_gmii ? PHY_INTERFACE_MODE_GMII :
|
||||
PHY_INTERFACE_MODE_MII;
|
||||
|
||||
ret = phy_connect_direct(tp->dev, phydev, r8169_phylink_handler,
|
||||
phy_mode);
|
||||
if (ret)
|
||||
ret = phylink_connect_phy(tp->phylink, tp->phydev);
|
||||
if (ret) {
|
||||
netdev_err(tp->dev, "failed to connect phy\n");
|
||||
return ret;
|
||||
|
||||
if (!tp->supports_gmii)
|
||||
phy_set_max_speed(phydev, SPEED_100);
|
||||
|
||||
phy_attached_info(phydev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -5007,8 +5001,6 @@ static void rtl8169_down(struct rtl8169_private *tp)
|
||||
/* Clear all task flags */
|
||||
bitmap_zero(tp->wk.flags, RTL_FLAG_MAX);
|
||||
|
||||
phy_stop(tp->phydev);
|
||||
|
||||
/* Reset SerDes PHY to bring down fiber link */
|
||||
if (tp->sfp_mode)
|
||||
rtl_sfp_reset(tp);
|
||||
@@ -5038,8 +5030,6 @@ static void rtl8169_up(struct rtl8169_private *tp)
|
||||
napi_enable(&tp->napi);
|
||||
enable_work(&tp->wk.work);
|
||||
rtl_reset_work(tp);
|
||||
|
||||
phy_start(tp->phydev);
|
||||
}
|
||||
|
||||
static int rtl8169_close(struct net_device *dev)
|
||||
@@ -5049,13 +5039,14 @@ static int rtl8169_close(struct net_device *dev)
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
phylink_stop(tp->phylink);
|
||||
netif_stop_queue(dev);
|
||||
rtl8169_down(tp);
|
||||
rtl8169_rx_clear(tp);
|
||||
|
||||
free_irq(tp->irq, tp);
|
||||
|
||||
phy_disconnect(tp->phydev);
|
||||
phylink_disconnect_phy(tp->phylink);
|
||||
|
||||
dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
|
||||
tp->RxPhyAddr);
|
||||
@@ -5117,6 +5108,7 @@ static int rtl_open(struct net_device *dev)
|
||||
goto err_free_irq;
|
||||
|
||||
rtl8169_up(tp);
|
||||
phylink_start(tp->phylink);
|
||||
rtl8169_init_counter_offsets(tp);
|
||||
netif_start_queue(dev);
|
||||
out:
|
||||
@@ -5288,6 +5280,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
|
||||
r8169_remove_leds(tp->leds);
|
||||
|
||||
unregister_netdev(tp->dev);
|
||||
phylink_destroy(tp->phylink);
|
||||
|
||||
if (tp->dash_type != RTL_DASH_NONE)
|
||||
rtl8168_driver_stop(tp);
|
||||
@@ -5310,7 +5303,7 @@ static const struct net_device_ops rtl_netdev_ops = {
|
||||
.ndo_fix_features = rtl8169_fix_features,
|
||||
.ndo_set_features = rtl8169_set_features,
|
||||
.ndo_set_mac_address = rtl_set_mac_address,
|
||||
.ndo_eth_ioctl = phy_do_ioctl_running,
|
||||
.ndo_eth_ioctl = rtl8169_ioctl,
|
||||
.ndo_set_rx_mode = rtl_set_rx_mode,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = rtl8169_netpoll,
|
||||
@@ -5474,16 +5467,6 @@ static int r8169_mdio_register(struct rtl8169_private *tp)
|
||||
return -EUNATCH;
|
||||
}
|
||||
|
||||
tp->phydev->mac_managed_pm = true;
|
||||
if (rtl_supports_eee(tp))
|
||||
phy_support_eee(tp->phydev);
|
||||
phy_support_asym_pause(tp->phydev);
|
||||
|
||||
/* mimic behavior of r8125/r8126 vendor drivers */
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_61)
|
||||
phy_disable_eee_mode(tp->phydev,
|
||||
ETHTOOL_LINK_MODE_2500baseT_Full_BIT);
|
||||
|
||||
/* PHY will be woken up in rtl_open() */
|
||||
phy_suspend(tp->phydev);
|
||||
|
||||
@@ -5599,6 +5582,159 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rtl_mac_link_down(struct phylink_config *config, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
struct rtl8169_private *tp = container_of(config,
|
||||
struct rtl8169_private,
|
||||
phylink_config);
|
||||
|
||||
tp->speed = SPEED_UNKNOWN;
|
||||
pm_runtime_idle(tp_to_dev(tp));
|
||||
}
|
||||
|
||||
static void rtl_mac_link_up(struct phylink_config *config,
|
||||
struct phy_device *phydev,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
int speed, int duplex,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
struct rtl8169_private *tp = container_of(config,
|
||||
struct rtl8169_private,
|
||||
phylink_config);
|
||||
struct device *d = tp_to_dev(tp);
|
||||
|
||||
tp->speed = speed;
|
||||
rtl_link_chg_patch(tp, speed);
|
||||
|
||||
/*
|
||||
* Note: This hardware does not support forcing flow control.
|
||||
* Tx/Rx pause is completely hardwired: if autoneg is ON, hardware
|
||||
* handles it automatically based on PHY result; if autoneg is OFF,
|
||||
* hardware forces pause to be disabled. No software override exists.
|
||||
*/
|
||||
pm_request_resume(d);
|
||||
}
|
||||
|
||||
static struct phylink_pcs *rtl_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rtl_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
}
|
||||
|
||||
static void rtl_mac_disable_tx_lpi(struct phylink_config *config)
|
||||
{
|
||||
struct rtl8169_private *tp = container_of(config,
|
||||
struct rtl8169_private,
|
||||
phylink_config);
|
||||
|
||||
rtl_enable_tx_lpi(tp, false);
|
||||
}
|
||||
|
||||
static int rtl_mac_enable_tx_lpi(struct phylink_config *config,
|
||||
u32 timer,
|
||||
bool tx_clk_stop)
|
||||
{
|
||||
struct rtl8169_private *tp = container_of(config,
|
||||
struct rtl8169_private,
|
||||
phylink_config);
|
||||
|
||||
rtl_enable_tx_lpi(tp, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phylink_mac_ops rtl_phylink_mac_ops = {
|
||||
.mac_select_pcs = rtl_mac_select_pcs,
|
||||
.mac_config = rtl_mac_config,
|
||||
.mac_link_down = rtl_mac_link_down,
|
||||
.mac_link_up = rtl_mac_link_up,
|
||||
.mac_disable_tx_lpi = rtl_mac_disable_tx_lpi,
|
||||
.mac_enable_tx_lpi = rtl_mac_enable_tx_lpi,
|
||||
};
|
||||
|
||||
static unsigned long rtl8169_get_lpi_caps(struct rtl8169_private *tp)
|
||||
{
|
||||
unsigned long caps = 0;
|
||||
|
||||
if (!rtl_supports_eee(tp))
|
||||
return 0;
|
||||
|
||||
caps |= MAC_100FD | MAC_1000FD;
|
||||
|
||||
/* mimic behavior of r8125/r8126 vendor drivers
|
||||
* RTL_GIGA_MAC_VER_61 doesn't support 2.5G eee
|
||||
*/
|
||||
if (tp->mac_version >= RTL_GIGA_MAC_VER_63)
|
||||
caps |= MAC_2500FD;
|
||||
if (tp->mac_version >= RTL_GIGA_MAC_VER_70)
|
||||
caps |= MAC_5000FD;
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_80)
|
||||
caps |= MAC_10000FD;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static int rtl_init_phylink(struct rtl8169_private *tp)
|
||||
{
|
||||
struct phylink *pl;
|
||||
phy_interface_t phy_mode;
|
||||
|
||||
tp->phylink_config.dev = &tp->dev->dev;
|
||||
tp->phylink_config.type = PHYLINK_NETDEV;
|
||||
tp->phylink_config.mac_managed_pm = true;
|
||||
tp->phylink_config.lpi_capabilities = rtl8169_get_lpi_caps(tp);
|
||||
tp->phylink_config.mac_capabilities |= MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
|
||||
|
||||
if (tp->sfp_mode) {
|
||||
phy_mode = PHY_INTERFACE_MODE_INTERNAL;
|
||||
tp->phylink_config.mac_capabilities |= MAC_10000FD;
|
||||
} else {
|
||||
tp->phylink_config.mac_capabilities |= MAC_10 | MAC_100;
|
||||
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_80)
|
||||
tp->phylink_config.mac_capabilities |= MAC_1000FD |
|
||||
MAC_2500FD |
|
||||
MAC_5000FD |
|
||||
MAC_10000FD;
|
||||
else if (tp->mac_version == RTL_GIGA_MAC_VER_70)
|
||||
tp->phylink_config.mac_capabilities |= MAC_1000FD |
|
||||
MAC_2500FD |
|
||||
MAC_5000FD;
|
||||
else if (tp->mac_version >= RTL_GIGA_MAC_VER_61)
|
||||
tp->phylink_config.mac_capabilities |= MAC_1000FD |
|
||||
MAC_2500FD;
|
||||
else
|
||||
if (tp->supports_gmii)
|
||||
tp->phylink_config.mac_capabilities |= MAC_1000FD;
|
||||
|
||||
if (tp->mac_version < RTL_GIGA_MAC_VER_61)
|
||||
phy_mode = tp->supports_gmii ? PHY_INTERFACE_MODE_GMII :
|
||||
PHY_INTERFACE_MODE_MII;
|
||||
else
|
||||
phy_mode = PHY_INTERFACE_MODE_INTERNAL;
|
||||
}
|
||||
|
||||
__set_bit(phy_mode, tp->phylink_config.supported_interfaces);
|
||||
if (tp->phylink_config.lpi_capabilities)
|
||||
__set_bit(phy_mode, tp->phylink_config.lpi_interfaces);
|
||||
|
||||
pl = phylink_create(&tp->phylink_config, tp_to_dev(tp)->fwnode,
|
||||
phy_mode, &rtl_phylink_mac_ops);
|
||||
if (IS_ERR(pl))
|
||||
return PTR_ERR(pl);
|
||||
|
||||
tp->phylink = pl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
const struct rtl_chip_info *chip;
|
||||
@@ -5789,13 +5925,21 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
||||
pci_set_drvdata(pdev, tp);
|
||||
|
||||
rc = r8169_mdio_register(tp);
|
||||
rc = rtl_init_phylink(tp);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = register_netdev(dev);
|
||||
if (rc)
|
||||
rc = r8169_mdio_register(tp);
|
||||
if (rc) {
|
||||
phylink_destroy(tp->phylink);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = register_netdev(dev);
|
||||
if (rc) {
|
||||
phylink_destroy(tp->phylink);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_R8169_LEDS)) {
|
||||
if (rtl_is_8125(tp))
|
||||
|
||||
Reference in new issue
Block a user