1 /*
2 * Marvell 88E6xxx Switch Port Registers support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
7 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15 #include <linux/bitfield.h>
16 #include <linux/if_bridge.h>
17 #include <linux/phy.h>
18 #include <linux/phylink.h>
19
20 #include "chip.h"
21 #include "port.h"
22 #include "serdes.h"
23
mv88e6xxx_port_read(struct mv88e6xxx_chip * chip,int port,int reg,u16 * val)24 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
25 u16 *val)
26 {
27 int addr = chip->info->port_base_addr + port;
28
29 return mv88e6xxx_read(chip, addr, reg, val);
30 }
31
mv88e6xxx_port_write(struct mv88e6xxx_chip * chip,int port,int reg,u16 val)32 int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
33 u16 val)
34 {
35 int addr = chip->info->port_base_addr + port;
36
37 return mv88e6xxx_write(chip, addr, reg, val);
38 }
39
40 /* Offset 0x00: MAC (or PCS or Physical) Status Register
41 *
42 * For most devices, this is read only. However the 6185 has the MyPause
43 * bit read/write.
44 */
mv88e6185_port_set_pause(struct mv88e6xxx_chip * chip,int port,int pause)45 int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
46 int pause)
47 {
48 u16 reg;
49 int err;
50
51 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
52 if (err)
53 return err;
54
55 if (pause)
56 reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
57 else
58 reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
59
60 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
61 }
62
63 /* Offset 0x01: MAC (or PCS or Physical) Control Register
64 *
65 * Link, Duplex and Flow Control have one force bit, one value bit.
66 *
67 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
68 * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
69 * Newer chips need a ForcedSpd bit 13 set to consider the value.
70 */
71
mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip * chip,int port,phy_interface_t mode)72 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
73 phy_interface_t mode)
74 {
75 u16 reg;
76 int err;
77
78 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
79 if (err)
80 return err;
81
82 reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
83 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
84
85 switch (mode) {
86 case PHY_INTERFACE_MODE_RGMII_RXID:
87 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
88 break;
89 case PHY_INTERFACE_MODE_RGMII_TXID:
90 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
91 break;
92 case PHY_INTERFACE_MODE_RGMII_ID:
93 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
94 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
95 break;
96 case PHY_INTERFACE_MODE_RGMII:
97 break;
98 default:
99 return 0;
100 }
101
102 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
103 if (err)
104 return err;
105
106 dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
107 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
108 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
109
110 return 0;
111 }
112
mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip * chip,int port,phy_interface_t mode)113 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
114 phy_interface_t mode)
115 {
116 if (port < 5)
117 return -EOPNOTSUPP;
118
119 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
120 }
121
mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip * chip,int port,phy_interface_t mode)122 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
123 phy_interface_t mode)
124 {
125 if (port != 0)
126 return -EOPNOTSUPP;
127
128 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
129 }
130
mv88e6xxx_port_set_link(struct mv88e6xxx_chip * chip,int port,int link)131 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
132 {
133 u16 reg;
134 int err;
135
136 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
137 if (err)
138 return err;
139
140 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
141 MV88E6XXX_PORT_MAC_CTL_LINK_UP);
142
143 switch (link) {
144 case LINK_FORCED_DOWN:
145 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
146 break;
147 case LINK_FORCED_UP:
148 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
149 MV88E6XXX_PORT_MAC_CTL_LINK_UP;
150 break;
151 case LINK_UNFORCED:
152 /* normal link detection */
153 break;
154 default:
155 return -EINVAL;
156 }
157
158 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
159 if (err)
160 return err;
161
162 dev_dbg(chip->dev, "p%d: %s link %s\n", port,
163 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
164 reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
165
166 return 0;
167 }
168
mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip * chip,int port,int dup)169 int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup)
170 {
171 u16 reg;
172 int err;
173
174 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
175 if (err)
176 return err;
177
178 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
179 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
180
181 switch (dup) {
182 case DUPLEX_HALF:
183 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
184 break;
185 case DUPLEX_FULL:
186 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
187 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
188 break;
189 case DUPLEX_UNFORCED:
190 /* normal duplex detection */
191 break;
192 default:
193 return -EINVAL;
194 }
195
196 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
197 if (err)
198 return err;
199
200 dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
201 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
202 reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
203
204 return 0;
205 }
206
mv88e6xxx_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed,bool alt_bit,bool force_bit)207 static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
208 int speed, bool alt_bit, bool force_bit)
209 {
210 u16 reg, ctrl;
211 int err;
212
213 switch (speed) {
214 case 10:
215 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
216 break;
217 case 100:
218 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
219 break;
220 case 200:
221 if (alt_bit)
222 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
223 MV88E6390_PORT_MAC_CTL_ALTSPEED;
224 else
225 ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
226 break;
227 case 1000:
228 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
229 break;
230 case 2500:
231 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
232 MV88E6390_PORT_MAC_CTL_ALTSPEED;
233 break;
234 case 10000:
235 /* all bits set, fall through... */
236 case SPEED_UNFORCED:
237 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
238 break;
239 default:
240 return -EOPNOTSUPP;
241 }
242
243 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
244 if (err)
245 return err;
246
247 reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK;
248 if (alt_bit)
249 reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
250 if (force_bit) {
251 reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
252 if (speed != SPEED_UNFORCED)
253 ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
254 }
255 reg |= ctrl;
256
257 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
258 if (err)
259 return err;
260
261 if (speed)
262 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
263 else
264 dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
265
266 return 0;
267 }
268
269 /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
mv88e6065_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)270 int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
271 {
272 if (speed == SPEED_MAX)
273 speed = 200;
274
275 if (speed > 200)
276 return -EOPNOTSUPP;
277
278 /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
279 return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
280 }
281
282 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
mv88e6185_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)283 int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
284 {
285 if (speed == SPEED_MAX)
286 speed = 1000;
287
288 if (speed == 200 || speed > 1000)
289 return -EOPNOTSUPP;
290
291 return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
292 }
293
294 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
mv88e6352_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)295 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
296 {
297 if (speed == SPEED_MAX)
298 speed = 1000;
299
300 if (speed > 1000)
301 return -EOPNOTSUPP;
302
303 if (speed == 200 && port < 5)
304 return -EOPNOTSUPP;
305
306 return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
307 }
308
309 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
mv88e6390_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)310 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
311 {
312 if (speed == SPEED_MAX)
313 speed = port < 9 ? 1000 : 2500;
314
315 if (speed > 2500)
316 return -EOPNOTSUPP;
317
318 if (speed == 200 && port != 0)
319 return -EOPNOTSUPP;
320
321 if (speed == 2500 && port < 9)
322 return -EOPNOTSUPP;
323
324 return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
325 }
326
327 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
mv88e6390x_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)328 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
329 {
330 if (speed == SPEED_MAX)
331 speed = port < 9 ? 1000 : 10000;
332
333 if (speed == 200 && port != 0)
334 return -EOPNOTSUPP;
335
336 if (speed >= 2500 && port < 9)
337 return -EOPNOTSUPP;
338
339 return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
340 }
341
mv88e6390x_port_set_cmode(struct mv88e6xxx_chip * chip,int port,phy_interface_t mode)342 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
343 phy_interface_t mode)
344 {
345 int lane;
346 u16 cmode;
347 u16 reg;
348 int err;
349
350 if (mode == PHY_INTERFACE_MODE_NA)
351 return 0;
352
353 if (port != 9 && port != 10)
354 return -EOPNOTSUPP;
355
356 switch (mode) {
357 case PHY_INTERFACE_MODE_1000BASEX:
358 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X;
359 break;
360 case PHY_INTERFACE_MODE_SGMII:
361 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
362 break;
363 case PHY_INTERFACE_MODE_2500BASEX:
364 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
365 break;
366 case PHY_INTERFACE_MODE_XGMII:
367 case PHY_INTERFACE_MODE_XAUI:
368 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
369 break;
370 case PHY_INTERFACE_MODE_RXAUI:
371 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
372 break;
373 default:
374 cmode = 0;
375 }
376
377 lane = mv88e6390x_serdes_get_lane(chip, port);
378 if (lane < 0)
379 return lane;
380
381 if (chip->ports[port].serdes_irq) {
382 err = mv88e6390_serdes_irq_disable(chip, port, lane);
383 if (err)
384 return err;
385 }
386
387 err = mv88e6390_serdes_power(chip, port, false);
388 if (err)
389 return err;
390
391 if (cmode) {
392 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
393 if (err)
394 return err;
395
396 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
397 reg |= cmode;
398
399 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
400 if (err)
401 return err;
402
403 err = mv88e6390_serdes_power(chip, port, true);
404 if (err)
405 return err;
406
407 if (chip->ports[port].serdes_irq) {
408 err = mv88e6390_serdes_irq_enable(chip, port, lane);
409 if (err)
410 return err;
411 }
412 }
413
414 chip->ports[port].cmode = cmode;
415
416 return 0;
417 }
418
mv88e6185_port_get_cmode(struct mv88e6xxx_chip * chip,int port,u8 * cmode)419 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
420 {
421 int err;
422 u16 reg;
423
424 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
425 if (err)
426 return err;
427
428 *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
429
430 return 0;
431 }
432
mv88e6352_port_get_cmode(struct mv88e6xxx_chip * chip,int port,u8 * cmode)433 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
434 {
435 int err;
436 u16 reg;
437
438 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
439 if (err)
440 return err;
441
442 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
443
444 return 0;
445 }
446
mv88e6352_port_link_state(struct mv88e6xxx_chip * chip,int port,struct phylink_link_state * state)447 int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
448 struct phylink_link_state *state)
449 {
450 int err;
451 u16 reg;
452
453 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
454 if (err)
455 return err;
456
457 switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
458 case MV88E6XXX_PORT_STS_SPEED_10:
459 state->speed = SPEED_10;
460 break;
461 case MV88E6XXX_PORT_STS_SPEED_100:
462 state->speed = SPEED_100;
463 break;
464 case MV88E6XXX_PORT_STS_SPEED_1000:
465 state->speed = SPEED_1000;
466 break;
467 case MV88E6XXX_PORT_STS_SPEED_10000:
468 if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
469 MV88E6XXX_PORT_STS_CMODE_2500BASEX)
470 state->speed = SPEED_2500;
471 else
472 state->speed = SPEED_10000;
473 break;
474 }
475
476 state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
477 DUPLEX_FULL : DUPLEX_HALF;
478 state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
479 state->an_enabled = 1;
480 state->an_complete = state->link;
481
482 return 0;
483 }
484
mv88e6185_port_link_state(struct mv88e6xxx_chip * chip,int port,struct phylink_link_state * state)485 int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
486 struct phylink_link_state *state)
487 {
488 if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
489 u8 cmode = chip->ports[port].cmode;
490
491 /* When a port is in "Cross-chip serdes" mode, it uses
492 * 1000Base-X full duplex mode, but there is no automatic
493 * link detection. Use the sync OK status for link (as it
494 * would do for 1000Base-X mode.)
495 */
496 if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
497 u16 mac;
498 int err;
499
500 err = mv88e6xxx_port_read(chip, port,
501 MV88E6XXX_PORT_MAC_CTL, &mac);
502 if (err)
503 return err;
504
505 state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
506 state->an_enabled = 1;
507 state->an_complete =
508 !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
509 state->duplex =
510 state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
511 state->speed =
512 state->link ? SPEED_1000 : SPEED_UNKNOWN;
513
514 return 0;
515 }
516 }
517
518 return mv88e6352_port_link_state(chip, port, state);
519 }
520
521 /* Offset 0x02: Jamming Control
522 *
523 * Do not limit the period of time that this port can be paused for by
524 * the remote end or the period of time that this port can pause the
525 * remote end.
526 */
mv88e6097_port_pause_limit(struct mv88e6xxx_chip * chip,int port,u8 in,u8 out)527 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
528 u8 out)
529 {
530 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
531 out << 8 | in);
532 }
533
mv88e6390_port_pause_limit(struct mv88e6xxx_chip * chip,int port,u8 in,u8 out)534 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
535 u8 out)
536 {
537 int err;
538
539 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
540 MV88E6390_PORT_FLOW_CTL_UPDATE |
541 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
542 if (err)
543 return err;
544
545 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
546 MV88E6390_PORT_FLOW_CTL_UPDATE |
547 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
548 }
549
550 /* Offset 0x04: Port Control Register */
551
552 static const char * const mv88e6xxx_port_state_names[] = {
553 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
554 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
555 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
556 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
557 };
558
mv88e6xxx_port_set_state(struct mv88e6xxx_chip * chip,int port,u8 state)559 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
560 {
561 u16 reg;
562 int err;
563
564 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
565 if (err)
566 return err;
567
568 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
569
570 switch (state) {
571 case BR_STATE_DISABLED:
572 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
573 break;
574 case BR_STATE_BLOCKING:
575 case BR_STATE_LISTENING:
576 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
577 break;
578 case BR_STATE_LEARNING:
579 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
580 break;
581 case BR_STATE_FORWARDING:
582 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
583 break;
584 default:
585 return -EINVAL;
586 }
587
588 reg |= state;
589
590 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
591 if (err)
592 return err;
593
594 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
595 mv88e6xxx_port_state_names[state]);
596
597 return 0;
598 }
599
mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip * chip,int port,enum mv88e6xxx_egress_mode mode)600 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
601 enum mv88e6xxx_egress_mode mode)
602 {
603 int err;
604 u16 reg;
605
606 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
607 if (err)
608 return err;
609
610 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
611
612 switch (mode) {
613 case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
614 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
615 break;
616 case MV88E6XXX_EGRESS_MODE_UNTAGGED:
617 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
618 break;
619 case MV88E6XXX_EGRESS_MODE_TAGGED:
620 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
621 break;
622 case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
623 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
624 break;
625 default:
626 return -EINVAL;
627 }
628
629 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
630 }
631
mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip * chip,int port,enum mv88e6xxx_frame_mode mode)632 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
633 enum mv88e6xxx_frame_mode mode)
634 {
635 int err;
636 u16 reg;
637
638 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
639 if (err)
640 return err;
641
642 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
643
644 switch (mode) {
645 case MV88E6XXX_FRAME_MODE_NORMAL:
646 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
647 break;
648 case MV88E6XXX_FRAME_MODE_DSA:
649 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
650 break;
651 default:
652 return -EINVAL;
653 }
654
655 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
656 }
657
mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip * chip,int port,enum mv88e6xxx_frame_mode mode)658 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
659 enum mv88e6xxx_frame_mode mode)
660 {
661 int err;
662 u16 reg;
663
664 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
665 if (err)
666 return err;
667
668 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
669
670 switch (mode) {
671 case MV88E6XXX_FRAME_MODE_NORMAL:
672 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
673 break;
674 case MV88E6XXX_FRAME_MODE_DSA:
675 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
676 break;
677 case MV88E6XXX_FRAME_MODE_PROVIDER:
678 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
679 break;
680 case MV88E6XXX_FRAME_MODE_ETHERTYPE:
681 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
682 break;
683 default:
684 return -EINVAL;
685 }
686
687 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
688 }
689
mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip * chip,int port,bool unicast)690 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
691 int port, bool unicast)
692 {
693 int err;
694 u16 reg;
695
696 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
697 if (err)
698 return err;
699
700 if (unicast)
701 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
702 else
703 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
704
705 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
706 }
707
mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip * chip,int port,bool unicast,bool multicast)708 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
709 bool unicast, bool multicast)
710 {
711 int err;
712 u16 reg;
713
714 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
715 if (err)
716 return err;
717
718 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
719
720 if (unicast && multicast)
721 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
722 else if (unicast)
723 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
724 else if (multicast)
725 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
726 else
727 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
728
729 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
730 }
731
732 /* Offset 0x05: Port Control 1 */
733
mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip * chip,int port,bool message_port)734 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
735 bool message_port)
736 {
737 u16 val;
738 int err;
739
740 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
741 if (err)
742 return err;
743
744 if (message_port)
745 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
746 else
747 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
748
749 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
750 }
751
752 /* Offset 0x06: Port Based VLAN Map */
753
mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip * chip,int port,u16 map)754 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
755 {
756 const u16 mask = mv88e6xxx_port_mask(chip);
757 u16 reg;
758 int err;
759
760 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
761 if (err)
762 return err;
763
764 reg &= ~mask;
765 reg |= map & mask;
766
767 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
768 if (err)
769 return err;
770
771 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
772
773 return 0;
774 }
775
mv88e6xxx_port_get_fid(struct mv88e6xxx_chip * chip,int port,u16 * fid)776 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
777 {
778 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
779 u16 reg;
780 int err;
781
782 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
783 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
784 if (err)
785 return err;
786
787 *fid = (reg & 0xf000) >> 12;
788
789 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
790 if (upper_mask) {
791 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
792 ®);
793 if (err)
794 return err;
795
796 *fid |= (reg & upper_mask) << 4;
797 }
798
799 return 0;
800 }
801
mv88e6xxx_port_set_fid(struct mv88e6xxx_chip * chip,int port,u16 fid)802 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
803 {
804 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
805 u16 reg;
806 int err;
807
808 if (fid >= mv88e6xxx_num_databases(chip))
809 return -EINVAL;
810
811 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
812 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
813 if (err)
814 return err;
815
816 reg &= 0x0fff;
817 reg |= (fid & 0x000f) << 12;
818
819 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
820 if (err)
821 return err;
822
823 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
824 if (upper_mask) {
825 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
826 ®);
827 if (err)
828 return err;
829
830 reg &= ~upper_mask;
831 reg |= (fid >> 4) & upper_mask;
832
833 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
834 reg);
835 if (err)
836 return err;
837 }
838
839 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
840
841 return 0;
842 }
843
844 /* Offset 0x07: Default Port VLAN ID & Priority */
845
mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip * chip,int port,u16 * pvid)846 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
847 {
848 u16 reg;
849 int err;
850
851 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
852 ®);
853 if (err)
854 return err;
855
856 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
857
858 return 0;
859 }
860
mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip * chip,int port,u16 pvid)861 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
862 {
863 u16 reg;
864 int err;
865
866 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
867 ®);
868 if (err)
869 return err;
870
871 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
872 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
873
874 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
875 reg);
876 if (err)
877 return err;
878
879 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
880
881 return 0;
882 }
883
884 /* Offset 0x08: Port Control 2 Register */
885
886 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
887 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
888 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
889 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
890 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
891 };
892
mv88e6185_port_set_default_forward(struct mv88e6xxx_chip * chip,int port,bool multicast)893 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
894 int port, bool multicast)
895 {
896 int err;
897 u16 reg;
898
899 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
900 if (err)
901 return err;
902
903 if (multicast)
904 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
905 else
906 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
907
908 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
909 }
910
mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip * chip,int port,bool unicast,bool multicast)911 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
912 bool unicast, bool multicast)
913 {
914 int err;
915
916 err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
917 if (err)
918 return err;
919
920 return mv88e6185_port_set_default_forward(chip, port, multicast);
921 }
922
mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip * chip,int port,int upstream_port)923 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
924 int upstream_port)
925 {
926 int err;
927 u16 reg;
928
929 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
930 if (err)
931 return err;
932
933 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
934 reg |= upstream_port;
935
936 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
937 }
938
mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip * chip,int port,u16 mode)939 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
940 u16 mode)
941 {
942 u16 reg;
943 int err;
944
945 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
946 if (err)
947 return err;
948
949 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
950 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
951
952 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
953 if (err)
954 return err;
955
956 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
957 mv88e6xxx_port_8021q_mode_names[mode]);
958
959 return 0;
960 }
961
mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip * chip,int port)962 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
963 {
964 u16 reg;
965 int err;
966
967 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
968 if (err)
969 return err;
970
971 reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
972
973 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
974 }
975
mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip * chip,int port,size_t size)976 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
977 size_t size)
978 {
979 u16 reg;
980 int err;
981
982 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
983 if (err)
984 return err;
985
986 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
987
988 if (size <= 1522)
989 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
990 else if (size <= 2048)
991 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
992 else if (size <= 10240)
993 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
994 else
995 return -ERANGE;
996
997 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
998 }
999
1000 /* Offset 0x09: Port Rate Control */
1001
mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip * chip,int port)1002 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1003 {
1004 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1005 0x0000);
1006 }
1007
mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip * chip,int port)1008 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1009 {
1010 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1011 0x0001);
1012 }
1013
1014 /* Offset 0x0C: Port ATU Control */
1015
mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip * chip,int port)1016 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
1017 {
1018 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
1019 }
1020
1021 /* Offset 0x0D: (Priority) Override Register */
1022
mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip * chip,int port)1023 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
1024 {
1025 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
1026 }
1027
1028 /* Offset 0x0f: Port Ether type */
1029
mv88e6351_port_set_ether_type(struct mv88e6xxx_chip * chip,int port,u16 etype)1030 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1031 u16 etype)
1032 {
1033 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
1034 }
1035
1036 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1037 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1038 */
1039
mv88e6095_port_tag_remap(struct mv88e6xxx_chip * chip,int port)1040 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1041 {
1042 int err;
1043
1044 /* Use a direct priority mapping for all IEEE tagged frames */
1045 err = mv88e6xxx_port_write(chip, port,
1046 MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
1047 0x3210);
1048 if (err)
1049 return err;
1050
1051 return mv88e6xxx_port_write(chip, port,
1052 MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
1053 0x7654);
1054 }
1055
mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip * chip,int port,u16 table,u8 ptr,u16 data)1056 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
1057 int port, u16 table, u8 ptr, u16 data)
1058 {
1059 u16 reg;
1060
1061 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
1062 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
1063 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
1064
1065 return mv88e6xxx_port_write(chip, port,
1066 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
1067 }
1068
mv88e6390_port_tag_remap(struct mv88e6xxx_chip * chip,int port)1069 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1070 {
1071 int err, i;
1072 u16 table;
1073
1074 for (i = 0; i <= 7; i++) {
1075 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
1076 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1077 (i | i << 4));
1078 if (err)
1079 return err;
1080
1081 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1082 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1083 if (err)
1084 return err;
1085
1086 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1087 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1088 if (err)
1089 return err;
1090
1091 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1092 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1093 if (err)
1094 return err;
1095 }
1096
1097 return 0;
1098 }
1099