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