diff options
| -rw-r--r-- | drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 97 | 
1 files changed, 52 insertions, 45 deletions
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index 8ddf58f379ac..587def69a6f7 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -6261,32 +6261,13 @@ static void mvpp2_phylink_validate(struct phylink_config *config,  	struct mvpp2_port *port = mvpp2_phylink_to_port(config);  	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -	/* Invalid combinations */ -	switch (state->interface) { -	case PHY_INTERFACE_MODE_10GBASER: -	case PHY_INTERFACE_MODE_XAUI: -		if (!mvpp2_port_supports_xlg(port)) -			goto empty_set; -		break; -	case PHY_INTERFACE_MODE_RGMII: -	case PHY_INTERFACE_MODE_RGMII_ID: -	case PHY_INTERFACE_MODE_RGMII_RXID: -	case PHY_INTERFACE_MODE_RGMII_TXID: -		if (!mvpp2_port_supports_rgmii(port)) -			goto empty_set; -		break; -	case PHY_INTERFACE_MODE_1000BASEX: -	case PHY_INTERFACE_MODE_2500BASEX: -		/* When in 802.3z mode, we must have AN enabled: -		 * Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... -		 * When <PortType> = 1 (1000BASE-X) this field must be set to 1. -		 */ -		if (!phylink_test(state->advertising, Autoneg)) -			goto empty_set; -		break; -	default: -		break; -	} +	/* When in 802.3z mode, we must have AN enabled: +	 * Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... +	 * When <PortType> = 1 (1000BASE-X) this field must be set to 1. +	 */ +	if (phy_interface_mode_is_8023z(state->interface) && +	    !phylink_test(state->advertising, Autoneg)) +		goto empty_set;  	phylink_set(mask, Autoneg);  	phylink_set_port_modes(mask); @@ -6299,14 +6280,12 @@ static void mvpp2_phylink_validate(struct phylink_config *config,  	switch (state->interface) {  	case PHY_INTERFACE_MODE_10GBASER:  	case PHY_INTERFACE_MODE_XAUI: -	case PHY_INTERFACE_MODE_NA:  		if (mvpp2_port_supports_xlg(port)) {  			phylink_set_10g_modes(mask);  			phylink_set(mask, 10000baseKR_Full);  		} -		if (state->interface != PHY_INTERFACE_MODE_NA) -			break; -		fallthrough; +		break; +  	case PHY_INTERFACE_MODE_RGMII:  	case PHY_INTERFACE_MODE_RGMII_ID:  	case PHY_INTERFACE_MODE_RGMII_RXID: @@ -6318,30 +6297,24 @@ static void mvpp2_phylink_validate(struct phylink_config *config,  		phylink_set(mask, 100baseT_Full);  		phylink_set(mask, 1000baseT_Full);  		phylink_set(mask, 1000baseX_Full); -		if (state->interface != PHY_INTERFACE_MODE_NA) -			break; -		fallthrough; +		break; +  	case PHY_INTERFACE_MODE_1000BASEX: +		phylink_set(mask, 1000baseT_Full); +		phylink_set(mask, 1000baseX_Full); +		break; +  	case PHY_INTERFACE_MODE_2500BASEX: -		if (port->comphy || -		    state->interface != PHY_INTERFACE_MODE_2500BASEX) { -			phylink_set(mask, 1000baseT_Full); -			phylink_set(mask, 1000baseX_Full); -		} -		if (port->comphy || -		    state->interface == PHY_INTERFACE_MODE_2500BASEX) { -			phylink_set(mask, 2500baseT_Full); -			phylink_set(mask, 2500baseX_Full); -		} +		phylink_set(mask, 2500baseT_Full); +		phylink_set(mask, 2500baseX_Full);  		break; +  	default:  		goto empty_set;  	}  	linkmode_and(supported, supported, mask);  	linkmode_and(state->advertising, state->advertising, mask); - -	phylink_helper_basex_speed(state);  	return;  empty_set: @@ -6937,6 +6910,40 @@ static int mvpp2_port_probe(struct platform_device *pdev,  		port->phylink_config.dev = &dev->dev;  		port->phylink_config.type = PHYLINK_NETDEV; +		if (mvpp2_port_supports_xlg(port)) { +			__set_bit(PHY_INTERFACE_MODE_10GBASER, +				  port->phylink_config.supported_interfaces); +			__set_bit(PHY_INTERFACE_MODE_XAUI, +				  port->phylink_config.supported_interfaces); +		} + +		if (mvpp2_port_supports_rgmii(port)) +			phy_interface_set_rgmii(port->phylink_config.supported_interfaces); + +		if (comphy) { +			/* If a COMPHY is present, we can support any of the +			 * serdes modes and switch between them. +			 */ +			__set_bit(PHY_INTERFACE_MODE_SGMII, +				  port->phylink_config.supported_interfaces); +			__set_bit(PHY_INTERFACE_MODE_1000BASEX, +				  port->phylink_config.supported_interfaces); +			__set_bit(PHY_INTERFACE_MODE_2500BASEX, +				  port->phylink_config.supported_interfaces); +		} else if (phy_mode == PHY_INTERFACE_MODE_2500BASEX) { +			/* No COMPHY, with only 2500BASE-X mode supported */ +			__set_bit(PHY_INTERFACE_MODE_2500BASEX, +				  port->phylink_config.supported_interfaces); +		} else if (phy_mode == PHY_INTERFACE_MODE_1000BASEX || +			   phy_mode == PHY_INTERFACE_MODE_SGMII) { +			/* No COMPHY, we can switch between 1000BASE-X and SGMII +			 */ +			__set_bit(PHY_INTERFACE_MODE_1000BASEX, +				  port->phylink_config.supported_interfaces); +			__set_bit(PHY_INTERFACE_MODE_SGMII, +				  port->phylink_config.supported_interfaces); +		} +  		phylink = phylink_create(&port->phylink_config, port_fwnode,  					 phy_mode, &mvpp2_phylink_ops);  		if (IS_ERR(phylink)) {  | 
