diff options
Diffstat (limited to 'drivers/net/phy/sfp.c')
| -rw-r--r-- | drivers/net/phy/sfp.c | 96 | 
1 files changed, 71 insertions, 25 deletions
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index c02cad6478a8..89636dc71e48 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -210,6 +210,12 @@ static const enum gpiod_flags gpio_flags[] = {  #define SFP_PHY_ADDR		22  #define SFP_PHY_ADDR_ROLLBALL	17 +/* SFP_EEPROM_BLOCK_SIZE is the size of data chunk to read the EEPROM + * at a time. Some SFP modules and also some Linux I2C drivers do not like + * reads longer than 16 bytes. + */ +#define SFP_EEPROM_BLOCK_SIZE	16 +  struct sff_data {  	unsigned int gpios;  	bool (*module_supported)(const struct sfp_eeprom_id *id); @@ -255,6 +261,8 @@ struct sfp {  	unsigned int module_power_mW;  	unsigned int module_t_start_up;  	unsigned int module_t_wait; + +	bool have_a2;  	bool tx_fault_ignore;  	const struct sfp_quirk *quirk; @@ -358,6 +366,23 @@ static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,  	__set_bit(PHY_INTERFACE_MODE_2500BASEX, interfaces);  } +static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id, +				      unsigned long *modes, +				      unsigned long *interfaces) +{ +	linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, modes); +} + +static void sfp_quirk_oem_2_5g(const struct sfp_eeprom_id *id, +			       unsigned long *modes, +			       unsigned long *interfaces) +{ +	/* Copper 2.5G SFP */ +	linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, modes); +	__set_bit(PHY_INTERFACE_MODE_2500BASEX, interfaces); +	sfp_quirk_disable_autoneg(id, modes, interfaces); +} +  static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,  				      unsigned long *modes,  				      unsigned long *interfaces) @@ -387,6 +412,10 @@ static const struct sfp_quirk sfp_quirks[] = {  	SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp), +	// HG MXPD-483II-F 2.5G supports 2500Base-X, but incorrectly reports +	// 2600MBd in their EERPOM +	SFP_QUIRK_M("HG GENUINE", "MXPD-483II", sfp_quirk_2500basex), +  	// Huawei MA5671A can operate at 2500base-X, but report 1.2GBd NRZ in  	// their EEPROM  	SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex, @@ -399,6 +428,7 @@ static const struct sfp_quirk sfp_quirks[] = {  	SFP_QUIRK_M("UBNT", "UF-INSTANT", sfp_quirk_ubnt_uf_instant),  	SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc), +	SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),  	SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),  	SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),  	SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball), @@ -1358,7 +1388,7 @@ static const struct hwmon_ops sfp_hwmon_ops = {  	.read_string = sfp_hwmon_read_string,  }; -static const struct hwmon_channel_info *sfp_hwmon_info[] = { +static const struct hwmon_channel_info * const sfp_hwmon_info[] = {  	HWMON_CHANNEL_INFO(chip,  			   HWMON_C_REGISTER_TZ),  	HWMON_CHANNEL_INFO(in, @@ -1453,20 +1483,10 @@ static void sfp_hwmon_probe(struct work_struct *work)  static int sfp_hwmon_insert(struct sfp *sfp)  { -	if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE) -		return 0; - -	if (!(sfp->id.ext.diagmon & SFP_DIAGMON_DDM)) -		return 0; - -	if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) -		/* This driver in general does not support address -		 * change. -		 */ -		return 0; - -	mod_delayed_work(system_wq, &sfp->hwmon_probe, 1); -	sfp->hwmon_tries = R_PROBE_RETRY_SLOW; +	if (sfp->have_a2 && sfp->id.ext.diagmon & SFP_DIAGMON_DDM) { +		mod_delayed_work(system_wq, &sfp->hwmon_probe, 1); +		sfp->hwmon_tries = R_PROBE_RETRY_SLOW; +	}  	return 0;  } @@ -1916,6 +1936,18 @@ static int sfp_cotsworks_fixup_check(struct sfp *sfp, struct sfp_eeprom_id *id)  	return 0;  } +static int sfp_module_parse_sff8472(struct sfp *sfp) +{ +	/* If the module requires address swap mode, warn about it */ +	if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) +		dev_warn(sfp->dev, +			 "module address swap to access page 0xA2 is not supported.\n"); +	else +		sfp->have_a2 = true; + +	return 0; +} +  static int sfp_sm_mod_probe(struct sfp *sfp, bool report)  {  	/* SFP module inserted - read I2C data */ @@ -1925,11 +1957,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)  	u8 check;  	int ret; -	/* Some SFP modules and also some Linux I2C drivers do not like reads -	 * longer than 16 bytes, so read the EEPROM in chunks of 16 bytes at -	 * a time. -	 */ -	sfp->i2c_block_size = 16; +	sfp->i2c_block_size = SFP_EEPROM_BLOCK_SIZE;  	ret = sfp_read(sfp, false, 0, &id.base, sizeof(id.base));  	if (ret < 0) { @@ -2053,10 +2081,11 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)  		return -EINVAL;  	} -	/* If the module requires address swap mode, warn about it */ -	if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) -		dev_warn(sfp->dev, -			 "module address swap to access page 0xA2 is not supported.\n"); +	if (sfp->id.ext.sff8472_compliance != SFP_SFF8472_COMPLIANCE_NONE) { +		ret = sfp_module_parse_sff8472(sfp); +		if (ret < 0) +			return ret; +	}  	/* Parse the module power requirement */  	ret = sfp_module_parse_power(sfp); @@ -2103,6 +2132,7 @@ static void sfp_sm_mod_remove(struct sfp *sfp)  	memset(&sfp->id, 0, sizeof(sfp->id));  	sfp->module_power_mW = 0; +	sfp->have_a2 = false;  	dev_info(sfp->dev, "module removed\n");  } @@ -2190,6 +2220,11 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)  			break;  		} +		/* Force a poll to re-read the hardware signal state after +		 * sfp_sm_mod_probe() changed state_hw_mask. +		 */ +		mod_delayed_work(system_wq, &sfp->poll, 1); +  		err = sfp_hwmon_insert(sfp);  		if (err)  			dev_warn(sfp->dev, "hwmon probe failed: %pe\n", @@ -2278,7 +2313,11 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)  		    sfp->sm_dev_state != SFP_DEV_UP)  			break; -		if (!(sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE)) +		/* Only use the soft state bits if we have access to the A2h +		 * memory, which implies that we have some level of SFF-8472 +		 * compliance. +		 */ +		if (sfp->have_a2)  			sfp_soft_start_poll(sfp);  		sfp_module_tx_enable(sfp); @@ -2476,6 +2515,9 @@ static int sfp_module_eeprom(struct sfp *sfp, struct ethtool_eeprom *ee,  	unsigned int first, last, len;  	int ret; +	if (!(sfp->state & SFP_F_PRESENT)) +		return -ENODEV; +  	if (ee->len == 0)  		return -EINVAL; @@ -2508,6 +2550,9 @@ static int sfp_module_eeprom_by_page(struct sfp *sfp,  				     const struct ethtool_module_eeprom *page,  				     struct netlink_ext_ack *extack)  { +	if (!(sfp->state & SFP_F_PRESENT)) +		return -ENODEV; +  	if (page->bank) {  		NL_SET_ERR_MSG(extack, "Banks not supported");  		return -EOPNOTSUPP; @@ -2612,6 +2657,7 @@ static struct sfp *sfp_alloc(struct device *dev)  		return ERR_PTR(-ENOMEM);  	sfp->dev = dev; +	sfp->i2c_block_size = SFP_EEPROM_BLOCK_SIZE;  	mutex_init(&sfp->sm_mutex);  	mutex_init(&sfp->st_mutex);  |