Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: phylink: add support for PCS link change notifications

Add a function, phylink_pcs_change() which can be used by PCs drivers
to notify phylink about changes to the PCS link state.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Russell King (Oracle) and committed by
David S. Miller
24699cc1 aee60988

+41 -4
+34 -4
drivers/net/phy/phylink.c
··· 1137 1137 if (pcs_changed) { 1138 1138 phylink_pcs_disable(pl->pcs); 1139 1139 1140 + if (pl->pcs) 1141 + pl->pcs->phylink = NULL; 1142 + 1143 + pcs->phylink = pl; 1144 + 1140 1145 pl->pcs = pcs; 1141 1146 } 1142 1147 ··· 1996 1991 } 1997 1992 EXPORT_SYMBOL_GPL(phylink_disconnect_phy); 1998 1993 1994 + static void phylink_link_changed(struct phylink *pl, bool up, const char *what) 1995 + { 1996 + if (!up) 1997 + pl->mac_link_dropped = true; 1998 + phylink_run_resolve(pl); 1999 + phylink_dbg(pl, "%s link %s\n", what, up ? "up" : "down"); 2000 + } 2001 + 1999 2002 /** 2000 2003 * phylink_mac_change() - notify phylink of a change in MAC state 2001 2004 * @pl: a pointer to a &struct phylink returned from phylink_create() ··· 2014 2001 */ 2015 2002 void phylink_mac_change(struct phylink *pl, bool up) 2016 2003 { 2017 - if (!up) 2018 - pl->mac_link_dropped = true; 2019 - phylink_run_resolve(pl); 2020 - phylink_dbg(pl, "mac link %s\n", up ? "up" : "down"); 2004 + phylink_link_changed(pl, up, "mac"); 2021 2005 } 2022 2006 EXPORT_SYMBOL_GPL(phylink_mac_change); 2007 + 2008 + /** 2009 + * phylink_pcs_change() - notify phylink of a change to PCS link state 2010 + * @pcs: pointer to &struct phylink_pcs 2011 + * @up: indicates whether the link is currently up. 2012 + * 2013 + * The PCS driver should call this when the state of its link changes 2014 + * (e.g. link failure, new negotiation results, etc.) Note: it should 2015 + * not determine "up" by reading the BMSR. If in doubt about the link 2016 + * state at interrupt time, then pass true if pcs_get_state() returns 2017 + * the latched link-down state, otherwise pass false. 2018 + */ 2019 + void phylink_pcs_change(struct phylink_pcs *pcs, bool up) 2020 + { 2021 + struct phylink *pl = pcs->phylink; 2022 + 2023 + if (pl) 2024 + phylink_link_changed(pl, up, "pcs"); 2025 + } 2026 + EXPORT_SYMBOL_GPL(phylink_pcs_change); 2023 2027 2024 2028 static irqreturn_t phylink_link_handler(int irq, void *data) 2025 2029 {
+7
include/linux/phylink.h
··· 9 9 struct ethtool_cmd; 10 10 struct fwnode_handle; 11 11 struct net_device; 12 + struct phylink; 12 13 13 14 enum { 14 15 MLO_PAUSE_NONE, ··· 521 520 /** 522 521 * struct phylink_pcs - PHYLINK PCS instance 523 522 * @ops: a pointer to the &struct phylink_pcs_ops structure 523 + * @phylink: pointer to &struct phylink_config 524 524 * @neg_mode: provide PCS neg mode via "mode" argument 525 525 * @poll: poll the PCS for link changes 526 526 * 527 527 * This structure is designed to be embedded within the PCS private data, 528 528 * and will be passed between phylink and the PCS. 529 + * 530 + * The @phylink member is private to phylink and must not be touched by 531 + * the PCS driver. 529 532 */ 530 533 struct phylink_pcs { 531 534 const struct phylink_pcs_ops *ops; 535 + struct phylink *phylink; 532 536 bool neg_mode; 533 537 bool poll; 534 538 }; ··· 705 699 void phylink_disconnect_phy(struct phylink *); 706 700 707 701 void phylink_mac_change(struct phylink *, bool up); 702 + void phylink_pcs_change(struct phylink_pcs *, bool up); 708 703 709 704 void phylink_start(struct phylink *); 710 705 void phylink_stop(struct phylink *);