Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux-2.6-block.git] / drivers / net / dsa / mv88e6xxx / port.c
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
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
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  */
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, &reg);
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
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, &reg);
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
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
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
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, &reg);
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
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, &reg);
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 -EOPNOTSUPP;
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
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                 if (alt_bit)
232                         ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
233                                 MV88E6390_PORT_MAC_CTL_ALTSPEED;
234                 else
235                         ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
236                 break;
237         case 10000:
238                 /* all bits set, fall through... */
239         case SPEED_UNFORCED:
240                 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
241                 break;
242         default:
243                 return -EOPNOTSUPP;
244         }
245
246         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
247         if (err)
248                 return err;
249
250         reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK;
251         if (alt_bit)
252                 reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
253         if (force_bit) {
254                 reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
255                 if (speed != SPEED_UNFORCED)
256                         ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
257         }
258         reg |= ctrl;
259
260         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
261         if (err)
262                 return err;
263
264         if (speed)
265                 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
266         else
267                 dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
268
269         return 0;
270 }
271
272 /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
273 int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
274 {
275         if (speed == SPEED_MAX)
276                 speed = 200;
277
278         if (speed > 200)
279                 return -EOPNOTSUPP;
280
281         /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
282         return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
283 }
284
285 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
286 int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
287 {
288         if (speed == SPEED_MAX)
289                 speed = 1000;
290
291         if (speed == 200 || speed > 1000)
292                 return -EOPNOTSUPP;
293
294         return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
295 }
296
297 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
298 int mv88e6341_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
299 {
300         if (speed == SPEED_MAX)
301                 speed = port < 5 ? 1000 : 2500;
302
303         if (speed > 2500)
304                 return -EOPNOTSUPP;
305
306         if (speed == 200 && port != 0)
307                 return -EOPNOTSUPP;
308
309         if (speed == 2500 && port < 5)
310                 return -EOPNOTSUPP;
311
312         return mv88e6xxx_port_set_speed(chip, port, speed, !port, true);
313 }
314
315 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
316 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
317 {
318         if (speed == SPEED_MAX)
319                 speed = 1000;
320
321         if (speed > 1000)
322                 return -EOPNOTSUPP;
323
324         if (speed == 200 && port < 5)
325                 return -EOPNOTSUPP;
326
327         return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
328 }
329
330 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
331 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
332 {
333         if (speed == SPEED_MAX)
334                 speed = port < 9 ? 1000 : 2500;
335
336         if (speed > 2500)
337                 return -EOPNOTSUPP;
338
339         if (speed == 200 && port != 0)
340                 return -EOPNOTSUPP;
341
342         if (speed == 2500 && port < 9)
343                 return -EOPNOTSUPP;
344
345         return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
346 }
347
348 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
349 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
350 {
351         if (speed == SPEED_MAX)
352                 speed = port < 9 ? 1000 : 10000;
353
354         if (speed == 200 && port != 0)
355                 return -EOPNOTSUPP;
356
357         if (speed >= 2500 && port < 9)
358                 return -EOPNOTSUPP;
359
360         return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
361 }
362
363 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
364                               phy_interface_t mode)
365 {
366         int lane;
367         u16 cmode;
368         u16 reg;
369         int err;
370
371         if (port != 9 && port != 10)
372                 return -EOPNOTSUPP;
373
374         /* Default to a slow mode, so freeing up SERDES interfaces for
375          * other ports which might use them for SFPs.
376          */
377         if (mode == PHY_INTERFACE_MODE_NA)
378                 mode = PHY_INTERFACE_MODE_1000BASEX;
379
380         switch (mode) {
381         case PHY_INTERFACE_MODE_1000BASEX:
382                 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X;
383                 break;
384         case PHY_INTERFACE_MODE_SGMII:
385                 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
386                 break;
387         case PHY_INTERFACE_MODE_2500BASEX:
388                 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
389                 break;
390         case PHY_INTERFACE_MODE_XGMII:
391         case PHY_INTERFACE_MODE_XAUI:
392                 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
393                 break;
394         case PHY_INTERFACE_MODE_RXAUI:
395                 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
396                 break;
397         default:
398                 cmode = 0;
399         }
400
401         /* cmode doesn't change, nothing to do for us */
402         if (cmode == chip->ports[port].cmode)
403                 return 0;
404
405         lane = mv88e6390x_serdes_get_lane(chip, port);
406         if (lane < 0)
407                 return lane;
408
409         if (chip->ports[port].serdes_irq) {
410                 err = mv88e6390_serdes_irq_disable(chip, port, lane);
411                 if (err)
412                         return err;
413         }
414
415         err = mv88e6390x_serdes_power(chip, port, false);
416         if (err)
417                 return err;
418
419         if (cmode) {
420                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
421                 if (err)
422                         return err;
423
424                 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
425                 reg |= cmode;
426
427                 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
428                 if (err)
429                         return err;
430
431                 err = mv88e6390x_serdes_power(chip, port, true);
432                 if (err)
433                         return err;
434
435                 if (chip->ports[port].serdes_irq) {
436                         err = mv88e6390_serdes_irq_enable(chip, port, lane);
437                         if (err)
438                                 return err;
439                 }
440         }
441
442         chip->ports[port].cmode = cmode;
443
444         return 0;
445 }
446
447 int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
448                              phy_interface_t mode)
449 {
450         switch (mode) {
451         case PHY_INTERFACE_MODE_NA:
452                 return 0;
453         case PHY_INTERFACE_MODE_XGMII:
454         case PHY_INTERFACE_MODE_XAUI:
455         case PHY_INTERFACE_MODE_RXAUI:
456                 return -EINVAL;
457         default:
458                 break;
459         }
460
461         return mv88e6390x_port_set_cmode(chip, port, mode);
462 }
463
464 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
465 {
466         int err;
467         u16 reg;
468
469         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
470         if (err)
471                 return err;
472
473         *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
474
475         return 0;
476 }
477
478 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
479 {
480         int err;
481         u16 reg;
482
483         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
484         if (err)
485                 return err;
486
487         *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
488
489         return 0;
490 }
491
492 int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
493                               struct phylink_link_state *state)
494 {
495         int err;
496         u16 reg;
497
498         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
499         if (err)
500                 return err;
501
502         switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
503         case MV88E6XXX_PORT_STS_SPEED_10:
504                 state->speed = SPEED_10;
505                 break;
506         case MV88E6XXX_PORT_STS_SPEED_100:
507                 state->speed = SPEED_100;
508                 break;
509         case MV88E6XXX_PORT_STS_SPEED_1000:
510                 state->speed = SPEED_1000;
511                 break;
512         case MV88E6XXX_PORT_STS_SPEED_10000:
513                 if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
514                     MV88E6XXX_PORT_STS_CMODE_2500BASEX)
515                         state->speed = SPEED_2500;
516                 else
517                         state->speed = SPEED_10000;
518                 break;
519         }
520
521         state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
522                         DUPLEX_FULL : DUPLEX_HALF;
523         state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
524         state->an_enabled = 1;
525         state->an_complete = state->link;
526
527         return 0;
528 }
529
530 int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
531                               struct phylink_link_state *state)
532 {
533         if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
534                 u8 cmode = chip->ports[port].cmode;
535
536                 /* When a port is in "Cross-chip serdes" mode, it uses
537                  * 1000Base-X full duplex mode, but there is no automatic
538                  * link detection. Use the sync OK status for link (as it
539                  * would do for 1000Base-X mode.)
540                  */
541                 if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
542                         u16 mac;
543                         int err;
544
545                         err = mv88e6xxx_port_read(chip, port,
546                                                   MV88E6XXX_PORT_MAC_CTL, &mac);
547                         if (err)
548                                 return err;
549
550                         state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
551                         state->an_enabled = 1;
552                         state->an_complete =
553                                 !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
554                         state->duplex =
555                                 state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
556                         state->speed =
557                                 state->link ? SPEED_1000 : SPEED_UNKNOWN;
558
559                         return 0;
560                 }
561         }
562
563         return mv88e6352_port_link_state(chip, port, state);
564 }
565
566 /* Offset 0x02: Jamming Control
567  *
568  * Do not limit the period of time that this port can be paused for by
569  * the remote end or the period of time that this port can pause the
570  * remote end.
571  */
572 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
573                                u8 out)
574 {
575         return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
576                                     out << 8 | in);
577 }
578
579 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
580                                u8 out)
581 {
582         int err;
583
584         err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
585                                    MV88E6390_PORT_FLOW_CTL_UPDATE |
586                                    MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
587         if (err)
588                 return err;
589
590         return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
591                                     MV88E6390_PORT_FLOW_CTL_UPDATE |
592                                     MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
593 }
594
595 /* Offset 0x04: Port Control Register */
596
597 static const char * const mv88e6xxx_port_state_names[] = {
598         [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
599         [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
600         [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
601         [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
602 };
603
604 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
605 {
606         u16 reg;
607         int err;
608
609         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
610         if (err)
611                 return err;
612
613         reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
614
615         switch (state) {
616         case BR_STATE_DISABLED:
617                 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
618                 break;
619         case BR_STATE_BLOCKING:
620         case BR_STATE_LISTENING:
621                 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
622                 break;
623         case BR_STATE_LEARNING:
624                 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
625                 break;
626         case BR_STATE_FORWARDING:
627                 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
628                 break;
629         default:
630                 return -EINVAL;
631         }
632
633         reg |= state;
634
635         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
636         if (err)
637                 return err;
638
639         dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
640                 mv88e6xxx_port_state_names[state]);
641
642         return 0;
643 }
644
645 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
646                                    enum mv88e6xxx_egress_mode mode)
647 {
648         int err;
649         u16 reg;
650
651         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
652         if (err)
653                 return err;
654
655         reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
656
657         switch (mode) {
658         case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
659                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
660                 break;
661         case MV88E6XXX_EGRESS_MODE_UNTAGGED:
662                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
663                 break;
664         case MV88E6XXX_EGRESS_MODE_TAGGED:
665                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
666                 break;
667         case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
668                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
669                 break;
670         default:
671                 return -EINVAL;
672         }
673
674         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
675 }
676
677 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
678                                   enum mv88e6xxx_frame_mode mode)
679 {
680         int err;
681         u16 reg;
682
683         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
684         if (err)
685                 return err;
686
687         reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
688
689         switch (mode) {
690         case MV88E6XXX_FRAME_MODE_NORMAL:
691                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
692                 break;
693         case MV88E6XXX_FRAME_MODE_DSA:
694                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
695                 break;
696         default:
697                 return -EINVAL;
698         }
699
700         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
701 }
702
703 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
704                                   enum mv88e6xxx_frame_mode mode)
705 {
706         int err;
707         u16 reg;
708
709         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
710         if (err)
711                 return err;
712
713         reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
714
715         switch (mode) {
716         case MV88E6XXX_FRAME_MODE_NORMAL:
717                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
718                 break;
719         case MV88E6XXX_FRAME_MODE_DSA:
720                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
721                 break;
722         case MV88E6XXX_FRAME_MODE_PROVIDER:
723                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
724                 break;
725         case MV88E6XXX_FRAME_MODE_ETHERTYPE:
726                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
727                 break;
728         default:
729                 return -EINVAL;
730         }
731
732         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
733 }
734
735 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
736                                               int port, bool unicast)
737 {
738         int err;
739         u16 reg;
740
741         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
742         if (err)
743                 return err;
744
745         if (unicast)
746                 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
747         else
748                 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
749
750         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
751 }
752
753 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
754                                      bool unicast, bool multicast)
755 {
756         int err;
757         u16 reg;
758
759         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
760         if (err)
761                 return err;
762
763         reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
764
765         if (unicast && multicast)
766                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
767         else if (unicast)
768                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
769         else if (multicast)
770                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
771         else
772                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
773
774         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
775 }
776
777 /* Offset 0x05: Port Control 1 */
778
779 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
780                                     bool message_port)
781 {
782         u16 val;
783         int err;
784
785         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
786         if (err)
787                 return err;
788
789         if (message_port)
790                 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
791         else
792                 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
793
794         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
795 }
796
797 /* Offset 0x06: Port Based VLAN Map */
798
799 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
800 {
801         const u16 mask = mv88e6xxx_port_mask(chip);
802         u16 reg;
803         int err;
804
805         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
806         if (err)
807                 return err;
808
809         reg &= ~mask;
810         reg |= map & mask;
811
812         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
813         if (err)
814                 return err;
815
816         dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
817
818         return 0;
819 }
820
821 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
822 {
823         const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
824         u16 reg;
825         int err;
826
827         /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
828         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
829         if (err)
830                 return err;
831
832         *fid = (reg & 0xf000) >> 12;
833
834         /* Port's default FID upper bits are located in reg 0x05, offset 0 */
835         if (upper_mask) {
836                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
837                                           &reg);
838                 if (err)
839                         return err;
840
841                 *fid |= (reg & upper_mask) << 4;
842         }
843
844         return 0;
845 }
846
847 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
848 {
849         const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
850         u16 reg;
851         int err;
852
853         if (fid >= mv88e6xxx_num_databases(chip))
854                 return -EINVAL;
855
856         /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
857         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
858         if (err)
859                 return err;
860
861         reg &= 0x0fff;
862         reg |= (fid & 0x000f) << 12;
863
864         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
865         if (err)
866                 return err;
867
868         /* Port's default FID upper bits are located in reg 0x05, offset 0 */
869         if (upper_mask) {
870                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
871                                           &reg);
872                 if (err)
873                         return err;
874
875                 reg &= ~upper_mask;
876                 reg |= (fid >> 4) & upper_mask;
877
878                 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
879                                            reg);
880                 if (err)
881                         return err;
882         }
883
884         dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
885
886         return 0;
887 }
888
889 /* Offset 0x07: Default Port VLAN ID & Priority */
890
891 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
892 {
893         u16 reg;
894         int err;
895
896         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
897                                   &reg);
898         if (err)
899                 return err;
900
901         *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
902
903         return 0;
904 }
905
906 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
907 {
908         u16 reg;
909         int err;
910
911         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
912                                   &reg);
913         if (err)
914                 return err;
915
916         reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
917         reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
918
919         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
920                                    reg);
921         if (err)
922                 return err;
923
924         dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
925
926         return 0;
927 }
928
929 /* Offset 0x08: Port Control 2 Register */
930
931 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
932         [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
933         [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
934         [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
935         [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
936 };
937
938 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
939                                               int port, bool multicast)
940 {
941         int err;
942         u16 reg;
943
944         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
945         if (err)
946                 return err;
947
948         if (multicast)
949                 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
950         else
951                 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
952
953         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
954 }
955
956 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
957                                      bool unicast, bool multicast)
958 {
959         int err;
960
961         err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
962         if (err)
963                 return err;
964
965         return mv88e6185_port_set_default_forward(chip, port, multicast);
966 }
967
968 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
969                                      int upstream_port)
970 {
971         int err;
972         u16 reg;
973
974         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
975         if (err)
976                 return err;
977
978         reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
979         reg |= upstream_port;
980
981         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
982 }
983
984 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
985                                   u16 mode)
986 {
987         u16 reg;
988         int err;
989
990         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
991         if (err)
992                 return err;
993
994         reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
995         reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
996
997         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
998         if (err)
999                 return err;
1000
1001         dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
1002                 mv88e6xxx_port_8021q_mode_names[mode]);
1003
1004         return 0;
1005 }
1006
1007 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
1008 {
1009         u16 reg;
1010         int err;
1011
1012         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1013         if (err)
1014                 return err;
1015
1016         reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
1017
1018         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1019 }
1020
1021 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
1022                                   size_t size)
1023 {
1024         u16 reg;
1025         int err;
1026
1027         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1028         if (err)
1029                 return err;
1030
1031         reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
1032
1033         if (size <= 1522)
1034                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
1035         else if (size <= 2048)
1036                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
1037         else if (size <= 10240)
1038                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
1039         else
1040                 return -ERANGE;
1041
1042         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1043 }
1044
1045 /* Offset 0x09: Port Rate Control */
1046
1047 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1048 {
1049         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1050                                     0x0000);
1051 }
1052
1053 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1054 {
1055         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1056                                     0x0001);
1057 }
1058
1059 /* Offset 0x0C: Port ATU Control */
1060
1061 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
1062 {
1063         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
1064 }
1065
1066 /* Offset 0x0D: (Priority) Override Register */
1067
1068 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
1069 {
1070         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
1071 }
1072
1073 /* Offset 0x0f: Port Ether type */
1074
1075 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1076                                   u16 etype)
1077 {
1078         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
1079 }
1080
1081 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1082  * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1083  */
1084
1085 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1086 {
1087         int err;
1088
1089         /* Use a direct priority mapping for all IEEE tagged frames */
1090         err = mv88e6xxx_port_write(chip, port,
1091                                    MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
1092                                    0x3210);
1093         if (err)
1094                 return err;
1095
1096         return mv88e6xxx_port_write(chip, port,
1097                                     MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
1098                                     0x7654);
1099 }
1100
1101 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
1102                                         int port, u16 table, u8 ptr, u16 data)
1103 {
1104         u16 reg;
1105
1106         reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
1107                 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
1108                 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
1109
1110         return mv88e6xxx_port_write(chip, port,
1111                                     MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
1112 }
1113
1114 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1115 {
1116         int err, i;
1117         u16 table;
1118
1119         for (i = 0; i <= 7; i++) {
1120                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
1121                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1122                                                    (i | i << 4));
1123                 if (err)
1124                         return err;
1125
1126                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1127                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1128                 if (err)
1129                         return err;
1130
1131                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1132                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1133                 if (err)
1134                         return err;
1135
1136                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1137                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1138                 if (err)
1139                         return err;
1140         }
1141
1142         return 0;
1143 }