Skip to content

Commit 7c2dcfa

Browse files
HoratiuVulturdavem330
authored andcommitted
net: phy: micrel: Add support for LAN8804 PHY
The LAN8804 PHY has same features as that of LAN8814 PHY except that it doesn't support 1588, SyncE or Q-USGMII. This PHY is found inside the LAN966X switches. Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: Horatiu Vultur <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 49f0134 commit 7c2dcfa

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

drivers/net/phy/micrel.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,65 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev,
15371537
return ret;
15381538
}
15391539

1540+
#define LAN_EXT_PAGE_ACCESS_CONTROL 0x16
1541+
#define LAN_EXT_PAGE_ACCESS_ADDRESS_DATA 0x17
1542+
#define LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC 0x4000
1543+
1544+
#define LAN8804_ALIGN_SWAP 0x4a
1545+
#define LAN8804_ALIGN_TX_A_B_SWAP 0x1
1546+
#define LAN8804_ALIGN_TX_A_B_SWAP_MASK GENMASK(2, 0)
1547+
#define LAN8814_CLOCK_MANAGEMENT 0xd
1548+
#define LAN8814_LINK_QUALITY 0x8e
1549+
1550+
static int lanphy_read_page_reg(struct phy_device *phydev, int page, u32 addr)
1551+
{
1552+
u32 data;
1553+
1554+
phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
1555+
phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
1556+
phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
1557+
(page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
1558+
data = phy_read(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA);
1559+
1560+
return data;
1561+
}
1562+
1563+
static int lanphy_write_page_reg(struct phy_device *phydev, int page, u16 addr,
1564+
u16 val)
1565+
{
1566+
phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
1567+
phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
1568+
phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
1569+
(page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
1570+
1571+
val = phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, val);
1572+
if (val) {
1573+
phydev_err(phydev, "Error: phy_write has returned error %d\n",
1574+
val);
1575+
return val;
1576+
}
1577+
return 0;
1578+
}
1579+
1580+
static int lan8804_config_init(struct phy_device *phydev)
1581+
{
1582+
int val;
1583+
1584+
/* MDI-X setting for swap A,B transmit */
1585+
val = lanphy_read_page_reg(phydev, 2, LAN8804_ALIGN_SWAP);
1586+
val &= ~LAN8804_ALIGN_TX_A_B_SWAP_MASK;
1587+
val |= LAN8804_ALIGN_TX_A_B_SWAP;
1588+
lanphy_write_page_reg(phydev, 2, LAN8804_ALIGN_SWAP, val);
1589+
1590+
/* Make sure that the PHY will not stop generating the clock when the
1591+
* link partner goes down
1592+
*/
1593+
lanphy_write_page_reg(phydev, 31, LAN8814_CLOCK_MANAGEMENT, 0x27e);
1594+
lanphy_read_page_reg(phydev, 1, LAN8814_LINK_QUALITY);
1595+
1596+
return 0;
1597+
}
1598+
15401599
static struct phy_driver ksphy_driver[] = {
15411600
{
15421601
.phy_id = PHY_ID_KS8737,
@@ -1718,6 +1777,20 @@ static struct phy_driver ksphy_driver[] = {
17181777
.get_stats = kszphy_get_stats,
17191778
.suspend = genphy_suspend,
17201779
.resume = kszphy_resume,
1780+
}, {
1781+
.phy_id = PHY_ID_LAN8804,
1782+
.phy_id_mask = MICREL_PHY_ID_MASK,
1783+
.name = "Microchip LAN966X Gigabit PHY",
1784+
.config_init = lan8804_config_init,
1785+
.driver_data = &ksz9021_type,
1786+
.probe = kszphy_probe,
1787+
.soft_reset = genphy_soft_reset,
1788+
.read_status = ksz9031_read_status,
1789+
.get_sset_count = kszphy_get_sset_count,
1790+
.get_strings = kszphy_get_strings,
1791+
.get_stats = kszphy_get_stats,
1792+
.suspend = genphy_suspend,
1793+
.resume = kszphy_resume,
17211794
}, {
17221795
.phy_id = PHY_ID_KSZ9131,
17231796
.phy_id_mask = MICREL_PHY_ID_MASK,
@@ -1794,6 +1867,7 @@ static struct mdio_device_id __maybe_unused micrel_tbl[] = {
17941867
{ PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK },
17951868
{ PHY_ID_KSZ886X, MICREL_PHY_ID_MASK },
17961869
{ PHY_ID_LAN8814, MICREL_PHY_ID_MASK },
1870+
{ PHY_ID_LAN8804, MICREL_PHY_ID_MASK },
17971871
{ }
17981872
};
17991873

include/linux/micrel_phy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define PHY_ID_KSZ9031 0x00221620
2929
#define PHY_ID_KSZ9131 0x00221640
3030
#define PHY_ID_LAN8814 0x00221660
31+
#define PHY_ID_LAN8804 0x00221670
3132

3233
#define PHY_ID_KSZ886X 0x00221430
3334
#define PHY_ID_KSZ8863 0x00221435

0 commit comments

Comments
 (0)