aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLendacky, Thomas <Thomas.Lendacky@amd.com>2014-09-03 13:14:22 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-05 18:11:20 -0400
commite6f0562ff42967a21708acc963ae12059d1d13e3 (patch)
tree4ae815dc8016dc5b1b46dc3477b266e6235e21ad /drivers/net
parente3eec4e79322957d9408dc4e2cf7276c558999d7 (diff)
amd-xgbe-phy: Enhance parallel detection to support KR speed
Add support to allow parallel detection to work in KR speed. With both speed modes of KX and KR supported, KX must be checked first. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/phy/amd-xgbe-phy.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/net/phy/amd-xgbe-phy.c b/drivers/net/phy/amd-xgbe-phy.c
index b3cef20637c0..da351d32b9f9 100644
--- a/drivers/net/phy/amd-xgbe-phy.c
+++ b/drivers/net/phy/amd-xgbe-phy.c
@@ -100,9 +100,11 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
100#ifndef MDIO_PMA_10GBR_PMD_CTRL 100#ifndef MDIO_PMA_10GBR_PMD_CTRL
101#define MDIO_PMA_10GBR_PMD_CTRL 0x0096 101#define MDIO_PMA_10GBR_PMD_CTRL 0x0096
102#endif 102#endif
103
103#ifndef MDIO_PMA_10GBR_FEC_CTRL 104#ifndef MDIO_PMA_10GBR_FEC_CTRL
104#define MDIO_PMA_10GBR_FEC_CTRL 0x00ab 105#define MDIO_PMA_10GBR_FEC_CTRL 0x00ab
105#endif 106#endif
107
106#ifndef MDIO_AN_XNP 108#ifndef MDIO_AN_XNP
107#define MDIO_AN_XNP 0x0016 109#define MDIO_AN_XNP 0x0016
108#endif 110#endif
@@ -110,14 +112,23 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
110#ifndef MDIO_AN_INTMASK 112#ifndef MDIO_AN_INTMASK
111#define MDIO_AN_INTMASK 0x8001 113#define MDIO_AN_INTMASK 0x8001
112#endif 114#endif
115
113#ifndef MDIO_AN_INT 116#ifndef MDIO_AN_INT
114#define MDIO_AN_INT 0x8002 117#define MDIO_AN_INT 0x8002
115#endif 118#endif
116 119
120#ifndef MDIO_AN_KR_CTRL
121#define MDIO_AN_KR_CTRL 0x8003
122#endif
123
117#ifndef MDIO_CTRL1_SPEED1G 124#ifndef MDIO_CTRL1_SPEED1G
118#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100) 125#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
119#endif 126#endif
120 127
128#ifndef MDIO_KR_CTRL_PDETECT
129#define MDIO_KR_CTRL_PDETECT 0x01
130#endif
131
121/* SerDes integration register offsets */ 132/* SerDes integration register offsets */
122#define SIR0_KR_RT_1 0x002c 133#define SIR0_KR_RT_1 0x002c
123#define SIR0_STATUS 0x0040 134#define SIR0_STATUS 0x0040
@@ -341,6 +352,7 @@ struct amd_xgbe_phy_priv {
341 enum amd_xgbe_phy_rx kx_state; 352 enum amd_xgbe_phy_rx kx_state;
342 struct work_struct an_work; 353 struct work_struct an_work;
343 struct workqueue_struct *an_workqueue; 354 struct workqueue_struct *an_workqueue;
355 unsigned int parallel_detect;
344}; 356};
345 357
346static int amd_xgbe_an_enable_kr_training(struct phy_device *phydev) 358static int amd_xgbe_an_enable_kr_training(struct phy_device *phydev)
@@ -808,6 +820,13 @@ static enum amd_xgbe_phy_an amd_xgbe_an_start(struct phy_device *phydev)
808 /* Enable and start auto-negotiation */ 820 /* Enable and start auto-negotiation */
809 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0); 821 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
810 822
823 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL);
824 if (ret < 0)
825 return AMD_XGBE_AN_ERROR;
826
827 ret |= MDIO_KR_CTRL_PDETECT;
828 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL, ret);
829
811 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1); 830 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
812 if (ret < 0) 831 if (ret < 0)
813 return AMD_XGBE_AN_ERROR; 832 return AMD_XGBE_AN_ERROR;
@@ -888,6 +907,10 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
888 int sleep; 907 int sleep;
889 unsigned int an_supported = 0; 908 unsigned int an_supported = 0;
890 909
910 /* Start in KX mode */
911 if (amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX))
912 priv->an_state = AMD_XGBE_AN_ERROR;
913
891 while (1) { 914 while (1) {
892 mutex_lock(&priv->an_mutex); 915 mutex_lock(&priv->an_mutex);
893 916
@@ -895,8 +918,9 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
895 918
896 switch (priv->an_state) { 919 switch (priv->an_state) {
897 case AMD_XGBE_AN_START: 920 case AMD_XGBE_AN_START:
898 priv->an_state = amd_xgbe_an_start(phydev);
899 an_supported = 0; 921 an_supported = 0;
922 priv->parallel_detect = 0;
923 priv->an_state = amd_xgbe_an_start(phydev);
900 break; 924 break;
901 925
902 case AMD_XGBE_AN_EVENT: 926 case AMD_XGBE_AN_EVENT:
@@ -913,6 +937,7 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
913 break; 937 break;
914 938
915 case AMD_XGBE_AN_COMPLETE: 939 case AMD_XGBE_AN_COMPLETE:
940 priv->parallel_detect = an_supported ? 0 : 1;
916 netdev_info(phydev->attached_dev, "%s successful\n", 941 netdev_info(phydev->attached_dev, "%s successful\n",
917 an_supported ? "Auto negotiation" 942 an_supported ? "Auto negotiation"
918 : "Parallel detection"); 943 : "Parallel detection");
@@ -1150,7 +1175,8 @@ static int amd_xgbe_phy_read_status(struct phy_device *phydev)
1150 if (ret) 1175 if (ret)
1151 return ret; 1176 return ret;
1152 1177
1153 if (phydev->autoneg == AUTONEG_ENABLE) { 1178 if ((phydev->autoneg == AUTONEG_ENABLE) &&
1179 !priv->parallel_detect) {
1154 if (!(mmd_mask & MDIO_DEVS_AN)) 1180 if (!(mmd_mask & MDIO_DEVS_AN))
1155 return -EINVAL; 1181 return -EINVAL;
1156 1182