1
2
3#include <linux/netdevice.h>
4#include <linux/phy/phy.h>
5
6#include "lan966x_main.h"
7
8
9#define MULTIPLIER_BIT BIT(8)
10static u32 lan966x_wm_enc(u32 value)
11{
12 value /= LAN966X_BUFFER_CELL_SZ;
13
14 if (value >= MULTIPLIER_BIT) {
15 value /= 16;
16 if (value >= MULTIPLIER_BIT)
17 value = (MULTIPLIER_BIT - 1);
18
19 value |= MULTIPLIER_BIT;
20 }
21
22 return value;
23}
24
25static void lan966x_port_link_down(struct lan966x_port *port)
26{
27 struct lan966x *lan966x = port->lan966x;
28 u32 val, delay = 0;
29
30
31 lan_rmw(AFI_PORT_CFG_FC_SKIP_TTI_INJ_SET(1) |
32 AFI_PORT_CFG_FRM_OUT_MAX_SET(0),
33 AFI_PORT_CFG_FC_SKIP_TTI_INJ |
34 AFI_PORT_CFG_FRM_OUT_MAX,
35 lan966x, AFI_PORT_CFG(port->chip_port));
36
37
38 while (true) {
39 val = lan_rd(lan966x, AFI_PORT_FRM_OUT(port->chip_port));
40 if (!AFI_PORT_FRM_OUT_FRM_OUT_CNT_GET(val))
41 break;
42
43 usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
44 delay++;
45 if (delay == 2000) {
46 pr_err("AFI timeout chip port %u", port->chip_port);
47 break;
48 }
49 }
50
51 delay = 0;
52
53
54 lan_rmw(DEV_CLOCK_CFG_PCS_RX_RST_SET(1),
55 DEV_CLOCK_CFG_PCS_RX_RST,
56 lan966x, DEV_CLOCK_CFG(port->chip_port));
57
58
59 lan_rmw(DEV_MAC_ENA_CFG_RX_ENA_SET(0),
60 DEV_MAC_ENA_CFG_RX_ENA,
61 lan966x, DEV_MAC_ENA_CFG(port->chip_port));
62
63
64 lan_rmw(QSYS_SW_PORT_MODE_PORT_ENA_SET(0),
65 QSYS_SW_PORT_MODE_PORT_ENA,
66 lan966x, QSYS_SW_PORT_MODE(port->chip_port));
67
68
69 lan_rmw(QSYS_PORT_MODE_DEQUEUE_DIS_SET(1),
70 QSYS_PORT_MODE_DEQUEUE_DIS,
71 lan966x, QSYS_PORT_MODE(port->chip_port));
72
73
74 lan_rmw(SYS_PAUSE_CFG_PAUSE_ENA_SET(0),
75 SYS_PAUSE_CFG_PAUSE_ENA,
76 lan966x, SYS_PAUSE_CFG(port->chip_port));
77
78
79 lan_rmw(QSYS_SW_PORT_MODE_TX_PFC_ENA_SET(0),
80 QSYS_SW_PORT_MODE_TX_PFC_ENA,
81 lan966x, QSYS_SW_PORT_MODE(port->chip_port));
82
83
84 usleep_range(8 * USEC_PER_MSEC, 9 * USEC_PER_MSEC);
85
86
87 lan_rmw(SYS_FRONT_PORT_MODE_HDX_MODE_SET(0),
88 SYS_FRONT_PORT_MODE_HDX_MODE,
89 lan966x, SYS_FRONT_PORT_MODE(port->chip_port));
90
91
92 lan_rmw(QSYS_SW_PORT_MODE_AGING_MODE_SET(3),
93 QSYS_SW_PORT_MODE_AGING_MODE,
94 lan966x, QSYS_SW_PORT_MODE(port->chip_port));
95
96
97 lan_rmw(QSYS_PORT_MODE_DEQUEUE_DIS_SET(0),
98 QSYS_PORT_MODE_DEQUEUE_DIS,
99 lan966x, QSYS_PORT_MODE(port->chip_port));
100
101
102 while (true) {
103 val = lan_rd(lan966x, QSYS_SW_STATUS(port->chip_port));
104 if (!QSYS_SW_STATUS_EQ_AVAIL_GET(val))
105 break;
106
107 usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
108 delay++;
109 if (delay == 2000) {
110 pr_err("Flush timeout chip port %u", port->chip_port);
111 break;
112 }
113 }
114
115
116 lan_rmw(DEV_MAC_ENA_CFG_TX_ENA_SET(0),
117 DEV_MAC_ENA_CFG_TX_ENA,
118 lan966x, DEV_MAC_ENA_CFG(port->chip_port));
119
120 lan_rmw(DEV_CLOCK_CFG_PORT_RST_SET(1),
121 DEV_CLOCK_CFG_PORT_RST,
122 lan966x, DEV_CLOCK_CFG(port->chip_port));
123
124 usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
125
126 lan_rmw(DEV_CLOCK_CFG_MAC_TX_RST_SET(1) |
127 DEV_CLOCK_CFG_MAC_RX_RST_SET(1) |
128 DEV_CLOCK_CFG_PORT_RST_SET(1),
129 DEV_CLOCK_CFG_MAC_TX_RST |
130 DEV_CLOCK_CFG_MAC_RX_RST |
131 DEV_CLOCK_CFG_PORT_RST,
132 lan966x, DEV_CLOCK_CFG(port->chip_port));
133
134
135 lan_rmw(QSYS_SW_PORT_MODE_AGING_MODE_SET(2),
136 QSYS_SW_PORT_MODE_AGING_MODE,
137 lan966x, QSYS_SW_PORT_MODE(port->chip_port));
138
139
140
141
142}
143
144static void lan966x_port_link_up(struct lan966x_port *port)
145{
146 struct lan966x_port_config *config = &port->config;
147 struct lan966x *lan966x = port->lan966x;
148 int speed = 0, mode = 0;
149 int atop_wm = 0;
150
151 switch (config->speed) {
152 case SPEED_10:
153 speed = LAN966X_SPEED_10;
154 break;
155 case SPEED_100:
156 speed = LAN966X_SPEED_100;
157 break;
158 case SPEED_1000:
159 speed = LAN966X_SPEED_1000;
160 mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
161 break;
162 case SPEED_2500:
163 speed = LAN966X_SPEED_2500;
164 mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
165 break;
166 }
167
168
169
170
171 if (config->portmode == PHY_INTERFACE_MODE_QSGMII)
172 mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
173
174 lan_wr(config->duplex | mode,
175 lan966x, DEV_MAC_MODE_CFG(port->chip_port));
176
177 lan_rmw(DEV_MAC_IFG_CFG_TX_IFG_SET(config->duplex ? 6 : 5) |
178 DEV_MAC_IFG_CFG_RX_IFG1_SET(config->speed == SPEED_10 ? 2 : 1) |
179 DEV_MAC_IFG_CFG_RX_IFG2_SET(2),
180 DEV_MAC_IFG_CFG_TX_IFG |
181 DEV_MAC_IFG_CFG_RX_IFG1 |
182 DEV_MAC_IFG_CFG_RX_IFG2,
183 lan966x, DEV_MAC_IFG_CFG(port->chip_port));
184
185 lan_rmw(DEV_MAC_HDX_CFG_SEED_SET(4) |
186 DEV_MAC_HDX_CFG_SEED_LOAD_SET(1),
187 DEV_MAC_HDX_CFG_SEED |
188 DEV_MAC_HDX_CFG_SEED_LOAD,
189 lan966x, DEV_MAC_HDX_CFG(port->chip_port));
190
191 if (config->portmode == PHY_INTERFACE_MODE_GMII) {
192 if (config->speed == SPEED_1000)
193 lan_rmw(CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA_SET(1),
194 CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA,
195 lan966x,
196 CHIP_TOP_CUPHY_PORT_CFG(port->chip_port));
197 else
198 lan_rmw(CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA_SET(0),
199 CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA,
200 lan966x,
201 CHIP_TOP_CUPHY_PORT_CFG(port->chip_port));
202 }
203
204
205 lan_wr(ANA_PFC_CFG_FC_LINK_SPEED_SET(speed),
206 lan966x, ANA_PFC_CFG(port->chip_port));
207
208 lan_rmw(DEV_PCS1G_CFG_PCS_ENA_SET(1),
209 DEV_PCS1G_CFG_PCS_ENA,
210 lan966x, DEV_PCS1G_CFG(port->chip_port));
211
212 lan_rmw(DEV_PCS1G_SD_CFG_SD_ENA_SET(0),
213 DEV_PCS1G_SD_CFG_SD_ENA,
214 lan966x, DEV_PCS1G_SD_CFG(port->chip_port));
215
216
217 lan_wr(SYS_PAUSE_CFG_PAUSE_ENA_SET(1) |
218 SYS_PAUSE_CFG_PAUSE_STOP_SET(lan966x_wm_enc(4 * 1518)) |
219 SYS_PAUSE_CFG_PAUSE_START_SET(lan966x_wm_enc(6 * 1518)),
220 lan966x, SYS_PAUSE_CFG(port->chip_port));
221
222
223 lan_wr(0, lan966x, DEV_FC_MAC_LOW_CFG(port->chip_port));
224 lan_wr(0, lan966x, DEV_FC_MAC_HIGH_CFG(port->chip_port));
225
226
227 lan_rmw(SYS_MAC_FC_CFG_FC_LINK_SPEED_SET(speed) |
228 SYS_MAC_FC_CFG_FC_LATENCY_CFG_SET(7) |
229 SYS_MAC_FC_CFG_ZERO_PAUSE_ENA_SET(1) |
230 SYS_MAC_FC_CFG_PAUSE_VAL_CFG_SET(0xffff) |
231 SYS_MAC_FC_CFG_RX_FC_ENA_SET(config->pause & MLO_PAUSE_RX ? 1 : 0) |
232 SYS_MAC_FC_CFG_TX_FC_ENA_SET(config->pause & MLO_PAUSE_TX ? 1 : 0),
233 SYS_MAC_FC_CFG_FC_LINK_SPEED |
234 SYS_MAC_FC_CFG_FC_LATENCY_CFG |
235 SYS_MAC_FC_CFG_ZERO_PAUSE_ENA |
236 SYS_MAC_FC_CFG_PAUSE_VAL_CFG |
237 SYS_MAC_FC_CFG_RX_FC_ENA |
238 SYS_MAC_FC_CFG_TX_FC_ENA,
239 lan966x, SYS_MAC_FC_CFG(port->chip_port));
240
241
242 atop_wm = lan966x->shared_queue_sz;
243
244
245
246
247 lan_wr(lan966x_wm_enc(atop_wm / lan966x->num_phys_ports + 1), lan966x,
248 SYS_ATOP(port->chip_port));
249 lan_wr(lan966x_wm_enc(atop_wm), lan966x, SYS_ATOP_TOT_CFG);
250
251
252
253 lan_wr(DEV_MAC_ENA_CFG_RX_ENA_SET(1) |
254 DEV_MAC_ENA_CFG_TX_ENA_SET(1),
255 lan966x, DEV_MAC_ENA_CFG(port->chip_port));
256
257
258 lan_wr(DEV_CLOCK_CFG_LINK_SPEED_SET(speed),
259 lan966x, DEV_CLOCK_CFG(port->chip_port));
260
261
262 lan_wr(QSYS_SW_PORT_MODE_PORT_ENA_SET(1) |
263 QSYS_SW_PORT_MODE_SCH_NEXT_CFG_SET(1) |
264 QSYS_SW_PORT_MODE_INGRESS_DROP_MODE_SET(1),
265 lan966x, QSYS_SW_PORT_MODE(port->chip_port));
266
267 lan_rmw(AFI_PORT_CFG_FC_SKIP_TTI_INJ_SET(0) |
268 AFI_PORT_CFG_FRM_OUT_MAX_SET(16),
269 AFI_PORT_CFG_FC_SKIP_TTI_INJ |
270 AFI_PORT_CFG_FRM_OUT_MAX,
271 lan966x, AFI_PORT_CFG(port->chip_port));
272}
273
274void lan966x_port_config_down(struct lan966x_port *port)
275{
276 lan966x_port_link_down(port);
277}
278
279void lan966x_port_config_up(struct lan966x_port *port)
280{
281 lan966x_port_link_up(port);
282}
283
284void lan966x_port_status_get(struct lan966x_port *port,
285 struct phylink_link_state *state)
286{
287 struct lan966x *lan966x = port->lan966x;
288 bool link_down;
289 u16 bmsr = 0;
290 u16 lp_adv;
291 u32 val;
292
293 val = lan_rd(lan966x, DEV_PCS1G_STICKY(port->chip_port));
294 link_down = DEV_PCS1G_STICKY_LINK_DOWN_STICKY_GET(val);
295 if (link_down)
296 lan_wr(val, lan966x, DEV_PCS1G_STICKY(port->chip_port));
297
298
299 val = lan_rd(lan966x, DEV_PCS1G_LINK_STATUS(port->chip_port));
300 state->link = DEV_PCS1G_LINK_STATUS_LINK_STATUS_GET(val) &&
301 DEV_PCS1G_LINK_STATUS_SYNC_STATUS_GET(val);
302 state->link &= !link_down;
303
304
305 val = lan_rd(lan966x, DEV_PCS1G_ANEG_STATUS(port->chip_port));
306
307 if (DEV_PCS1G_ANEG_STATUS_ANEG_COMPLETE_GET(val)) {
308 state->an_complete = true;
309
310 bmsr |= state->link ? BMSR_LSTATUS : 0;
311 bmsr |= BMSR_ANEGCOMPLETE;
312
313 lp_adv = DEV_PCS1G_ANEG_STATUS_LP_ADV_GET(val);
314 phylink_mii_c22_pcs_decode_state(state, bmsr, lp_adv);
315 } else {
316 if (!state->link)
317 return;
318
319 if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
320 state->speed = SPEED_1000;
321 else if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
322 state->speed = SPEED_2500;
323
324 state->duplex = DUPLEX_FULL;
325 }
326}
327
328int lan966x_port_pcs_set(struct lan966x_port *port,
329 struct lan966x_port_config *config)
330{
331 struct lan966x *lan966x = port->lan966x;
332 bool inband_aneg = false;
333 bool outband;
334
335 if (config->inband) {
336 if (config->portmode == PHY_INTERFACE_MODE_SGMII ||
337 config->portmode == PHY_INTERFACE_MODE_QSGMII)
338 inband_aneg = true;
339 else if (config->portmode == PHY_INTERFACE_MODE_1000BASEX &&
340 config->autoneg)
341 inband_aneg = true;
342
343 outband = false;
344 } else {
345 outband = true;
346 }
347
348
349 lan_rmw(DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(outband),
350 DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA,
351 lan966x, DEV_PCS1G_MODE_CFG(port->chip_port));
352
353
354 lan_wr(DEV_PCS1G_CFG_PCS_ENA_SET(1),
355 lan966x, DEV_PCS1G_CFG(port->chip_port));
356
357 if (inband_aneg) {
358 int adv = phylink_mii_c22_pcs_encode_advertisement(config->portmode,
359 config->advertising);
360 if (adv >= 0)
361
362 lan_wr(DEV_PCS1G_ANEG_CFG_ADV_ABILITY_SET(adv) |
363 DEV_PCS1G_ANEG_CFG_SW_RESOLVE_ENA_SET(1) |
364 DEV_PCS1G_ANEG_CFG_ENA_SET(1) |
365 DEV_PCS1G_ANEG_CFG_RESTART_ONE_SHOT_SET(1),
366 lan966x, DEV_PCS1G_ANEG_CFG(port->chip_port));
367 } else {
368 lan_wr(0, lan966x, DEV_PCS1G_ANEG_CFG(port->chip_port));
369 }
370
371
372 lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(2) |
373 DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
374 DEV_CLOCK_CFG_PCS_TX_RST_SET(0),
375 DEV_CLOCK_CFG_LINK_SPEED |
376 DEV_CLOCK_CFG_PCS_RX_RST |
377 DEV_CLOCK_CFG_PCS_TX_RST,
378 lan966x, DEV_CLOCK_CFG(port->chip_port));
379
380 port->config = *config;
381
382 return 0;
383}
384
385void lan966x_port_init(struct lan966x_port *port)
386{
387 struct lan966x_port_config *config = &port->config;
388 struct lan966x *lan966x = port->lan966x;
389
390 lan_rmw(ANA_PORT_CFG_LEARN_ENA_SET(0),
391 ANA_PORT_CFG_LEARN_ENA,
392 lan966x, ANA_PORT_CFG(port->chip_port));
393
394 lan966x_port_config_down(port);
395
396 if (config->portmode != PHY_INTERFACE_MODE_QSGMII)
397 return;
398
399 lan_rmw(DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
400 DEV_CLOCK_CFG_PCS_TX_RST_SET(0) |
401 DEV_CLOCK_CFG_LINK_SPEED_SET(LAN966X_SPEED_1000),
402 DEV_CLOCK_CFG_PCS_RX_RST |
403 DEV_CLOCK_CFG_PCS_TX_RST |
404 DEV_CLOCK_CFG_LINK_SPEED,
405 lan966x, DEV_CLOCK_CFG(port->chip_port));
406}
407