|
@@ -105,68 +105,6 @@ int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(sfp_parse_port);
|
|
|
|
|
|
-/**
|
|
|
- * sfp_parse_interface() - Parse the phy_interface_t
|
|
|
- * @bus: a pointer to the &struct sfp_bus structure for the sfp module
|
|
|
- * @id: a pointer to the module's &struct sfp_eeprom_id
|
|
|
- *
|
|
|
- * Derive the phy_interface_t mode for the information found in the
|
|
|
- * module's identifying EEPROM. There is no standard or defined way
|
|
|
- * to derive this information, so we use some heuristics.
|
|
|
- *
|
|
|
- * If the encoding is 64b66b, then the module must be >= 10G, so
|
|
|
- * return %PHY_INTERFACE_MODE_10GKR.
|
|
|
- *
|
|
|
- * If it's 8b10b, then it's 1G or slower. If it's definitely a fibre
|
|
|
- * module, return %PHY_INTERFACE_MODE_1000BASEX mode, otherwise return
|
|
|
- * %PHY_INTERFACE_MODE_SGMII mode.
|
|
|
- *
|
|
|
- * If the encoding is not known, return %PHY_INTERFACE_MODE_NA.
|
|
|
- */
|
|
|
-phy_interface_t sfp_parse_interface(struct sfp_bus *bus,
|
|
|
- const struct sfp_eeprom_id *id)
|
|
|
-{
|
|
|
- phy_interface_t iface;
|
|
|
-
|
|
|
- /* Setting the serdes link mode is guesswork: there's no field in
|
|
|
- * the EEPROM which indicates what mode should be used.
|
|
|
- *
|
|
|
- * If the module wants 64b66b, then it must be >= 10G.
|
|
|
- *
|
|
|
- * If it's a gigabit-only fiber module, it probably does not have
|
|
|
- * a PHY, so switch to 802.3z negotiation mode. Otherwise, switch
|
|
|
- * to SGMII mode (which is required to support non-gigabit speeds).
|
|
|
- */
|
|
|
- switch (id->base.encoding) {
|
|
|
- case SFP_ENCODING_8472_64B66B:
|
|
|
- iface = PHY_INTERFACE_MODE_10GKR;
|
|
|
- break;
|
|
|
-
|
|
|
- case SFP_ENCODING_8B10B:
|
|
|
- if (!id->base.e1000_base_t &&
|
|
|
- !id->base.e100_base_lx &&
|
|
|
- !id->base.e100_base_fx)
|
|
|
- iface = PHY_INTERFACE_MODE_1000BASEX;
|
|
|
- else
|
|
|
- iface = PHY_INTERFACE_MODE_SGMII;
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- if (id->base.e1000_base_cx) {
|
|
|
- iface = PHY_INTERFACE_MODE_1000BASEX;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- iface = PHY_INTERFACE_MODE_NA;
|
|
|
- dev_err(bus->sfp_dev,
|
|
|
- "SFP module encoding does not support 8b10b nor 64b66b\n");
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- return iface;
|
|
|
-}
|
|
|
-EXPORT_SYMBOL_GPL(sfp_parse_interface);
|
|
|
-
|
|
|
/**
|
|
|
* sfp_parse_support() - Parse the eeprom id for supported link modes
|
|
|
* @bus: a pointer to the &struct sfp_bus structure for the sfp module
|
|
@@ -296,6 +234,45 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(sfp_parse_support);
|
|
|
|
|
|
+/**
|
|
|
+ * sfp_select_interface() - Select appropriate phy_interface_t mode
|
|
|
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
|
|
|
+ * @id: a pointer to the module's &struct sfp_eeprom_id
|
|
|
+ * @link_modes: ethtool link modes mask
|
|
|
+ *
|
|
|
+ * Derive the phy_interface_t mode for the information found in the
|
|
|
+ * module's identifying EEPROM and the link modes mask. There is no
|
|
|
+ * standard or defined way to derive this information, so we decide
|
|
|
+ * based upon the link mode mask.
|
|
|
+ */
|
|
|
+phy_interface_t sfp_select_interface(struct sfp_bus *bus,
|
|
|
+ const struct sfp_eeprom_id *id,
|
|
|
+ unsigned long *link_modes)
|
|
|
+{
|
|
|
+ if (phylink_test(link_modes, 10000baseCR_Full) ||
|
|
|
+ phylink_test(link_modes, 10000baseSR_Full) ||
|
|
|
+ phylink_test(link_modes, 10000baseLR_Full) ||
|
|
|
+ phylink_test(link_modes, 10000baseLRM_Full) ||
|
|
|
+ phylink_test(link_modes, 10000baseER_Full))
|
|
|
+ return PHY_INTERFACE_MODE_10GKR;
|
|
|
+
|
|
|
+ if (phylink_test(link_modes, 2500baseX_Full))
|
|
|
+ return PHY_INTERFACE_MODE_2500BASEX;
|
|
|
+
|
|
|
+ if (id->base.e1000_base_t ||
|
|
|
+ id->base.e100_base_lx ||
|
|
|
+ id->base.e100_base_fx)
|
|
|
+ return PHY_INTERFACE_MODE_SGMII;
|
|
|
+
|
|
|
+ if (phylink_test(link_modes, 1000baseX_Full))
|
|
|
+ return PHY_INTERFACE_MODE_1000BASEX;
|
|
|
+
|
|
|
+ dev_warn(bus->sfp_dev, "Unable to ascertain link mode\n");
|
|
|
+
|
|
|
+ return PHY_INTERFACE_MODE_NA;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(sfp_select_interface);
|
|
|
+
|
|
|
static LIST_HEAD(sfp_buses);
|
|
|
static DEFINE_MUTEX(sfp_mutex);
|
|
|
|