aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2019-11-10 14:06:44 +0000
committerDavid S. Miller <davem@davemloft.net>2019-11-11 16:17:00 -0800
commit7cfa9c92d0a325f97ac13f894a7b47d37bd2040e (patch)
treebaeaec25788d043c0b625b08d100e72d2c1d42d9 /drivers
parentnet: sfp: parse SFP power requirement earlier (diff)
downloadlinux-dev-7cfa9c92d0a325f97ac13f894a7b47d37bd2040e.tar.xz
linux-dev-7cfa9c92d0a325f97ac13f894a7b47d37bd2040e.zip
net: sfp: avoid power switch on address-change modules
If the module indicates that it requires an address change sequence to switch between address 0x50 and 0x51, which we don't support, we can't write to the register that controls the power mode to switch to high power mode. Warn the user that the module may not be functional in this case, and don't try to change the power mode. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/phy/sfp.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 69f7683ba6ab..d8efa1d3a903 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1385,25 +1385,34 @@ static int sfp_module_parse_power(struct sfp *sfp)
if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL))
power_mW = 2000;
- if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE &&
- (sfp->id.ext.diagmon & (SFP_DIAGMON_DDM | SFP_DIAGMON_ADDRMODE)) !=
- SFP_DIAGMON_DDM) {
- /* The module appears not to implement bus address 0xa2,
- * or requires an address change sequence, so assume that
- * the module powers up in the indicated power mode.
- */
- if (power_mW > sfp->max_power_mW) {
+ if (power_mW > sfp->max_power_mW) {
+ /* Module power specification exceeds the allowed maximum. */
+ if (sfp->id.ext.sff8472_compliance ==
+ SFP_SFF8472_COMPLIANCE_NONE &&
+ !(sfp->id.ext.diagmon & SFP_DIAGMON_DDM)) {
+ /* The module appears not to implement bus address
+ * 0xa2, so assume that the module powers up in the
+ * indicated mode.
+ */
dev_err(sfp->dev,
"Host does not support %u.%uW modules\n",
power_mW / 1000, (power_mW / 100) % 10);
return -EINVAL;
+ } else {
+ dev_warn(sfp->dev,
+ "Host does not support %u.%uW modules, module left in power mode 1\n",
+ power_mW / 1000, (power_mW / 100) % 10);
+ return 0;
}
- return 0;
}
- if (power_mW > sfp->max_power_mW) {
+ /* If the module requires a higher power mode, but also requires
+ * an address change sequence, warn the user that the module may
+ * not be functional.
+ */
+ if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE && power_mW > 1000) {
dev_warn(sfp->dev,
- "Host does not support %u.%uW modules, module left in power mode 1\n",
+ "Address Change Sequence not supported but module requies %u.%uW, module may not be functional\n",
power_mW / 1000, (power_mW / 100) % 10);
return 0;
}