Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ccab371f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sfp-phylink-fixes'



Russell King says:

====================
SFP/phylink fixes

Here are four phylink fixes:
- the "options" is a big-endian value, we must test the bits taking the
  endian-ness into account.
- improve the handling of RX_LOS polarity, taking no RX_LOS polarity
  bits set to mean there is no RX_LOS functionality provided.
- do not report modules that require the address mode switching as
  supporting SFF8472.
- ensure that the mac_link_down() function is called when phylink_stop()
  is called.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a0da456b 2012b7d6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -773,6 +773,7 @@ void phylink_stop(struct phylink *pl)
		sfp_upstream_stop(pl->sfp_bus);

	set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
	queue_work(system_power_efficient_wq, &pl->resolve);
	flush_work(&pl->resolve);
}
EXPORT_SYMBOL_GPL(phylink_stop);
+30 −11
Original line number Diff line number Diff line
@@ -351,12 +351,13 @@ static void sfp_sm_link_check_los(struct sfp *sfp)
{
	unsigned int los = sfp->state & SFP_F_LOS;

	/* FIXME: what if neither SFP_OPTIONS_LOS_INVERTED nor
	 * SFP_OPTIONS_LOS_NORMAL are set?  For now, we assume
	 * the same as SFP_OPTIONS_LOS_NORMAL set.
	/* If neither SFP_OPTIONS_LOS_INVERTED nor SFP_OPTIONS_LOS_NORMAL
	 * are set, we assume that no LOS signal is available.
	 */
	if (sfp->id.ext.options & SFP_OPTIONS_LOS_INVERTED)
	if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_INVERTED))
		los ^= SFP_F_LOS;
	else if (!(sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_NORMAL)))
		los = 0;

	if (los)
		sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0);
@@ -364,6 +365,22 @@ static void sfp_sm_link_check_los(struct sfp *sfp)
		sfp_sm_link_up(sfp);
}

static bool sfp_los_event_active(struct sfp *sfp, unsigned int event)
{
	return (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_INVERTED) &&
		event == SFP_E_LOS_LOW) ||
	       (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_NORMAL) &&
		event == SFP_E_LOS_HIGH);
}

static bool sfp_los_event_inactive(struct sfp *sfp, unsigned int event)
{
	return (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_INVERTED) &&
		event == SFP_E_LOS_HIGH) ||
	       (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_NORMAL) &&
		event == SFP_E_LOS_LOW);
}

static void sfp_sm_fault(struct sfp *sfp, bool warn)
{
	if (sfp->sm_retries && !--sfp->sm_retries) {
@@ -470,6 +487,11 @@ static int sfp_sm_mod_probe(struct sfp *sfp)
		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");

	return sfp_module_insert(sfp->sfp_bus, &sfp->id);
}

@@ -581,9 +603,7 @@ static void sfp_sm_event(struct sfp *sfp, unsigned int event)
	case SFP_S_WAIT_LOS:
		if (event == SFP_E_TX_FAULT)
			sfp_sm_fault(sfp, true);
		else if (event ==
			 (sfp->id.ext.options & SFP_OPTIONS_LOS_INVERTED ?
			  SFP_E_LOS_HIGH : SFP_E_LOS_LOW))
		else if (sfp_los_event_inactive(sfp, event))
			sfp_sm_link_up(sfp);
		break;

@@ -591,9 +611,7 @@ static void sfp_sm_event(struct sfp *sfp, unsigned int event)
		if (event == SFP_E_TX_FAULT) {
			sfp_sm_link_down(sfp);
			sfp_sm_fault(sfp, true);
		} else if (event ==
			   (sfp->id.ext.options & SFP_OPTIONS_LOS_INVERTED ?
			    SFP_E_LOS_LOW : SFP_E_LOS_HIGH)) {
		} else if (sfp_los_event_active(sfp, event)) {
			sfp_sm_link_down(sfp);
			sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0);
		}
@@ -639,7 +657,8 @@ static int sfp_module_info(struct sfp *sfp, struct ethtool_modinfo *modinfo)
{
	/* locking... and check module is present */

	if (sfp->id.ext.sff8472_compliance) {
	if (sfp->id.ext.sff8472_compliance &&
	    !(sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE)) {
		modinfo->type = ETH_MODULE_SFF_8472;
		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
	} else {