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