[][kernel][common][eth][Add phylink pcs_enable and pcs_disable methods]
[Description]
Add phylink pcs_enable and pcs_disable methods from Linux-6.6.
Without this patch, the phylink framework is unable to enable or
disable PCS.
[Release-log]
N/A
Change-Id: I66f217e7279c152ef3f093d6c31c072c1dac423f
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9070480
diff --git a/21.02/files/target/linux/mediatek/patches-5.4/999-1716-v6.6-net-phy-add-phylink-pcs_enable-and-pcs_disable.patch b/21.02/files/target/linux/mediatek/patches-5.4/999-1716-v6.6-net-phy-add-phylink-pcs_enable-and-pcs_disable.patch
new file mode 100644
index 0000000..29306fd
--- /dev/null
+++ b/21.02/files/target/linux/mediatek/patches-5.4/999-1716-v6.6-net-phy-add-phylink-pcs_enable-and-pcs_disable.patch
@@ -0,0 +1,109 @@
+From d3fd7b4ccaf867811a777cf7aecaaa9f32d94331 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Mon, 13 May 2024 17:05:16 +0800
+Subject: [PATCH] 999-1716-v6.6-net-phy-add-phylink-pcs_enable-and-pcs_disable
+
+---
+ drivers/net/phy/phylink.c | 26 +++++++++++++++++++++++++-
+ include/linux/phylink.h | 2 ++
+ 2 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
+index 9b9bb17..1d79f59 100644
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -32,6 +32,10 @@
+ enum {
+ PHYLINK_DISABLE_STOPPED,
+ PHYLINK_DISABLE_LINK,
++
++ PCS_STATE_DOWN = 0,
++ PCS_STATE_STARTING,
++ PCS_STATE_STARTED,
+ };
+
+ /**
+@@ -69,6 +73,7 @@ struct phylink {
+ struct mutex state_mutex;
+ struct phylink_link_state phy_state;
+ struct work_struct resolve;
++ unsigned int pcs_state;
+
+ bool mac_link_dropped;
+ bool using_mac_select_pcs;
+@@ -520,11 +525,20 @@ static void phylink_major_config(struct phylink *pl, bool restart,
+ /* If we have a new PCS, switch to the new PCS after preparing the MAC
+ * for the change.
+ */
+- if (pcs_changed)
++ if (pcs_changed) {
++ if (pl->pcs && pl->pcs->ops->pcs_disable)
++ pcs->ops->pcs_disable(pl->pcs);
++
+ pl->pcs = pcs;
++ }
+
+ phylink_mac_config(pl, state);
+
++ if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) {
++ if (pl->pcs && pl->pcs->ops->pcs_enable)
++ err = pcs->ops->pcs_enable(pl->pcs);
++ }
++
+ if (pl->pcs) {
+ err = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
+ state->interface,
+@@ -1022,6 +1036,7 @@ struct phylink *phylink_create(struct phylink_config *config,
+ pl->link_config.speed = SPEED_UNKNOWN;
+ pl->link_config.duplex = DUPLEX_UNKNOWN;
+ pl->link_config.an_enabled = true;
++ pl->pcs_state = PCS_STATE_DOWN;
+ pl->mac_ops = mac_ops;
+ __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
+ timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
+@@ -1370,6 +1385,8 @@ void phylink_start(struct phylink *pl)
+ if (pl->netdev)
+ netif_carrier_off(pl->netdev);
+
++ pl->pcs_state = PCS_STATE_STARTING;
++
+ /* Apply the link configuration to the MAC when starting. This allows
+ * a fixed-link to start with the correct parameters, and also
+ * ensures that we set the appropriate advertisement for Serdes links.
+@@ -1381,6 +1398,8 @@ void phylink_start(struct phylink *pl)
+ phylink_resolve_flow(pl, &pl->link_config);
+ phylink_mac_initial_config(pl, true);
+
++ pl->pcs_state = PCS_STATE_STARTED;
++
+ clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
+ phylink_run_resolve(pl);
+
+@@ -1442,6 +1461,11 @@ void phylink_stop(struct phylink *pl)
+ }
+
+ phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
++
++ pl->pcs_state = PCS_STATE_DOWN;
++
++ if (pl->pcs && pl->pcs->ops->pcs_disable)
++ pl->pcs->ops->pcs_disable(pl->pcs);
+ }
+ EXPORT_SYMBOL_GPL(phylink_stop);
+
+diff --git a/include/linux/phylink.h b/include/linux/phylink.h
+index e1c022f..fae9794 100644
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -349,6 +349,8 @@ struct phylink_pcs {
+ struct phylink_pcs_ops {
+ int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
+ const struct phylink_link_state *state);
++ int (*pcs_enable)(struct phylink_pcs *pcs);
++ void (*pcs_disable)(struct phylink_pcs *pcs);
+ void (*pcs_get_state)(struct phylink_pcs *pcs,
+ struct phylink_link_state *state);
+ int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
+--
+2.18.0
+