|
@@ -27,6 +27,11 @@ enum rgmii_rx_clock_delay {
|
|
|
|
|
|
/* Microsemi VSC85xx PHY registers */
|
|
/* Microsemi VSC85xx PHY registers */
|
|
/* IEEE 802. Std Registers */
|
|
/* IEEE 802. Std Registers */
|
|
|
|
+#define MSCC_PHY_BYPASS_CONTROL 18
|
|
|
|
+#define DISABLE_HP_AUTO_MDIX_MASK 0x0080
|
|
|
|
+#define DISABLE_PAIR_SWAP_CORR_MASK 0x0020
|
|
|
|
+#define DISABLE_POLARITY_CORR_MASK 0x0010
|
|
|
|
+
|
|
#define MSCC_PHY_EXT_PHY_CNTL_1 23
|
|
#define MSCC_PHY_EXT_PHY_CNTL_1 23
|
|
#define MAC_IF_SELECTION_MASK 0x1800
|
|
#define MAC_IF_SELECTION_MASK 0x1800
|
|
#define MAC_IF_SELECTION_GMII 0
|
|
#define MAC_IF_SELECTION_GMII 0
|
|
@@ -44,12 +49,20 @@ enum rgmii_rx_clock_delay {
|
|
#define EDGE_RATE_CNTL_POS 5
|
|
#define EDGE_RATE_CNTL_POS 5
|
|
#define EDGE_RATE_CNTL_MASK 0x00E0
|
|
#define EDGE_RATE_CNTL_MASK 0x00E0
|
|
|
|
|
|
|
|
+#define MSCC_PHY_DEV_AUX_CNTL 28
|
|
|
|
+#define HP_AUTO_MDIX_X_OVER_IND_MASK 0x2000
|
|
|
|
+
|
|
#define MSCC_EXT_PAGE_ACCESS 31
|
|
#define MSCC_EXT_PAGE_ACCESS 31
|
|
#define MSCC_PHY_PAGE_STANDARD 0x0000 /* Standard registers */
|
|
#define MSCC_PHY_PAGE_STANDARD 0x0000 /* Standard registers */
|
|
#define MSCC_PHY_PAGE_EXTENDED 0x0001 /* Extended registers */
|
|
#define MSCC_PHY_PAGE_EXTENDED 0x0001 /* Extended registers */
|
|
#define MSCC_PHY_PAGE_EXTENDED_2 0x0002 /* Extended reg - page 2 */
|
|
#define MSCC_PHY_PAGE_EXTENDED_2 0x0002 /* Extended reg - page 2 */
|
|
|
|
|
|
/* Extended Page 1 Registers */
|
|
/* Extended Page 1 Registers */
|
|
|
|
+#define MSCC_PHY_EXT_MODE_CNTL 19
|
|
|
|
+#define FORCE_MDI_CROSSOVER_MASK 0x000C
|
|
|
|
+#define FORCE_MDI_CROSSOVER_MDIX 0x000C
|
|
|
|
+#define FORCE_MDI_CROSSOVER_MDI 0x0008
|
|
|
|
+
|
|
#define MSCC_PHY_ACTIPHY_CNTL 20
|
|
#define MSCC_PHY_ACTIPHY_CNTL 20
|
|
#define DOWNSHIFT_CNTL_MASK 0x001C
|
|
#define DOWNSHIFT_CNTL_MASK 0x001C
|
|
#define DOWNSHIFT_EN 0x0010
|
|
#define DOWNSHIFT_EN 0x0010
|
|
@@ -110,6 +123,59 @@ static int vsc85xx_phy_page_set(struct phy_device *phydev, u8 page)
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
|
|
|
|
+{
|
|
|
|
+ u16 reg_val;
|
|
|
|
+
|
|
|
|
+ reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
|
|
|
|
+ if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
|
|
|
|
+ *mdix = ETH_TP_MDI_X;
|
|
|
|
+ else
|
|
|
|
+ *mdix = ETH_TP_MDI;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
|
|
|
|
+{
|
|
|
|
+ int rc;
|
|
|
|
+ u16 reg_val;
|
|
|
|
+
|
|
|
|
+ reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
|
|
|
|
+ if ((mdix == ETH_TP_MDI) || (mdix == ETH_TP_MDI_X)) {
|
|
|
|
+ reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
|
|
|
|
+ DISABLE_POLARITY_CORR_MASK |
|
|
|
|
+ DISABLE_HP_AUTO_MDIX_MASK);
|
|
|
|
+ } else {
|
|
|
|
+ reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
|
|
|
|
+ DISABLE_POLARITY_CORR_MASK |
|
|
|
|
+ DISABLE_HP_AUTO_MDIX_MASK);
|
|
|
|
+ }
|
|
|
|
+ rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_EXTENDED);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ reg_val = phy_read(phydev, MSCC_PHY_EXT_MODE_CNTL);
|
|
|
|
+ reg_val &= ~(FORCE_MDI_CROSSOVER_MASK);
|
|
|
|
+ if (mdix == ETH_TP_MDI)
|
|
|
|
+ reg_val |= FORCE_MDI_CROSSOVER_MDI;
|
|
|
|
+ else if (mdix == ETH_TP_MDI_X)
|
|
|
|
+ reg_val |= FORCE_MDI_CROSSOVER_MDIX;
|
|
|
|
+ rc = phy_write(phydev, MSCC_PHY_EXT_MODE_CNTL, reg_val);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_STANDARD);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ return genphy_restart_aneg(phydev);
|
|
|
|
+}
|
|
|
|
+
|
|
static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
|
|
static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
|
|
{
|
|
{
|
|
int rc;
|
|
int rc;
|
|
@@ -375,6 +441,7 @@ static int vsc85xx_default_config(struct phy_device *phydev)
|
|
int rc;
|
|
int rc;
|
|
u16 reg_val;
|
|
u16 reg_val;
|
|
|
|
|
|
|
|
+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
|
|
mutex_lock(&phydev->lock);
|
|
mutex_lock(&phydev->lock);
|
|
rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_EXTENDED_2);
|
|
rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_EXTENDED_2);
|
|
if (rc != 0)
|
|
if (rc != 0)
|
|
@@ -464,6 +531,28 @@ static int vsc85xx_config_intr(struct phy_device *phydev)
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int vsc85xx_config_aneg(struct phy_device *phydev)
|
|
|
|
+{
|
|
|
|
+ int rc;
|
|
|
|
+
|
|
|
|
+ rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
|
|
|
|
+ if (rc < 0)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ return genphy_config_aneg(phydev);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int vsc85xx_read_status(struct phy_device *phydev)
|
|
|
|
+{
|
|
|
|
+ int rc;
|
|
|
|
+
|
|
|
|
+ rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
|
|
|
|
+ if (rc < 0)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ return genphy_read_status(phydev);
|
|
|
|
+}
|
|
|
|
+
|
|
static int vsc85xx_probe(struct phy_device *phydev)
|
|
static int vsc85xx_probe(struct phy_device *phydev)
|
|
{
|
|
{
|
|
int rate_magic;
|
|
int rate_magic;
|
|
@@ -494,9 +583,9 @@ static struct phy_driver vsc85xx_driver[] = {
|
|
.flags = PHY_HAS_INTERRUPT,
|
|
.flags = PHY_HAS_INTERRUPT,
|
|
.soft_reset = &genphy_soft_reset,
|
|
.soft_reset = &genphy_soft_reset,
|
|
.config_init = &vsc85xx_config_init,
|
|
.config_init = &vsc85xx_config_init,
|
|
- .config_aneg = &genphy_config_aneg,
|
|
|
|
|
|
+ .config_aneg = &vsc85xx_config_aneg,
|
|
.aneg_done = &genphy_aneg_done,
|
|
.aneg_done = &genphy_aneg_done,
|
|
- .read_status = &genphy_read_status,
|
|
|
|
|
|
+ .read_status = &vsc85xx_read_status,
|
|
.ack_interrupt = &vsc85xx_ack_interrupt,
|
|
.ack_interrupt = &vsc85xx_ack_interrupt,
|
|
.config_intr = &vsc85xx_config_intr,
|
|
.config_intr = &vsc85xx_config_intr,
|
|
.suspend = &genphy_suspend,
|
|
.suspend = &genphy_suspend,
|
|
@@ -515,9 +604,9 @@ static struct phy_driver vsc85xx_driver[] = {
|
|
.flags = PHY_HAS_INTERRUPT,
|
|
.flags = PHY_HAS_INTERRUPT,
|
|
.soft_reset = &genphy_soft_reset,
|
|
.soft_reset = &genphy_soft_reset,
|
|
.config_init = &vsc85xx_config_init,
|
|
.config_init = &vsc85xx_config_init,
|
|
- .config_aneg = &genphy_config_aneg,
|
|
|
|
|
|
+ .config_aneg = &vsc85xx_config_aneg,
|
|
.aneg_done = &genphy_aneg_done,
|
|
.aneg_done = &genphy_aneg_done,
|
|
- .read_status = &genphy_read_status,
|
|
|
|
|
|
+ .read_status = &vsc85xx_read_status,
|
|
.ack_interrupt = &vsc85xx_ack_interrupt,
|
|
.ack_interrupt = &vsc85xx_ack_interrupt,
|
|
.config_intr = &vsc85xx_config_intr,
|
|
.config_intr = &vsc85xx_config_intr,
|
|
.suspend = &genphy_suspend,
|
|
.suspend = &genphy_suspend,
|
|
@@ -536,9 +625,9 @@ static struct phy_driver vsc85xx_driver[] = {
|
|
.flags = PHY_HAS_INTERRUPT,
|
|
.flags = PHY_HAS_INTERRUPT,
|
|
.soft_reset = &genphy_soft_reset,
|
|
.soft_reset = &genphy_soft_reset,
|
|
.config_init = &vsc85xx_config_init,
|
|
.config_init = &vsc85xx_config_init,
|
|
- .config_aneg = &genphy_config_aneg,
|
|
|
|
|
|
+ .config_aneg = &vsc85xx_config_aneg,
|
|
.aneg_done = &genphy_aneg_done,
|
|
.aneg_done = &genphy_aneg_done,
|
|
- .read_status = &genphy_read_status,
|
|
|
|
|
|
+ .read_status = &vsc85xx_read_status,
|
|
.ack_interrupt = &vsc85xx_ack_interrupt,
|
|
.ack_interrupt = &vsc85xx_ack_interrupt,
|
|
.config_intr = &vsc85xx_config_intr,
|
|
.config_intr = &vsc85xx_config_intr,
|
|
.suspend = &genphy_suspend,
|
|
.suspend = &genphy_suspend,
|
|
@@ -557,9 +646,9 @@ static struct phy_driver vsc85xx_driver[] = {
|
|
.flags = PHY_HAS_INTERRUPT,
|
|
.flags = PHY_HAS_INTERRUPT,
|
|
.soft_reset = &genphy_soft_reset,
|
|
.soft_reset = &genphy_soft_reset,
|
|
.config_init = &vsc85xx_config_init,
|
|
.config_init = &vsc85xx_config_init,
|
|
- .config_aneg = &genphy_config_aneg,
|
|
|
|
|
|
+ .config_aneg = &vsc85xx_config_aneg,
|
|
.aneg_done = &genphy_aneg_done,
|
|
.aneg_done = &genphy_aneg_done,
|
|
- .read_status = &genphy_read_status,
|
|
|
|
|
|
+ .read_status = &vsc85xx_read_status,
|
|
.ack_interrupt = &vsc85xx_ack_interrupt,
|
|
.ack_interrupt = &vsc85xx_ack_interrupt,
|
|
.config_intr = &vsc85xx_config_intr,
|
|
.config_intr = &vsc85xx_config_intr,
|
|
.suspend = &genphy_suspend,
|
|
.suspend = &genphy_suspend,
|