diff options
author | David S. Miller <davem@davemloft.net> | 2016-11-13 00:56:28 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-13 00:56:28 -0500 |
commit | 849dcce3fee7f2a68b2c82141e2f3b919bce3c79 (patch) | |
tree | d3a0d6adaa0cc72c1fc568721df940b032f2551d | |
parent | f0a404001204a23f94e1ca0cda8597ce80714f5e (diff) | |
parent | d7445d1f0506fe26a877fac8dcdff7f4eff1328e (diff) |
Merge branch 'amd-xgbe-updates'
Tom Lendacky says:
====================
amd-xgbe: AMD XGBE driver updates 2016-11-10
This patch series is targeted at adding support for a new PCI version
of the hardware. As part of the new PCI device, there is a new PCS/PHY
interaction, ECC support, I2C sideband communication, SFP+ support and
more.
The following updates and fixes are included in this driver update series:
- Hardware workaround for possible incorrectly generated interrupts
during software reset
- Hardware workaround for Tx timestamp register access order
- Add support for a PCI version of the device
- Increase the Rx queue limit to take advantage of the increased number
of DMA channels that might be available
- Add support for a new DMA channel interrupt mode
- Add ECC support for the device memory
- Add support for using the integrated I2C controller for sideband
communication
- Expose the phylib phy_aneg_done() function so it can be called by the
driver
- Add support for SFP+ modules
- Add support for MDIO attached PHYs
- Add support for KR re-driver between the PCS/SerDes and an external
PHY
This patch series is based on net-next.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/aeroflex/greth.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/Kconfig | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-common.h | 314 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c | 152 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 225 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 316 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-i2c.c | 492 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-main.c | 48 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 182 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-pci.c | 529 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 3083 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-platform.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe.h | 177 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 3 | ||||
-rw-r--r-- | include/linux/phy.h | 1 |
17 files changed, 5487 insertions, 90 deletions
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index f8df8248035e..93def92f9997 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c | |||
@@ -1290,15 +1290,6 @@ static int greth_mdio_probe(struct net_device *dev) | |||
1290 | return 0; | 1290 | return 0; |
1291 | } | 1291 | } |
1292 | 1292 | ||
1293 | static inline int phy_aneg_done(struct phy_device *phydev) | ||
1294 | { | ||
1295 | int retval; | ||
1296 | |||
1297 | retval = phy_read(phydev, MII_BMSR); | ||
1298 | |||
1299 | return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE); | ||
1300 | } | ||
1301 | |||
1302 | static int greth_mdio_init(struct greth_private *greth) | 1293 | static int greth_mdio_init(struct greth_private *greth) |
1303 | { | 1294 | { |
1304 | int ret; | 1295 | int ret; |
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig index 0038709fd317..7ab6efbe4189 100644 --- a/drivers/net/ethernet/amd/Kconfig +++ b/drivers/net/ethernet/amd/Kconfig | |||
@@ -173,11 +173,13 @@ config SUNLANCE | |||
173 | 173 | ||
174 | config AMD_XGBE | 174 | config AMD_XGBE |
175 | tristate "AMD 10GbE Ethernet driver" | 175 | tristate "AMD 10GbE Ethernet driver" |
176 | depends on ((OF_NET && OF_ADDRESS) || ACPI) && HAS_IOMEM && HAS_DMA | 176 | depends on ((OF_NET && OF_ADDRESS) || ACPI || PCI) && HAS_IOMEM && HAS_DMA |
177 | depends on ARM64 || COMPILE_TEST | 177 | depends on X86 || ARM64 || COMPILE_TEST |
178 | select BITREVERSE | 178 | select BITREVERSE |
179 | select CRC32 | 179 | select CRC32 |
180 | select PTP_1588_CLOCK | 180 | select PTP_1588_CLOCK |
181 | select PHYLIB | ||
182 | select AMD_XGBE_HAVE_ECC if X86 | ||
181 | ---help--- | 183 | ---help--- |
182 | This driver supports the AMD 10GbE Ethernet device found on an | 184 | This driver supports the AMD 10GbE Ethernet device found on an |
183 | AMD SoC. | 185 | AMD SoC. |
@@ -195,4 +197,8 @@ config AMD_XGBE_DCB | |||
195 | 197 | ||
196 | If unsure, say N. | 198 | If unsure, say N. |
197 | 199 | ||
200 | config AMD_XGBE_HAVE_ECC | ||
201 | bool | ||
202 | default n | ||
203 | |||
198 | endif # NET_VENDOR_AMD | 204 | endif # NET_VENDOR_AMD |
diff --git a/drivers/net/ethernet/amd/xgbe/Makefile b/drivers/net/ethernet/amd/xgbe/Makefile index 217d59ea1c52..0dea8f5da899 100644 --- a/drivers/net/ethernet/amd/xgbe/Makefile +++ b/drivers/net/ethernet/amd/xgbe/Makefile | |||
@@ -3,8 +3,9 @@ obj-$(CONFIG_AMD_XGBE) += amd-xgbe.o | |||
3 | amd-xgbe-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \ | 3 | amd-xgbe-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \ |
4 | xgbe-desc.o xgbe-ethtool.o xgbe-mdio.o \ | 4 | xgbe-desc.o xgbe-ethtool.o xgbe-mdio.o \ |
5 | xgbe-ptp.o \ | 5 | xgbe-ptp.o \ |
6 | xgbe-phy-v1.o \ | 6 | xgbe-i2c.o xgbe-phy-v1.o xgbe-phy-v2.o \ |
7 | xgbe-platform.o | 7 | xgbe-platform.o |
8 | 8 | ||
9 | amd-xgbe-$(CONFIG_PCI) += xgbe-pci.o | ||
9 | amd-xgbe-$(CONFIG_AMD_XGBE_DCB) += xgbe-dcb.o | 10 | amd-xgbe-$(CONFIG_AMD_XGBE_DCB) += xgbe-dcb.o |
10 | amd-xgbe-$(CONFIG_DEBUG_FS) += xgbe-debugfs.o | 11 | amd-xgbe-$(CONFIG_DEBUG_FS) += xgbe-debugfs.o |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index 8036ee52add6..5b7ba25e0065 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h | |||
@@ -159,6 +159,8 @@ | |||
159 | #define DMA_ISR_MACIS_WIDTH 1 | 159 | #define DMA_ISR_MACIS_WIDTH 1 |
160 | #define DMA_ISR_MTLIS_INDEX 16 | 160 | #define DMA_ISR_MTLIS_INDEX 16 |
161 | #define DMA_ISR_MTLIS_WIDTH 1 | 161 | #define DMA_ISR_MTLIS_WIDTH 1 |
162 | #define DMA_MR_INTM_INDEX 12 | ||
163 | #define DMA_MR_INTM_WIDTH 2 | ||
162 | #define DMA_MR_SWR_INDEX 0 | 164 | #define DMA_MR_SWR_INDEX 0 |
163 | #define DMA_MR_SWR_WIDTH 1 | 165 | #define DMA_MR_SWR_WIDTH 1 |
164 | #define DMA_SBMR_EAME_INDEX 11 | 166 | #define DMA_SBMR_EAME_INDEX 11 |
@@ -309,6 +311,11 @@ | |||
309 | #define MAC_HWF0R 0x011c | 311 | #define MAC_HWF0R 0x011c |
310 | #define MAC_HWF1R 0x0120 | 312 | #define MAC_HWF1R 0x0120 |
311 | #define MAC_HWF2R 0x0124 | 313 | #define MAC_HWF2R 0x0124 |
314 | #define MAC_MDIOSCAR 0x0200 | ||
315 | #define MAC_MDIOSCCDR 0x0204 | ||
316 | #define MAC_MDIOISR 0x0214 | ||
317 | #define MAC_MDIOIER 0x0218 | ||
318 | #define MAC_MDIOCL22R 0x0220 | ||
312 | #define MAC_GPIOCR 0x0278 | 319 | #define MAC_GPIOCR 0x0278 |
313 | #define MAC_GPIOSR 0x027c | 320 | #define MAC_GPIOSR 0x027c |
314 | #define MAC_MACA0HR 0x0300 | 321 | #define MAC_MACA0HR 0x0300 |
@@ -409,10 +416,34 @@ | |||
409 | #define MAC_ISR_MMCTXIS_WIDTH 1 | 416 | #define MAC_ISR_MMCTXIS_WIDTH 1 |
410 | #define MAC_ISR_PMTIS_INDEX 4 | 417 | #define MAC_ISR_PMTIS_INDEX 4 |
411 | #define MAC_ISR_PMTIS_WIDTH 1 | 418 | #define MAC_ISR_PMTIS_WIDTH 1 |
419 | #define MAC_ISR_SMI_INDEX 1 | ||
420 | #define MAC_ISR_SMI_WIDTH 1 | ||
412 | #define MAC_ISR_TSIS_INDEX 12 | 421 | #define MAC_ISR_TSIS_INDEX 12 |
413 | #define MAC_ISR_TSIS_WIDTH 1 | 422 | #define MAC_ISR_TSIS_WIDTH 1 |
414 | #define MAC_MACA1HR_AE_INDEX 31 | 423 | #define MAC_MACA1HR_AE_INDEX 31 |
415 | #define MAC_MACA1HR_AE_WIDTH 1 | 424 | #define MAC_MACA1HR_AE_WIDTH 1 |
425 | #define MAC_MDIOIER_SNGLCOMPIE_INDEX 12 | ||
426 | #define MAC_MDIOIER_SNGLCOMPIE_WIDTH 1 | ||
427 | #define MAC_MDIOISR_SNGLCOMPINT_INDEX 12 | ||
428 | #define MAC_MDIOISR_SNGLCOMPINT_WIDTH 1 | ||
429 | #define MAC_MDIOSCAR_DA_INDEX 21 | ||
430 | #define MAC_MDIOSCAR_DA_WIDTH 5 | ||
431 | #define MAC_MDIOSCAR_PA_INDEX 16 | ||
432 | #define MAC_MDIOSCAR_PA_WIDTH 5 | ||
433 | #define MAC_MDIOSCAR_RA_INDEX 0 | ||
434 | #define MAC_MDIOSCAR_RA_WIDTH 16 | ||
435 | #define MAC_MDIOSCAR_REG_INDEX 0 | ||
436 | #define MAC_MDIOSCAR_REG_WIDTH 21 | ||
437 | #define MAC_MDIOSCCDR_BUSY_INDEX 22 | ||
438 | #define MAC_MDIOSCCDR_BUSY_WIDTH 1 | ||
439 | #define MAC_MDIOSCCDR_CMD_INDEX 16 | ||
440 | #define MAC_MDIOSCCDR_CMD_WIDTH 2 | ||
441 | #define MAC_MDIOSCCDR_CR_INDEX 19 | ||
442 | #define MAC_MDIOSCCDR_CR_WIDTH 3 | ||
443 | #define MAC_MDIOSCCDR_DATA_INDEX 0 | ||
444 | #define MAC_MDIOSCCDR_DATA_WIDTH 16 | ||
445 | #define MAC_MDIOSCCDR_SADDR_INDEX 18 | ||
446 | #define MAC_MDIOSCCDR_SADDR_WIDTH 1 | ||
416 | #define MAC_PFR_HMC_INDEX 2 | 447 | #define MAC_PFR_HMC_INDEX 2 |
417 | #define MAC_PFR_HMC_WIDTH 1 | 448 | #define MAC_PFR_HMC_WIDTH 1 |
418 | #define MAC_PFR_HPF_INDEX 10 | 449 | #define MAC_PFR_HPF_INDEX 10 |
@@ -858,8 +889,15 @@ | |||
858 | 889 | ||
859 | /* PCS register offsets */ | 890 | /* PCS register offsets */ |
860 | #define PCS_V1_WINDOW_SELECT 0x03fc | 891 | #define PCS_V1_WINDOW_SELECT 0x03fc |
892 | #define PCS_V2_WINDOW_DEF 0x9060 | ||
861 | #define PCS_V2_WINDOW_SELECT 0x9064 | 893 | #define PCS_V2_WINDOW_SELECT 0x9064 |
862 | 894 | ||
895 | /* PCS register entry bit positions and sizes */ | ||
896 | #define PCS_V2_WINDOW_DEF_OFFSET_INDEX 6 | ||
897 | #define PCS_V2_WINDOW_DEF_OFFSET_WIDTH 14 | ||
898 | #define PCS_V2_WINDOW_DEF_SIZE_INDEX 2 | ||
899 | #define PCS_V2_WINDOW_DEF_SIZE_WIDTH 4 | ||
900 | |||
863 | /* SerDes integration register offsets */ | 901 | /* SerDes integration register offsets */ |
864 | #define SIR0_KR_RT_1 0x002c | 902 | #define SIR0_KR_RT_1 0x002c |
865 | #define SIR0_STATUS 0x0040 | 903 | #define SIR0_STATUS 0x0040 |
@@ -902,6 +940,198 @@ | |||
902 | #define RXTX_REG129_RXDFE_CONFIG_INDEX 14 | 940 | #define RXTX_REG129_RXDFE_CONFIG_INDEX 14 |
903 | #define RXTX_REG129_RXDFE_CONFIG_WIDTH 2 | 941 | #define RXTX_REG129_RXDFE_CONFIG_WIDTH 2 |
904 | 942 | ||
943 | /* MAC Control register offsets */ | ||
944 | #define XP_PROP_0 0x0000 | ||
945 | #define XP_PROP_1 0x0004 | ||
946 | #define XP_PROP_2 0x0008 | ||
947 | #define XP_PROP_3 0x000c | ||
948 | #define XP_PROP_4 0x0010 | ||
949 | #define XP_PROP_5 0x0014 | ||
950 | #define XP_MAC_ADDR_LO 0x0020 | ||
951 | #define XP_MAC_ADDR_HI 0x0024 | ||
952 | #define XP_ECC_ISR 0x0030 | ||
953 | #define XP_ECC_IER 0x0034 | ||
954 | #define XP_ECC_CNT0 0x003c | ||
955 | #define XP_ECC_CNT1 0x0040 | ||
956 | #define XP_DRIVER_INT_REQ 0x0060 | ||
957 | #define XP_DRIVER_INT_RO 0x0064 | ||
958 | #define XP_DRIVER_SCRATCH_0 0x0068 | ||
959 | #define XP_DRIVER_SCRATCH_1 0x006c | ||
960 | #define XP_INT_EN 0x0078 | ||
961 | #define XP_I2C_MUTEX 0x0080 | ||
962 | #define XP_MDIO_MUTEX 0x0084 | ||
963 | |||
964 | /* MAC Control register entry bit positions and sizes */ | ||
965 | #define XP_DRIVER_INT_REQ_REQUEST_INDEX 0 | ||
966 | #define XP_DRIVER_INT_REQ_REQUEST_WIDTH 1 | ||
967 | #define XP_DRIVER_INT_RO_STATUS_INDEX 0 | ||
968 | #define XP_DRIVER_INT_RO_STATUS_WIDTH 1 | ||
969 | #define XP_DRIVER_SCRATCH_0_COMMAND_INDEX 0 | ||
970 | #define XP_DRIVER_SCRATCH_0_COMMAND_WIDTH 8 | ||
971 | #define XP_DRIVER_SCRATCH_0_SUB_COMMAND_INDEX 8 | ||
972 | #define XP_DRIVER_SCRATCH_0_SUB_COMMAND_WIDTH 8 | ||
973 | #define XP_ECC_CNT0_RX_DED_INDEX 24 | ||
974 | #define XP_ECC_CNT0_RX_DED_WIDTH 8 | ||
975 | #define XP_ECC_CNT0_RX_SEC_INDEX 16 | ||
976 | #define XP_ECC_CNT0_RX_SEC_WIDTH 8 | ||
977 | #define XP_ECC_CNT0_TX_DED_INDEX 8 | ||
978 | #define XP_ECC_CNT0_TX_DED_WIDTH 8 | ||
979 | #define XP_ECC_CNT0_TX_SEC_INDEX 0 | ||
980 | #define XP_ECC_CNT0_TX_SEC_WIDTH 8 | ||
981 | #define XP_ECC_CNT1_DESC_DED_INDEX 8 | ||
982 | #define XP_ECC_CNT1_DESC_DED_WIDTH 8 | ||
983 | #define XP_ECC_CNT1_DESC_SEC_INDEX 0 | ||
984 | #define XP_ECC_CNT1_DESC_SEC_WIDTH 8 | ||
985 | #define XP_ECC_IER_DESC_DED_INDEX 0 | ||
986 | #define XP_ECC_IER_DESC_DED_WIDTH 1 | ||
987 | #define XP_ECC_IER_DESC_SEC_INDEX 1 | ||
988 | #define XP_ECC_IER_DESC_SEC_WIDTH 1 | ||
989 | #define XP_ECC_IER_RX_DED_INDEX 2 | ||
990 | #define XP_ECC_IER_RX_DED_WIDTH 1 | ||
991 | #define XP_ECC_IER_RX_SEC_INDEX 3 | ||
992 | #define XP_ECC_IER_RX_SEC_WIDTH 1 | ||
993 | #define XP_ECC_IER_TX_DED_INDEX 4 | ||
994 | #define XP_ECC_IER_TX_DED_WIDTH 1 | ||
995 | #define XP_ECC_IER_TX_SEC_INDEX 5 | ||
996 | #define XP_ECC_IER_TX_SEC_WIDTH 1 | ||
997 | #define XP_ECC_ISR_DESC_DED_INDEX 0 | ||
998 | #define XP_ECC_ISR_DESC_DED_WIDTH 1 | ||
999 | #define XP_ECC_ISR_DESC_SEC_INDEX 1 | ||
1000 | #define XP_ECC_ISR_DESC_SEC_WIDTH 1 | ||
1001 | #define XP_ECC_ISR_RX_DED_INDEX 2 | ||
1002 | #define XP_ECC_ISR_RX_DED_WIDTH 1 | ||
1003 | #define XP_ECC_ISR_RX_SEC_INDEX 3 | ||
1004 | #define XP_ECC_ISR_RX_SEC_WIDTH 1 | ||
1005 | #define XP_ECC_ISR_TX_DED_INDEX 4 | ||
1006 | #define XP_ECC_ISR_TX_DED_WIDTH 1 | ||
1007 | #define XP_ECC_ISR_TX_SEC_INDEX 5 | ||
1008 | #define XP_ECC_ISR_TX_SEC_WIDTH 1 | ||
1009 | #define XP_I2C_MUTEX_BUSY_INDEX 31 | ||
1010 | #define XP_I2C_MUTEX_BUSY_WIDTH 1 | ||
1011 | #define XP_I2C_MUTEX_ID_INDEX 29 | ||
1012 | #define XP_I2C_MUTEX_ID_WIDTH 2 | ||
1013 | #define XP_I2C_MUTEX_ACTIVE_INDEX 0 | ||
1014 | #define XP_I2C_MUTEX_ACTIVE_WIDTH 1 | ||
1015 | #define XP_MAC_ADDR_HI_VALID_INDEX 31 | ||
1016 | #define XP_MAC_ADDR_HI_VALID_WIDTH 1 | ||
1017 | #define XP_PROP_0_CONN_TYPE_INDEX 28 | ||
1018 | #define XP_PROP_0_CONN_TYPE_WIDTH 3 | ||
1019 | #define XP_PROP_0_MDIO_ADDR_INDEX 16 | ||
1020 | #define XP_PROP_0_MDIO_ADDR_WIDTH 5 | ||
1021 | #define XP_PROP_0_PORT_ID_INDEX 0 | ||
1022 | #define XP_PROP_0_PORT_ID_WIDTH 8 | ||
1023 | #define XP_PROP_0_PORT_MODE_INDEX 8 | ||
1024 | #define XP_PROP_0_PORT_MODE_WIDTH 4 | ||
1025 | #define XP_PROP_0_PORT_SPEEDS_INDEX 23 | ||
1026 | #define XP_PROP_0_PORT_SPEEDS_WIDTH 4 | ||
1027 | #define XP_PROP_1_MAX_RX_DMA_INDEX 24 | ||
1028 | #define XP_PROP_1_MAX_RX_DMA_WIDTH 5 | ||
1029 | #define XP_PROP_1_MAX_RX_QUEUES_INDEX 8 | ||
1030 | #define XP_PROP_1_MAX_RX_QUEUES_WIDTH 5 | ||
1031 | #define XP_PROP_1_MAX_TX_DMA_INDEX 16 | ||
1032 | #define XP_PROP_1_MAX_TX_DMA_WIDTH 5 | ||
1033 | #define XP_PROP_1_MAX_TX_QUEUES_INDEX 0 | ||
1034 | #define XP_PROP_1_MAX_TX_QUEUES_WIDTH 5 | ||
1035 | #define XP_PROP_2_RX_FIFO_SIZE_INDEX 16 | ||
1036 | #define XP_PROP_2_RX_FIFO_SIZE_WIDTH 16 | ||
1037 | #define XP_PROP_2_TX_FIFO_SIZE_INDEX 0 | ||
1038 | #define XP_PROP_2_TX_FIFO_SIZE_WIDTH 16 | ||
1039 | #define XP_PROP_3_GPIO_MASK_INDEX 28 | ||
1040 | #define XP_PROP_3_GPIO_MASK_WIDTH 4 | ||
1041 | #define XP_PROP_3_GPIO_MOD_ABS_INDEX 20 | ||
1042 | #define XP_PROP_3_GPIO_MOD_ABS_WIDTH 4 | ||
1043 | #define XP_PROP_3_GPIO_RATE_SELECT_INDEX 16 | ||
1044 | #define XP_PROP_3_GPIO_RATE_SELECT_WIDTH 4 | ||
1045 | #define XP_PROP_3_GPIO_RX_LOS_INDEX 24 | ||
1046 | #define XP_PROP_3_GPIO_RX_LOS_WIDTH 4 | ||
1047 | #define XP_PROP_3_GPIO_TX_FAULT_INDEX 12 | ||
1048 | #define XP_PROP_3_GPIO_TX_FAULT_WIDTH 4 | ||
1049 | #define XP_PROP_3_GPIO_ADDR_INDEX 8 | ||
1050 | #define XP_PROP_3_GPIO_ADDR_WIDTH 3 | ||
1051 | #define XP_PROP_3_MDIO_RESET_INDEX 0 | ||
1052 | #define XP_PROP_3_MDIO_RESET_WIDTH 2 | ||
1053 | #define XP_PROP_3_MDIO_RESET_I2C_ADDR_INDEX 8 | ||
1054 | #define XP_PROP_3_MDIO_RESET_I2C_ADDR_WIDTH 3 | ||
1055 | #define XP_PROP_3_MDIO_RESET_I2C_GPIO_INDEX 12 | ||
1056 | #define XP_PROP_3_MDIO_RESET_I2C_GPIO_WIDTH 4 | ||
1057 | #define XP_PROP_3_MDIO_RESET_INT_GPIO_INDEX 4 | ||
1058 | #define XP_PROP_3_MDIO_RESET_INT_GPIO_WIDTH 2 | ||
1059 | #define XP_PROP_4_MUX_ADDR_HI_INDEX 8 | ||
1060 | #define XP_PROP_4_MUX_ADDR_HI_WIDTH 5 | ||
1061 | #define XP_PROP_4_MUX_ADDR_LO_INDEX 0 | ||
1062 | #define XP_PROP_4_MUX_ADDR_LO_WIDTH 3 | ||
1063 | #define XP_PROP_4_MUX_CHAN_INDEX 4 | ||
1064 | #define XP_PROP_4_MUX_CHAN_WIDTH 3 | ||
1065 | #define XP_PROP_4_REDRV_ADDR_INDEX 16 | ||
1066 | #define XP_PROP_4_REDRV_ADDR_WIDTH 7 | ||
1067 | #define XP_PROP_4_REDRV_IF_INDEX 23 | ||
1068 | #define XP_PROP_4_REDRV_IF_WIDTH 1 | ||
1069 | #define XP_PROP_4_REDRV_LANE_INDEX 24 | ||
1070 | #define XP_PROP_4_REDRV_LANE_WIDTH 3 | ||
1071 | #define XP_PROP_4_REDRV_MODEL_INDEX 28 | ||
1072 | #define XP_PROP_4_REDRV_MODEL_WIDTH 3 | ||
1073 | #define XP_PROP_4_REDRV_PRESENT_INDEX 31 | ||
1074 | #define XP_PROP_4_REDRV_PRESENT_WIDTH 1 | ||
1075 | |||
1076 | /* I2C Control register offsets */ | ||
1077 | #define IC_CON 0x0000 | ||
1078 | #define IC_TAR 0x0004 | ||
1079 | #define IC_DATA_CMD 0x0010 | ||
1080 | #define IC_INTR_STAT 0x002c | ||
1081 | #define IC_INTR_MASK 0x0030 | ||
1082 | #define IC_RAW_INTR_STAT 0x0034 | ||
1083 | #define IC_CLR_INTR 0x0040 | ||
1084 | #define IC_CLR_TX_ABRT 0x0054 | ||
1085 | #define IC_CLR_STOP_DET 0x0060 | ||
1086 | #define IC_ENABLE 0x006c | ||
1087 | #define IC_TXFLR 0x0074 | ||
1088 | #define IC_RXFLR 0x0078 | ||
1089 | #define IC_TX_ABRT_SOURCE 0x0080 | ||
1090 | #define IC_ENABLE_STATUS 0x009c | ||
1091 | #define IC_COMP_PARAM_1 0x00f4 | ||
1092 | |||
1093 | /* I2C Control register entry bit positions and sizes */ | ||
1094 | #define IC_COMP_PARAM_1_MAX_SPEED_MODE_INDEX 2 | ||
1095 | #define IC_COMP_PARAM_1_MAX_SPEED_MODE_WIDTH 2 | ||
1096 | #define IC_COMP_PARAM_1_RX_BUFFER_DEPTH_INDEX 8 | ||
1097 | #define IC_COMP_PARAM_1_RX_BUFFER_DEPTH_WIDTH 8 | ||
1098 | #define IC_COMP_PARAM_1_TX_BUFFER_DEPTH_INDEX 16 | ||
1099 | #define IC_COMP_PARAM_1_TX_BUFFER_DEPTH_WIDTH 8 | ||
1100 | #define IC_CON_MASTER_MODE_INDEX 0 | ||
1101 | #define IC_CON_MASTER_MODE_WIDTH 1 | ||
1102 | #define IC_CON_RESTART_EN_INDEX 5 | ||
1103 | #define IC_CON_RESTART_EN_WIDTH 1 | ||
1104 | #define IC_CON_RX_FIFO_FULL_HOLD_INDEX 9 | ||
1105 | #define IC_CON_RX_FIFO_FULL_HOLD_WIDTH 1 | ||
1106 | #define IC_CON_SLAVE_DISABLE_INDEX 6 | ||
1107 | #define IC_CON_SLAVE_DISABLE_WIDTH 1 | ||
1108 | #define IC_CON_SPEED_INDEX 1 | ||
1109 | #define IC_CON_SPEED_WIDTH 2 | ||
1110 | #define IC_DATA_CMD_CMD_INDEX 8 | ||
1111 | #define IC_DATA_CMD_CMD_WIDTH 1 | ||
1112 | #define IC_DATA_CMD_STOP_INDEX 9 | ||
1113 | #define IC_DATA_CMD_STOP_WIDTH 1 | ||
1114 | #define IC_ENABLE_ABORT_INDEX 1 | ||
1115 | #define IC_ENABLE_ABORT_WIDTH 1 | ||
1116 | #define IC_ENABLE_EN_INDEX 0 | ||
1117 | #define IC_ENABLE_EN_WIDTH 1 | ||
1118 | #define IC_ENABLE_STATUS_EN_INDEX 0 | ||
1119 | #define IC_ENABLE_STATUS_EN_WIDTH 1 | ||
1120 | #define IC_INTR_MASK_TX_EMPTY_INDEX 4 | ||
1121 | #define IC_INTR_MASK_TX_EMPTY_WIDTH 1 | ||
1122 | #define IC_RAW_INTR_STAT_RX_FULL_INDEX 2 | ||
1123 | #define IC_RAW_INTR_STAT_RX_FULL_WIDTH 1 | ||
1124 | #define IC_RAW_INTR_STAT_STOP_DET_INDEX 9 | ||
1125 | #define IC_RAW_INTR_STAT_STOP_DET_WIDTH 1 | ||
1126 | #define IC_RAW_INTR_STAT_TX_ABRT_INDEX 6 | ||
1127 | #define IC_RAW_INTR_STAT_TX_ABRT_WIDTH 1 | ||
1128 | #define IC_RAW_INTR_STAT_TX_EMPTY_INDEX 4 | ||
1129 | #define IC_RAW_INTR_STAT_TX_EMPTY_WIDTH 1 | ||
1130 | |||
1131 | /* I2C Control register value */ | ||
1132 | #define IC_TX_ABRT_7B_ADDR_NOACK 0x0001 | ||
1133 | #define IC_TX_ABRT_ARB_LOST 0x1000 | ||
1134 | |||
905 | /* Descriptor/Packet entry bit positions and sizes */ | 1135 | /* Descriptor/Packet entry bit positions and sizes */ |
906 | #define RX_PACKET_ERRORS_CRC_INDEX 2 | 1136 | #define RX_PACKET_ERRORS_CRC_INDEX 2 |
907 | #define RX_PACKET_ERRORS_CRC_WIDTH 1 | 1137 | #define RX_PACKET_ERRORS_CRC_WIDTH 1 |
@@ -1078,6 +1308,14 @@ | |||
1078 | #define MDIO_VEND2_CTRL1_AN_RESTART BIT(9) | 1308 | #define MDIO_VEND2_CTRL1_AN_RESTART BIT(9) |
1079 | #endif | 1309 | #endif |
1080 | 1310 | ||
1311 | #ifndef MDIO_VEND2_CTRL1_SS6 | ||
1312 | #define MDIO_VEND2_CTRL1_SS6 BIT(6) | ||
1313 | #endif | ||
1314 | |||
1315 | #ifndef MDIO_VEND2_CTRL1_SS13 | ||
1316 | #define MDIO_VEND2_CTRL1_SS13 BIT(13) | ||
1317 | #endif | ||
1318 | |||
1081 | /* MDIO mask values */ | 1319 | /* MDIO mask values */ |
1082 | #define XGBE_AN_CL73_INT_CMPLT BIT(0) | 1320 | #define XGBE_AN_CL73_INT_CMPLT BIT(0) |
1083 | #define XGBE_AN_CL73_INC_LINK BIT(1) | 1321 | #define XGBE_AN_CL73_INC_LINK BIT(1) |
@@ -1240,6 +1478,16 @@ do { \ | |||
1240 | /* Macros for building, reading or writing register values or bits | 1478 | /* Macros for building, reading or writing register values or bits |
1241 | * within the register values of XPCS registers. | 1479 | * within the register values of XPCS registers. |
1242 | */ | 1480 | */ |
1481 | #define XPCS_GET_BITS(_var, _prefix, _field) \ | ||
1482 | GET_BITS((_var), \ | ||
1483 | _prefix##_##_field##_INDEX, \ | ||
1484 | _prefix##_##_field##_WIDTH) | ||
1485 | |||
1486 | #define XPCS_SET_BITS(_var, _prefix, _field, _val) \ | ||
1487 | SET_BITS((_var), \ | ||
1488 | _prefix##_##_field##_INDEX, \ | ||
1489 | _prefix##_##_field##_WIDTH, (_val)) | ||
1490 | |||
1243 | #define XPCS32_IOWRITE(_pdata, _off, _val) \ | 1491 | #define XPCS32_IOWRITE(_pdata, _off, _val) \ |
1244 | iowrite32(_val, (_pdata)->xpcs_regs + (_off)) | 1492 | iowrite32(_val, (_pdata)->xpcs_regs + (_off)) |
1245 | 1493 | ||
@@ -1329,6 +1577,72 @@ do { \ | |||
1329 | } while (0) | 1577 | } while (0) |
1330 | 1578 | ||
1331 | /* Macros for building, reading or writing register values or bits | 1579 | /* Macros for building, reading or writing register values or bits |
1580 | * within the register values of MAC Control registers. | ||
1581 | */ | ||
1582 | #define XP_GET_BITS(_var, _prefix, _field) \ | ||
1583 | GET_BITS((_var), \ | ||
1584 | _prefix##_##_field##_INDEX, \ | ||
1585 | _prefix##_##_field##_WIDTH) | ||
1586 | |||
1587 | #define XP_SET_BITS(_var, _prefix, _field, _val) \ | ||
1588 | SET_BITS((_var), \ | ||
1589 | _prefix##_##_field##_INDEX, \ | ||
1590 | _prefix##_##_field##_WIDTH, (_val)) | ||
1591 | |||
1592 | #define XP_IOREAD(_pdata, _reg) \ | ||
1593 | ioread32((_pdata)->xprop_regs + (_reg)) | ||
1594 | |||
1595 | #define XP_IOREAD_BITS(_pdata, _reg, _field) \ | ||
1596 | GET_BITS(XP_IOREAD((_pdata), (_reg)), \ | ||
1597 | _reg##_##_field##_INDEX, \ | ||
1598 | _reg##_##_field##_WIDTH) | ||
1599 | |||
1600 | #define XP_IOWRITE(_pdata, _reg, _val) \ | ||
1601 | iowrite32((_val), (_pdata)->xprop_regs + (_reg)) | ||
1602 | |||
1603 | #define XP_IOWRITE_BITS(_pdata, _reg, _field, _val) \ | ||
1604 | do { \ | ||
1605 | u32 reg_val = XP_IOREAD((_pdata), (_reg)); \ | ||
1606 | SET_BITS(reg_val, \ | ||
1607 | _reg##_##_field##_INDEX, \ | ||
1608 | _reg##_##_field##_WIDTH, (_val)); \ | ||
1609 | XP_IOWRITE((_pdata), (_reg), reg_val); \ | ||
1610 | } while (0) | ||
1611 | |||
1612 | /* Macros for building, reading or writing register values or bits | ||
1613 | * within the register values of I2C Control registers. | ||
1614 | */ | ||
1615 | #define XI2C_GET_BITS(_var, _prefix, _field) \ | ||
1616 | GET_BITS((_var), \ | ||
1617 | _prefix##_##_field##_INDEX, \ | ||
1618 | _prefix##_##_field##_WIDTH) | ||
1619 | |||
1620 | #define XI2C_SET_BITS(_var, _prefix, _field, _val) \ | ||
1621 | SET_BITS((_var), \ | ||
1622 | _prefix##_##_field##_INDEX, \ | ||
1623 | _prefix##_##_field##_WIDTH, (_val)) | ||
1624 | |||
1625 | #define XI2C_IOREAD(_pdata, _reg) \ | ||
1626 | ioread32((_pdata)->xi2c_regs + (_reg)) | ||
1627 | |||
1628 | #define XI2C_IOREAD_BITS(_pdata, _reg, _field) \ | ||
1629 | GET_BITS(XI2C_IOREAD((_pdata), (_reg)), \ | ||
1630 | _reg##_##_field##_INDEX, \ | ||
1631 | _reg##_##_field##_WIDTH) | ||
1632 | |||
1633 | #define XI2C_IOWRITE(_pdata, _reg, _val) \ | ||
1634 | iowrite32((_val), (_pdata)->xi2c_regs + (_reg)) | ||
1635 | |||
1636 | #define XI2C_IOWRITE_BITS(_pdata, _reg, _field, _val) \ | ||
1637 | do { \ | ||
1638 | u32 reg_val = XI2C_IOREAD((_pdata), (_reg)); \ | ||
1639 | SET_BITS(reg_val, \ | ||
1640 | _reg##_##_field##_INDEX, \ | ||
1641 | _reg##_##_field##_WIDTH, (_val)); \ | ||
1642 | XI2C_IOWRITE((_pdata), (_reg), reg_val); \ | ||
1643 | } while (0) | ||
1644 | |||
1645 | /* Macros for building, reading or writing register values or bits | ||
1332 | * using MDIO. Different from above because of the use of standardized | 1646 | * using MDIO. Different from above because of the use of standardized |
1333 | * Linux include values. No shifting is performed with the bit | 1647 | * Linux include values. No shifting is performed with the bit |
1334 | * operations, everything works on mask values. | 1648 | * operations, everything works on mask values. |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c index 96f485ab612e..0c0140decbc2 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c | |||
@@ -316,6 +316,126 @@ static const struct file_operations xpcs_reg_value_fops = { | |||
316 | .write = xpcs_reg_value_write, | 316 | .write = xpcs_reg_value_write, |
317 | }; | 317 | }; |
318 | 318 | ||
319 | static ssize_t xprop_reg_addr_read(struct file *filp, char __user *buffer, | ||
320 | size_t count, loff_t *ppos) | ||
321 | { | ||
322 | struct xgbe_prv_data *pdata = filp->private_data; | ||
323 | |||
324 | return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xprop_reg); | ||
325 | } | ||
326 | |||
327 | static ssize_t xprop_reg_addr_write(struct file *filp, | ||
328 | const char __user *buffer, | ||
329 | size_t count, loff_t *ppos) | ||
330 | { | ||
331 | struct xgbe_prv_data *pdata = filp->private_data; | ||
332 | |||
333 | return xgbe_common_write(buffer, count, ppos, | ||
334 | &pdata->debugfs_xprop_reg); | ||
335 | } | ||
336 | |||
337 | static ssize_t xprop_reg_value_read(struct file *filp, char __user *buffer, | ||
338 | size_t count, loff_t *ppos) | ||
339 | { | ||
340 | struct xgbe_prv_data *pdata = filp->private_data; | ||
341 | unsigned int value; | ||
342 | |||
343 | value = XP_IOREAD(pdata, pdata->debugfs_xprop_reg); | ||
344 | |||
345 | return xgbe_common_read(buffer, count, ppos, value); | ||
346 | } | ||
347 | |||
348 | static ssize_t xprop_reg_value_write(struct file *filp, | ||
349 | const char __user *buffer, | ||
350 | size_t count, loff_t *ppos) | ||
351 | { | ||
352 | struct xgbe_prv_data *pdata = filp->private_data; | ||
353 | unsigned int value; | ||
354 | ssize_t len; | ||
355 | |||
356 | len = xgbe_common_write(buffer, count, ppos, &value); | ||
357 | if (len < 0) | ||
358 | return len; | ||
359 | |||
360 | XP_IOWRITE(pdata, pdata->debugfs_xprop_reg, value); | ||
361 | |||
362 | return len; | ||
363 | } | ||
364 | |||
365 | static const struct file_operations xprop_reg_addr_fops = { | ||
366 | .owner = THIS_MODULE, | ||
367 | .open = simple_open, | ||
368 | .read = xprop_reg_addr_read, | ||
369 | .write = xprop_reg_addr_write, | ||
370 | }; | ||
371 | |||
372 | static const struct file_operations xprop_reg_value_fops = { | ||
373 | .owner = THIS_MODULE, | ||
374 | .open = simple_open, | ||
375 | .read = xprop_reg_value_read, | ||
376 | .write = xprop_reg_value_write, | ||
377 | }; | ||
378 | |||
379 | static ssize_t xi2c_reg_addr_read(struct file *filp, char __user *buffer, | ||
380 | size_t count, loff_t *ppos) | ||
381 | { | ||
382 | struct xgbe_prv_data *pdata = filp->private_data; | ||
383 | |||
384 | return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xi2c_reg); | ||
385 | } | ||
386 | |||
387 | static ssize_t xi2c_reg_addr_write(struct file *filp, | ||
388 | const char __user *buffer, | ||
389 | size_t count, loff_t *ppos) | ||
390 | { | ||
391 | struct xgbe_prv_data *pdata = filp->private_data; | ||
392 | |||
393 | return xgbe_common_write(buffer, count, ppos, | ||
394 | &pdata->debugfs_xi2c_reg); | ||
395 | } | ||
396 | |||
397 | static ssize_t xi2c_reg_value_read(struct file *filp, char __user *buffer, | ||
398 | size_t count, loff_t *ppos) | ||
399 | { | ||
400 | struct xgbe_prv_data *pdata = filp->private_data; | ||
401 | unsigned int value; | ||
402 | |||
403 | value = XI2C_IOREAD(pdata, pdata->debugfs_xi2c_reg); | ||
404 | |||
405 | return xgbe_common_read(buffer, count, ppos, value); | ||
406 | } | ||
407 | |||
408 | static ssize_t xi2c_reg_value_write(struct file *filp, | ||
409 | const char __user *buffer, | ||
410 | size_t count, loff_t *ppos) | ||
411 | { | ||
412 | struct xgbe_prv_data *pdata = filp->private_data; | ||
413 | unsigned int value; | ||
414 | ssize_t len; | ||
415 | |||
416 | len = xgbe_common_write(buffer, count, ppos, &value); | ||
417 | if (len < 0) | ||
418 | return len; | ||
419 | |||
420 | XI2C_IOWRITE(pdata, pdata->debugfs_xi2c_reg, value); | ||
421 | |||
422 | return len; | ||
423 | } | ||
424 | |||
425 | static const struct file_operations xi2c_reg_addr_fops = { | ||
426 | .owner = THIS_MODULE, | ||
427 | .open = simple_open, | ||
428 | .read = xi2c_reg_addr_read, | ||
429 | .write = xi2c_reg_addr_write, | ||
430 | }; | ||
431 | |||
432 | static const struct file_operations xi2c_reg_value_fops = { | ||
433 | .owner = THIS_MODULE, | ||
434 | .open = simple_open, | ||
435 | .read = xi2c_reg_value_read, | ||
436 | .write = xi2c_reg_value_write, | ||
437 | }; | ||
438 | |||
319 | void xgbe_debugfs_init(struct xgbe_prv_data *pdata) | 439 | void xgbe_debugfs_init(struct xgbe_prv_data *pdata) |
320 | { | 440 | { |
321 | struct dentry *pfile; | 441 | struct dentry *pfile; |
@@ -367,6 +487,38 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata) | |||
367 | if (!pfile) | 487 | if (!pfile) |
368 | netdev_err(pdata->netdev, "debugfs_create_file failed\n"); | 488 | netdev_err(pdata->netdev, "debugfs_create_file failed\n"); |
369 | 489 | ||
490 | if (pdata->xprop_regs) { | ||
491 | pfile = debugfs_create_file("xprop_register", 0600, | ||
492 | pdata->xgbe_debugfs, pdata, | ||
493 | &xprop_reg_addr_fops); | ||
494 | if (!pfile) | ||
495 | netdev_err(pdata->netdev, | ||
496 | "debugfs_create_file failed\n"); | ||
497 | |||
498 | pfile = debugfs_create_file("xprop_register_value", 0600, | ||
499 | pdata->xgbe_debugfs, pdata, | ||
500 | &xprop_reg_value_fops); | ||
501 | if (!pfile) | ||
502 | netdev_err(pdata->netdev, | ||
503 | "debugfs_create_file failed\n"); | ||
504 | } | ||
505 | |||
506 | if (pdata->xi2c_regs) { | ||
507 | pfile = debugfs_create_file("xi2c_register", 0600, | ||
508 | pdata->xgbe_debugfs, pdata, | ||
509 | &xi2c_reg_addr_fops); | ||
510 | if (!pfile) | ||
511 | netdev_err(pdata->netdev, | ||
512 | "debugfs_create_file failed\n"); | ||
513 | |||
514 | pfile = debugfs_create_file("xi2c_register_value", 0600, | ||
515 | pdata->xgbe_debugfs, pdata, | ||
516 | &xi2c_reg_value_fops); | ||
517 | if (!pfile) | ||
518 | netdev_err(pdata->netdev, | ||
519 | "debugfs_create_file failed\n"); | ||
520 | } | ||
521 | |||
370 | kfree(buf); | 522 | kfree(buf); |
371 | } | 523 | } |
372 | 524 | ||
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 903731902153..30056e24e1fc 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c | |||
@@ -646,6 +646,11 @@ static void xgbe_enable_dma_interrupts(struct xgbe_prv_data *pdata) | |||
646 | unsigned int dma_ch_isr, dma_ch_ier; | 646 | unsigned int dma_ch_isr, dma_ch_ier; |
647 | unsigned int i; | 647 | unsigned int i; |
648 | 648 | ||
649 | /* Set the interrupt mode if supported */ | ||
650 | if (pdata->channel_irq_mode) | ||
651 | XGMAC_IOWRITE_BITS(pdata, DMA_MR, INTM, | ||
652 | pdata->channel_irq_mode); | ||
653 | |||
649 | channel = pdata->channel; | 654 | channel = pdata->channel; |
650 | for (i = 0; i < pdata->channel_count; i++, channel++) { | 655 | for (i = 0; i < pdata->channel_count; i++, channel++) { |
651 | /* Clear all the interrupts which are set */ | 656 | /* Clear all the interrupts which are set */ |
@@ -667,19 +672,21 @@ static void xgbe_enable_dma_interrupts(struct xgbe_prv_data *pdata) | |||
667 | if (channel->tx_ring) { | 672 | if (channel->tx_ring) { |
668 | /* Enable the following Tx interrupts | 673 | /* Enable the following Tx interrupts |
669 | * TIE - Transmit Interrupt Enable (unless using | 674 | * TIE - Transmit Interrupt Enable (unless using |
670 | * per channel interrupts) | 675 | * per channel interrupts in edge triggered |
676 | * mode) | ||
671 | */ | 677 | */ |
672 | if (!pdata->per_channel_irq) | 678 | if (!pdata->per_channel_irq || pdata->channel_irq_mode) |
673 | XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1); | 679 | XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1); |
674 | } | 680 | } |
675 | if (channel->rx_ring) { | 681 | if (channel->rx_ring) { |
676 | /* Enable following Rx interrupts | 682 | /* Enable following Rx interrupts |
677 | * RBUE - Receive Buffer Unavailable Enable | 683 | * RBUE - Receive Buffer Unavailable Enable |
678 | * RIE - Receive Interrupt Enable (unless using | 684 | * RIE - Receive Interrupt Enable (unless using |
679 | * per channel interrupts) | 685 | * per channel interrupts in edge triggered |
686 | * mode) | ||
680 | */ | 687 | */ |
681 | XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 1); | 688 | XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 1); |
682 | if (!pdata->per_channel_irq) | 689 | if (!pdata->per_channel_irq || pdata->channel_irq_mode) |
683 | XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1); | 690 | XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1); |
684 | } | 691 | } |
685 | 692 | ||
@@ -715,6 +722,68 @@ static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata) | |||
715 | /* Enable all counter interrupts */ | 722 | /* Enable all counter interrupts */ |
716 | XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xffffffff); | 723 | XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xffffffff); |
717 | XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xffffffff); | 724 | XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xffffffff); |
725 | |||
726 | /* Enable MDIO single command completion interrupt */ | ||
727 | XGMAC_IOWRITE_BITS(pdata, MAC_MDIOIER, SNGLCOMPIE, 1); | ||
728 | } | ||
729 | |||
730 | static void xgbe_enable_ecc_interrupts(struct xgbe_prv_data *pdata) | ||
731 | { | ||
732 | unsigned int ecc_isr, ecc_ier = 0; | ||
733 | |||
734 | if (!pdata->vdata->ecc_support) | ||
735 | return; | ||
736 | |||
737 | /* Clear all the interrupts which are set */ | ||
738 | ecc_isr = XP_IOREAD(pdata, XP_ECC_ISR); | ||
739 | XP_IOWRITE(pdata, XP_ECC_ISR, ecc_isr); | ||
740 | |||
741 | /* Enable ECC interrupts */ | ||
742 | XP_SET_BITS(ecc_ier, XP_ECC_IER, TX_DED, 1); | ||
743 | XP_SET_BITS(ecc_ier, XP_ECC_IER, TX_SEC, 1); | ||
744 | XP_SET_BITS(ecc_ier, XP_ECC_IER, RX_DED, 1); | ||
745 | XP_SET_BITS(ecc_ier, XP_ECC_IER, RX_SEC, 1); | ||
746 | XP_SET_BITS(ecc_ier, XP_ECC_IER, DESC_DED, 1); | ||
747 | XP_SET_BITS(ecc_ier, XP_ECC_IER, DESC_SEC, 1); | ||
748 | |||
749 | XP_IOWRITE(pdata, XP_ECC_IER, ecc_ier); | ||
750 | } | ||
751 | |||
752 | static void xgbe_disable_ecc_ded(struct xgbe_prv_data *pdata) | ||
753 | { | ||
754 | unsigned int ecc_ier; | ||
755 | |||
756 | ecc_ier = XP_IOREAD(pdata, XP_ECC_IER); | ||
757 | |||
758 | /* Disable ECC DED interrupts */ | ||
759 | XP_SET_BITS(ecc_ier, XP_ECC_IER, TX_DED, 0); | ||
760 | XP_SET_BITS(ecc_ier, XP_ECC_IER, RX_DED, 0); | ||
761 | XP_SET_BITS(ecc_ier, XP_ECC_IER, DESC_DED, 0); | ||
762 | |||
763 | XP_IOWRITE(pdata, XP_ECC_IER, ecc_ier); | ||
764 | } | ||
765 | |||
766 | static void xgbe_disable_ecc_sec(struct xgbe_prv_data *pdata, | ||
767 | enum xgbe_ecc_sec sec) | ||
768 | { | ||
769 | unsigned int ecc_ier; | ||
770 | |||
771 | ecc_ier = XP_IOREAD(pdata, XP_ECC_IER); | ||
772 | |||
773 | /* Disable ECC SEC interrupt */ | ||
774 | switch (sec) { | ||
775 | case XGBE_ECC_SEC_TX: | ||
776 | XP_SET_BITS(ecc_ier, XP_ECC_IER, TX_SEC, 0); | ||
777 | break; | ||
778 | case XGBE_ECC_SEC_RX: | ||
779 | XP_SET_BITS(ecc_ier, XP_ECC_IER, RX_SEC, 0); | ||
780 | break; | ||
781 | case XGBE_ECC_SEC_DESC: | ||
782 | XP_SET_BITS(ecc_ier, XP_ECC_IER, DESC_SEC, 0); | ||
783 | break; | ||
784 | } | ||
785 | |||
786 | XP_IOWRITE(pdata, XP_ECC_IER, ecc_ier); | ||
718 | } | 787 | } |
719 | 788 | ||
720 | static int xgbe_set_speed(struct xgbe_prv_data *pdata, int speed) | 789 | static int xgbe_set_speed(struct xgbe_prv_data *pdata, int speed) |
@@ -1026,6 +1095,36 @@ static int xgbe_config_rx_mode(struct xgbe_prv_data *pdata) | |||
1026 | return 0; | 1095 | return 0; |
1027 | } | 1096 | } |
1028 | 1097 | ||
1098 | static int xgbe_clr_gpio(struct xgbe_prv_data *pdata, unsigned int gpio) | ||
1099 | { | ||
1100 | unsigned int reg; | ||
1101 | |||
1102 | if (gpio > 16) | ||
1103 | return -EINVAL; | ||
1104 | |||
1105 | reg = XGMAC_IOREAD(pdata, MAC_GPIOSR); | ||
1106 | |||
1107 | reg &= ~(1 << (gpio + 16)); | ||
1108 | XGMAC_IOWRITE(pdata, MAC_GPIOSR, reg); | ||
1109 | |||
1110 | return 0; | ||
1111 | } | ||
1112 | |||
1113 | static int xgbe_set_gpio(struct xgbe_prv_data *pdata, unsigned int gpio) | ||
1114 | { | ||
1115 | unsigned int reg; | ||
1116 | |||
1117 | if (gpio > 16) | ||
1118 | return -EINVAL; | ||
1119 | |||
1120 | reg = XGMAC_IOREAD(pdata, MAC_GPIOSR); | ||
1121 | |||
1122 | reg |= (1 << (gpio + 16)); | ||
1123 | XGMAC_IOWRITE(pdata, MAC_GPIOSR, reg); | ||
1124 | |||
1125 | return 0; | ||
1126 | } | ||
1127 | |||
1029 | static int xgbe_read_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad, | 1128 | static int xgbe_read_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad, |
1030 | int mmd_reg) | 1129 | int mmd_reg) |
1031 | { | 1130 | { |
@@ -1170,6 +1269,79 @@ static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad, | |||
1170 | } | 1269 | } |
1171 | } | 1270 | } |
1172 | 1271 | ||
1272 | static int xgbe_write_ext_mii_regs(struct xgbe_prv_data *pdata, int addr, | ||
1273 | int reg, u16 val) | ||
1274 | { | ||
1275 | unsigned int mdio_sca, mdio_sccd; | ||
1276 | |||
1277 | reinit_completion(&pdata->mdio_complete); | ||
1278 | |||
1279 | mdio_sca = 0; | ||
1280 | XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, REG, reg); | ||
1281 | XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, addr); | ||
1282 | XGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca); | ||
1283 | |||
1284 | mdio_sccd = 0; | ||
1285 | XGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, DATA, val); | ||
1286 | XGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, CMD, 1); | ||
1287 | XGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, BUSY, 1); | ||
1288 | XGMAC_IOWRITE(pdata, MAC_MDIOSCCDR, mdio_sccd); | ||
1289 | |||
1290 | if (!wait_for_completion_timeout(&pdata->mdio_complete, HZ)) { | ||
1291 | netdev_err(pdata->netdev, "mdio write operation timed out\n"); | ||
1292 | return -ETIMEDOUT; | ||
1293 | } | ||
1294 | |||
1295 | return 0; | ||
1296 | } | ||
1297 | |||
1298 | static int xgbe_read_ext_mii_regs(struct xgbe_prv_data *pdata, int addr, | ||
1299 | int reg) | ||
1300 | { | ||
1301 | unsigned int mdio_sca, mdio_sccd; | ||
1302 | |||
1303 | reinit_completion(&pdata->mdio_complete); | ||
1304 | |||
1305 | mdio_sca = 0; | ||
1306 | XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, REG, reg); | ||
1307 | XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, addr); | ||
1308 | XGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca); | ||
1309 | |||
1310 | mdio_sccd = 0; | ||
1311 | XGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, CMD, 3); | ||
1312 | XGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, BUSY, 1); | ||
1313 | XGMAC_IOWRITE(pdata, MAC_MDIOSCCDR, mdio_sccd); | ||
1314 | |||
1315 | if (!wait_for_completion_timeout(&pdata->mdio_complete, HZ)) { | ||
1316 | netdev_err(pdata->netdev, "mdio read operation timed out\n"); | ||
1317 | return -ETIMEDOUT; | ||
1318 | } | ||
1319 | |||
1320 | return XGMAC_IOREAD_BITS(pdata, MAC_MDIOSCCDR, DATA); | ||
1321 | } | ||
1322 | |||
1323 | static int xgbe_set_ext_mii_mode(struct xgbe_prv_data *pdata, unsigned int port, | ||
1324 | enum xgbe_mdio_mode mode) | ||
1325 | { | ||
1326 | unsigned int reg_val = 0; | ||
1327 | |||
1328 | switch (mode) { | ||
1329 | case XGBE_MDIO_MODE_CL22: | ||
1330 | if (port > XGMAC_MAX_C22_PORT) | ||
1331 | return -EINVAL; | ||
1332 | reg_val |= (1 << port); | ||
1333 | break; | ||
1334 | case XGBE_MDIO_MODE_CL45: | ||
1335 | break; | ||
1336 | default: | ||
1337 | return -EINVAL; | ||
1338 | } | ||
1339 | |||
1340 | XGMAC_IOWRITE(pdata, MAC_MDIOCL22R, reg_val); | ||
1341 | |||
1342 | return 0; | ||
1343 | } | ||
1344 | |||
1173 | static int xgbe_tx_complete(struct xgbe_ring_desc *rdesc) | 1345 | static int xgbe_tx_complete(struct xgbe_ring_desc *rdesc) |
1174 | { | 1346 | { |
1175 | return !XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN); | 1347 | return !XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN); |
@@ -1360,14 +1532,21 @@ static u64 xgbe_get_tstamp_time(struct xgbe_prv_data *pdata) | |||
1360 | 1532 | ||
1361 | static u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata) | 1533 | static u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata) |
1362 | { | 1534 | { |
1363 | unsigned int tx_snr; | 1535 | unsigned int tx_snr, tx_ssr; |
1364 | u64 nsec; | 1536 | u64 nsec; |
1365 | 1537 | ||
1366 | tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR); | 1538 | if (pdata->vdata->tx_tstamp_workaround) { |
1539 | tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR); | ||
1540 | tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR); | ||
1541 | } else { | ||
1542 | tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR); | ||
1543 | tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR); | ||
1544 | } | ||
1545 | |||
1367 | if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS)) | 1546 | if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS)) |
1368 | return 0; | 1547 | return 0; |
1369 | 1548 | ||
1370 | nsec = XGMAC_IOREAD(pdata, MAC_TXSSR); | 1549 | nsec = tx_ssr; |
1371 | nsec *= NSEC_PER_SEC; | 1550 | nsec *= NSEC_PER_SEC; |
1372 | nsec += tx_snr; | 1551 | nsec += tx_snr; |
1373 | 1552 | ||
@@ -1897,7 +2076,7 @@ static int xgbe_disable_int(struct xgbe_channel *channel, | |||
1897 | return 0; | 2076 | return 0; |
1898 | } | 2077 | } |
1899 | 2078 | ||
1900 | static int xgbe_exit(struct xgbe_prv_data *pdata) | 2079 | static int __xgbe_exit(struct xgbe_prv_data *pdata) |
1901 | { | 2080 | { |
1902 | unsigned int count = 2000; | 2081 | unsigned int count = 2000; |
1903 | 2082 | ||
@@ -1919,6 +2098,20 @@ static int xgbe_exit(struct xgbe_prv_data *pdata) | |||
1919 | return 0; | 2098 | return 0; |
1920 | } | 2099 | } |
1921 | 2100 | ||
2101 | static int xgbe_exit(struct xgbe_prv_data *pdata) | ||
2102 | { | ||
2103 | int ret; | ||
2104 | |||
2105 | /* To guard against possible incorrectly generated interrupts, | ||
2106 | * issue the software reset twice. | ||
2107 | */ | ||
2108 | ret = __xgbe_exit(pdata); | ||
2109 | if (ret) | ||
2110 | return ret; | ||
2111 | |||
2112 | return __xgbe_exit(pdata); | ||
2113 | } | ||
2114 | |||
1922 | static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata) | 2115 | static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata) |
1923 | { | 2116 | { |
1924 | unsigned int i, count; | 2117 | unsigned int i, count; |
@@ -3266,6 +3459,11 @@ static int xgbe_init(struct xgbe_prv_data *pdata) | |||
3266 | xgbe_config_mmc(pdata); | 3459 | xgbe_config_mmc(pdata); |
3267 | xgbe_enable_mac_interrupts(pdata); | 3460 | xgbe_enable_mac_interrupts(pdata); |
3268 | 3461 | ||
3462 | /* | ||
3463 | * Initialize ECC related features | ||
3464 | */ | ||
3465 | xgbe_enable_ecc_interrupts(pdata); | ||
3466 | |||
3269 | DBGPR("<--xgbe_init\n"); | 3467 | DBGPR("<--xgbe_init\n"); |
3270 | 3468 | ||
3271 | return 0; | 3469 | return 0; |
@@ -3294,6 +3492,13 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if) | |||
3294 | 3492 | ||
3295 | hw_if->set_speed = xgbe_set_speed; | 3493 | hw_if->set_speed = xgbe_set_speed; |
3296 | 3494 | ||
3495 | hw_if->set_ext_mii_mode = xgbe_set_ext_mii_mode; | ||
3496 | hw_if->read_ext_mii_regs = xgbe_read_ext_mii_regs; | ||
3497 | hw_if->write_ext_mii_regs = xgbe_write_ext_mii_regs; | ||
3498 | |||
3499 | hw_if->set_gpio = xgbe_set_gpio; | ||
3500 | hw_if->clr_gpio = xgbe_clr_gpio; | ||
3501 | |||
3297 | hw_if->enable_tx = xgbe_enable_tx; | 3502 | hw_if->enable_tx = xgbe_enable_tx; |
3298 | hw_if->disable_tx = xgbe_disable_tx; | 3503 | hw_if->disable_tx = xgbe_disable_tx; |
3299 | hw_if->enable_rx = xgbe_enable_rx; | 3504 | hw_if->enable_rx = xgbe_enable_rx; |
@@ -3371,5 +3576,9 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if) | |||
3371 | hw_if->set_rss_hash_key = xgbe_set_rss_hash_key; | 3576 | hw_if->set_rss_hash_key = xgbe_set_rss_hash_key; |
3372 | hw_if->set_rss_lookup_table = xgbe_set_rss_lookup_table; | 3577 | hw_if->set_rss_lookup_table = xgbe_set_rss_lookup_table; |
3373 | 3578 | ||
3579 | /* For ECC */ | ||
3580 | hw_if->disable_ecc_ded = xgbe_disable_ecc_ded; | ||
3581 | hw_if->disable_ecc_sec = xgbe_disable_ecc_sec; | ||
3582 | |||
3374 | DBGPR("<--xgbe_init_function_ptrs\n"); | 3583 | DBGPR("<--xgbe_init_function_ptrs\n"); |
3375 | } | 3584 | } |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index a43e9303be90..155190db682d 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c | |||
@@ -114,6 +114,7 @@ | |||
114 | * THE POSSIBILITY OF SUCH DAMAGE. | 114 | * THE POSSIBILITY OF SUCH DAMAGE. |
115 | */ | 115 | */ |
116 | 116 | ||
117 | #include <linux/module.h> | ||
117 | #include <linux/spinlock.h> | 118 | #include <linux/spinlock.h> |
118 | #include <linux/tcp.h> | 119 | #include <linux/tcp.h> |
119 | #include <linux/if_vlan.h> | 120 | #include <linux/if_vlan.h> |
@@ -126,8 +127,35 @@ | |||
126 | #include "xgbe.h" | 127 | #include "xgbe.h" |
127 | #include "xgbe-common.h" | 128 | #include "xgbe-common.h" |
128 | 129 | ||
130 | static unsigned int ecc_sec_info_threshold = 10; | ||
131 | static unsigned int ecc_sec_warn_threshold = 10000; | ||
132 | static unsigned int ecc_sec_period = 600; | ||
133 | static unsigned int ecc_ded_threshold = 2; | ||
134 | static unsigned int ecc_ded_period = 600; | ||
135 | |||
136 | #ifdef CONFIG_AMD_XGBE_HAVE_ECC | ||
137 | /* Only expose the ECC parameters if supported */ | ||
138 | module_param(ecc_sec_info_threshold, uint, S_IWUSR | S_IRUGO); | ||
139 | MODULE_PARM_DESC(ecc_sec_info_threshold, | ||
140 | " ECC corrected error informational threshold setting"); | ||
141 | |||
142 | module_param(ecc_sec_warn_threshold, uint, S_IWUSR | S_IRUGO); | ||
143 | MODULE_PARM_DESC(ecc_sec_warn_threshold, | ||
144 | " ECC corrected error warning threshold setting"); | ||
145 | |||
146 | module_param(ecc_sec_period, uint, S_IWUSR | S_IRUGO); | ||
147 | MODULE_PARM_DESC(ecc_sec_period, " ECC corrected error period (in seconds)"); | ||
148 | |||
149 | module_param(ecc_ded_threshold, uint, S_IWUSR | S_IRUGO); | ||
150 | MODULE_PARM_DESC(ecc_ded_threshold, " ECC detected error threshold setting"); | ||
151 | |||
152 | module_param(ecc_ded_period, uint, S_IWUSR | S_IRUGO); | ||
153 | MODULE_PARM_DESC(ecc_ded_period, " ECC detected error period (in seconds)"); | ||
154 | #endif | ||
155 | |||
129 | static int xgbe_one_poll(struct napi_struct *, int); | 156 | static int xgbe_one_poll(struct napi_struct *, int); |
130 | static int xgbe_all_poll(struct napi_struct *, int); | 157 | static int xgbe_all_poll(struct napi_struct *, int); |
158 | static void xgbe_stop(struct xgbe_prv_data *); | ||
131 | 159 | ||
132 | static int xgbe_alloc_channels(struct xgbe_prv_data *pdata) | 160 | static int xgbe_alloc_channels(struct xgbe_prv_data *pdata) |
133 | { | 161 | { |
@@ -252,48 +280,161 @@ static int xgbe_calc_rx_buf_size(struct net_device *netdev, unsigned int mtu) | |||
252 | return rx_buf_size; | 280 | return rx_buf_size; |
253 | } | 281 | } |
254 | 282 | ||
255 | static void xgbe_enable_rx_tx_ints(struct xgbe_prv_data *pdata) | 283 | static void xgbe_enable_rx_tx_int(struct xgbe_prv_data *pdata, |
284 | struct xgbe_channel *channel) | ||
256 | { | 285 | { |
257 | struct xgbe_hw_if *hw_if = &pdata->hw_if; | 286 | struct xgbe_hw_if *hw_if = &pdata->hw_if; |
258 | struct xgbe_channel *channel; | ||
259 | enum xgbe_int int_id; | 287 | enum xgbe_int int_id; |
288 | |||
289 | if (channel->tx_ring && channel->rx_ring) | ||
290 | int_id = XGMAC_INT_DMA_CH_SR_TI_RI; | ||
291 | else if (channel->tx_ring) | ||
292 | int_id = XGMAC_INT_DMA_CH_SR_TI; | ||
293 | else if (channel->rx_ring) | ||
294 | int_id = XGMAC_INT_DMA_CH_SR_RI; | ||
295 | else | ||
296 | return; | ||
297 | |||
298 | hw_if->enable_int(channel, int_id); | ||
299 | } | ||
300 | |||
301 | static void xgbe_enable_rx_tx_ints(struct xgbe_prv_data *pdata) | ||
302 | { | ||
303 | struct xgbe_channel *channel; | ||
260 | unsigned int i; | 304 | unsigned int i; |
261 | 305 | ||
262 | channel = pdata->channel; | 306 | channel = pdata->channel; |
263 | for (i = 0; i < pdata->channel_count; i++, channel++) { | 307 | for (i = 0; i < pdata->channel_count; i++, channel++) |
264 | if (channel->tx_ring && channel->rx_ring) | 308 | xgbe_enable_rx_tx_int(pdata, channel); |
265 | int_id = XGMAC_INT_DMA_CH_SR_TI_RI; | 309 | } |
266 | else if (channel->tx_ring) | ||
267 | int_id = XGMAC_INT_DMA_CH_SR_TI; | ||
268 | else if (channel->rx_ring) | ||
269 | int_id = XGMAC_INT_DMA_CH_SR_RI; | ||
270 | else | ||
271 | continue; | ||
272 | 310 | ||
273 | hw_if->enable_int(channel, int_id); | 311 | static void xgbe_disable_rx_tx_int(struct xgbe_prv_data *pdata, |
274 | } | 312 | struct xgbe_channel *channel) |
313 | { | ||
314 | struct xgbe_hw_if *hw_if = &pdata->hw_if; | ||
315 | enum xgbe_int int_id; | ||
316 | |||
317 | if (channel->tx_ring && channel->rx_ring) | ||
318 | int_id = XGMAC_INT_DMA_CH_SR_TI_RI; | ||
319 | else if (channel->tx_ring) | ||
320 | int_id = XGMAC_INT_DMA_CH_SR_TI; | ||
321 | else if (channel->rx_ring) | ||
322 | int_id = XGMAC_INT_DMA_CH_SR_RI; | ||
323 | else | ||
324 | return; | ||
325 | |||
326 | hw_if->disable_int(channel, int_id); | ||
275 | } | 327 | } |
276 | 328 | ||
277 | static void xgbe_disable_rx_tx_ints(struct xgbe_prv_data *pdata) | 329 | static void xgbe_disable_rx_tx_ints(struct xgbe_prv_data *pdata) |
278 | { | 330 | { |
279 | struct xgbe_hw_if *hw_if = &pdata->hw_if; | ||
280 | struct xgbe_channel *channel; | 331 | struct xgbe_channel *channel; |
281 | enum xgbe_int int_id; | ||
282 | unsigned int i; | 332 | unsigned int i; |
283 | 333 | ||
284 | channel = pdata->channel; | 334 | channel = pdata->channel; |
285 | for (i = 0; i < pdata->channel_count; i++, channel++) { | 335 | for (i = 0; i < pdata->channel_count; i++, channel++) |
286 | if (channel->tx_ring && channel->rx_ring) | 336 | xgbe_disable_rx_tx_int(pdata, channel); |
287 | int_id = XGMAC_INT_DMA_CH_SR_TI_RI; | 337 | } |
288 | else if (channel->tx_ring) | 338 | |
289 | int_id = XGMAC_INT_DMA_CH_SR_TI; | 339 | static bool xgbe_ecc_sec(struct xgbe_prv_data *pdata, unsigned long *period, |
290 | else if (channel->rx_ring) | 340 | unsigned int *count, const char *area) |
291 | int_id = XGMAC_INT_DMA_CH_SR_RI; | 341 | { |
292 | else | 342 | if (time_before(jiffies, *period)) { |
293 | continue; | 343 | (*count)++; |
344 | } else { | ||
345 | *period = jiffies + (ecc_sec_period * HZ); | ||
346 | *count = 1; | ||
347 | } | ||
348 | |||
349 | if (*count > ecc_sec_info_threshold) | ||
350 | dev_warn_once(pdata->dev, | ||
351 | "%s ECC corrected errors exceed informational threshold\n", | ||
352 | area); | ||
353 | |||
354 | if (*count > ecc_sec_warn_threshold) { | ||
355 | dev_warn_once(pdata->dev, | ||
356 | "%s ECC corrected errors exceed warning threshold\n", | ||
357 | area); | ||
358 | return true; | ||
359 | } | ||
360 | |||
361 | return false; | ||
362 | } | ||
363 | |||
364 | static bool xgbe_ecc_ded(struct xgbe_prv_data *pdata, unsigned long *period, | ||
365 | unsigned int *count, const char *area) | ||
366 | { | ||
367 | if (time_before(jiffies, *period)) { | ||
368 | (*count)++; | ||
369 | } else { | ||
370 | *period = jiffies + (ecc_ded_period * HZ); | ||
371 | *count = 1; | ||
372 | } | ||
373 | |||
374 | if (*count > ecc_ded_threshold) { | ||
375 | netdev_alert(pdata->netdev, | ||
376 | "%s ECC detected errors exceed threshold\n", | ||
377 | area); | ||
378 | return true; | ||
379 | } | ||
380 | |||
381 | return false; | ||
382 | } | ||
383 | |||
384 | static irqreturn_t xgbe_ecc_isr(int irq, void *data) | ||
385 | { | ||
386 | struct xgbe_prv_data *pdata = data; | ||
387 | unsigned int ecc_isr; | ||
388 | bool stop = false; | ||
389 | |||
390 | /* Mask status with only the interrupts we care about */ | ||
391 | ecc_isr = XP_IOREAD(pdata, XP_ECC_ISR); | ||
392 | ecc_isr &= XP_IOREAD(pdata, XP_ECC_IER); | ||
393 | netif_dbg(pdata, intr, pdata->netdev, "ECC_ISR=%#010x\n", ecc_isr); | ||
394 | |||
395 | if (XP_GET_BITS(ecc_isr, XP_ECC_ISR, TX_DED)) { | ||
396 | stop |= xgbe_ecc_ded(pdata, &pdata->tx_ded_period, | ||
397 | &pdata->tx_ded_count, "TX fifo"); | ||
398 | } | ||
399 | |||
400 | if (XP_GET_BITS(ecc_isr, XP_ECC_ISR, RX_DED)) { | ||
401 | stop |= xgbe_ecc_ded(pdata, &pdata->rx_ded_period, | ||
402 | &pdata->rx_ded_count, "RX fifo"); | ||
403 | } | ||
294 | 404 | ||
295 | hw_if->disable_int(channel, int_id); | 405 | if (XP_GET_BITS(ecc_isr, XP_ECC_ISR, DESC_DED)) { |
406 | stop |= xgbe_ecc_ded(pdata, &pdata->desc_ded_period, | ||
407 | &pdata->desc_ded_count, | ||
408 | "descriptor cache"); | ||
296 | } | 409 | } |
410 | |||
411 | if (stop) { | ||
412 | pdata->hw_if.disable_ecc_ded(pdata); | ||
413 | schedule_work(&pdata->stopdev_work); | ||
414 | goto out; | ||
415 | } | ||
416 | |||
417 | if (XP_GET_BITS(ecc_isr, XP_ECC_ISR, TX_SEC)) { | ||
418 | if (xgbe_ecc_sec(pdata, &pdata->tx_sec_period, | ||
419 | &pdata->tx_sec_count, "TX fifo")) | ||
420 | pdata->hw_if.disable_ecc_sec(pdata, XGBE_ECC_SEC_TX); | ||
421 | } | ||
422 | |||
423 | if (XP_GET_BITS(ecc_isr, XP_ECC_ISR, RX_SEC)) | ||
424 | if (xgbe_ecc_sec(pdata, &pdata->rx_sec_period, | ||
425 | &pdata->rx_sec_count, "RX fifo")) | ||
426 | pdata->hw_if.disable_ecc_sec(pdata, XGBE_ECC_SEC_RX); | ||
427 | |||
428 | if (XP_GET_BITS(ecc_isr, XP_ECC_ISR, DESC_SEC)) | ||
429 | if (xgbe_ecc_sec(pdata, &pdata->desc_sec_period, | ||
430 | &pdata->desc_sec_count, "descriptor cache")) | ||
431 | pdata->hw_if.disable_ecc_sec(pdata, XGBE_ECC_SEC_DESC); | ||
432 | |||
433 | out: | ||
434 | /* Clear all ECC interrupts */ | ||
435 | XP_IOWRITE(pdata, XP_ECC_ISR, ecc_isr); | ||
436 | |||
437 | return IRQ_HANDLED; | ||
297 | } | 438 | } |
298 | 439 | ||
299 | static irqreturn_t xgbe_isr(int irq, void *data) | 440 | static irqreturn_t xgbe_isr(int irq, void *data) |
@@ -302,7 +443,7 @@ static irqreturn_t xgbe_isr(int irq, void *data) | |||
302 | struct xgbe_hw_if *hw_if = &pdata->hw_if; | 443 | struct xgbe_hw_if *hw_if = &pdata->hw_if; |
303 | struct xgbe_channel *channel; | 444 | struct xgbe_channel *channel; |
304 | unsigned int dma_isr, dma_ch_isr; | 445 | unsigned int dma_isr, dma_ch_isr; |
305 | unsigned int mac_isr, mac_tssr; | 446 | unsigned int mac_isr, mac_tssr, mac_mdioisr; |
306 | unsigned int i; | 447 | unsigned int i; |
307 | 448 | ||
308 | /* The DMA interrupt status register also reports MAC and MTL | 449 | /* The DMA interrupt status register also reports MAC and MTL |
@@ -339,6 +480,13 @@ static irqreturn_t xgbe_isr(int irq, void *data) | |||
339 | /* Turn on polling */ | 480 | /* Turn on polling */ |
340 | __napi_schedule_irqoff(&pdata->napi); | 481 | __napi_schedule_irqoff(&pdata->napi); |
341 | } | 482 | } |
483 | } else { | ||
484 | /* Don't clear Rx/Tx status if doing per channel DMA | ||
485 | * interrupts, these will be cleared by the ISR for | ||
486 | * per channel DMA interrupts. | ||
487 | */ | ||
488 | XGMAC_SET_BITS(dma_ch_isr, DMA_CH_SR, TI, 0); | ||
489 | XGMAC_SET_BITS(dma_ch_isr, DMA_CH_SR, RI, 0); | ||
342 | } | 490 | } |
343 | 491 | ||
344 | if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RBU)) | 492 | if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RBU)) |
@@ -348,13 +496,16 @@ static irqreturn_t xgbe_isr(int irq, void *data) | |||
348 | if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, FBE)) | 496 | if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, FBE)) |
349 | schedule_work(&pdata->restart_work); | 497 | schedule_work(&pdata->restart_work); |
350 | 498 | ||
351 | /* Clear all interrupt signals */ | 499 | /* Clear interrupt signals */ |
352 | XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr); | 500 | XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr); |
353 | } | 501 | } |
354 | 502 | ||
355 | if (XGMAC_GET_BITS(dma_isr, DMA_ISR, MACIS)) { | 503 | if (XGMAC_GET_BITS(dma_isr, DMA_ISR, MACIS)) { |
356 | mac_isr = XGMAC_IOREAD(pdata, MAC_ISR); | 504 | mac_isr = XGMAC_IOREAD(pdata, MAC_ISR); |
357 | 505 | ||
506 | netif_dbg(pdata, intr, pdata->netdev, "MAC_ISR=%#010x\n", | ||
507 | mac_isr); | ||
508 | |||
358 | if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCTXIS)) | 509 | if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCTXIS)) |
359 | hw_if->tx_mmc_int(pdata); | 510 | hw_if->tx_mmc_int(pdata); |
360 | 511 | ||
@@ -364,6 +515,9 @@ static irqreturn_t xgbe_isr(int irq, void *data) | |||
364 | if (XGMAC_GET_BITS(mac_isr, MAC_ISR, TSIS)) { | 515 | if (XGMAC_GET_BITS(mac_isr, MAC_ISR, TSIS)) { |
365 | mac_tssr = XGMAC_IOREAD(pdata, MAC_TSSR); | 516 | mac_tssr = XGMAC_IOREAD(pdata, MAC_TSSR); |
366 | 517 | ||
518 | netif_dbg(pdata, intr, pdata->netdev, | ||
519 | "MAC_TSSR=%#010x\n", mac_tssr); | ||
520 | |||
367 | if (XGMAC_GET_BITS(mac_tssr, MAC_TSSR, TXTSC)) { | 521 | if (XGMAC_GET_BITS(mac_tssr, MAC_TSSR, TXTSC)) { |
368 | /* Read Tx Timestamp to clear interrupt */ | 522 | /* Read Tx Timestamp to clear interrupt */ |
369 | pdata->tx_tstamp = | 523 | pdata->tx_tstamp = |
@@ -372,8 +526,31 @@ static irqreturn_t xgbe_isr(int irq, void *data) | |||
372 | &pdata->tx_tstamp_work); | 526 | &pdata->tx_tstamp_work); |
373 | } | 527 | } |
374 | } | 528 | } |
529 | |||
530 | if (XGMAC_GET_BITS(mac_isr, MAC_ISR, SMI)) { | ||
531 | mac_mdioisr = XGMAC_IOREAD(pdata, MAC_MDIOISR); | ||
532 | |||
533 | netif_dbg(pdata, intr, pdata->netdev, | ||
534 | "MAC_MDIOISR=%#010x\n", mac_mdioisr); | ||
535 | |||
536 | if (XGMAC_GET_BITS(mac_mdioisr, MAC_MDIOISR, | ||
537 | SNGLCOMPINT)) | ||
538 | complete(&pdata->mdio_complete); | ||
539 | } | ||
375 | } | 540 | } |
376 | 541 | ||
542 | /* If there is not a separate AN irq, handle it here */ | ||
543 | if (pdata->dev_irq == pdata->an_irq) | ||
544 | pdata->phy_if.an_isr(irq, pdata); | ||
545 | |||
546 | /* If there is not a separate ECC irq, handle it here */ | ||
547 | if (pdata->vdata->ecc_support && (pdata->dev_irq == pdata->ecc_irq)) | ||
548 | xgbe_ecc_isr(irq, pdata); | ||
549 | |||
550 | /* If there is not a separate I2C irq, handle it here */ | ||
551 | if (pdata->vdata->i2c_support && (pdata->dev_irq == pdata->i2c_irq)) | ||
552 | pdata->i2c_if.i2c_isr(irq, pdata); | ||
553 | |||
377 | isr_done: | 554 | isr_done: |
378 | return IRQ_HANDLED; | 555 | return IRQ_HANDLED; |
379 | } | 556 | } |
@@ -381,18 +558,29 @@ isr_done: | |||
381 | static irqreturn_t xgbe_dma_isr(int irq, void *data) | 558 | static irqreturn_t xgbe_dma_isr(int irq, void *data) |
382 | { | 559 | { |
383 | struct xgbe_channel *channel = data; | 560 | struct xgbe_channel *channel = data; |
561 | struct xgbe_prv_data *pdata = channel->pdata; | ||
562 | unsigned int dma_status; | ||
384 | 563 | ||
385 | /* Per channel DMA interrupts are enabled, so we use the per | 564 | /* Per channel DMA interrupts are enabled, so we use the per |
386 | * channel napi structure and not the private data napi structure | 565 | * channel napi structure and not the private data napi structure |
387 | */ | 566 | */ |
388 | if (napi_schedule_prep(&channel->napi)) { | 567 | if (napi_schedule_prep(&channel->napi)) { |
389 | /* Disable Tx and Rx interrupts */ | 568 | /* Disable Tx and Rx interrupts */ |
390 | disable_irq_nosync(channel->dma_irq); | 569 | if (pdata->channel_irq_mode) |
570 | xgbe_disable_rx_tx_int(pdata, channel); | ||
571 | else | ||
572 | disable_irq_nosync(channel->dma_irq); | ||
391 | 573 | ||
392 | /* Turn on polling */ | 574 | /* Turn on polling */ |
393 | __napi_schedule_irqoff(&channel->napi); | 575 | __napi_schedule_irqoff(&channel->napi); |
394 | } | 576 | } |
395 | 577 | ||
578 | /* Clear Tx/Rx signals */ | ||
579 | dma_status = 0; | ||
580 | XGMAC_SET_BITS(dma_status, DMA_CH_SR, TI, 1); | ||
581 | XGMAC_SET_BITS(dma_status, DMA_CH_SR, RI, 1); | ||
582 | XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_status); | ||
583 | |||
396 | return IRQ_HANDLED; | 584 | return IRQ_HANDLED; |
397 | } | 585 | } |
398 | 586 | ||
@@ -409,7 +597,10 @@ static void xgbe_tx_timer(unsigned long data) | |||
409 | if (napi_schedule_prep(napi)) { | 597 | if (napi_schedule_prep(napi)) { |
410 | /* Disable Tx and Rx interrupts */ | 598 | /* Disable Tx and Rx interrupts */ |
411 | if (pdata->per_channel_irq) | 599 | if (pdata->per_channel_irq) |
412 | disable_irq_nosync(channel->dma_irq); | 600 | if (pdata->channel_irq_mode) |
601 | xgbe_disable_rx_tx_int(pdata, channel); | ||
602 | else | ||
603 | disable_irq_nosync(channel->dma_irq); | ||
413 | else | 604 | else |
414 | xgbe_disable_rx_tx_ints(pdata); | 605 | xgbe_disable_rx_tx_ints(pdata); |
415 | 606 | ||
@@ -642,6 +833,16 @@ static int xgbe_request_irqs(struct xgbe_prv_data *pdata) | |||
642 | return ret; | 833 | return ret; |
643 | } | 834 | } |
644 | 835 | ||
836 | if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq)) { | ||
837 | ret = devm_request_irq(pdata->dev, pdata->ecc_irq, xgbe_ecc_isr, | ||
838 | 0, pdata->ecc_name, pdata); | ||
839 | if (ret) { | ||
840 | netdev_alert(netdev, "error requesting ecc irq %d\n", | ||
841 | pdata->ecc_irq); | ||
842 | goto err_dev_irq; | ||
843 | } | ||
844 | } | ||
845 | |||
645 | if (!pdata->per_channel_irq) | 846 | if (!pdata->per_channel_irq) |
646 | return 0; | 847 | return 0; |
647 | 848 | ||
@@ -658,17 +859,21 @@ static int xgbe_request_irqs(struct xgbe_prv_data *pdata) | |||
658 | if (ret) { | 859 | if (ret) { |
659 | netdev_alert(netdev, "error requesting irq %d\n", | 860 | netdev_alert(netdev, "error requesting irq %d\n", |
660 | channel->dma_irq); | 861 | channel->dma_irq); |
661 | goto err_irq; | 862 | goto err_dma_irq; |
662 | } | 863 | } |
663 | } | 864 | } |
664 | 865 | ||
665 | return 0; | 866 | return 0; |
666 | 867 | ||
667 | err_irq: | 868 | err_dma_irq: |
668 | /* Using an unsigned int, 'i' will go to UINT_MAX and exit */ | 869 | /* Using an unsigned int, 'i' will go to UINT_MAX and exit */ |
669 | for (i--, channel--; i < pdata->channel_count; i--, channel--) | 870 | for (i--, channel--; i < pdata->channel_count; i--, channel--) |
670 | devm_free_irq(pdata->dev, channel->dma_irq, channel); | 871 | devm_free_irq(pdata->dev, channel->dma_irq, channel); |
671 | 872 | ||
873 | if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq)) | ||
874 | devm_free_irq(pdata->dev, pdata->ecc_irq, pdata); | ||
875 | |||
876 | err_dev_irq: | ||
672 | devm_free_irq(pdata->dev, pdata->dev_irq, pdata); | 877 | devm_free_irq(pdata->dev, pdata->dev_irq, pdata); |
673 | 878 | ||
674 | return ret; | 879 | return ret; |
@@ -681,6 +886,9 @@ static void xgbe_free_irqs(struct xgbe_prv_data *pdata) | |||
681 | 886 | ||
682 | devm_free_irq(pdata->dev, pdata->dev_irq, pdata); | 887 | devm_free_irq(pdata->dev, pdata->dev_irq, pdata); |
683 | 888 | ||
889 | if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq)) | ||
890 | devm_free_irq(pdata->dev, pdata->ecc_irq, pdata); | ||
891 | |||
684 | if (!pdata->per_channel_irq) | 892 | if (!pdata->per_channel_irq) |
685 | return; | 893 | return; |
686 | 894 | ||
@@ -864,16 +1072,16 @@ static int xgbe_start(struct xgbe_prv_data *pdata) | |||
864 | 1072 | ||
865 | hw_if->init(pdata); | 1073 | hw_if->init(pdata); |
866 | 1074 | ||
867 | ret = phy_if->phy_start(pdata); | ||
868 | if (ret) | ||
869 | goto err_phy; | ||
870 | |||
871 | xgbe_napi_enable(pdata, 1); | 1075 | xgbe_napi_enable(pdata, 1); |
872 | 1076 | ||
873 | ret = xgbe_request_irqs(pdata); | 1077 | ret = xgbe_request_irqs(pdata); |
874 | if (ret) | 1078 | if (ret) |
875 | goto err_napi; | 1079 | goto err_napi; |
876 | 1080 | ||
1081 | ret = phy_if->phy_start(pdata); | ||
1082 | if (ret) | ||
1083 | goto err_irqs; | ||
1084 | |||
877 | hw_if->enable_tx(pdata); | 1085 | hw_if->enable_tx(pdata); |
878 | hw_if->enable_rx(pdata); | 1086 | hw_if->enable_rx(pdata); |
879 | 1087 | ||
@@ -882,16 +1090,18 @@ static int xgbe_start(struct xgbe_prv_data *pdata) | |||
882 | xgbe_start_timers(pdata); | 1090 | xgbe_start_timers(pdata); |
883 | queue_work(pdata->dev_workqueue, &pdata->service_work); | 1091 | queue_work(pdata->dev_workqueue, &pdata->service_work); |
884 | 1092 | ||
1093 | clear_bit(XGBE_STOPPED, &pdata->dev_state); | ||
1094 | |||
885 | DBGPR("<--xgbe_start\n"); | 1095 | DBGPR("<--xgbe_start\n"); |
886 | 1096 | ||
887 | return 0; | 1097 | return 0; |
888 | 1098 | ||
1099 | err_irqs: | ||
1100 | xgbe_free_irqs(pdata); | ||
1101 | |||
889 | err_napi: | 1102 | err_napi: |
890 | xgbe_napi_disable(pdata, 1); | 1103 | xgbe_napi_disable(pdata, 1); |
891 | 1104 | ||
892 | phy_if->phy_stop(pdata); | ||
893 | |||
894 | err_phy: | ||
895 | hw_if->exit(pdata); | 1105 | hw_if->exit(pdata); |
896 | 1106 | ||
897 | return ret; | 1107 | return ret; |
@@ -908,6 +1118,9 @@ static void xgbe_stop(struct xgbe_prv_data *pdata) | |||
908 | 1118 | ||
909 | DBGPR("-->xgbe_stop\n"); | 1119 | DBGPR("-->xgbe_stop\n"); |
910 | 1120 | ||
1121 | if (test_bit(XGBE_STOPPED, &pdata->dev_state)) | ||
1122 | return; | ||
1123 | |||
911 | netif_tx_stop_all_queues(netdev); | 1124 | netif_tx_stop_all_queues(netdev); |
912 | 1125 | ||
913 | xgbe_stop_timers(pdata); | 1126 | xgbe_stop_timers(pdata); |
@@ -933,9 +1146,29 @@ static void xgbe_stop(struct xgbe_prv_data *pdata) | |||
933 | netdev_tx_reset_queue(txq); | 1146 | netdev_tx_reset_queue(txq); |
934 | } | 1147 | } |
935 | 1148 | ||
1149 | set_bit(XGBE_STOPPED, &pdata->dev_state); | ||
1150 | |||
936 | DBGPR("<--xgbe_stop\n"); | 1151 | DBGPR("<--xgbe_stop\n"); |
937 | } | 1152 | } |
938 | 1153 | ||
1154 | static void xgbe_stopdev(struct work_struct *work) | ||
1155 | { | ||
1156 | struct xgbe_prv_data *pdata = container_of(work, | ||
1157 | struct xgbe_prv_data, | ||
1158 | stopdev_work); | ||
1159 | |||
1160 | rtnl_lock(); | ||
1161 | |||
1162 | xgbe_stop(pdata); | ||
1163 | |||
1164 | xgbe_free_tx_data(pdata); | ||
1165 | xgbe_free_rx_data(pdata); | ||
1166 | |||
1167 | rtnl_unlock(); | ||
1168 | |||
1169 | netdev_alert(pdata->netdev, "device stopped\n"); | ||
1170 | } | ||
1171 | |||
939 | static void xgbe_restart_dev(struct xgbe_prv_data *pdata) | 1172 | static void xgbe_restart_dev(struct xgbe_prv_data *pdata) |
940 | { | 1173 | { |
941 | DBGPR("-->xgbe_restart_dev\n"); | 1174 | DBGPR("-->xgbe_restart_dev\n"); |
@@ -1318,6 +1551,7 @@ static int xgbe_open(struct net_device *netdev) | |||
1318 | 1551 | ||
1319 | INIT_WORK(&pdata->service_work, xgbe_service); | 1552 | INIT_WORK(&pdata->service_work, xgbe_service); |
1320 | INIT_WORK(&pdata->restart_work, xgbe_restart); | 1553 | INIT_WORK(&pdata->restart_work, xgbe_restart); |
1554 | INIT_WORK(&pdata->stopdev_work, xgbe_stopdev); | ||
1321 | INIT_WORK(&pdata->tx_tstamp_work, xgbe_tx_tstamp); | 1555 | INIT_WORK(&pdata->tx_tstamp_work, xgbe_tx_tstamp); |
1322 | xgbe_init_timers(pdata); | 1556 | xgbe_init_timers(pdata); |
1323 | 1557 | ||
@@ -2026,6 +2260,7 @@ static int xgbe_one_poll(struct napi_struct *napi, int budget) | |||
2026 | { | 2260 | { |
2027 | struct xgbe_channel *channel = container_of(napi, struct xgbe_channel, | 2261 | struct xgbe_channel *channel = container_of(napi, struct xgbe_channel, |
2028 | napi); | 2262 | napi); |
2263 | struct xgbe_prv_data *pdata = channel->pdata; | ||
2029 | int processed = 0; | 2264 | int processed = 0; |
2030 | 2265 | ||
2031 | DBGPR("-->xgbe_one_poll: budget=%d\n", budget); | 2266 | DBGPR("-->xgbe_one_poll: budget=%d\n", budget); |
@@ -2042,7 +2277,10 @@ static int xgbe_one_poll(struct napi_struct *napi, int budget) | |||
2042 | napi_complete_done(napi, processed); | 2277 | napi_complete_done(napi, processed); |
2043 | 2278 | ||
2044 | /* Enable Tx and Rx interrupts */ | 2279 | /* Enable Tx and Rx interrupts */ |
2045 | enable_irq(channel->dma_irq); | 2280 | if (pdata->channel_irq_mode) |
2281 | xgbe_enable_rx_tx_int(pdata, channel); | ||
2282 | else | ||
2283 | enable_irq(channel->dma_irq); | ||
2046 | } | 2284 | } |
2047 | 2285 | ||
2048 | DBGPR("<--xgbe_one_poll: received = %d\n", processed); | 2286 | DBGPR("<--xgbe_one_poll: received = %d\n", processed); |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c b/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c new file mode 100644 index 000000000000..0c7088a426e9 --- /dev/null +++ b/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c | |||
@@ -0,0 +1,492 @@ | |||
1 | /* | ||
2 | * AMD 10Gb Ethernet driver | ||
3 | * | ||
4 | * This file is available to you under your choice of the following two | ||
5 | * licenses: | ||
6 | * | ||
7 | * License 1: GPLv2 | ||
8 | * | ||
9 | * Copyright (c) 2016 Advanced Micro Devices, Inc. | ||
10 | * | ||
11 | * This file is free software; you may copy, redistribute and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 2 of the License, or (at | ||
14 | * your option) any later version. | ||
15 | * | ||
16 | * This file is distributed in the hope that it will be useful, but | ||
17 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | * General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
23 | * | ||
24 | * This file incorporates work covered by the following copyright and | ||
25 | * permission notice: | ||
26 | * The Synopsys DWC ETHER XGMAC Software Driver and documentation | ||
27 | * (hereinafter "Software") is an unsupported proprietary work of Synopsys, | ||
28 | * Inc. unless otherwise expressly agreed to in writing between Synopsys | ||
29 | * and you. | ||
30 | * | ||
31 | * The Software IS NOT an item of Licensed Software or Licensed Product | ||
32 | * under any End User Software License Agreement or Agreement for Licensed | ||
33 | * Product with Synopsys or any supplement thereto. Permission is hereby | ||
34 | * granted, free of charge, to any person obtaining a copy of this software | ||
35 | * annotated with this license and the Software, to deal in the Software | ||
36 | * without restriction, including without limitation the rights to use, | ||
37 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
38 | * of the Software, and to permit persons to whom the Software is furnished | ||
39 | * to do so, subject to the following conditions: | ||
40 | * | ||
41 | * The above copyright notice and this permission notice shall be included | ||
42 | * in all copies or substantial portions of the Software. | ||
43 | * | ||
44 | * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
45 | * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
46 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
47 | * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS | ||
48 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
49 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
50 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
51 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
52 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
53 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
54 | * THE POSSIBILITY OF SUCH DAMAGE. | ||
55 | * | ||
56 | * | ||
57 | * License 2: Modified BSD | ||
58 | * | ||
59 | * Copyright (c) 2016 Advanced Micro Devices, Inc. | ||
60 | * All rights reserved. | ||
61 | * | ||
62 | * Redistribution and use in source and binary forms, with or without | ||
63 | * modification, are permitted provided that the following conditions are met: | ||
64 | * * Redistributions of source code must retain the above copyright | ||
65 | * notice, this list of conditions and the following disclaimer. | ||
66 | * * Redistributions in binary form must reproduce the above copyright | ||
67 | * notice, this list of conditions and the following disclaimer in the | ||
68 | * documentation and/or other materials provided with the distribution. | ||
69 | * * Neither the name of Advanced Micro Devices, Inc. nor the | ||
70 | * names of its contributors may be used to endorse or promote products | ||
71 | * derived from this software without specific prior written permission. | ||
72 | * | ||
73 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
74 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
75 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
76 | * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | ||
77 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
78 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
79 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
80 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
81 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
82 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
83 | * | ||
84 | * This file incorporates work covered by the following copyright and | ||
85 | * permission notice: | ||
86 | * The Synopsys DWC ETHER XGMAC Software Driver and documentation | ||
87 | * (hereinafter "Software") is an unsupported proprietary work of Synopsys, | ||
88 | * Inc. unless otherwise expressly agreed to in writing between Synopsys | ||
89 | * and you. | ||
90 | * | ||
91 | * The Software IS NOT an item of Licensed Software or Licensed Product | ||
92 | * under any End User Software License Agreement or Agreement for Licensed | ||
93 | * Product with Synopsys or any supplement thereto. Permission is hereby | ||
94 | * granted, free of charge, to any person obtaining a copy of this software | ||
95 | * annotated with this license and the Software, to deal in the Software | ||
96 | * without restriction, including without limitation the rights to use, | ||
97 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
98 | * of the Software, and to permit persons to whom the Software is furnished | ||
99 | * to do so, subject to the following conditions: | ||
100 | * | ||
101 | * The above copyright notice and this permission notice shall be included | ||
102 | * in all copies or substantial portions of the Software. | ||
103 | * | ||
104 | * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
105 | * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
106 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
107 | * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS | ||
108 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
109 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
110 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
111 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
112 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
113 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
114 | * THE POSSIBILITY OF SUCH DAMAGE. | ||
115 | */ | ||
116 | |||
117 | #include <linux/module.h> | ||
118 | #include <linux/kmod.h> | ||
119 | #include <linux/delay.h> | ||
120 | #include <linux/completion.h> | ||
121 | #include <linux/mutex.h> | ||
122 | |||
123 | #include "xgbe.h" | ||
124 | #include "xgbe-common.h" | ||
125 | |||
126 | #define XGBE_ABORT_COUNT 500 | ||
127 | #define XGBE_DISABLE_COUNT 1000 | ||
128 | |||
129 | #define XGBE_STD_SPEED 1 | ||
130 | |||
131 | #define XGBE_INTR_RX_FULL BIT(IC_RAW_INTR_STAT_RX_FULL_INDEX) | ||
132 | #define XGBE_INTR_TX_EMPTY BIT(IC_RAW_INTR_STAT_TX_EMPTY_INDEX) | ||
133 | #define XGBE_INTR_TX_ABRT BIT(IC_RAW_INTR_STAT_TX_ABRT_INDEX) | ||
134 | #define XGBE_INTR_STOP_DET BIT(IC_RAW_INTR_STAT_STOP_DET_INDEX) | ||
135 | #define XGBE_DEFAULT_INT_MASK (XGBE_INTR_RX_FULL | \ | ||
136 | XGBE_INTR_TX_EMPTY | \ | ||
137 | XGBE_INTR_TX_ABRT | \ | ||
138 | XGBE_INTR_STOP_DET) | ||
139 | |||
140 | #define XGBE_I2C_READ BIT(8) | ||
141 | #define XGBE_I2C_STOP BIT(9) | ||
142 | |||
143 | static int xgbe_i2c_abort(struct xgbe_prv_data *pdata) | ||
144 | { | ||
145 | unsigned int wait = XGBE_ABORT_COUNT; | ||
146 | |||
147 | /* Must be enabled to recognize the abort request */ | ||
148 | XI2C_IOWRITE_BITS(pdata, IC_ENABLE, EN, 1); | ||
149 | |||
150 | /* Issue the abort */ | ||
151 | XI2C_IOWRITE_BITS(pdata, IC_ENABLE, ABORT, 1); | ||
152 | |||
153 | while (wait--) { | ||
154 | if (!XI2C_IOREAD_BITS(pdata, IC_ENABLE, ABORT)) | ||
155 | return 0; | ||
156 | |||
157 | usleep_range(500, 600); | ||
158 | } | ||
159 | |||
160 | return -EBUSY; | ||
161 | } | ||
162 | |||
163 | static int xgbe_i2c_set_enable(struct xgbe_prv_data *pdata, bool enable) | ||
164 | { | ||
165 | unsigned int wait = XGBE_DISABLE_COUNT; | ||
166 | unsigned int mode = enable ? 1 : 0; | ||
167 | |||
168 | while (wait--) { | ||
169 | XI2C_IOWRITE_BITS(pdata, IC_ENABLE, EN, mode); | ||
170 | if (XI2C_IOREAD_BITS(pdata, IC_ENABLE_STATUS, EN) == mode) | ||
171 | return 0; | ||
172 | |||
173 | usleep_range(100, 110); | ||
174 | } | ||
175 | |||
176 | return -EBUSY; | ||
177 | } | ||
178 | |||
179 | static int xgbe_i2c_disable(struct xgbe_prv_data *pdata) | ||
180 | { | ||
181 | unsigned int ret; | ||
182 | |||
183 | ret = xgbe_i2c_set_enable(pdata, false); | ||
184 | if (ret) { | ||
185 | /* Disable failed, try an abort */ | ||
186 | ret = xgbe_i2c_abort(pdata); | ||
187 | if (ret) | ||
188 | return ret; | ||
189 | |||
190 | /* Abort succeeded, try to disable again */ | ||
191 | ret = xgbe_i2c_set_enable(pdata, false); | ||
192 | } | ||
193 | |||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static int xgbe_i2c_enable(struct xgbe_prv_data *pdata) | ||
198 | { | ||
199 | return xgbe_i2c_set_enable(pdata, true); | ||
200 | } | ||
201 | |||
202 | static void xgbe_i2c_clear_all_interrupts(struct xgbe_prv_data *pdata) | ||
203 | { | ||
204 | XI2C_IOREAD(pdata, IC_CLR_INTR); | ||
205 | } | ||
206 | |||
207 | static void xgbe_i2c_disable_interrupts(struct xgbe_prv_data *pdata) | ||
208 | { | ||
209 | XI2C_IOWRITE(pdata, IC_INTR_MASK, 0); | ||
210 | } | ||
211 | |||
212 | static void xgbe_i2c_enable_interrupts(struct xgbe_prv_data *pdata) | ||
213 | { | ||
214 | XI2C_IOWRITE(pdata, IC_INTR_MASK, XGBE_DEFAULT_INT_MASK); | ||
215 | } | ||
216 | |||
217 | static void xgbe_i2c_write(struct xgbe_prv_data *pdata) | ||
218 | { | ||
219 | struct xgbe_i2c_op_state *state = &pdata->i2c.op_state; | ||
220 | unsigned int tx_slots; | ||
221 | unsigned int cmd; | ||
222 | |||
223 | /* Configured to never receive Rx overflows, so fill up Tx fifo */ | ||
224 | tx_slots = pdata->i2c.tx_fifo_size - XI2C_IOREAD(pdata, IC_TXFLR); | ||
225 | while (tx_slots && state->tx_len) { | ||
226 | if (state->op->cmd == XGBE_I2C_CMD_READ) | ||
227 | cmd = XGBE_I2C_READ; | ||
228 | else | ||
229 | cmd = *state->tx_buf++; | ||
230 | |||
231 | if (state->tx_len == 1) | ||
232 | XI2C_SET_BITS(cmd, IC_DATA_CMD, STOP, 1); | ||
233 | |||
234 | XI2C_IOWRITE(pdata, IC_DATA_CMD, cmd); | ||
235 | |||
236 | tx_slots--; | ||
237 | state->tx_len--; | ||
238 | } | ||
239 | |||
240 | /* No more Tx operations, so ignore TX_EMPTY and return */ | ||
241 | if (!state->tx_len) | ||
242 | XI2C_IOWRITE_BITS(pdata, IC_INTR_MASK, TX_EMPTY, 0); | ||
243 | } | ||
244 | |||
245 | static void xgbe_i2c_read(struct xgbe_prv_data *pdata) | ||
246 | { | ||
247 | struct xgbe_i2c_op_state *state = &pdata->i2c.op_state; | ||
248 | unsigned int rx_slots; | ||
249 | |||
250 | /* Anything to be read? */ | ||
251 | if (state->op->cmd != XGBE_I2C_CMD_READ) | ||
252 | return; | ||
253 | |||
254 | rx_slots = XI2C_IOREAD(pdata, IC_RXFLR); | ||
255 | while (rx_slots && state->rx_len) { | ||
256 | *state->rx_buf++ = XI2C_IOREAD(pdata, IC_DATA_CMD); | ||
257 | state->rx_len--; | ||
258 | rx_slots--; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static void xgbe_i2c_clear_isr_interrupts(struct xgbe_prv_data *pdata, | ||
263 | unsigned int isr) | ||
264 | { | ||
265 | struct xgbe_i2c_op_state *state = &pdata->i2c.op_state; | ||
266 | |||
267 | if (isr & XGBE_INTR_TX_ABRT) { | ||
268 | state->tx_abort_source = XI2C_IOREAD(pdata, IC_TX_ABRT_SOURCE); | ||
269 | XI2C_IOREAD(pdata, IC_CLR_TX_ABRT); | ||
270 | } | ||
271 | |||
272 | if (isr & XGBE_INTR_STOP_DET) | ||
273 | XI2C_IOREAD(pdata, IC_CLR_STOP_DET); | ||
274 | } | ||
275 | |||
276 | static irqreturn_t xgbe_i2c_isr(int irq, void *data) | ||
277 | { | ||
278 | struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data; | ||
279 | struct xgbe_i2c_op_state *state = &pdata->i2c.op_state; | ||
280 | unsigned int isr; | ||
281 | |||
282 | isr = XI2C_IOREAD(pdata, IC_RAW_INTR_STAT); | ||
283 | netif_dbg(pdata, intr, pdata->netdev, | ||
284 | "I2C interrupt received: status=%#010x\n", isr); | ||
285 | |||
286 | xgbe_i2c_clear_isr_interrupts(pdata, isr); | ||
287 | |||
288 | if (isr & XGBE_INTR_TX_ABRT) { | ||
289 | netif_dbg(pdata, link, pdata->netdev, | ||
290 | "I2C TX_ABRT received (%#010x) for target %#04x\n", | ||
291 | state->tx_abort_source, state->op->target); | ||
292 | |||
293 | xgbe_i2c_disable_interrupts(pdata); | ||
294 | |||
295 | state->ret = -EIO; | ||
296 | goto out; | ||
297 | } | ||
298 | |||
299 | /* Check for data in the Rx fifo */ | ||
300 | xgbe_i2c_read(pdata); | ||
301 | |||
302 | /* Fill up the Tx fifo next */ | ||
303 | xgbe_i2c_write(pdata); | ||
304 | |||
305 | out: | ||
306 | /* Complete on an error or STOP condition */ | ||
307 | if (state->ret || XI2C_GET_BITS(isr, IC_RAW_INTR_STAT, STOP_DET)) | ||
308 | complete(&pdata->i2c_complete); | ||
309 | |||
310 | return IRQ_HANDLED; | ||
311 | } | ||
312 | |||
313 | static void xgbe_i2c_set_mode(struct xgbe_prv_data *pdata) | ||
314 | { | ||
315 | unsigned int reg; | ||
316 | |||
317 | reg = XI2C_IOREAD(pdata, IC_CON); | ||
318 | XI2C_SET_BITS(reg, IC_CON, MASTER_MODE, 1); | ||
319 | XI2C_SET_BITS(reg, IC_CON, SLAVE_DISABLE, 1); | ||
320 | XI2C_SET_BITS(reg, IC_CON, RESTART_EN, 1); | ||
321 | XI2C_SET_BITS(reg, IC_CON, SPEED, XGBE_STD_SPEED); | ||
322 | XI2C_SET_BITS(reg, IC_CON, RX_FIFO_FULL_HOLD, 1); | ||
323 | XI2C_IOWRITE(pdata, IC_CON, reg); | ||
324 | } | ||
325 | |||
326 | static void xgbe_i2c_get_features(struct xgbe_prv_data *pdata) | ||
327 | { | ||
328 | struct xgbe_i2c *i2c = &pdata->i2c; | ||
329 | unsigned int reg; | ||
330 | |||
331 | reg = XI2C_IOREAD(pdata, IC_COMP_PARAM_1); | ||
332 | i2c->max_speed_mode = XI2C_GET_BITS(reg, IC_COMP_PARAM_1, | ||
333 | MAX_SPEED_MODE); | ||
334 | i2c->rx_fifo_size = XI2C_GET_BITS(reg, IC_COMP_PARAM_1, | ||
335 | RX_BUFFER_DEPTH); | ||
336 | i2c->tx_fifo_size = XI2C_GET_BITS(reg, IC_COMP_PARAM_1, | ||
337 | TX_BUFFER_DEPTH); | ||
338 | |||
339 | if (netif_msg_probe(pdata)) | ||
340 | dev_dbg(pdata->dev, "I2C features: %s=%u, %s=%u, %s=%u\n", | ||
341 | "MAX_SPEED_MODE", i2c->max_speed_mode, | ||
342 | "RX_BUFFER_DEPTH", i2c->rx_fifo_size, | ||
343 | "TX_BUFFER_DEPTH", i2c->tx_fifo_size); | ||
344 | } | ||
345 | |||
346 | static void xgbe_i2c_set_target(struct xgbe_prv_data *pdata, unsigned int addr) | ||
347 | { | ||
348 | XI2C_IOWRITE(pdata, IC_TAR, addr); | ||
349 | } | ||
350 | |||
351 | static irqreturn_t xgbe_i2c_combined_isr(int irq, struct xgbe_prv_data *pdata) | ||
352 | { | ||
353 | if (!XI2C_IOREAD(pdata, IC_RAW_INTR_STAT)) | ||
354 | return IRQ_HANDLED; | ||
355 | |||
356 | return xgbe_i2c_isr(irq, pdata); | ||
357 | } | ||
358 | |||
359 | static int xgbe_i2c_xfer(struct xgbe_prv_data *pdata, struct xgbe_i2c_op *op) | ||
360 | { | ||
361 | struct xgbe_i2c_op_state *state = &pdata->i2c.op_state; | ||
362 | int ret; | ||
363 | |||
364 | mutex_lock(&pdata->i2c_mutex); | ||
365 | |||
366 | reinit_completion(&pdata->i2c_complete); | ||
367 | |||
368 | ret = xgbe_i2c_disable(pdata); | ||
369 | if (ret) { | ||
370 | netdev_err(pdata->netdev, "failed to disable i2c master\n"); | ||
371 | goto unlock; | ||
372 | } | ||
373 | |||
374 | xgbe_i2c_set_target(pdata, op->target); | ||
375 | |||
376 | memset(state, 0, sizeof(*state)); | ||
377 | state->op = op; | ||
378 | state->tx_len = op->len; | ||
379 | state->tx_buf = op->buf; | ||
380 | state->rx_len = op->len; | ||
381 | state->rx_buf = op->buf; | ||
382 | |||
383 | xgbe_i2c_clear_all_interrupts(pdata); | ||
384 | ret = xgbe_i2c_enable(pdata); | ||
385 | if (ret) { | ||
386 | netdev_err(pdata->netdev, "failed to enable i2c master\n"); | ||
387 | goto unlock; | ||
388 | } | ||
389 | |||
390 | /* Enabling the interrupts will cause the TX FIFO empty interrupt to | ||
391 | * fire and begin to process the command via the ISR. | ||
392 | */ | ||
393 | xgbe_i2c_enable_interrupts(pdata); | ||
394 | |||
395 | if (!wait_for_completion_timeout(&pdata->i2c_complete, HZ)) { | ||
396 | netdev_err(pdata->netdev, "i2c operation timed out\n"); | ||
397 | ret = -ETIMEDOUT; | ||
398 | goto disable; | ||
399 | } | ||
400 | |||
401 | ret = state->ret; | ||
402 | if (ret) { | ||
403 | if (state->tx_abort_source & IC_TX_ABRT_7B_ADDR_NOACK) | ||
404 | ret = -ENOTCONN; | ||
405 | else if (state->tx_abort_source & IC_TX_ABRT_ARB_LOST) | ||
406 | ret = -EAGAIN; | ||
407 | } | ||
408 | |||
409 | disable: | ||
410 | xgbe_i2c_disable_interrupts(pdata); | ||
411 | xgbe_i2c_disable(pdata); | ||
412 | |||
413 | unlock: | ||
414 | mutex_unlock(&pdata->i2c_mutex); | ||
415 | |||
416 | return ret; | ||
417 | } | ||
418 | |||
419 | static void xgbe_i2c_stop(struct xgbe_prv_data *pdata) | ||
420 | { | ||
421 | if (!pdata->i2c.started) | ||
422 | return; | ||
423 | |||
424 | netif_dbg(pdata, link, pdata->netdev, "stopping I2C\n"); | ||
425 | |||
426 | pdata->i2c.started = 0; | ||
427 | |||
428 | xgbe_i2c_disable_interrupts(pdata); | ||
429 | xgbe_i2c_disable(pdata); | ||
430 | xgbe_i2c_clear_all_interrupts(pdata); | ||
431 | |||
432 | if (pdata->dev_irq != pdata->i2c_irq) | ||
433 | devm_free_irq(pdata->dev, pdata->i2c_irq, pdata); | ||
434 | } | ||
435 | |||
436 | static int xgbe_i2c_start(struct xgbe_prv_data *pdata) | ||
437 | { | ||
438 | int ret; | ||
439 | |||
440 | if (pdata->i2c.started) | ||
441 | return 0; | ||
442 | |||
443 | netif_dbg(pdata, link, pdata->netdev, "starting I2C\n"); | ||
444 | |||
445 | /* If we have a separate I2C irq, enable it */ | ||
446 | if (pdata->dev_irq != pdata->i2c_irq) { | ||
447 | ret = devm_request_irq(pdata->dev, pdata->i2c_irq, | ||
448 | xgbe_i2c_isr, 0, pdata->i2c_name, | ||
449 | pdata); | ||
450 | if (ret) { | ||
451 | netdev_err(pdata->netdev, "i2c irq request failed\n"); | ||
452 | return ret; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | pdata->i2c.started = 1; | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | static int xgbe_i2c_init(struct xgbe_prv_data *pdata) | ||
462 | { | ||
463 | int ret; | ||
464 | |||
465 | xgbe_i2c_disable_interrupts(pdata); | ||
466 | |||
467 | ret = xgbe_i2c_disable(pdata); | ||
468 | if (ret) { | ||
469 | dev_err(pdata->dev, "failed to disable i2c master\n"); | ||
470 | return ret; | ||
471 | } | ||
472 | |||
473 | xgbe_i2c_get_features(pdata); | ||
474 | |||
475 | xgbe_i2c_set_mode(pdata); | ||
476 | |||
477 | xgbe_i2c_clear_all_interrupts(pdata); | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | void xgbe_init_function_ptrs_i2c(struct xgbe_i2c_if *i2c_if) | ||
483 | { | ||
484 | i2c_if->i2c_init = xgbe_i2c_init; | ||
485 | |||
486 | i2c_if->i2c_start = xgbe_i2c_start; | ||
487 | i2c_if->i2c_stop = xgbe_i2c_stop; | ||
488 | |||
489 | i2c_if->i2c_xfer = xgbe_i2c_xfer; | ||
490 | |||
491 | i2c_if->i2c_isr = xgbe_i2c_combined_isr; | ||
492 | } | ||
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index c7187fca5fb7..b87a89988ffd 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c | |||
@@ -161,6 +161,7 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata) | |||
161 | { | 161 | { |
162 | xgbe_init_function_ptrs_dev(&pdata->hw_if); | 162 | xgbe_init_function_ptrs_dev(&pdata->hw_if); |
163 | xgbe_init_function_ptrs_phy(&pdata->phy_if); | 163 | xgbe_init_function_ptrs_phy(&pdata->phy_if); |
164 | xgbe_init_function_ptrs_i2c(&pdata->i2c_if); | ||
164 | xgbe_init_function_ptrs_desc(&pdata->desc_if); | 165 | xgbe_init_function_ptrs_desc(&pdata->desc_if); |
165 | 166 | ||
166 | pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if); | 167 | pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if); |
@@ -186,10 +187,14 @@ struct xgbe_prv_data *xgbe_alloc_pdata(struct device *dev) | |||
186 | spin_lock_init(&pdata->xpcs_lock); | 187 | spin_lock_init(&pdata->xpcs_lock); |
187 | mutex_init(&pdata->rss_mutex); | 188 | mutex_init(&pdata->rss_mutex); |
188 | spin_lock_init(&pdata->tstamp_lock); | 189 | spin_lock_init(&pdata->tstamp_lock); |
190 | mutex_init(&pdata->i2c_mutex); | ||
191 | init_completion(&pdata->i2c_complete); | ||
192 | init_completion(&pdata->mdio_complete); | ||
189 | 193 | ||
190 | pdata->msg_enable = netif_msg_init(debug, default_msg_level); | 194 | pdata->msg_enable = netif_msg_init(debug, default_msg_level); |
191 | 195 | ||
192 | set_bit(XGBE_DOWN, &pdata->dev_state); | 196 | set_bit(XGBE_DOWN, &pdata->dev_state); |
197 | set_bit(XGBE_STOPPED, &pdata->dev_state); | ||
193 | 198 | ||
194 | return pdata; | 199 | return pdata; |
195 | } | 200 | } |
@@ -236,8 +241,7 @@ void xgbe_set_counts(struct xgbe_prv_data *pdata) | |||
236 | 241 | ||
237 | pdata->tx_q_count = pdata->tx_ring_count; | 242 | pdata->tx_q_count = pdata->tx_ring_count; |
238 | 243 | ||
239 | pdata->rx_ring_count = min_t(unsigned int, | 244 | pdata->rx_ring_count = min_t(unsigned int, num_online_cpus(), |
240 | netif_get_num_default_rss_queues(), | ||
241 | pdata->hw_feat.rx_ch_cnt); | 245 | pdata->hw_feat.rx_ch_cnt); |
242 | pdata->rx_ring_count = min_t(unsigned int, pdata->rx_ring_count, | 246 | pdata->rx_ring_count = min_t(unsigned int, pdata->rx_ring_count, |
243 | pdata->rx_max_channel_count); | 247 | pdata->rx_max_channel_count); |
@@ -264,6 +268,14 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) | |||
264 | netdev->base_addr = (unsigned long)pdata->xgmac_regs; | 268 | netdev->base_addr = (unsigned long)pdata->xgmac_regs; |
265 | memcpy(netdev->dev_addr, pdata->mac_addr, netdev->addr_len); | 269 | memcpy(netdev->dev_addr, pdata->mac_addr, netdev->addr_len); |
266 | 270 | ||
271 | /* Initialize ECC timestamps */ | ||
272 | pdata->tx_sec_period = jiffies; | ||
273 | pdata->tx_ded_period = jiffies; | ||
274 | pdata->rx_sec_period = jiffies; | ||
275 | pdata->rx_ded_period = jiffies; | ||
276 | pdata->desc_sec_period = jiffies; | ||
277 | pdata->desc_ded_period = jiffies; | ||
278 | |||
267 | /* Issue software reset to device */ | 279 | /* Issue software reset to device */ |
268 | pdata->hw_if.exit(pdata); | 280 | pdata->hw_if.exit(pdata); |
269 | 281 | ||
@@ -291,6 +303,19 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) | |||
291 | BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_RX_DESC_CNT); | 303 | BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_RX_DESC_CNT); |
292 | pdata->rx_desc_count = XGBE_RX_DESC_CNT; | 304 | pdata->rx_desc_count = XGBE_RX_DESC_CNT; |
293 | 305 | ||
306 | /* Adjust the number of queues based on interrupts assigned */ | ||
307 | if (pdata->channel_irq_count) { | ||
308 | pdata->tx_ring_count = min_t(unsigned int, pdata->tx_ring_count, | ||
309 | pdata->channel_irq_count); | ||
310 | pdata->rx_ring_count = min_t(unsigned int, pdata->rx_ring_count, | ||
311 | pdata->channel_irq_count); | ||
312 | |||
313 | if (netif_msg_probe(pdata)) | ||
314 | dev_dbg(pdata->dev, | ||
315 | "adjusted TX/RX DMA channel count = %u/%u\n", | ||
316 | pdata->tx_ring_count, pdata->rx_ring_count); | ||
317 | } | ||
318 | |||
294 | /* Set the number of queues */ | 319 | /* Set the number of queues */ |
295 | ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count); | 320 | ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count); |
296 | if (ret) { | 321 | if (ret) { |
@@ -372,6 +397,14 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) | |||
372 | snprintf(pdata->an_name, sizeof(pdata->an_name) - 1, "%s-pcs", | 397 | snprintf(pdata->an_name, sizeof(pdata->an_name) - 1, "%s-pcs", |
373 | netdev_name(netdev)); | 398 | netdev_name(netdev)); |
374 | 399 | ||
400 | /* Create the ECC name based on netdev name */ | ||
401 | snprintf(pdata->ecc_name, sizeof(pdata->ecc_name) - 1, "%s-ecc", | ||
402 | netdev_name(netdev)); | ||
403 | |||
404 | /* Create the I2C name based on netdev name */ | ||
405 | snprintf(pdata->i2c_name, sizeof(pdata->i2c_name) - 1, "%s-i2c", | ||
406 | netdev_name(netdev)); | ||
407 | |||
375 | /* Create workqueues */ | 408 | /* Create workqueues */ |
376 | pdata->dev_workqueue = | 409 | pdata->dev_workqueue = |
377 | create_singlethread_workqueue(netdev_name(netdev)); | 410 | create_singlethread_workqueue(netdev_name(netdev)); |
@@ -393,6 +426,11 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) | |||
393 | 426 | ||
394 | xgbe_debugfs_init(pdata); | 427 | xgbe_debugfs_init(pdata); |
395 | 428 | ||
429 | netif_dbg(pdata, drv, pdata->netdev, "%u Tx software queues\n", | ||
430 | pdata->tx_ring_count); | ||
431 | netif_dbg(pdata, drv, pdata->netdev, "%u Rx software queues\n", | ||
432 | pdata->rx_ring_count); | ||
433 | |||
396 | return 0; | 434 | return 0; |
397 | 435 | ||
398 | err_wq: | 436 | err_wq: |
@@ -431,11 +469,17 @@ static int __init xgbe_mod_init(void) | |||
431 | if (ret) | 469 | if (ret) |
432 | return ret; | 470 | return ret; |
433 | 471 | ||
472 | ret = xgbe_pci_init(); | ||
473 | if (ret) | ||
474 | return ret; | ||
475 | |||
434 | return 0; | 476 | return 0; |
435 | } | 477 | } |
436 | 478 | ||
437 | static void __exit xgbe_mod_exit(void) | 479 | static void __exit xgbe_mod_exit(void) |
438 | { | 480 | { |
481 | xgbe_pci_exit(); | ||
482 | |||
439 | xgbe_platform_exit(); | 483 | xgbe_platform_exit(); |
440 | } | 484 | } |
441 | 485 | ||
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c index 723eb908b262..0ecae7045044 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | |||
@@ -179,6 +179,7 @@ static void xgbe_an_enable_interrupts(struct xgbe_prv_data *pdata) | |||
179 | { | 179 | { |
180 | switch (pdata->an_mode) { | 180 | switch (pdata->an_mode) { |
181 | case XGBE_AN_MODE_CL73: | 181 | case XGBE_AN_MODE_CL73: |
182 | case XGBE_AN_MODE_CL73_REDRV: | ||
182 | xgbe_an73_enable_interrupts(pdata); | 183 | xgbe_an73_enable_interrupts(pdata); |
183 | break; | 184 | break; |
184 | case XGBE_AN_MODE_CL37: | 185 | case XGBE_AN_MODE_CL37: |
@@ -252,6 +253,58 @@ static void xgbe_kx_1000_mode(struct xgbe_prv_data *pdata) | |||
252 | pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_1000); | 253 | pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_1000); |
253 | } | 254 | } |
254 | 255 | ||
256 | static void xgbe_sfi_mode(struct xgbe_prv_data *pdata) | ||
257 | { | ||
258 | /* If a KR re-driver is present, change to KR mode instead */ | ||
259 | if (pdata->kr_redrv) | ||
260 | return xgbe_kr_mode(pdata); | ||
261 | |||
262 | /* Disable KR training */ | ||
263 | xgbe_an73_disable_kr_training(pdata); | ||
264 | |||
265 | /* Set MAC to 10G speed */ | ||
266 | pdata->hw_if.set_speed(pdata, SPEED_10000); | ||
267 | |||
268 | /* Call PHY implementation support to complete rate change */ | ||
269 | pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SFI); | ||
270 | } | ||
271 | |||
272 | static void xgbe_x_mode(struct xgbe_prv_data *pdata) | ||
273 | { | ||
274 | /* Disable KR training */ | ||
275 | xgbe_an73_disable_kr_training(pdata); | ||
276 | |||
277 | /* Set MAC to 1G speed */ | ||
278 | pdata->hw_if.set_speed(pdata, SPEED_1000); | ||
279 | |||
280 | /* Call PHY implementation support to complete rate change */ | ||
281 | pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_X); | ||
282 | } | ||
283 | |||
284 | static void xgbe_sgmii_1000_mode(struct xgbe_prv_data *pdata) | ||
285 | { | ||
286 | /* Disable KR training */ | ||
287 | xgbe_an73_disable_kr_training(pdata); | ||
288 | |||
289 | /* Set MAC to 1G speed */ | ||
290 | pdata->hw_if.set_speed(pdata, SPEED_1000); | ||
291 | |||
292 | /* Call PHY implementation support to complete rate change */ | ||
293 | pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_1000); | ||
294 | } | ||
295 | |||
296 | static void xgbe_sgmii_100_mode(struct xgbe_prv_data *pdata) | ||
297 | { | ||
298 | /* Disable KR training */ | ||
299 | xgbe_an73_disable_kr_training(pdata); | ||
300 | |||
301 | /* Set MAC to 1G speed */ | ||
302 | pdata->hw_if.set_speed(pdata, SPEED_1000); | ||
303 | |||
304 | /* Call PHY implementation support to complete rate change */ | ||
305 | pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_100); | ||
306 | } | ||
307 | |||
255 | static enum xgbe_mode xgbe_cur_mode(struct xgbe_prv_data *pdata) | 308 | static enum xgbe_mode xgbe_cur_mode(struct xgbe_prv_data *pdata) |
256 | { | 309 | { |
257 | return pdata->phy_if.phy_impl.cur_mode(pdata); | 310 | return pdata->phy_if.phy_impl.cur_mode(pdata); |
@@ -275,6 +328,18 @@ static void xgbe_change_mode(struct xgbe_prv_data *pdata, | |||
275 | case XGBE_MODE_KR: | 328 | case XGBE_MODE_KR: |
276 | xgbe_kr_mode(pdata); | 329 | xgbe_kr_mode(pdata); |
277 | break; | 330 | break; |
331 | case XGBE_MODE_SGMII_100: | ||
332 | xgbe_sgmii_100_mode(pdata); | ||
333 | break; | ||
334 | case XGBE_MODE_SGMII_1000: | ||
335 | xgbe_sgmii_1000_mode(pdata); | ||
336 | break; | ||
337 | case XGBE_MODE_X: | ||
338 | xgbe_x_mode(pdata); | ||
339 | break; | ||
340 | case XGBE_MODE_SFI: | ||
341 | xgbe_sfi_mode(pdata); | ||
342 | break; | ||
278 | case XGBE_MODE_UNKNOWN: | 343 | case XGBE_MODE_UNKNOWN: |
279 | break; | 344 | break; |
280 | default: | 345 | default: |
@@ -373,6 +438,7 @@ static void xgbe_an_restart(struct xgbe_prv_data *pdata) | |||
373 | { | 438 | { |
374 | switch (pdata->an_mode) { | 439 | switch (pdata->an_mode) { |
375 | case XGBE_AN_MODE_CL73: | 440 | case XGBE_AN_MODE_CL73: |
441 | case XGBE_AN_MODE_CL73_REDRV: | ||
376 | xgbe_an73_restart(pdata); | 442 | xgbe_an73_restart(pdata); |
377 | break; | 443 | break; |
378 | case XGBE_AN_MODE_CL37: | 444 | case XGBE_AN_MODE_CL37: |
@@ -388,6 +454,7 @@ static void xgbe_an_disable(struct xgbe_prv_data *pdata) | |||
388 | { | 454 | { |
389 | switch (pdata->an_mode) { | 455 | switch (pdata->an_mode) { |
390 | case XGBE_AN_MODE_CL73: | 456 | case XGBE_AN_MODE_CL73: |
457 | case XGBE_AN_MODE_CL73_REDRV: | ||
391 | xgbe_an73_disable(pdata); | 458 | xgbe_an73_disable(pdata); |
392 | break; | 459 | break; |
393 | case XGBE_AN_MODE_CL37: | 460 | case XGBE_AN_MODE_CL37: |
@@ -627,6 +694,7 @@ static irqreturn_t xgbe_an_isr(int irq, void *data) | |||
627 | 694 | ||
628 | switch (pdata->an_mode) { | 695 | switch (pdata->an_mode) { |
629 | case XGBE_AN_MODE_CL73: | 696 | case XGBE_AN_MODE_CL73: |
697 | case XGBE_AN_MODE_CL73_REDRV: | ||
630 | xgbe_an73_isr(pdata); | 698 | xgbe_an73_isr(pdata); |
631 | break; | 699 | break; |
632 | case XGBE_AN_MODE_CL37: | 700 | case XGBE_AN_MODE_CL37: |
@@ -640,6 +708,11 @@ static irqreturn_t xgbe_an_isr(int irq, void *data) | |||
640 | return IRQ_HANDLED; | 708 | return IRQ_HANDLED; |
641 | } | 709 | } |
642 | 710 | ||
711 | static irqreturn_t xgbe_an_combined_isr(int irq, struct xgbe_prv_data *pdata) | ||
712 | { | ||
713 | return xgbe_an_isr(irq, pdata); | ||
714 | } | ||
715 | |||
643 | static void xgbe_an_irq_work(struct work_struct *work) | 716 | static void xgbe_an_irq_work(struct work_struct *work) |
644 | { | 717 | { |
645 | struct xgbe_prv_data *pdata = container_of(work, | 718 | struct xgbe_prv_data *pdata = container_of(work, |
@@ -830,6 +903,7 @@ static void xgbe_an_state_machine(struct work_struct *work) | |||
830 | 903 | ||
831 | switch (pdata->an_mode) { | 904 | switch (pdata->an_mode) { |
832 | case XGBE_AN_MODE_CL73: | 905 | case XGBE_AN_MODE_CL73: |
906 | case XGBE_AN_MODE_CL73_REDRV: | ||
833 | xgbe_an73_state_machine(pdata); | 907 | xgbe_an73_state_machine(pdata); |
834 | break; | 908 | break; |
835 | case XGBE_AN_MODE_CL37: | 909 | case XGBE_AN_MODE_CL37: |
@@ -845,16 +919,18 @@ static void xgbe_an_state_machine(struct work_struct *work) | |||
845 | 919 | ||
846 | static void xgbe_an37_init(struct xgbe_prv_data *pdata) | 920 | static void xgbe_an37_init(struct xgbe_prv_data *pdata) |
847 | { | 921 | { |
848 | unsigned int reg; | 922 | unsigned int advertising, reg; |
923 | |||
924 | advertising = pdata->phy_if.phy_impl.an_advertising(pdata); | ||
849 | 925 | ||
850 | /* Set up Advertisement register */ | 926 | /* Set up Advertisement register */ |
851 | reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE); | 927 | reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE); |
852 | if (pdata->phy.advertising & ADVERTISED_Pause) | 928 | if (advertising & ADVERTISED_Pause) |
853 | reg |= 0x100; | 929 | reg |= 0x100; |
854 | else | 930 | else |
855 | reg &= ~0x100; | 931 | reg &= ~0x100; |
856 | 932 | ||
857 | if (pdata->phy.advertising & ADVERTISED_Asym_Pause) | 933 | if (advertising & ADVERTISED_Asym_Pause) |
858 | reg |= 0x80; | 934 | reg |= 0x80; |
859 | else | 935 | else |
860 | reg &= ~0x80; | 936 | reg &= ~0x80; |
@@ -889,11 +965,13 @@ static void xgbe_an37_init(struct xgbe_prv_data *pdata) | |||
889 | 965 | ||
890 | static void xgbe_an73_init(struct xgbe_prv_data *pdata) | 966 | static void xgbe_an73_init(struct xgbe_prv_data *pdata) |
891 | { | 967 | { |
892 | unsigned int reg; | 968 | unsigned int advertising, reg; |
969 | |||
970 | advertising = pdata->phy_if.phy_impl.an_advertising(pdata); | ||
893 | 971 | ||
894 | /* Set up Advertisement register 3 first */ | 972 | /* Set up Advertisement register 3 first */ |
895 | reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); | 973 | reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); |
896 | if (pdata->phy.advertising & ADVERTISED_10000baseR_FEC) | 974 | if (advertising & ADVERTISED_10000baseR_FEC) |
897 | reg |= 0xc000; | 975 | reg |= 0xc000; |
898 | else | 976 | else |
899 | reg &= ~0xc000; | 977 | reg &= ~0xc000; |
@@ -902,13 +980,13 @@ static void xgbe_an73_init(struct xgbe_prv_data *pdata) | |||
902 | 980 | ||
903 | /* Set up Advertisement register 2 next */ | 981 | /* Set up Advertisement register 2 next */ |
904 | reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); | 982 | reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); |
905 | if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) | 983 | if (advertising & ADVERTISED_10000baseKR_Full) |
906 | reg |= 0x80; | 984 | reg |= 0x80; |
907 | else | 985 | else |
908 | reg &= ~0x80; | 986 | reg &= ~0x80; |
909 | 987 | ||
910 | if ((pdata->phy.advertising & ADVERTISED_1000baseKX_Full) || | 988 | if ((advertising & ADVERTISED_1000baseKX_Full) || |
911 | (pdata->phy.advertising & ADVERTISED_2500baseX_Full)) | 989 | (advertising & ADVERTISED_2500baseX_Full)) |
912 | reg |= 0x20; | 990 | reg |= 0x20; |
913 | else | 991 | else |
914 | reg &= ~0x20; | 992 | reg &= ~0x20; |
@@ -917,12 +995,12 @@ static void xgbe_an73_init(struct xgbe_prv_data *pdata) | |||
917 | 995 | ||
918 | /* Set up Advertisement register 1 last */ | 996 | /* Set up Advertisement register 1 last */ |
919 | reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); | 997 | reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); |
920 | if (pdata->phy.advertising & ADVERTISED_Pause) | 998 | if (advertising & ADVERTISED_Pause) |
921 | reg |= 0x400; | 999 | reg |= 0x400; |
922 | else | 1000 | else |
923 | reg &= ~0x400; | 1001 | reg &= ~0x400; |
924 | 1002 | ||
925 | if (pdata->phy.advertising & ADVERTISED_Asym_Pause) | 1003 | if (advertising & ADVERTISED_Asym_Pause) |
926 | reg |= 0x800; | 1004 | reg |= 0x800; |
927 | else | 1005 | else |
928 | reg &= ~0x800; | 1006 | reg &= ~0x800; |
@@ -941,6 +1019,7 @@ static void xgbe_an_init(struct xgbe_prv_data *pdata) | |||
941 | pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata); | 1019 | pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata); |
942 | switch (pdata->an_mode) { | 1020 | switch (pdata->an_mode) { |
943 | case XGBE_AN_MODE_CL73: | 1021 | case XGBE_AN_MODE_CL73: |
1022 | case XGBE_AN_MODE_CL73_REDRV: | ||
944 | xgbe_an73_init(pdata); | 1023 | xgbe_an73_init(pdata); |
945 | break; | 1024 | break; |
946 | case XGBE_AN_MODE_CL37: | 1025 | case XGBE_AN_MODE_CL37: |
@@ -967,6 +1046,8 @@ static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata) | |||
967 | static const char *xgbe_phy_speed_string(int speed) | 1046 | static const char *xgbe_phy_speed_string(int speed) |
968 | { | 1047 | { |
969 | switch (speed) { | 1048 | switch (speed) { |
1049 | case SPEED_100: | ||
1050 | return "100Mbps"; | ||
970 | case SPEED_1000: | 1051 | case SPEED_1000: |
971 | return "1Gbps"; | 1052 | return "1Gbps"; |
972 | case SPEED_2500: | 1053 | case SPEED_2500: |
@@ -1052,6 +1133,10 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) | |||
1052 | case XGBE_MODE_KX_1000: | 1133 | case XGBE_MODE_KX_1000: |
1053 | case XGBE_MODE_KX_2500: | 1134 | case XGBE_MODE_KX_2500: |
1054 | case XGBE_MODE_KR: | 1135 | case XGBE_MODE_KR: |
1136 | case XGBE_MODE_SGMII_100: | ||
1137 | case XGBE_MODE_SGMII_1000: | ||
1138 | case XGBE_MODE_X: | ||
1139 | case XGBE_MODE_SFI: | ||
1055 | break; | 1140 | break; |
1056 | case XGBE_MODE_UNKNOWN: | 1141 | case XGBE_MODE_UNKNOWN: |
1057 | default: | 1142 | default: |
@@ -1069,13 +1154,24 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) | |||
1069 | 1154 | ||
1070 | static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) | 1155 | static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) |
1071 | { | 1156 | { |
1157 | int ret; | ||
1158 | |||
1072 | set_bit(XGBE_LINK_INIT, &pdata->dev_state); | 1159 | set_bit(XGBE_LINK_INIT, &pdata->dev_state); |
1073 | pdata->link_check = jiffies; | 1160 | pdata->link_check = jiffies; |
1074 | 1161 | ||
1075 | if (pdata->phy.autoneg != AUTONEG_ENABLE) | 1162 | ret = pdata->phy_if.phy_impl.an_config(pdata); |
1076 | return xgbe_phy_config_fixed(pdata); | 1163 | if (ret) |
1164 | return ret; | ||
1077 | 1165 | ||
1078 | netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n"); | 1166 | if (pdata->phy.autoneg != AUTONEG_ENABLE) { |
1167 | ret = xgbe_phy_config_fixed(pdata); | ||
1168 | if (ret || !pdata->kr_redrv) | ||
1169 | return ret; | ||
1170 | |||
1171 | netif_dbg(pdata, link, pdata->netdev, "AN redriver support\n"); | ||
1172 | } else { | ||
1173 | netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n"); | ||
1174 | } | ||
1079 | 1175 | ||
1080 | /* Disable auto-negotiation interrupt */ | 1176 | /* Disable auto-negotiation interrupt */ |
1081 | disable_irq(pdata->an_irq); | 1177 | disable_irq(pdata->an_irq); |
@@ -1087,6 +1183,14 @@ static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) | |||
1087 | xgbe_set_mode(pdata, XGBE_MODE_KX_2500); | 1183 | xgbe_set_mode(pdata, XGBE_MODE_KX_2500); |
1088 | } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) { | 1184 | } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) { |
1089 | xgbe_set_mode(pdata, XGBE_MODE_KX_1000); | 1185 | xgbe_set_mode(pdata, XGBE_MODE_KX_1000); |
1186 | } else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) { | ||
1187 | xgbe_set_mode(pdata, XGBE_MODE_SFI); | ||
1188 | } else if (xgbe_use_mode(pdata, XGBE_MODE_X)) { | ||
1189 | xgbe_set_mode(pdata, XGBE_MODE_X); | ||
1190 | } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) { | ||
1191 | xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000); | ||
1192 | } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) { | ||
1193 | xgbe_set_mode(pdata, XGBE_MODE_SGMII_100); | ||
1090 | } else { | 1194 | } else { |
1091 | enable_irq(pdata->an_irq); | 1195 | enable_irq(pdata->an_irq); |
1092 | return -EINVAL; | 1196 | return -EINVAL; |
@@ -1162,13 +1266,19 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata) | |||
1162 | mode = xgbe_phy_status_aneg(pdata); | 1266 | mode = xgbe_phy_status_aneg(pdata); |
1163 | 1267 | ||
1164 | switch (mode) { | 1268 | switch (mode) { |
1269 | case XGBE_MODE_SGMII_100: | ||
1270 | pdata->phy.speed = SPEED_100; | ||
1271 | break; | ||
1272 | case XGBE_MODE_X: | ||
1165 | case XGBE_MODE_KX_1000: | 1273 | case XGBE_MODE_KX_1000: |
1274 | case XGBE_MODE_SGMII_1000: | ||
1166 | pdata->phy.speed = SPEED_1000; | 1275 | pdata->phy.speed = SPEED_1000; |
1167 | break; | 1276 | break; |
1168 | case XGBE_MODE_KX_2500: | 1277 | case XGBE_MODE_KX_2500: |
1169 | pdata->phy.speed = SPEED_2500; | 1278 | pdata->phy.speed = SPEED_2500; |
1170 | break; | 1279 | break; |
1171 | case XGBE_MODE_KR: | 1280 | case XGBE_MODE_KR: |
1281 | case XGBE_MODE_SFI: | ||
1172 | pdata->phy.speed = SPEED_10000; | 1282 | pdata->phy.speed = SPEED_10000; |
1173 | break; | 1283 | break; |
1174 | case XGBE_MODE_UNKNOWN: | 1284 | case XGBE_MODE_UNKNOWN: |
@@ -1184,6 +1294,7 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata) | |||
1184 | static void xgbe_phy_status(struct xgbe_prv_data *pdata) | 1294 | static void xgbe_phy_status(struct xgbe_prv_data *pdata) |
1185 | { | 1295 | { |
1186 | unsigned int link_aneg; | 1296 | unsigned int link_aneg; |
1297 | int an_restart; | ||
1187 | 1298 | ||
1188 | if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) { | 1299 | if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) { |
1189 | netif_carrier_off(pdata->netdev); | 1300 | netif_carrier_off(pdata->netdev); |
@@ -1194,7 +1305,13 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata) | |||
1194 | 1305 | ||
1195 | link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); | 1306 | link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); |
1196 | 1307 | ||
1197 | pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata); | 1308 | pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata, |
1309 | &an_restart); | ||
1310 | if (an_restart) { | ||
1311 | xgbe_phy_config_aneg(pdata); | ||
1312 | return; | ||
1313 | } | ||
1314 | |||
1198 | if (pdata->phy.link) { | 1315 | if (pdata->phy.link) { |
1199 | if (link_aneg && !xgbe_phy_aneg_done(pdata)) { | 1316 | if (link_aneg && !xgbe_phy_aneg_done(pdata)) { |
1200 | xgbe_check_link_timeout(pdata); | 1317 | xgbe_check_link_timeout(pdata); |
@@ -1237,7 +1354,8 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata) | |||
1237 | /* Disable auto-negotiation */ | 1354 | /* Disable auto-negotiation */ |
1238 | xgbe_an_disable_all(pdata); | 1355 | xgbe_an_disable_all(pdata); |
1239 | 1356 | ||
1240 | devm_free_irq(pdata->dev, pdata->an_irq, pdata); | 1357 | if (pdata->dev_irq != pdata->an_irq) |
1358 | devm_free_irq(pdata->dev, pdata->an_irq, pdata); | ||
1241 | 1359 | ||
1242 | pdata->phy_if.phy_impl.stop(pdata); | 1360 | pdata->phy_if.phy_impl.stop(pdata); |
1243 | 1361 | ||
@@ -1258,12 +1376,15 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata) | |||
1258 | if (ret) | 1376 | if (ret) |
1259 | return ret; | 1377 | return ret; |
1260 | 1378 | ||
1261 | ret = devm_request_irq(pdata->dev, pdata->an_irq, | 1379 | /* If we have a separate AN irq, enable it */ |
1262 | xgbe_an_isr, 0, pdata->an_name, | 1380 | if (pdata->dev_irq != pdata->an_irq) { |
1263 | pdata); | 1381 | ret = devm_request_irq(pdata->dev, pdata->an_irq, |
1264 | if (ret) { | 1382 | xgbe_an_isr, 0, pdata->an_name, |
1265 | netdev_err(netdev, "phy irq request failed\n"); | 1383 | pdata); |
1266 | goto err_stop; | 1384 | if (ret) { |
1385 | netdev_err(netdev, "phy irq request failed\n"); | ||
1386 | goto err_stop; | ||
1387 | } | ||
1267 | } | 1388 | } |
1268 | 1389 | ||
1269 | /* Set initial mode - call the mode setting routines | 1390 | /* Set initial mode - call the mode setting routines |
@@ -1275,6 +1396,14 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata) | |||
1275 | xgbe_kx_2500_mode(pdata); | 1396 | xgbe_kx_2500_mode(pdata); |
1276 | } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) { | 1397 | } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) { |
1277 | xgbe_kx_1000_mode(pdata); | 1398 | xgbe_kx_1000_mode(pdata); |
1399 | } else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) { | ||
1400 | xgbe_sfi_mode(pdata); | ||
1401 | } else if (xgbe_use_mode(pdata, XGBE_MODE_X)) { | ||
1402 | xgbe_x_mode(pdata); | ||
1403 | } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) { | ||
1404 | xgbe_sgmii_1000_mode(pdata); | ||
1405 | } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) { | ||
1406 | xgbe_sgmii_100_mode(pdata); | ||
1278 | } else { | 1407 | } else { |
1279 | ret = -EINVAL; | 1408 | ret = -EINVAL; |
1280 | goto err_irq; | 1409 | goto err_irq; |
@@ -1289,7 +1418,8 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata) | |||
1289 | return xgbe_phy_config_aneg(pdata); | 1418 | return xgbe_phy_config_aneg(pdata); |
1290 | 1419 | ||
1291 | err_irq: | 1420 | err_irq: |
1292 | devm_free_irq(pdata->dev, pdata->an_irq, pdata); | 1421 | if (pdata->dev_irq != pdata->an_irq) |
1422 | devm_free_irq(pdata->dev, pdata->an_irq, pdata); | ||
1293 | 1423 | ||
1294 | err_stop: | 1424 | err_stop: |
1295 | pdata->phy_if.phy_impl.stop(pdata); | 1425 | pdata->phy_if.phy_impl.stop(pdata); |
@@ -1357,10 +1487,16 @@ static int xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata) | |||
1357 | { | 1487 | { |
1358 | if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) | 1488 | if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) |
1359 | return SPEED_10000; | 1489 | return SPEED_10000; |
1490 | else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full) | ||
1491 | return SPEED_10000; | ||
1360 | else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full) | 1492 | else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full) |
1361 | return SPEED_2500; | 1493 | return SPEED_2500; |
1362 | else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full) | 1494 | else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full) |
1363 | return SPEED_1000; | 1495 | return SPEED_1000; |
1496 | else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full) | ||
1497 | return SPEED_1000; | ||
1498 | else if (pdata->phy.advertising & ADVERTISED_100baseT_Full) | ||
1499 | return SPEED_100; | ||
1364 | 1500 | ||
1365 | return SPEED_UNKNOWN; | 1501 | return SPEED_UNKNOWN; |
1366 | } | 1502 | } |
@@ -1442,4 +1578,6 @@ void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *phy_if) | |||
1442 | phy_if->phy_config_aneg = xgbe_phy_config_aneg; | 1578 | phy_if->phy_config_aneg = xgbe_phy_config_aneg; |
1443 | 1579 | ||
1444 | phy_if->phy_valid_speed = xgbe_phy_valid_speed; | 1580 | phy_if->phy_valid_speed = xgbe_phy_valid_speed; |
1581 | |||
1582 | phy_if->an_isr = xgbe_an_combined_isr; | ||
1445 | } | 1583 | } |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c new file mode 100644 index 000000000000..e76b7f65b805 --- /dev/null +++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c | |||
@@ -0,0 +1,529 @@ | |||
1 | /* | ||
2 | * AMD 10Gb Ethernet driver | ||
3 | * | ||
4 | * This file is available to you under your choice of the following two | ||
5 | * licenses: | ||
6 | * | ||
7 | * License 1: GPLv2 | ||
8 | * | ||
9 | * Copyright (c) 2016 Advanced Micro Devices, Inc. | ||
10 | * | ||
11 | * This file is free software; you may copy, redistribute and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 2 of the License, or (at | ||
14 | * your option) any later version. | ||
15 | * | ||
16 | * This file is distributed in the hope that it will be useful, but | ||
17 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | * General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
23 | * | ||
24 | * This file incorporates work covered by the following copyright and | ||
25 | * permission notice: | ||
26 | * The Synopsys DWC ETHER XGMAC Software Driver and documentation | ||
27 | * (hereinafter "Software") is an unsupported proprietary work of Synopsys, | ||
28 | * Inc. unless otherwise expressly agreed to in writing between Synopsys | ||
29 | * and you. | ||
30 | * | ||
31 | * The Software IS NOT an item of Licensed Software or Licensed Product | ||
32 | * under any End User Software License Agreement or Agreement for Licensed | ||
33 | * Product with Synopsys or any supplement thereto. Permission is hereby | ||
34 | * granted, free of charge, to any person obtaining a copy of this software | ||
35 | * annotated with this license and the Software, to deal in the Software | ||
36 | * without restriction, including without limitation the rights to use, | ||
37 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
38 | * of the Software, and to permit persons to whom the Software is furnished | ||
39 | * to do so, subject to the following conditions: | ||
40 | * | ||
41 | * The above copyright notice and this permission notice shall be included | ||
42 | * in all copies or substantial portions of the Software. | ||
43 | * | ||
44 | * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
45 | * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
46 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
47 | * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS | ||
48 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
49 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
50 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
51 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
52 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
53 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
54 | * THE POSSIBILITY OF SUCH DAMAGE. | ||
55 | * | ||
56 | * | ||
57 | * License 2: Modified BSD | ||
58 | * | ||
59 | * Copyright (c) 2016 Advanced Micro Devices, Inc. | ||
60 | * All rights reserved. | ||
61 | * | ||
62 | * Redistribution and use in source and binary forms, with or without | ||
63 | * modification, are permitted provided that the following conditions are met: | ||
64 | * * Redistributions of source code must retain the above copyright | ||
65 | * notice, this list of conditions and the following disclaimer. | ||
66 | * * Redistributions in binary form must reproduce the above copyright | ||
67 | * notice, this list of conditions and the following disclaimer in the | ||
68 | * documentation and/or other materials provided with the distribution. | ||
69 | * * Neither the name of Advanced Micro Devices, Inc. nor the | ||
70 | * names of its contributors may be used to endorse or promote products | ||
71 | * derived from this software without specific prior written permission. | ||
72 | * | ||
73 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
74 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
75 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
76 | * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | ||
77 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
78 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
79 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
80 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
81 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
82 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
83 | * | ||
84 | * This file incorporates work covered by the following copyright and | ||
85 | * permission notice: | ||
86 | * The Synopsys DWC ETHER XGMAC Software Driver and documentation | ||
87 | * (hereinafter "Software") is an unsupported proprietary work of Synopsys, | ||
88 | * Inc. unless otherwise expressly agreed to in writing between Synopsys | ||
89 | * and you. | ||
90 | * | ||
91 | * The Software IS NOT an item of Licensed Software or Licensed Product | ||
92 | * under any End User Software License Agreement or Agreement for Licensed | ||
93 | * Product with Synopsys or any supplement thereto. Permission is hereby | ||
94 | * granted, free of charge, to any person obtaining a copy of this software | ||
95 | * annotated with this license and the Software, to deal in the Software | ||
96 | * without restriction, including without limitation the rights to use, | ||
97 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
98 | * of the Software, and to permit persons to whom the Software is furnished | ||
99 | * to do so, subject to the following conditions: | ||
100 | * | ||
101 | * The above copyright notice and this permission notice shall be included | ||
102 | * in all copies or substantial portions of the Software. | ||
103 | * | ||
104 | * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
105 | * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
106 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
107 | * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS | ||
108 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
109 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
110 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
111 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
112 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
113 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
114 | * THE POSSIBILITY OF SUCH DAMAGE. | ||
115 | */ | ||
116 | |||
117 | #include <linux/module.h> | ||
118 | #include <linux/device.h> | ||
119 | #include <linux/pci.h> | ||
120 | #include <linux/log2.h> | ||
121 | |||
122 | #include "xgbe.h" | ||
123 | #include "xgbe-common.h" | ||
124 | |||
125 | static int xgbe_config_msi(struct xgbe_prv_data *pdata) | ||
126 | { | ||
127 | unsigned int msi_count; | ||
128 | unsigned int i, j; | ||
129 | int ret; | ||
130 | |||
131 | msi_count = XGBE_MSIX_BASE_COUNT; | ||
132 | msi_count += max(pdata->rx_ring_count, | ||
133 | pdata->tx_ring_count); | ||
134 | msi_count = roundup_pow_of_two(msi_count); | ||
135 | |||
136 | ret = pci_enable_msi_exact(pdata->pcidev, msi_count); | ||
137 | if (ret < 0) { | ||
138 | dev_info(pdata->dev, "MSI request for %u interrupts failed\n", | ||
139 | msi_count); | ||
140 | |||
141 | ret = pci_enable_msi(pdata->pcidev); | ||
142 | if (ret < 0) { | ||
143 | dev_info(pdata->dev, "MSI enablement failed\n"); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | msi_count = 1; | ||
148 | } | ||
149 | |||
150 | pdata->irq_count = msi_count; | ||
151 | |||
152 | pdata->dev_irq = pdata->pcidev->irq; | ||
153 | |||
154 | if (msi_count > 1) { | ||
155 | pdata->ecc_irq = pdata->pcidev->irq + 1; | ||
156 | pdata->i2c_irq = pdata->pcidev->irq + 2; | ||
157 | pdata->an_irq = pdata->pcidev->irq + 3; | ||
158 | |||
159 | for (i = XGBE_MSIX_BASE_COUNT, j = 0; | ||
160 | (i < msi_count) && (j < XGBE_MAX_DMA_CHANNELS); | ||
161 | i++, j++) | ||
162 | pdata->channel_irq[j] = pdata->pcidev->irq + i; | ||
163 | pdata->channel_irq_count = j; | ||
164 | |||
165 | pdata->per_channel_irq = 1; | ||
166 | pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL; | ||
167 | } else { | ||
168 | pdata->ecc_irq = pdata->pcidev->irq; | ||
169 | pdata->i2c_irq = pdata->pcidev->irq; | ||
170 | pdata->an_irq = pdata->pcidev->irq; | ||
171 | } | ||
172 | |||
173 | if (netif_msg_probe(pdata)) | ||
174 | dev_dbg(pdata->dev, "MSI interrupts enabled\n"); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int xgbe_config_msix(struct xgbe_prv_data *pdata) | ||
180 | { | ||
181 | unsigned int msix_count; | ||
182 | unsigned int i, j; | ||
183 | int ret; | ||
184 | |||
185 | msix_count = XGBE_MSIX_BASE_COUNT; | ||
186 | msix_count += max(pdata->rx_ring_count, | ||
187 | pdata->tx_ring_count); | ||
188 | |||
189 | pdata->msix_entries = devm_kcalloc(pdata->dev, msix_count, | ||
190 | sizeof(struct msix_entry), | ||
191 | GFP_KERNEL); | ||
192 | if (!pdata->msix_entries) | ||
193 | return -ENOMEM; | ||
194 | |||
195 | for (i = 0; i < msix_count; i++) | ||
196 | pdata->msix_entries[i].entry = i; | ||
197 | |||
198 | ret = pci_enable_msix_range(pdata->pcidev, pdata->msix_entries, | ||
199 | XGBE_MSIX_MIN_COUNT, msix_count); | ||
200 | if (ret < 0) { | ||
201 | dev_info(pdata->dev, "MSI-X enablement failed\n"); | ||
202 | devm_kfree(pdata->dev, pdata->msix_entries); | ||
203 | pdata->msix_entries = NULL; | ||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | pdata->irq_count = ret; | ||
208 | |||
209 | pdata->dev_irq = pdata->msix_entries[0].vector; | ||
210 | pdata->ecc_irq = pdata->msix_entries[1].vector; | ||
211 | pdata->i2c_irq = pdata->msix_entries[2].vector; | ||
212 | pdata->an_irq = pdata->msix_entries[3].vector; | ||
213 | |||
214 | for (i = XGBE_MSIX_BASE_COUNT, j = 0; i < ret; i++, j++) | ||
215 | pdata->channel_irq[j] = pdata->msix_entries[i].vector; | ||
216 | pdata->channel_irq_count = j; | ||
217 | |||
218 | pdata->per_channel_irq = 1; | ||
219 | pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL; | ||
220 | |||
221 | if (netif_msg_probe(pdata)) | ||
222 | dev_dbg(pdata->dev, "MSI-X interrupts enabled\n"); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int xgbe_config_irqs(struct xgbe_prv_data *pdata) | ||
228 | { | ||
229 | int ret; | ||
230 | |||
231 | ret = xgbe_config_msix(pdata); | ||
232 | if (!ret) | ||
233 | goto out; | ||
234 | |||
235 | ret = xgbe_config_msi(pdata); | ||
236 | if (!ret) | ||
237 | goto out; | ||
238 | |||
239 | pdata->irq_count = 1; | ||
240 | pdata->irq_shared = 1; | ||
241 | |||
242 | pdata->dev_irq = pdata->pcidev->irq; | ||
243 | pdata->ecc_irq = pdata->pcidev->irq; | ||
244 | pdata->i2c_irq = pdata->pcidev->irq; | ||
245 | pdata->an_irq = pdata->pcidev->irq; | ||
246 | |||
247 | out: | ||
248 | if (netif_msg_probe(pdata)) { | ||
249 | unsigned int i; | ||
250 | |||
251 | dev_dbg(pdata->dev, " dev irq=%d\n", pdata->dev_irq); | ||
252 | dev_dbg(pdata->dev, " ecc irq=%d\n", pdata->ecc_irq); | ||
253 | dev_dbg(pdata->dev, " i2c irq=%d\n", pdata->i2c_irq); | ||
254 | dev_dbg(pdata->dev, " an irq=%d\n", pdata->an_irq); | ||
255 | for (i = 0; i < pdata->channel_irq_count; i++) | ||
256 | dev_dbg(pdata->dev, " dma%u irq=%d\n", | ||
257 | i, pdata->channel_irq[i]); | ||
258 | } | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
264 | { | ||
265 | struct xgbe_prv_data *pdata; | ||
266 | struct device *dev = &pdev->dev; | ||
267 | void __iomem * const *iomap_table; | ||
268 | unsigned int ma_lo, ma_hi; | ||
269 | unsigned int reg; | ||
270 | int bar_mask; | ||
271 | int ret; | ||
272 | |||
273 | pdata = xgbe_alloc_pdata(dev); | ||
274 | if (IS_ERR(pdata)) { | ||
275 | ret = PTR_ERR(pdata); | ||
276 | goto err_alloc; | ||
277 | } | ||
278 | |||
279 | pdata->pcidev = pdev; | ||
280 | pci_set_drvdata(pdev, pdata); | ||
281 | |||
282 | /* Get the version data */ | ||
283 | pdata->vdata = (struct xgbe_version_data *)id->driver_data; | ||
284 | |||
285 | ret = pcim_enable_device(pdev); | ||
286 | if (ret) { | ||
287 | dev_err(dev, "pcim_enable_device failed\n"); | ||
288 | goto err_pci_enable; | ||
289 | } | ||
290 | |||
291 | /* Obtain the mmio areas for the device */ | ||
292 | bar_mask = pci_select_bars(pdev, IORESOURCE_MEM); | ||
293 | ret = pcim_iomap_regions(pdev, bar_mask, XGBE_DRV_NAME); | ||
294 | if (ret) { | ||
295 | dev_err(dev, "pcim_iomap_regions failed\n"); | ||
296 | goto err_pci_enable; | ||
297 | } | ||
298 | |||
299 | iomap_table = pcim_iomap_table(pdev); | ||
300 | if (!iomap_table) { | ||
301 | dev_err(dev, "pcim_iomap_table failed\n"); | ||
302 | ret = -ENOMEM; | ||
303 | goto err_pci_enable; | ||
304 | } | ||
305 | |||
306 | pdata->xgmac_regs = iomap_table[XGBE_XGMAC_BAR]; | ||
307 | if (!pdata->xgmac_regs) { | ||
308 | dev_err(dev, "xgmac ioremap failed\n"); | ||
309 | ret = -ENOMEM; | ||
310 | goto err_pci_enable; | ||
311 | } | ||
312 | pdata->xprop_regs = pdata->xgmac_regs + XGBE_MAC_PROP_OFFSET; | ||
313 | pdata->xi2c_regs = pdata->xgmac_regs + XGBE_I2C_CTRL_OFFSET; | ||
314 | if (netif_msg_probe(pdata)) { | ||
315 | dev_dbg(dev, "xgmac_regs = %p\n", pdata->xgmac_regs); | ||
316 | dev_dbg(dev, "xprop_regs = %p\n", pdata->xprop_regs); | ||
317 | dev_dbg(dev, "xi2c_regs = %p\n", pdata->xi2c_regs); | ||
318 | } | ||
319 | |||
320 | pdata->xpcs_regs = iomap_table[XGBE_XPCS_BAR]; | ||
321 | if (!pdata->xpcs_regs) { | ||
322 | dev_err(dev, "xpcs ioremap failed\n"); | ||
323 | ret = -ENOMEM; | ||
324 | goto err_pci_enable; | ||
325 | } | ||
326 | if (netif_msg_probe(pdata)) | ||
327 | dev_dbg(dev, "xpcs_regs = %p\n", pdata->xpcs_regs); | ||
328 | |||
329 | /* Configure the PCS indirect addressing support */ | ||
330 | reg = XPCS32_IOREAD(pdata, PCS_V2_WINDOW_DEF); | ||
331 | pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET); | ||
332 | pdata->xpcs_window <<= 6; | ||
333 | pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE); | ||
334 | pdata->xpcs_window_size = 1 << (pdata->xpcs_window_size + 7); | ||
335 | pdata->xpcs_window_mask = pdata->xpcs_window_size - 1; | ||
336 | if (netif_msg_probe(pdata)) { | ||
337 | dev_dbg(dev, "xpcs window = %#010x\n", | ||
338 | pdata->xpcs_window); | ||
339 | dev_dbg(dev, "xpcs window size = %#010x\n", | ||
340 | pdata->xpcs_window_size); | ||
341 | dev_dbg(dev, "xpcs window mask = %#010x\n", | ||
342 | pdata->xpcs_window_mask); | ||
343 | } | ||
344 | |||
345 | pci_set_master(pdev); | ||
346 | |||
347 | /* Enable all interrupts in the hardware */ | ||
348 | XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff); | ||
349 | |||
350 | /* Retrieve the MAC address */ | ||
351 | ma_lo = XP_IOREAD(pdata, XP_MAC_ADDR_LO); | ||
352 | ma_hi = XP_IOREAD(pdata, XP_MAC_ADDR_HI); | ||
353 | pdata->mac_addr[0] = ma_lo & 0xff; | ||
354 | pdata->mac_addr[1] = (ma_lo >> 8) & 0xff; | ||
355 | pdata->mac_addr[2] = (ma_lo >> 16) & 0xff; | ||
356 | pdata->mac_addr[3] = (ma_lo >> 24) & 0xff; | ||
357 | pdata->mac_addr[4] = ma_hi & 0xff; | ||
358 | pdata->mac_addr[5] = (ma_hi >> 8) & 0xff; | ||
359 | if (!XP_GET_BITS(ma_hi, XP_MAC_ADDR_HI, VALID) || | ||
360 | !is_valid_ether_addr(pdata->mac_addr)) { | ||
361 | dev_err(dev, "invalid mac address\n"); | ||
362 | ret = -EINVAL; | ||
363 | goto err_pci_enable; | ||
364 | } | ||
365 | |||
366 | /* Clock settings */ | ||
367 | pdata->sysclk_rate = XGBE_V2_DMA_CLOCK_FREQ; | ||
368 | pdata->ptpclk_rate = XGBE_V2_PTP_CLOCK_FREQ; | ||
369 | |||
370 | /* Set the DMA coherency values */ | ||
371 | pdata->coherent = 1; | ||
372 | pdata->axdomain = XGBE_DMA_OS_AXDOMAIN; | ||
373 | pdata->arcache = XGBE_DMA_OS_ARCACHE; | ||
374 | pdata->awcache = XGBE_DMA_OS_AWCACHE; | ||
375 | |||
376 | /* Set the maximum channels and queues */ | ||
377 | reg = XP_IOREAD(pdata, XP_PROP_1); | ||
378 | pdata->tx_max_channel_count = XP_GET_BITS(reg, XP_PROP_1, MAX_TX_DMA); | ||
379 | pdata->rx_max_channel_count = XP_GET_BITS(reg, XP_PROP_1, MAX_RX_DMA); | ||
380 | pdata->tx_max_q_count = XP_GET_BITS(reg, XP_PROP_1, MAX_TX_QUEUES); | ||
381 | pdata->rx_max_q_count = XP_GET_BITS(reg, XP_PROP_1, MAX_RX_QUEUES); | ||
382 | if (netif_msg_probe(pdata)) { | ||
383 | dev_dbg(dev, "max tx/rx channel count = %u/%u\n", | ||
384 | pdata->tx_max_channel_count, | ||
385 | pdata->tx_max_channel_count); | ||
386 | dev_dbg(dev, "max tx/rx hw queue count = %u/%u\n", | ||
387 | pdata->tx_max_q_count, pdata->rx_max_q_count); | ||
388 | } | ||
389 | |||
390 | /* Set the hardware channel and queue counts */ | ||
391 | xgbe_set_counts(pdata); | ||
392 | |||
393 | /* Set the maximum fifo amounts */ | ||
394 | reg = XP_IOREAD(pdata, XP_PROP_2); | ||
395 | pdata->tx_max_fifo_size = XP_GET_BITS(reg, XP_PROP_2, TX_FIFO_SIZE); | ||
396 | pdata->tx_max_fifo_size *= 16384; | ||
397 | pdata->tx_max_fifo_size = min(pdata->tx_max_fifo_size, | ||
398 | pdata->vdata->tx_max_fifo_size); | ||
399 | pdata->rx_max_fifo_size = XP_GET_BITS(reg, XP_PROP_2, RX_FIFO_SIZE); | ||
400 | pdata->rx_max_fifo_size *= 16384; | ||
401 | pdata->rx_max_fifo_size = min(pdata->rx_max_fifo_size, | ||
402 | pdata->vdata->rx_max_fifo_size); | ||
403 | if (netif_msg_probe(pdata)) | ||
404 | dev_dbg(dev, "max tx/rx max fifo size = %u/%u\n", | ||
405 | pdata->tx_max_fifo_size, pdata->rx_max_fifo_size); | ||
406 | |||
407 | /* Configure interrupt support */ | ||
408 | ret = xgbe_config_irqs(pdata); | ||
409 | if (ret) | ||
410 | goto err_pci_enable; | ||
411 | |||
412 | /* Configure the netdev resource */ | ||
413 | ret = xgbe_config_netdev(pdata); | ||
414 | if (ret) | ||
415 | goto err_pci_enable; | ||
416 | |||
417 | netdev_notice(pdata->netdev, "net device enabled\n"); | ||
418 | |||
419 | return 0; | ||
420 | |||
421 | err_pci_enable: | ||
422 | xgbe_free_pdata(pdata); | ||
423 | |||
424 | err_alloc: | ||
425 | dev_notice(dev, "net device not enabled\n"); | ||
426 | |||
427 | return ret; | ||
428 | } | ||
429 | |||
430 | static void xgbe_pci_remove(struct pci_dev *pdev) | ||
431 | { | ||
432 | struct xgbe_prv_data *pdata = pci_get_drvdata(pdev); | ||
433 | |||
434 | xgbe_deconfig_netdev(pdata); | ||
435 | |||
436 | xgbe_free_pdata(pdata); | ||
437 | } | ||
438 | |||
439 | #ifdef CONFIG_PM | ||
440 | static int xgbe_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
441 | { | ||
442 | struct xgbe_prv_data *pdata = pci_get_drvdata(pdev); | ||
443 | struct net_device *netdev = pdata->netdev; | ||
444 | int ret = 0; | ||
445 | |||
446 | if (netif_running(netdev)) | ||
447 | ret = xgbe_powerdown(netdev, XGMAC_DRIVER_CONTEXT); | ||
448 | |||
449 | pdata->lpm_ctrl = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); | ||
450 | pdata->lpm_ctrl |= MDIO_CTRL1_LPOWER; | ||
451 | XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl); | ||
452 | |||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | static int xgbe_pci_resume(struct pci_dev *pdev) | ||
457 | { | ||
458 | struct xgbe_prv_data *pdata = pci_get_drvdata(pdev); | ||
459 | struct net_device *netdev = pdata->netdev; | ||
460 | int ret = 0; | ||
461 | |||
462 | pdata->lpm_ctrl &= ~MDIO_CTRL1_LPOWER; | ||
463 | XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl); | ||
464 | |||
465 | if (netif_running(netdev)) { | ||
466 | ret = xgbe_powerup(netdev, XGMAC_DRIVER_CONTEXT); | ||
467 | |||
468 | /* Schedule a restart in case the link or phy state changed | ||
469 | * while we were powered down. | ||
470 | */ | ||
471 | schedule_work(&pdata->restart_work); | ||
472 | } | ||
473 | |||
474 | return ret; | ||
475 | } | ||
476 | #endif /* CONFIG_PM */ | ||
477 | |||
478 | static const struct xgbe_version_data xgbe_v2a = { | ||
479 | .init_function_ptrs_phy_impl = xgbe_init_function_ptrs_phy_v2, | ||
480 | .xpcs_access = XGBE_XPCS_ACCESS_V2, | ||
481 | .mmc_64bit = 1, | ||
482 | .tx_max_fifo_size = 229376, | ||
483 | .rx_max_fifo_size = 229376, | ||
484 | .tx_tstamp_workaround = 1, | ||
485 | .ecc_support = 1, | ||
486 | .i2c_support = 1, | ||
487 | }; | ||
488 | |||
489 | static const struct xgbe_version_data xgbe_v2b = { | ||
490 | .init_function_ptrs_phy_impl = xgbe_init_function_ptrs_phy_v2, | ||
491 | .xpcs_access = XGBE_XPCS_ACCESS_V2, | ||
492 | .mmc_64bit = 1, | ||
493 | .tx_max_fifo_size = 65536, | ||
494 | .rx_max_fifo_size = 65536, | ||
495 | .tx_tstamp_workaround = 1, | ||
496 | .ecc_support = 1, | ||
497 | .i2c_support = 1, | ||
498 | }; | ||
499 | |||
500 | static const struct pci_device_id xgbe_pci_table[] = { | ||
501 | { PCI_VDEVICE(AMD, 0x1458), | ||
502 | .driver_data = (kernel_ulong_t)&xgbe_v2a }, | ||
503 | { PCI_VDEVICE(AMD, 0x1459), | ||
504 | .driver_data = (kernel_ulong_t)&xgbe_v2b }, | ||
505 | /* Last entry must be zero */ | ||
506 | { 0, } | ||
507 | }; | ||
508 | MODULE_DEVICE_TABLE(pci, xgbe_pci_table); | ||
509 | |||
510 | static struct pci_driver xgbe_driver = { | ||
511 | .name = XGBE_DRV_NAME, | ||
512 | .id_table = xgbe_pci_table, | ||
513 | .probe = xgbe_pci_probe, | ||
514 | .remove = xgbe_pci_remove, | ||
515 | #ifdef CONFIG_PM | ||
516 | .suspend = xgbe_pci_suspend, | ||
517 | .resume = xgbe_pci_resume, | ||
518 | #endif | ||
519 | }; | ||
520 | |||
521 | int xgbe_pci_init(void) | ||
522 | { | ||
523 | return pci_register_driver(&xgbe_driver); | ||
524 | } | ||
525 | |||
526 | void xgbe_pci_exit(void) | ||
527 | { | ||
528 | pci_unregister_driver(&xgbe_driver); | ||
529 | } | ||
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c index 9c913a06efcc..c75edcac5e0a 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c | |||
@@ -295,6 +295,17 @@ static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata) | |||
295 | return mode; | 295 | return mode; |
296 | } | 296 | } |
297 | 297 | ||
298 | static unsigned int xgbe_phy_an_advertising(struct xgbe_prv_data *pdata) | ||
299 | { | ||
300 | return pdata->phy.advertising; | ||
301 | } | ||
302 | |||
303 | static int xgbe_phy_an_config(struct xgbe_prv_data *pdata) | ||
304 | { | ||
305 | /* Nothing uniquely required for an configuration */ | ||
306 | return 0; | ||
307 | } | ||
308 | |||
298 | static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata) | 309 | static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata) |
299 | { | 310 | { |
300 | return XGBE_AN_MODE_CL73; | 311 | return XGBE_AN_MODE_CL73; |
@@ -607,10 +618,12 @@ static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed) | |||
607 | } | 618 | } |
608 | } | 619 | } |
609 | 620 | ||
610 | static int xgbe_phy_link_status(struct xgbe_prv_data *pdata) | 621 | static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) |
611 | { | 622 | { |
612 | unsigned int reg; | 623 | unsigned int reg; |
613 | 624 | ||
625 | *an_restart = 0; | ||
626 | |||
614 | /* Link status is latched low, so read once to clear | 627 | /* Link status is latched low, so read once to clear |
615 | * and then read again to get current state | 628 | * and then read again to get current state |
616 | */ | 629 | */ |
@@ -821,6 +834,10 @@ void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *phy_if) | |||
821 | 834 | ||
822 | phy_impl->an_mode = xgbe_phy_an_mode; | 835 | phy_impl->an_mode = xgbe_phy_an_mode; |
823 | 836 | ||
837 | phy_impl->an_config = xgbe_phy_an_config; | ||
838 | |||
839 | phy_impl->an_advertising = xgbe_phy_an_advertising; | ||
840 | |||
824 | phy_impl->an_outcome = xgbe_phy_an_outcome; | 841 | phy_impl->an_outcome = xgbe_phy_an_outcome; |
825 | 842 | ||
826 | phy_impl->kr_training_pre = xgbe_phy_kr_training_pre; | 843 | phy_impl->kr_training_pre = xgbe_phy_kr_training_pre; |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c new file mode 100644 index 000000000000..4ba43328d99e --- /dev/null +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | |||
@@ -0,0 +1,3083 @@ | |||
1 | /* | ||
2 | * AMD 10Gb Ethernet driver | ||
3 | * | ||
4 | * This file is available to you under your choice of the following two | ||
5 | * licenses: | ||
6 | * | ||
7 | * License 1: GPLv2 | ||
8 | * | ||
9 | * Copyright (c) 2016 Advanced Micro Devices, Inc. | ||
10 | * | ||
11 | * This file is free software; you may copy, redistribute and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 2 of the License, or (at | ||
14 | * your option) any later version. | ||
15 | * | ||
16 | * This file is distributed in the hope that it will be useful, but | ||
17 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | * General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
23 | * | ||
24 | * This file incorporates work covered by the following copyright and | ||
25 | * permission notice: | ||
26 | * The Synopsys DWC ETHER XGMAC Software Driver and documentation | ||
27 | * (hereinafter "Software") is an unsupported proprietary work of Synopsys, | ||
28 | * Inc. unless otherwise expressly agreed to in writing between Synopsys | ||
29 | * and you. | ||
30 | * | ||
31 | * The Software IS NOT an item of Licensed Software or Licensed Product | ||
32 | * under any End User Software License Agreement or Agreement for Licensed | ||
33 | * Product with Synopsys or any supplement thereto. Permission is hereby | ||
34 | * granted, free of charge, to any person obtaining a copy of this software | ||
35 | * annotated with this license and the Software, to deal in the Software | ||
36 | * without restriction, including without limitation the rights to use, | ||
37 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
38 | * of the Software, and to permit persons to whom the Software is furnished | ||
39 | * to do so, subject to the following conditions: | ||
40 | * | ||
41 | * The above copyright notice and this permission notice shall be included | ||
42 | * in all copies or substantial portions of the Software. | ||
43 | * | ||
44 | * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
45 | * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
46 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
47 | * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS | ||
48 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
49 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
50 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
51 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
52 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
53 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
54 | * THE POSSIBILITY OF SUCH DAMAGE. | ||
55 | * | ||
56 | * | ||
57 | * License 2: Modified BSD | ||
58 | * | ||
59 | * Copyright (c) 2016 Advanced Micro Devices, Inc. | ||
60 | * All rights reserved. | ||
61 | * | ||
62 | * Redistribution and use in source and binary forms, with or without | ||
63 | * modification, are permitted provided that the following conditions are met: | ||
64 | * * Redistributions of source code must retain the above copyright | ||
65 | * notice, this list of conditions and the following disclaimer. | ||
66 | * * Redistributions in binary form must reproduce the above copyright | ||
67 | * notice, this list of conditions and the following disclaimer in the | ||
68 | * documentation and/or other materials provided with the distribution. | ||
69 | * * Neither the name of Advanced Micro Devices, Inc. nor the | ||
70 | * names of its contributors may be used to endorse or promote products | ||
71 | * derived from this software without specific prior written permission. | ||
72 | * | ||
73 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
74 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
75 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
76 | * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | ||
77 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
78 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
79 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
80 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
81 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
82 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
83 | * | ||
84 | * This file incorporates work covered by the following copyright and | ||
85 | * permission notice: | ||
86 | * The Synopsys DWC ETHER XGMAC Software Driver and documentation | ||
87 | * (hereinafter "Software") is an unsupported proprietary work of Synopsys, | ||
88 | * Inc. unless otherwise expressly agreed to in writing between Synopsys | ||
89 | * and you. | ||
90 | * | ||
91 | * The Software IS NOT an item of Licensed Software or Licensed Product | ||
92 | * under any End User Software License Agreement or Agreement for Licensed | ||
93 | * Product with Synopsys or any supplement thereto. Permission is hereby | ||
94 | * granted, free of charge, to any person obtaining a copy of this software | ||
95 | * annotated with this license and the Software, to deal in the Software | ||
96 | * without restriction, including without limitation the rights to use, | ||
97 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
98 | * of the Software, and to permit persons to whom the Software is furnished | ||
99 | * to do so, subject to the following conditions: | ||
100 | * | ||
101 | * The above copyright notice and this permission notice shall be included | ||
102 | * in all copies or substantial portions of the Software. | ||
103 | * | ||
104 | * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
105 | * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
106 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
107 | * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS | ||
108 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
109 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
110 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
111 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
112 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
113 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
114 | * THE POSSIBILITY OF SUCH DAMAGE. | ||
115 | */ | ||
116 | |||
117 | #include <linux/module.h> | ||
118 | #include <linux/device.h> | ||
119 | #include <linux/kmod.h> | ||
120 | #include <linux/mdio.h> | ||
121 | #include <linux/phy.h> | ||
122 | |||
123 | #include "xgbe.h" | ||
124 | #include "xgbe-common.h" | ||
125 | |||
126 | #define XGBE_PHY_PORT_SPEED_100 BIT(0) | ||
127 | #define XGBE_PHY_PORT_SPEED_1000 BIT(1) | ||
128 | #define XGBE_PHY_PORT_SPEED_2500 BIT(2) | ||
129 | #define XGBE_PHY_PORT_SPEED_10000 BIT(3) | ||
130 | |||
131 | #define XGBE_MUTEX_RELEASE 0x80000000 | ||
132 | |||
133 | #define XGBE_SFP_DIRECT 7 | ||
134 | |||
135 | /* I2C target addresses */ | ||
136 | #define XGBE_SFP_SERIAL_ID_ADDRESS 0x50 | ||
137 | #define XGBE_SFP_DIAG_INFO_ADDRESS 0x51 | ||
138 | #define XGBE_SFP_PHY_ADDRESS 0x56 | ||
139 | #define XGBE_GPIO_ADDRESS_PCA9555 0x20 | ||
140 | |||
141 | /* SFP sideband signal indicators */ | ||
142 | #define XGBE_GPIO_NO_TX_FAULT BIT(0) | ||
143 | #define XGBE_GPIO_NO_RATE_SELECT BIT(1) | ||
144 | #define XGBE_GPIO_NO_MOD_ABSENT BIT(2) | ||
145 | #define XGBE_GPIO_NO_RX_LOS BIT(3) | ||
146 | |||
147 | /* Rate-change complete wait/retry count */ | ||
148 | #define XGBE_RATECHANGE_COUNT 500 | ||
149 | |||
150 | enum xgbe_port_mode { | ||
151 | XGBE_PORT_MODE_RSVD = 0, | ||
152 | XGBE_PORT_MODE_BACKPLANE, | ||
153 | XGBE_PORT_MODE_BACKPLANE_2500, | ||
154 | XGBE_PORT_MODE_1000BASE_T, | ||
155 | XGBE_PORT_MODE_1000BASE_X, | ||
156 | XGBE_PORT_MODE_NBASE_T, | ||
157 | XGBE_PORT_MODE_10GBASE_T, | ||
158 | XGBE_PORT_MODE_10GBASE_R, | ||
159 | XGBE_PORT_MODE_SFP, | ||
160 | XGBE_PORT_MODE_MAX, | ||
161 | }; | ||
162 | |||
163 | enum xgbe_conn_type { | ||
164 | XGBE_CONN_TYPE_NONE = 0, | ||
165 | XGBE_CONN_TYPE_SFP, | ||
166 | XGBE_CONN_TYPE_MDIO, | ||
167 | XGBE_CONN_TYPE_BACKPLANE, | ||
168 | XGBE_CONN_TYPE_MAX, | ||
169 | }; | ||
170 | |||
171 | /* SFP/SFP+ related definitions */ | ||
172 | enum xgbe_sfp_comm { | ||
173 | XGBE_SFP_COMM_DIRECT = 0, | ||
174 | XGBE_SFP_COMM_PCA9545, | ||
175 | }; | ||
176 | |||
177 | enum xgbe_sfp_cable { | ||
178 | XGBE_SFP_CABLE_UNKNOWN = 0, | ||
179 | XGBE_SFP_CABLE_ACTIVE, | ||
180 | XGBE_SFP_CABLE_PASSIVE, | ||
181 | }; | ||
182 | |||
183 | enum xgbe_sfp_base { | ||
184 | XGBE_SFP_BASE_UNKNOWN = 0, | ||
185 | XGBE_SFP_BASE_1000_T, | ||
186 | XGBE_SFP_BASE_1000_SX, | ||
187 | XGBE_SFP_BASE_1000_LX, | ||
188 | XGBE_SFP_BASE_1000_CX, | ||
189 | XGBE_SFP_BASE_10000_SR, | ||
190 | XGBE_SFP_BASE_10000_LR, | ||
191 | XGBE_SFP_BASE_10000_LRM, | ||
192 | XGBE_SFP_BASE_10000_ER, | ||
193 | XGBE_SFP_BASE_10000_CR, | ||
194 | }; | ||
195 | |||
196 | enum xgbe_sfp_speed { | ||
197 | XGBE_SFP_SPEED_UNKNOWN = 0, | ||
198 | XGBE_SFP_SPEED_100_1000, | ||
199 | XGBE_SFP_SPEED_1000, | ||
200 | XGBE_SFP_SPEED_10000, | ||
201 | }; | ||
202 | |||
203 | /* SFP Serial ID Base ID values relative to an offset of 0 */ | ||
204 | #define XGBE_SFP_BASE_ID 0 | ||
205 | #define XGBE_SFP_ID_SFP 0x03 | ||
206 | |||
207 | #define XGBE_SFP_BASE_EXT_ID 1 | ||
208 | #define XGBE_SFP_EXT_ID_SFP 0x04 | ||
209 | |||
210 | #define XGBE_SFP_BASE_10GBE_CC 3 | ||
211 | #define XGBE_SFP_BASE_10GBE_CC_SR BIT(4) | ||
212 | #define XGBE_SFP_BASE_10GBE_CC_LR BIT(5) | ||
213 | #define XGBE_SFP_BASE_10GBE_CC_LRM BIT(6) | ||
214 | #define XGBE_SFP_BASE_10GBE_CC_ER BIT(7) | ||
215 | |||
216 | #define XGBE_SFP_BASE_1GBE_CC 6 | ||
217 | #define XGBE_SFP_BASE_1GBE_CC_SX BIT(0) | ||
218 | #define XGBE_SFP_BASE_1GBE_CC_LX BIT(1) | ||
219 | #define XGBE_SFP_BASE_1GBE_CC_CX BIT(2) | ||
220 | #define XGBE_SFP_BASE_1GBE_CC_T BIT(3) | ||
221 | |||
222 | #define XGBE_SFP_BASE_CABLE 8 | ||
223 | #define XGBE_SFP_BASE_CABLE_PASSIVE BIT(2) | ||
224 | #define XGBE_SFP_BASE_CABLE_ACTIVE BIT(3) | ||
225 | |||
226 | #define XGBE_SFP_BASE_BR 12 | ||
227 | #define XGBE_SFP_BASE_BR_1GBE_MIN 0x0a | ||
228 | #define XGBE_SFP_BASE_BR_1GBE_MAX 0x0d | ||
229 | #define XGBE_SFP_BASE_BR_10GBE_MIN 0x64 | ||
230 | #define XGBE_SFP_BASE_BR_10GBE_MAX 0x68 | ||
231 | |||
232 | #define XGBE_SFP_BASE_CU_CABLE_LEN 18 | ||
233 | |||
234 | #define XGBE_SFP_BASE_VENDOR_NAME 20 | ||
235 | #define XGBE_SFP_BASE_VENDOR_NAME_LEN 16 | ||
236 | #define XGBE_SFP_BASE_VENDOR_PN 40 | ||
237 | #define XGBE_SFP_BASE_VENDOR_PN_LEN 16 | ||
238 | #define XGBE_SFP_BASE_VENDOR_REV 56 | ||
239 | #define XGBE_SFP_BASE_VENDOR_REV_LEN 4 | ||
240 | |||
241 | #define XGBE_SFP_BASE_CC 63 | ||
242 | |||
243 | /* SFP Serial ID Extended ID values relative to an offset of 64 */ | ||
244 | #define XGBE_SFP_BASE_VENDOR_SN 4 | ||
245 | #define XGBE_SFP_BASE_VENDOR_SN_LEN 16 | ||
246 | |||
247 | #define XGBE_SFP_EXTD_DIAG 28 | ||
248 | #define XGBE_SFP_EXTD_DIAG_ADDR_CHANGE BIT(2) | ||
249 | |||
250 | #define XGBE_SFP_EXTD_SFF_8472 30 | ||
251 | |||
252 | #define XGBE_SFP_EXTD_CC 31 | ||
253 | |||
254 | struct xgbe_sfp_eeprom { | ||
255 | u8 base[64]; | ||
256 | u8 extd[32]; | ||
257 | u8 vendor[32]; | ||
258 | }; | ||
259 | |||
260 | #define XGBE_BEL_FUSE_VENDOR "BEL-FUSE " | ||
261 | #define XGBE_BEL_FUSE_PARTNO "1GBT-SFP06 " | ||
262 | |||
263 | struct xgbe_sfp_ascii { | ||
264 | union { | ||
265 | char vendor[XGBE_SFP_BASE_VENDOR_NAME_LEN + 1]; | ||
266 | char partno[XGBE_SFP_BASE_VENDOR_PN_LEN + 1]; | ||
267 | char rev[XGBE_SFP_BASE_VENDOR_REV_LEN + 1]; | ||
268 | char serno[XGBE_SFP_BASE_VENDOR_SN_LEN + 1]; | ||
269 | } u; | ||
270 | }; | ||
271 | |||
272 | /* MDIO PHY reset types */ | ||
273 | enum xgbe_mdio_reset { | ||
274 | XGBE_MDIO_RESET_NONE = 0, | ||
275 | XGBE_MDIO_RESET_I2C_GPIO, | ||
276 | XGBE_MDIO_RESET_INT_GPIO, | ||
277 | XGBE_MDIO_RESET_MAX, | ||
278 | }; | ||
279 | |||
280 | /* Re-driver related definitions */ | ||
281 | enum xgbe_phy_redrv_if { | ||
282 | XGBE_PHY_REDRV_IF_MDIO = 0, | ||
283 | XGBE_PHY_REDRV_IF_I2C, | ||
284 | XGBE_PHY_REDRV_IF_MAX, | ||
285 | }; | ||
286 | |||
287 | enum xgbe_phy_redrv_model { | ||
288 | XGBE_PHY_REDRV_MODEL_4223 = 0, | ||
289 | XGBE_PHY_REDRV_MODEL_4227, | ||
290 | XGBE_PHY_REDRV_MODEL_MAX, | ||
291 | }; | ||
292 | |||
293 | enum xgbe_phy_redrv_mode { | ||
294 | XGBE_PHY_REDRV_MODE_CX = 5, | ||
295 | XGBE_PHY_REDRV_MODE_SR = 9, | ||
296 | }; | ||
297 | |||
298 | #define XGBE_PHY_REDRV_MODE_REG 0x12b0 | ||
299 | |||
300 | /* PHY related configuration information */ | ||
301 | struct xgbe_phy_data { | ||
302 | enum xgbe_port_mode port_mode; | ||
303 | |||
304 | unsigned int port_id; | ||
305 | |||
306 | unsigned int port_speeds; | ||
307 | |||
308 | enum xgbe_conn_type conn_type; | ||
309 | |||
310 | enum xgbe_mode cur_mode; | ||
311 | enum xgbe_mode start_mode; | ||
312 | |||
313 | unsigned int rrc_count; | ||
314 | |||
315 | unsigned int mdio_addr; | ||
316 | |||
317 | unsigned int comm_owned; | ||
318 | |||
319 | /* SFP Support */ | ||
320 | enum xgbe_sfp_comm sfp_comm; | ||
321 | unsigned int sfp_mux_address; | ||
322 | unsigned int sfp_mux_channel; | ||
323 | |||
324 | unsigned int sfp_gpio_address; | ||
325 | unsigned int sfp_gpio_mask; | ||
326 | unsigned int sfp_gpio_rx_los; | ||
327 | unsigned int sfp_gpio_tx_fault; | ||
328 | unsigned int sfp_gpio_mod_absent; | ||
329 | unsigned int sfp_gpio_rate_select; | ||
330 | |||
331 | unsigned int sfp_rx_los; | ||
332 | unsigned int sfp_tx_fault; | ||
333 | unsigned int sfp_mod_absent; | ||
334 | unsigned int sfp_diags; | ||
335 | unsigned int sfp_changed; | ||
336 | unsigned int sfp_phy_avail; | ||
337 | unsigned int sfp_cable_len; | ||
338 | enum xgbe_sfp_base sfp_base; | ||
339 | enum xgbe_sfp_cable sfp_cable; | ||
340 | enum xgbe_sfp_speed sfp_speed; | ||
341 | struct xgbe_sfp_eeprom sfp_eeprom; | ||
342 | |||
343 | /* External PHY support */ | ||
344 | enum xgbe_mdio_mode phydev_mode; | ||
345 | struct mii_bus *mii; | ||
346 | struct phy_device *phydev; | ||
347 | enum xgbe_mdio_reset mdio_reset; | ||
348 | unsigned int mdio_reset_addr; | ||
349 | unsigned int mdio_reset_gpio; | ||
350 | |||
351 | /* Re-driver support */ | ||
352 | unsigned int redrv; | ||
353 | unsigned int redrv_if; | ||
354 | unsigned int redrv_addr; | ||
355 | unsigned int redrv_lane; | ||
356 | unsigned int redrv_model; | ||
357 | }; | ||
358 | |||
359 | /* I2C, MDIO and GPIO lines are muxed, so only one device at a time */ | ||
360 | static DEFINE_MUTEX(xgbe_phy_comm_lock); | ||
361 | |||
362 | static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata); | ||
363 | |||
364 | static int xgbe_phy_i2c_xfer(struct xgbe_prv_data *pdata, | ||
365 | struct xgbe_i2c_op *i2c_op) | ||
366 | { | ||
367 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
368 | |||
369 | /* Be sure we own the bus */ | ||
370 | if (WARN_ON(!phy_data->comm_owned)) | ||
371 | return -EIO; | ||
372 | |||
373 | return pdata->i2c_if.i2c_xfer(pdata, i2c_op); | ||
374 | } | ||
375 | |||
376 | static int xgbe_phy_redrv_write(struct xgbe_prv_data *pdata, unsigned int reg, | ||
377 | unsigned int val) | ||
378 | { | ||
379 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
380 | struct xgbe_i2c_op i2c_op; | ||
381 | __be16 *redrv_val; | ||
382 | u8 redrv_data[5], csum; | ||
383 | unsigned int i, retry; | ||
384 | int ret; | ||
385 | |||
386 | /* High byte of register contains read/write indicator */ | ||
387 | redrv_data[0] = ((reg >> 8) & 0xff) << 1; | ||
388 | redrv_data[1] = reg & 0xff; | ||
389 | redrv_val = (__be16 *)&redrv_data[2]; | ||
390 | *redrv_val = cpu_to_be16(val); | ||
391 | |||
392 | /* Calculate 1 byte checksum */ | ||
393 | csum = 0; | ||
394 | for (i = 0; i < 4; i++) { | ||
395 | csum += redrv_data[i]; | ||
396 | if (redrv_data[i] > csum) | ||
397 | csum++; | ||
398 | } | ||
399 | redrv_data[4] = ~csum; | ||
400 | |||
401 | retry = 1; | ||
402 | again1: | ||
403 | i2c_op.cmd = XGBE_I2C_CMD_WRITE; | ||
404 | i2c_op.target = phy_data->redrv_addr; | ||
405 | i2c_op.len = sizeof(redrv_data); | ||
406 | i2c_op.buf = redrv_data; | ||
407 | ret = xgbe_phy_i2c_xfer(pdata, &i2c_op); | ||
408 | if (ret) { | ||
409 | if ((ret == -EAGAIN) && retry--) | ||
410 | goto again1; | ||
411 | |||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | retry = 1; | ||
416 | again2: | ||
417 | i2c_op.cmd = XGBE_I2C_CMD_READ; | ||
418 | i2c_op.target = phy_data->redrv_addr; | ||
419 | i2c_op.len = 1; | ||
420 | i2c_op.buf = redrv_data; | ||
421 | ret = xgbe_phy_i2c_xfer(pdata, &i2c_op); | ||
422 | if (ret) { | ||
423 | if ((ret == -EAGAIN) && retry--) | ||
424 | goto again2; | ||
425 | |||
426 | return ret; | ||
427 | } | ||
428 | |||
429 | if (redrv_data[0] != 0xff) { | ||
430 | netif_dbg(pdata, drv, pdata->netdev, | ||
431 | "Redriver write checksum error\n"); | ||
432 | ret = -EIO; | ||
433 | } | ||
434 | |||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | static int xgbe_phy_i2c_write(struct xgbe_prv_data *pdata, unsigned int target, | ||
439 | void *val, unsigned int val_len) | ||
440 | { | ||
441 | struct xgbe_i2c_op i2c_op; | ||
442 | int retry, ret; | ||
443 | |||
444 | retry = 1; | ||
445 | again: | ||
446 | /* Write the specfied register */ | ||
447 | i2c_op.cmd = XGBE_I2C_CMD_WRITE; | ||
448 | i2c_op.target = target; | ||
449 | i2c_op.len = val_len; | ||
450 | i2c_op.buf = val; | ||
451 | ret = xgbe_phy_i2c_xfer(pdata, &i2c_op); | ||
452 | if ((ret == -EAGAIN) && retry--) | ||
453 | goto again; | ||
454 | |||
455 | return ret; | ||
456 | } | ||
457 | |||
458 | static int xgbe_phy_i2c_read(struct xgbe_prv_data *pdata, unsigned int target, | ||
459 | void *reg, unsigned int reg_len, | ||
460 | void *val, unsigned int val_len) | ||
461 | { | ||
462 | struct xgbe_i2c_op i2c_op; | ||
463 | int retry, ret; | ||
464 | |||
465 | retry = 1; | ||
466 | again1: | ||
467 | /* Set the specified register to read */ | ||
468 | i2c_op.cmd = XGBE_I2C_CMD_WRITE; | ||
469 | i2c_op.target = target; | ||
470 | i2c_op.len = reg_len; | ||
471 | i2c_op.buf = reg; | ||
472 | ret = xgbe_phy_i2c_xfer(pdata, &i2c_op); | ||
473 | if (ret) { | ||
474 | if ((ret == -EAGAIN) && retry--) | ||
475 | goto again1; | ||
476 | |||
477 | return ret; | ||
478 | } | ||
479 | |||
480 | retry = 1; | ||
481 | again2: | ||
482 | /* Read the specfied register */ | ||
483 | i2c_op.cmd = XGBE_I2C_CMD_READ; | ||
484 | i2c_op.target = target; | ||
485 | i2c_op.len = val_len; | ||
486 | i2c_op.buf = val; | ||
487 | ret = xgbe_phy_i2c_xfer(pdata, &i2c_op); | ||
488 | if ((ret == -EAGAIN) && retry--) | ||
489 | goto again2; | ||
490 | |||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | static int xgbe_phy_sfp_put_mux(struct xgbe_prv_data *pdata) | ||
495 | { | ||
496 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
497 | struct xgbe_i2c_op i2c_op; | ||
498 | u8 mux_channel; | ||
499 | |||
500 | if (phy_data->sfp_comm == XGBE_SFP_COMM_DIRECT) | ||
501 | return 0; | ||
502 | |||
503 | /* Select no mux channels */ | ||
504 | mux_channel = 0; | ||
505 | i2c_op.cmd = XGBE_I2C_CMD_WRITE; | ||
506 | i2c_op.target = phy_data->sfp_mux_address; | ||
507 | i2c_op.len = sizeof(mux_channel); | ||
508 | i2c_op.buf = &mux_channel; | ||
509 | |||
510 | return xgbe_phy_i2c_xfer(pdata, &i2c_op); | ||
511 | } | ||
512 | |||
513 | static int xgbe_phy_sfp_get_mux(struct xgbe_prv_data *pdata) | ||
514 | { | ||
515 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
516 | struct xgbe_i2c_op i2c_op; | ||
517 | u8 mux_channel; | ||
518 | |||
519 | if (phy_data->sfp_comm == XGBE_SFP_COMM_DIRECT) | ||
520 | return 0; | ||
521 | |||
522 | /* Select desired mux channel */ | ||
523 | mux_channel = 1 << phy_data->sfp_mux_channel; | ||
524 | i2c_op.cmd = XGBE_I2C_CMD_WRITE; | ||
525 | i2c_op.target = phy_data->sfp_mux_address; | ||
526 | i2c_op.len = sizeof(mux_channel); | ||
527 | i2c_op.buf = &mux_channel; | ||
528 | |||
529 | return xgbe_phy_i2c_xfer(pdata, &i2c_op); | ||
530 | } | ||
531 | |||
532 | static void xgbe_phy_put_comm_ownership(struct xgbe_prv_data *pdata) | ||
533 | { | ||
534 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
535 | |||
536 | phy_data->comm_owned = 0; | ||
537 | |||
538 | mutex_unlock(&xgbe_phy_comm_lock); | ||
539 | } | ||
540 | |||
541 | static int xgbe_phy_get_comm_ownership(struct xgbe_prv_data *pdata) | ||
542 | { | ||
543 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
544 | unsigned long timeout; | ||
545 | unsigned int mutex_id; | ||
546 | |||
547 | if (phy_data->comm_owned) | ||
548 | return 0; | ||
549 | |||
550 | /* The I2C and MDIO/GPIO bus is multiplexed between multiple devices, | ||
551 | * the driver needs to take the software mutex and then the hardware | ||
552 | * mutexes before being able to use the busses. | ||
553 | */ | ||
554 | mutex_lock(&xgbe_phy_comm_lock); | ||
555 | |||
556 | /* Clear the mutexes */ | ||
557 | XP_IOWRITE(pdata, XP_I2C_MUTEX, XGBE_MUTEX_RELEASE); | ||
558 | XP_IOWRITE(pdata, XP_MDIO_MUTEX, XGBE_MUTEX_RELEASE); | ||
559 | |||
560 | /* Mutex formats are the same for I2C and MDIO/GPIO */ | ||
561 | mutex_id = 0; | ||
562 | XP_SET_BITS(mutex_id, XP_I2C_MUTEX, ID, phy_data->port_id); | ||
563 | XP_SET_BITS(mutex_id, XP_I2C_MUTEX, ACTIVE, 1); | ||
564 | |||
565 | timeout = jiffies + (5 * HZ); | ||
566 | while (time_before(jiffies, timeout)) { | ||
567 | /* Must be all zeroes in order to obtain the mutex */ | ||
568 | if (XP_IOREAD(pdata, XP_I2C_MUTEX) || | ||
569 | XP_IOREAD(pdata, XP_MDIO_MUTEX)) { | ||
570 | usleep_range(100, 200); | ||
571 | continue; | ||
572 | } | ||
573 | |||
574 | /* Obtain the mutex */ | ||
575 | XP_IOWRITE(pdata, XP_I2C_MUTEX, mutex_id); | ||
576 | XP_IOWRITE(pdata, XP_MDIO_MUTEX, mutex_id); | ||
577 | |||
578 | phy_data->comm_owned = 1; | ||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | mutex_unlock(&xgbe_phy_comm_lock); | ||
583 | |||
584 | netdev_err(pdata->netdev, "unable to obtain hardware mutexes\n"); | ||
585 | |||
586 | return -ETIMEDOUT; | ||
587 | } | ||
588 | |||
589 | static int xgbe_phy_mdio_mii_write(struct xgbe_prv_data *pdata, int addr, | ||
590 | int reg, u16 val) | ||
591 | { | ||
592 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
593 | |||
594 | if (reg & MII_ADDR_C45) { | ||
595 | if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL45) | ||
596 | return -ENOTSUPP; | ||
597 | } else { | ||
598 | if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL22) | ||
599 | return -ENOTSUPP; | ||
600 | } | ||
601 | |||
602 | return pdata->hw_if.write_ext_mii_regs(pdata, addr, reg, val); | ||
603 | } | ||
604 | |||
605 | static int xgbe_phy_i2c_mii_write(struct xgbe_prv_data *pdata, int reg, u16 val) | ||
606 | { | ||
607 | __be16 *mii_val; | ||
608 | u8 mii_data[3]; | ||
609 | int ret; | ||
610 | |||
611 | ret = xgbe_phy_sfp_get_mux(pdata); | ||
612 | if (ret) | ||
613 | return ret; | ||
614 | |||
615 | mii_data[0] = reg & 0xff; | ||
616 | mii_val = (__be16 *)&mii_data[1]; | ||
617 | *mii_val = cpu_to_be16(val); | ||
618 | |||
619 | ret = xgbe_phy_i2c_write(pdata, XGBE_SFP_PHY_ADDRESS, | ||
620 | mii_data, sizeof(mii_data)); | ||
621 | |||
622 | xgbe_phy_sfp_put_mux(pdata); | ||
623 | |||
624 | return ret; | ||
625 | } | ||
626 | |||
627 | static int xgbe_phy_mii_write(struct mii_bus *mii, int addr, int reg, u16 val) | ||
628 | { | ||
629 | struct xgbe_prv_data *pdata = mii->priv; | ||
630 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
631 | int ret; | ||
632 | |||
633 | ret = xgbe_phy_get_comm_ownership(pdata); | ||
634 | if (ret) | ||
635 | return ret; | ||
636 | |||
637 | if (phy_data->conn_type == XGBE_CONN_TYPE_SFP) | ||
638 | ret = xgbe_phy_i2c_mii_write(pdata, reg, val); | ||
639 | else if (phy_data->conn_type & XGBE_CONN_TYPE_MDIO) | ||
640 | ret = xgbe_phy_mdio_mii_write(pdata, addr, reg, val); | ||
641 | else | ||
642 | ret = -ENOTSUPP; | ||
643 | |||
644 | xgbe_phy_put_comm_ownership(pdata); | ||
645 | |||
646 | return ret; | ||
647 | } | ||
648 | |||
649 | static int xgbe_phy_mdio_mii_read(struct xgbe_prv_data *pdata, int addr, | ||
650 | int reg) | ||
651 | { | ||
652 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
653 | |||
654 | if (reg & MII_ADDR_C45) { | ||
655 | if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL45) | ||
656 | return -ENOTSUPP; | ||
657 | } else { | ||
658 | if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL22) | ||
659 | return -ENOTSUPP; | ||
660 | } | ||
661 | |||
662 | return pdata->hw_if.read_ext_mii_regs(pdata, addr, reg); | ||
663 | } | ||
664 | |||
665 | static int xgbe_phy_i2c_mii_read(struct xgbe_prv_data *pdata, int reg) | ||
666 | { | ||
667 | __be16 mii_val; | ||
668 | u8 mii_reg; | ||
669 | int ret; | ||
670 | |||
671 | ret = xgbe_phy_sfp_get_mux(pdata); | ||
672 | if (ret) | ||
673 | return ret; | ||
674 | |||
675 | mii_reg = reg; | ||
676 | ret = xgbe_phy_i2c_read(pdata, XGBE_SFP_PHY_ADDRESS, | ||
677 | &mii_reg, sizeof(mii_reg), | ||
678 | &mii_val, sizeof(mii_val)); | ||
679 | if (!ret) | ||
680 | ret = be16_to_cpu(mii_val); | ||
681 | |||
682 | xgbe_phy_sfp_put_mux(pdata); | ||
683 | |||
684 | return ret; | ||
685 | } | ||
686 | |||
687 | static int xgbe_phy_mii_read(struct mii_bus *mii, int addr, int reg) | ||
688 | { | ||
689 | struct xgbe_prv_data *pdata = mii->priv; | ||
690 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
691 | int ret; | ||
692 | |||
693 | ret = xgbe_phy_get_comm_ownership(pdata); | ||
694 | if (ret) | ||
695 | return ret; | ||
696 | |||
697 | if (phy_data->conn_type == XGBE_CONN_TYPE_SFP) | ||
698 | ret = xgbe_phy_i2c_mii_read(pdata, reg); | ||
699 | else if (phy_data->conn_type & XGBE_CONN_TYPE_MDIO) | ||
700 | ret = xgbe_phy_mdio_mii_read(pdata, addr, reg); | ||
701 | else | ||
702 | ret = -ENOTSUPP; | ||
703 | |||
704 | xgbe_phy_put_comm_ownership(pdata); | ||
705 | |||
706 | return ret; | ||
707 | } | ||
708 | |||
709 | static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata) | ||
710 | { | ||
711 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
712 | |||
713 | if (phy_data->sfp_mod_absent) { | ||
714 | pdata->phy.speed = SPEED_UNKNOWN; | ||
715 | pdata->phy.duplex = DUPLEX_UNKNOWN; | ||
716 | pdata->phy.autoneg = AUTONEG_ENABLE; | ||
717 | pdata->phy.advertising = pdata->phy.supported; | ||
718 | } | ||
719 | |||
720 | pdata->phy.advertising &= ~ADVERTISED_Autoneg; | ||
721 | pdata->phy.advertising &= ~ADVERTISED_TP; | ||
722 | pdata->phy.advertising &= ~ADVERTISED_FIBRE; | ||
723 | pdata->phy.advertising &= ~ADVERTISED_100baseT_Full; | ||
724 | pdata->phy.advertising &= ~ADVERTISED_1000baseT_Full; | ||
725 | pdata->phy.advertising &= ~ADVERTISED_10000baseT_Full; | ||
726 | pdata->phy.advertising &= ~ADVERTISED_10000baseR_FEC; | ||
727 | |||
728 | switch (phy_data->sfp_base) { | ||
729 | case XGBE_SFP_BASE_1000_T: | ||
730 | case XGBE_SFP_BASE_1000_SX: | ||
731 | case XGBE_SFP_BASE_1000_LX: | ||
732 | case XGBE_SFP_BASE_1000_CX: | ||
733 | pdata->phy.speed = SPEED_UNKNOWN; | ||
734 | pdata->phy.duplex = DUPLEX_UNKNOWN; | ||
735 | pdata->phy.autoneg = AUTONEG_ENABLE; | ||
736 | pdata->phy.advertising |= ADVERTISED_Autoneg; | ||
737 | break; | ||
738 | case XGBE_SFP_BASE_10000_SR: | ||
739 | case XGBE_SFP_BASE_10000_LR: | ||
740 | case XGBE_SFP_BASE_10000_LRM: | ||
741 | case XGBE_SFP_BASE_10000_ER: | ||
742 | case XGBE_SFP_BASE_10000_CR: | ||
743 | default: | ||
744 | pdata->phy.speed = SPEED_10000; | ||
745 | pdata->phy.duplex = DUPLEX_FULL; | ||
746 | pdata->phy.autoneg = AUTONEG_DISABLE; | ||
747 | break; | ||
748 | } | ||
749 | |||
750 | switch (phy_data->sfp_base) { | ||
751 | case XGBE_SFP_BASE_1000_T: | ||
752 | case XGBE_SFP_BASE_1000_CX: | ||
753 | case XGBE_SFP_BASE_10000_CR: | ||
754 | pdata->phy.advertising |= ADVERTISED_TP; | ||
755 | break; | ||
756 | default: | ||
757 | pdata->phy.advertising |= ADVERTISED_FIBRE; | ||
758 | } | ||
759 | |||
760 | switch (phy_data->sfp_speed) { | ||
761 | case XGBE_SFP_SPEED_100_1000: | ||
762 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) | ||
763 | pdata->phy.advertising |= ADVERTISED_100baseT_Full; | ||
764 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) | ||
765 | pdata->phy.advertising |= ADVERTISED_1000baseT_Full; | ||
766 | break; | ||
767 | case XGBE_SFP_SPEED_1000: | ||
768 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) | ||
769 | pdata->phy.advertising |= ADVERTISED_1000baseT_Full; | ||
770 | break; | ||
771 | case XGBE_SFP_SPEED_10000: | ||
772 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) | ||
773 | pdata->phy.advertising |= ADVERTISED_10000baseT_Full; | ||
774 | break; | ||
775 | default: | ||
776 | /* Choose the fastest supported speed */ | ||
777 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) | ||
778 | pdata->phy.advertising |= ADVERTISED_10000baseT_Full; | ||
779 | else if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) | ||
780 | pdata->phy.advertising |= ADVERTISED_1000baseT_Full; | ||
781 | else if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) | ||
782 | pdata->phy.advertising |= ADVERTISED_100baseT_Full; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom, | ||
787 | enum xgbe_sfp_speed sfp_speed) | ||
788 | { | ||
789 | u8 *sfp_base, min, max; | ||
790 | |||
791 | sfp_base = sfp_eeprom->base; | ||
792 | |||
793 | switch (sfp_speed) { | ||
794 | case XGBE_SFP_SPEED_1000: | ||
795 | min = XGBE_SFP_BASE_BR_1GBE_MIN; | ||
796 | max = XGBE_SFP_BASE_BR_1GBE_MAX; | ||
797 | break; | ||
798 | case XGBE_SFP_SPEED_10000: | ||
799 | min = XGBE_SFP_BASE_BR_10GBE_MIN; | ||
800 | max = XGBE_SFP_BASE_BR_10GBE_MAX; | ||
801 | break; | ||
802 | default: | ||
803 | return false; | ||
804 | } | ||
805 | |||
806 | return ((sfp_base[XGBE_SFP_BASE_BR] >= min) && | ||
807 | (sfp_base[XGBE_SFP_BASE_BR] <= max)); | ||
808 | } | ||
809 | |||
810 | static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata) | ||
811 | { | ||
812 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
813 | |||
814 | if (phy_data->phydev) { | ||
815 | phy_detach(phy_data->phydev); | ||
816 | phy_device_remove(phy_data->phydev); | ||
817 | phy_device_free(phy_data->phydev); | ||
818 | phy_data->phydev = NULL; | ||
819 | } | ||
820 | } | ||
821 | |||
822 | static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) | ||
823 | { | ||
824 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
825 | unsigned int phy_id = phy_data->phydev->phy_id; | ||
826 | |||
827 | if ((phy_id & 0xfffffff0) != 0x01ff0cc0) | ||
828 | return false; | ||
829 | |||
830 | /* Enable Base-T AN */ | ||
831 | phy_write(phy_data->phydev, 0x16, 0x0001); | ||
832 | phy_write(phy_data->phydev, 0x00, 0x9140); | ||
833 | phy_write(phy_data->phydev, 0x16, 0x0000); | ||
834 | |||
835 | /* Enable SGMII at 100Base-T/1000Base-T Full Duplex */ | ||
836 | phy_write(phy_data->phydev, 0x1b, 0x9084); | ||
837 | phy_write(phy_data->phydev, 0x09, 0x0e00); | ||
838 | phy_write(phy_data->phydev, 0x00, 0x8140); | ||
839 | phy_write(phy_data->phydev, 0x04, 0x0d01); | ||
840 | phy_write(phy_data->phydev, 0x00, 0x9140); | ||
841 | |||
842 | phy_data->phydev->supported = PHY_GBIT_FEATURES; | ||
843 | phy_data->phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
844 | phy_data->phydev->advertising = phy_data->phydev->supported; | ||
845 | |||
846 | netif_dbg(pdata, drv, pdata->netdev, | ||
847 | "Finisar PHY quirk in place\n"); | ||
848 | |||
849 | return true; | ||
850 | } | ||
851 | |||
852 | static void xgbe_phy_external_phy_quirks(struct xgbe_prv_data *pdata) | ||
853 | { | ||
854 | if (xgbe_phy_finisar_phy_quirks(pdata)) | ||
855 | return; | ||
856 | } | ||
857 | |||
858 | static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata) | ||
859 | { | ||
860 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
861 | struct phy_device *phydev; | ||
862 | int ret; | ||
863 | |||
864 | /* If we already have a PHY, just return */ | ||
865 | if (phy_data->phydev) | ||
866 | return 0; | ||
867 | |||
868 | /* Check for the use of an external PHY */ | ||
869 | if (phy_data->phydev_mode == XGBE_MDIO_MODE_NONE) | ||
870 | return 0; | ||
871 | |||
872 | /* For SFP, only use an external PHY if available */ | ||
873 | if ((phy_data->port_mode == XGBE_PORT_MODE_SFP) && | ||
874 | !phy_data->sfp_phy_avail) | ||
875 | return 0; | ||
876 | |||
877 | /* Create and connect to the PHY device */ | ||
878 | phydev = get_phy_device(phy_data->mii, phy_data->mdio_addr, | ||
879 | (phy_data->phydev_mode == XGBE_MDIO_MODE_CL45)); | ||
880 | if (IS_ERR(phydev)) { | ||
881 | netdev_err(pdata->netdev, "get_phy_device failed\n"); | ||
882 | return -ENODEV; | ||
883 | } | ||
884 | netif_dbg(pdata, drv, pdata->netdev, "external PHY id is %#010x\n", | ||
885 | phydev->phy_id); | ||
886 | |||
887 | /*TODO: If c45, add request_module based on one of the MMD ids? */ | ||
888 | |||
889 | ret = phy_device_register(phydev); | ||
890 | if (ret) { | ||
891 | netdev_err(pdata->netdev, "phy_device_register failed\n"); | ||
892 | phy_device_free(phydev); | ||
893 | return ret; | ||
894 | } | ||
895 | |||
896 | ret = phy_attach_direct(pdata->netdev, phydev, phydev->dev_flags, | ||
897 | PHY_INTERFACE_MODE_SGMII); | ||
898 | if (ret) { | ||
899 | netdev_err(pdata->netdev, "phy_attach_direct failed\n"); | ||
900 | phy_device_remove(phydev); | ||
901 | phy_device_free(phydev); | ||
902 | return ret; | ||
903 | } | ||
904 | phy_data->phydev = phydev; | ||
905 | |||
906 | xgbe_phy_external_phy_quirks(pdata); | ||
907 | phydev->advertising &= pdata->phy.advertising; | ||
908 | |||
909 | phy_start_aneg(phy_data->phydev); | ||
910 | |||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static void xgbe_phy_sfp_external_phy(struct xgbe_prv_data *pdata) | ||
915 | { | ||
916 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
917 | int ret; | ||
918 | |||
919 | if (!phy_data->sfp_changed) | ||
920 | return; | ||
921 | |||
922 | phy_data->sfp_phy_avail = 0; | ||
923 | |||
924 | if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T) | ||
925 | return; | ||
926 | |||
927 | /* Check access to the PHY by reading CTRL1 */ | ||
928 | ret = xgbe_phy_i2c_mii_read(pdata, MII_BMCR); | ||
929 | if (ret < 0) | ||
930 | return; | ||
931 | |||
932 | /* Successfully accessed the PHY */ | ||
933 | phy_data->sfp_phy_avail = 1; | ||
934 | } | ||
935 | |||
936 | static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata) | ||
937 | { | ||
938 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
939 | struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom; | ||
940 | |||
941 | if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME], | ||
942 | XGBE_BEL_FUSE_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN)) | ||
943 | return false; | ||
944 | |||
945 | if (!memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_PN], | ||
946 | XGBE_BEL_FUSE_PARTNO, XGBE_SFP_BASE_VENDOR_PN_LEN)) { | ||
947 | phy_data->sfp_base = XGBE_SFP_BASE_1000_SX; | ||
948 | phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE; | ||
949 | phy_data->sfp_speed = XGBE_SFP_SPEED_1000; | ||
950 | if (phy_data->sfp_changed) | ||
951 | netif_dbg(pdata, drv, pdata->netdev, | ||
952 | "Bel-Fuse SFP quirk in place\n"); | ||
953 | return true; | ||
954 | } | ||
955 | |||
956 | return false; | ||
957 | } | ||
958 | |||
959 | static bool xgbe_phy_sfp_parse_quirks(struct xgbe_prv_data *pdata) | ||
960 | { | ||
961 | if (xgbe_phy_belfuse_parse_quirks(pdata)) | ||
962 | return true; | ||
963 | |||
964 | return false; | ||
965 | } | ||
966 | |||
967 | static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata) | ||
968 | { | ||
969 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
970 | struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom; | ||
971 | u8 *sfp_base; | ||
972 | |||
973 | sfp_base = sfp_eeprom->base; | ||
974 | |||
975 | if (sfp_base[XGBE_SFP_BASE_ID] != XGBE_SFP_ID_SFP) | ||
976 | return; | ||
977 | |||
978 | if (sfp_base[XGBE_SFP_BASE_EXT_ID] != XGBE_SFP_EXT_ID_SFP) | ||
979 | return; | ||
980 | |||
981 | if (xgbe_phy_sfp_parse_quirks(pdata)) | ||
982 | return; | ||
983 | |||
984 | /* Assume ACTIVE cable unless told it is PASSIVE */ | ||
985 | if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_PASSIVE) { | ||
986 | phy_data->sfp_cable = XGBE_SFP_CABLE_PASSIVE; | ||
987 | phy_data->sfp_cable_len = sfp_base[XGBE_SFP_BASE_CU_CABLE_LEN]; | ||
988 | } else { | ||
989 | phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE; | ||
990 | } | ||
991 | |||
992 | /* Determine the type of SFP */ | ||
993 | if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR) | ||
994 | phy_data->sfp_base = XGBE_SFP_BASE_10000_SR; | ||
995 | else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LR) | ||
996 | phy_data->sfp_base = XGBE_SFP_BASE_10000_LR; | ||
997 | else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LRM) | ||
998 | phy_data->sfp_base = XGBE_SFP_BASE_10000_LRM; | ||
999 | else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_ER) | ||
1000 | phy_data->sfp_base = XGBE_SFP_BASE_10000_ER; | ||
1001 | else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_SX) | ||
1002 | phy_data->sfp_base = XGBE_SFP_BASE_1000_SX; | ||
1003 | else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_LX) | ||
1004 | phy_data->sfp_base = XGBE_SFP_BASE_1000_LX; | ||
1005 | else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_CX) | ||
1006 | phy_data->sfp_base = XGBE_SFP_BASE_1000_CX; | ||
1007 | else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_T) | ||
1008 | phy_data->sfp_base = XGBE_SFP_BASE_1000_T; | ||
1009 | else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) && | ||
1010 | xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000)) | ||
1011 | phy_data->sfp_base = XGBE_SFP_BASE_10000_CR; | ||
1012 | |||
1013 | switch (phy_data->sfp_base) { | ||
1014 | case XGBE_SFP_BASE_1000_T: | ||
1015 | phy_data->sfp_speed = XGBE_SFP_SPEED_100_1000; | ||
1016 | break; | ||
1017 | case XGBE_SFP_BASE_1000_SX: | ||
1018 | case XGBE_SFP_BASE_1000_LX: | ||
1019 | case XGBE_SFP_BASE_1000_CX: | ||
1020 | phy_data->sfp_speed = XGBE_SFP_SPEED_1000; | ||
1021 | break; | ||
1022 | case XGBE_SFP_BASE_10000_SR: | ||
1023 | case XGBE_SFP_BASE_10000_LR: | ||
1024 | case XGBE_SFP_BASE_10000_LRM: | ||
1025 | case XGBE_SFP_BASE_10000_ER: | ||
1026 | case XGBE_SFP_BASE_10000_CR: | ||
1027 | phy_data->sfp_speed = XGBE_SFP_SPEED_10000; | ||
1028 | break; | ||
1029 | default: | ||
1030 | break; | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | static void xgbe_phy_sfp_eeprom_info(struct xgbe_prv_data *pdata, | ||
1035 | struct xgbe_sfp_eeprom *sfp_eeprom) | ||
1036 | { | ||
1037 | struct xgbe_sfp_ascii sfp_ascii; | ||
1038 | char *sfp_data = (char *)&sfp_ascii; | ||
1039 | |||
1040 | netif_dbg(pdata, drv, pdata->netdev, "SFP detected:\n"); | ||
1041 | memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME], | ||
1042 | XGBE_SFP_BASE_VENDOR_NAME_LEN); | ||
1043 | sfp_data[XGBE_SFP_BASE_VENDOR_NAME_LEN] = '\0'; | ||
1044 | netif_dbg(pdata, drv, pdata->netdev, " vendor: %s\n", | ||
1045 | sfp_data); | ||
1046 | |||
1047 | memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_PN], | ||
1048 | XGBE_SFP_BASE_VENDOR_PN_LEN); | ||
1049 | sfp_data[XGBE_SFP_BASE_VENDOR_PN_LEN] = '\0'; | ||
1050 | netif_dbg(pdata, drv, pdata->netdev, " part number: %s\n", | ||
1051 | sfp_data); | ||
1052 | |||
1053 | memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_REV], | ||
1054 | XGBE_SFP_BASE_VENDOR_REV_LEN); | ||
1055 | sfp_data[XGBE_SFP_BASE_VENDOR_REV_LEN] = '\0'; | ||
1056 | netif_dbg(pdata, drv, pdata->netdev, " revision level: %s\n", | ||
1057 | sfp_data); | ||
1058 | |||
1059 | memcpy(sfp_data, &sfp_eeprom->extd[XGBE_SFP_BASE_VENDOR_SN], | ||
1060 | XGBE_SFP_BASE_VENDOR_SN_LEN); | ||
1061 | sfp_data[XGBE_SFP_BASE_VENDOR_SN_LEN] = '\0'; | ||
1062 | netif_dbg(pdata, drv, pdata->netdev, " serial number: %s\n", | ||
1063 | sfp_data); | ||
1064 | } | ||
1065 | |||
1066 | static bool xgbe_phy_sfp_verify_eeprom(u8 cc_in, u8 *buf, unsigned int len) | ||
1067 | { | ||
1068 | u8 cc; | ||
1069 | |||
1070 | for (cc = 0; len; buf++, len--) | ||
1071 | cc += *buf; | ||
1072 | |||
1073 | return (cc == cc_in) ? true : false; | ||
1074 | } | ||
1075 | |||
1076 | static int xgbe_phy_sfp_read_eeprom(struct xgbe_prv_data *pdata) | ||
1077 | { | ||
1078 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1079 | struct xgbe_sfp_eeprom sfp_eeprom; | ||
1080 | u8 eeprom_addr; | ||
1081 | int ret; | ||
1082 | |||
1083 | ret = xgbe_phy_sfp_get_mux(pdata); | ||
1084 | if (ret) { | ||
1085 | netdev_err(pdata->netdev, "I2C error setting SFP MUX\n"); | ||
1086 | return ret; | ||
1087 | } | ||
1088 | |||
1089 | /* Read the SFP serial ID eeprom */ | ||
1090 | eeprom_addr = 0; | ||
1091 | ret = xgbe_phy_i2c_read(pdata, XGBE_SFP_SERIAL_ID_ADDRESS, | ||
1092 | &eeprom_addr, sizeof(eeprom_addr), | ||
1093 | &sfp_eeprom, sizeof(sfp_eeprom)); | ||
1094 | if (ret) { | ||
1095 | netdev_err(pdata->netdev, "I2C error reading SFP EEPROM\n"); | ||
1096 | goto put; | ||
1097 | } | ||
1098 | |||
1099 | /* Validate the contents read */ | ||
1100 | if (!xgbe_phy_sfp_verify_eeprom(sfp_eeprom.base[XGBE_SFP_BASE_CC], | ||
1101 | sfp_eeprom.base, | ||
1102 | sizeof(sfp_eeprom.base) - 1)) { | ||
1103 | ret = -EINVAL; | ||
1104 | goto put; | ||
1105 | } | ||
1106 | |||
1107 | if (!xgbe_phy_sfp_verify_eeprom(sfp_eeprom.extd[XGBE_SFP_EXTD_CC], | ||
1108 | sfp_eeprom.extd, | ||
1109 | sizeof(sfp_eeprom.extd) - 1)) { | ||
1110 | ret = -EINVAL; | ||
1111 | goto put; | ||
1112 | } | ||
1113 | |||
1114 | /* Check for an added or changed SFP */ | ||
1115 | if (memcmp(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom))) { | ||
1116 | phy_data->sfp_changed = 1; | ||
1117 | |||
1118 | if (netif_msg_drv(pdata)) | ||
1119 | xgbe_phy_sfp_eeprom_info(pdata, &sfp_eeprom); | ||
1120 | |||
1121 | memcpy(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom)); | ||
1122 | |||
1123 | if (sfp_eeprom.extd[XGBE_SFP_EXTD_SFF_8472]) { | ||
1124 | u8 diag_type = sfp_eeprom.extd[XGBE_SFP_EXTD_DIAG]; | ||
1125 | |||
1126 | if (!(diag_type & XGBE_SFP_EXTD_DIAG_ADDR_CHANGE)) | ||
1127 | phy_data->sfp_diags = 1; | ||
1128 | } | ||
1129 | |||
1130 | xgbe_phy_free_phy_device(pdata); | ||
1131 | } else { | ||
1132 | phy_data->sfp_changed = 0; | ||
1133 | } | ||
1134 | |||
1135 | put: | ||
1136 | xgbe_phy_sfp_put_mux(pdata); | ||
1137 | |||
1138 | return ret; | ||
1139 | } | ||
1140 | |||
1141 | static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata) | ||
1142 | { | ||
1143 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1144 | unsigned int gpio_input; | ||
1145 | u8 gpio_reg, gpio_ports[2]; | ||
1146 | int ret; | ||
1147 | |||
1148 | /* Read the input port registers */ | ||
1149 | gpio_reg = 0; | ||
1150 | ret = xgbe_phy_i2c_read(pdata, phy_data->sfp_gpio_address, | ||
1151 | &gpio_reg, sizeof(gpio_reg), | ||
1152 | gpio_ports, sizeof(gpio_ports)); | ||
1153 | if (ret) { | ||
1154 | netdev_err(pdata->netdev, "I2C error reading SFP GPIOs\n"); | ||
1155 | return; | ||
1156 | } | ||
1157 | |||
1158 | gpio_input = (gpio_ports[1] << 8) | gpio_ports[0]; | ||
1159 | |||
1160 | if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT) { | ||
1161 | /* No GPIO, just assume the module is present for now */ | ||
1162 | phy_data->sfp_mod_absent = 0; | ||
1163 | } else { | ||
1164 | if (!(gpio_input & (1 << phy_data->sfp_gpio_mod_absent))) | ||
1165 | phy_data->sfp_mod_absent = 0; | ||
1166 | } | ||
1167 | |||
1168 | if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS) && | ||
1169 | (gpio_input & (1 << phy_data->sfp_gpio_rx_los))) | ||
1170 | phy_data->sfp_rx_los = 1; | ||
1171 | |||
1172 | if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT) && | ||
1173 | (gpio_input & (1 << phy_data->sfp_gpio_tx_fault))) | ||
1174 | phy_data->sfp_tx_fault = 1; | ||
1175 | } | ||
1176 | |||
1177 | static void xgbe_phy_sfp_mod_absent(struct xgbe_prv_data *pdata) | ||
1178 | { | ||
1179 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1180 | |||
1181 | xgbe_phy_free_phy_device(pdata); | ||
1182 | |||
1183 | phy_data->sfp_mod_absent = 1; | ||
1184 | phy_data->sfp_phy_avail = 0; | ||
1185 | memset(&phy_data->sfp_eeprom, 0, sizeof(phy_data->sfp_eeprom)); | ||
1186 | } | ||
1187 | |||
1188 | static void xgbe_phy_sfp_reset(struct xgbe_phy_data *phy_data) | ||
1189 | { | ||
1190 | phy_data->sfp_rx_los = 0; | ||
1191 | phy_data->sfp_tx_fault = 0; | ||
1192 | phy_data->sfp_mod_absent = 1; | ||
1193 | phy_data->sfp_diags = 0; | ||
1194 | phy_data->sfp_base = XGBE_SFP_BASE_UNKNOWN; | ||
1195 | phy_data->sfp_cable = XGBE_SFP_CABLE_UNKNOWN; | ||
1196 | phy_data->sfp_speed = XGBE_SFP_SPEED_UNKNOWN; | ||
1197 | } | ||
1198 | |||
1199 | static void xgbe_phy_sfp_detect(struct xgbe_prv_data *pdata) | ||
1200 | { | ||
1201 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1202 | int ret; | ||
1203 | |||
1204 | /* Reset the SFP signals and info */ | ||
1205 | xgbe_phy_sfp_reset(phy_data); | ||
1206 | |||
1207 | ret = xgbe_phy_get_comm_ownership(pdata); | ||
1208 | if (ret) | ||
1209 | return; | ||
1210 | |||
1211 | /* Read the SFP signals and check for module presence */ | ||
1212 | xgbe_phy_sfp_signals(pdata); | ||
1213 | if (phy_data->sfp_mod_absent) { | ||
1214 | xgbe_phy_sfp_mod_absent(pdata); | ||
1215 | goto put; | ||
1216 | } | ||
1217 | |||
1218 | ret = xgbe_phy_sfp_read_eeprom(pdata); | ||
1219 | if (ret) { | ||
1220 | /* Treat any error as if there isn't an SFP plugged in */ | ||
1221 | xgbe_phy_sfp_reset(phy_data); | ||
1222 | xgbe_phy_sfp_mod_absent(pdata); | ||
1223 | goto put; | ||
1224 | } | ||
1225 | |||
1226 | xgbe_phy_sfp_parse_eeprom(pdata); | ||
1227 | |||
1228 | xgbe_phy_sfp_external_phy(pdata); | ||
1229 | |||
1230 | put: | ||
1231 | xgbe_phy_sfp_phy_settings(pdata); | ||
1232 | |||
1233 | xgbe_phy_put_comm_ownership(pdata); | ||
1234 | } | ||
1235 | |||
1236 | static void xgbe_phy_phydev_flowctrl(struct xgbe_prv_data *pdata) | ||
1237 | { | ||
1238 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1239 | u16 lcl_adv = 0, rmt_adv = 0; | ||
1240 | u8 fc; | ||
1241 | |||
1242 | pdata->phy.tx_pause = 0; | ||
1243 | pdata->phy.rx_pause = 0; | ||
1244 | |||
1245 | if (!phy_data->phydev) | ||
1246 | return; | ||
1247 | |||
1248 | if (phy_data->phydev->advertising & ADVERTISED_Pause) | ||
1249 | lcl_adv |= ADVERTISE_PAUSE_CAP; | ||
1250 | if (phy_data->phydev->advertising & ADVERTISED_Asym_Pause) | ||
1251 | lcl_adv |= ADVERTISE_PAUSE_ASYM; | ||
1252 | |||
1253 | if (phy_data->phydev->pause) { | ||
1254 | pdata->phy.lp_advertising |= ADVERTISED_Pause; | ||
1255 | rmt_adv |= LPA_PAUSE_CAP; | ||
1256 | } | ||
1257 | if (phy_data->phydev->asym_pause) { | ||
1258 | pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause; | ||
1259 | rmt_adv |= LPA_PAUSE_ASYM; | ||
1260 | } | ||
1261 | |||
1262 | fc = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | ||
1263 | if (fc & FLOW_CTRL_TX) | ||
1264 | pdata->phy.tx_pause = 1; | ||
1265 | if (fc & FLOW_CTRL_RX) | ||
1266 | pdata->phy.rx_pause = 1; | ||
1267 | } | ||
1268 | |||
1269 | static enum xgbe_mode xgbe_phy_an37_sgmii_outcome(struct xgbe_prv_data *pdata) | ||
1270 | { | ||
1271 | enum xgbe_mode mode; | ||
1272 | |||
1273 | pdata->phy.lp_advertising |= ADVERTISED_Autoneg; | ||
1274 | pdata->phy.lp_advertising |= ADVERTISED_TP; | ||
1275 | |||
1276 | /* Use external PHY to determine flow control */ | ||
1277 | if (pdata->phy.pause_autoneg) | ||
1278 | xgbe_phy_phydev_flowctrl(pdata); | ||
1279 | |||
1280 | switch (pdata->an_status & XGBE_SGMII_AN_LINK_SPEED) { | ||
1281 | case XGBE_SGMII_AN_LINK_SPEED_100: | ||
1282 | if (pdata->an_status & XGBE_SGMII_AN_LINK_DUPLEX) { | ||
1283 | pdata->phy.lp_advertising |= ADVERTISED_100baseT_Full; | ||
1284 | mode = XGBE_MODE_SGMII_100; | ||
1285 | } else { | ||
1286 | /* Half-duplex not supported */ | ||
1287 | pdata->phy.lp_advertising |= ADVERTISED_100baseT_Half; | ||
1288 | mode = XGBE_MODE_UNKNOWN; | ||
1289 | } | ||
1290 | break; | ||
1291 | case XGBE_SGMII_AN_LINK_SPEED_1000: | ||
1292 | if (pdata->an_status & XGBE_SGMII_AN_LINK_DUPLEX) { | ||
1293 | pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Full; | ||
1294 | mode = XGBE_MODE_SGMII_1000; | ||
1295 | } else { | ||
1296 | /* Half-duplex not supported */ | ||
1297 | pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Half; | ||
1298 | mode = XGBE_MODE_UNKNOWN; | ||
1299 | } | ||
1300 | break; | ||
1301 | default: | ||
1302 | mode = XGBE_MODE_UNKNOWN; | ||
1303 | } | ||
1304 | |||
1305 | return mode; | ||
1306 | } | ||
1307 | |||
1308 | static enum xgbe_mode xgbe_phy_an37_outcome(struct xgbe_prv_data *pdata) | ||
1309 | { | ||
1310 | enum xgbe_mode mode; | ||
1311 | unsigned int ad_reg, lp_reg; | ||
1312 | |||
1313 | pdata->phy.lp_advertising |= ADVERTISED_Autoneg; | ||
1314 | pdata->phy.lp_advertising |= ADVERTISED_FIBRE; | ||
1315 | |||
1316 | /* Compare Advertisement and Link Partner register */ | ||
1317 | ad_reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE); | ||
1318 | lp_reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_LP_ABILITY); | ||
1319 | if (lp_reg & 0x100) | ||
1320 | pdata->phy.lp_advertising |= ADVERTISED_Pause; | ||
1321 | if (lp_reg & 0x80) | ||
1322 | pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause; | ||
1323 | |||
1324 | if (pdata->phy.pause_autoneg) { | ||
1325 | /* Set flow control based on auto-negotiation result */ | ||
1326 | pdata->phy.tx_pause = 0; | ||
1327 | pdata->phy.rx_pause = 0; | ||
1328 | |||
1329 | if (ad_reg & lp_reg & 0x100) { | ||
1330 | pdata->phy.tx_pause = 1; | ||
1331 | pdata->phy.rx_pause = 1; | ||
1332 | } else if (ad_reg & lp_reg & 0x80) { | ||
1333 | if (ad_reg & 0x100) | ||
1334 | pdata->phy.rx_pause = 1; | ||
1335 | else if (lp_reg & 0x100) | ||
1336 | pdata->phy.tx_pause = 1; | ||
1337 | } | ||
1338 | } | ||
1339 | |||
1340 | if (lp_reg & 0x40) | ||
1341 | pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Half; | ||
1342 | if (lp_reg & 0x20) | ||
1343 | pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Full; | ||
1344 | |||
1345 | /* Half duplex is not supported */ | ||
1346 | ad_reg &= lp_reg; | ||
1347 | mode = (ad_reg & 0x20) ? XGBE_MODE_X : XGBE_MODE_UNKNOWN; | ||
1348 | |||
1349 | return mode; | ||
1350 | } | ||
1351 | |||
1352 | static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata) | ||
1353 | { | ||
1354 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1355 | enum xgbe_mode mode; | ||
1356 | unsigned int ad_reg, lp_reg; | ||
1357 | |||
1358 | pdata->phy.lp_advertising |= ADVERTISED_Autoneg; | ||
1359 | pdata->phy.lp_advertising |= ADVERTISED_Backplane; | ||
1360 | |||
1361 | /* Use external PHY to determine flow control */ | ||
1362 | if (pdata->phy.pause_autoneg) | ||
1363 | xgbe_phy_phydev_flowctrl(pdata); | ||
1364 | |||
1365 | /* Compare Advertisement and Link Partner register 2 */ | ||
1366 | ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); | ||
1367 | lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); | ||
1368 | if (lp_reg & 0x80) | ||
1369 | pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full; | ||
1370 | if (lp_reg & 0x20) | ||
1371 | pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full; | ||
1372 | |||
1373 | ad_reg &= lp_reg; | ||
1374 | if (ad_reg & 0x80) { | ||
1375 | switch (phy_data->port_mode) { | ||
1376 | case XGBE_PORT_MODE_BACKPLANE: | ||
1377 | mode = XGBE_MODE_KR; | ||
1378 | break; | ||
1379 | default: | ||
1380 | mode = XGBE_MODE_SFI; | ||
1381 | break; | ||
1382 | } | ||
1383 | } else if (ad_reg & 0x20) { | ||
1384 | switch (phy_data->port_mode) { | ||
1385 | case XGBE_PORT_MODE_BACKPLANE: | ||
1386 | mode = XGBE_MODE_KX_1000; | ||
1387 | break; | ||
1388 | case XGBE_PORT_MODE_1000BASE_X: | ||
1389 | mode = XGBE_MODE_X; | ||
1390 | break; | ||
1391 | case XGBE_PORT_MODE_SFP: | ||
1392 | switch (phy_data->sfp_base) { | ||
1393 | case XGBE_SFP_BASE_1000_T: | ||
1394 | if (phy_data->phydev && | ||
1395 | (phy_data->phydev->speed == SPEED_100)) | ||
1396 | mode = XGBE_MODE_SGMII_100; | ||
1397 | else | ||
1398 | mode = XGBE_MODE_SGMII_1000; | ||
1399 | break; | ||
1400 | case XGBE_SFP_BASE_1000_SX: | ||
1401 | case XGBE_SFP_BASE_1000_LX: | ||
1402 | case XGBE_SFP_BASE_1000_CX: | ||
1403 | default: | ||
1404 | mode = XGBE_MODE_X; | ||
1405 | break; | ||
1406 | } | ||
1407 | break; | ||
1408 | default: | ||
1409 | if (phy_data->phydev && | ||
1410 | (phy_data->phydev->speed == SPEED_100)) | ||
1411 | mode = XGBE_MODE_SGMII_100; | ||
1412 | else | ||
1413 | mode = XGBE_MODE_SGMII_1000; | ||
1414 | break; | ||
1415 | } | ||
1416 | } else { | ||
1417 | mode = XGBE_MODE_UNKNOWN; | ||
1418 | } | ||
1419 | |||
1420 | /* Compare Advertisement and Link Partner register 3 */ | ||
1421 | ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); | ||
1422 | lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); | ||
1423 | if (lp_reg & 0xc000) | ||
1424 | pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC; | ||
1425 | |||
1426 | return mode; | ||
1427 | } | ||
1428 | |||
1429 | static enum xgbe_mode xgbe_phy_an73_outcome(struct xgbe_prv_data *pdata) | ||
1430 | { | ||
1431 | enum xgbe_mode mode; | ||
1432 | unsigned int ad_reg, lp_reg; | ||
1433 | |||
1434 | pdata->phy.lp_advertising |= ADVERTISED_Autoneg; | ||
1435 | pdata->phy.lp_advertising |= ADVERTISED_Backplane; | ||
1436 | |||
1437 | /* Compare Advertisement and Link Partner register 1 */ | ||
1438 | ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); | ||
1439 | lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); | ||
1440 | if (lp_reg & 0x400) | ||
1441 | pdata->phy.lp_advertising |= ADVERTISED_Pause; | ||
1442 | if (lp_reg & 0x800) | ||
1443 | pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause; | ||
1444 | |||
1445 | if (pdata->phy.pause_autoneg) { | ||
1446 | /* Set flow control based on auto-negotiation result */ | ||
1447 | pdata->phy.tx_pause = 0; | ||
1448 | pdata->phy.rx_pause = 0; | ||
1449 | |||
1450 | if (ad_reg & lp_reg & 0x400) { | ||
1451 | pdata->phy.tx_pause = 1; | ||
1452 | pdata->phy.rx_pause = 1; | ||
1453 | } else if (ad_reg & lp_reg & 0x800) { | ||
1454 | if (ad_reg & 0x400) | ||
1455 | pdata->phy.rx_pause = 1; | ||
1456 | else if (lp_reg & 0x400) | ||
1457 | pdata->phy.tx_pause = 1; | ||
1458 | } | ||
1459 | } | ||
1460 | |||
1461 | /* Compare Advertisement and Link Partner register 2 */ | ||
1462 | ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); | ||
1463 | lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); | ||
1464 | if (lp_reg & 0x80) | ||
1465 | pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full; | ||
1466 | if (lp_reg & 0x20) | ||
1467 | pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full; | ||
1468 | |||
1469 | ad_reg &= lp_reg; | ||
1470 | if (ad_reg & 0x80) | ||
1471 | mode = XGBE_MODE_KR; | ||
1472 | else if (ad_reg & 0x20) | ||
1473 | mode = XGBE_MODE_KX_1000; | ||
1474 | else | ||
1475 | mode = XGBE_MODE_UNKNOWN; | ||
1476 | |||
1477 | /* Compare Advertisement and Link Partner register 3 */ | ||
1478 | ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); | ||
1479 | lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); | ||
1480 | if (lp_reg & 0xc000) | ||
1481 | pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC; | ||
1482 | |||
1483 | return mode; | ||
1484 | } | ||
1485 | |||
1486 | static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata) | ||
1487 | { | ||
1488 | switch (pdata->an_mode) { | ||
1489 | case XGBE_AN_MODE_CL73: | ||
1490 | return xgbe_phy_an73_outcome(pdata); | ||
1491 | case XGBE_AN_MODE_CL73_REDRV: | ||
1492 | return xgbe_phy_an73_redrv_outcome(pdata); | ||
1493 | case XGBE_AN_MODE_CL37: | ||
1494 | return xgbe_phy_an37_outcome(pdata); | ||
1495 | case XGBE_AN_MODE_CL37_SGMII: | ||
1496 | return xgbe_phy_an37_sgmii_outcome(pdata); | ||
1497 | default: | ||
1498 | return XGBE_MODE_UNKNOWN; | ||
1499 | } | ||
1500 | } | ||
1501 | |||
1502 | static unsigned int xgbe_phy_an_advertising(struct xgbe_prv_data *pdata) | ||
1503 | { | ||
1504 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1505 | unsigned int advertising; | ||
1506 | |||
1507 | /* Without a re-driver, just return current advertising */ | ||
1508 | if (!phy_data->redrv) | ||
1509 | return pdata->phy.advertising; | ||
1510 | |||
1511 | /* With the KR re-driver we need to advertise a single speed */ | ||
1512 | advertising = pdata->phy.advertising; | ||
1513 | advertising &= ~ADVERTISED_1000baseKX_Full; | ||
1514 | advertising &= ~ADVERTISED_10000baseKR_Full; | ||
1515 | |||
1516 | switch (phy_data->port_mode) { | ||
1517 | case XGBE_PORT_MODE_BACKPLANE: | ||
1518 | advertising |= ADVERTISED_10000baseKR_Full; | ||
1519 | break; | ||
1520 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
1521 | advertising |= ADVERTISED_1000baseKX_Full; | ||
1522 | break; | ||
1523 | case XGBE_PORT_MODE_1000BASE_T: | ||
1524 | case XGBE_PORT_MODE_1000BASE_X: | ||
1525 | case XGBE_PORT_MODE_NBASE_T: | ||
1526 | advertising |= ADVERTISED_1000baseKX_Full; | ||
1527 | break; | ||
1528 | case XGBE_PORT_MODE_10GBASE_T: | ||
1529 | if (phy_data->phydev && | ||
1530 | (phy_data->phydev->speed == SPEED_10000)) | ||
1531 | advertising |= ADVERTISED_10000baseKR_Full; | ||
1532 | else | ||
1533 | advertising |= ADVERTISED_1000baseKX_Full; | ||
1534 | break; | ||
1535 | case XGBE_PORT_MODE_10GBASE_R: | ||
1536 | advertising |= ADVERTISED_10000baseKR_Full; | ||
1537 | break; | ||
1538 | case XGBE_PORT_MODE_SFP: | ||
1539 | switch (phy_data->sfp_base) { | ||
1540 | case XGBE_SFP_BASE_1000_T: | ||
1541 | case XGBE_SFP_BASE_1000_SX: | ||
1542 | case XGBE_SFP_BASE_1000_LX: | ||
1543 | case XGBE_SFP_BASE_1000_CX: | ||
1544 | advertising |= ADVERTISED_1000baseKX_Full; | ||
1545 | break; | ||
1546 | default: | ||
1547 | advertising |= ADVERTISED_10000baseKR_Full; | ||
1548 | break; | ||
1549 | } | ||
1550 | break; | ||
1551 | default: | ||
1552 | advertising |= ADVERTISED_10000baseKR_Full; | ||
1553 | break; | ||
1554 | } | ||
1555 | |||
1556 | return advertising; | ||
1557 | } | ||
1558 | |||
1559 | static int xgbe_phy_an_config(struct xgbe_prv_data *pdata) | ||
1560 | { | ||
1561 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1562 | int ret; | ||
1563 | |||
1564 | ret = xgbe_phy_find_phy_device(pdata); | ||
1565 | if (ret) | ||
1566 | return ret; | ||
1567 | |||
1568 | if (!phy_data->phydev) | ||
1569 | return 0; | ||
1570 | |||
1571 | phy_data->phydev->autoneg = pdata->phy.autoneg; | ||
1572 | phy_data->phydev->advertising = phy_data->phydev->supported & | ||
1573 | pdata->phy.advertising; | ||
1574 | |||
1575 | if (pdata->phy.autoneg != AUTONEG_ENABLE) { | ||
1576 | phy_data->phydev->speed = pdata->phy.speed; | ||
1577 | phy_data->phydev->duplex = pdata->phy.duplex; | ||
1578 | } | ||
1579 | |||
1580 | ret = phy_start_aneg(phy_data->phydev); | ||
1581 | |||
1582 | return ret; | ||
1583 | } | ||
1584 | |||
1585 | static enum xgbe_an_mode xgbe_phy_an_sfp_mode(struct xgbe_phy_data *phy_data) | ||
1586 | { | ||
1587 | switch (phy_data->sfp_base) { | ||
1588 | case XGBE_SFP_BASE_1000_T: | ||
1589 | return XGBE_AN_MODE_CL37_SGMII; | ||
1590 | case XGBE_SFP_BASE_1000_SX: | ||
1591 | case XGBE_SFP_BASE_1000_LX: | ||
1592 | case XGBE_SFP_BASE_1000_CX: | ||
1593 | return XGBE_AN_MODE_CL37; | ||
1594 | default: | ||
1595 | return XGBE_AN_MODE_NONE; | ||
1596 | } | ||
1597 | } | ||
1598 | |||
1599 | static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata) | ||
1600 | { | ||
1601 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1602 | |||
1603 | /* A KR re-driver will always require CL73 AN */ | ||
1604 | if (phy_data->redrv) | ||
1605 | return XGBE_AN_MODE_CL73_REDRV; | ||
1606 | |||
1607 | switch (phy_data->port_mode) { | ||
1608 | case XGBE_PORT_MODE_BACKPLANE: | ||
1609 | return XGBE_AN_MODE_CL73; | ||
1610 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
1611 | return XGBE_AN_MODE_NONE; | ||
1612 | case XGBE_PORT_MODE_1000BASE_T: | ||
1613 | return XGBE_AN_MODE_CL37_SGMII; | ||
1614 | case XGBE_PORT_MODE_1000BASE_X: | ||
1615 | return XGBE_AN_MODE_CL37; | ||
1616 | case XGBE_PORT_MODE_NBASE_T: | ||
1617 | return XGBE_AN_MODE_CL37_SGMII; | ||
1618 | case XGBE_PORT_MODE_10GBASE_T: | ||
1619 | return XGBE_AN_MODE_CL73; | ||
1620 | case XGBE_PORT_MODE_10GBASE_R: | ||
1621 | return XGBE_AN_MODE_NONE; | ||
1622 | case XGBE_PORT_MODE_SFP: | ||
1623 | return xgbe_phy_an_sfp_mode(phy_data); | ||
1624 | default: | ||
1625 | return XGBE_AN_MODE_NONE; | ||
1626 | } | ||
1627 | } | ||
1628 | |||
1629 | static int xgbe_phy_set_redrv_mode_mdio(struct xgbe_prv_data *pdata, | ||
1630 | enum xgbe_phy_redrv_mode mode) | ||
1631 | { | ||
1632 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1633 | u16 redrv_reg, redrv_val; | ||
1634 | |||
1635 | redrv_reg = XGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000); | ||
1636 | redrv_val = (u16)mode; | ||
1637 | |||
1638 | return pdata->hw_if.write_ext_mii_regs(pdata, phy_data->redrv_addr, | ||
1639 | redrv_reg, redrv_val); | ||
1640 | } | ||
1641 | |||
1642 | static int xgbe_phy_set_redrv_mode_i2c(struct xgbe_prv_data *pdata, | ||
1643 | enum xgbe_phy_redrv_mode mode) | ||
1644 | { | ||
1645 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1646 | unsigned int redrv_reg; | ||
1647 | int ret; | ||
1648 | |||
1649 | /* Calculate the register to write */ | ||
1650 | redrv_reg = XGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000); | ||
1651 | |||
1652 | ret = xgbe_phy_redrv_write(pdata, redrv_reg, mode); | ||
1653 | |||
1654 | return ret; | ||
1655 | } | ||
1656 | |||
1657 | static void xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata) | ||
1658 | { | ||
1659 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1660 | enum xgbe_phy_redrv_mode mode; | ||
1661 | int ret; | ||
1662 | |||
1663 | if (!phy_data->redrv) | ||
1664 | return; | ||
1665 | |||
1666 | mode = XGBE_PHY_REDRV_MODE_CX; | ||
1667 | if ((phy_data->port_mode == XGBE_PORT_MODE_SFP) && | ||
1668 | (phy_data->sfp_base != XGBE_SFP_BASE_1000_CX) && | ||
1669 | (phy_data->sfp_base != XGBE_SFP_BASE_10000_CR)) | ||
1670 | mode = XGBE_PHY_REDRV_MODE_SR; | ||
1671 | |||
1672 | ret = xgbe_phy_get_comm_ownership(pdata); | ||
1673 | if (ret) | ||
1674 | return; | ||
1675 | |||
1676 | if (phy_data->redrv_if) | ||
1677 | xgbe_phy_set_redrv_mode_i2c(pdata, mode); | ||
1678 | else | ||
1679 | xgbe_phy_set_redrv_mode_mdio(pdata, mode); | ||
1680 | |||
1681 | xgbe_phy_put_comm_ownership(pdata); | ||
1682 | } | ||
1683 | |||
1684 | static void xgbe_phy_start_ratechange(struct xgbe_prv_data *pdata) | ||
1685 | { | ||
1686 | if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) | ||
1687 | return; | ||
1688 | |||
1689 | /* Log if a previous command did not complete */ | ||
1690 | netif_dbg(pdata, link, pdata->netdev, | ||
1691 | "firmware mailbox not ready for command\n"); | ||
1692 | } | ||
1693 | |||
1694 | static void xgbe_phy_complete_ratechange(struct xgbe_prv_data *pdata) | ||
1695 | { | ||
1696 | unsigned int wait; | ||
1697 | |||
1698 | /* Wait for command to complete */ | ||
1699 | wait = XGBE_RATECHANGE_COUNT; | ||
1700 | while (wait--) { | ||
1701 | if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) | ||
1702 | return; | ||
1703 | |||
1704 | usleep_range(1000, 2000); | ||
1705 | } | ||
1706 | |||
1707 | netif_dbg(pdata, link, pdata->netdev, | ||
1708 | "firmware mailbox command did not complete\n"); | ||
1709 | } | ||
1710 | |||
1711 | static void xgbe_phy_rrc(struct xgbe_prv_data *pdata) | ||
1712 | { | ||
1713 | unsigned int s0; | ||
1714 | |||
1715 | xgbe_phy_start_ratechange(pdata); | ||
1716 | |||
1717 | /* Receiver Reset Cycle */ | ||
1718 | s0 = 0; | ||
1719 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 5); | ||
1720 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0); | ||
1721 | |||
1722 | /* Call FW to make the change */ | ||
1723 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0); | ||
1724 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1725 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1726 | |||
1727 | xgbe_phy_complete_ratechange(pdata); | ||
1728 | |||
1729 | netif_dbg(pdata, link, pdata->netdev, "receiver reset complete\n"); | ||
1730 | } | ||
1731 | |||
1732 | static void xgbe_phy_power_off(struct xgbe_prv_data *pdata) | ||
1733 | { | ||
1734 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1735 | |||
1736 | xgbe_phy_start_ratechange(pdata); | ||
1737 | |||
1738 | /* Call FW to make the change */ | ||
1739 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, 0); | ||
1740 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1741 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1742 | |||
1743 | xgbe_phy_complete_ratechange(pdata); | ||
1744 | |||
1745 | phy_data->cur_mode = XGBE_MODE_UNKNOWN; | ||
1746 | |||
1747 | netif_dbg(pdata, link, pdata->netdev, "phy powered off\n"); | ||
1748 | } | ||
1749 | |||
1750 | static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata) | ||
1751 | { | ||
1752 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1753 | unsigned int s0; | ||
1754 | |||
1755 | xgbe_phy_set_redrv_mode(pdata); | ||
1756 | |||
1757 | xgbe_phy_start_ratechange(pdata); | ||
1758 | |||
1759 | /* 10G/SFI */ | ||
1760 | s0 = 0; | ||
1761 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 3); | ||
1762 | if (phy_data->sfp_cable != XGBE_SFP_CABLE_PASSIVE) { | ||
1763 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0); | ||
1764 | } else { | ||
1765 | if (phy_data->sfp_cable_len <= 1) | ||
1766 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 1); | ||
1767 | else if (phy_data->sfp_cable_len <= 3) | ||
1768 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 2); | ||
1769 | else if (phy_data->sfp_cable_len <= 5) | ||
1770 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 3); | ||
1771 | else | ||
1772 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 3); | ||
1773 | } | ||
1774 | |||
1775 | /* Call FW to make the change */ | ||
1776 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0); | ||
1777 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1778 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1779 | |||
1780 | xgbe_phy_complete_ratechange(pdata); | ||
1781 | |||
1782 | phy_data->cur_mode = XGBE_MODE_SFI; | ||
1783 | |||
1784 | netif_dbg(pdata, link, pdata->netdev, "10GbE SFI mode set\n"); | ||
1785 | } | ||
1786 | |||
1787 | static void xgbe_phy_x_mode(struct xgbe_prv_data *pdata) | ||
1788 | { | ||
1789 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1790 | unsigned int s0; | ||
1791 | |||
1792 | xgbe_phy_set_redrv_mode(pdata); | ||
1793 | |||
1794 | xgbe_phy_start_ratechange(pdata); | ||
1795 | |||
1796 | /* 1G/X */ | ||
1797 | s0 = 0; | ||
1798 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1); | ||
1799 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 3); | ||
1800 | |||
1801 | /* Call FW to make the change */ | ||
1802 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0); | ||
1803 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1804 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1805 | |||
1806 | xgbe_phy_complete_ratechange(pdata); | ||
1807 | |||
1808 | phy_data->cur_mode = XGBE_MODE_X; | ||
1809 | |||
1810 | netif_dbg(pdata, link, pdata->netdev, "1GbE X mode set\n"); | ||
1811 | } | ||
1812 | |||
1813 | static void xgbe_phy_sgmii_1000_mode(struct xgbe_prv_data *pdata) | ||
1814 | { | ||
1815 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1816 | unsigned int s0; | ||
1817 | |||
1818 | xgbe_phy_set_redrv_mode(pdata); | ||
1819 | |||
1820 | xgbe_phy_start_ratechange(pdata); | ||
1821 | |||
1822 | /* 1G/SGMII */ | ||
1823 | s0 = 0; | ||
1824 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1); | ||
1825 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 2); | ||
1826 | |||
1827 | /* Call FW to make the change */ | ||
1828 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0); | ||
1829 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1830 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1831 | |||
1832 | xgbe_phy_complete_ratechange(pdata); | ||
1833 | |||
1834 | phy_data->cur_mode = XGBE_MODE_SGMII_1000; | ||
1835 | |||
1836 | netif_dbg(pdata, link, pdata->netdev, "1GbE SGMII mode set\n"); | ||
1837 | } | ||
1838 | |||
1839 | static void xgbe_phy_sgmii_100_mode(struct xgbe_prv_data *pdata) | ||
1840 | { | ||
1841 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1842 | unsigned int s0; | ||
1843 | |||
1844 | xgbe_phy_set_redrv_mode(pdata); | ||
1845 | |||
1846 | xgbe_phy_start_ratechange(pdata); | ||
1847 | |||
1848 | /* 1G/SGMII */ | ||
1849 | s0 = 0; | ||
1850 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1); | ||
1851 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 1); | ||
1852 | |||
1853 | /* Call FW to make the change */ | ||
1854 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0); | ||
1855 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1856 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1857 | |||
1858 | xgbe_phy_complete_ratechange(pdata); | ||
1859 | |||
1860 | phy_data->cur_mode = XGBE_MODE_SGMII_100; | ||
1861 | |||
1862 | netif_dbg(pdata, link, pdata->netdev, "100MbE SGMII mode set\n"); | ||
1863 | } | ||
1864 | |||
1865 | static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata) | ||
1866 | { | ||
1867 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1868 | unsigned int s0; | ||
1869 | |||
1870 | xgbe_phy_set_redrv_mode(pdata); | ||
1871 | |||
1872 | xgbe_phy_start_ratechange(pdata); | ||
1873 | |||
1874 | /* 10G/KR */ | ||
1875 | s0 = 0; | ||
1876 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 4); | ||
1877 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0); | ||
1878 | |||
1879 | /* Call FW to make the change */ | ||
1880 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0); | ||
1881 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1882 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1883 | |||
1884 | xgbe_phy_complete_ratechange(pdata); | ||
1885 | |||
1886 | phy_data->cur_mode = XGBE_MODE_KR; | ||
1887 | |||
1888 | netif_dbg(pdata, link, pdata->netdev, "10GbE KR mode set\n"); | ||
1889 | } | ||
1890 | |||
1891 | static void xgbe_phy_kx_2500_mode(struct xgbe_prv_data *pdata) | ||
1892 | { | ||
1893 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1894 | unsigned int s0; | ||
1895 | |||
1896 | xgbe_phy_set_redrv_mode(pdata); | ||
1897 | |||
1898 | xgbe_phy_start_ratechange(pdata); | ||
1899 | |||
1900 | /* 2.5G/KX */ | ||
1901 | s0 = 0; | ||
1902 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 2); | ||
1903 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0); | ||
1904 | |||
1905 | /* Call FW to make the change */ | ||
1906 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0); | ||
1907 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1908 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1909 | |||
1910 | xgbe_phy_complete_ratechange(pdata); | ||
1911 | |||
1912 | phy_data->cur_mode = XGBE_MODE_KX_2500; | ||
1913 | |||
1914 | netif_dbg(pdata, link, pdata->netdev, "2.5GbE KX mode set\n"); | ||
1915 | } | ||
1916 | |||
1917 | static void xgbe_phy_kx_1000_mode(struct xgbe_prv_data *pdata) | ||
1918 | { | ||
1919 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1920 | unsigned int s0; | ||
1921 | |||
1922 | xgbe_phy_set_redrv_mode(pdata); | ||
1923 | |||
1924 | xgbe_phy_start_ratechange(pdata); | ||
1925 | |||
1926 | /* 1G/KX */ | ||
1927 | s0 = 0; | ||
1928 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1); | ||
1929 | XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 3); | ||
1930 | |||
1931 | /* Call FW to make the change */ | ||
1932 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0); | ||
1933 | XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0); | ||
1934 | XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1); | ||
1935 | |||
1936 | xgbe_phy_complete_ratechange(pdata); | ||
1937 | |||
1938 | phy_data->cur_mode = XGBE_MODE_KX_1000; | ||
1939 | |||
1940 | netif_dbg(pdata, link, pdata->netdev, "1GbE KX mode set\n"); | ||
1941 | } | ||
1942 | |||
1943 | static enum xgbe_mode xgbe_phy_cur_mode(struct xgbe_prv_data *pdata) | ||
1944 | { | ||
1945 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1946 | |||
1947 | return phy_data->cur_mode; | ||
1948 | } | ||
1949 | |||
1950 | static enum xgbe_mode xgbe_phy_switch_baset_mode(struct xgbe_prv_data *pdata) | ||
1951 | { | ||
1952 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1953 | |||
1954 | /* No switching if not 10GBase-T */ | ||
1955 | if (phy_data->port_mode != XGBE_PORT_MODE_10GBASE_T) | ||
1956 | return xgbe_phy_cur_mode(pdata); | ||
1957 | |||
1958 | switch (xgbe_phy_cur_mode(pdata)) { | ||
1959 | case XGBE_MODE_SGMII_100: | ||
1960 | case XGBE_MODE_SGMII_1000: | ||
1961 | return XGBE_MODE_KR; | ||
1962 | case XGBE_MODE_KR: | ||
1963 | default: | ||
1964 | return XGBE_MODE_SGMII_1000; | ||
1965 | } | ||
1966 | } | ||
1967 | |||
1968 | static enum xgbe_mode xgbe_phy_switch_bp_2500_mode(struct xgbe_prv_data *pdata) | ||
1969 | { | ||
1970 | return XGBE_MODE_KX_2500; | ||
1971 | } | ||
1972 | |||
1973 | static enum xgbe_mode xgbe_phy_switch_bp_mode(struct xgbe_prv_data *pdata) | ||
1974 | { | ||
1975 | /* If we are in KR switch to KX, and vice-versa */ | ||
1976 | switch (xgbe_phy_cur_mode(pdata)) { | ||
1977 | case XGBE_MODE_KX_1000: | ||
1978 | return XGBE_MODE_KR; | ||
1979 | case XGBE_MODE_KR: | ||
1980 | default: | ||
1981 | return XGBE_MODE_KX_1000; | ||
1982 | } | ||
1983 | } | ||
1984 | |||
1985 | static enum xgbe_mode xgbe_phy_switch_mode(struct xgbe_prv_data *pdata) | ||
1986 | { | ||
1987 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
1988 | |||
1989 | switch (phy_data->port_mode) { | ||
1990 | case XGBE_PORT_MODE_BACKPLANE: | ||
1991 | return xgbe_phy_switch_bp_mode(pdata); | ||
1992 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
1993 | return xgbe_phy_switch_bp_2500_mode(pdata); | ||
1994 | case XGBE_PORT_MODE_1000BASE_T: | ||
1995 | case XGBE_PORT_MODE_NBASE_T: | ||
1996 | case XGBE_PORT_MODE_10GBASE_T: | ||
1997 | return xgbe_phy_switch_baset_mode(pdata); | ||
1998 | case XGBE_PORT_MODE_1000BASE_X: | ||
1999 | case XGBE_PORT_MODE_10GBASE_R: | ||
2000 | case XGBE_PORT_MODE_SFP: | ||
2001 | /* No switching, so just return current mode */ | ||
2002 | return xgbe_phy_cur_mode(pdata); | ||
2003 | default: | ||
2004 | return XGBE_MODE_UNKNOWN; | ||
2005 | } | ||
2006 | } | ||
2007 | |||
2008 | static enum xgbe_mode xgbe_phy_get_basex_mode(struct xgbe_phy_data *phy_data, | ||
2009 | int speed) | ||
2010 | { | ||
2011 | switch (speed) { | ||
2012 | case SPEED_1000: | ||
2013 | return XGBE_MODE_X; | ||
2014 | case SPEED_10000: | ||
2015 | return XGBE_MODE_KR; | ||
2016 | default: | ||
2017 | return XGBE_MODE_UNKNOWN; | ||
2018 | } | ||
2019 | } | ||
2020 | |||
2021 | static enum xgbe_mode xgbe_phy_get_baset_mode(struct xgbe_phy_data *phy_data, | ||
2022 | int speed) | ||
2023 | { | ||
2024 | switch (speed) { | ||
2025 | case SPEED_100: | ||
2026 | return XGBE_MODE_SGMII_100; | ||
2027 | case SPEED_1000: | ||
2028 | return XGBE_MODE_SGMII_1000; | ||
2029 | case SPEED_10000: | ||
2030 | return XGBE_MODE_KR; | ||
2031 | default: | ||
2032 | return XGBE_MODE_UNKNOWN; | ||
2033 | } | ||
2034 | } | ||
2035 | |||
2036 | static enum xgbe_mode xgbe_phy_get_sfp_mode(struct xgbe_phy_data *phy_data, | ||
2037 | int speed) | ||
2038 | { | ||
2039 | switch (speed) { | ||
2040 | case SPEED_100: | ||
2041 | return XGBE_MODE_SGMII_100; | ||
2042 | case SPEED_1000: | ||
2043 | if (phy_data->sfp_base == XGBE_SFP_BASE_1000_T) | ||
2044 | return XGBE_MODE_SGMII_1000; | ||
2045 | else | ||
2046 | return XGBE_MODE_X; | ||
2047 | case SPEED_10000: | ||
2048 | case SPEED_UNKNOWN: | ||
2049 | return XGBE_MODE_SFI; | ||
2050 | default: | ||
2051 | return XGBE_MODE_UNKNOWN; | ||
2052 | } | ||
2053 | } | ||
2054 | |||
2055 | static enum xgbe_mode xgbe_phy_get_bp_2500_mode(int speed) | ||
2056 | { | ||
2057 | switch (speed) { | ||
2058 | case SPEED_2500: | ||
2059 | return XGBE_MODE_KX_2500; | ||
2060 | default: | ||
2061 | return XGBE_MODE_UNKNOWN; | ||
2062 | } | ||
2063 | } | ||
2064 | |||
2065 | static enum xgbe_mode xgbe_phy_get_bp_mode(int speed) | ||
2066 | { | ||
2067 | switch (speed) { | ||
2068 | case SPEED_1000: | ||
2069 | return XGBE_MODE_KX_1000; | ||
2070 | case SPEED_10000: | ||
2071 | return XGBE_MODE_KR; | ||
2072 | default: | ||
2073 | return XGBE_MODE_UNKNOWN; | ||
2074 | } | ||
2075 | } | ||
2076 | |||
2077 | static enum xgbe_mode xgbe_phy_get_mode(struct xgbe_prv_data *pdata, | ||
2078 | int speed) | ||
2079 | { | ||
2080 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2081 | |||
2082 | switch (phy_data->port_mode) { | ||
2083 | case XGBE_PORT_MODE_BACKPLANE: | ||
2084 | return xgbe_phy_get_bp_mode(speed); | ||
2085 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
2086 | return xgbe_phy_get_bp_2500_mode(speed); | ||
2087 | case XGBE_PORT_MODE_1000BASE_T: | ||
2088 | case XGBE_PORT_MODE_NBASE_T: | ||
2089 | case XGBE_PORT_MODE_10GBASE_T: | ||
2090 | return xgbe_phy_get_baset_mode(phy_data, speed); | ||
2091 | case XGBE_PORT_MODE_1000BASE_X: | ||
2092 | case XGBE_PORT_MODE_10GBASE_R: | ||
2093 | return xgbe_phy_get_basex_mode(phy_data, speed); | ||
2094 | case XGBE_PORT_MODE_SFP: | ||
2095 | return xgbe_phy_get_sfp_mode(phy_data, speed); | ||
2096 | default: | ||
2097 | return XGBE_MODE_UNKNOWN; | ||
2098 | } | ||
2099 | } | ||
2100 | |||
2101 | static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode) | ||
2102 | { | ||
2103 | switch (mode) { | ||
2104 | case XGBE_MODE_KX_1000: | ||
2105 | xgbe_phy_kx_1000_mode(pdata); | ||
2106 | break; | ||
2107 | case XGBE_MODE_KX_2500: | ||
2108 | xgbe_phy_kx_2500_mode(pdata); | ||
2109 | break; | ||
2110 | case XGBE_MODE_KR: | ||
2111 | xgbe_phy_kr_mode(pdata); | ||
2112 | break; | ||
2113 | case XGBE_MODE_SGMII_100: | ||
2114 | xgbe_phy_sgmii_100_mode(pdata); | ||
2115 | break; | ||
2116 | case XGBE_MODE_SGMII_1000: | ||
2117 | xgbe_phy_sgmii_1000_mode(pdata); | ||
2118 | break; | ||
2119 | case XGBE_MODE_X: | ||
2120 | xgbe_phy_x_mode(pdata); | ||
2121 | break; | ||
2122 | case XGBE_MODE_SFI: | ||
2123 | xgbe_phy_sfi_mode(pdata); | ||
2124 | break; | ||
2125 | default: | ||
2126 | break; | ||
2127 | } | ||
2128 | } | ||
2129 | |||
2130 | static bool xgbe_phy_check_mode(struct xgbe_prv_data *pdata, | ||
2131 | enum xgbe_mode mode, u32 advert) | ||
2132 | { | ||
2133 | if (pdata->phy.autoneg == AUTONEG_ENABLE) { | ||
2134 | if (pdata->phy.advertising & advert) | ||
2135 | return true; | ||
2136 | } else { | ||
2137 | enum xgbe_mode cur_mode; | ||
2138 | |||
2139 | cur_mode = xgbe_phy_get_mode(pdata, pdata->phy.speed); | ||
2140 | if (cur_mode == mode) | ||
2141 | return true; | ||
2142 | } | ||
2143 | |||
2144 | return false; | ||
2145 | } | ||
2146 | |||
2147 | static bool xgbe_phy_use_basex_mode(struct xgbe_prv_data *pdata, | ||
2148 | enum xgbe_mode mode) | ||
2149 | { | ||
2150 | switch (mode) { | ||
2151 | case XGBE_MODE_X: | ||
2152 | return xgbe_phy_check_mode(pdata, mode, | ||
2153 | ADVERTISED_1000baseT_Full); | ||
2154 | case XGBE_MODE_KR: | ||
2155 | return xgbe_phy_check_mode(pdata, mode, | ||
2156 | ADVERTISED_10000baseT_Full); | ||
2157 | default: | ||
2158 | return false; | ||
2159 | } | ||
2160 | } | ||
2161 | |||
2162 | static bool xgbe_phy_use_baset_mode(struct xgbe_prv_data *pdata, | ||
2163 | enum xgbe_mode mode) | ||
2164 | { | ||
2165 | switch (mode) { | ||
2166 | case XGBE_MODE_SGMII_100: | ||
2167 | return xgbe_phy_check_mode(pdata, mode, | ||
2168 | ADVERTISED_100baseT_Full); | ||
2169 | case XGBE_MODE_SGMII_1000: | ||
2170 | return xgbe_phy_check_mode(pdata, mode, | ||
2171 | ADVERTISED_1000baseT_Full); | ||
2172 | case XGBE_MODE_KR: | ||
2173 | return xgbe_phy_check_mode(pdata, mode, | ||
2174 | ADVERTISED_10000baseT_Full); | ||
2175 | default: | ||
2176 | return false; | ||
2177 | } | ||
2178 | } | ||
2179 | |||
2180 | static bool xgbe_phy_use_sfp_mode(struct xgbe_prv_data *pdata, | ||
2181 | enum xgbe_mode mode) | ||
2182 | { | ||
2183 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2184 | |||
2185 | switch (mode) { | ||
2186 | case XGBE_MODE_X: | ||
2187 | if (phy_data->sfp_base == XGBE_SFP_BASE_1000_T) | ||
2188 | return false; | ||
2189 | return xgbe_phy_check_mode(pdata, mode, | ||
2190 | ADVERTISED_1000baseT_Full); | ||
2191 | case XGBE_MODE_SGMII_100: | ||
2192 | if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T) | ||
2193 | return false; | ||
2194 | return xgbe_phy_check_mode(pdata, mode, | ||
2195 | ADVERTISED_100baseT_Full); | ||
2196 | case XGBE_MODE_SGMII_1000: | ||
2197 | if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T) | ||
2198 | return false; | ||
2199 | return xgbe_phy_check_mode(pdata, mode, | ||
2200 | ADVERTISED_1000baseT_Full); | ||
2201 | case XGBE_MODE_SFI: | ||
2202 | return xgbe_phy_check_mode(pdata, mode, | ||
2203 | ADVERTISED_10000baseT_Full); | ||
2204 | default: | ||
2205 | return false; | ||
2206 | } | ||
2207 | } | ||
2208 | |||
2209 | static bool xgbe_phy_use_bp_2500_mode(struct xgbe_prv_data *pdata, | ||
2210 | enum xgbe_mode mode) | ||
2211 | { | ||
2212 | switch (mode) { | ||
2213 | case XGBE_MODE_KX_2500: | ||
2214 | return xgbe_phy_check_mode(pdata, mode, | ||
2215 | ADVERTISED_2500baseX_Full); | ||
2216 | default: | ||
2217 | return false; | ||
2218 | } | ||
2219 | } | ||
2220 | |||
2221 | static bool xgbe_phy_use_bp_mode(struct xgbe_prv_data *pdata, | ||
2222 | enum xgbe_mode mode) | ||
2223 | { | ||
2224 | switch (mode) { | ||
2225 | case XGBE_MODE_KX_1000: | ||
2226 | return xgbe_phy_check_mode(pdata, mode, | ||
2227 | ADVERTISED_1000baseKX_Full); | ||
2228 | case XGBE_MODE_KR: | ||
2229 | return xgbe_phy_check_mode(pdata, mode, | ||
2230 | ADVERTISED_10000baseKR_Full); | ||
2231 | default: | ||
2232 | return false; | ||
2233 | } | ||
2234 | } | ||
2235 | |||
2236 | static bool xgbe_phy_use_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode) | ||
2237 | { | ||
2238 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2239 | |||
2240 | switch (phy_data->port_mode) { | ||
2241 | case XGBE_PORT_MODE_BACKPLANE: | ||
2242 | return xgbe_phy_use_bp_mode(pdata, mode); | ||
2243 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
2244 | return xgbe_phy_use_bp_2500_mode(pdata, mode); | ||
2245 | case XGBE_PORT_MODE_1000BASE_T: | ||
2246 | case XGBE_PORT_MODE_NBASE_T: | ||
2247 | case XGBE_PORT_MODE_10GBASE_T: | ||
2248 | return xgbe_phy_use_baset_mode(pdata, mode); | ||
2249 | case XGBE_PORT_MODE_1000BASE_X: | ||
2250 | case XGBE_PORT_MODE_10GBASE_R: | ||
2251 | return xgbe_phy_use_basex_mode(pdata, mode); | ||
2252 | case XGBE_PORT_MODE_SFP: | ||
2253 | return xgbe_phy_use_sfp_mode(pdata, mode); | ||
2254 | default: | ||
2255 | return false; | ||
2256 | } | ||
2257 | } | ||
2258 | |||
2259 | static bool xgbe_phy_valid_speed_basex_mode(struct xgbe_phy_data *phy_data, | ||
2260 | int speed) | ||
2261 | { | ||
2262 | switch (speed) { | ||
2263 | case SPEED_1000: | ||
2264 | return (phy_data->port_mode == XGBE_PORT_MODE_1000BASE_X); | ||
2265 | case SPEED_10000: | ||
2266 | return (phy_data->port_mode == XGBE_PORT_MODE_10GBASE_R); | ||
2267 | default: | ||
2268 | return false; | ||
2269 | } | ||
2270 | } | ||
2271 | |||
2272 | static bool xgbe_phy_valid_speed_baset_mode(struct xgbe_phy_data *phy_data, | ||
2273 | int speed) | ||
2274 | { | ||
2275 | switch (speed) { | ||
2276 | case SPEED_100: | ||
2277 | case SPEED_1000: | ||
2278 | return true; | ||
2279 | case SPEED_10000: | ||
2280 | return (phy_data->port_mode == XGBE_PORT_MODE_10GBASE_T); | ||
2281 | default: | ||
2282 | return false; | ||
2283 | } | ||
2284 | } | ||
2285 | |||
2286 | static bool xgbe_phy_valid_speed_sfp_mode(struct xgbe_phy_data *phy_data, | ||
2287 | int speed) | ||
2288 | { | ||
2289 | switch (speed) { | ||
2290 | case SPEED_100: | ||
2291 | return (phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000); | ||
2292 | case SPEED_1000: | ||
2293 | return ((phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000) || | ||
2294 | (phy_data->sfp_speed == XGBE_SFP_SPEED_1000)); | ||
2295 | case SPEED_10000: | ||
2296 | return (phy_data->sfp_speed == XGBE_SFP_SPEED_10000); | ||
2297 | default: | ||
2298 | return false; | ||
2299 | } | ||
2300 | } | ||
2301 | |||
2302 | static bool xgbe_phy_valid_speed_bp_2500_mode(int speed) | ||
2303 | { | ||
2304 | switch (speed) { | ||
2305 | case SPEED_2500: | ||
2306 | return true; | ||
2307 | default: | ||
2308 | return false; | ||
2309 | } | ||
2310 | } | ||
2311 | |||
2312 | static bool xgbe_phy_valid_speed_bp_mode(int speed) | ||
2313 | { | ||
2314 | switch (speed) { | ||
2315 | case SPEED_1000: | ||
2316 | case SPEED_10000: | ||
2317 | return true; | ||
2318 | default: | ||
2319 | return false; | ||
2320 | } | ||
2321 | } | ||
2322 | |||
2323 | static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed) | ||
2324 | { | ||
2325 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2326 | |||
2327 | switch (phy_data->port_mode) { | ||
2328 | case XGBE_PORT_MODE_BACKPLANE: | ||
2329 | return xgbe_phy_valid_speed_bp_mode(speed); | ||
2330 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
2331 | return xgbe_phy_valid_speed_bp_2500_mode(speed); | ||
2332 | case XGBE_PORT_MODE_1000BASE_T: | ||
2333 | case XGBE_PORT_MODE_NBASE_T: | ||
2334 | case XGBE_PORT_MODE_10GBASE_T: | ||
2335 | return xgbe_phy_valid_speed_baset_mode(phy_data, speed); | ||
2336 | case XGBE_PORT_MODE_1000BASE_X: | ||
2337 | case XGBE_PORT_MODE_10GBASE_R: | ||
2338 | return xgbe_phy_valid_speed_basex_mode(phy_data, speed); | ||
2339 | case XGBE_PORT_MODE_SFP: | ||
2340 | return xgbe_phy_valid_speed_sfp_mode(phy_data, speed); | ||
2341 | default: | ||
2342 | return false; | ||
2343 | } | ||
2344 | } | ||
2345 | |||
2346 | static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) | ||
2347 | { | ||
2348 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2349 | unsigned int ret, reg; | ||
2350 | |||
2351 | *an_restart = 0; | ||
2352 | |||
2353 | if (phy_data->port_mode == XGBE_PORT_MODE_SFP) { | ||
2354 | /* Check SFP signals */ | ||
2355 | xgbe_phy_sfp_detect(pdata); | ||
2356 | |||
2357 | if (phy_data->sfp_changed) { | ||
2358 | *an_restart = 1; | ||
2359 | return 0; | ||
2360 | } | ||
2361 | |||
2362 | if (phy_data->sfp_mod_absent || phy_data->sfp_rx_los) | ||
2363 | return 0; | ||
2364 | } | ||
2365 | |||
2366 | if (phy_data->phydev) { | ||
2367 | /* Check external PHY */ | ||
2368 | ret = phy_read_status(phy_data->phydev); | ||
2369 | if (ret < 0) | ||
2370 | return 0; | ||
2371 | |||
2372 | if ((pdata->phy.autoneg == AUTONEG_ENABLE) && | ||
2373 | !phy_aneg_done(phy_data->phydev)) | ||
2374 | return 0; | ||
2375 | |||
2376 | if (!phy_data->phydev->link) | ||
2377 | return 0; | ||
2378 | } | ||
2379 | |||
2380 | /* Link status is latched low, so read once to clear | ||
2381 | * and then read again to get current state | ||
2382 | */ | ||
2383 | reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); | ||
2384 | reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); | ||
2385 | if (reg & MDIO_STAT1_LSTATUS) | ||
2386 | return 1; | ||
2387 | |||
2388 | /* No link, attempt a receiver reset cycle */ | ||
2389 | if (phy_data->rrc_count++) { | ||
2390 | phy_data->rrc_count = 0; | ||
2391 | xgbe_phy_rrc(pdata); | ||
2392 | } | ||
2393 | |||
2394 | return 0; | ||
2395 | } | ||
2396 | |||
2397 | static void xgbe_phy_sfp_gpio_setup(struct xgbe_prv_data *pdata) | ||
2398 | { | ||
2399 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2400 | unsigned int reg; | ||
2401 | |||
2402 | reg = XP_IOREAD(pdata, XP_PROP_3); | ||
2403 | |||
2404 | phy_data->sfp_gpio_address = XGBE_GPIO_ADDRESS_PCA9555 + | ||
2405 | XP_GET_BITS(reg, XP_PROP_3, GPIO_ADDR); | ||
2406 | |||
2407 | phy_data->sfp_gpio_mask = XP_GET_BITS(reg, XP_PROP_3, GPIO_MASK); | ||
2408 | |||
2409 | phy_data->sfp_gpio_rx_los = XP_GET_BITS(reg, XP_PROP_3, | ||
2410 | GPIO_RX_LOS); | ||
2411 | phy_data->sfp_gpio_tx_fault = XP_GET_BITS(reg, XP_PROP_3, | ||
2412 | GPIO_TX_FAULT); | ||
2413 | phy_data->sfp_gpio_mod_absent = XP_GET_BITS(reg, XP_PROP_3, | ||
2414 | GPIO_MOD_ABS); | ||
2415 | phy_data->sfp_gpio_rate_select = XP_GET_BITS(reg, XP_PROP_3, | ||
2416 | GPIO_RATE_SELECT); | ||
2417 | |||
2418 | if (netif_msg_probe(pdata)) { | ||
2419 | dev_dbg(pdata->dev, "SFP: gpio_address=%#x\n", | ||
2420 | phy_data->sfp_gpio_address); | ||
2421 | dev_dbg(pdata->dev, "SFP: gpio_mask=%#x\n", | ||
2422 | phy_data->sfp_gpio_mask); | ||
2423 | dev_dbg(pdata->dev, "SFP: gpio_rx_los=%u\n", | ||
2424 | phy_data->sfp_gpio_rx_los); | ||
2425 | dev_dbg(pdata->dev, "SFP: gpio_tx_fault=%u\n", | ||
2426 | phy_data->sfp_gpio_tx_fault); | ||
2427 | dev_dbg(pdata->dev, "SFP: gpio_mod_absent=%u\n", | ||
2428 | phy_data->sfp_gpio_mod_absent); | ||
2429 | dev_dbg(pdata->dev, "SFP: gpio_rate_select=%u\n", | ||
2430 | phy_data->sfp_gpio_rate_select); | ||
2431 | } | ||
2432 | } | ||
2433 | |||
2434 | static void xgbe_phy_sfp_comm_setup(struct xgbe_prv_data *pdata) | ||
2435 | { | ||
2436 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2437 | unsigned int reg, mux_addr_hi, mux_addr_lo; | ||
2438 | |||
2439 | reg = XP_IOREAD(pdata, XP_PROP_4); | ||
2440 | |||
2441 | mux_addr_hi = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_HI); | ||
2442 | mux_addr_lo = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_LO); | ||
2443 | if (mux_addr_lo == XGBE_SFP_DIRECT) | ||
2444 | return; | ||
2445 | |||
2446 | phy_data->sfp_comm = XGBE_SFP_COMM_PCA9545; | ||
2447 | phy_data->sfp_mux_address = (mux_addr_hi << 2) + mux_addr_lo; | ||
2448 | phy_data->sfp_mux_channel = XP_GET_BITS(reg, XP_PROP_4, MUX_CHAN); | ||
2449 | |||
2450 | if (netif_msg_probe(pdata)) { | ||
2451 | dev_dbg(pdata->dev, "SFP: mux_address=%#x\n", | ||
2452 | phy_data->sfp_mux_address); | ||
2453 | dev_dbg(pdata->dev, "SFP: mux_channel=%u\n", | ||
2454 | phy_data->sfp_mux_channel); | ||
2455 | } | ||
2456 | } | ||
2457 | |||
2458 | static void xgbe_phy_sfp_setup(struct xgbe_prv_data *pdata) | ||
2459 | { | ||
2460 | xgbe_phy_sfp_comm_setup(pdata); | ||
2461 | xgbe_phy_sfp_gpio_setup(pdata); | ||
2462 | } | ||
2463 | |||
2464 | static int xgbe_phy_int_mdio_reset(struct xgbe_prv_data *pdata) | ||
2465 | { | ||
2466 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2467 | unsigned int ret; | ||
2468 | |||
2469 | ret = pdata->hw_if.set_gpio(pdata, phy_data->mdio_reset_gpio); | ||
2470 | if (ret) | ||
2471 | return ret; | ||
2472 | |||
2473 | ret = pdata->hw_if.clr_gpio(pdata, phy_data->mdio_reset_gpio); | ||
2474 | |||
2475 | return ret; | ||
2476 | } | ||
2477 | |||
2478 | static int xgbe_phy_i2c_mdio_reset(struct xgbe_prv_data *pdata) | ||
2479 | { | ||
2480 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2481 | u8 gpio_reg, gpio_ports[2], gpio_data[3]; | ||
2482 | int ret; | ||
2483 | |||
2484 | /* Read the output port registers */ | ||
2485 | gpio_reg = 2; | ||
2486 | ret = xgbe_phy_i2c_read(pdata, phy_data->mdio_reset_addr, | ||
2487 | &gpio_reg, sizeof(gpio_reg), | ||
2488 | gpio_ports, sizeof(gpio_ports)); | ||
2489 | if (ret) | ||
2490 | return ret; | ||
2491 | |||
2492 | /* Prepare to write the GPIO data */ | ||
2493 | gpio_data[0] = 2; | ||
2494 | gpio_data[1] = gpio_ports[0]; | ||
2495 | gpio_data[2] = gpio_ports[1]; | ||
2496 | |||
2497 | /* Set the GPIO pin */ | ||
2498 | if (phy_data->mdio_reset_gpio < 8) | ||
2499 | gpio_data[1] |= (1 << (phy_data->mdio_reset_gpio % 8)); | ||
2500 | else | ||
2501 | gpio_data[2] |= (1 << (phy_data->mdio_reset_gpio % 8)); | ||
2502 | |||
2503 | /* Write the output port registers */ | ||
2504 | ret = xgbe_phy_i2c_write(pdata, phy_data->mdio_reset_addr, | ||
2505 | gpio_data, sizeof(gpio_data)); | ||
2506 | if (ret) | ||
2507 | return ret; | ||
2508 | |||
2509 | /* Clear the GPIO pin */ | ||
2510 | if (phy_data->mdio_reset_gpio < 8) | ||
2511 | gpio_data[1] &= ~(1 << (phy_data->mdio_reset_gpio % 8)); | ||
2512 | else | ||
2513 | gpio_data[2] &= ~(1 << (phy_data->mdio_reset_gpio % 8)); | ||
2514 | |||
2515 | /* Write the output port registers */ | ||
2516 | ret = xgbe_phy_i2c_write(pdata, phy_data->mdio_reset_addr, | ||
2517 | gpio_data, sizeof(gpio_data)); | ||
2518 | |||
2519 | return ret; | ||
2520 | } | ||
2521 | |||
2522 | static int xgbe_phy_mdio_reset(struct xgbe_prv_data *pdata) | ||
2523 | { | ||
2524 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2525 | int ret; | ||
2526 | |||
2527 | if (phy_data->conn_type != XGBE_CONN_TYPE_MDIO) | ||
2528 | return 0; | ||
2529 | |||
2530 | ret = xgbe_phy_get_comm_ownership(pdata); | ||
2531 | if (ret) | ||
2532 | return ret; | ||
2533 | |||
2534 | if (phy_data->mdio_reset == XGBE_MDIO_RESET_I2C_GPIO) | ||
2535 | ret = xgbe_phy_i2c_mdio_reset(pdata); | ||
2536 | else if (phy_data->mdio_reset == XGBE_MDIO_RESET_INT_GPIO) | ||
2537 | ret = xgbe_phy_int_mdio_reset(pdata); | ||
2538 | |||
2539 | xgbe_phy_put_comm_ownership(pdata); | ||
2540 | |||
2541 | return ret; | ||
2542 | } | ||
2543 | |||
2544 | static bool xgbe_phy_redrv_error(struct xgbe_phy_data *phy_data) | ||
2545 | { | ||
2546 | if (!phy_data->redrv) | ||
2547 | return false; | ||
2548 | |||
2549 | if (phy_data->redrv_if >= XGBE_PHY_REDRV_IF_MAX) | ||
2550 | return true; | ||
2551 | |||
2552 | switch (phy_data->redrv_model) { | ||
2553 | case XGBE_PHY_REDRV_MODEL_4223: | ||
2554 | if (phy_data->redrv_lane > 3) | ||
2555 | return true; | ||
2556 | break; | ||
2557 | case XGBE_PHY_REDRV_MODEL_4227: | ||
2558 | if (phy_data->redrv_lane > 1) | ||
2559 | return true; | ||
2560 | break; | ||
2561 | default: | ||
2562 | return true; | ||
2563 | } | ||
2564 | |||
2565 | return false; | ||
2566 | } | ||
2567 | |||
2568 | static int xgbe_phy_mdio_reset_setup(struct xgbe_prv_data *pdata) | ||
2569 | { | ||
2570 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2571 | unsigned int reg; | ||
2572 | |||
2573 | if (phy_data->conn_type != XGBE_CONN_TYPE_MDIO) | ||
2574 | return 0; | ||
2575 | |||
2576 | reg = XP_IOREAD(pdata, XP_PROP_3); | ||
2577 | phy_data->mdio_reset = XP_GET_BITS(reg, XP_PROP_3, MDIO_RESET); | ||
2578 | switch (phy_data->mdio_reset) { | ||
2579 | case XGBE_MDIO_RESET_NONE: | ||
2580 | case XGBE_MDIO_RESET_I2C_GPIO: | ||
2581 | case XGBE_MDIO_RESET_INT_GPIO: | ||
2582 | break; | ||
2583 | default: | ||
2584 | dev_err(pdata->dev, "unsupported MDIO reset (%#x)\n", | ||
2585 | phy_data->mdio_reset); | ||
2586 | return -EINVAL; | ||
2587 | } | ||
2588 | |||
2589 | if (phy_data->mdio_reset == XGBE_MDIO_RESET_I2C_GPIO) { | ||
2590 | phy_data->mdio_reset_addr = XGBE_GPIO_ADDRESS_PCA9555 + | ||
2591 | XP_GET_BITS(reg, XP_PROP_3, | ||
2592 | MDIO_RESET_I2C_ADDR); | ||
2593 | phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3, | ||
2594 | MDIO_RESET_I2C_GPIO); | ||
2595 | } else if (phy_data->mdio_reset == XGBE_MDIO_RESET_INT_GPIO) { | ||
2596 | phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3, | ||
2597 | MDIO_RESET_INT_GPIO); | ||
2598 | } | ||
2599 | |||
2600 | return 0; | ||
2601 | } | ||
2602 | |||
2603 | static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata) | ||
2604 | { | ||
2605 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2606 | |||
2607 | switch (phy_data->port_mode) { | ||
2608 | case XGBE_PORT_MODE_BACKPLANE: | ||
2609 | if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) || | ||
2610 | (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)) | ||
2611 | return false; | ||
2612 | break; | ||
2613 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
2614 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500) | ||
2615 | return false; | ||
2616 | break; | ||
2617 | case XGBE_PORT_MODE_1000BASE_T: | ||
2618 | if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) || | ||
2619 | (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)) | ||
2620 | return false; | ||
2621 | break; | ||
2622 | case XGBE_PORT_MODE_1000BASE_X: | ||
2623 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) | ||
2624 | return false; | ||
2625 | break; | ||
2626 | case XGBE_PORT_MODE_NBASE_T: | ||
2627 | if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) || | ||
2628 | (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) || | ||
2629 | (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500)) | ||
2630 | return false; | ||
2631 | break; | ||
2632 | case XGBE_PORT_MODE_10GBASE_T: | ||
2633 | if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) || | ||
2634 | (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) || | ||
2635 | (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)) | ||
2636 | return false; | ||
2637 | break; | ||
2638 | case XGBE_PORT_MODE_10GBASE_R: | ||
2639 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) | ||
2640 | return false; | ||
2641 | break; | ||
2642 | case XGBE_PORT_MODE_SFP: | ||
2643 | if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) || | ||
2644 | (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) || | ||
2645 | (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)) | ||
2646 | return false; | ||
2647 | break; | ||
2648 | default: | ||
2649 | break; | ||
2650 | } | ||
2651 | |||
2652 | return true; | ||
2653 | } | ||
2654 | |||
2655 | static bool xgbe_phy_conn_type_mismatch(struct xgbe_prv_data *pdata) | ||
2656 | { | ||
2657 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2658 | |||
2659 | switch (phy_data->port_mode) { | ||
2660 | case XGBE_PORT_MODE_BACKPLANE: | ||
2661 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
2662 | if (phy_data->conn_type == XGBE_CONN_TYPE_BACKPLANE) | ||
2663 | return false; | ||
2664 | break; | ||
2665 | case XGBE_PORT_MODE_1000BASE_T: | ||
2666 | case XGBE_PORT_MODE_1000BASE_X: | ||
2667 | case XGBE_PORT_MODE_NBASE_T: | ||
2668 | case XGBE_PORT_MODE_10GBASE_T: | ||
2669 | case XGBE_PORT_MODE_10GBASE_R: | ||
2670 | if (phy_data->conn_type == XGBE_CONN_TYPE_MDIO) | ||
2671 | return false; | ||
2672 | break; | ||
2673 | case XGBE_PORT_MODE_SFP: | ||
2674 | if (phy_data->conn_type == XGBE_CONN_TYPE_SFP) | ||
2675 | return false; | ||
2676 | break; | ||
2677 | default: | ||
2678 | break; | ||
2679 | } | ||
2680 | |||
2681 | return true; | ||
2682 | } | ||
2683 | |||
2684 | static bool xgbe_phy_port_enabled(struct xgbe_prv_data *pdata) | ||
2685 | { | ||
2686 | unsigned int reg; | ||
2687 | |||
2688 | reg = XP_IOREAD(pdata, XP_PROP_0); | ||
2689 | if (!XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS)) | ||
2690 | return false; | ||
2691 | if (!XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE)) | ||
2692 | return false; | ||
2693 | |||
2694 | return true; | ||
2695 | } | ||
2696 | |||
2697 | static void xgbe_phy_stop(struct xgbe_prv_data *pdata) | ||
2698 | { | ||
2699 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2700 | |||
2701 | /* If we have an external PHY, free it */ | ||
2702 | xgbe_phy_free_phy_device(pdata); | ||
2703 | |||
2704 | /* Reset SFP data */ | ||
2705 | xgbe_phy_sfp_reset(phy_data); | ||
2706 | xgbe_phy_sfp_mod_absent(pdata); | ||
2707 | |||
2708 | /* Power off the PHY */ | ||
2709 | xgbe_phy_power_off(pdata); | ||
2710 | |||
2711 | /* Stop the I2C controller */ | ||
2712 | pdata->i2c_if.i2c_stop(pdata); | ||
2713 | } | ||
2714 | |||
2715 | static int xgbe_phy_start(struct xgbe_prv_data *pdata) | ||
2716 | { | ||
2717 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2718 | int ret; | ||
2719 | |||
2720 | /* Start the I2C controller */ | ||
2721 | ret = pdata->i2c_if.i2c_start(pdata); | ||
2722 | if (ret) | ||
2723 | return ret; | ||
2724 | |||
2725 | /* Start in highest supported mode */ | ||
2726 | xgbe_phy_set_mode(pdata, phy_data->start_mode); | ||
2727 | |||
2728 | /* After starting the I2C controller, we can check for an SFP */ | ||
2729 | switch (phy_data->port_mode) { | ||
2730 | case XGBE_PORT_MODE_SFP: | ||
2731 | xgbe_phy_sfp_detect(pdata); | ||
2732 | break; | ||
2733 | default: | ||
2734 | break; | ||
2735 | } | ||
2736 | |||
2737 | /* If we have an external PHY, start it */ | ||
2738 | ret = xgbe_phy_find_phy_device(pdata); | ||
2739 | if (ret) | ||
2740 | goto err_i2c; | ||
2741 | |||
2742 | return 0; | ||
2743 | |||
2744 | err_i2c: | ||
2745 | pdata->i2c_if.i2c_stop(pdata); | ||
2746 | |||
2747 | return ret; | ||
2748 | } | ||
2749 | |||
2750 | static int xgbe_phy_reset(struct xgbe_prv_data *pdata) | ||
2751 | { | ||
2752 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2753 | enum xgbe_mode cur_mode; | ||
2754 | int ret; | ||
2755 | |||
2756 | /* Reset by power cycling the PHY */ | ||
2757 | cur_mode = phy_data->cur_mode; | ||
2758 | xgbe_phy_power_off(pdata); | ||
2759 | xgbe_phy_set_mode(pdata, cur_mode); | ||
2760 | |||
2761 | if (!phy_data->phydev) | ||
2762 | return 0; | ||
2763 | |||
2764 | /* Reset the external PHY */ | ||
2765 | ret = xgbe_phy_mdio_reset(pdata); | ||
2766 | if (ret) | ||
2767 | return ret; | ||
2768 | |||
2769 | return phy_init_hw(phy_data->phydev); | ||
2770 | } | ||
2771 | |||
2772 | static void xgbe_phy_exit(struct xgbe_prv_data *pdata) | ||
2773 | { | ||
2774 | struct xgbe_phy_data *phy_data = pdata->phy_data; | ||
2775 | |||
2776 | /* Unregister for driving external PHYs */ | ||
2777 | mdiobus_unregister(phy_data->mii); | ||
2778 | } | ||
2779 | |||
2780 | static int xgbe_phy_init(struct xgbe_prv_data *pdata) | ||
2781 | { | ||
2782 | struct xgbe_phy_data *phy_data; | ||
2783 | struct mii_bus *mii; | ||
2784 | unsigned int reg; | ||
2785 | int ret; | ||
2786 | |||
2787 | /* Check if enabled */ | ||
2788 | if (!xgbe_phy_port_enabled(pdata)) { | ||
2789 | dev_info(pdata->dev, "device is not enabled\n"); | ||
2790 | return -ENODEV; | ||
2791 | } | ||
2792 | |||
2793 | /* Initialize the I2C controller */ | ||
2794 | ret = pdata->i2c_if.i2c_init(pdata); | ||
2795 | if (ret) | ||
2796 | return ret; | ||
2797 | |||
2798 | phy_data = devm_kzalloc(pdata->dev, sizeof(*phy_data), GFP_KERNEL); | ||
2799 | if (!phy_data) | ||
2800 | return -ENOMEM; | ||
2801 | pdata->phy_data = phy_data; | ||
2802 | |||
2803 | reg = XP_IOREAD(pdata, XP_PROP_0); | ||
2804 | phy_data->port_mode = XP_GET_BITS(reg, XP_PROP_0, PORT_MODE); | ||
2805 | phy_data->port_id = XP_GET_BITS(reg, XP_PROP_0, PORT_ID); | ||
2806 | phy_data->port_speeds = XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS); | ||
2807 | phy_data->conn_type = XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE); | ||
2808 | phy_data->mdio_addr = XP_GET_BITS(reg, XP_PROP_0, MDIO_ADDR); | ||
2809 | if (netif_msg_probe(pdata)) { | ||
2810 | dev_dbg(pdata->dev, "port mode=%u\n", phy_data->port_mode); | ||
2811 | dev_dbg(pdata->dev, "port id=%u\n", phy_data->port_id); | ||
2812 | dev_dbg(pdata->dev, "port speeds=%#x\n", phy_data->port_speeds); | ||
2813 | dev_dbg(pdata->dev, "conn type=%u\n", phy_data->conn_type); | ||
2814 | dev_dbg(pdata->dev, "mdio addr=%u\n", phy_data->mdio_addr); | ||
2815 | } | ||
2816 | |||
2817 | reg = XP_IOREAD(pdata, XP_PROP_4); | ||
2818 | phy_data->redrv = XP_GET_BITS(reg, XP_PROP_4, REDRV_PRESENT); | ||
2819 | phy_data->redrv_if = XP_GET_BITS(reg, XP_PROP_4, REDRV_IF); | ||
2820 | phy_data->redrv_addr = XP_GET_BITS(reg, XP_PROP_4, REDRV_ADDR); | ||
2821 | phy_data->redrv_lane = XP_GET_BITS(reg, XP_PROP_4, REDRV_LANE); | ||
2822 | phy_data->redrv_model = XP_GET_BITS(reg, XP_PROP_4, REDRV_MODEL); | ||
2823 | if (phy_data->redrv && netif_msg_probe(pdata)) { | ||
2824 | dev_dbg(pdata->dev, "redrv present\n"); | ||
2825 | dev_dbg(pdata->dev, "redrv i/f=%u\n", phy_data->redrv_if); | ||
2826 | dev_dbg(pdata->dev, "redrv addr=%#x\n", phy_data->redrv_addr); | ||
2827 | dev_dbg(pdata->dev, "redrv lane=%u\n", phy_data->redrv_lane); | ||
2828 | dev_dbg(pdata->dev, "redrv model=%u\n", phy_data->redrv_model); | ||
2829 | } | ||
2830 | |||
2831 | /* Validate the connection requested */ | ||
2832 | if (xgbe_phy_conn_type_mismatch(pdata)) { | ||
2833 | dev_err(pdata->dev, "phy mode/connection mismatch (%#x/%#x)\n", | ||
2834 | phy_data->port_mode, phy_data->conn_type); | ||
2835 | } | ||
2836 | |||
2837 | /* Validate the mode requested */ | ||
2838 | if (xgbe_phy_port_mode_mismatch(pdata)) { | ||
2839 | dev_err(pdata->dev, "phy mode/speed mismatch (%#x/%#x)\n", | ||
2840 | phy_data->port_mode, phy_data->port_speeds); | ||
2841 | return -EINVAL; | ||
2842 | } | ||
2843 | |||
2844 | /* Check for and validate MDIO reset support */ | ||
2845 | ret = xgbe_phy_mdio_reset_setup(pdata); | ||
2846 | if (ret) | ||
2847 | return ret; | ||
2848 | |||
2849 | /* Validate the re-driver information */ | ||
2850 | if (xgbe_phy_redrv_error(phy_data)) { | ||
2851 | dev_err(pdata->dev, "phy re-driver settings error\n"); | ||
2852 | return -EINVAL; | ||
2853 | } | ||
2854 | pdata->kr_redrv = phy_data->redrv; | ||
2855 | |||
2856 | /* Indicate current mode is unknown */ | ||
2857 | phy_data->cur_mode = XGBE_MODE_UNKNOWN; | ||
2858 | |||
2859 | /* Initialize supported features */ | ||
2860 | pdata->phy.supported = 0; | ||
2861 | |||
2862 | switch (phy_data->port_mode) { | ||
2863 | /* Backplane support */ | ||
2864 | case XGBE_PORT_MODE_BACKPLANE: | ||
2865 | pdata->phy.supported |= SUPPORTED_Autoneg; | ||
2866 | pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
2867 | pdata->phy.supported |= SUPPORTED_Backplane; | ||
2868 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) { | ||
2869 | pdata->phy.supported |= SUPPORTED_1000baseKX_Full; | ||
2870 | phy_data->start_mode = XGBE_MODE_KX_1000; | ||
2871 | } | ||
2872 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) { | ||
2873 | pdata->phy.supported |= SUPPORTED_10000baseKR_Full; | ||
2874 | if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) | ||
2875 | pdata->phy.supported |= | ||
2876 | SUPPORTED_10000baseR_FEC; | ||
2877 | phy_data->start_mode = XGBE_MODE_KR; | ||
2878 | } | ||
2879 | |||
2880 | phy_data->phydev_mode = XGBE_MDIO_MODE_NONE; | ||
2881 | break; | ||
2882 | case XGBE_PORT_MODE_BACKPLANE_2500: | ||
2883 | pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
2884 | pdata->phy.supported |= SUPPORTED_Backplane; | ||
2885 | pdata->phy.supported |= SUPPORTED_2500baseX_Full; | ||
2886 | phy_data->start_mode = XGBE_MODE_KX_2500; | ||
2887 | |||
2888 | phy_data->phydev_mode = XGBE_MDIO_MODE_NONE; | ||
2889 | break; | ||
2890 | |||
2891 | /* MDIO 1GBase-T support */ | ||
2892 | case XGBE_PORT_MODE_1000BASE_T: | ||
2893 | pdata->phy.supported |= SUPPORTED_Autoneg; | ||
2894 | pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
2895 | pdata->phy.supported |= SUPPORTED_TP; | ||
2896 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) { | ||
2897 | pdata->phy.supported |= SUPPORTED_100baseT_Full; | ||
2898 | phy_data->start_mode = XGBE_MODE_SGMII_100; | ||
2899 | } | ||
2900 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) { | ||
2901 | pdata->phy.supported |= SUPPORTED_1000baseT_Full; | ||
2902 | phy_data->start_mode = XGBE_MODE_SGMII_1000; | ||
2903 | } | ||
2904 | |||
2905 | phy_data->phydev_mode = XGBE_MDIO_MODE_CL22; | ||
2906 | break; | ||
2907 | |||
2908 | /* MDIO Base-X support */ | ||
2909 | case XGBE_PORT_MODE_1000BASE_X: | ||
2910 | pdata->phy.supported |= SUPPORTED_Autoneg; | ||
2911 | pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
2912 | pdata->phy.supported |= SUPPORTED_FIBRE; | ||
2913 | pdata->phy.supported |= SUPPORTED_1000baseT_Full; | ||
2914 | phy_data->start_mode = XGBE_MODE_X; | ||
2915 | |||
2916 | phy_data->phydev_mode = XGBE_MDIO_MODE_CL22; | ||
2917 | break; | ||
2918 | |||
2919 | /* MDIO NBase-T support */ | ||
2920 | case XGBE_PORT_MODE_NBASE_T: | ||
2921 | pdata->phy.supported |= SUPPORTED_Autoneg; | ||
2922 | pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
2923 | pdata->phy.supported |= SUPPORTED_TP; | ||
2924 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) { | ||
2925 | pdata->phy.supported |= SUPPORTED_100baseT_Full; | ||
2926 | phy_data->start_mode = XGBE_MODE_SGMII_100; | ||
2927 | } | ||
2928 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) { | ||
2929 | pdata->phy.supported |= SUPPORTED_1000baseT_Full; | ||
2930 | phy_data->start_mode = XGBE_MODE_SGMII_1000; | ||
2931 | } | ||
2932 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500) { | ||
2933 | pdata->phy.supported |= SUPPORTED_2500baseX_Full; | ||
2934 | phy_data->start_mode = XGBE_MODE_KX_2500; | ||
2935 | } | ||
2936 | |||
2937 | phy_data->phydev_mode = XGBE_MDIO_MODE_CL45; | ||
2938 | break; | ||
2939 | |||
2940 | /* 10GBase-T support */ | ||
2941 | case XGBE_PORT_MODE_10GBASE_T: | ||
2942 | pdata->phy.supported |= SUPPORTED_Autoneg; | ||
2943 | pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
2944 | pdata->phy.supported |= SUPPORTED_TP; | ||
2945 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) { | ||
2946 | pdata->phy.supported |= SUPPORTED_100baseT_Full; | ||
2947 | phy_data->start_mode = XGBE_MODE_SGMII_100; | ||
2948 | } | ||
2949 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) { | ||
2950 | pdata->phy.supported |= SUPPORTED_1000baseT_Full; | ||
2951 | phy_data->start_mode = XGBE_MODE_SGMII_1000; | ||
2952 | } | ||
2953 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) { | ||
2954 | pdata->phy.supported |= SUPPORTED_10000baseT_Full; | ||
2955 | phy_data->start_mode = XGBE_MODE_KR; | ||
2956 | } | ||
2957 | |||
2958 | phy_data->phydev_mode = XGBE_MDIO_MODE_NONE; | ||
2959 | break; | ||
2960 | |||
2961 | /* 10GBase-R support */ | ||
2962 | case XGBE_PORT_MODE_10GBASE_R: | ||
2963 | pdata->phy.supported |= SUPPORTED_Autoneg; | ||
2964 | pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
2965 | pdata->phy.supported |= SUPPORTED_TP; | ||
2966 | pdata->phy.supported |= SUPPORTED_10000baseT_Full; | ||
2967 | if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) | ||
2968 | pdata->phy.supported |= SUPPORTED_10000baseR_FEC; | ||
2969 | phy_data->start_mode = XGBE_MODE_SFI; | ||
2970 | |||
2971 | phy_data->phydev_mode = XGBE_MDIO_MODE_NONE; | ||
2972 | break; | ||
2973 | |||
2974 | /* SFP support */ | ||
2975 | case XGBE_PORT_MODE_SFP: | ||
2976 | pdata->phy.supported |= SUPPORTED_Autoneg; | ||
2977 | pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
2978 | pdata->phy.supported |= SUPPORTED_TP; | ||
2979 | pdata->phy.supported |= SUPPORTED_FIBRE; | ||
2980 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) { | ||
2981 | pdata->phy.supported |= SUPPORTED_100baseT_Full; | ||
2982 | phy_data->start_mode = XGBE_MODE_SGMII_100; | ||
2983 | } | ||
2984 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) { | ||
2985 | pdata->phy.supported |= SUPPORTED_1000baseT_Full; | ||
2986 | phy_data->start_mode = XGBE_MODE_SGMII_1000; | ||
2987 | } | ||
2988 | if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) { | ||
2989 | pdata->phy.supported |= SUPPORTED_10000baseT_Full; | ||
2990 | phy_data->start_mode = XGBE_MODE_SFI; | ||
2991 | if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) | ||
2992 | pdata->phy.supported |= | ||
2993 | SUPPORTED_10000baseR_FEC; | ||
2994 | } | ||
2995 | |||
2996 | phy_data->phydev_mode = XGBE_MDIO_MODE_CL22; | ||
2997 | |||
2998 | xgbe_phy_sfp_setup(pdata); | ||
2999 | break; | ||
3000 | default: | ||
3001 | return -EINVAL; | ||
3002 | } | ||
3003 | |||
3004 | if (netif_msg_probe(pdata)) | ||
3005 | dev_dbg(pdata->dev, "phy supported=%#x\n", | ||
3006 | pdata->phy.supported); | ||
3007 | |||
3008 | if ((phy_data->conn_type & XGBE_CONN_TYPE_MDIO) && | ||
3009 | (phy_data->phydev_mode != XGBE_MDIO_MODE_NONE)) { | ||
3010 | ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->mdio_addr, | ||
3011 | phy_data->phydev_mode); | ||
3012 | if (ret) { | ||
3013 | dev_err(pdata->dev, | ||
3014 | "mdio port/clause not compatible (%d/%u)\n", | ||
3015 | phy_data->mdio_addr, phy_data->phydev_mode); | ||
3016 | return -EINVAL; | ||
3017 | } | ||
3018 | } | ||
3019 | |||
3020 | if (phy_data->redrv && !phy_data->redrv_if) { | ||
3021 | ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->redrv_addr, | ||
3022 | XGBE_MDIO_MODE_CL22); | ||
3023 | if (ret) { | ||
3024 | dev_err(pdata->dev, | ||
3025 | "redriver mdio port not compatible (%u)\n", | ||
3026 | phy_data->redrv_addr); | ||
3027 | return -EINVAL; | ||
3028 | } | ||
3029 | } | ||
3030 | |||
3031 | /* Register for driving external PHYs */ | ||
3032 | mii = devm_mdiobus_alloc(pdata->dev); | ||
3033 | if (!mii) { | ||
3034 | dev_err(pdata->dev, "mdiobus_alloc failed\n"); | ||
3035 | return -ENOMEM; | ||
3036 | } | ||
3037 | |||
3038 | mii->priv = pdata; | ||
3039 | mii->name = "amd-xgbe-mii"; | ||
3040 | mii->read = xgbe_phy_mii_read; | ||
3041 | mii->write = xgbe_phy_mii_write; | ||
3042 | mii->parent = pdata->dev; | ||
3043 | mii->phy_mask = ~0; | ||
3044 | snprintf(mii->id, sizeof(mii->id), "%s", dev_name(pdata->dev)); | ||
3045 | ret = mdiobus_register(mii); | ||
3046 | if (ret) { | ||
3047 | dev_err(pdata->dev, "mdiobus_register failed\n"); | ||
3048 | return ret; | ||
3049 | } | ||
3050 | phy_data->mii = mii; | ||
3051 | |||
3052 | return 0; | ||
3053 | } | ||
3054 | |||
3055 | void xgbe_init_function_ptrs_phy_v2(struct xgbe_phy_if *phy_if) | ||
3056 | { | ||
3057 | struct xgbe_phy_impl_if *phy_impl = &phy_if->phy_impl; | ||
3058 | |||
3059 | phy_impl->init = xgbe_phy_init; | ||
3060 | phy_impl->exit = xgbe_phy_exit; | ||
3061 | |||
3062 | phy_impl->reset = xgbe_phy_reset; | ||
3063 | phy_impl->start = xgbe_phy_start; | ||
3064 | phy_impl->stop = xgbe_phy_stop; | ||
3065 | |||
3066 | phy_impl->link_status = xgbe_phy_link_status; | ||
3067 | |||
3068 | phy_impl->valid_speed = xgbe_phy_valid_speed; | ||
3069 | |||
3070 | phy_impl->use_mode = xgbe_phy_use_mode; | ||
3071 | phy_impl->set_mode = xgbe_phy_set_mode; | ||
3072 | phy_impl->get_mode = xgbe_phy_get_mode; | ||
3073 | phy_impl->switch_mode = xgbe_phy_switch_mode; | ||
3074 | phy_impl->cur_mode = xgbe_phy_cur_mode; | ||
3075 | |||
3076 | phy_impl->an_mode = xgbe_phy_an_mode; | ||
3077 | |||
3078 | phy_impl->an_config = xgbe_phy_an_config; | ||
3079 | |||
3080 | phy_impl->an_advertising = xgbe_phy_an_advertising; | ||
3081 | |||
3082 | phy_impl->an_outcome = xgbe_phy_an_outcome; | ||
3083 | } | ||
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-platform.c b/drivers/net/ethernet/amd/xgbe/xgbe-platform.c index 0edbcd523f8f..8c530dccb447 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-platform.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-platform.c | |||
@@ -426,8 +426,10 @@ static int xgbe_platform_probe(struct platform_device *pdev) | |||
426 | pdata->phy_mode = PHY_INTERFACE_MODE_XGMII; | 426 | pdata->phy_mode = PHY_INTERFACE_MODE_XGMII; |
427 | 427 | ||
428 | /* Check for per channel interrupt support */ | 428 | /* Check for per channel interrupt support */ |
429 | if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY)) | 429 | if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY)) { |
430 | pdata->per_channel_irq = 1; | 430 | pdata->per_channel_irq = 1; |
431 | pdata->channel_irq_mode = XGBE_IRQ_MODE_EDGE; | ||
432 | } | ||
431 | 433 | ||
432 | /* Obtain device settings unique to ACPI/OF */ | 434 | /* Obtain device settings unique to ACPI/OF */ |
433 | if (pdata->use_acpi) | 435 | if (pdata->use_acpi) |
@@ -462,6 +464,9 @@ static int xgbe_platform_probe(struct platform_device *pdev) | |||
462 | /* Set the hardware channel and queue counts */ | 464 | /* Set the hardware channel and queue counts */ |
463 | xgbe_set_counts(pdata); | 465 | xgbe_set_counts(pdata); |
464 | 466 | ||
467 | /* Always have XGMAC and XPCS (auto-negotiation) interrupts */ | ||
468 | pdata->irq_count = 2; | ||
469 | |||
465 | /* Get the device interrupt */ | 470 | /* Get the device interrupt */ |
466 | ret = platform_get_irq(pdev, 0); | 471 | ret = platform_get_irq(pdev, 0); |
467 | if (ret < 0) { | 472 | if (ret < 0) { |
@@ -485,6 +490,10 @@ static int xgbe_platform_probe(struct platform_device *pdev) | |||
485 | 490 | ||
486 | pdata->channel_irq[i] = ret; | 491 | pdata->channel_irq[i] = ret; |
487 | } | 492 | } |
493 | |||
494 | pdata->channel_irq_count = max; | ||
495 | |||
496 | pdata->irq_count += max; | ||
488 | } | 497 | } |
489 | 498 | ||
490 | /* Get the auto-negotiation interrupt */ | 499 | /* Get the auto-negotiation interrupt */ |
@@ -581,6 +590,7 @@ static const struct xgbe_version_data xgbe_v1 = { | |||
581 | .xpcs_access = XGBE_XPCS_ACCESS_V1, | 590 | .xpcs_access = XGBE_XPCS_ACCESS_V1, |
582 | .tx_max_fifo_size = 81920, | 591 | .tx_max_fifo_size = 81920, |
583 | .rx_max_fifo_size = 81920, | 592 | .rx_max_fifo_size = 81920, |
593 | .tx_tstamp_workaround = 1, | ||
584 | }; | 594 | }; |
585 | 595 | ||
586 | #ifdef CONFIG_ACPI | 596 | #ifdef CONFIG_ACPI |
@@ -608,7 +618,7 @@ static SIMPLE_DEV_PM_OPS(xgbe_platform_pm_ops, | |||
608 | 618 | ||
609 | static struct platform_driver xgbe_driver = { | 619 | static struct platform_driver xgbe_driver = { |
610 | .driver = { | 620 | .driver = { |
611 | .name = "amd-xgbe", | 621 | .name = XGBE_DRV_NAME, |
612 | #ifdef CONFIG_ACPI | 622 | #ifdef CONFIG_ACPI |
613 | .acpi_match_table = xgbe_acpi_match, | 623 | .acpi_match_table = xgbe_acpi_match, |
614 | #endif | 624 | #endif |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 0779247057fb..f52a9bd05bac 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h | |||
@@ -127,6 +127,7 @@ | |||
127 | #include <linux/timecounter.h> | 127 | #include <linux/timecounter.h> |
128 | #include <linux/net_tstamp.h> | 128 | #include <linux/net_tstamp.h> |
129 | #include <net/dcbnl.h> | 129 | #include <net/dcbnl.h> |
130 | #include <linux/completion.h> | ||
130 | 131 | ||
131 | #define XGBE_DRV_NAME "amd-xgbe" | 132 | #define XGBE_DRV_NAME "amd-xgbe" |
132 | #define XGBE_DRV_VERSION "1.0.3" | 133 | #define XGBE_DRV_VERSION "1.0.3" |
@@ -171,6 +172,10 @@ | |||
171 | #define XGBE_DMA_SYS_ARCACHE 0x0 | 172 | #define XGBE_DMA_SYS_ARCACHE 0x0 |
172 | #define XGBE_DMA_SYS_AWCACHE 0x0 | 173 | #define XGBE_DMA_SYS_AWCACHE 0x0 |
173 | 174 | ||
175 | /* DMA channel interrupt modes */ | ||
176 | #define XGBE_IRQ_MODE_EDGE 0 | ||
177 | #define XGBE_IRQ_MODE_LEVEL 1 | ||
178 | |||
174 | #define XGBE_DMA_INTERRUPT_MASK 0x31c7 | 179 | #define XGBE_DMA_INTERRUPT_MASK 0x31c7 |
175 | 180 | ||
176 | #define XGMAC_MIN_PACKET 60 | 181 | #define XGMAC_MIN_PACKET 60 |
@@ -200,6 +205,20 @@ | |||
200 | #define XGBE_ACPI_DMA_FREQ "amd,dma-freq" | 205 | #define XGBE_ACPI_DMA_FREQ "amd,dma-freq" |
201 | #define XGBE_ACPI_PTP_FREQ "amd,ptp-freq" | 206 | #define XGBE_ACPI_PTP_FREQ "amd,ptp-freq" |
202 | 207 | ||
208 | /* PCI BAR mapping */ | ||
209 | #define XGBE_XGMAC_BAR 0 | ||
210 | #define XGBE_XPCS_BAR 1 | ||
211 | #define XGBE_MAC_PROP_OFFSET 0x1d000 | ||
212 | #define XGBE_I2C_CTRL_OFFSET 0x1e000 | ||
213 | |||
214 | /* PCI MSIx support */ | ||
215 | #define XGBE_MSIX_BASE_COUNT 4 | ||
216 | #define XGBE_MSIX_MIN_COUNT (XGBE_MSIX_BASE_COUNT + 1) | ||
217 | |||
218 | /* PCI clock frequencies */ | ||
219 | #define XGBE_V2_DMA_CLOCK_FREQ 500000000 /* 500 MHz */ | ||
220 | #define XGBE_V2_PTP_CLOCK_FREQ 125000000 /* 125 MHz */ | ||
221 | |||
203 | /* Timestamp support - values based on 50MHz PTP clock | 222 | /* Timestamp support - values based on 50MHz PTP clock |
204 | * 50MHz => 20 nsec | 223 | * 50MHz => 20 nsec |
205 | */ | 224 | */ |
@@ -267,6 +286,12 @@ | |||
267 | #define XGBE_SGMII_AN_LINK_SPEED_1000 0x08 | 286 | #define XGBE_SGMII_AN_LINK_SPEED_1000 0x08 |
268 | #define XGBE_SGMII_AN_LINK_DUPLEX BIT(4) | 287 | #define XGBE_SGMII_AN_LINK_DUPLEX BIT(4) |
269 | 288 | ||
289 | /* ECC correctable error notification window (seconds) */ | ||
290 | #define XGBE_ECC_LIMIT 60 | ||
291 | |||
292 | /* MDIO port types */ | ||
293 | #define XGMAC_MAX_C22_PORT 3 | ||
294 | |||
270 | struct xgbe_prv_data; | 295 | struct xgbe_prv_data; |
271 | 296 | ||
272 | struct xgbe_packet_data { | 297 | struct xgbe_packet_data { |
@@ -443,6 +468,7 @@ enum xgbe_state { | |||
443 | XGBE_DOWN, | 468 | XGBE_DOWN, |
444 | XGBE_LINK_INIT, | 469 | XGBE_LINK_INIT, |
445 | XGBE_LINK_ERR, | 470 | XGBE_LINK_ERR, |
471 | XGBE_STOPPED, | ||
446 | }; | 472 | }; |
447 | 473 | ||
448 | enum xgbe_int { | 474 | enum xgbe_int { |
@@ -462,6 +488,12 @@ enum xgbe_int_state { | |||
462 | XGMAC_INT_STATE_RESTORE, | 488 | XGMAC_INT_STATE_RESTORE, |
463 | }; | 489 | }; |
464 | 490 | ||
491 | enum xgbe_ecc_sec { | ||
492 | XGBE_ECC_SEC_TX, | ||
493 | XGBE_ECC_SEC_RX, | ||
494 | XGBE_ECC_SEC_DESC, | ||
495 | }; | ||
496 | |||
465 | enum xgbe_speed { | 497 | enum xgbe_speed { |
466 | XGBE_SPEED_1000 = 0, | 498 | XGBE_SPEED_1000 = 0, |
467 | XGBE_SPEED_2500, | 499 | XGBE_SPEED_2500, |
@@ -476,6 +508,7 @@ enum xgbe_xpcs_access { | |||
476 | 508 | ||
477 | enum xgbe_an_mode { | 509 | enum xgbe_an_mode { |
478 | XGBE_AN_MODE_CL73 = 0, | 510 | XGBE_AN_MODE_CL73 = 0, |
511 | XGBE_AN_MODE_CL73_REDRV, | ||
479 | XGBE_AN_MODE_CL37, | 512 | XGBE_AN_MODE_CL37, |
480 | XGBE_AN_MODE_CL37_SGMII, | 513 | XGBE_AN_MODE_CL37_SGMII, |
481 | XGBE_AN_MODE_NONE, | 514 | XGBE_AN_MODE_NONE, |
@@ -501,6 +534,10 @@ enum xgbe_mode { | |||
501 | XGBE_MODE_KX_1000 = 0, | 534 | XGBE_MODE_KX_1000 = 0, |
502 | XGBE_MODE_KX_2500, | 535 | XGBE_MODE_KX_2500, |
503 | XGBE_MODE_KR, | 536 | XGBE_MODE_KR, |
537 | XGBE_MODE_X, | ||
538 | XGBE_MODE_SGMII_100, | ||
539 | XGBE_MODE_SGMII_1000, | ||
540 | XGBE_MODE_SFI, | ||
504 | XGBE_MODE_UNKNOWN, | 541 | XGBE_MODE_UNKNOWN, |
505 | }; | 542 | }; |
506 | 543 | ||
@@ -509,6 +546,12 @@ enum xgbe_speedset { | |||
509 | XGBE_SPEEDSET_2500_10000, | 546 | XGBE_SPEEDSET_2500_10000, |
510 | }; | 547 | }; |
511 | 548 | ||
549 | enum xgbe_mdio_mode { | ||
550 | XGBE_MDIO_MODE_NONE = 0, | ||
551 | XGBE_MDIO_MODE_CL22, | ||
552 | XGBE_MDIO_MODE_CL45, | ||
553 | }; | ||
554 | |||
512 | struct xgbe_phy { | 555 | struct xgbe_phy { |
513 | u32 supported; | 556 | u32 supported; |
514 | u32 advertising; | 557 | u32 advertising; |
@@ -527,6 +570,43 @@ struct xgbe_phy { | |||
527 | int rx_pause; | 570 | int rx_pause; |
528 | }; | 571 | }; |
529 | 572 | ||
573 | enum xgbe_i2c_cmd { | ||
574 | XGBE_I2C_CMD_READ = 0, | ||
575 | XGBE_I2C_CMD_WRITE, | ||
576 | }; | ||
577 | |||
578 | struct xgbe_i2c_op { | ||
579 | enum xgbe_i2c_cmd cmd; | ||
580 | |||
581 | unsigned int target; | ||
582 | |||
583 | void *buf; | ||
584 | unsigned int len; | ||
585 | }; | ||
586 | |||
587 | struct xgbe_i2c_op_state { | ||
588 | struct xgbe_i2c_op *op; | ||
589 | |||
590 | unsigned int tx_len; | ||
591 | unsigned char *tx_buf; | ||
592 | |||
593 | unsigned int rx_len; | ||
594 | unsigned char *rx_buf; | ||
595 | |||
596 | unsigned int tx_abort_source; | ||
597 | |||
598 | int ret; | ||
599 | }; | ||
600 | |||
601 | struct xgbe_i2c { | ||
602 | unsigned int started; | ||
603 | unsigned int max_speed_mode; | ||
604 | unsigned int rx_fifo_size; | ||
605 | unsigned int tx_fifo_size; | ||
606 | |||
607 | struct xgbe_i2c_op_state op_state; | ||
608 | }; | ||
609 | |||
530 | struct xgbe_mmc_stats { | 610 | struct xgbe_mmc_stats { |
531 | /* Tx Stats */ | 611 | /* Tx Stats */ |
532 | u64 txoctetcount_gb; | 612 | u64 txoctetcount_gb; |
@@ -599,6 +679,14 @@ struct xgbe_hw_if { | |||
599 | void (*write_mmd_regs)(struct xgbe_prv_data *, int, int, int); | 679 | void (*write_mmd_regs)(struct xgbe_prv_data *, int, int, int); |
600 | int (*set_speed)(struct xgbe_prv_data *, int); | 680 | int (*set_speed)(struct xgbe_prv_data *, int); |
601 | 681 | ||
682 | int (*set_ext_mii_mode)(struct xgbe_prv_data *, unsigned int, | ||
683 | enum xgbe_mdio_mode); | ||
684 | int (*read_ext_mii_regs)(struct xgbe_prv_data *, int, int); | ||
685 | int (*write_ext_mii_regs)(struct xgbe_prv_data *, int, int, u16); | ||
686 | |||
687 | int (*set_gpio)(struct xgbe_prv_data *, unsigned int); | ||
688 | int (*clr_gpio)(struct xgbe_prv_data *, unsigned int); | ||
689 | |||
602 | void (*enable_tx)(struct xgbe_prv_data *); | 690 | void (*enable_tx)(struct xgbe_prv_data *); |
603 | void (*disable_tx)(struct xgbe_prv_data *); | 691 | void (*disable_tx)(struct xgbe_prv_data *); |
604 | void (*enable_rx)(struct xgbe_prv_data *); | 692 | void (*enable_rx)(struct xgbe_prv_data *); |
@@ -676,6 +764,10 @@ struct xgbe_hw_if { | |||
676 | int (*disable_rss)(struct xgbe_prv_data *); | 764 | int (*disable_rss)(struct xgbe_prv_data *); |
677 | int (*set_rss_hash_key)(struct xgbe_prv_data *, const u8 *); | 765 | int (*set_rss_hash_key)(struct xgbe_prv_data *, const u8 *); |
678 | int (*set_rss_lookup_table)(struct xgbe_prv_data *, const u32 *); | 766 | int (*set_rss_lookup_table)(struct xgbe_prv_data *, const u32 *); |
767 | |||
768 | /* For ECC */ | ||
769 | void (*disable_ecc_ded)(struct xgbe_prv_data *); | ||
770 | void (*disable_ecc_sec)(struct xgbe_prv_data *, enum xgbe_ecc_sec); | ||
679 | }; | 771 | }; |
680 | 772 | ||
681 | /* This structure represents implementation specific routines for an | 773 | /* This structure represents implementation specific routines for an |
@@ -694,7 +786,7 @@ struct xgbe_phy_impl_if { | |||
694 | void (*stop)(struct xgbe_prv_data *); | 786 | void (*stop)(struct xgbe_prv_data *); |
695 | 787 | ||
696 | /* Return the link status */ | 788 | /* Return the link status */ |
697 | int (*link_status)(struct xgbe_prv_data *); | 789 | int (*link_status)(struct xgbe_prv_data *, int *); |
698 | 790 | ||
699 | /* Indicate if a particular speed is valid */ | 791 | /* Indicate if a particular speed is valid */ |
700 | bool (*valid_speed)(struct xgbe_prv_data *, int); | 792 | bool (*valid_speed)(struct xgbe_prv_data *, int); |
@@ -713,6 +805,12 @@ struct xgbe_phy_impl_if { | |||
713 | /* Retrieve current auto-negotiation mode */ | 805 | /* Retrieve current auto-negotiation mode */ |
714 | enum xgbe_an_mode (*an_mode)(struct xgbe_prv_data *); | 806 | enum xgbe_an_mode (*an_mode)(struct xgbe_prv_data *); |
715 | 807 | ||
808 | /* Configure auto-negotiation settings */ | ||
809 | int (*an_config)(struct xgbe_prv_data *); | ||
810 | |||
811 | /* Set/override auto-negotiation advertisement settings */ | ||
812 | unsigned int (*an_advertising)(struct xgbe_prv_data *); | ||
813 | |||
716 | /* Process results of auto-negotiation */ | 814 | /* Process results of auto-negotiation */ |
717 | enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *); | 815 | enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *); |
718 | 816 | ||
@@ -738,10 +836,28 @@ struct xgbe_phy_if { | |||
738 | /* For PHY settings validation */ | 836 | /* For PHY settings validation */ |
739 | bool (*phy_valid_speed)(struct xgbe_prv_data *, int); | 837 | bool (*phy_valid_speed)(struct xgbe_prv_data *, int); |
740 | 838 | ||
839 | /* For single interrupt support */ | ||
840 | irqreturn_t (*an_isr)(int, struct xgbe_prv_data *); | ||
841 | |||
741 | /* PHY implementation specific services */ | 842 | /* PHY implementation specific services */ |
742 | struct xgbe_phy_impl_if phy_impl; | 843 | struct xgbe_phy_impl_if phy_impl; |
743 | }; | 844 | }; |
744 | 845 | ||
846 | struct xgbe_i2c_if { | ||
847 | /* For initial I2C setup */ | ||
848 | int (*i2c_init)(struct xgbe_prv_data *); | ||
849 | |||
850 | /* For I2C support when setting device up/down */ | ||
851 | int (*i2c_start)(struct xgbe_prv_data *); | ||
852 | void (*i2c_stop)(struct xgbe_prv_data *); | ||
853 | |||
854 | /* For performing I2C operations */ | ||
855 | int (*i2c_xfer)(struct xgbe_prv_data *, struct xgbe_i2c_op *); | ||
856 | |||
857 | /* For single interrupt support */ | ||
858 | irqreturn_t (*i2c_isr)(int, struct xgbe_prv_data *); | ||
859 | }; | ||
860 | |||
745 | struct xgbe_desc_if { | 861 | struct xgbe_desc_if { |
746 | int (*alloc_ring_resources)(struct xgbe_prv_data *); | 862 | int (*alloc_ring_resources)(struct xgbe_prv_data *); |
747 | void (*free_ring_resources)(struct xgbe_prv_data *); | 863 | void (*free_ring_resources)(struct xgbe_prv_data *); |
@@ -805,10 +921,14 @@ struct xgbe_version_data { | |||
805 | unsigned int mmc_64bit; | 921 | unsigned int mmc_64bit; |
806 | unsigned int tx_max_fifo_size; | 922 | unsigned int tx_max_fifo_size; |
807 | unsigned int rx_max_fifo_size; | 923 | unsigned int rx_max_fifo_size; |
924 | unsigned int tx_tstamp_workaround; | ||
925 | unsigned int ecc_support; | ||
926 | unsigned int i2c_support; | ||
808 | }; | 927 | }; |
809 | 928 | ||
810 | struct xgbe_prv_data { | 929 | struct xgbe_prv_data { |
811 | struct net_device *netdev; | 930 | struct net_device *netdev; |
931 | struct pci_dev *pcidev; | ||
812 | struct platform_device *platdev; | 932 | struct platform_device *platdev; |
813 | struct acpi_device *adev; | 933 | struct acpi_device *adev; |
814 | struct device *dev; | 934 | struct device *dev; |
@@ -827,6 +947,8 @@ struct xgbe_prv_data { | |||
827 | void __iomem *rxtx_regs; /* SerDes Rx/Tx CSRs */ | 947 | void __iomem *rxtx_regs; /* SerDes Rx/Tx CSRs */ |
828 | void __iomem *sir0_regs; /* SerDes integration registers (1/2) */ | 948 | void __iomem *sir0_regs; /* SerDes integration registers (1/2) */ |
829 | void __iomem *sir1_regs; /* SerDes integration registers (2/2) */ | 949 | void __iomem *sir1_regs; /* SerDes integration registers (2/2) */ |
950 | void __iomem *xprop_regs; /* XGBE property registers */ | ||
951 | void __iomem *xi2c_regs; /* XGBE I2C CSRs */ | ||
830 | 952 | ||
831 | /* Overall device lock */ | 953 | /* Overall device lock */ |
832 | spinlock_t lock; | 954 | spinlock_t lock; |
@@ -843,13 +965,39 @@ struct xgbe_prv_data { | |||
843 | /* Flags representing xgbe_state */ | 965 | /* Flags representing xgbe_state */ |
844 | unsigned long dev_state; | 966 | unsigned long dev_state; |
845 | 967 | ||
968 | /* ECC support */ | ||
969 | unsigned long tx_sec_period; | ||
970 | unsigned long tx_ded_period; | ||
971 | unsigned long rx_sec_period; | ||
972 | unsigned long rx_ded_period; | ||
973 | unsigned long desc_sec_period; | ||
974 | unsigned long desc_ded_period; | ||
975 | |||
976 | unsigned int tx_sec_count; | ||
977 | unsigned int tx_ded_count; | ||
978 | unsigned int rx_sec_count; | ||
979 | unsigned int rx_ded_count; | ||
980 | unsigned int desc_ded_count; | ||
981 | unsigned int desc_sec_count; | ||
982 | |||
983 | struct msix_entry *msix_entries; | ||
846 | int dev_irq; | 984 | int dev_irq; |
847 | unsigned int per_channel_irq; | 985 | int ecc_irq; |
986 | int i2c_irq; | ||
848 | int channel_irq[XGBE_MAX_DMA_CHANNELS]; | 987 | int channel_irq[XGBE_MAX_DMA_CHANNELS]; |
849 | 988 | ||
989 | unsigned int per_channel_irq; | ||
990 | unsigned int irq_shared; | ||
991 | unsigned int irq_count; | ||
992 | unsigned int channel_irq_count; | ||
993 | unsigned int channel_irq_mode; | ||
994 | |||
995 | char ecc_name[IFNAMSIZ + 32]; | ||
996 | |||
850 | struct xgbe_hw_if hw_if; | 997 | struct xgbe_hw_if hw_if; |
851 | struct xgbe_phy_if phy_if; | 998 | struct xgbe_phy_if phy_if; |
852 | struct xgbe_desc_if desc_if; | 999 | struct xgbe_desc_if desc_if; |
1000 | struct xgbe_i2c_if i2c_if; | ||
853 | 1001 | ||
854 | /* AXI DMA settings */ | 1002 | /* AXI DMA settings */ |
855 | unsigned int coherent; | 1003 | unsigned int coherent; |
@@ -957,8 +1105,9 @@ struct xgbe_prv_data { | |||
957 | /* Hardware features of the device */ | 1105 | /* Hardware features of the device */ |
958 | struct xgbe_hw_features hw_feat; | 1106 | struct xgbe_hw_features hw_feat; |
959 | 1107 | ||
960 | /* Device restart work structure */ | 1108 | /* Device work structures */ |
961 | struct work_struct restart_work; | 1109 | struct work_struct restart_work; |
1110 | struct work_struct stopdev_work; | ||
962 | 1111 | ||
963 | /* Keeps track of power mode */ | 1112 | /* Keeps track of power mode */ |
964 | unsigned int power_down; | 1113 | unsigned int power_down; |
@@ -977,6 +1126,9 @@ struct xgbe_prv_data { | |||
977 | struct xgbe_phy phy; | 1126 | struct xgbe_phy phy; |
978 | int mdio_mmd; | 1127 | int mdio_mmd; |
979 | unsigned long link_check; | 1128 | unsigned long link_check; |
1129 | struct completion mdio_complete; | ||
1130 | |||
1131 | unsigned int kr_redrv; | ||
980 | 1132 | ||
981 | char an_name[IFNAMSIZ + 32]; | 1133 | char an_name[IFNAMSIZ + 32]; |
982 | struct workqueue_struct *an_workqueue; | 1134 | struct workqueue_struct *an_workqueue; |
@@ -999,6 +1151,12 @@ struct xgbe_prv_data { | |||
999 | unsigned long an_start; | 1151 | unsigned long an_start; |
1000 | enum xgbe_an_mode an_mode; | 1152 | enum xgbe_an_mode an_mode; |
1001 | 1153 | ||
1154 | /* I2C support */ | ||
1155 | struct xgbe_i2c i2c; | ||
1156 | struct mutex i2c_mutex; | ||
1157 | struct completion i2c_complete; | ||
1158 | char i2c_name[IFNAMSIZ + 32]; | ||
1159 | |||
1002 | unsigned int lpm_ctrl; /* CTRL1 for resume */ | 1160 | unsigned int lpm_ctrl; /* CTRL1 for resume */ |
1003 | 1161 | ||
1004 | #ifdef CONFIG_DEBUG_FS | 1162 | #ifdef CONFIG_DEBUG_FS |
@@ -1008,6 +1166,10 @@ struct xgbe_prv_data { | |||
1008 | 1166 | ||
1009 | unsigned int debugfs_xpcs_mmd; | 1167 | unsigned int debugfs_xpcs_mmd; |
1010 | unsigned int debugfs_xpcs_reg; | 1168 | unsigned int debugfs_xpcs_reg; |
1169 | |||
1170 | unsigned int debugfs_xprop_reg; | ||
1171 | |||
1172 | unsigned int debugfs_xi2c_reg; | ||
1011 | #endif | 1173 | #endif |
1012 | }; | 1174 | }; |
1013 | 1175 | ||
@@ -1020,11 +1182,20 @@ void xgbe_deconfig_netdev(struct xgbe_prv_data *); | |||
1020 | 1182 | ||
1021 | int xgbe_platform_init(void); | 1183 | int xgbe_platform_init(void); |
1022 | void xgbe_platform_exit(void); | 1184 | void xgbe_platform_exit(void); |
1185 | #ifdef CONFIG_PCI | ||
1186 | int xgbe_pci_init(void); | ||
1187 | void xgbe_pci_exit(void); | ||
1188 | #else | ||
1189 | static inline int xgbe_pci_init(void) { return 0; } | ||
1190 | static inline void xgbe_pci_exit(void) { } | ||
1191 | #endif | ||
1023 | 1192 | ||
1024 | void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *); | 1193 | void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *); |
1025 | void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *); | 1194 | void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *); |
1026 | void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *); | 1195 | void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *); |
1196 | void xgbe_init_function_ptrs_phy_v2(struct xgbe_phy_if *); | ||
1027 | void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *); | 1197 | void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *); |
1198 | void xgbe_init_function_ptrs_i2c(struct xgbe_i2c_if *); | ||
1028 | const struct net_device_ops *xgbe_get_netdev_ops(void); | 1199 | const struct net_device_ops *xgbe_get_netdev_ops(void); |
1029 | const struct ethtool_ops *xgbe_get_ethtool_ops(void); | 1200 | const struct ethtool_ops *xgbe_get_ethtool_ops(void); |
1030 | 1201 | ||
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 2f94c60d4939..e6dd222fddb1 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -143,13 +143,14 @@ static int phy_config_interrupt(struct phy_device *phydev, u32 interrupts) | |||
143 | * Returns > 0 on success or < 0 on error. 0 means that auto-negotiation | 143 | * Returns > 0 on success or < 0 on error. 0 means that auto-negotiation |
144 | * is still pending. | 144 | * is still pending. |
145 | */ | 145 | */ |
146 | static inline int phy_aneg_done(struct phy_device *phydev) | 146 | int phy_aneg_done(struct phy_device *phydev) |
147 | { | 147 | { |
148 | if (phydev->drv->aneg_done) | 148 | if (phydev->drv->aneg_done) |
149 | return phydev->drv->aneg_done(phydev); | 149 | return phydev->drv->aneg_done(phydev); |
150 | 150 | ||
151 | return genphy_aneg_done(phydev); | 151 | return genphy_aneg_done(phydev); |
152 | } | 152 | } |
153 | EXPORT_SYMBOL(phy_aneg_done); | ||
153 | 154 | ||
154 | /* A structure for mapping a particular speed and duplex | 155 | /* A structure for mapping a particular speed and duplex |
155 | * combination to a particular SUPPORTED and ADVERTISED value | 156 | * combination to a particular SUPPORTED and ADVERTISED value |
diff --git a/include/linux/phy.h b/include/linux/phy.h index e7e1fd382564..9880d73a2c3d 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h | |||
@@ -786,6 +786,7 @@ void phy_detach(struct phy_device *phydev); | |||
786 | void phy_start(struct phy_device *phydev); | 786 | void phy_start(struct phy_device *phydev); |
787 | void phy_stop(struct phy_device *phydev); | 787 | void phy_stop(struct phy_device *phydev); |
788 | int phy_start_aneg(struct phy_device *phydev); | 788 | int phy_start_aneg(struct phy_device *phydev); |
789 | int phy_aneg_done(struct phy_device *phydev); | ||
789 | 790 | ||
790 | int phy_stop_interrupts(struct phy_device *phydev); | 791 | int phy_stop_interrupts(struct phy_device *phydev); |
791 | 792 | ||