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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
ccab371f74
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue