Skip to content

Commit d50736a

Browse files
Raju Lakkarajudavem330
authored andcommitted
Microsemi VSC 8531/41 PHY Driver
Hello, I added all review comments and re-sending for review. >From a5017f5878a92d2acec86a6a29b1498c457cb73a Mon Sep 17 00:00:00 2001 From: Nagaraju Lakkaraju <[email protected]> Date: Wed, 3 Aug 2016 18:28:24 +0530 Subject: [PATCH v2] net: phy: Add drivers for Microsemi PHYs Signed-off-by: Nagaraju Lakkaraju <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 07bf2e1 commit d50736a

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed

drivers/net/phy/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@ config MDIO_XGENE
307307
This module provides a driver for the MDIO busses found in the
308308
APM X-Gene SoC's.
309309

310+
config MICROSEMI_PHY
311+
tristate "Drivers for the Microsemi PHYs"
312+
---help---
313+
Currently supports the VSC8531 and VSC8541 PHYs
314+
310315
endif # PHYLIB
311316

312317
config MICREL_KS8995MA

drivers/net/phy/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ obj-$(CONFIG_CICADA_PHY) += cicada.o
1111
obj-$(CONFIG_LXT_PHY) += lxt.o
1212
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
1313
obj-$(CONFIG_SMSC_PHY) += smsc.o
14+
obj-$(CONFIG_MICROSEMI_PHY) += mscc.o
1415
obj-$(CONFIG_TERANETICS_PHY) += teranetics.o
1516
obj-$(CONFIG_VITESSE_PHY) += vitesse.o
1617
obj-$(CONFIG_BCM_NET_PHYLIB) += bcm-phy-lib.o

drivers/net/phy/mscc.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Driver for Microsemi VSC85xx PHYs
3+
*
4+
* Author: Nagaraju Lakkaraju
5+
* License: Dual MIT/GPL
6+
* Copyright (c) 2016 Microsemi Corporation
7+
*/
8+
9+
#include <linux/kernel.h>
10+
#include <linux/module.h>
11+
#include <linux/mdio.h>
12+
#include <linux/mii.h>
13+
#include <linux/phy.h>
14+
15+
enum rgmii_rx_clock_delay {
16+
RGMII_RX_CLK_DELAY_0_2_NS = 0,
17+
RGMII_RX_CLK_DELAY_0_8_NS = 1,
18+
RGMII_RX_CLK_DELAY_1_1_NS = 2,
19+
RGMII_RX_CLK_DELAY_1_7_NS = 3,
20+
RGMII_RX_CLK_DELAY_2_0_NS = 4,
21+
RGMII_RX_CLK_DELAY_2_3_NS = 5,
22+
RGMII_RX_CLK_DELAY_2_6_NS = 6,
23+
RGMII_RX_CLK_DELAY_3_4_NS = 7
24+
};
25+
26+
#define MII_VSC85XX_INT_MASK 25
27+
#define MII_VSC85XX_INT_MASK_MASK 0xa000
28+
#define MII_VSC85XX_INT_STATUS 26
29+
30+
#define MSCC_EXT_PAGE_ACCESS 31
31+
#define MSCC_PHY_PAGE_STANDARD 0x0000 /* Standard registers */
32+
#define MSCC_PHY_PAGE_EXTENDED_2 0x0002 /* Extended reg - page 2 */
33+
34+
/* Extended Page 2 Registers */
35+
#define MSCC_PHY_RGMII_CNTL 20
36+
#define RGMII_RX_CLK_DELAY_MASK 0x0070
37+
#define RGMII_RX_CLK_DELAY_POS 4
38+
39+
/* Microsemi PHY ID's */
40+
#define PHY_ID_VSC8531 0x00070570
41+
#define PHY_ID_VSC8541 0x00070770
42+
43+
static int vsc85xx_phy_page_set(struct phy_device *phydev, u8 page)
44+
{
45+
int rc;
46+
47+
rc = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
48+
return rc;
49+
}
50+
51+
static int vsc85xx_default_config(struct phy_device *phydev)
52+
{
53+
int rc;
54+
u16 reg_val;
55+
56+
mutex_lock(&phydev->lock);
57+
rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_EXTENDED_2);
58+
if (rc != 0)
59+
goto out_unlock;
60+
61+
reg_val = phy_read(phydev, MSCC_PHY_RGMII_CNTL);
62+
reg_val &= ~(RGMII_RX_CLK_DELAY_MASK);
63+
reg_val |= (RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS);
64+
phy_write(phydev, MSCC_PHY_RGMII_CNTL, reg_val);
65+
rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_STANDARD);
66+
67+
out_unlock:
68+
mutex_unlock(&phydev->lock);
69+
70+
return rc;
71+
}
72+
73+
static int vsc85xx_config_init(struct phy_device *phydev)
74+
{
75+
int rc;
76+
77+
rc = vsc85xx_default_config(phydev);
78+
if (rc)
79+
return rc;
80+
rc = genphy_config_init(phydev);
81+
82+
return rc;
83+
}
84+
85+
static int vsc85xx_ack_interrupt(struct phy_device *phydev)
86+
{
87+
int rc;
88+
89+
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
90+
rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
91+
92+
return (rc < 0) ? rc : 0;
93+
}
94+
95+
static int vsc85xx_config_intr(struct phy_device *phydev)
96+
{
97+
int rc;
98+
99+
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
100+
rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
101+
MII_VSC85XX_INT_MASK_MASK);
102+
} else {
103+
rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
104+
if (rc < 0)
105+
return rc;
106+
rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
107+
}
108+
109+
return rc;
110+
}
111+
112+
/* Microsemi VSC85xx PHYs */
113+
static struct phy_driver vsc85xx_driver[] = {
114+
{
115+
.phy_id = PHY_ID_VSC8531,
116+
.name = "Microsemi VSC8531",
117+
.phy_id_mask = 0xfffffff0,
118+
.features = PHY_GBIT_FEATURES,
119+
.flags = PHY_HAS_INTERRUPT,
120+
.soft_reset = &genphy_soft_reset,
121+
.config_init = &vsc85xx_config_init,
122+
.config_aneg = &genphy_config_aneg,
123+
.aneg_done = &genphy_aneg_done,
124+
.read_status = &genphy_read_status,
125+
.ack_interrupt = &vsc85xx_ack_interrupt,
126+
.config_intr = &vsc85xx_config_intr,
127+
.suspend = &genphy_suspend,
128+
.resume = &genphy_resume,
129+
},
130+
{
131+
.phy_id = PHY_ID_VSC8541,
132+
.name = "Microsemi VSC8541 SyncE",
133+
.phy_id_mask = 0xfffffff0,
134+
.features = PHY_GBIT_FEATURES,
135+
.flags = PHY_HAS_INTERRUPT,
136+
.soft_reset = &genphy_soft_reset,
137+
.config_init = &vsc85xx_config_init,
138+
.config_aneg = &genphy_config_aneg,
139+
.aneg_done = &genphy_aneg_done,
140+
.read_status = &genphy_read_status,
141+
.ack_interrupt = &vsc85xx_ack_interrupt,
142+
.config_intr = &vsc85xx_config_intr,
143+
.suspend = &genphy_suspend,
144+
.resume = &genphy_resume,
145+
}
146+
147+
};
148+
149+
module_phy_driver(vsc85xx_driver);
150+
151+
static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
152+
{ PHY_ID_VSC8531, 0xfffffff0, },
153+
{ PHY_ID_VSC8541, 0xfffffff0, },
154+
{ }
155+
};
156+
157+
MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
158+
159+
MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
160+
MODULE_AUTHOR("Nagaraju Lakkaraju");
161+
MODULE_LICENSE("Dual MIT/GPL");

0 commit comments

Comments
 (0)