mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-13 04:38:14 +04:00
generic: update pending PCS patch with .fill_available_pcs OP
While implementing standalone PCS support for DSA, it was found that making
the MAC driver passing the available_pcs array is limiting and problematic
for memory handling and allocation. To better handle this, change the logic
and make phylink allocate the struct and make the MAC driver implement a
function in phylink_config .fill_available_pcs to fill the PCS array.
Update the Airoha and Mediatek driver to reflect this new implementation.
Link: https://github.com/openwrt/openwrt/pull/23413
(cherry picked from commit 627cd79e1c)
Link: https://github.com/openwrt/openwrt/pull/24823
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
5 files changed
+85
-31
No files matched your search
+77
-23
@@ -210,13 +210,13 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
|
||||
- pcs_changed = pl->pcs != pcs;
|
||||
+ if (!pcs_found) {
|
||||
+ phylink_err(pl,
|
||||
+ "couldn't find a PCS for %s\n",
|
||||
+ phy_modes(state->interface));
|
||||
|
||||
- pcs_changed = pl->pcs != pcs;
|
||||
+
|
||||
+ pl->major_config_failed = true;
|
||||
+ return;
|
||||
+ }
|
||||
@@ -245,28 +245,70 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
pl->pcs = pcs;
|
||||
}
|
||||
@@ -1931,8 +2006,9 @@ struct phylink *phylink_create(struct ph
|
||||
@@ -1909,6 +1984,44 @@ int phylink_set_fixed_link(struct phylin
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phylink_set_fixed_link);
|
||||
|
||||
+static int phylink_fill_available_pcs(struct phylink *pl,
|
||||
+ struct phylink_config *config)
|
||||
+{
|
||||
+ struct phylink_pcs **pcss;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ if (!config->num_available_pcs)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!config->fill_available_pcs) {
|
||||
+ dev_err(config->dev,
|
||||
+ "phylink: error: num_available_pcs defined but no fill_available_pcs\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ pcss = kcalloc(config->num_available_pcs, sizeof(*pcss), GFP_KERNEL);
|
||||
+ if (!pcss)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = config->fill_available_pcs(config, pcss, config->num_available_pcs);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ for (i = 0; i < config->num_available_pcs; i++) {
|
||||
+ struct phylink_pcs *pcs = pcss[i];
|
||||
+
|
||||
+ if (!pcs)
|
||||
+ continue;
|
||||
+
|
||||
+ list_add(&pcs->list, &pl->pcs_list);
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ kfree(pcss);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* phylink_create() - create a phylink instance
|
||||
* @config: a pointer to the target &struct phylink_config
|
||||
@@ -1931,6 +2044,7 @@ struct phylink *phylink_create(struct ph
|
||||
const struct phylink_mac_ops *mac_ops)
|
||||
{
|
||||
bool using_mac_select_pcs = false;
|
||||
+ struct phylink_pcs *pcs;
|
||||
struct phylink *pl;
|
||||
- int ret;
|
||||
+ int i, ret;
|
||||
int ret;
|
||||
|
||||
/* Validate the supplied configuration */
|
||||
if (phy_interface_empty(config->supported_interfaces)) {
|
||||
@@ -1952,9 +2028,21 @@ struct phylink *phylink_create(struct ph
|
||||
@@ -1952,9 +2066,21 @@ struct phylink *phylink_create(struct ph
|
||||
|
||||
mutex_init(&pl->state_mutex);
|
||||
INIT_WORK(&pl->resolve, phylink_resolve);
|
||||
+ INIT_LIST_HEAD(&pl->pcs_list);
|
||||
+
|
||||
+ /* Fill the PCS list with available PCS from phylink config */
|
||||
+ for (i = 0; i < config->num_available_pcs; i++) {
|
||||
+ pcs = config->available_pcs[i];
|
||||
+
|
||||
+ list_add(&pcs->list, &pl->pcs_list);
|
||||
+ ret = phylink_fill_available_pcs(pl, config);
|
||||
+ if (ret) {
|
||||
+ kfree(pl);
|
||||
+ return ERR_PTR(ret);
|
||||
+ }
|
||||
|
||||
phy_interface_copy(pl->supported_interfaces,
|
||||
@@ -278,7 +320,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
pl->config = config;
|
||||
if (config->type == PHYLINK_NETDEV) {
|
||||
@@ -2024,10 +2112,16 @@ EXPORT_SYMBOL_GPL(phylink_create);
|
||||
@@ -2025,10 +2151,16 @@ EXPORT_SYMBOL_GPL(phylink_create);
|
||||
*/
|
||||
void phylink_destroy(struct phylink *pl)
|
||||
{
|
||||
@@ -295,7 +337,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
cancel_work_sync(&pl->resolve);
|
||||
kfree(pl);
|
||||
}
|
||||
@@ -2472,6 +2566,7 @@ static irqreturn_t phylink_link_handler(
|
||||
@@ -2473,6 +2605,7 @@ static irqreturn_t phylink_link_handler(
|
||||
*/
|
||||
void phylink_start(struct phylink *pl)
|
||||
{
|
||||
@@ -303,7 +345,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
bool poll = false;
|
||||
|
||||
ASSERT_RTNL();
|
||||
@@ -2498,6 +2593,10 @@ void phylink_start(struct phylink *pl)
|
||||
@@ -2499,6 +2632,10 @@ void phylink_start(struct phylink *pl)
|
||||
|
||||
pl->pcs_state = PCS_STATE_STARTED;
|
||||
|
||||
@@ -314,7 +356,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_STOPPED);
|
||||
|
||||
if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) {
|
||||
@@ -2542,6 +2641,8 @@ EXPORT_SYMBOL_GPL(phylink_start);
|
||||
@@ -2543,6 +2680,8 @@ EXPORT_SYMBOL_GPL(phylink_start);
|
||||
*/
|
||||
void phylink_stop(struct phylink *pl)
|
||||
{
|
||||
@@ -323,7 +365,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (pl->sfp_bus)
|
||||
@@ -2559,6 +2660,14 @@ void phylink_stop(struct phylink *pl)
|
||||
@@ -2560,6 +2699,14 @@ void phylink_stop(struct phylink *pl)
|
||||
pl->pcs_state = PCS_STATE_DOWN;
|
||||
|
||||
phylink_pcs_disable(pl->pcs);
|
||||
@@ -340,31 +382,43 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -147,7 +147,11 @@ enum phylink_op_type {
|
||||
@@ -10,6 +10,7 @@ struct ethtool_cmd;
|
||||
struct fwnode_handle;
|
||||
struct net_device;
|
||||
struct phylink;
|
||||
+struct phylink_pcs;
|
||||
|
||||
enum {
|
||||
MLO_PAUSE_NONE,
|
||||
@@ -147,7 +148,13 @@ enum phylink_op_type {
|
||||
* if MAC link is at %MLO_AN_FIXED mode.
|
||||
* @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx
|
||||
* are supported by the MAC/PCS.
|
||||
+ * @pcs_interfaces: bitmap describing for which PHY_INTERFACE_MODE_xxx a
|
||||
+ * dedicated PCS is required.
|
||||
* @mac_capabilities: MAC pause/speed/duplex capabilities.
|
||||
+ * @available_pcs: array of available phylink_pcs PCS
|
||||
+ * @num_available_pcs: num of available phylink_pcs PCS
|
||||
+ * @fill_available_pcs: callback to fill the available PCS in the passed
|
||||
+ * array struct of phylink_pcs PCS available_pcs up to
|
||||
+ * num_available_pcs.
|
||||
*/
|
||||
struct phylink_config {
|
||||
struct device *dev;
|
||||
@@ -159,7 +163,11 @@ struct phylink_config {
|
||||
@@ -159,7 +166,13 @@ struct phylink_config {
|
||||
void (*get_fixed_state)(struct phylink_config *config,
|
||||
struct phylink_link_state *state);
|
||||
DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
|
||||
+ DECLARE_PHY_INTERFACE_MASK(pcs_interfaces);
|
||||
unsigned long mac_capabilities;
|
||||
+
|
||||
+ struct phylink_pcs **available_pcs;
|
||||
+ unsigned int num_available_pcs;
|
||||
+ int (*fill_available_pcs)(struct phylink_config *config,
|
||||
+ struct phylink_pcs **available_pcs,
|
||||
+ unsigned int num_available_pcs);
|
||||
};
|
||||
|
||||
void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed);
|
||||
@@ -417,6 +425,9 @@ struct phylink_pcs {
|
||||
@@ -417,6 +430,9 @@ struct phylink_pcs {
|
||||
bool neg_mode;
|
||||
bool poll;
|
||||
bool rxc_always_on;
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
/* If configuration of the interface failed, force the link down
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -632,6 +632,8 @@ void phylink_disconnect_phy(struct phyli
|
||||
@@ -637,6 +637,8 @@ void phylink_disconnect_phy(struct phyli
|
||||
int phylink_set_fixed_link(struct phylink *,
|
||||
const struct phylink_link_state *);
|
||||
|
||||
|
||||
+3
-3
@@ -110,9 +110,9 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
/* What interface are supported by the current link.
|
||||
* Can change on removal or addition of new PCS.
|
||||
@@ -2039,6 +2041,51 @@ int phylink_set_fixed_link(struct phylin
|
||||
@@ -2077,6 +2079,51 @@ out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phylink_set_fixed_link);
|
||||
|
||||
+static int pcs_provider_notify(struct notifier_block *self,
|
||||
+ unsigned long val, void *data)
|
||||
@@ -162,7 +162,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
/**
|
||||
* phylink_create() - create a phylink instance
|
||||
* @config: a pointer to the target &struct phylink_config
|
||||
@@ -2099,6 +2146,11 @@ struct phylink *phylink_create(struct ph
|
||||
@@ -2137,6 +2184,11 @@ struct phylink *phylink_create(struct ph
|
||||
pl->supported_interfaces,
|
||||
pcs->supported_interfaces);
|
||||
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
phylink_info(pl, "Link is Down\n");
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -443,6 +443,7 @@ struct phylink_pcs {
|
||||
@@ -448,6 +448,7 @@ struct phylink_pcs {
|
||||
* @pcs_an_restart: restart 802.3z BaseX autonegotiation.
|
||||
* @pcs_link_up: program the PCS for the resolved link configuration
|
||||
* (where necessary).
|
||||
@@ -54,7 +54,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
* @pcs_pre_init: configure PCS components necessary for MAC hardware
|
||||
* initialization e.g. RX clock for stmmac.
|
||||
*/
|
||||
@@ -466,6 +467,7 @@ struct phylink_pcs_ops {
|
||||
@@ -471,6 +472,7 @@ struct phylink_pcs_ops {
|
||||
void (*pcs_an_restart)(struct phylink_pcs *pcs);
|
||||
void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode,
|
||||
phy_interface_t interface, int speed, int duplex);
|
||||
|
||||
@@ -11,7 +11,7 @@ Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
|
||||
---
|
||||
--- a/drivers/net/pcs/Kconfig
|
||||
+++ b/drivers/net/pcs/Kconfig
|
||||
@@ -36,6 +36,14 @@ config PCS_MTK_USXGMII
|
||||
@@ -43,6 +43,14 @@ config PCS_MTK_USXGMII
|
||||
1000Base-X, 2500Base-X and Cisco SGMII are supported on the same
|
||||
differential pairs via an embedded LynxI PHY.
|
||||
|
||||
@@ -28,7 +28,7 @@ Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
|
||||
depends on OF && (ARCH_RZN1 || COMPILE_TEST)
|
||||
--- a/drivers/net/pcs/Makefile
|
||||
+++ b/drivers/net/pcs/Makefile
|
||||
@@ -7,5 +7,6 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.
|
||||
@@ -8,5 +8,6 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.
|
||||
obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o
|
||||
obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
|
||||
obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o
|
||||
|
||||
Reference in new issue
Block a user