@@ -115,6 +115,16 @@
};
};
};
+
+ sfp: sfp {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2csfp>;
+ tx-fault-gpios = <&pcawan 0 GPIO_ACTIVE_HIGH>;
+ tx-disable-gpios = <&pcawan 1 GPIO_ACTIVE_HIGH>;
+ rate-select0-gpios = <&pcawan 2 GPIO_ACTIVE_HIGH>;
+ los-gpios = <&pcawan 3 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&pcawan 4 GPIO_ACTIVE_LOW>;
+ };
};
/* Connected to 88E6176 switch, port 6 */
@@ -148,6 +158,7 @@
status = "okay";
phy-mode = "sgmii";
phy = <&phy1>;
+ sfp = <&sfp>;
};
&i2c0 {
@@ -210,7 +221,7 @@
/* routed to PCIe2 connector (CN62A) */
};
- i2c@4 {
+ i2csfp: i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
@@ -58,6 +58,12 @@ struct phylink {
bool mac_link_dropped;
struct sfp_bus *sfp_bus;
+
+ /* Things to remember across a module insertion/removal cycle */
+ u8 default_an_mode;
+ u8 default_port;
+ struct phylink_link_state default_config;
+ bool sfp_module_present;
};
static inline void linkmode_zero(unsigned long *dst)
@@ -680,6 +686,10 @@ int phylink_of_phy_connect(struct phylin
if (pl->link_an_mode == MLO_AN_FIXED)
return 0;
+ /* If SFP module present, we do not need a separate PHY */
+ if (pl->sfp_module_present)
+ return 0;
+
phy_node = of_parse_phandle(dn, "phy-handle", 0);
if (!phy_node)
phy_node = of_parse_phandle(dn, "phy", 0);
@@ -1371,6 +1381,11 @@ static int phylink_sfp_module_insert(voi
if (mode == MLO_AN_8023Z && pl->phydev)
return -EINVAL;
+ pl->default_an_mode = pl->link_an_mode;
+ pl->default_port = pl->link_port;
+ pl->default_config = pl->link_config;
+ pl->sfp_module_present = true;
+
changed = !bitmap_equal(pl->supported, support,
__ETHTOOL_LINK_MODE_MASK_NBITS);
if (changed) {
@@ -1399,6 +1414,16 @@ static int phylink_sfp_module_insert(voi
return ret;
}
+static void phylink_sfp_module_remove(void *upstream)
+{
+ struct phylink *pl = upstream;
+
+ pl->link_an_mode = pl->default_an_mode;
+ pl->link_port = pl->default_port;
+ pl->link_config = pl->default_config;
+ pl->sfp_module_present = false;
+}
+
static void phylink_sfp_link_down(void *upstream)
{
struct phylink *pl = upstream;
@@ -1432,6 +1457,7 @@ static void phylink_sfp_disconnect_phy(v
static const struct sfp_upstream_ops sfp_phylink_ops = {
.module_insert = phylink_sfp_module_insert,
+ .module_remove = phylink_sfp_module_remove,
.link_up = phylink_sfp_link_up,
.link_down = phylink_sfp_link_down,
.connect_phy = phylink_sfp_connect_phy,