Merge tag 'mips_4.16_2' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/mips
[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
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         case PHY_INTERFACE_MODE_XAUI:
342                 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
343                 break;
344         case PHY_INTERFACE_MODE_RXAUI:
345                 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
346                 break;
347         default:
348                 cmode = 0;
349         }
350
351         if (cmode) {
352                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
353                 if (err)
354                         return err;
355
356                 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
357                 reg |= cmode;
358
359                 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
360                 if (err)
361                         return err;
362         }
363
364         return 0;
365 }
366
367 int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
368 {
369         int err;
370         u16 reg;
371
372         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
373         if (err)
374                 return err;
375
376         *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
377
378         return 0;
379 }
380
381 /* Offset 0x02: Jamming Control
382  *
383  * Do not limit the period of time that this port can be paused for by
384  * the remote end or the period of time that this port can pause the
385  * remote end.
386  */
387 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
388                                u8 out)
389 {
390         return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
391                                     out << 8 | in);
392 }
393
394 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
395                                u8 out)
396 {
397         int err;
398
399         err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
400                                    MV88E6390_PORT_FLOW_CTL_UPDATE |
401                                    MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
402         if (err)
403                 return err;
404
405         return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
406                                     MV88E6390_PORT_FLOW_CTL_UPDATE |
407                                     MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
408 }
409
410 /* Offset 0x04: Port Control Register */
411
412 static const char * const mv88e6xxx_port_state_names[] = {
413         [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
414         [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
415         [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
416         [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
417 };
418
419 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
420 {
421         u16 reg;
422         int err;
423
424         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
425         if (err)
426                 return err;
427
428         reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
429
430         switch (state) {
431         case BR_STATE_DISABLED:
432                 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
433                 break;
434         case BR_STATE_BLOCKING:
435         case BR_STATE_LISTENING:
436                 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
437                 break;
438         case BR_STATE_LEARNING:
439                 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
440                 break;
441         case BR_STATE_FORWARDING:
442                 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
443                 break;
444         default:
445                 return -EINVAL;
446         }
447
448         reg |= state;
449
450         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
451         if (err)
452                 return err;
453
454         dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
455                 mv88e6xxx_port_state_names[state]);
456
457         return 0;
458 }
459
460 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
461                                    enum mv88e6xxx_egress_mode mode)
462 {
463         int err;
464         u16 reg;
465
466         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
467         if (err)
468                 return err;
469
470         reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
471
472         switch (mode) {
473         case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
474                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
475                 break;
476         case MV88E6XXX_EGRESS_MODE_UNTAGGED:
477                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
478                 break;
479         case MV88E6XXX_EGRESS_MODE_TAGGED:
480                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
481                 break;
482         case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
483                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
484                 break;
485         default:
486                 return -EINVAL;
487         }
488
489         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
490 }
491
492 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
493                                   enum mv88e6xxx_frame_mode mode)
494 {
495         int err;
496         u16 reg;
497
498         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
499         if (err)
500                 return err;
501
502         reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
503
504         switch (mode) {
505         case MV88E6XXX_FRAME_MODE_NORMAL:
506                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
507                 break;
508         case MV88E6XXX_FRAME_MODE_DSA:
509                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
510                 break;
511         default:
512                 return -EINVAL;
513         }
514
515         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
516 }
517
518 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
519                                   enum mv88e6xxx_frame_mode mode)
520 {
521         int err;
522         u16 reg;
523
524         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
525         if (err)
526                 return err;
527
528         reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
529
530         switch (mode) {
531         case MV88E6XXX_FRAME_MODE_NORMAL:
532                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
533                 break;
534         case MV88E6XXX_FRAME_MODE_DSA:
535                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
536                 break;
537         case MV88E6XXX_FRAME_MODE_PROVIDER:
538                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
539                 break;
540         case MV88E6XXX_FRAME_MODE_ETHERTYPE:
541                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
542                 break;
543         default:
544                 return -EINVAL;
545         }
546
547         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
548 }
549
550 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
551                                               int port, bool unicast)
552 {
553         int err;
554         u16 reg;
555
556         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
557         if (err)
558                 return err;
559
560         if (unicast)
561                 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
562         else
563                 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
564
565         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
566 }
567
568 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
569                                      bool unicast, bool multicast)
570 {
571         int err;
572         u16 reg;
573
574         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
575         if (err)
576                 return err;
577
578         reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
579
580         if (unicast && multicast)
581                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
582         else if (unicast)
583                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
584         else if (multicast)
585                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
586         else
587                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
588
589         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
590 }
591
592 /* Offset 0x05: Port Control 1 */
593
594 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
595                                     bool message_port)
596 {
597         u16 val;
598         int err;
599
600         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
601         if (err)
602                 return err;
603
604         if (message_port)
605                 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
606         else
607                 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
608
609         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
610 }
611
612 /* Offset 0x06: Port Based VLAN Map */
613
614 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
615 {
616         const u16 mask = mv88e6xxx_port_mask(chip);
617         u16 reg;
618         int err;
619
620         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
621         if (err)
622                 return err;
623
624         reg &= ~mask;
625         reg |= map & mask;
626
627         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
628         if (err)
629                 return err;
630
631         dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
632
633         return 0;
634 }
635
636 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
637 {
638         const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
639         u16 reg;
640         int err;
641
642         /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
643         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
644         if (err)
645                 return err;
646
647         *fid = (reg & 0xf000) >> 12;
648
649         /* Port's default FID upper bits are located in reg 0x05, offset 0 */
650         if (upper_mask) {
651                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
652                                           &reg);
653                 if (err)
654                         return err;
655
656                 *fid |= (reg & upper_mask) << 4;
657         }
658
659         return 0;
660 }
661
662 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
663 {
664         const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
665         u16 reg;
666         int err;
667
668         if (fid >= mv88e6xxx_num_databases(chip))
669                 return -EINVAL;
670
671         /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
672         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
673         if (err)
674                 return err;
675
676         reg &= 0x0fff;
677         reg |= (fid & 0x000f) << 12;
678
679         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
680         if (err)
681                 return err;
682
683         /* Port's default FID upper bits are located in reg 0x05, offset 0 */
684         if (upper_mask) {
685                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
686                                           &reg);
687                 if (err)
688                         return err;
689
690                 reg &= ~upper_mask;
691                 reg |= (fid >> 4) & upper_mask;
692
693                 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
694                                            reg);
695                 if (err)
696                         return err;
697         }
698
699         dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
700
701         return 0;
702 }
703
704 /* Offset 0x07: Default Port VLAN ID & Priority */
705
706 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
707 {
708         u16 reg;
709         int err;
710
711         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
712                                   &reg);
713         if (err)
714                 return err;
715
716         *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
717
718         return 0;
719 }
720
721 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
722 {
723         u16 reg;
724         int err;
725
726         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
727                                   &reg);
728         if (err)
729                 return err;
730
731         reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
732         reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
733
734         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
735                                    reg);
736         if (err)
737                 return err;
738
739         dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
740
741         return 0;
742 }
743
744 /* Offset 0x08: Port Control 2 Register */
745
746 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
747         [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
748         [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
749         [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
750         [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
751 };
752
753 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
754                                               int port, bool multicast)
755 {
756         int err;
757         u16 reg;
758
759         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
760         if (err)
761                 return err;
762
763         if (multicast)
764                 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
765         else
766                 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
767
768         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
769 }
770
771 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
772                                      bool unicast, bool multicast)
773 {
774         int err;
775
776         err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
777         if (err)
778                 return err;
779
780         return mv88e6185_port_set_default_forward(chip, port, multicast);
781 }
782
783 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
784                                      int upstream_port)
785 {
786         int err;
787         u16 reg;
788
789         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
790         if (err)
791                 return err;
792
793         reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
794         reg |= upstream_port;
795
796         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
797 }
798
799 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
800                                   u16 mode)
801 {
802         u16 reg;
803         int err;
804
805         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
806         if (err)
807                 return err;
808
809         reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
810         reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
811
812         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
813         if (err)
814                 return err;
815
816         dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
817                 mv88e6xxx_port_8021q_mode_names[mode]);
818
819         return 0;
820 }
821
822 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
823 {
824         u16 reg;
825         int err;
826
827         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
828         if (err)
829                 return err;
830
831         reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
832
833         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
834 }
835
836 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
837                                   size_t size)
838 {
839         u16 reg;
840         int err;
841
842         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
843         if (err)
844                 return err;
845
846         reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
847
848         if (size <= 1522)
849                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
850         else if (size <= 2048)
851                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
852         else if (size <= 10240)
853                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
854         else
855                 return -ERANGE;
856
857         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
858 }
859
860 /* Offset 0x09: Port Rate Control */
861
862 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
863 {
864         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
865                                     0x0000);
866 }
867
868 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
869 {
870         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
871                                     0x0001);
872 }
873
874 /* Offset 0x0C: Port ATU Control */
875
876 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
877 {
878         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
879 }
880
881 /* Offset 0x0D: (Priority) Override Register */
882
883 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
884 {
885         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
886 }
887
888 /* Offset 0x0f: Port Ether type */
889
890 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
891                                   u16 etype)
892 {
893         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
894 }
895
896 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
897  * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
898  */
899
900 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
901 {
902         int err;
903
904         /* Use a direct priority mapping for all IEEE tagged frames */
905         err = mv88e6xxx_port_write(chip, port,
906                                    MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
907                                    0x3210);
908         if (err)
909                 return err;
910
911         return mv88e6xxx_port_write(chip, port,
912                                     MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
913                                     0x7654);
914 }
915
916 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
917                                         int port, u16 table, u8 ptr, u16 data)
918 {
919         u16 reg;
920
921         reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
922                 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
923                 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
924
925         return mv88e6xxx_port_write(chip, port,
926                                     MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
927 }
928
929 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
930 {
931         int err, i;
932         u16 table;
933
934         for (i = 0; i <= 7; i++) {
935                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
936                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
937                                                    (i | i << 4));
938                 if (err)
939                         return err;
940
941                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
942                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
943                 if (err)
944                         return err;
945
946                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
947                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
948                 if (err)
949                         return err;
950
951                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
952                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
953                 if (err)
954                         return err;
955         }
956
957         return 0;
958 }