mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 10:26:10 +01:00 
			
		
		
		
	Merge branch 'master' of git://git.denx.de/u-boot-net
- Various PHY fixes / enhancements. - TI K2G fixes
This commit is contained in:
		| @@ -44,28 +44,28 @@ | ||||
| 					reg = <0x1>; | ||||
| 					interrupt-parent = <&pioB>; | ||||
| 					interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||||
| 					txen-skew-ps = <800>; | ||||
| 					txc-skew-ps = <3000>; | ||||
| 					rxdv-skew-ps = <400>; | ||||
| 					rxc-skew-ps = <3000>; | ||||
| 					rxd0-skew-ps = <400>; | ||||
| 					rxd1-skew-ps = <400>; | ||||
| 					rxd2-skew-ps = <400>; | ||||
| 					rxd3-skew-ps = <400>; | ||||
| 					txen-skew-ps = <480>; | ||||
| 					txc-skew-ps = <1800>; | ||||
| 					rxdv-skew-ps = <240>; | ||||
| 					rxc-skew-ps = <1800>; | ||||
| 					rxd0-skew-ps = <240>; | ||||
| 					rxd1-skew-ps = <240>; | ||||
| 					rxd2-skew-ps = <240>; | ||||
| 					rxd3-skew-ps = <240>; | ||||
| 				}; | ||||
|  | ||||
| 				ethernet-phy@7 { | ||||
| 					reg = <0x7>; | ||||
| 					interrupt-parent = <&pioB>; | ||||
| 					interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||||
| 					txen-skew-ps = <800>; | ||||
| 					txc-skew-ps = <3000>; | ||||
| 					rxdv-skew-ps = <400>; | ||||
| 					rxc-skew-ps = <3000>; | ||||
| 					rxd0-skew-ps = <400>; | ||||
| 					rxd1-skew-ps = <400>; | ||||
| 					rxd2-skew-ps = <400>; | ||||
| 					rxd3-skew-ps = <400>; | ||||
| 					txen-skew-ps = <480>; | ||||
| 					txc-skew-ps = <1800>; | ||||
| 					rxdv-skew-ps = <240>; | ||||
| 					rxc-skew-ps = <1800>; | ||||
| 					rxd0-skew-ps = <240>; | ||||
| 					rxd1-skew-ps = <240>; | ||||
| 					rxd2-skew-ps = <240>; | ||||
| 					rxd3-skew-ps = <240>; | ||||
| 				}; | ||||
| 			}; | ||||
| 		}; | ||||
|   | ||||
| @@ -43,28 +43,28 @@ | ||||
| 					reg = <0x1>; | ||||
| 					interrupt-parent = <&pioB>; | ||||
| 					interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||||
| 					txen-skew-ps = <800>; | ||||
| 					txc-skew-ps = <3000>; | ||||
| 					rxdv-skew-ps = <400>; | ||||
| 					rxc-skew-ps = <3000>; | ||||
| 					rxd0-skew-ps = <400>; | ||||
| 					rxd1-skew-ps = <400>; | ||||
| 					rxd2-skew-ps = <400>; | ||||
| 					rxd3-skew-ps = <400>; | ||||
| 					txen-skew-ps = <480>; | ||||
| 					txc-skew-ps = <1800>; | ||||
| 					rxdv-skew-ps = <240>; | ||||
| 					rxc-skew-ps = <1800>; | ||||
| 					rxd0-skew-ps = <240>; | ||||
| 					rxd1-skew-ps = <240>; | ||||
| 					rxd2-skew-ps = <240>; | ||||
| 					rxd3-skew-ps = <240>; | ||||
| 				}; | ||||
|  | ||||
| 				ethernet-phy@7 { | ||||
| 					reg = <0x7>; | ||||
| 					interrupt-parent = <&pioB>; | ||||
| 					interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||||
| 					txen-skew-ps = <800>; | ||||
| 					txc-skew-ps = <3000>; | ||||
| 					rxdv-skew-ps = <400>; | ||||
| 					rxc-skew-ps = <3000>; | ||||
| 					rxd0-skew-ps = <400>; | ||||
| 					rxd1-skew-ps = <400>; | ||||
| 					rxd2-skew-ps = <400>; | ||||
| 					rxd3-skew-ps = <400>; | ||||
| 					txen-skew-ps = <480>; | ||||
| 					txc-skew-ps = <1800>; | ||||
| 					rxdv-skew-ps = <240>; | ||||
| 					rxc-skew-ps = <1800>; | ||||
| 					rxd0-skew-ps = <240>; | ||||
| 					rxd1-skew-ps = <240>; | ||||
| 					rxd2-skew-ps = <240>; | ||||
| 					rxd3-skew-ps = <240>; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
|   | ||||
| @@ -67,9 +67,9 @@ | ||||
| 	rxd2-skew-ps = <0>; | ||||
| 	rxd3-skew-ps = <0>; | ||||
| 	txen-skew-ps = <0>; | ||||
| 	txc-skew-ps = <2600>; | ||||
| 	txc-skew-ps = <1560>; | ||||
| 	rxdv-skew-ps = <0>; | ||||
| 	rxc-skew-ps = <2000>; | ||||
| 	rxc-skew-ps = <1200>; | ||||
| }; | ||||
|  | ||||
| &gpio0 { | ||||
|   | ||||
| @@ -43,9 +43,9 @@ | ||||
| 	rxd2-skew-ps = <0>; | ||||
| 	rxd3-skew-ps = <0>; | ||||
| 	txen-skew-ps = <0>; | ||||
| 	txc-skew-ps = <2600>; | ||||
| 	txc-skew-ps = <1560>; | ||||
| 	rxdv-skew-ps = <0>; | ||||
| 	rxc-skew-ps = <2000>; | ||||
| 	rxc-skew-ps = <1200>; | ||||
| }; | ||||
|  | ||||
| &gpio1 { | ||||
|   | ||||
| @@ -71,9 +71,9 @@ | ||||
| 	rxd2-skew-ps = <0>; | ||||
| 	rxd3-skew-ps = <0>; | ||||
| 	txen-skew-ps = <0>; | ||||
| 	txc-skew-ps = <2600>; | ||||
| 	txc-skew-ps = <1560>; | ||||
| 	rxdv-skew-ps = <0>; | ||||
| 	rxc-skew-ps = <2000>; | ||||
| 	rxc-skew-ps = <1200>; | ||||
| }; | ||||
|  | ||||
| &gpio0 { | ||||
|   | ||||
| @@ -128,9 +128,9 @@ | ||||
| 	rxd2-skew-ps = <0>; | ||||
| 	rxd3-skew-ps = <0>; | ||||
| 	txen-skew-ps = <0>; | ||||
| 	txc-skew-ps = <2600>; | ||||
| 	txc-skew-ps = <1560>; | ||||
| 	rxdv-skew-ps = <0>; | ||||
| 	rxc-skew-ps = <2000>; | ||||
| 	rxc-skew-ps = <1200>; | ||||
| }; | ||||
|  | ||||
| &gpio0 {	/* GPIO 0..29 */ | ||||
|   | ||||
| @@ -85,9 +85,9 @@ | ||||
| 			rxd2-skew-ps = <0>; | ||||
| 			rxd3-skew-ps = <0>; | ||||
| 			txen-skew-ps = <0>; | ||||
| 			txc-skew-ps = <2600>; | ||||
| 			txc-skew-ps = <1560>; | ||||
| 			rxdv-skew-ps = <0>; | ||||
| 			rxc-skew-ps = <2000>; | ||||
| 			rxc-skew-ps = <1200>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|   | ||||
| @@ -126,22 +126,22 @@ struct pin_cfg k2g_evm_pin_cfg[] = { | ||||
| 	{ 71,	MODE(0) },	/* MMC1POW TP124 */ | ||||
|  | ||||
| 		/* EMAC */ | ||||
| 	{ 79,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD1 */ | ||||
| 	{ 78,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD2 */ | ||||
| 	{ 77,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD3 */ | ||||
| 	{ 80,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD0 */ | ||||
| 	{ 94,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD0 */ | ||||
| 	{ 93,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD1 */ | ||||
| 	{ 92,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD2 */ | ||||
| 	{ 91,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD3 */ | ||||
| 	{ 85,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXC */ | ||||
| 	{ 95,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXCTL */ | ||||
| 	{ 72,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXC */ | ||||
| 	{ 77,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD3 */ | ||||
| 	{ 78,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD2 */ | ||||
| 	{ 79,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD1 */ | ||||
| 	{ 80,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD0 */ | ||||
| 	{ 81,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXCTL */ | ||||
| 	{ 85,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXC */ | ||||
| 	{ 91,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD3 */ | ||||
| 	{ 92,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD2 */ | ||||
| 	{ 93,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD1 */ | ||||
| 	{ 94,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD0 */ | ||||
| 	{ 95,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXCTL */ | ||||
|  | ||||
| 	/* MDIO */ | ||||
| 	{ 99,	BUFFER_CLASS_B | PIN_PDIS | MODE(0) },	/* MDIO_CLK */ | ||||
| 	{ 98,	BUFFER_CLASS_B | PIN_PDIS | MODE(0) },	/* MDIO_DATA */ | ||||
| 	{ 99,	BUFFER_CLASS_B | PIN_PDIS | MODE(0) },	/* MDIO_CLK */ | ||||
|  | ||||
| 	/* PWM */ | ||||
| 	{ 73,	MODE(4) },	/* SOC_EHRPWM3A */ | ||||
| @@ -350,22 +350,22 @@ struct pin_cfg k2g_ice_evm_pin_cfg[] = { | ||||
| 	{ 135,	MODE(0) },	/* SOC_QSPI_CSN0 */ | ||||
|  | ||||
| 	/* EMAC */ | ||||
| 	{ 79,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD1 */ | ||||
| 	{ 78,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD2 */ | ||||
| 	{ 77,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD3 */ | ||||
| 	{ 80,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD0 */ | ||||
| 	{ 94,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD0 */ | ||||
| 	{ 93,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD1 */ | ||||
| 	{ 92,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD2 */ | ||||
| 	{ 91,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD3 */ | ||||
| 	{ 85,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXC */ | ||||
| 	{ 95,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXCTL */ | ||||
| 	{ 72,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXC */ | ||||
| 	{ 77,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD3 */ | ||||
| 	{ 78,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD2 */ | ||||
| 	{ 79,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD1 */ | ||||
| 	{ 80,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXD0 */ | ||||
| 	{ 81,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_RXCTL */ | ||||
| 	{ 85,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXC */ | ||||
| 	{ 91,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD3 */ | ||||
| 	{ 92,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD2 */ | ||||
| 	{ 93,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD1 */ | ||||
| 	{ 94,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXD0 */ | ||||
| 	{ 95,	BUFFER_CLASS_D | PIN_PDIS | MODE(1) },	/* RGMII_TXCTL */ | ||||
|  | ||||
| 	/* MDIO */ | ||||
| 	{ 99,	BUFFER_CLASS_B | PIN_PDIS | MODE(0) },	/* MDIO_CLK */ | ||||
| 	{ 98,	BUFFER_CLASS_B | PIN_PDIS | MODE(0) },	/* MDIO_DATA */ | ||||
| 	{ 99,	BUFFER_CLASS_B | PIN_PDIS | MODE(0) },	/* MDIO_CLK */ | ||||
|  | ||||
| 	{ MAX_PIN_N, } | ||||
| }; | ||||
|   | ||||
							
								
								
									
										27
									
								
								cmd/mdio.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								cmd/mdio.c
									
									
									
									
									
								
							| @@ -39,21 +39,24 @@ static int extract_range(char *input, int *plo, int *phi) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int mdio_write_ranges(struct phy_device *phydev, struct mii_dev *bus, | ||||
| static int mdio_write_ranges(struct mii_dev *bus, | ||||
| 			     int addrlo, | ||||
| 			     int addrhi, int devadlo, int devadhi, | ||||
| 			     int reglo, int reghi, unsigned short data, | ||||
| 			     int extended) | ||||
| { | ||||
| 	struct phy_device *phydev; | ||||
| 	int addr, devad, reg; | ||||
| 	int err = 0; | ||||
|  | ||||
| 	for (addr = addrlo; addr <= addrhi; addr++) { | ||||
| 		phydev = bus->phymap[addr]; | ||||
|  | ||||
| 		for (devad = devadlo; devad <= devadhi; devad++) { | ||||
| 			for (reg = reglo; reg <= reghi; reg++) { | ||||
| 				if (!extended) | ||||
| 					err = bus->write(bus, addr, devad, | ||||
| 							 reg, data); | ||||
| 					err = phy_write_mmd(phydev, devad, | ||||
| 							    reg, data); | ||||
| 				else | ||||
| 					err = phydev->drv->writeext(phydev, | ||||
| 							addr, devad, reg, data); | ||||
| @@ -68,15 +71,17 @@ err_out: | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus, | ||||
| static int mdio_read_ranges(struct mii_dev *bus, | ||||
| 			    int addrlo, | ||||
| 			    int addrhi, int devadlo, int devadhi, | ||||
| 			    int reglo, int reghi, int extended) | ||||
| { | ||||
| 	int addr, devad, reg; | ||||
| 	struct phy_device *phydev; | ||||
|  | ||||
| 	printf("Reading from bus %s\n", bus->name); | ||||
| 	for (addr = addrlo; addr <= addrhi; addr++) { | ||||
| 		phydev = bus->phymap[addr]; | ||||
| 		printf("PHY at address %x:\n", addr); | ||||
|  | ||||
| 		for (devad = devadlo; devad <= devadhi; devad++) { | ||||
| @@ -84,7 +89,7 @@ static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus, | ||||
| 				int val; | ||||
|  | ||||
| 				if (!extended) | ||||
| 					val = bus->read(bus, addr, devad, reg); | ||||
| 					val = phy_read_mmd(phydev, devad, reg); | ||||
| 				else | ||||
| 					val = phydev->drv->readext(phydev, addr, | ||||
| 						devad, reg); | ||||
| @@ -222,14 +227,14 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||
| 				bus = phydev->bus; | ||||
| 				extended = 1; | ||||
| 			} else { | ||||
| 				return -1; | ||||
| 				return CMD_RET_FAILURE; | ||||
| 			} | ||||
|  | ||||
| 			if (!phydev->drv || | ||||
| 			    (!phydev->drv->writeext && (op[0] == 'w')) || | ||||
| 			    (!phydev->drv->readext && (op[0] == 'r'))) { | ||||
| 				puts("PHY does not have extended functions\n"); | ||||
| 				return -1; | ||||
| 				return CMD_RET_FAILURE; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -242,13 +247,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||
| 		if (pos > 1) | ||||
| 			if (extract_reg_range(argv[pos--], &devadlo, &devadhi, | ||||
| 					      ®lo, ®hi)) | ||||
| 				return -1; | ||||
| 				return CMD_RET_FAILURE; | ||||
|  | ||||
| 	default: | ||||
| 		if (pos > 1) | ||||
| 			if (extract_phy_range(&argv[2], pos - 1, &bus, | ||||
| 					      &phydev, &addrlo, &addrhi)) | ||||
| 				return -1; | ||||
| 				return CMD_RET_FAILURE; | ||||
|  | ||||
| 		break; | ||||
| 	} | ||||
| @@ -264,12 +269,12 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||
|  | ||||
| 	switch (op[0]) { | ||||
| 	case 'w': | ||||
| 		mdio_write_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi, | ||||
| 		mdio_write_ranges(bus, addrlo, addrhi, devadlo, devadhi, | ||||
| 				  reglo, reghi, data, extended); | ||||
| 		break; | ||||
|  | ||||
| 	case 'r': | ||||
| 		mdio_read_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi, | ||||
| 		mdio_read_ranges(bus, addrlo, addrhi, devadlo, devadhi, | ||||
| 				 reglo, reghi, extended); | ||||
| 		break; | ||||
| 	} | ||||
|   | ||||
| @@ -14,6 +14,33 @@ KSZ9021: | ||||
|   value is 0, the maximum value is 1800, and it is incremented by 120ps | ||||
|   steps. | ||||
|  | ||||
|   The KSZ9021 hardware supports a range of skew values from negative to | ||||
|   positive, where the specific range is property dependent. All values | ||||
|   specified in the devicetree are offset by the minimum value so they | ||||
|   can be represented as positive integers in the devicetree since it's | ||||
|   difficult to represent a negative number in the devictree. | ||||
|  | ||||
|   The following 4-bit values table applies to all the skew properties: | ||||
|  | ||||
|   Pad Skew Value	Delay (ps)	Devicetree Value | ||||
|   ------------------------------------------------------ | ||||
|   0000			-840ps		0 | ||||
|   0001			-720ps		120 | ||||
|   0010			-600ps		240 | ||||
|   0011			-480ps		360 | ||||
|   0100			-360ps		480 | ||||
|   0101			-240ps		600 | ||||
|   0110			-120ps		720 | ||||
|   0111			0ps		840 | ||||
|   1000			120ps		960 | ||||
|   1001			240ps		1080 | ||||
|   1010			360ps		1200 | ||||
|   1011			480ps		1320 | ||||
|   1100			600ps		1440 | ||||
|   1101			720ps		1560 | ||||
|   1110			840ps		1680 | ||||
|   1111			960ps		1800 | ||||
|  | ||||
|   Optional properties: | ||||
|  | ||||
|     - rxc-skew-ps : Skew control of RXC pad | ||||
|   | ||||
| @@ -1074,6 +1074,7 @@ int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) | ||||
| 	priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); | ||||
| 	if (!priv) { | ||||
| 		printf("ldpaa_eth_priv malloc() failed\n"); | ||||
| 		free(net_dev); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	memset(priv, 0, sizeof(struct ldpaa_eth_priv)); | ||||
|   | ||||
| @@ -202,6 +202,26 @@ config RTL8211X_PHY_FORCE_MASTER | ||||
|  | ||||
| 	  If unsure, say N. | ||||
|  | ||||
| config RTL8211F_PHY_FORCE_EEE_RXC_ON | ||||
| 	bool "Ethernet PHY RTL8211F: do not stop receiving the xMII clock during LPI" | ||||
| 	depends on PHY_REALTEK | ||||
| 	default n | ||||
| 	help | ||||
| 	  The IEEE 802.3az-2010 (EEE) standard provides a protocol to coordinate | ||||
| 	  transitions to/from a lower power consumption level (Low Power Idle | ||||
| 	  mode) based on link utilization. When no packets are being | ||||
| 	  transmitted, the system goes to Low Power Idle mode to save power. | ||||
|  | ||||
| 	  Under particular circumstances this setting can cause issues where | ||||
| 	  the PHY is unable to transmit or receive any packet when in LPI mode. | ||||
| 	  The problem is caused when the PHY is configured to stop receiving | ||||
| 	  the xMII clock while it is signaling LPI. For some PHYs the bit | ||||
| 	  configuring this behavior is set by the Linux kernel, causing the | ||||
| 	  issue in U-Boot on reboot if the PHY retains the register value. | ||||
|  | ||||
| 	  Default n, which means that the PHY state is not changed. To work | ||||
| 	  around the issues, change this setting to y. | ||||
|  | ||||
| config PHY_SMSC | ||||
| 	bool  "Microchip(SMSC) Ethernet PHYs support" | ||||
|  | ||||
|   | ||||
| @@ -303,9 +303,14 @@ int aquantia_config(struct phy_device *phydev) | ||||
| 			       AQUANTIA_SYSTEM_INTERFACE_SR); | ||||
| 		/* If SI is USXGMII then start USXGMII autoneg */ | ||||
| 		if ((val & AQUANTIA_SI_IN_USE_MASK) == AQUANTIA_SI_USXGMII) { | ||||
| 			reg_val1 =  phy_read(phydev, MDIO_MMD_PHYXS, | ||||
| 					     AQUANTIA_VENDOR_PROVISIONING_REG); | ||||
|  | ||||
| 			reg_val1 |= AQUANTIA_USX_AUTONEG_CONTROL_ENA; | ||||
|  | ||||
| 			phy_write(phydev, MDIO_MMD_PHYXS, | ||||
| 				  AQUANTIA_VENDOR_PROVISIONING_REG, | ||||
| 				  AQUANTIA_USX_AUTONEG_CONTROL_ENA); | ||||
| 				  reg_val1); | ||||
| 			printf("%s: system interface USXGMII\n", | ||||
| 			       phydev->dev->name); | ||||
| 		} else { | ||||
|   | ||||
| @@ -33,10 +33,14 @@ | ||||
| #define CTRL1000_CONFIG_MASTER		(1 << 11) | ||||
| #define CTRL1000_MANUAL_CONFIG		(1 << 12) | ||||
|  | ||||
| #define KSZ9021_PS_TO_REG		120 | ||||
|  | ||||
| /* KSZ9031 PHY Registers */ | ||||
| #define MII_KSZ9031_MMD_ACCES_CTRL	0x0d | ||||
| #define MII_KSZ9031_MMD_REG_DATA	0x0e | ||||
|  | ||||
| #define KSZ9031_PS_TO_REG		60 | ||||
|  | ||||
| static int ksz90xx_startup(struct phy_device *phydev) | ||||
| { | ||||
| 	unsigned phy_ctl; | ||||
| @@ -102,20 +106,28 @@ static const struct ksz90x1_reg_field ksz9031_clk_grp[] = { | ||||
| }; | ||||
|  | ||||
| static int ksz90x1_of_config_group(struct phy_device *phydev, | ||||
| 				   struct ksz90x1_ofcfg *ofcfg) | ||||
| 				   struct ksz90x1_ofcfg *ofcfg, | ||||
| 				   int ps_to_regval) | ||||
| { | ||||
| 	struct udevice *dev = phydev->dev; | ||||
| 	struct phy_driver *drv = phydev->drv; | ||||
| 	const int ps_to_regval = 60; | ||||
| 	int val[4]; | ||||
| 	int i, changed = 0, offset, max; | ||||
| 	u16 regval = 0; | ||||
| 	ofnode node; | ||||
|  | ||||
| 	if (!drv || !drv->writeext) | ||||
| 		return -EOPNOTSUPP; | ||||
|  | ||||
| 	/* Look for a PHY node under the Ethernet node */ | ||||
| 	node = dev_read_subnode(dev, "ethernet-phy"); | ||||
| 	if (!ofnode_valid(node)) { | ||||
| 		/* No node found, look in the Ethernet node */ | ||||
| 		node = dev_ofnode(dev); | ||||
| 	} | ||||
|  | ||||
| 	for (i = 0; i < ofcfg->grpsz; i++) { | ||||
| 		val[i] = dev_read_u32_default(dev, ofcfg->grp[i].name, ~0); | ||||
| 		val[i] = ofnode_read_u32_default(node, ofcfg->grp[i].name, ~0); | ||||
| 		offset = ofcfg->grp[i].off; | ||||
| 		if (val[i] == -1) { | ||||
| 			/* Default register value for KSZ9021 */ | ||||
| @@ -148,7 +160,8 @@ static int ksz9021_of_config(struct phy_device *phydev) | ||||
| 	int i, ret = 0; | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { | ||||
| 		ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); | ||||
| 		ret = ksz90x1_of_config_group(phydev, &ofcfg[i], | ||||
| 					      KSZ9021_PS_TO_REG); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 	} | ||||
| @@ -167,7 +180,8 @@ static int ksz9031_of_config(struct phy_device *phydev) | ||||
| 	int i, ret = 0; | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { | ||||
| 		ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); | ||||
| 		ret = ksz90x1_of_config_group(phydev, &ofcfg[i], | ||||
| 					      KSZ9031_PS_TO_REG); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 	} | ||||
|   | ||||
| @@ -462,6 +462,18 @@ static LIST_HEAD(phy_drivers); | ||||
|  | ||||
| int phy_init(void) | ||||
| { | ||||
| #ifdef CONFIG_NEEDS_MANUAL_RELOC | ||||
| 	/* | ||||
| 	 * The pointers inside phy_drivers also needs to be updated incase of | ||||
| 	 * manual reloc, without which these points to some invalid | ||||
| 	 * pre reloc address and leads to invalid accesses, hangs. | ||||
| 	 */ | ||||
| 	struct list_head *head = &phy_drivers; | ||||
|  | ||||
| 	head->next = (void *)head->next + gd->reloc_off; | ||||
| 	head->prev = (void *)head->prev + gd->reloc_off; | ||||
| #endif | ||||
|  | ||||
| #ifdef CONFIG_B53_SWITCH | ||||
| 	phy_b53_init(); | ||||
| #endif | ||||
| @@ -549,6 +561,10 @@ int phy_register(struct phy_driver *drv) | ||||
| 		drv->readext += gd->reloc_off; | ||||
| 	if (drv->writeext) | ||||
| 		drv->writeext += gd->reloc_off; | ||||
| 	if (drv->read_mmd) | ||||
| 		drv->read_mmd += gd->reloc_off; | ||||
| 	if (drv->write_mmd) | ||||
| 		drv->write_mmd += gd->reloc_off; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| @@ -655,7 +671,10 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, | ||||
|  | ||||
| 	dev->drv = get_phy_driver(dev, interface); | ||||
|  | ||||
| 	phy_probe(dev); | ||||
| 	if (phy_probe(dev)) { | ||||
| 		printf("%s, PHY probe failed\n", __func__); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (addr >= 0 && addr < PHY_MAX_ADDR) | ||||
| 		bus->phymap[addr] = dev; | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
|  | ||||
| #define PHY_RTL8211x_FORCE_MASTER BIT(1) | ||||
| #define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2) | ||||
| #define PHY_RTL8211F_FORCE_EEE_RXC_ON BIT(3) | ||||
|  | ||||
| #define PHY_AUTONEGOTIATE_TIMEOUT 5000 | ||||
|  | ||||
| @@ -102,6 +103,15 @@ static int rtl8211e_probe(struct phy_device *phydev) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int rtl8211f_probe(struct phy_device *phydev) | ||||
| { | ||||
| #ifdef CONFIG_RTL8211F_PHY_FORCE_EEE_RXC_ON | ||||
| 	phydev->flags |= PHY_RTL8211F_FORCE_EEE_RXC_ON; | ||||
| #endif | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* RealTek RTL8211x */ | ||||
| static int rtl8211x_config(struct phy_device *phydev) | ||||
| { | ||||
| @@ -151,6 +161,14 @@ static int rtl8211f_config(struct phy_device *phydev) | ||||
| { | ||||
| 	u16 reg; | ||||
|  | ||||
| 	if (phydev->flags & PHY_RTL8211F_FORCE_EEE_RXC_ON) { | ||||
| 		unsigned int reg; | ||||
|  | ||||
| 		reg = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1); | ||||
| 		reg &= ~MDIO_PCS_CTRL1_CLKSTOP_EN; | ||||
| 		phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, reg); | ||||
| 	} | ||||
|  | ||||
| 	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); | ||||
|  | ||||
| 	phy_write(phydev, MDIO_DEVAD_NONE, | ||||
| @@ -360,6 +378,7 @@ static struct phy_driver RTL8211F_driver = { | ||||
| 	.uid = 0x1cc916, | ||||
| 	.mask = 0xffffff, | ||||
| 	.features = PHY_GBIT_FEATURES, | ||||
| 	.probe = &rtl8211f_probe, | ||||
| 	.config = &rtl8211f_config, | ||||
| 	.startup = &rtl8211f_startup, | ||||
| 	.shutdown = &genphy_shutdown, | ||||
|   | ||||
| @@ -73,16 +73,6 @@ | ||||
| #define MII_DP83867_CFG2_SPEEDOPT_INTLOW	0x2000 | ||||
| #define MII_DP83867_CFG2_MASK			0x003F | ||||
|  | ||||
| #define MII_MMD_CTRL	0x0d /* MMD Access Control Register */ | ||||
| #define MII_MMD_DATA	0x0e /* MMD Access Data Register */ | ||||
|  | ||||
| /* MMD Access Control register fields */ | ||||
| #define MII_MMD_CTRL_DEVAD_MASK	0x1f /* Mask MMD DEVAD*/ | ||||
| #define MII_MMD_CTRL_ADDR	0x0000 /* Address */ | ||||
| #define MII_MMD_CTRL_NOINCR	0x4000 /* no post increment */ | ||||
| #define MII_MMD_CTRL_INCR_RDWT	0x8000 /* post increment on reads & writes */ | ||||
| #define MII_MMD_CTRL_INCR_ON_WT	0xC000 /* post increment on writes only */ | ||||
|  | ||||
| /* User setting - can be taken from DTS */ | ||||
| #define DEFAULT_RX_ID_DELAY	DP83867_RGMIIDCTL_2_25_NS | ||||
| #define DEFAULT_TX_ID_DELAY	DP83867_RGMIIDCTL_2_75_NS | ||||
| @@ -116,88 +106,20 @@ struct dp83867_private { | ||||
| 	int clk_output_sel; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * phy_read_mmd_indirect - reads data from the MMD registers | ||||
|  * @phydev: The PHY device bus | ||||
|  * @prtad: MMD Address | ||||
|  * @devad: MMD DEVAD | ||||
|  * @addr: PHY address on the MII bus | ||||
|  * | ||||
|  * Description: it reads data from the MMD registers (clause 22 to access to | ||||
|  * clause 45) of the specified phy address. | ||||
|  * To read these registers we have: | ||||
|  * 1) Write reg 13 // DEVAD | ||||
|  * 2) Write reg 14 // MMD Address | ||||
|  * 3) Write reg 13 // MMD Data Command for MMD DEVAD | ||||
|  * 3) Read  reg 14 // Read MMD data | ||||
|  */ | ||||
| int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, | ||||
| 			  int devad, int addr) | ||||
| { | ||||
| 	int value = -1; | ||||
|  | ||||
| 	/* Write the desired MMD Devad */ | ||||
| 	phy_write(phydev, addr, MII_MMD_CTRL, devad); | ||||
|  | ||||
| 	/* Write the desired MMD register address */ | ||||
| 	phy_write(phydev, addr, MII_MMD_DATA, prtad); | ||||
|  | ||||
| 	/* Select the Function : DATA with no post increment */ | ||||
| 	phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); | ||||
|  | ||||
| 	/* Read the content of the MMD's selected register */ | ||||
| 	value = phy_read(phydev, addr, MII_MMD_DATA); | ||||
| 	return value; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * phy_write_mmd_indirect - writes data to the MMD registers | ||||
|  * @phydev: The PHY device | ||||
|  * @prtad: MMD Address | ||||
|  * @devad: MMD DEVAD | ||||
|  * @addr: PHY address on the MII bus | ||||
|  * @data: data to write in the MMD register | ||||
|  * | ||||
|  * Description: Write data from the MMD registers of the specified | ||||
|  * phy address. | ||||
|  * To write these registers we have: | ||||
|  * 1) Write reg 13 // DEVAD | ||||
|  * 2) Write reg 14 // MMD Address | ||||
|  * 3) Write reg 13 // MMD Data Command for MMD DEVAD | ||||
|  * 3) Write reg 14 // Write MMD data | ||||
|  */ | ||||
| void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, | ||||
| 			    int devad, int addr, u32 data) | ||||
| { | ||||
| 	/* Write the desired MMD Devad */ | ||||
| 	phy_write(phydev, addr, MII_MMD_CTRL, devad); | ||||
|  | ||||
| 	/* Write the desired MMD register address */ | ||||
| 	phy_write(phydev, addr, MII_MMD_DATA, prtad); | ||||
|  | ||||
| 	/* Select the Function : DATA with no post increment */ | ||||
| 	phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); | ||||
|  | ||||
| 	/* Write the data into MMD's selected register */ | ||||
| 	phy_write(phydev, addr, MII_MMD_DATA, data); | ||||
| } | ||||
|  | ||||
| static int dp83867_config_port_mirroring(struct phy_device *phydev) | ||||
| { | ||||
| 	struct dp83867_private *dp83867 = | ||||
| 		(struct dp83867_private *)phydev->priv; | ||||
| 	u16 val; | ||||
|  | ||||
| 	val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR, | ||||
| 				    phydev->addr); | ||||
| 	val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4); | ||||
|  | ||||
| 	if (dp83867->port_mirroring == DP83867_PORT_MIRRORING_EN) | ||||
| 		val |= DP83867_CFG4_PORT_MIRROR_EN; | ||||
| 	else | ||||
| 		val &= ~DP83867_CFG4_PORT_MIRROR_EN; | ||||
|  | ||||
| 	phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR, | ||||
| 			       phydev->addr, val); | ||||
| 	phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| @@ -257,13 +179,13 @@ static int dp83867_of_init(struct phy_device *phydev) | ||||
|  | ||||
| 	/* Clock output selection if muxing property is set */ | ||||
| 	if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) { | ||||
| 		val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG, | ||||
| 					    DP83867_DEVADDR, phydev->addr); | ||||
| 		val = phy_read_mmd(phydev, DP83867_DEVADDR, | ||||
| 				   DP83867_IO_MUX_CFG); | ||||
| 		val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK; | ||||
| 		val |= (dp83867->clk_output_sel << | ||||
| 			DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT); | ||||
| 		phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG, | ||||
| 				       DP83867_DEVADDR, phydev->addr, val); | ||||
| 		phy_write_mmd(phydev, DP83867_DEVADDR, | ||||
| 			      DP83867_IO_MUX_CFG, val); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| @@ -308,11 +230,11 @@ static int dp83867_config(struct phy_device *phydev) | ||||
|  | ||||
| 	/* Mode 1 or 2 workaround */ | ||||
| 	if (dp83867->rxctrl_strap_quirk) { | ||||
| 		val = phy_read_mmd_indirect(phydev, DP83867_CFG4, | ||||
| 					    DP83867_DEVADDR, phydev->addr); | ||||
| 		val = phy_read_mmd(phydev, DP83867_DEVADDR, | ||||
| 				   DP83867_CFG4); | ||||
| 		val &= ~BIT(7); | ||||
| 		phy_write_mmd_indirect(phydev, DP83867_CFG4, | ||||
| 				       DP83867_DEVADDR, phydev->addr, val); | ||||
| 		phy_write_mmd(phydev, DP83867_DEVADDR, | ||||
| 			      DP83867_CFG4, val); | ||||
| 	} | ||||
|  | ||||
| 	if (phy_interface_is_rgmii(phydev)) { | ||||
| @@ -332,8 +254,8 @@ static int dp83867_config(struct phy_device *phydev) | ||||
| 		 * register's bit 11 (marked as RESERVED). | ||||
| 		 */ | ||||
|  | ||||
| 		bs = phy_read_mmd_indirect(phydev, DP83867_STRAP_STS1, | ||||
| 					   DP83867_DEVADDR, phydev->addr); | ||||
| 		bs = phy_read_mmd(phydev, DP83867_DEVADDR, | ||||
| 				  DP83867_STRAP_STS1); | ||||
| 		val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL); | ||||
| 		if (bs & DP83867_STRAP_STS1_RESERVED) { | ||||
| 			val &= ~DP83867_PHYCR_RESERVED_MASK; | ||||
| @@ -354,8 +276,8 @@ static int dp83867_config(struct phy_device *phydev) | ||||
| 			 MII_DP83867_CFG2_SPEEDOPT_INTLOW); | ||||
| 		phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG2, cfg2); | ||||
|  | ||||
| 		phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, | ||||
| 				       DP83867_DEVADDR, phydev->addr, 0x0); | ||||
| 		phy_write_mmd(phydev, DP83867_DEVADDR, | ||||
| 			      DP83867_RGMIICTL, 0x0); | ||||
|  | ||||
| 		phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL, | ||||
| 			  DP83867_PHYCTRL_SGMIIEN | | ||||
| @@ -367,8 +289,8 @@ static int dp83867_config(struct phy_device *phydev) | ||||
| 	} | ||||
|  | ||||
| 	if (phy_interface_is_rgmii(phydev)) { | ||||
| 		val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL, | ||||
| 					    DP83867_DEVADDR, phydev->addr); | ||||
| 		val = phy_read_mmd(phydev, DP83867_DEVADDR, | ||||
| 				   DP83867_RGMIICTL); | ||||
|  | ||||
| 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) | ||||
| 			val |= (DP83867_RGMII_TX_CLK_DELAY_EN | | ||||
| @@ -380,26 +302,24 @@ static int dp83867_config(struct phy_device *phydev) | ||||
| 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) | ||||
| 			val |= DP83867_RGMII_RX_CLK_DELAY_EN; | ||||
|  | ||||
| 		phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, | ||||
| 				       DP83867_DEVADDR, phydev->addr, val); | ||||
| 		phy_write_mmd(phydev, DP83867_DEVADDR, | ||||
| 			      DP83867_RGMIICTL, val); | ||||
|  | ||||
| 		delay = (dp83867->rx_id_delay | | ||||
| 			 (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT)); | ||||
|  | ||||
| 		phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL, | ||||
| 				       DP83867_DEVADDR, phydev->addr, delay); | ||||
| 		phy_write_mmd(phydev, DP83867_DEVADDR, | ||||
| 			      DP83867_RGMIIDCTL, delay); | ||||
|  | ||||
| 		if (dp83867->io_impedance >= 0) { | ||||
| 			val = phy_read_mmd_indirect(phydev, | ||||
| 						    DP83867_IO_MUX_CFG, | ||||
| 						    DP83867_DEVADDR, | ||||
| 						    phydev->addr); | ||||
| 			val = phy_read_mmd(phydev, | ||||
| 					   DP83867_DEVADDR, | ||||
| 					   DP83867_IO_MUX_CFG); | ||||
| 			val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; | ||||
| 			val |= dp83867->io_impedance & | ||||
| 			       DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; | ||||
| 			phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG, | ||||
| 					       DP83867_DEVADDR, phydev->addr, | ||||
| 					       val); | ||||
| 			phy_write_mmd(phydev, DP83867_DEVADDR, | ||||
| 				      DP83867_IO_MUX_CFG, val); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -101,6 +101,14 @@ struct phy_driver { | ||||
| 	int (*readext)(struct phy_device *phydev, int addr, int devad, int reg); | ||||
| 	int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg, | ||||
| 			u16 val); | ||||
|  | ||||
| 	/* Phy specific driver override for reading a MMD register */ | ||||
| 	int (*read_mmd)(struct phy_device *phydev, int devad, int reg); | ||||
|  | ||||
| 	/* Phy specific driver override for writing a MMD register */ | ||||
| 	int (*write_mmd)(struct phy_device *phydev, int devad, int reg, | ||||
| 			 u16 val); | ||||
|  | ||||
| 	struct list_head list; | ||||
| }; | ||||
|  | ||||
| @@ -165,6 +173,68 @@ static inline int phy_write(struct phy_device *phydev, int devad, int regnum, | ||||
| 	return bus->write(bus, phydev->addr, devad, regnum, val); | ||||
| } | ||||
|  | ||||
| static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad, | ||||
| 					  int regnum) | ||||
| { | ||||
| 	/* Write the desired MMD Devad */ | ||||
| 	phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, devad); | ||||
|  | ||||
| 	/* Write the desired MMD register address */ | ||||
| 	phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, regnum); | ||||
|  | ||||
| 	/* Select the Function : DATA with no post increment */ | ||||
| 	phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, | ||||
| 		  (devad | MII_MMD_CTRL_NOINCR)); | ||||
| } | ||||
|  | ||||
| static inline int phy_read_mmd(struct phy_device *phydev, int devad, | ||||
| 			       int regnum) | ||||
| { | ||||
| 	struct phy_driver *drv = phydev->drv; | ||||
|  | ||||
| 	if (regnum > (u16)~0 || devad > 32) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	/* driver-specific access */ | ||||
| 	if (drv->read_mmd) | ||||
| 		return drv->read_mmd(phydev, devad, regnum); | ||||
|  | ||||
| 	/* direct C45 / C22 access */ | ||||
| 	if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES || | ||||
| 	    devad == MDIO_DEVAD_NONE || !devad) | ||||
| 		return phy_read(phydev, devad, regnum); | ||||
|  | ||||
| 	/* indirect C22 access */ | ||||
| 	phy_mmd_start_indirect(phydev, devad, regnum); | ||||
|  | ||||
| 	/* Read the content of the MMD's selected register */ | ||||
| 	return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA); | ||||
| } | ||||
|  | ||||
| static inline int phy_write_mmd(struct phy_device *phydev, int devad, | ||||
| 				int regnum, u16 val) | ||||
| { | ||||
| 	struct phy_driver *drv = phydev->drv; | ||||
|  | ||||
| 	if (regnum > (u16)~0 || devad > 32) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	/* driver-specific access */ | ||||
| 	if (drv->write_mmd) | ||||
| 		return drv->write_mmd(phydev, devad, regnum, val); | ||||
|  | ||||
| 	/* direct C45 / C22 access */ | ||||
| 	if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES || | ||||
| 	    devad == MDIO_DEVAD_NONE || !devad) | ||||
| 		return phy_write(phydev, devad, regnum, val); | ||||
|  | ||||
| 	/* indirect C22 access */ | ||||
| 	phy_mmd_start_indirect(phydev, devad, regnum); | ||||
|  | ||||
| 	/* Write the data into MMD's selected register */ | ||||
| 	return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val); | ||||
| } | ||||
|  | ||||
| #ifdef CONFIG_PHYLIB_10G | ||||
| extern struct phy_driver gen10g_driver; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user