Skip to content

Commit af74be9

Browse files
committed
Merge branch 'net-dsa-allow-phylink_mac_ops-in-dsa-drivers'
Russell King says: ==================== net: dsa: allow phylink_mac_ops in DSA drivers This series showcases my idea of moving the phylink_mac_ops into DSA drivers, using mv88e6xxx as an example. Since I'm only changing one driver, providing the mac_ops has to be optional and the existing shims need to be kept for unconverted drivers. The first patch introduces a new helper that converts from the phylink_config structure that phylink uses to communicate with MAC drivers to the dsa_port structure. From this, DSA drivers can get the dsa_switch structure and thus their implementation specific data structure, and they can also retrieve the port index. The second patch adds the support to the core DSA layer to allow DSA drivers to provide phylink_mac_ops. The third patch converts mv88e6xxx to use this. I initially made this change after adding yet more phylink to DSA driver shims for my work with phylink-based EEE support, and decided that it was getting silly to keep implementing more and more shims. There are cases where shims don't work well - we had already tripped over a case a few years ago when the phylink mac_select_pcs operation was introduced. Phylink tested for the presence of this in the ops structure, but with DSA shims, this doesn't necessarily mean that the sub-driver supports this method. The only way to find that out is to call the method with dummy values and check the return code. The same thing was partly true when adding EEE support, and I ended up with this in phylink to determine whether the MAC supported EEE: +static bool phylink_mac_supports_eee(struct phylink *pl) +{ + return pl->mac_ops->mac_disable_tx_lpi && + pl->mac_ops->mac_enable_tx_lpi && + pl->config->lpi_capabilities; +} because merely testing for the presence of the operations is insufficient when shims are involved - and it wasn't possible to call these functions in the way that mac_select_pcs could be called. So, I think it's time to get away from this shimming model and instead have drivers directly interface to the various subsystems. This converts mv88e6xxx. I have similar patches for other DSA drivers that will be sent once this has been reviewed. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents f7ac8fb + 0cb6da0 commit af74be9

File tree

4 files changed

+87
-36
lines changed

4 files changed

+87
-36
lines changed

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -790,24 +790,27 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
790790
}
791791
}
792792

793-
static struct phylink_pcs *mv88e6xxx_mac_select_pcs(struct dsa_switch *ds,
794-
int port,
795-
phy_interface_t interface)
793+
static struct phylink_pcs *
794+
mv88e6xxx_mac_select_pcs(struct phylink_config *config,
795+
phy_interface_t interface)
796796
{
797-
struct mv88e6xxx_chip *chip = ds->priv;
797+
struct dsa_port *dp = dsa_phylink_to_port(config);
798+
struct mv88e6xxx_chip *chip = dp->ds->priv;
798799
struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
799800

800801
if (chip->info->ops->pcs_ops)
801-
pcs = chip->info->ops->pcs_ops->pcs_select(chip, port,
802+
pcs = chip->info->ops->pcs_ops->pcs_select(chip, dp->index,
802803
interface);
803804

804805
return pcs;
805806
}
806807

807-
static int mv88e6xxx_mac_prepare(struct dsa_switch *ds, int port,
808+
static int mv88e6xxx_mac_prepare(struct phylink_config *config,
808809
unsigned int mode, phy_interface_t interface)
809810
{
810-
struct mv88e6xxx_chip *chip = ds->priv;
811+
struct dsa_port *dp = dsa_phylink_to_port(config);
812+
struct mv88e6xxx_chip *chip = dp->ds->priv;
813+
int port = dp->index;
811814
int err = 0;
812815

813816
/* In inband mode, the link may come up at any time while the link
@@ -826,11 +829,13 @@ static int mv88e6xxx_mac_prepare(struct dsa_switch *ds, int port,
826829
return err;
827830
}
828831

829-
static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
832+
static void mv88e6xxx_mac_config(struct phylink_config *config,
830833
unsigned int mode,
831834
const struct phylink_link_state *state)
832835
{
833-
struct mv88e6xxx_chip *chip = ds->priv;
836+
struct dsa_port *dp = dsa_phylink_to_port(config);
837+
struct mv88e6xxx_chip *chip = dp->ds->priv;
838+
int port = dp->index;
834839
int err = 0;
835840

836841
mv88e6xxx_reg_lock(chip);
@@ -846,13 +851,15 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
846851
mv88e6xxx_reg_unlock(chip);
847852

848853
if (err && err != -EOPNOTSUPP)
849-
dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
854+
dev_err(chip->dev, "p%d: failed to configure MAC/PCS\n", port);
850855
}
851856

852-
static int mv88e6xxx_mac_finish(struct dsa_switch *ds, int port,
857+
static int mv88e6xxx_mac_finish(struct phylink_config *config,
853858
unsigned int mode, phy_interface_t interface)
854859
{
855-
struct mv88e6xxx_chip *chip = ds->priv;
860+
struct dsa_port *dp = dsa_phylink_to_port(config);
861+
struct mv88e6xxx_chip *chip = dp->ds->priv;
862+
int port = dp->index;
856863
int err = 0;
857864

858865
/* Undo the forced down state above after completing configuration
@@ -876,12 +883,14 @@ static int mv88e6xxx_mac_finish(struct dsa_switch *ds, int port,
876883
return err;
877884
}
878885

879-
static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
886+
static void mv88e6xxx_mac_link_down(struct phylink_config *config,
880887
unsigned int mode,
881888
phy_interface_t interface)
882889
{
883-
struct mv88e6xxx_chip *chip = ds->priv;
890+
struct dsa_port *dp = dsa_phylink_to_port(config);
891+
struct mv88e6xxx_chip *chip = dp->ds->priv;
884892
const struct mv88e6xxx_ops *ops;
893+
int port = dp->index;
885894
int err = 0;
886895

887896
ops = chip->info->ops;
@@ -904,14 +913,16 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
904913
"p%d: failed to force MAC link down\n", port);
905914
}
906915

907-
static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
908-
unsigned int mode, phy_interface_t interface,
916+
static void mv88e6xxx_mac_link_up(struct phylink_config *config,
909917
struct phy_device *phydev,
918+
unsigned int mode, phy_interface_t interface,
910919
int speed, int duplex,
911920
bool tx_pause, bool rx_pause)
912921
{
913-
struct mv88e6xxx_chip *chip = ds->priv;
922+
struct dsa_port *dp = dsa_phylink_to_port(config);
923+
struct mv88e6xxx_chip *chip = dp->ds->priv;
914924
const struct mv88e6xxx_ops *ops;
925+
int port = dp->index;
915926
int err = 0;
916927

917928
ops = chip->info->ops;
@@ -937,7 +948,7 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
937948
mv88e6xxx_reg_unlock(chip);
938949

939950
if (err && err != -EOPNOTSUPP)
940-
dev_err(ds->dev,
951+
dev_err(chip->dev,
941952
"p%d: failed to configure MAC link up\n", port);
942953
}
943954

@@ -6922,6 +6933,15 @@ static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,
69226933
return err_sync ? : err_pvt;
69236934
}
69246935

6936+
static const struct phylink_mac_ops mv88e6xxx_phylink_mac_ops = {
6937+
.mac_select_pcs = mv88e6xxx_mac_select_pcs,
6938+
.mac_prepare = mv88e6xxx_mac_prepare,
6939+
.mac_config = mv88e6xxx_mac_config,
6940+
.mac_finish = mv88e6xxx_mac_finish,
6941+
.mac_link_down = mv88e6xxx_mac_link_down,
6942+
.mac_link_up = mv88e6xxx_mac_link_up,
6943+
};
6944+
69256945
static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
69266946
.get_tag_protocol = mv88e6xxx_get_tag_protocol,
69276947
.change_tag_protocol = mv88e6xxx_change_tag_protocol,
@@ -6930,12 +6950,6 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
69306950
.port_setup = mv88e6xxx_port_setup,
69316951
.port_teardown = mv88e6xxx_port_teardown,
69326952
.phylink_get_caps = mv88e6xxx_get_caps,
6933-
.phylink_mac_select_pcs = mv88e6xxx_mac_select_pcs,
6934-
.phylink_mac_prepare = mv88e6xxx_mac_prepare,
6935-
.phylink_mac_config = mv88e6xxx_mac_config,
6936-
.phylink_mac_finish = mv88e6xxx_mac_finish,
6937-
.phylink_mac_link_down = mv88e6xxx_mac_link_down,
6938-
.phylink_mac_link_up = mv88e6xxx_mac_link_up,
69396953
.get_strings = mv88e6xxx_get_strings,
69406954
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
69416955
.get_eth_mac_stats = mv88e6xxx_get_eth_mac_stats,
@@ -7004,6 +7018,7 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
70047018
ds->priv = chip;
70057019
ds->dev = dev;
70067020
ds->ops = &mv88e6xxx_switch_ops;
7021+
ds->phylink_mac_ops = &mv88e6xxx_phylink_mac_ops;
70077022
ds->ageing_time_min = chip->info->age_time_coeff;
70087023
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
70097024

include/net/dsa.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,12 @@ struct dsa_port {
327327
};
328328
};
329329

330+
static inline struct dsa_port *
331+
dsa_phylink_to_port(struct phylink_config *config)
332+
{
333+
return container_of(config, struct dsa_port, pl_config);
334+
}
335+
330336
/* TODO: ideally DSA ports would have a single dp->link_dp member,
331337
* and no dst->rtable nor this struct dsa_link would be needed,
332338
* but this would require some more complex tree walking,
@@ -451,6 +457,11 @@ struct dsa_switch {
451457
*/
452458
const struct dsa_switch_ops *ops;
453459

460+
/*
461+
* Allow a DSA switch driver to override the phylink MAC ops
462+
*/
463+
const struct phylink_mac_ops *phylink_mac_ops;
464+
454465
/*
455466
* User mii_bus and devices for the individual ports.
456467
*/

net/dsa/dsa.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,17 @@ static int dsa_switch_probe(struct dsa_switch *ds)
15051505
if (!ds->num_ports)
15061506
return -EINVAL;
15071507

1508+
if (ds->phylink_mac_ops) {
1509+
if (ds->ops->phylink_mac_select_pcs ||
1510+
ds->ops->phylink_mac_prepare ||
1511+
ds->ops->phylink_mac_config ||
1512+
ds->ops->phylink_mac_finish ||
1513+
ds->ops->phylink_mac_link_down ||
1514+
ds->ops->phylink_mac_link_up ||
1515+
ds->ops->adjust_link)
1516+
return -EINVAL;
1517+
}
1518+
15081519
if (np) {
15091520
err = dsa_switch_parse_of(ds, np);
15101521
if (err)

net/dsa/port.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ static struct phylink_pcs *
15581558
dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
15591559
phy_interface_t interface)
15601560
{
1561-
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
1561+
struct dsa_port *dp = dsa_phylink_to_port(config);
15621562
struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
15631563
struct dsa_switch *ds = dp->ds;
15641564

@@ -1572,7 +1572,7 @@ static int dsa_port_phylink_mac_prepare(struct phylink_config *config,
15721572
unsigned int mode,
15731573
phy_interface_t interface)
15741574
{
1575-
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
1575+
struct dsa_port *dp = dsa_phylink_to_port(config);
15761576
struct dsa_switch *ds = dp->ds;
15771577
int err = 0;
15781578

@@ -1587,7 +1587,7 @@ static void dsa_port_phylink_mac_config(struct phylink_config *config,
15871587
unsigned int mode,
15881588
const struct phylink_link_state *state)
15891589
{
1590-
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
1590+
struct dsa_port *dp = dsa_phylink_to_port(config);
15911591
struct dsa_switch *ds = dp->ds;
15921592

15931593
if (!ds->ops->phylink_mac_config)
@@ -1600,7 +1600,7 @@ static int dsa_port_phylink_mac_finish(struct phylink_config *config,
16001600
unsigned int mode,
16011601
phy_interface_t interface)
16021602
{
1603-
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
1603+
struct dsa_port *dp = dsa_phylink_to_port(config);
16041604
struct dsa_switch *ds = dp->ds;
16051605
int err = 0;
16061606

@@ -1615,7 +1615,7 @@ static void dsa_port_phylink_mac_link_down(struct phylink_config *config,
16151615
unsigned int mode,
16161616
phy_interface_t interface)
16171617
{
1618-
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
1618+
struct dsa_port *dp = dsa_phylink_to_port(config);
16191619
struct phy_device *phydev = NULL;
16201620
struct dsa_switch *ds = dp->ds;
16211621

@@ -1638,7 +1638,7 @@ static void dsa_port_phylink_mac_link_up(struct phylink_config *config,
16381638
int speed, int duplex,
16391639
bool tx_pause, bool rx_pause)
16401640
{
1641-
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
1641+
struct dsa_port *dp = dsa_phylink_to_port(config);
16421642
struct dsa_switch *ds = dp->ds;
16431643

16441644
if (!ds->ops->phylink_mac_link_up) {
@@ -1662,6 +1662,7 @@ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
16621662

16631663
int dsa_port_phylink_create(struct dsa_port *dp)
16641664
{
1665+
const struct phylink_mac_ops *mac_ops;
16651666
struct dsa_switch *ds = dp->ds;
16661667
phy_interface_t mode;
16671668
struct phylink *pl;
@@ -1685,8 +1686,12 @@ int dsa_port_phylink_create(struct dsa_port *dp)
16851686
}
16861687
}
16871688

1688-
pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
1689-
mode, &dsa_port_phylink_mac_ops);
1689+
mac_ops = &dsa_port_phylink_mac_ops;
1690+
if (ds->phylink_mac_ops)
1691+
mac_ops = ds->phylink_mac_ops;
1692+
1693+
pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
1694+
mac_ops);
16901695
if (IS_ERR(pl)) {
16911696
pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
16921697
return PTR_ERR(pl);
@@ -1952,12 +1957,23 @@ static void dsa_shared_port_validate_of(struct dsa_port *dp,
19521957
dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
19531958
}
19541959

1960+
static void dsa_shared_port_link_down(struct dsa_port *dp)
1961+
{
1962+
struct dsa_switch *ds = dp->ds;
1963+
1964+
if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
1965+
ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
1966+
PHY_INTERFACE_MODE_NA);
1967+
else if (ds->ops->phylink_mac_link_down)
1968+
ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
1969+
PHY_INTERFACE_MODE_NA);
1970+
}
1971+
19551972
int dsa_shared_port_link_register_of(struct dsa_port *dp)
19561973
{
19571974
struct dsa_switch *ds = dp->ds;
19581975
bool missing_link_description;
19591976
bool missing_phy_mode;
1960-
int port = dp->index;
19611977

19621978
dsa_shared_port_validate_of(dp, &missing_phy_mode,
19631979
&missing_link_description);
@@ -1973,9 +1989,7 @@ int dsa_shared_port_link_register_of(struct dsa_port *dp)
19731989
"Skipping phylink registration for %s port %d\n",
19741990
dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
19751991
} else {
1976-
if (ds->ops->phylink_mac_link_down)
1977-
ds->ops->phylink_mac_link_down(ds, port,
1978-
MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
1992+
dsa_shared_port_link_down(dp);
19791993

19801994
return dsa_shared_port_phylink_register(dp);
19811995
}

0 commit comments

Comments
 (0)