aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/Kconfig10
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/amd-xgbe-phy.c168
-rw-r--r--drivers/net/phy/bcm7xxx.c116
-rw-r--r--drivers/net/phy/broadcom.c122
-rw-r--r--drivers/net/phy/dp83640.c29
-rw-r--r--drivers/net/phy/fixed.c11
-rw-r--r--drivers/net/phy/mdio-bcm-unimac.c213
-rw-r--r--drivers/net/phy/mdio_bus.c8
-rw-r--r--drivers/net/phy/phy.c12
-rw-r--r--drivers/net/phy/phy_device.c4
11 files changed, 447 insertions, 247 deletions
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 65de0cab8d07..14afa4f24424 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -159,8 +159,6 @@ config MDIO_OCTEON
159config MDIO_SUN4I 159config MDIO_SUN4I
160 tristate "Allwinner sun4i MDIO interface support" 160 tristate "Allwinner sun4i MDIO interface support"
161 depends on ARCH_SUNXI 161 depends on ARCH_SUNXI
162 select REGULATOR
163 select REGULATOR_FIXED_VOLTAGE
164 help 162 help
165 This driver supports the MDIO interface found in the network 163 This driver supports the MDIO interface found in the network
166 interface units of the Allwinner SoC that have an EMAC (A10, 164 interface units of the Allwinner SoC that have an EMAC (A10,
@@ -205,6 +203,14 @@ config MDIO_BUS_MUX_MMIOREG
205 203
206 Currently, only 8-bit registers are supported. 204 Currently, only 8-bit registers are supported.
207 205
206config MDIO_BCM_UNIMAC
207 tristate "Broadcom UniMAC MDIO bus controller"
208 help
209 This module provides a driver for the Broadcom UniMAC MDIO busses.
210 This hardware can be found in the Broadcom GENET Ethernet MAC
211 controllers as well as some Broadcom Ethernet switches such as the
212 Starfighter 2 switches.
213
208endif # PHYLIB 214endif # PHYLIB
209 215
210config MICREL_KS8995MA 216config MICREL_KS8995MA
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 7dc3d5b304cf..eb3b18b5978b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -34,3 +34,4 @@ obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o
34obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o 34obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
35obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o 35obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
36obj-$(CONFIG_AMD_XGBE_PHY) += amd-xgbe-phy.o 36obj-$(CONFIG_AMD_XGBE_PHY) += amd-xgbe-phy.o
37obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o
diff --git a/drivers/net/phy/amd-xgbe-phy.c b/drivers/net/phy/amd-xgbe-phy.c
index f3230eef41fd..c456559f6e7f 100644
--- a/drivers/net/phy/amd-xgbe-phy.c
+++ b/drivers/net/phy/amd-xgbe-phy.c
@@ -75,7 +75,6 @@
75#include <linux/of_device.h> 75#include <linux/of_device.h>
76#include <linux/uaccess.h> 76#include <linux/uaccess.h>
77 77
78
79MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>"); 78MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
80MODULE_LICENSE("Dual BSD/GPL"); 79MODULE_LICENSE("Dual BSD/GPL");
81MODULE_VERSION("1.0.0-a"); 80MODULE_VERSION("1.0.0-a");
@@ -100,9 +99,11 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
100#ifndef MDIO_PMA_10GBR_PMD_CTRL 99#ifndef MDIO_PMA_10GBR_PMD_CTRL
101#define MDIO_PMA_10GBR_PMD_CTRL 0x0096 100#define MDIO_PMA_10GBR_PMD_CTRL 0x0096
102#endif 101#endif
102
103#ifndef MDIO_PMA_10GBR_FEC_CTRL 103#ifndef MDIO_PMA_10GBR_FEC_CTRL
104#define MDIO_PMA_10GBR_FEC_CTRL 0x00ab 104#define MDIO_PMA_10GBR_FEC_CTRL 0x00ab
105#endif 105#endif
106
106#ifndef MDIO_AN_XNP 107#ifndef MDIO_AN_XNP
107#define MDIO_AN_XNP 0x0016 108#define MDIO_AN_XNP 0x0016
108#endif 109#endif
@@ -110,14 +111,23 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
110#ifndef MDIO_AN_INTMASK 111#ifndef MDIO_AN_INTMASK
111#define MDIO_AN_INTMASK 0x8001 112#define MDIO_AN_INTMASK 0x8001
112#endif 113#endif
114
113#ifndef MDIO_AN_INT 115#ifndef MDIO_AN_INT
114#define MDIO_AN_INT 0x8002 116#define MDIO_AN_INT 0x8002
115#endif 117#endif
116 118
119#ifndef MDIO_AN_KR_CTRL
120#define MDIO_AN_KR_CTRL 0x8003
121#endif
122
117#ifndef MDIO_CTRL1_SPEED1G 123#ifndef MDIO_CTRL1_SPEED1G
118#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100) 124#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
119#endif 125#endif
120 126
127#ifndef MDIO_KR_CTRL_PDETECT
128#define MDIO_KR_CTRL_PDETECT 0x01
129#endif
130
121/* SerDes integration register offsets */ 131/* SerDes integration register offsets */
122#define SIR0_KR_RT_1 0x002c 132#define SIR0_KR_RT_1 0x002c
123#define SIR0_STATUS 0x0040 133#define SIR0_STATUS 0x0040
@@ -161,7 +171,6 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
161#define SPEED_1000_TXAMP 0xf 171#define SPEED_1000_TXAMP 0xf
162#define SPEED_1000_WORD 0x1 172#define SPEED_1000_WORD 0x1
163 173
164
165/* SerDes RxTx register offsets */ 174/* SerDes RxTx register offsets */
166#define RXTX_REG20 0x0050 175#define RXTX_REG20 0x0050
167#define RXTX_REG114 0x01c8 176#define RXTX_REG114 0x01c8
@@ -255,7 +264,6 @@ do { \
255 XSIR1_IOWRITE((_priv), _reg, reg_val); \ 264 XSIR1_IOWRITE((_priv), _reg, reg_val); \
256} while (0) 265} while (0)
257 266
258
259/* Macros for reading or writing SerDes RxTx registers 267/* Macros for reading or writing SerDes RxTx registers
260 * The ioread macros will get bit fields or full values using the 268 * The ioread macros will get bit fields or full values using the
261 * register definitions formed using the input names 269 * register definitions formed using the input names
@@ -283,7 +291,6 @@ do { \
283 XRXTX_IOWRITE((_priv), _reg, reg_val); \ 291 XRXTX_IOWRITE((_priv), _reg, reg_val); \
284} while (0) 292} while (0)
285 293
286
287enum amd_xgbe_phy_an { 294enum amd_xgbe_phy_an {
288 AMD_XGBE_AN_READY = 0, 295 AMD_XGBE_AN_READY = 0,
289 AMD_XGBE_AN_START, 296 AMD_XGBE_AN_START,
@@ -331,7 +338,6 @@ struct amd_xgbe_phy_priv {
331 338
332 /* Maintain link status for re-starting auto-negotiation */ 339 /* Maintain link status for re-starting auto-negotiation */
333 unsigned int link; 340 unsigned int link;
334 enum amd_xgbe_phy_mode mode;
335 unsigned int speed_set; 341 unsigned int speed_set;
336 342
337 /* Auto-negotiation state machine support */ 343 /* Auto-negotiation state machine support */
@@ -342,6 +348,7 @@ struct amd_xgbe_phy_priv {
342 enum amd_xgbe_phy_rx kx_state; 348 enum amd_xgbe_phy_rx kx_state;
343 struct work_struct an_work; 349 struct work_struct an_work;
344 struct workqueue_struct *an_workqueue; 350 struct workqueue_struct *an_workqueue;
351 unsigned int parallel_detect;
345}; 352};
346 353
347static int amd_xgbe_an_enable_kr_training(struct phy_device *phydev) 354static int amd_xgbe_an_enable_kr_training(struct phy_device *phydev)
@@ -468,8 +475,6 @@ static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
468 475
469 amd_xgbe_phy_serdes_complete_ratechange(phydev); 476 amd_xgbe_phy_serdes_complete_ratechange(phydev);
470 477
471 priv->mode = AMD_XGBE_MODE_KR;
472
473 return 0; 478 return 0;
474} 479}
475 480
@@ -518,8 +523,6 @@ static int amd_xgbe_phy_gmii_2500_mode(struct phy_device *phydev)
518 523
519 amd_xgbe_phy_serdes_complete_ratechange(phydev); 524 amd_xgbe_phy_serdes_complete_ratechange(phydev);
520 525
521 priv->mode = AMD_XGBE_MODE_KX;
522
523 return 0; 526 return 0;
524} 527}
525 528
@@ -568,18 +571,43 @@ static int amd_xgbe_phy_gmii_mode(struct phy_device *phydev)
568 571
569 amd_xgbe_phy_serdes_complete_ratechange(phydev); 572 amd_xgbe_phy_serdes_complete_ratechange(phydev);
570 573
571 priv->mode = AMD_XGBE_MODE_KX; 574 return 0;
575}
576
577static int amd_xgbe_phy_cur_mode(struct phy_device *phydev,
578 enum amd_xgbe_phy_mode *mode)
579{
580 int ret;
581
582 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
583 if (ret < 0)
584 return ret;
585
586 if ((ret & MDIO_PCS_CTRL2_TYPE) == MDIO_PCS_CTRL2_10GBR)
587 *mode = AMD_XGBE_MODE_KR;
588 else
589 *mode = AMD_XGBE_MODE_KX;
572 590
573 return 0; 591 return 0;
574} 592}
575 593
594static bool amd_xgbe_phy_in_kr_mode(struct phy_device *phydev)
595{
596 enum amd_xgbe_phy_mode mode;
597
598 if (amd_xgbe_phy_cur_mode(phydev, &mode))
599 return false;
600
601 return (mode == AMD_XGBE_MODE_KR);
602}
603
576static int amd_xgbe_phy_switch_mode(struct phy_device *phydev) 604static int amd_xgbe_phy_switch_mode(struct phy_device *phydev)
577{ 605{
578 struct amd_xgbe_phy_priv *priv = phydev->priv; 606 struct amd_xgbe_phy_priv *priv = phydev->priv;
579 int ret; 607 int ret;
580 608
581 /* If we are in KR switch to KX, and vice-versa */ 609 /* If we are in KR switch to KX, and vice-versa */
582 if (priv->mode == AMD_XGBE_MODE_KR) { 610 if (amd_xgbe_phy_in_kr_mode(phydev)) {
583 if (priv->speed_set == AMD_XGBE_PHY_SPEEDSET_1000_10000) 611 if (priv->speed_set == AMD_XGBE_PHY_SPEEDSET_1000_10000)
584 ret = amd_xgbe_phy_gmii_mode(phydev); 612 ret = amd_xgbe_phy_gmii_mode(phydev);
585 else 613 else
@@ -591,15 +619,20 @@ static int amd_xgbe_phy_switch_mode(struct phy_device *phydev)
591 return ret; 619 return ret;
592} 620}
593 621
594static enum amd_xgbe_phy_an amd_xgbe_an_switch_mode(struct phy_device *phydev) 622static int amd_xgbe_phy_set_mode(struct phy_device *phydev,
623 enum amd_xgbe_phy_mode mode)
595{ 624{
625 enum amd_xgbe_phy_mode cur_mode;
596 int ret; 626 int ret;
597 627
598 ret = amd_xgbe_phy_switch_mode(phydev); 628 ret = amd_xgbe_phy_cur_mode(phydev, &cur_mode);
599 if (ret < 0) 629 if (ret)
600 return AMD_XGBE_AN_ERROR; 630 return ret;
601 631
602 return AMD_XGBE_AN_START; 632 if (mode != cur_mode)
633 ret = amd_xgbe_phy_switch_mode(phydev);
634
635 return ret;
603} 636}
604 637
605static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev, 638static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
@@ -610,8 +643,8 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
610 643
611 *state = AMD_XGBE_RX_COMPLETE; 644 *state = AMD_XGBE_RX_COMPLETE;
612 645
613 /* If we're in KX mode then we're done */ 646 /* If we're not in KR mode then we're done */
614 if (priv->mode == AMD_XGBE_MODE_KX) 647 if (!amd_xgbe_phy_in_kr_mode(phydev))
615 return AMD_XGBE_AN_EVENT; 648 return AMD_XGBE_AN_EVENT;
616 649
617 /* Enable/Disable FEC */ 650 /* Enable/Disable FEC */
@@ -669,7 +702,6 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_xnp(struct phy_device *phydev,
669static enum amd_xgbe_phy_an amd_xgbe_an_rx_bpa(struct phy_device *phydev, 702static enum amd_xgbe_phy_an amd_xgbe_an_rx_bpa(struct phy_device *phydev,
670 enum amd_xgbe_phy_rx *state) 703 enum amd_xgbe_phy_rx *state)
671{ 704{
672 struct amd_xgbe_phy_priv *priv = phydev->priv;
673 unsigned int link_support; 705 unsigned int link_support;
674 int ret, ad_reg, lp_reg; 706 int ret, ad_reg, lp_reg;
675 707
@@ -679,9 +711,9 @@ static enum amd_xgbe_phy_an amd_xgbe_an_rx_bpa(struct phy_device *phydev,
679 return AMD_XGBE_AN_ERROR; 711 return AMD_XGBE_AN_ERROR;
680 712
681 /* Check for a supported mode, otherwise restart in a different one */ 713 /* Check for a supported mode, otherwise restart in a different one */
682 link_support = (priv->mode == AMD_XGBE_MODE_KR) ? 0x80 : 0x20; 714 link_support = amd_xgbe_phy_in_kr_mode(phydev) ? 0x80 : 0x20;
683 if (!(ret & link_support)) 715 if (!(ret & link_support))
684 return amd_xgbe_an_switch_mode(phydev); 716 return AMD_XGBE_AN_INCOMPAT_LINK;
685 717
686 /* Check Extended Next Page support */ 718 /* Check Extended Next Page support */
687 ad_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 719 ad_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
@@ -722,7 +754,7 @@ static enum amd_xgbe_phy_an amd_xgbe_an_start(struct phy_device *phydev)
722 int ret; 754 int ret;
723 755
724 /* Be sure we aren't looping trying to negotiate */ 756 /* Be sure we aren't looping trying to negotiate */
725 if (priv->mode == AMD_XGBE_MODE_KR) { 757 if (amd_xgbe_phy_in_kr_mode(phydev)) {
726 if (priv->kr_state != AMD_XGBE_RX_READY) 758 if (priv->kr_state != AMD_XGBE_RX_READY)
727 return AMD_XGBE_AN_NO_LINK; 759 return AMD_XGBE_AN_NO_LINK;
728 priv->kr_state = AMD_XGBE_RX_BPA; 760 priv->kr_state = AMD_XGBE_RX_BPA;
@@ -785,6 +817,13 @@ static enum amd_xgbe_phy_an amd_xgbe_an_start(struct phy_device *phydev)
785 /* Enable and start auto-negotiation */ 817 /* Enable and start auto-negotiation */
786 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0); 818 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
787 819
820 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL);
821 if (ret < 0)
822 return AMD_XGBE_AN_ERROR;
823
824 ret |= MDIO_KR_CTRL_PDETECT;
825 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL, ret);
826
788 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1); 827 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
789 if (ret < 0) 828 if (ret < 0)
790 return AMD_XGBE_AN_ERROR; 829 return AMD_XGBE_AN_ERROR;
@@ -825,8 +864,8 @@ static enum amd_xgbe_phy_an amd_xgbe_an_page_received(struct phy_device *phydev)
825 enum amd_xgbe_phy_rx *state; 864 enum amd_xgbe_phy_rx *state;
826 int ret; 865 int ret;
827 866
828 state = (priv->mode == AMD_XGBE_MODE_KR) ? &priv->kr_state 867 state = amd_xgbe_phy_in_kr_mode(phydev) ? &priv->kr_state
829 : &priv->kx_state; 868 : &priv->kx_state;
830 869
831 switch (*state) { 870 switch (*state) {
832 case AMD_XGBE_RX_BPA: 871 case AMD_XGBE_RX_BPA:
@@ -846,7 +885,13 @@ static enum amd_xgbe_phy_an amd_xgbe_an_page_received(struct phy_device *phydev)
846 885
847static enum amd_xgbe_phy_an amd_xgbe_an_incompat_link(struct phy_device *phydev) 886static enum amd_xgbe_phy_an amd_xgbe_an_incompat_link(struct phy_device *phydev)
848{ 887{
849 return amd_xgbe_an_switch_mode(phydev); 888 int ret;
889
890 ret = amd_xgbe_phy_switch_mode(phydev);
891 if (ret)
892 return AMD_XGBE_AN_ERROR;
893
894 return AMD_XGBE_AN_START;
850} 895}
851 896
852static void amd_xgbe_an_state_machine(struct work_struct *work) 897static void amd_xgbe_an_state_machine(struct work_struct *work)
@@ -859,6 +904,10 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
859 int sleep; 904 int sleep;
860 unsigned int an_supported = 0; 905 unsigned int an_supported = 0;
861 906
907 /* Start in KX mode */
908 if (amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX))
909 priv->an_state = AMD_XGBE_AN_ERROR;
910
862 while (1) { 911 while (1) {
863 mutex_lock(&priv->an_mutex); 912 mutex_lock(&priv->an_mutex);
864 913
@@ -866,8 +915,9 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
866 915
867 switch (priv->an_state) { 916 switch (priv->an_state) {
868 case AMD_XGBE_AN_START: 917 case AMD_XGBE_AN_START:
869 priv->an_state = amd_xgbe_an_start(phydev);
870 an_supported = 0; 918 an_supported = 0;
919 priv->parallel_detect = 0;
920 priv->an_state = amd_xgbe_an_start(phydev);
871 break; 921 break;
872 922
873 case AMD_XGBE_AN_EVENT: 923 case AMD_XGBE_AN_EVENT:
@@ -884,6 +934,7 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
884 break; 934 break;
885 935
886 case AMD_XGBE_AN_COMPLETE: 936 case AMD_XGBE_AN_COMPLETE:
937 priv->parallel_detect = an_supported ? 0 : 1;
887 netdev_info(phydev->attached_dev, "%s successful\n", 938 netdev_info(phydev->attached_dev, "%s successful\n",
888 an_supported ? "Auto negotiation" 939 an_supported ? "Auto negotiation"
889 : "Parallel detection"); 940 : "Parallel detection");
@@ -1018,7 +1069,6 @@ static int amd_xgbe_phy_config_aneg(struct phy_device *phydev)
1018{ 1069{
1019 struct amd_xgbe_phy_priv *priv = phydev->priv; 1070 struct amd_xgbe_phy_priv *priv = phydev->priv;
1020 u32 mmd_mask = phydev->c45_ids.devices_in_package; 1071 u32 mmd_mask = phydev->c45_ids.devices_in_package;
1021 int ret;
1022 1072
1023 if (phydev->autoneg != AUTONEG_ENABLE) 1073 if (phydev->autoneg != AUTONEG_ENABLE)
1024 return amd_xgbe_phy_setup_forced(phydev); 1074 return amd_xgbe_phy_setup_forced(phydev);
@@ -1027,11 +1077,6 @@ static int amd_xgbe_phy_config_aneg(struct phy_device *phydev)
1027 if (!(mmd_mask & MDIO_DEVS_AN)) 1077 if (!(mmd_mask & MDIO_DEVS_AN))
1028 return -EINVAL; 1078 return -EINVAL;
1029 1079
1030 /* Get the current speed mode */
1031 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
1032 if (ret < 0)
1033 return ret;
1034
1035 /* Start/Restart the auto-negotiation state machine */ 1080 /* Start/Restart the auto-negotiation state machine */
1036 mutex_lock(&priv->an_mutex); 1081 mutex_lock(&priv->an_mutex);
1037 priv->an_result = AMD_XGBE_AN_READY; 1082 priv->an_result = AMD_XGBE_AN_READY;
@@ -1121,18 +1166,14 @@ static int amd_xgbe_phy_read_status(struct phy_device *phydev)
1121{ 1166{
1122 struct amd_xgbe_phy_priv *priv = phydev->priv; 1167 struct amd_xgbe_phy_priv *priv = phydev->priv;
1123 u32 mmd_mask = phydev->c45_ids.devices_in_package; 1168 u32 mmd_mask = phydev->c45_ids.devices_in_package;
1124 int ret, mode, ad_ret, lp_ret; 1169 int ret, ad_ret, lp_ret;
1125 1170
1126 ret = amd_xgbe_phy_update_link(phydev); 1171 ret = amd_xgbe_phy_update_link(phydev);
1127 if (ret) 1172 if (ret)
1128 return ret; 1173 return ret;
1129 1174
1130 mode = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2); 1175 if ((phydev->autoneg == AUTONEG_ENABLE) &&
1131 if (mode < 0) 1176 !priv->parallel_detect) {
1132 return mode;
1133 mode &= MDIO_PCS_CTRL2_TYPE;
1134
1135 if (phydev->autoneg == AUTONEG_ENABLE) {
1136 if (!(mmd_mask & MDIO_DEVS_AN)) 1177 if (!(mmd_mask & MDIO_DEVS_AN))
1137 return -EINVAL; 1178 return -EINVAL;
1138 1179
@@ -1163,40 +1204,39 @@ static int amd_xgbe_phy_read_status(struct phy_device *phydev)
1163 ad_ret &= lp_ret; 1204 ad_ret &= lp_ret;
1164 if (ad_ret & 0x80) { 1205 if (ad_ret & 0x80) {
1165 phydev->speed = SPEED_10000; 1206 phydev->speed = SPEED_10000;
1166 if (mode != MDIO_PCS_CTRL2_10GBR) { 1207 ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KR);
1167 ret = amd_xgbe_phy_xgmii_mode(phydev); 1208 if (ret)
1168 if (ret < 0) 1209 return ret;
1169 return ret;
1170 }
1171 } else { 1210 } else {
1172 int (*mode_fcn)(struct phy_device *); 1211 switch (priv->speed_set) {
1173 1212 case AMD_XGBE_PHY_SPEEDSET_1000_10000:
1174 if (priv->speed_set ==
1175 AMD_XGBE_PHY_SPEEDSET_1000_10000) {
1176 phydev->speed = SPEED_1000; 1213 phydev->speed = SPEED_1000;
1177 mode_fcn = amd_xgbe_phy_gmii_mode; 1214 break;
1178 } else { 1215
1216 case AMD_XGBE_PHY_SPEEDSET_2500_10000:
1179 phydev->speed = SPEED_2500; 1217 phydev->speed = SPEED_2500;
1180 mode_fcn = amd_xgbe_phy_gmii_2500_mode; 1218 break;
1181 } 1219 }
1182 1220
1183 if (mode == MDIO_PCS_CTRL2_10GBR) { 1221 ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX);
1184 ret = mode_fcn(phydev); 1222 if (ret)
1185 if (ret < 0) 1223 return ret;
1186 return ret;
1187 }
1188 } 1224 }
1189 1225
1190 phydev->duplex = DUPLEX_FULL; 1226 phydev->duplex = DUPLEX_FULL;
1191 } else { 1227 } else {
1192 if (mode == MDIO_PCS_CTRL2_10GBR) { 1228 if (amd_xgbe_phy_in_kr_mode(phydev)) {
1193 phydev->speed = SPEED_10000; 1229 phydev->speed = SPEED_10000;
1194 } else { 1230 } else {
1195 if (priv->speed_set == 1231 switch (priv->speed_set) {
1196 AMD_XGBE_PHY_SPEEDSET_1000_10000) 1232 case AMD_XGBE_PHY_SPEEDSET_1000_10000:
1197 phydev->speed = SPEED_1000; 1233 phydev->speed = SPEED_1000;
1198 else 1234 break;
1235
1236 case AMD_XGBE_PHY_SPEEDSET_2500_10000:
1199 phydev->speed = SPEED_2500; 1237 phydev->speed = SPEED_2500;
1238 break;
1239 }
1200 } 1240 }
1201 phydev->duplex = DUPLEX_FULL; 1241 phydev->duplex = DUPLEX_FULL;
1202 phydev->pause = 0; 1242 phydev->pause = 0;
@@ -1329,14 +1369,6 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
1329 1369
1330 priv->link = 1; 1370 priv->link = 1;
1331 1371
1332 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
1333 if (ret < 0)
1334 goto err_sir1;
1335 if ((ret & MDIO_PCS_CTRL2_TYPE) == MDIO_PCS_CTRL2_10GBR)
1336 priv->mode = AMD_XGBE_MODE_KR;
1337 else
1338 priv->mode = AMD_XGBE_MODE_KX;
1339
1340 mutex_init(&priv->an_mutex); 1372 mutex_init(&priv->an_mutex);
1341 INIT_WORK(&priv->an_work, amd_xgbe_an_state_machine); 1373 INIT_WORK(&priv->an_work, amd_xgbe_an_state_machine);
1342 priv->an_workqueue = create_singlethread_workqueue(wq_name); 1374 priv->an_workqueue = create_singlethread_workqueue(wq_name);
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index fdce1ea28790..09dd6e1dc6e1 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -14,6 +14,7 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/bitops.h> 15#include <linux/bitops.h>
16#include <linux/brcmphy.h> 16#include <linux/brcmphy.h>
17#include <linux/mdio.h>
17 18
18/* Broadcom BCM7xxx internal PHY registers */ 19/* Broadcom BCM7xxx internal PHY registers */
19#define MII_BCM7XXX_CHANNEL_WIDTH 0x2000 20#define MII_BCM7XXX_CHANNEL_WIDTH 0x2000
@@ -146,6 +147,53 @@ static int bcm7xxx_28nm_afe_config_init(struct phy_device *phydev)
146 return 0; 147 return 0;
147} 148}
148 149
150static int bcm7xxx_apd_enable(struct phy_device *phydev)
151{
152 int val;
153
154 /* Enable powering down of the DLL during auto-power down */
155 val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_SCR3);
156 if (val < 0)
157 return val;
158
159 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
160 bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val);
161
162 /* Enable auto-power down */
163 val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_APD);
164 if (val < 0)
165 return val;
166
167 val |= BCM54XX_SHD_APD_EN;
168 return bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val);
169}
170
171static int bcm7xxx_eee_enable(struct phy_device *phydev)
172{
173 int val;
174
175 val = phy_read_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL,
176 MDIO_MMD_AN, phydev->addr);
177 if (val < 0)
178 return val;
179
180 /* Enable general EEE feature at the PHY level */
181 val |= LPI_FEATURE_EN | LPI_FEATURE_EN_DIG1000X;
182
183 phy_write_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL,
184 MDIO_MMD_AN, phydev->addr, val);
185
186 /* Advertise supported modes */
187 val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
188 MDIO_MMD_AN, phydev->addr);
189
190 val |= (MDIO_AN_EEE_ADV_100TX | MDIO_AN_EEE_ADV_1000T);
191 phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
192 MDIO_MMD_AN, phydev->addr, val);
193
194 return 0;
195}
196
149static int bcm7xxx_28nm_config_init(struct phy_device *phydev) 197static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
150{ 198{
151 int ret; 199 int ret;
@@ -154,7 +202,15 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
154 if (ret) 202 if (ret)
155 return ret; 203 return ret;
156 204
157 return bcm7xxx_28nm_afe_config_init(phydev); 205 ret = bcm7xxx_28nm_afe_config_init(phydev);
206 if (ret)
207 return ret;
208
209 ret = bcm7xxx_eee_enable(phydev);
210 if (ret)
211 return ret;
212
213 return bcm7xxx_apd_enable(phydev);
158} 214}
159 215
160static int bcm7xxx_28nm_resume(struct phy_device *phydev) 216static int bcm7xxx_28nm_resume(struct phy_device *phydev)
@@ -263,44 +319,28 @@ static int bcm7xxx_dummy_config_init(struct phy_device *phydev)
263 return 0; 319 return 0;
264} 320}
265 321
322#define BCM7XXX_28NM_GPHY(_oui, _name) \
323{ \
324 .phy_id = (_oui), \
325 .phy_id_mask = 0xfffffff0, \
326 .name = _name, \
327 .features = PHY_GBIT_FEATURES | \
328 SUPPORTED_Pause | SUPPORTED_Asym_Pause, \
329 .flags = PHY_IS_INTERNAL, \
330 .config_init = bcm7xxx_28nm_afe_config_init, \
331 .config_aneg = genphy_config_aneg, \
332 .read_status = genphy_read_status, \
333 .resume = bcm7xxx_28nm_resume, \
334 .driver = { .owner = THIS_MODULE }, \
335}
336
266static struct phy_driver bcm7xxx_driver[] = { 337static struct phy_driver bcm7xxx_driver[] = {
338 BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"),
339 BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"),
340 BCM7XXX_28NM_GPHY(PHY_ID_BCM7366, "Broadcom BCM7366"),
341 BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"),
342 BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"),
267{ 343{
268 .phy_id = PHY_ID_BCM7366,
269 .phy_id_mask = 0xfffffff0,
270 .name = "Broadcom BCM7366",
271 .features = PHY_GBIT_FEATURES |
272 SUPPORTED_Pause | SUPPORTED_Asym_Pause,
273 .flags = PHY_IS_INTERNAL,
274 .config_init = bcm7xxx_28nm_afe_config_init,
275 .config_aneg = genphy_config_aneg,
276 .read_status = genphy_read_status,
277 .resume = bcm7xxx_28nm_resume,
278 .driver = { .owner = THIS_MODULE },
279}, {
280 .phy_id = PHY_ID_BCM7439,
281 .phy_id_mask = 0xfffffff0,
282 .name = "Broadcom BCM7439",
283 .features = PHY_GBIT_FEATURES |
284 SUPPORTED_Pause | SUPPORTED_Asym_Pause,
285 .flags = PHY_IS_INTERNAL,
286 .config_init = bcm7xxx_28nm_afe_config_init,
287 .config_aneg = genphy_config_aneg,
288 .read_status = genphy_read_status,
289 .resume = bcm7xxx_28nm_resume,
290 .driver = { .owner = THIS_MODULE },
291}, {
292 .phy_id = PHY_ID_BCM7445,
293 .phy_id_mask = 0xfffffff0,
294 .name = "Broadcom BCM7445",
295 .features = PHY_GBIT_FEATURES |
296 SUPPORTED_Pause | SUPPORTED_Asym_Pause,
297 .flags = PHY_IS_INTERNAL,
298 .config_init = bcm7xxx_28nm_config_init,
299 .config_aneg = genphy_config_aneg,
300 .read_status = genphy_read_status,
301 .resume = bcm7xxx_28nm_afe_config_init,
302 .driver = { .owner = THIS_MODULE },
303}, {
304 .phy_id = PHY_BCM_OUI_4, 344 .phy_id = PHY_BCM_OUI_4,
305 .phy_id_mask = 0xffff0000, 345 .phy_id_mask = 0xffff0000,
306 .name = "Broadcom BCM7XXX 40nm", 346 .name = "Broadcom BCM7XXX 40nm",
@@ -329,6 +369,8 @@ static struct phy_driver bcm7xxx_driver[] = {
329} }; 369} };
330 370
331static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = { 371static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
372 { PHY_ID_BCM7250, 0xfffffff0, },
373 { PHY_ID_BCM7364, 0xfffffff0, },
332 { PHY_ID_BCM7366, 0xfffffff0, }, 374 { PHY_ID_BCM7366, 0xfffffff0, },
333 { PHY_ID_BCM7439, 0xfffffff0, }, 375 { PHY_ID_BCM7439, 0xfffffff0, },
334 { PHY_ID_BCM7445, 0xfffffff0, }, 376 { PHY_ID_BCM7445, 0xfffffff0, },
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 34088d60da74..854f2c9a7b2b 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -25,132 +25,10 @@
25#define BRCM_PHY_REV(phydev) \ 25#define BRCM_PHY_REV(phydev) \
26 ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask)) 26 ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
27 27
28/*
29 * Broadcom LED source encodings. These are used in BCM5461, BCM5481,
30 * BCM5482, and possibly some others.
31 */
32#define BCM_LED_SRC_LINKSPD1 0x0
33#define BCM_LED_SRC_LINKSPD2 0x1
34#define BCM_LED_SRC_XMITLED 0x2
35#define BCM_LED_SRC_ACTIVITYLED 0x3
36#define BCM_LED_SRC_FDXLED 0x4
37#define BCM_LED_SRC_SLAVE 0x5
38#define BCM_LED_SRC_INTR 0x6
39#define BCM_LED_SRC_QUALITY 0x7
40#define BCM_LED_SRC_RCVLED 0x8
41#define BCM_LED_SRC_MULTICOLOR1 0xa
42#define BCM_LED_SRC_OPENSHORT 0xb
43#define BCM_LED_SRC_OFF 0xe /* Tied high */
44#define BCM_LED_SRC_ON 0xf /* Tied low */
45
46
47/*
48 * BCM5482: Shadow registers
49 * Shadow values go into bits [14:10] of register 0x1c to select a shadow
50 * register to access.
51 */
52/* 00101: Spare Control Register 3 */
53#define BCM54XX_SHD_SCR3 0x05
54#define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001
55#define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002
56#define BCM54XX_SHD_SCR3_TRDDAPD 0x0004
57
58/* 01010: Auto Power-Down */
59#define BCM54XX_SHD_APD 0x0a
60#define BCM54XX_SHD_APD_EN 0x0020
61
62#define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */
63 /* LED3 / ~LINKSPD[2] selector */
64#define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4)
65 /* LED1 / ~LINKSPD[1] selector */
66#define BCM5482_SHD_LEDS1_LED1(src) ((src & 0xf) << 0)
67#define BCM54XX_SHD_RGMII_MODE 0x0b /* 01011: RGMII Mode Selector */
68#define BCM5482_SHD_SSD 0x14 /* 10100: Secondary SerDes control */
69#define BCM5482_SHD_SSD_LEDM 0x0008 /* SSD LED Mode enable */
70#define BCM5482_SHD_SSD_EN 0x0001 /* SSD enable */
71#define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */
72#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
73
74
75/*
76 * EXPANSION SHADOW ACCESS REGISTERS. (PHY REG 0x15, 0x16, and 0x17)
77 */
78#define MII_BCM54XX_EXP_AADJ1CH0 0x001f
79#define MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN 0x0200
80#define MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF 0x0100
81#define MII_BCM54XX_EXP_AADJ1CH3 0x601f
82#define MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ 0x0002
83#define MII_BCM54XX_EXP_EXP08 0x0F08
84#define MII_BCM54XX_EXP_EXP08_RJCT_2MHZ 0x0001
85#define MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE 0x0200
86#define MII_BCM54XX_EXP_EXP75 0x0f75
87#define MII_BCM54XX_EXP_EXP75_VDACCTRL 0x003c
88#define MII_BCM54XX_EXP_EXP75_CM_OSC 0x0001
89#define MII_BCM54XX_EXP_EXP96 0x0f96
90#define MII_BCM54XX_EXP_EXP96_MYST 0x0010
91#define MII_BCM54XX_EXP_EXP97 0x0f97
92#define MII_BCM54XX_EXP_EXP97_MYST 0x0c0c
93
94/*
95 * BCM5482: Secondary SerDes registers
96 */
97#define BCM5482_SSD_1000BX_CTL 0x00 /* 1000BASE-X Control */
98#define BCM5482_SSD_1000BX_CTL_PWRDOWN 0x0800 /* Power-down SSD */
99#define BCM5482_SSD_SGMII_SLAVE 0x15 /* SGMII Slave Register */
100#define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */
101#define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */
102
103
104/*****************************************************************************/
105/* Fast Ethernet Transceiver definitions. */
106/*****************************************************************************/
107
108#define MII_BRCM_FET_INTREG 0x1a /* Interrupt register */
109#define MII_BRCM_FET_IR_MASK 0x0100 /* Mask all interrupts */
110#define MII_BRCM_FET_IR_LINK_EN 0x0200 /* Link status change enable */
111#define MII_BRCM_FET_IR_SPEED_EN 0x0400 /* Link speed change enable */
112#define MII_BRCM_FET_IR_DUPLEX_EN 0x0800 /* Duplex mode change enable */
113#define MII_BRCM_FET_IR_ENABLE 0x4000 /* Interrupt enable */
114
115#define MII_BRCM_FET_BRCMTEST 0x1f /* Brcm test register */
116#define MII_BRCM_FET_BT_SRE 0x0080 /* Shadow register enable */
117
118
119/*** Shadow register definitions ***/
120
121#define MII_BRCM_FET_SHDW_MISCCTRL 0x10 /* Shadow misc ctrl */
122#define MII_BRCM_FET_SHDW_MC_FAME 0x4000 /* Force Auto MDIX enable */
123
124#define MII_BRCM_FET_SHDW_AUXMODE4 0x1a /* Auxiliary mode 4 */
125#define MII_BRCM_FET_SHDW_AM4_LED_MASK 0x0003
126#define MII_BRCM_FET_SHDW_AM4_LED_MODE1 0x0001
127
128#define MII_BRCM_FET_SHDW_AUXSTAT2 0x1b /* Auxiliary status 2 */
129#define MII_BRCM_FET_SHDW_AS2_APDE 0x0020 /* Auto power down enable */
130
131
132MODULE_DESCRIPTION("Broadcom PHY driver"); 28MODULE_DESCRIPTION("Broadcom PHY driver");
133MODULE_AUTHOR("Maciej W. Rozycki"); 29MODULE_AUTHOR("Maciej W. Rozycki");
134MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
135 31
136/*
137 * Indirect register access functions for the 1000BASE-T/100BASE-TX/10BASE-T
138 * 0x1c shadow registers.
139 */
140static int bcm54xx_shadow_read(struct phy_device *phydev, u16 shadow)
141{
142 phy_write(phydev, MII_BCM54XX_SHD, MII_BCM54XX_SHD_VAL(shadow));
143 return MII_BCM54XX_SHD_DATA(phy_read(phydev, MII_BCM54XX_SHD));
144}
145
146static int bcm54xx_shadow_write(struct phy_device *phydev, u16 shadow, u16 val)
147{
148 return phy_write(phydev, MII_BCM54XX_SHD,
149 MII_BCM54XX_SHD_WRITE |
150 MII_BCM54XX_SHD_VAL(shadow) |
151 MII_BCM54XX_SHD_DATA(val));
152}
153
154/* Indirect register access functions for the Expansion Registers */ 32/* Indirect register access functions for the Expansion Registers */
155static int bcm54xx_exp_read(struct phy_device *phydev, u16 regnum) 33static int bcm54xx_exp_read(struct phy_device *phydev, u16 regnum)
156{ 34{
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index c301e4cb37ca..87648b306551 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -721,7 +721,7 @@ static inline u16 exts_chan_to_edata(int ch)
721} 721}
722 722
723static int decode_evnt(struct dp83640_private *dp83640, 723static int decode_evnt(struct dp83640_private *dp83640,
724 void *data, u16 ests) 724 void *data, int len, u16 ests)
725{ 725{
726 struct phy_txts *phy_txts; 726 struct phy_txts *phy_txts;
727 struct ptp_clock_event event; 727 struct ptp_clock_event event;
@@ -729,6 +729,16 @@ static int decode_evnt(struct dp83640_private *dp83640,
729 int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK; 729 int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK;
730 u16 ext_status = 0; 730 u16 ext_status = 0;
731 731
732 /* calculate length of the event timestamp status message */
733 if (ests & MULT_EVNT)
734 parsed = (words + 2) * sizeof(u16);
735 else
736 parsed = (words + 1) * sizeof(u16);
737
738 /* check if enough data is available */
739 if (len < parsed)
740 return len;
741
732 if (ests & MULT_EVNT) { 742 if (ests & MULT_EVNT) {
733 ext_status = *(u16 *) data; 743 ext_status = *(u16 *) data;
734 data += sizeof(ext_status); 744 data += sizeof(ext_status);
@@ -747,10 +757,7 @@ static int decode_evnt(struct dp83640_private *dp83640,
747 dp83640->edata.ns_lo = phy_txts->ns_lo; 757 dp83640->edata.ns_lo = phy_txts->ns_lo;
748 } 758 }
749 759
750 if (ext_status) { 760 if (!ext_status) {
751 parsed = words + 2;
752 } else {
753 parsed = words + 1;
754 i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK) - EXT_EVENT; 761 i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK) - EXT_EVENT;
755 ext_status = exts_chan_to_edata(i); 762 ext_status = exts_chan_to_edata(i);
756 } 763 }
@@ -768,7 +775,7 @@ static int decode_evnt(struct dp83640_private *dp83640,
768 } 775 }
769 } 776 }
770 777
771 return parsed * sizeof(u16); 778 return parsed;
772} 779}
773 780
774static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts) 781static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
@@ -905,9 +912,9 @@ static void decode_status_frame(struct dp83640_private *dp83640,
905 decode_txts(dp83640, phy_txts); 912 decode_txts(dp83640, phy_txts);
906 size = sizeof(*phy_txts); 913 size = sizeof(*phy_txts);
907 914
908 } else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) { 915 } else if (PSF_EVNT == type) {
909 916
910 size = decode_evnt(dp83640, ptr, ests); 917 size = decode_evnt(dp83640, ptr, len, ests);
911 918
912 } else { 919 } else {
913 size = 0; 920 size = 0;
@@ -1141,7 +1148,7 @@ static void dp83640_remove(struct phy_device *phydev)
1141 kfree_skb(skb); 1148 kfree_skb(skb);
1142 1149
1143 while ((skb = skb_dequeue(&dp83640->tx_queue)) != NULL) 1150 while ((skb = skb_dequeue(&dp83640->tx_queue)) != NULL)
1144 skb_complete_tx_timestamp(skb, NULL); 1151 kfree_skb(skb);
1145 1152
1146 clock = dp83640_clock_get(dp83640->clock); 1153 clock = dp83640_clock_get(dp83640->clock);
1147 1154
@@ -1398,7 +1405,7 @@ static void dp83640_txtstamp(struct phy_device *phydev,
1398 1405
1399 case HWTSTAMP_TX_ONESTEP_SYNC: 1406 case HWTSTAMP_TX_ONESTEP_SYNC:
1400 if (is_sync(skb, type)) { 1407 if (is_sync(skb, type)) {
1401 skb_complete_tx_timestamp(skb, NULL); 1408 kfree_skb(skb);
1402 return; 1409 return;
1403 } 1410 }
1404 /* fall through */ 1411 /* fall through */
@@ -1409,7 +1416,7 @@ static void dp83640_txtstamp(struct phy_device *phydev,
1409 1416
1410 case HWTSTAMP_TX_OFF: 1417 case HWTSTAMP_TX_OFF:
1411 default: 1418 default:
1412 skb_complete_tx_timestamp(skb, NULL); 1419 kfree_skb(skb);
1413 break; 1420 break;
1414 } 1421 }
1415} 1422}
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index d60d875cb445..5b19fbbda6d4 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -124,6 +124,17 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
124 if (reg_num >= MII_REGS_NUM) 124 if (reg_num >= MII_REGS_NUM)
125 return -1; 125 return -1;
126 126
127 /* We do not support emulating Clause 45 over Clause 22 register reads
128 * return an error instead of bogus data.
129 */
130 switch (reg_num) {
131 case MII_MMD_CTRL:
132 case MII_MMD_DATA:
133 return -1;
134 default:
135 break;
136 }
137
127 list_for_each_entry(fp, &fmb->phys, node) { 138 list_for_each_entry(fp, &fmb->phys, node) {
128 if (fp->addr == phy_addr) { 139 if (fp->addr == phy_addr) {
129 /* Issue callback if user registered it. */ 140 /* Issue callback if user registered it. */
diff --git a/drivers/net/phy/mdio-bcm-unimac.c b/drivers/net/phy/mdio-bcm-unimac.c
new file mode 100644
index 000000000000..5b643e588e8f
--- /dev/null
+++ b/drivers/net/phy/mdio-bcm-unimac.c
@@ -0,0 +1,213 @@
1/*
2 * Broadcom UniMAC MDIO bus controller driver
3 *
4 * Copyright (C) 2014, Broadcom Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/phy.h>
14#include <linux/platform_device.h>
15#include <linux/sched.h>
16#include <linux/module.h>
17#include <linux/io.h>
18#include <linux/delay.h>
19
20#include <linux/of.h>
21#include <linux/of_platform.h>
22#include <linux/of_mdio.h>
23
24#define MDIO_CMD 0x00
25#define MDIO_START_BUSY (1 << 29)
26#define MDIO_READ_FAIL (1 << 28)
27#define MDIO_RD (2 << 26)
28#define MDIO_WR (1 << 26)
29#define MDIO_PMD_SHIFT 21
30#define MDIO_PMD_MASK 0x1F
31#define MDIO_REG_SHIFT 16
32#define MDIO_REG_MASK 0x1F
33
34#define MDIO_CFG 0x04
35#define MDIO_C22 (1 << 0)
36#define MDIO_C45 0
37#define MDIO_CLK_DIV_SHIFT 4
38#define MDIO_CLK_DIV_MASK 0x3F
39#define MDIO_SUPP_PREAMBLE (1 << 12)
40
41struct unimac_mdio_priv {
42 struct mii_bus *mii_bus;
43 void __iomem *base;
44};
45
46static inline void unimac_mdio_start(struct unimac_mdio_priv *priv)
47{
48 u32 reg;
49
50 reg = __raw_readl(priv->base + MDIO_CMD);
51 reg |= MDIO_START_BUSY;
52 __raw_writel(reg, priv->base + MDIO_CMD);
53}
54
55static inline unsigned int unimac_mdio_busy(struct unimac_mdio_priv *priv)
56{
57 return __raw_readl(priv->base + MDIO_CMD) & MDIO_START_BUSY;
58}
59
60static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
61{
62 struct unimac_mdio_priv *priv = bus->priv;
63 unsigned int timeout = 1000;
64 u32 cmd;
65
66 /* Prepare the read operation */
67 cmd = MDIO_RD | (phy_id << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT);
68 __raw_writel(cmd, priv->base + MDIO_CMD);
69
70 /* Start MDIO transaction */
71 unimac_mdio_start(priv);
72
73 do {
74 if (!unimac_mdio_busy(priv))
75 break;
76
77 usleep_range(1000, 2000);
78 } while (timeout--);
79
80 if (!timeout)
81 return -ETIMEDOUT;
82
83 cmd = __raw_readl(priv->base + MDIO_CMD);
84 if (cmd & MDIO_READ_FAIL)
85 return -EIO;
86
87 return cmd & 0xffff;
88}
89
90static int unimac_mdio_write(struct mii_bus *bus, int phy_id,
91 int reg, u16 val)
92{
93 struct unimac_mdio_priv *priv = bus->priv;
94 unsigned int timeout = 1000;
95 u32 cmd;
96
97 /* Prepare the write operation */
98 cmd = MDIO_WR | (phy_id << MDIO_PMD_SHIFT) |
99 (reg << MDIO_REG_SHIFT) | (0xffff & val);
100 __raw_writel(cmd, priv->base + MDIO_CMD);
101
102 unimac_mdio_start(priv);
103
104 do {
105 if (!unimac_mdio_busy(priv))
106 break;
107
108 usleep_range(1000, 2000);
109 } while (timeout--);
110
111 if (!timeout)
112 return -ETIMEDOUT;
113
114 return 0;
115}
116
117static int unimac_mdio_probe(struct platform_device *pdev)
118{
119 struct unimac_mdio_priv *priv;
120 struct device_node *np;
121 struct mii_bus *bus;
122 struct resource *r;
123 int ret;
124
125 np = pdev->dev.of_node;
126
127 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
128 if (!priv)
129 return -ENOMEM;
130
131 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
132
133 /* Just ioremap, as this MDIO block is usually integrated into an
134 * Ethernet MAC controller register range
135 */
136 priv->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
137 if (!priv->base) {
138 dev_err(&pdev->dev, "failed to remap register\n");
139 return -ENOMEM;
140 }
141
142 priv->mii_bus = mdiobus_alloc();
143 if (!priv->mii_bus)
144 return -ENOMEM;
145
146 bus = priv->mii_bus;
147 bus->priv = priv;
148 bus->name = "unimac MII bus";
149 bus->parent = &pdev->dev;
150 bus->read = unimac_mdio_read;
151 bus->write = unimac_mdio_write;
152 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
153
154 bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
155 if (!bus->irq) {
156 ret = -ENOMEM;
157 goto out_mdio_free;
158 }
159
160 ret = of_mdiobus_register(bus, np);
161 if (ret) {
162 dev_err(&pdev->dev, "MDIO bus registration failed\n");
163 goto out_mdio_irq;
164 }
165
166 platform_set_drvdata(pdev, priv);
167
168 dev_info(&pdev->dev, "Broadcom UniMAC MDIO bus at 0x%p\n", priv->base);
169
170 return 0;
171
172out_mdio_irq:
173 kfree(bus->irq);
174out_mdio_free:
175 mdiobus_free(bus);
176 return ret;
177}
178
179static int unimac_mdio_remove(struct platform_device *pdev)
180{
181 struct unimac_mdio_priv *priv = platform_get_drvdata(pdev);
182
183 mdiobus_unregister(priv->mii_bus);
184 kfree(priv->mii_bus->irq);
185 mdiobus_free(priv->mii_bus);
186
187 return 0;
188}
189
190static struct of_device_id unimac_mdio_ids[] = {
191 { .compatible = "brcm,genet-mdio-v4", },
192 { .compatible = "brcm,genet-mdio-v3", },
193 { .compatible = "brcm,genet-mdio-v2", },
194 { .compatible = "brcm,genet-mdio-v1", },
195 { .compatible = "brcm,unimac-mdio", },
196 { /* sentinel */ },
197};
198
199static struct platform_driver unimac_mdio_driver = {
200 .driver = {
201 .name = "unimac-mdio",
202 .owner = THIS_MODULE,
203 .of_match_table = unimac_mdio_ids,
204 },
205 .probe = unimac_mdio_probe,
206 .remove = unimac_mdio_remove,
207};
208module_platform_driver(unimac_mdio_driver);
209
210MODULE_AUTHOR("Broadcom Corporation");
211MODULE_DESCRIPTION("Broadcom UniMAC MDIO bus controller");
212MODULE_LICENSE("GPL");
213MODULE_ALIAS("platform:unimac-mdio");
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 4eaadcfcb0fe..50051f271b10 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -553,8 +553,14 @@ static ssize_t
553phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf) 553phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf)
554{ 554{
555 struct phy_device *phydev = to_phy_device(dev); 555 struct phy_device *phydev = to_phy_device(dev);
556 const char *mode = NULL;
556 557
557 return sprintf(buf, "%s\n", phy_modes(phydev->interface)); 558 if (phy_is_internal(phydev))
559 mode = "internal";
560 else
561 mode = phy_modes(phydev->interface);
562
563 return sprintf(buf, "%s\n", mode);
558} 564}
559static DEVICE_ATTR_RO(phy_interface); 565static DEVICE_ATTR_RO(phy_interface);
560 566
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index a854d38c231d..1dfffdc9dfc3 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -955,7 +955,7 @@ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
955 * 3) Write reg 13 // MMD Data Command for MMD DEVAD 955 * 3) Write reg 13 // MMD Data Command for MMD DEVAD
956 * 3) Read reg 14 // Read MMD data 956 * 3) Read reg 14 // Read MMD data
957 */ 957 */
958static int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, 958int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
959 int devad, int addr) 959 int devad, int addr)
960{ 960{
961 struct phy_driver *phydrv = phydev->drv; 961 struct phy_driver *phydrv = phydev->drv;
@@ -971,6 +971,7 @@ static int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
971 } 971 }
972 return value; 972 return value;
973} 973}
974EXPORT_SYMBOL(phy_read_mmd_indirect);
974 975
975/** 976/**
976 * phy_write_mmd_indirect - writes data to the MMD registers 977 * phy_write_mmd_indirect - writes data to the MMD registers
@@ -988,7 +989,7 @@ static int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
988 * 3) Write reg 13 // MMD Data Command for MMD DEVAD 989 * 3) Write reg 13 // MMD Data Command for MMD DEVAD
989 * 3) Write reg 14 // Write MMD data 990 * 3) Write reg 14 // Write MMD data
990 */ 991 */
991static void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, 992void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
992 int devad, int addr, u32 data) 993 int devad, int addr, u32 data)
993{ 994{
994 struct phy_driver *phydrv = phydev->drv; 995 struct phy_driver *phydrv = phydev->drv;
@@ -1002,6 +1003,7 @@ static void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
1002 phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data); 1003 phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
1003 } 1004 }
1004} 1005}
1006EXPORT_SYMBOL(phy_write_mmd_indirect);
1005 1007
1006/** 1008/**
1007 * phy_init_eee - init and check the EEE feature 1009 * phy_init_eee - init and check the EEE feature
@@ -1017,12 +1019,14 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
1017{ 1019{
1018 /* According to 802.3az,the EEE is supported only in full duplex-mode. 1020 /* According to 802.3az,the EEE is supported only in full duplex-mode.
1019 * Also EEE feature is active when core is operating with MII, GMII 1021 * Also EEE feature is active when core is operating with MII, GMII
1020 * or RGMII. 1022 * or RGMII. Internal PHYs are also allowed to proceed and should
1023 * return an error if they do not support EEE.
1021 */ 1024 */
1022 if ((phydev->duplex == DUPLEX_FULL) && 1025 if ((phydev->duplex == DUPLEX_FULL) &&
1023 ((phydev->interface == PHY_INTERFACE_MODE_MII) || 1026 ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
1024 (phydev->interface == PHY_INTERFACE_MODE_GMII) || 1027 (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
1025 (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { 1028 (phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
1029 phy_is_internal(phydev))) {
1026 int eee_lp, eee_cap, eee_adv; 1030 int eee_lp, eee_cap, eee_adv;
1027 u32 lp, cap, adv; 1031 u32 lp, cap, adv;
1028 int status; 1032 int status;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index ca5ec3e18d36..3fc91e89f5a5 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -230,13 +230,13 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id,
230 for (i = 1; 230 for (i = 1;
231 i < num_ids && c45_ids->devices_in_package == 0; 231 i < num_ids && c45_ids->devices_in_package == 0;
232 i++) { 232 i++) {
233 reg_addr = MII_ADDR_C45 | i << 16 | 6; 233 reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS2;
234 phy_reg = mdiobus_read(bus, addr, reg_addr); 234 phy_reg = mdiobus_read(bus, addr, reg_addr);
235 if (phy_reg < 0) 235 if (phy_reg < 0)
236 return -EIO; 236 return -EIO;
237 c45_ids->devices_in_package = (phy_reg & 0xffff) << 16; 237 c45_ids->devices_in_package = (phy_reg & 0xffff) << 16;
238 238
239 reg_addr = MII_ADDR_C45 | i << 16 | 5; 239 reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS1;
240 phy_reg = mdiobus_read(bus, addr, reg_addr); 240 phy_reg = mdiobus_read(bus, addr, reg_addr);
241 if (phy_reg < 0) 241 if (phy_reg < 0)
242 return -EIO; 242 return -EIO;