Skip to content

Commit

Permalink
Merge branch 'Add-phylib-support-to-smsc95xx'
Browse files Browse the repository at this point in the history
Andre Edich says:

====================
Add phylib support to smsc95xx

To allow to probe external PHY drivers, this patch series adds use of
phylib to the smsc95xx driver.

Changes in v5:
- Removed all phy_read calls from the smsc95xx driver.

Changes in v4:
- Removed useless inline type qualifier.

Changes in v3:
- Moved all MDI-X functionality to the corresponding phy driver;
- Removed field internal_phy from a struct smsc95xx_priv;
- Initialized field is_internal of a struct phy_device;
- Kconfig: Added selection of PHYLIB and SMSC_PHY for USB_NET_SMSC95XX.

Changes in v2:
- Moved 'net' patches from here to the separate patch series;
- Removed redundant call of the phy_start_aneg after phy_start;
- Removed netif_dbg tracing "speed, duplex, lcladv, and rmtadv";
- mdiobus: added dependency from the usbnet device;
- Moved making of the MII address from 'phy_id' and 'idx' into the
  function mii_address;
- Moved direct MDIO accesses under condition 'if (pdata->internal_phy)',
  as they only need for the internal PHY;
- To be sure, that this set of patches is git-bisectable, tested each
  sub-set of patches to be functional for both, internal and external
  PHYs, including suspend/resume test for the 'devices'
  (5.7.8-1-ARCH, Raspberry Pi 3 Model B).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 28, 2020
2 parents ae9a138 + 05b35e7 commit 0baf019
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 306 deletions.
67 changes: 67 additions & 0 deletions drivers/net/phy/smsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@
#include <linux/netdevice.h>
#include <linux/smscphy.h>

/* Vendor-specific PHY Definitions */
/* EDPD NLP / crossover time configuration */
#define PHY_EDPD_CONFIG 16
#define PHY_EDPD_CONFIG_EXT_CROSSOVER_ 0x0001

/* Control/Status Indication Register */
#define SPECIAL_CTRL_STS 27
#define SPECIAL_CTRL_STS_OVRRD_AMDIX_ 0x8000
#define SPECIAL_CTRL_STS_AMDIX_ENABLE_ 0x4000
#define SPECIAL_CTRL_STS_AMDIX_STATE_ 0x2000

struct smsc_hw_stat {
const char *string;
u8 reg;
Expand Down Expand Up @@ -96,6 +107,54 @@ static int lan911x_config_init(struct phy_device *phydev)
return smsc_phy_ack_interrupt(phydev);
}

static int lan87xx_config_aneg(struct phy_device *phydev)
{
int rc;
int val;

switch (phydev->mdix_ctrl) {
case ETH_TP_MDI:
val = SPECIAL_CTRL_STS_OVRRD_AMDIX_;
break;
case ETH_TP_MDI_X:
val = SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
SPECIAL_CTRL_STS_AMDIX_STATE_;
break;
case ETH_TP_MDI_AUTO:
val = SPECIAL_CTRL_STS_AMDIX_ENABLE_;
break;
default:
return genphy_config_aneg(phydev);
}

rc = phy_read(phydev, SPECIAL_CTRL_STS);
if (rc < 0)
return rc;

rc &= ~(SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
SPECIAL_CTRL_STS_AMDIX_ENABLE_ |
SPECIAL_CTRL_STS_AMDIX_STATE_);
rc |= val;
phy_write(phydev, SPECIAL_CTRL_STS, rc);

phydev->mdix = phydev->mdix_ctrl;
return genphy_config_aneg(phydev);
}

static int lan87xx_config_aneg_ext(struct phy_device *phydev)
{
int rc;

/* Extend Manual AutoMDIX timer */
rc = phy_read(phydev, PHY_EDPD_CONFIG);
if (rc < 0)
return rc;

rc |= PHY_EDPD_CONFIG_EXT_CROSSOVER_;
phy_write(phydev, PHY_EDPD_CONFIG, rc);
return lan87xx_config_aneg(phydev);
}

/*
* The LAN87xx suffers from rare absence of the ENERGYON-bit when Ethernet cable
* plugs in while LAN87xx is in Energy Detect Power-Down mode. This leads to
Expand Down Expand Up @@ -250,6 +309,9 @@ static struct phy_driver smsc_phy_driver[] = {
.suspend = genphy_suspend,
.resume = genphy_resume,
}, {
/* This covers internal PHY (phy_id: 0x0007C0C3) for
* LAN9500 (PID: 0x9500), LAN9514 (PID: 0xec00), LAN9505 (PID: 0x9505)
*/
.phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN8700",
Expand All @@ -262,6 +324,7 @@ static struct phy_driver smsc_phy_driver[] = {
.read_status = lan87xx_read_status,
.config_init = smsc_phy_config_init,
.soft_reset = smsc_phy_reset,
.config_aneg = lan87xx_config_aneg,

/* IRQ related */
.ack_interrupt = smsc_phy_ack_interrupt,
Expand Down Expand Up @@ -293,6 +356,9 @@ static struct phy_driver smsc_phy_driver[] = {
.suspend = genphy_suspend,
.resume = genphy_resume,
}, {
/* This covers internal PHY (phy_id: 0x0007C0F0) for
* LAN9500A (PID: 0x9E00), LAN9505A (PID: 0x9E01)
*/
.phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN8710/LAN8720",
Expand All @@ -306,6 +372,7 @@ static struct phy_driver smsc_phy_driver[] = {
.read_status = lan87xx_read_status,
.config_init = smsc_phy_config_init,
.soft_reset = smsc_phy_reset,
.config_aneg = lan87xx_config_aneg_ext,

/* IRQ related */
.ack_interrupt = smsc_phy_ack_interrupt,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ config USB_NET_SMSC75XX
config USB_NET_SMSC95XX
tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices"
depends on USB_USBNET
select PHYLIB
select SMSC_PHY
select BITREVERSE
select CRC16
select CRC32
Expand Down
Loading

0 comments on commit 0baf019

Please sign in to comment.