]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - drivers/net/dsa/mv88e6xxx/port.c
net: dsa: mv88e6xxx: rework port mode setup
[mirror_ubuntu-eoan-kernel.git] / drivers / net / dsa / mv88e6xxx / port.c
CommitLineData
18abed21
VD
1/*
2 * Marvell 88E6xxx Switch Port Registers support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2016 Vivien Didelot <vivien.didelot@savoirfairelinux.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
f39908d3 14#include <linux/phy.h>
18abed21
VD
15#include "mv88e6xxx.h"
16#include "port.h"
17
18int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
19 u16 *val)
20{
21 int addr = chip->info->port_base_addr + port;
22
23 return mv88e6xxx_read(chip, addr, reg, val);
24}
25
26int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
27 u16 val)
28{
29 int addr = chip->info->port_base_addr + port;
30
31 return mv88e6xxx_write(chip, addr, reg, val);
32}
e28def33 33
08ef7f10
VD
34/* Offset 0x01: MAC (or PCS or Physical) Control Register
35 *
36 * Link, Duplex and Flow Control have one force bit, one value bit.
96a2b40c
VD
37 *
38 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
39 * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
40 * Newer chips need a ForcedSpd bit 13 set to consider the value.
08ef7f10
VD
41 */
42
a0a0f622
VD
43static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
44 phy_interface_t mode)
45{
46 u16 reg;
47 int err;
48
49 err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
50 if (err)
51 return err;
52
53 reg &= ~(PORT_PCS_CTRL_RGMII_DELAY_RXCLK |
54 PORT_PCS_CTRL_RGMII_DELAY_TXCLK);
55
56 switch (mode) {
57 case PHY_INTERFACE_MODE_RGMII_RXID:
58 reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK;
59 break;
60 case PHY_INTERFACE_MODE_RGMII_TXID:
61 reg |= PORT_PCS_CTRL_RGMII_DELAY_TXCLK;
62 break;
63 case PHY_INTERFACE_MODE_RGMII_ID:
64 reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK |
65 PORT_PCS_CTRL_RGMII_DELAY_TXCLK;
66 break;
fedf1865 67 case PHY_INTERFACE_MODE_RGMII:
a0a0f622 68 break;
fedf1865
AL
69 default:
70 return 0;
a0a0f622
VD
71 }
72
73 err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
74 if (err)
75 return err;
76
77 netdev_dbg(chip->ds->ports[port].netdev, "delay RXCLK %s, TXCLK %s\n",
78 reg & PORT_PCS_CTRL_RGMII_DELAY_RXCLK ? "yes" : "no",
79 reg & PORT_PCS_CTRL_RGMII_DELAY_TXCLK ? "yes" : "no");
80
81 return 0;
82}
83
84int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
85 phy_interface_t mode)
86{
87 if (port < 5)
88 return -EOPNOTSUPP;
89
90 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
91}
92
93int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
94 phy_interface_t mode)
95{
96 if (port != 0)
97 return -EOPNOTSUPP;
98
99 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
100}
101
08ef7f10
VD
102int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
103{
104 u16 reg;
105 int err;
106
107 err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
108 if (err)
109 return err;
110
111 reg &= ~(PORT_PCS_CTRL_FORCE_LINK | PORT_PCS_CTRL_LINK_UP);
112
113 switch (link) {
114 case LINK_FORCED_DOWN:
115 reg |= PORT_PCS_CTRL_FORCE_LINK;
116 break;
117 case LINK_FORCED_UP:
118 reg |= PORT_PCS_CTRL_FORCE_LINK | PORT_PCS_CTRL_LINK_UP;
119 break;
120 case LINK_UNFORCED:
121 /* normal link detection */
122 break;
123 default:
124 return -EINVAL;
125 }
126
127 err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
128 if (err)
129 return err;
130
131 netdev_dbg(chip->ds->ports[port].netdev, "%s link %s\n",
132 reg & PORT_PCS_CTRL_FORCE_LINK ? "Force" : "Unforce",
133 reg & PORT_PCS_CTRL_LINK_UP ? "up" : "down");
134
135 return 0;
136}
137
7f1ae07b
VD
138int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup)
139{
140 u16 reg;
141 int err;
142
143 err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
144 if (err)
145 return err;
146
147 reg &= ~(PORT_PCS_CTRL_FORCE_DUPLEX | PORT_PCS_CTRL_DUPLEX_FULL);
148
149 switch (dup) {
150 case DUPLEX_HALF:
151 reg |= PORT_PCS_CTRL_FORCE_DUPLEX;
152 break;
153 case DUPLEX_FULL:
154 reg |= PORT_PCS_CTRL_FORCE_DUPLEX | PORT_PCS_CTRL_DUPLEX_FULL;
155 break;
156 case DUPLEX_UNFORCED:
157 /* normal duplex detection */
158 break;
159 default:
160 return -EINVAL;
161 }
162
163 err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
164 if (err)
165 return err;
166
167 netdev_dbg(chip->ds->ports[port].netdev, "%s %s duplex\n",
168 reg & PORT_PCS_CTRL_FORCE_DUPLEX ? "Force" : "Unforce",
169 reg & PORT_PCS_CTRL_DUPLEX_FULL ? "full" : "half");
170
171 return 0;
172}
173
96a2b40c
VD
174static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
175 int speed, bool alt_bit, bool force_bit)
176{
177 u16 reg, ctrl;
178 int err;
179
180 switch (speed) {
181 case 10:
182 ctrl = PORT_PCS_CTRL_SPEED_10;
183 break;
184 case 100:
185 ctrl = PORT_PCS_CTRL_SPEED_100;
186 break;
187 case 200:
188 if (alt_bit)
189 ctrl = PORT_PCS_CTRL_SPEED_100 | PORT_PCS_CTRL_ALTSPEED;
190 else
191 ctrl = PORT_PCS_CTRL_SPEED_200;
192 break;
193 case 1000:
194 ctrl = PORT_PCS_CTRL_SPEED_1000;
195 break;
196 case 2500:
740117a8 197 ctrl = PORT_PCS_CTRL_SPEED_10000 | PORT_PCS_CTRL_ALTSPEED;
96a2b40c
VD
198 break;
199 case 10000:
200 /* all bits set, fall through... */
201 case SPEED_UNFORCED:
202 ctrl = PORT_PCS_CTRL_SPEED_UNFORCED;
203 break;
204 default:
205 return -EOPNOTSUPP;
206 }
207
208 err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
209 if (err)
210 return err;
211
212 reg &= ~PORT_PCS_CTRL_SPEED_MASK;
213 if (alt_bit)
214 reg &= ~PORT_PCS_CTRL_ALTSPEED;
215 if (force_bit) {
216 reg &= ~PORT_PCS_CTRL_FORCE_SPEED;
0b6e3d03 217 if (speed != SPEED_UNFORCED)
96a2b40c
VD
218 ctrl |= PORT_PCS_CTRL_FORCE_SPEED;
219 }
220 reg |= ctrl;
221
222 err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
223 if (err)
224 return err;
225
226 if (speed)
227 netdev_dbg(chip->ds->ports[port].netdev,
228 "Speed set to %d Mbps\n", speed);
229 else
230 netdev_dbg(chip->ds->ports[port].netdev, "Speed unforced\n");
231
232 return 0;
233}
234
235/* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
236int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
237{
238 if (speed == SPEED_MAX)
239 speed = 200;
240
241 if (speed > 200)
242 return -EOPNOTSUPP;
243
244 /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
245 return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
246}
247
248/* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
249int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
250{
251 if (speed == SPEED_MAX)
252 speed = 1000;
253
254 if (speed == 200 || speed > 1000)
255 return -EOPNOTSUPP;
256
257 return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
258}
259
260/* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
261int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
262{
263 if (speed == SPEED_MAX)
264 speed = 1000;
265
266 if (speed > 1000)
267 return -EOPNOTSUPP;
268
269 if (speed == 200 && port < 5)
270 return -EOPNOTSUPP;
271
272 return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
273}
274
275/* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
276int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
277{
278 if (speed == SPEED_MAX)
279 speed = port < 9 ? 1000 : 2500;
280
281 if (speed > 2500)
282 return -EOPNOTSUPP;
283
284 if (speed == 200 && port != 0)
285 return -EOPNOTSUPP;
286
287 if (speed == 2500 && port < 9)
288 return -EOPNOTSUPP;
289
290 return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
291}
292
293/* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
294int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
295{
296 if (speed == SPEED_MAX)
297 speed = port < 9 ? 1000 : 10000;
298
299 if (speed == 200 && port != 0)
300 return -EOPNOTSUPP;
301
302 if (speed >= 2500 && port < 9)
303 return -EOPNOTSUPP;
304
305 return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
306}
307
f39908d3
AL
308int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
309 phy_interface_t mode)
310{
311 u16 reg;
312 u16 cmode;
313 int err;
314
315 if (mode == PHY_INTERFACE_MODE_NA)
316 return 0;
317
318 if (port != 9 && port != 10)
319 return -EOPNOTSUPP;
320
321 switch (mode) {
322 case PHY_INTERFACE_MODE_1000BASEX:
323 cmode = PORT_STATUS_CMODE_1000BASE_X;
324 break;
325 case PHY_INTERFACE_MODE_SGMII:
326 cmode = PORT_STATUS_CMODE_SGMII;
327 break;
328 case PHY_INTERFACE_MODE_2500BASEX:
329 cmode = PORT_STATUS_CMODE_2500BASEX;
330 break;
331 case PHY_INTERFACE_MODE_XGMII:
332 cmode = PORT_STATUS_CMODE_XAUI;
333 break;
334 case PHY_INTERFACE_MODE_RXAUI:
335 cmode = PORT_STATUS_CMODE_RXAUI;
336 break;
337 default:
338 cmode = 0;
339 }
340
341 if (cmode) {
342 err = mv88e6xxx_port_read(chip, port, PORT_STATUS, &reg);
343 if (err)
344 return err;
345
346 reg &= ~PORT_STATUS_CMODE_MASK;
347 reg |= cmode;
348
349 err = mv88e6xxx_port_write(chip, port, PORT_STATUS, reg);
350 if (err)
351 return err;
352 }
353
354 return 0;
355}
356
357int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
358{
359 int err;
360 u16 reg;
361
362 err = mv88e6xxx_port_read(chip, port, PORT_STATUS, &reg);
363 if (err)
364 return err;
365
366 *cmode = reg & PORT_STATUS_CMODE_MASK;
367
368 return 0;
369}
370
b35d322a
AL
371/* Offset 0x02: Pause Control
372 *
373 * Do not limit the period of time that this port can be paused for by
374 * the remote end or the period of time that this port can pause the
375 * remote end.
376 */
377int mv88e6097_port_pause_config(struct mv88e6xxx_chip *chip, int port)
378{
379 return mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL, 0x0000);
380}
381
3ce0e65e
AL
382int mv88e6390_port_pause_config(struct mv88e6xxx_chip *chip, int port)
383{
384 int err;
385
386 err = mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL,
387 PORT_FLOW_CTRL_LIMIT_IN | 0);
388 if (err)
389 return err;
390
391 return mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL,
392 PORT_FLOW_CTRL_LIMIT_OUT | 0);
393}
394
e28def33
VD
395/* Offset 0x04: Port Control Register */
396
397static const char * const mv88e6xxx_port_state_names[] = {
398 [PORT_CONTROL_STATE_DISABLED] = "Disabled",
399 [PORT_CONTROL_STATE_BLOCKING] = "Blocking/Listening",
400 [PORT_CONTROL_STATE_LEARNING] = "Learning",
401 [PORT_CONTROL_STATE_FORWARDING] = "Forwarding",
402};
403
404int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
405{
406 u16 reg;
407 int err;
408
409 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg);
410 if (err)
411 return err;
412
413 reg &= ~PORT_CONTROL_STATE_MASK;
414 reg |= state;
415
416 err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
417 if (err)
418 return err;
419
420 netdev_dbg(chip->ds->ports[port].netdev, "PortState set to %s\n",
421 mv88e6xxx_port_state_names[state]);
422
423 return 0;
424}
5a7921f4 425
56995cbc
AL
426int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
427 u16 mode)
428{
429 int err;
430 u16 reg;
431
432 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg);
433 if (err)
434 return err;
435
436 reg &= ~PORT_CONTROL_EGRESS_MASK;
437 reg |= mode;
438
439 return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
440}
441
442int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
443 enum mv88e6xxx_frame_mode mode)
444{
445 int err;
446 u16 reg;
447
448 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg);
449 if (err)
450 return err;
451
452 reg &= ~PORT_CONTROL_FRAME_MODE_DSA;
453
454 switch (mode) {
455 case MV88E6XXX_FRAME_MODE_NORMAL:
456 reg |= PORT_CONTROL_FRAME_MODE_NORMAL;
457 break;
458 case MV88E6XXX_FRAME_MODE_DSA:
459 reg |= PORT_CONTROL_FRAME_MODE_DSA;
460 break;
461 default:
462 return -EINVAL;
463 }
464
465 return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
466}
467
468int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
469 enum mv88e6xxx_frame_mode mode)
470{
471 int err;
472 u16 reg;
473
474 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg);
475 if (err)
476 return err;
477
478 reg &= ~PORT_CONTROL_FRAME_MASK;
479
480 switch (mode) {
481 case MV88E6XXX_FRAME_MODE_NORMAL:
482 reg |= PORT_CONTROL_FRAME_MODE_NORMAL;
483 break;
484 case MV88E6XXX_FRAME_MODE_DSA:
485 reg |= PORT_CONTROL_FRAME_MODE_DSA;
486 break;
487 case MV88E6XXX_FRAME_MODE_PROVIDER:
488 reg |= PORT_CONTROL_FRAME_MODE_PROVIDER;
489 break;
490 case MV88E6XXX_FRAME_MODE_ETHERTYPE:
491 reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA;
492 break;
493 default:
494 return -EINVAL;
495 }
496
497 return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
498}
499
500int mv88e6085_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port,
501 bool on)
502{
503 int err;
504 u16 reg;
505
506 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg);
507 if (err)
508 return err;
509
510 if (on)
511 reg |= PORT_CONTROL_FORWARD_UNKNOWN;
512 else
513 reg &= ~PORT_CONTROL_FORWARD_UNKNOWN;
514
515 return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
516}
517
518int mv88e6351_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port,
519 bool on)
520{
521 int err;
522 u16 reg;
523
524 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg);
525 if (err)
526 return err;
527
528 if (on)
529 reg |= PORT_CONTROL_EGRESS_ALL_UNKNOWN_DA;
530 else
531 reg &= ~PORT_CONTROL_EGRESS_ALL_UNKNOWN_DA;
532
533 return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
534}
535
b4e48c50
VD
536/* Offset 0x05: Port Control 1 */
537
ea698f4f
VD
538int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
539 bool message_port)
540{
541 u16 val;
542 int err;
543
544 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &val);
545 if (err)
546 return err;
547
548 if (message_port)
549 val |= PORT_CONTROL_1_MESSAGE_PORT;
550 else
551 val &= ~PORT_CONTROL_1_MESSAGE_PORT;
552
553 return mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, val);
554}
555
5a7921f4
VD
556/* Offset 0x06: Port Based VLAN Map */
557
558int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
559{
4d294af2 560 const u16 mask = mv88e6xxx_port_mask(chip);
5a7921f4
VD
561 u16 reg;
562 int err;
563
564 err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg);
565 if (err)
566 return err;
567
568 reg &= ~mask;
569 reg |= map & mask;
570
571 err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg);
572 if (err)
573 return err;
574
575 netdev_dbg(chip->ds->ports[port].netdev, "VLANTable set to %.3x\n",
576 map);
577
578 return 0;
579}
b4e48c50
VD
580
581int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
582{
583 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
584 u16 reg;
585 int err;
586
587 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
588 err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg);
589 if (err)
590 return err;
591
592 *fid = (reg & 0xf000) >> 12;
593
594 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
595 if (upper_mask) {
596 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &reg);
597 if (err)
598 return err;
599
600 *fid |= (reg & upper_mask) << 4;
601 }
602
603 return 0;
604}
605
606int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
607{
608 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
609 u16 reg;
610 int err;
611
612 if (fid >= mv88e6xxx_num_databases(chip))
613 return -EINVAL;
614
615 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
616 err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg);
617 if (err)
618 return err;
619
620 reg &= 0x0fff;
621 reg |= (fid & 0x000f) << 12;
622
623 err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg);
624 if (err)
625 return err;
626
627 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
628 if (upper_mask) {
629 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &reg);
630 if (err)
631 return err;
632
633 reg &= ~upper_mask;
634 reg |= (fid >> 4) & upper_mask;
635
636 err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, reg);
637 if (err)
638 return err;
639 }
640
641 netdev_dbg(chip->ds->ports[port].netdev, "FID set to %u\n", fid);
642
643 return 0;
644}
77064f37
VD
645
646/* Offset 0x07: Default Port VLAN ID & Priority */
647
648int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
649{
650 u16 reg;
651 int err;
652
653 err = mv88e6xxx_port_read(chip, port, PORT_DEFAULT_VLAN, &reg);
654 if (err)
655 return err;
656
657 *pvid = reg & PORT_DEFAULT_VLAN_MASK;
658
659 return 0;
660}
661
662int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
663{
664 u16 reg;
665 int err;
666
667 err = mv88e6xxx_port_read(chip, port, PORT_DEFAULT_VLAN, &reg);
668 if (err)
669 return err;
670
671 reg &= ~PORT_DEFAULT_VLAN_MASK;
672 reg |= pvid & PORT_DEFAULT_VLAN_MASK;
673
674 err = mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, reg);
675 if (err)
676 return err;
677
678 netdev_dbg(chip->ds->ports[port].netdev, "DefaultVID set to %u\n",
679 pvid);
680
681 return 0;
682}
385a0995
VD
683
684/* Offset 0x08: Port Control 2 Register */
685
686static const char * const mv88e6xxx_port_8021q_mode_names[] = {
687 [PORT_CONTROL_2_8021Q_DISABLED] = "Disabled",
688 [PORT_CONTROL_2_8021Q_FALLBACK] = "Fallback",
689 [PORT_CONTROL_2_8021Q_CHECK] = "Check",
690 [PORT_CONTROL_2_8021Q_SECURE] = "Secure",
691};
692
a23b2961
AL
693int mv88e6095_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port,
694 bool on)
695{
696 int err;
697 u16 reg;
698
699 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg);
700 if (err)
701 return err;
702
703 if (on)
704 reg |= PORT_CONTROL_2_FORWARD_UNKNOWN;
705 else
706 reg &= ~PORT_CONTROL_2_FORWARD_UNKNOWN;
707
708 return mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
709}
710
711int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
712 int upstream_port)
713{
714 int err;
715 u16 reg;
716
717 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg);
718 if (err)
719 return err;
720
721 reg &= ~PORT_CONTROL_2_UPSTREAM_MASK;
722 reg |= upstream_port;
723
724 return mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
725}
726
385a0995
VD
727int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
728 u16 mode)
729{
730 u16 reg;
731 int err;
732
733 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg);
734 if (err)
735 return err;
736
737 reg &= ~PORT_CONTROL_2_8021Q_MASK;
738 reg |= mode & PORT_CONTROL_2_8021Q_MASK;
739
740 err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
741 if (err)
742 return err;
743
744 netdev_dbg(chip->ds->ports[port].netdev, "802.1QMode set to %s\n",
745 mv88e6xxx_port_8021q_mode_names[mode]);
746
747 return 0;
748}
ef0a7318 749
a23b2961
AL
750int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
751{
752 u16 reg;
753 int err;
754
755 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg);
756 if (err)
757 return err;
758
759 reg |= PORT_CONTROL_2_MAP_DA;
760
761 return mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
762}
763
5f436666
AL
764int mv88e6165_port_jumbo_config(struct mv88e6xxx_chip *chip, int port)
765{
766 u16 reg;
767 int err;
768
769 err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg);
770 if (err)
771 return err;
772
773 reg |= PORT_CONTROL_2_JUMBO_10240;
774
775 return mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
776}
777
ef70b111
AL
778/* Offset 0x09: Port Rate Control */
779
780int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
781{
782 return mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL, 0x0000);
783}
784
785int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
786{
787 return mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL, 0x0001);
788}
789
56995cbc
AL
790/* Offset 0x0f: Port Ether type */
791
792int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
793 u16 etype)
794{
795 return mv88e6xxx_port_write(chip, port, PORT_ETH_TYPE, etype);
796}
797
ef0a7318
AL
798/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
799 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
800 */
801
802int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
803{
804 int err;
805
806 /* Use a direct priority mapping for all IEEE tagged frames */
807 err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_0123, 0x3210);
808 if (err)
809 return err;
810
811 return mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_4567, 0x7654);
812}
813
814static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
815 int port, u16 table,
816 u8 pointer, u16 data)
817{
818 u16 reg;
819
820 reg = PORT_IEEE_PRIO_MAP_TABLE_UPDATE |
821 table |
822 (pointer << PORT_IEEE_PRIO_MAP_TABLE_POINTER_SHIFT) |
823 data;
824
825 return mv88e6xxx_port_write(chip, port, PORT_IEEE_PRIO_MAP_TABLE, reg);
826}
827
828int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
829{
830 int err, i;
831
832 for (i = 0; i <= 7; i++) {
833 err = mv88e6xxx_port_ieeepmt_write(
834 chip, port, PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP,
835 i, (i | i << 4));
836 if (err)
837 return err;
838
839 err = mv88e6xxx_port_ieeepmt_write(
840 chip, port, PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP,
841 i, i);
842 if (err)
843 return err;
844
845 err = mv88e6xxx_port_ieeepmt_write(
846 chip, port, PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP,
847 i, i);
848 if (err)
849 return err;
850
851 err = mv88e6xxx_port_ieeepmt_write(
852 chip, port, PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP,
853 i, i);
854 if (err)
855 return err;
856 }
857
858 return 0;
859}