d7ae1196dd0c70ddf7e67369d6bd39284f2921eb
[openwrt/staging/ldir.git] /
1 From 07f63e91f5e81f7f36c1e646f72c394c7f60c05c Mon Sep 17 00:00:00 2001
2 From: Vladimir Oltean <vladimir.oltean@nxp.com>
3 Date: Fri, 22 Nov 2019 13:46:34 +0200
4 Subject: [PATCH] net: mscc: ocelot: introduce more focused PCS ops for PHYLINK
5
6 The reason for doing this is that the 2 mainline Ocelot switches so far,
7 VSC7514 and VSC9959, have radically different SoC/SerDes integration. So
8 although the PHYLINK callbacks are common, the implementations will
9 actually lie in device-specific function pointers.
10
11 Also, there was a duplicated and unused function pointer for pcs_init in
12 struct ocelot, remove that.
13
14 Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
15 ---
16 drivers/net/ethernet/mscc/ocelot.c | 36 ++++++++------------------------
17 drivers/net/ethernet/mscc/ocelot_board.c | 35 ++++++++++++++++++++++++++++++-
18 include/soc/mscc/ocelot.h | 12 ++++++++---
19 3 files changed, 52 insertions(+), 31 deletions(-)
20
21 --- a/drivers/net/ethernet/mscc/ocelot.c
22 +++ b/drivers/net/ethernet/mscc/ocelot.c
23 @@ -410,43 +410,25 @@ void ocelot_phylink_validate(struct ocel
24 unsigned long *supported,
25 struct phylink_link_state *state)
26 {
27 - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
28 -
29 - if (state->interface != PHY_INTERFACE_MODE_NA &&
30 - state->interface != PHY_INTERFACE_MODE_GMII &&
31 - state->interface != PHY_INTERFACE_MODE_SGMII &&
32 - state->interface != PHY_INTERFACE_MODE_QSGMII) {
33 - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
34 - return;
35 - }
36 -
37 - /* No half-duplex. */
38 - phylink_set_port_modes(mask);
39 - phylink_set(mask, Autoneg);
40 - phylink_set(mask, Pause);
41 - phylink_set(mask, Asym_Pause);
42 - phylink_set(mask, 10baseT_Full);
43 - phylink_set(mask, 100baseT_Full);
44 - phylink_set(mask, 1000baseT_Full);
45 - phylink_set(mask, 2500baseT_Full);
46 -
47 - bitmap_and(supported, supported, mask,
48 - __ETHTOOL_LINK_MODE_MASK_NBITS);
49 - bitmap_and(state->advertising, state->advertising, mask,
50 - __ETHTOOL_LINK_MODE_MASK_NBITS);
51 + if (ocelot->ops->pcs_validate)
52 + ocelot->ops->pcs_validate(ocelot, port, supported, state);
53 }
54 EXPORT_SYMBOL(ocelot_phylink_validate);
55
56 void ocelot_phylink_mac_pcs_get_state(struct ocelot *ocelot, int port,
57 struct phylink_link_state *state)
58 {
59 - state->link = 1;
60 + if (ocelot->ops->pcs_link_state)
61 + ocelot->ops->pcs_link_state(ocelot, port, state);
62 + else
63 + state->link = 1;
64 }
65 EXPORT_SYMBOL(ocelot_phylink_mac_pcs_get_state);
66
67 void ocelot_phylink_mac_an_restart(struct ocelot *ocelot, int port)
68 {
69 - /* Not supported */
70 + if (ocelot->ops->pcs_an_restart)
71 + ocelot->ops->pcs_an_restart(ocelot, port);
72 }
73 EXPORT_SYMBOL(ocelot_phylink_mac_an_restart);
74
75 @@ -490,7 +472,7 @@ void ocelot_phylink_mac_config(struct oc
76 ocelot_port_writel(ocelot_port, mac_mode, DEV_MAC_MODE_CFG);
77
78 if (ocelot->ops->pcs_init)
79 - ocelot->ops->pcs_init(ocelot, port);
80 + ocelot->ops->pcs_init(ocelot, port, link_an_mode, state);
81
82 /* Enable MAC module */
83 ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA |
84 --- a/drivers/net/ethernet/mscc/ocelot_board.c
85 +++ b/drivers/net/ethernet/mscc/ocelot_board.c
86 @@ -212,7 +212,9 @@ static const struct of_device_id mscc_oc
87 };
88 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
89
90 -static void ocelot_port_pcs_init(struct ocelot *ocelot, int port)
91 +static void ocelot_port_pcs_init(struct ocelot *ocelot, int port,
92 + unsigned int link_an_mode,
93 + const struct phylink_link_state *state)
94 {
95 struct ocelot_port *ocelot_port = ocelot->ports[port];
96
97 @@ -235,6 +237,36 @@ static void ocelot_port_pcs_init(struct
98 ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG);
99 }
100
101 +void ocelot_port_pcs_validate(struct ocelot *ocelot, int port,
102 + unsigned long *supported,
103 + struct phylink_link_state *state)
104 +{
105 + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
106 +
107 + if (state->interface != PHY_INTERFACE_MODE_NA &&
108 + state->interface != PHY_INTERFACE_MODE_GMII &&
109 + state->interface != PHY_INTERFACE_MODE_SGMII &&
110 + state->interface != PHY_INTERFACE_MODE_QSGMII) {
111 + bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
112 + return;
113 + }
114 +
115 + /* No half-duplex. */
116 + phylink_set_port_modes(mask);
117 + phylink_set(mask, Autoneg);
118 + phylink_set(mask, Pause);
119 + phylink_set(mask, Asym_Pause);
120 + phylink_set(mask, 10baseT_Full);
121 + phylink_set(mask, 100baseT_Full);
122 + phylink_set(mask, 1000baseT_Full);
123 + phylink_set(mask, 2500baseT_Full);
124 +
125 + bitmap_and(supported, supported, mask,
126 + __ETHTOOL_LINK_MODE_MASK_NBITS);
127 + bitmap_and(state->advertising, state->advertising, mask,
128 + __ETHTOOL_LINK_MODE_MASK_NBITS);
129 +}
130 +
131 static int ocelot_reset(struct ocelot *ocelot)
132 {
133 int retries = 100;
134 @@ -260,6 +292,7 @@ static int ocelot_reset(struct ocelot *o
135
136 static const struct ocelot_ops ocelot_ops = {
137 .pcs_init = ocelot_port_pcs_init,
138 + .pcs_validate = ocelot_port_pcs_validate,
139 .reset = ocelot_reset,
140 };
141
142 --- a/include/soc/mscc/ocelot.h
143 +++ b/include/soc/mscc/ocelot.h
144 @@ -412,7 +412,15 @@ enum {
145 struct ocelot;
146
147 struct ocelot_ops {
148 - void (*pcs_init)(struct ocelot *ocelot, int port);
149 + void (*pcs_init)(struct ocelot *ocelot, int port,
150 + unsigned int link_an_mode,
151 + const struct phylink_link_state *state);
152 + void (*pcs_an_restart)(struct ocelot *ocelot, int port);
153 + void (*pcs_link_state)(struct ocelot *ocelot, int port,
154 + struct phylink_link_state *state);
155 + void (*pcs_validate)(struct ocelot *ocelot, int port,
156 + unsigned long *supported,
157 + struct phylink_link_state *state);
158 int (*reset)(struct ocelot *ocelot);
159 };
160
161 @@ -479,8 +487,6 @@ struct ocelot {
162 struct mutex ptp_lock;
163 /* Protects the PTP clock */
164 spinlock_t ptp_clock_lock;
165 -
166 - void (*port_pcs_init)(struct ocelot_port *port);
167 };
168
169 #define ocelot_read_ix(ocelot, reg, gi, ri) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))