Skip to content

Commit f5e17b4

Browse files
committed
Merge branch 'stmmac-cleanups'
Russell King says: ==================== stmmac cleanups One of the comments I had on Feiyang Chen's series was concerning the initialisation of phylink... and so I've decided to do something about it, cleaning it up a bit. This series: 1) adds a new phylink function to limit the MAC capabilities according to a maximum speed. This allows us to greatly simplify stmmac's initialisation of phylink's mac capabilities. 2) everywhere that uses priv->plat->phylink_node first converts this to a fwnode before doing anything with it. This is silly. Let's instead store it as a fwnode to eliminate these conversions in multiple places. 3) clean up passing the fwnode to phylink - it might as well happen at the phylink_create() callsite, rather than being scattered throughout the entire function. 4) same for mdio_bus_data 5) use phylink_limit_mac_speed() to handle the priv->plat->max_speed restriction. 6) add a method to get the MAC-specific capabilities from the code dealing with the MACs, and arrange to call it at an appropriate time. 7) convert the gmac4 users to use the MAC specific method. 8) same for xgmac. 9) group all the simple phylink_config initialisations together. 10) convert half-duplex logic to being positive logic. While looking into all of this, this raised eyebrows: if (priv->plat->tx_queues_to_use > 1) priv->phylink_config.mac_capabilities &= ~(MAC_10HD | MAC_100HD | MAC_1000HD); priv->plat->tx_queues_to_use is initialised by platforms to either 1, 4 or 8, and can be controlled from userspace via the --set-channels ethtool op. The implementation of this op in this driver limits the number of channels to priv->dma_cap.number_tx_queues, which is derived from the DMA hwcap. So, the obvious questions are: 1) what guarantees that the static initialisation of tx_queues_to_use will always be less than or equal to number_tx_queues from the DMA hw cap? 2) tx_queues_to_use starts off as 1, but number_tx_queues is larger, we will leave the half-duplex capabilities in place, but userspace can increase tx_queues_to_use above 1. Does that mean half-duplex is then not supported? 3) Should we be basing the decision whether half-duplex is supported off the DMA capabilities? 4) What about priv->dma_cap.half_duplex? Doesn't that get a say in whether half-duplex is supported or not? Why isn't this used? Why is it only reported via debugfs? If it's not being used by the driver, what's the point of reporting it via debugfs? ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 215eb9f + 76649fc commit f5e17b4

File tree

9 files changed

+70
-39
lines changed

9 files changed

+70
-39
lines changed

drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ static void dwmac4_core_init(struct mac_device_info *hw,
6868
init_waitqueue_head(&priv->tstamp_busy_wait);
6969
}
7070

71+
static void dwmac4_phylink_get_caps(struct stmmac_priv *priv)
72+
{
73+
priv->phylink_config.mac_capabilities |= MAC_2500FD;
74+
}
75+
7176
static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
7277
u8 mode, u32 queue)
7378
{
@@ -1131,6 +1136,7 @@ static int dwmac4_config_l4_filter(struct mac_device_info *hw, u32 filter_no,
11311136

11321137
const struct stmmac_ops dwmac4_ops = {
11331138
.core_init = dwmac4_core_init,
1139+
.phylink_get_caps = dwmac4_phylink_get_caps,
11341140
.set_mac = stmmac_set_mac,
11351141
.rx_ipc = dwmac4_rx_ipc_enable,
11361142
.rx_queue_enable = dwmac4_rx_queue_enable,
@@ -1173,6 +1179,7 @@ const struct stmmac_ops dwmac4_ops = {
11731179

11741180
const struct stmmac_ops dwmac410_ops = {
11751181
.core_init = dwmac4_core_init,
1182+
.phylink_get_caps = dwmac4_phylink_get_caps,
11761183
.set_mac = stmmac_dwmac4_set_mac,
11771184
.rx_ipc = dwmac4_rx_ipc_enable,
11781185
.rx_queue_enable = dwmac4_rx_queue_enable,
@@ -1221,6 +1228,7 @@ const struct stmmac_ops dwmac410_ops = {
12211228

12221229
const struct stmmac_ops dwmac510_ops = {
12231230
.core_init = dwmac4_core_init,
1231+
.phylink_get_caps = dwmac4_phylink_get_caps,
12241232
.set_mac = stmmac_dwmac4_set_mac,
12251233
.rx_ipc = dwmac4_rx_ipc_enable,
12261234
.rx_queue_enable = dwmac4_rx_queue_enable,

drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
4747
writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
4848
}
4949

50+
static void xgmac_phylink_get_caps(struct stmmac_priv *priv)
51+
{
52+
priv->phylink_config.mac_capabilities |= MAC_2500FD | MAC_5000FD |
53+
MAC_10000FD | MAC_25000FD |
54+
MAC_40000FD | MAC_50000FD |
55+
MAC_100000FD;
56+
}
57+
5058
static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
5159
{
5260
u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
@@ -1490,6 +1498,7 @@ static void dwxgmac3_fpe_configure(void __iomem *ioaddr, u32 num_txq,
14901498

14911499
const struct stmmac_ops dwxgmac210_ops = {
14921500
.core_init = dwxgmac2_core_init,
1501+
.phylink_get_caps = xgmac_phylink_get_caps,
14931502
.set_mac = dwxgmac2_set_mac,
14941503
.rx_ipc = dwxgmac2_rx_ipc,
14951504
.rx_queue_enable = dwxgmac2_rx_queue_enable,
@@ -1551,6 +1560,7 @@ static void dwxlgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
15511560

15521561
const struct stmmac_ops dwxlgmac2_ops = {
15531562
.core_init = dwxgmac2_core_init,
1563+
.phylink_get_caps = xgmac_phylink_get_caps,
15541564
.set_mac = dwxgmac2_set_mac,
15551565
.rx_ipc = dwxgmac2_rx_ipc,
15561566
.rx_queue_enable = dwxlgmac2_rx_queue_enable,

drivers/net/ethernet/stmicro/stmmac/hwif.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ struct stmmac_est;
300300
struct stmmac_ops {
301301
/* MAC core initialization */
302302
void (*core_init)(struct mac_device_info *hw, struct net_device *dev);
303+
/* Get phylink capabilities */
304+
void (*phylink_get_caps)(struct stmmac_priv *priv);
303305
/* Enable the MAC RX/TX */
304306
void (*set_mac)(void __iomem *ioaddr, bool enable);
305307
/* Enable and verify that the IPC module is supported */
@@ -419,6 +421,8 @@ struct stmmac_ops {
419421

420422
#define stmmac_core_init(__priv, __args...) \
421423
stmmac_do_void_callback(__priv, mac, core_init, __args)
424+
#define stmmac_mac_phylink_get_caps(__priv) \
425+
stmmac_do_void_callback(__priv, mac, phylink_get_caps, __priv)
422426
#define stmmac_mac_set(__priv, __args...) \
423427
stmmac_do_void_callback(__priv, mac, set_mac, __args)
424428
#define stmmac_rx_ipc(__priv, __args...) \

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ static int stmmac_init_phy(struct net_device *dev)
11531153
if (!phylink_expects_phy(priv->phylink))
11541154
return 0;
11551155

1156-
fwnode = of_fwnode_handle(priv->plat->phylink_node);
1156+
fwnode = priv->plat->port_node;
11571157
if (!fwnode)
11581158
fwnode = dev_fwnode(priv->device);
11591159

@@ -1199,21 +1199,21 @@ static int stmmac_init_phy(struct net_device *dev)
11991199

12001200
static int stmmac_phy_setup(struct stmmac_priv *priv)
12011201
{
1202-
struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
1203-
struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node);
1204-
int max_speed = priv->plat->max_speed;
1202+
struct stmmac_mdio_bus_data *mdio_bus_data;
12051203
int mode = priv->plat->phy_interface;
1204+
struct fwnode_handle *fwnode;
12061205
struct phylink *phylink;
1206+
int max_speed;
12071207

12081208
priv->phylink_config.dev = &priv->dev->dev;
12091209
priv->phylink_config.type = PHYLINK_NETDEV;
1210-
if (priv->plat->mdio_bus_data)
1210+
priv->phylink_config.mac_managed_pm = true;
1211+
1212+
mdio_bus_data = priv->plat->mdio_bus_data;
1213+
if (mdio_bus_data)
12111214
priv->phylink_config.ovr_an_inband =
12121215
mdio_bus_data->xpcs_an_inband;
12131216

1214-
if (!fwnode)
1215-
fwnode = dev_fwnode(priv->device);
1216-
12171217
/* Set the platform/firmware specified interface mode */
12181218
__set_bit(mode, priv->phylink_config.supported_interfaces);
12191219

@@ -1223,36 +1223,24 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
12231223
priv->phylink_config.supported_interfaces);
12241224

12251225
priv->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
1226-
MAC_10 | MAC_100;
1227-
1228-
if (!max_speed || max_speed >= 1000)
1229-
priv->phylink_config.mac_capabilities |= MAC_1000;
1230-
1231-
if (priv->plat->has_gmac4) {
1232-
if (!max_speed || max_speed >= 2500)
1233-
priv->phylink_config.mac_capabilities |= MAC_2500FD;
1234-
} else if (priv->plat->has_xgmac) {
1235-
if (!max_speed || max_speed >= 2500)
1236-
priv->phylink_config.mac_capabilities |= MAC_2500FD;
1237-
if (!max_speed || max_speed >= 5000)
1238-
priv->phylink_config.mac_capabilities |= MAC_5000FD;
1239-
if (!max_speed || max_speed >= 10000)
1240-
priv->phylink_config.mac_capabilities |= MAC_10000FD;
1241-
if (!max_speed || max_speed >= 25000)
1242-
priv->phylink_config.mac_capabilities |= MAC_25000FD;
1243-
if (!max_speed || max_speed >= 40000)
1244-
priv->phylink_config.mac_capabilities |= MAC_40000FD;
1245-
if (!max_speed || max_speed >= 50000)
1246-
priv->phylink_config.mac_capabilities |= MAC_50000FD;
1247-
if (!max_speed || max_speed >= 100000)
1248-
priv->phylink_config.mac_capabilities |= MAC_100000FD;
1249-
}
1226+
MAC_10FD | MAC_100FD |
1227+
MAC_1000FD;
12501228

12511229
/* Half-Duplex can only work with single queue */
1252-
if (priv->plat->tx_queues_to_use > 1)
1253-
priv->phylink_config.mac_capabilities &=
1254-
~(MAC_10HD | MAC_100HD | MAC_1000HD);
1255-
priv->phylink_config.mac_managed_pm = true;
1230+
if (priv->plat->tx_queues_to_use <= 1)
1231+
priv->phylink_config.mac_capabilities |= MAC_10HD | MAC_100HD |
1232+
MAC_1000HD;
1233+
1234+
/* Get the MAC specific capabilities */
1235+
stmmac_mac_phylink_get_caps(priv);
1236+
1237+
max_speed = priv->plat->max_speed;
1238+
if (max_speed)
1239+
phylink_limit_mac_speed(&priv->phylink_config, max_speed);
1240+
1241+
fwnode = priv->plat->port_node;
1242+
if (!fwnode)
1243+
fwnode = dev_fwnode(priv->device);
12561244

12571245
phylink = phylink_create(&priv->phylink_config, fwnode,
12581246
mode, &stmmac_phylink_mac_ops);

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,11 @@ int stmmac_mdio_register(struct net_device *ndev)
533533
int err = 0;
534534
struct mii_bus *new_bus;
535535
struct stmmac_priv *priv = netdev_priv(ndev);
536-
struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node);
537536
struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
538537
struct device_node *mdio_node = priv->plat->mdio_node;
539538
struct device *dev = ndev->dev.parent;
540539
struct fwnode_handle *fixed_node;
540+
struct fwnode_handle *fwnode;
541541
int addr, found, max_addr;
542542

543543
if (!mdio_bus_data)
@@ -601,6 +601,7 @@ int stmmac_mdio_register(struct net_device *ndev)
601601
stmmac_xgmac2_mdio_read_c45(new_bus, 0, 0, 0);
602602

603603
/* If fixed-link is set, skip PHY scanning */
604+
fwnode = priv->plat->port_node;
604605
if (!fwnode)
605606
fwnode = dev_fwnode(priv->device);
606607

drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
428428
plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
429429

430430
/* PHYLINK automatically parses the phy-handle property */
431-
plat->phylink_node = np;
431+
plat->port_node = of_fwnode_handle(np);
432432

433433
/* Get max speed of operation from device tree */
434434
of_property_read_u32(np, "max-speed", &plat->max_speed);

drivers/net/phy/phylink.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,24 @@ static struct {
426426
{ MAC_10HD, SPEED_10, DUPLEX_HALF },
427427
};
428428

429+
/**
430+
* phylink_limit_mac_speed - limit the phylink_config to a maximum speed
431+
* @config: pointer to a &struct phylink_config
432+
* @max_speed: maximum speed
433+
*
434+
* Mask off MAC capabilities for speeds higher than the @max_speed parameter.
435+
* Any further motifications of config.mac_capabilities will override this.
436+
*/
437+
void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed)
438+
{
439+
int i;
440+
441+
for (i = 0; i < ARRAY_SIZE(phylink_caps_params) &&
442+
phylink_caps_params[i].speed > max_speed; i++)
443+
config->mac_capabilities &= ~phylink_caps_params[i].mask;
444+
}
445+
EXPORT_SYMBOL_GPL(phylink_limit_mac_speed);
446+
429447
/**
430448
* phylink_cap_from_speed_duplex - Get mac capability from speed/duplex
431449
* @speed: the speed to search for

include/linux/phylink.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ struct phylink_config {
223223
unsigned long mac_capabilities;
224224
};
225225

226+
void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed);
227+
226228
/**
227229
* struct phylink_mac_ops - MAC operations structure.
228230
* @validate: Validate and update the link configuration.

include/linux/stmmac.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ struct plat_stmmacenet_data {
227227
phy_interface_t phy_interface;
228228
struct stmmac_mdio_bus_data *mdio_bus_data;
229229
struct device_node *phy_node;
230-
struct device_node *phylink_node;
230+
struct fwnode_handle *port_node;
231231
struct device_node *mdio_node;
232232
struct stmmac_dma_cfg *dma_cfg;
233233
struct stmmac_est *est;

0 commit comments

Comments
 (0)