GNU Linux-libre 5.10.153-gnu1
[releases.git] / drivers / net / dsa / mv88e6xxx / port.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Marvell 88E6xxx Switch Port Registers support
4  *
5  * Copyright (c) 2008 Marvell Semiconductor
6  *
7  * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
8  *      Vivien Didelot <vivien.didelot@savoirfairelinux.com>
9  */
10
11 #include <linux/bitfield.h>
12 #include <linux/if_bridge.h>
13 #include <linux/phy.h>
14 #include <linux/phylink.h>
15
16 #include "chip.h"
17 #include "port.h"
18 #include "serdes.h"
19
20 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
21                         u16 *val)
22 {
23         int addr = chip->info->port_base_addr + port;
24
25         return mv88e6xxx_read(chip, addr, reg, val);
26 }
27
28 int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
29                          u16 val)
30 {
31         int addr = chip->info->port_base_addr + port;
32
33         return mv88e6xxx_write(chip, addr, reg, val);
34 }
35
36 /* Offset 0x00: MAC (or PCS or Physical) Status Register
37  *
38  * For most devices, this is read only. However the 6185 has the MyPause
39  * bit read/write.
40  */
41 int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
42                              int pause)
43 {
44         u16 reg;
45         int err;
46
47         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
48         if (err)
49                 return err;
50
51         if (pause)
52                 reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
53         else
54                 reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
55
56         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
57 }
58
59 /* Offset 0x01: MAC (or PCS or Physical) Control Register
60  *
61  * Link, Duplex and Flow Control have one force bit, one value bit.
62  *
63  * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
64  * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
65  * Newer chips need a ForcedSpd bit 13 set to consider the value.
66  */
67
68 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
69                                           phy_interface_t mode)
70 {
71         u16 reg;
72         int err;
73
74         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
75         if (err)
76                 return err;
77
78         reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
79                  MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
80
81         switch (mode) {
82         case PHY_INTERFACE_MODE_RGMII_RXID:
83                 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
84                 break;
85         case PHY_INTERFACE_MODE_RGMII_TXID:
86                 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
87                 break;
88         case PHY_INTERFACE_MODE_RGMII_ID:
89                 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
90                         MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
91                 break;
92         case PHY_INTERFACE_MODE_RGMII:
93                 break;
94         default:
95                 return 0;
96         }
97
98         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
99         if (err)
100                 return err;
101
102         dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
103                 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
104                 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
105
106         return 0;
107 }
108
109 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
110                                    phy_interface_t mode)
111 {
112         if (port < 5)
113                 return -EOPNOTSUPP;
114
115         return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
116 }
117
118 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
119                                    phy_interface_t mode)
120 {
121         if (port != 0)
122                 return -EOPNOTSUPP;
123
124         return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
125 }
126
127 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
128 {
129         u16 reg;
130         int err;
131
132         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
133         if (err)
134                 return err;
135
136         reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
137                  MV88E6XXX_PORT_MAC_CTL_LINK_UP);
138
139         switch (link) {
140         case LINK_FORCED_DOWN:
141                 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
142                 break;
143         case LINK_FORCED_UP:
144                 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
145                         MV88E6XXX_PORT_MAC_CTL_LINK_UP;
146                 break;
147         case LINK_UNFORCED:
148                 /* normal link detection */
149                 break;
150         default:
151                 return -EINVAL;
152         }
153
154         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
155         if (err)
156                 return err;
157
158         dev_dbg(chip->dev, "p%d: %s link %s\n", port,
159                 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
160                 reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
161
162         return 0;
163 }
164
165 static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
166                                            int port, int speed, bool alt_bit,
167                                            bool force_bit, int duplex)
168 {
169         u16 reg, ctrl;
170         int err;
171
172         switch (speed) {
173         case 10:
174                 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
175                 break;
176         case 100:
177                 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
178                 break;
179         case 200:
180                 if (alt_bit)
181                         ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
182                                 MV88E6390_PORT_MAC_CTL_ALTSPEED;
183                 else
184                         ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
185                 break;
186         case 1000:
187                 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
188                 break;
189         case 2500:
190                 if (alt_bit)
191                         ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
192                                 MV88E6390_PORT_MAC_CTL_ALTSPEED;
193                 else
194                         ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
195                 break;
196         case 10000:
197                 /* all bits set, fall through... */
198         case SPEED_UNFORCED:
199                 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
200                 break;
201         default:
202                 return -EOPNOTSUPP;
203         }
204
205         switch (duplex) {
206         case DUPLEX_HALF:
207                 ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
208                 break;
209         case DUPLEX_FULL:
210                 ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
211                         MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
212                 break;
213         case DUPLEX_UNFORCED:
214                 /* normal duplex detection */
215                 break;
216         default:
217                 return -EOPNOTSUPP;
218         }
219
220         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
221         if (err)
222                 return err;
223
224         reg &= ~(MV88E6XXX_PORT_MAC_CTL_SPEED_MASK |
225                  MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
226                  MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
227
228         if (alt_bit)
229                 reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
230         if (force_bit) {
231                 reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
232                 if (speed != SPEED_UNFORCED)
233                         ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
234         }
235         reg |= ctrl;
236
237         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
238         if (err)
239                 return err;
240
241         if (speed)
242                 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
243         else
244                 dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
245         dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
246                 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
247                 reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
248
249         return 0;
250 }
251
252 /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
253 int mv88e6065_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
254                                     int speed, int duplex)
255 {
256         if (speed == SPEED_MAX)
257                 speed = 200;
258
259         if (speed > 200)
260                 return -EOPNOTSUPP;
261
262         /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
263         return mv88e6xxx_port_set_speed_duplex(chip, port, speed, false, false,
264                                                duplex);
265 }
266
267 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
268 int mv88e6185_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
269                                     int speed, int duplex)
270 {
271         if (speed == SPEED_MAX)
272                 speed = 1000;
273
274         if (speed == 200 || speed > 1000)
275                 return -EOPNOTSUPP;
276
277         return mv88e6xxx_port_set_speed_duplex(chip, port, speed, false, false,
278                                                duplex);
279 }
280
281 /* Support 10, 100 Mbps (e.g. 88E6250 family) */
282 int mv88e6250_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
283                                     int speed, int duplex)
284 {
285         if (speed == SPEED_MAX)
286                 speed = 100;
287
288         if (speed > 100)
289                 return -EOPNOTSUPP;
290
291         return mv88e6xxx_port_set_speed_duplex(chip, port, speed, false, false,
292                                                duplex);
293 }
294
295 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
296 int mv88e6341_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
297                                     int speed, int duplex)
298 {
299         if (speed == SPEED_MAX)
300                 speed = port < 5 ? 1000 : 2500;
301
302         if (speed > 2500)
303                 return -EOPNOTSUPP;
304
305         if (speed == 200 && port != 0)
306                 return -EOPNOTSUPP;
307
308         if (speed == 2500 && port < 5)
309                 return -EOPNOTSUPP;
310
311         return mv88e6xxx_port_set_speed_duplex(chip, port, speed, !port, true,
312                                                duplex);
313 }
314
315 phy_interface_t mv88e6341_port_max_speed_mode(int port)
316 {
317         if (port == 5)
318                 return PHY_INTERFACE_MODE_2500BASEX;
319
320         return PHY_INTERFACE_MODE_NA;
321 }
322
323 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
324 int mv88e6352_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
325                                     int speed, int duplex)
326 {
327         if (speed == SPEED_MAX)
328                 speed = 1000;
329
330         if (speed > 1000)
331                 return -EOPNOTSUPP;
332
333         if (speed == 200 && port < 5)
334                 return -EOPNOTSUPP;
335
336         return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, false,
337                                                duplex);
338 }
339
340 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
341 int mv88e6390_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
342                                     int speed, int duplex)
343 {
344         if (speed == SPEED_MAX)
345                 speed = port < 9 ? 1000 : 2500;
346
347         if (speed > 2500)
348                 return -EOPNOTSUPP;
349
350         if (speed == 200 && port != 0)
351                 return -EOPNOTSUPP;
352
353         if (speed == 2500 && port < 9)
354                 return -EOPNOTSUPP;
355
356         return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, true,
357                                                duplex);
358 }
359
360 phy_interface_t mv88e6390_port_max_speed_mode(int port)
361 {
362         if (port == 9 || port == 10)
363                 return PHY_INTERFACE_MODE_2500BASEX;
364
365         return PHY_INTERFACE_MODE_NA;
366 }
367
368 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
369 int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
370                                      int speed, int duplex)
371 {
372         if (speed == SPEED_MAX)
373                 speed = port < 9 ? 1000 : 10000;
374
375         if (speed == 200 && port != 0)
376                 return -EOPNOTSUPP;
377
378         if (speed >= 2500 && port < 9)
379                 return -EOPNOTSUPP;
380
381         return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, true,
382                                                duplex);
383 }
384
385 phy_interface_t mv88e6390x_port_max_speed_mode(int port)
386 {
387         if (port == 9 || port == 10)
388                 return PHY_INTERFACE_MODE_XAUI;
389
390         return PHY_INTERFACE_MODE_NA;
391 }
392
393 static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
394                                     phy_interface_t mode, bool force)
395 {
396         u8 lane;
397         u16 cmode;
398         u16 reg;
399         int err;
400
401         /* Default to a slow mode, so freeing up SERDES interfaces for
402          * other ports which might use them for SFPs.
403          */
404         if (mode == PHY_INTERFACE_MODE_NA)
405                 mode = PHY_INTERFACE_MODE_1000BASEX;
406
407         switch (mode) {
408         case PHY_INTERFACE_MODE_1000BASEX:
409                 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASEX;
410                 break;
411         case PHY_INTERFACE_MODE_SGMII:
412                 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
413                 break;
414         case PHY_INTERFACE_MODE_2500BASEX:
415                 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
416                 break;
417         case PHY_INTERFACE_MODE_XGMII:
418         case PHY_INTERFACE_MODE_XAUI:
419                 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
420                 break;
421         case PHY_INTERFACE_MODE_RXAUI:
422                 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
423                 break;
424         default:
425                 cmode = 0;
426         }
427
428         /* cmode doesn't change, nothing to do for us unless forced */
429         if (cmode == chip->ports[port].cmode && !force)
430                 return 0;
431
432         lane = mv88e6xxx_serdes_get_lane(chip, port);
433         if (lane) {
434                 if (chip->ports[port].serdes_irq) {
435                         err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
436                         if (err)
437                                 return err;
438                 }
439
440                 err = mv88e6xxx_serdes_power_down(chip, port, lane);
441                 if (err)
442                         return err;
443         }
444
445         chip->ports[port].cmode = 0;
446
447         if (cmode) {
448                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
449                 if (err)
450                         return err;
451
452                 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
453                 reg |= cmode;
454
455                 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
456                 if (err)
457                         return err;
458
459                 chip->ports[port].cmode = cmode;
460
461                 lane = mv88e6xxx_serdes_get_lane(chip, port);
462                 if (!lane)
463                         return -ENODEV;
464
465                 err = mv88e6xxx_serdes_power_up(chip, port, lane);
466                 if (err)
467                         return err;
468
469                 if (chip->ports[port].serdes_irq) {
470                         err = mv88e6xxx_serdes_irq_enable(chip, port, lane);
471                         if (err)
472                                 return err;
473                 }
474         }
475
476         return 0;
477 }
478
479 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
480                               phy_interface_t mode)
481 {
482         if (port != 9 && port != 10)
483                 return -EOPNOTSUPP;
484
485         return mv88e6xxx_port_set_cmode(chip, port, mode, false);
486 }
487
488 int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
489                              phy_interface_t mode)
490 {
491         if (port != 9 && port != 10)
492                 return -EOPNOTSUPP;
493
494         switch (mode) {
495         case PHY_INTERFACE_MODE_NA:
496                 return 0;
497         case PHY_INTERFACE_MODE_XGMII:
498         case PHY_INTERFACE_MODE_XAUI:
499         case PHY_INTERFACE_MODE_RXAUI:
500                 return -EINVAL;
501         default:
502                 break;
503         }
504
505         return mv88e6xxx_port_set_cmode(chip, port, mode, false);
506 }
507
508 static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip,
509                                              int port)
510 {
511         int err, addr;
512         u16 reg, bits;
513
514         if (port != 5)
515                 return -EOPNOTSUPP;
516
517         addr = chip->info->port_base_addr + port;
518
519         err = mv88e6xxx_port_hidden_read(chip, 0x7, addr, 0, &reg);
520         if (err)
521                 return err;
522
523         bits = MV88E6341_PORT_RESERVED_1A_FORCE_CMODE |
524                MV88E6341_PORT_RESERVED_1A_SGMII_AN;
525
526         if ((reg & bits) == bits)
527                 return 0;
528
529         reg |= bits;
530         return mv88e6xxx_port_hidden_write(chip, 0x7, addr, 0, reg);
531 }
532
533 int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
534                              phy_interface_t mode)
535 {
536         int err;
537
538         if (port != 5)
539                 return -EOPNOTSUPP;
540
541         switch (mode) {
542         case PHY_INTERFACE_MODE_NA:
543                 return 0;
544         case PHY_INTERFACE_MODE_XGMII:
545         case PHY_INTERFACE_MODE_XAUI:
546         case PHY_INTERFACE_MODE_RXAUI:
547                 return -EINVAL;
548         default:
549                 break;
550         }
551
552         err = mv88e6341_port_set_cmode_writable(chip, port);
553         if (err)
554                 return err;
555
556         return mv88e6xxx_port_set_cmode(chip, port, mode, true);
557 }
558
559 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
560 {
561         int err;
562         u16 reg;
563
564         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
565         if (err)
566                 return err;
567
568         *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
569
570         return 0;
571 }
572
573 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
574 {
575         int err;
576         u16 reg;
577
578         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
579         if (err)
580                 return err;
581
582         *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
583
584         return 0;
585 }
586
587 /* Offset 0x02: Jamming Control
588  *
589  * Do not limit the period of time that this port can be paused for by
590  * the remote end or the period of time that this port can pause the
591  * remote end.
592  */
593 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
594                                u8 out)
595 {
596         return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
597                                     out << 8 | in);
598 }
599
600 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
601                                u8 out)
602 {
603         int err;
604
605         err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
606                                    MV88E6390_PORT_FLOW_CTL_UPDATE |
607                                    MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
608         if (err)
609                 return err;
610
611         return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
612                                     MV88E6390_PORT_FLOW_CTL_UPDATE |
613                                     MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
614 }
615
616 /* Offset 0x04: Port Control Register */
617
618 static const char * const mv88e6xxx_port_state_names[] = {
619         [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
620         [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
621         [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
622         [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
623 };
624
625 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
626 {
627         u16 reg;
628         int err;
629
630         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
631         if (err)
632                 return err;
633
634         reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
635
636         switch (state) {
637         case BR_STATE_DISABLED:
638                 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
639                 break;
640         case BR_STATE_BLOCKING:
641         case BR_STATE_LISTENING:
642                 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
643                 break;
644         case BR_STATE_LEARNING:
645                 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
646                 break;
647         case BR_STATE_FORWARDING:
648                 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
649                 break;
650         default:
651                 return -EINVAL;
652         }
653
654         reg |= state;
655
656         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
657         if (err)
658                 return err;
659
660         dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
661                 mv88e6xxx_port_state_names[state]);
662
663         return 0;
664 }
665
666 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
667                                    enum mv88e6xxx_egress_mode mode)
668 {
669         int err;
670         u16 reg;
671
672         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
673         if (err)
674                 return err;
675
676         reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
677
678         switch (mode) {
679         case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
680                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
681                 break;
682         case MV88E6XXX_EGRESS_MODE_UNTAGGED:
683                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
684                 break;
685         case MV88E6XXX_EGRESS_MODE_TAGGED:
686                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
687                 break;
688         case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
689                 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
690                 break;
691         default:
692                 return -EINVAL;
693         }
694
695         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
696 }
697
698 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
699                                   enum mv88e6xxx_frame_mode mode)
700 {
701         int err;
702         u16 reg;
703
704         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
705         if (err)
706                 return err;
707
708         reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
709
710         switch (mode) {
711         case MV88E6XXX_FRAME_MODE_NORMAL:
712                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
713                 break;
714         case MV88E6XXX_FRAME_MODE_DSA:
715                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
716                 break;
717         default:
718                 return -EINVAL;
719         }
720
721         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
722 }
723
724 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
725                                   enum mv88e6xxx_frame_mode mode)
726 {
727         int err;
728         u16 reg;
729
730         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
731         if (err)
732                 return err;
733
734         reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
735
736         switch (mode) {
737         case MV88E6XXX_FRAME_MODE_NORMAL:
738                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
739                 break;
740         case MV88E6XXX_FRAME_MODE_DSA:
741                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
742                 break;
743         case MV88E6XXX_FRAME_MODE_PROVIDER:
744                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
745                 break;
746         case MV88E6XXX_FRAME_MODE_ETHERTYPE:
747                 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
748                 break;
749         default:
750                 return -EINVAL;
751         }
752
753         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
754 }
755
756 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
757                                               int port, bool unicast)
758 {
759         int err;
760         u16 reg;
761
762         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
763         if (err)
764                 return err;
765
766         if (unicast)
767                 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
768         else
769                 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
770
771         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
772 }
773
774 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
775                                      bool unicast, bool multicast)
776 {
777         int err;
778         u16 reg;
779
780         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
781         if (err)
782                 return err;
783
784         reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
785
786         if (unicast && multicast)
787                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
788         else if (unicast)
789                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
790         else if (multicast)
791                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
792         else
793                 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
794
795         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
796 }
797
798 /* Offset 0x05: Port Control 1 */
799
800 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
801                                     bool message_port)
802 {
803         u16 val;
804         int err;
805
806         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
807         if (err)
808                 return err;
809
810         if (message_port)
811                 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
812         else
813                 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
814
815         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
816 }
817
818 /* Offset 0x06: Port Based VLAN Map */
819
820 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
821 {
822         const u16 mask = mv88e6xxx_port_mask(chip);
823         u16 reg;
824         int err;
825
826         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
827         if (err)
828                 return err;
829
830         reg &= ~mask;
831         reg |= map & mask;
832
833         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
834         if (err)
835                 return err;
836
837         dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
838
839         return 0;
840 }
841
842 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
843 {
844         const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
845         u16 reg;
846         int err;
847
848         /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
849         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
850         if (err)
851                 return err;
852
853         *fid = (reg & 0xf000) >> 12;
854
855         /* Port's default FID upper bits are located in reg 0x05, offset 0 */
856         if (upper_mask) {
857                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
858                                           &reg);
859                 if (err)
860                         return err;
861
862                 *fid |= (reg & upper_mask) << 4;
863         }
864
865         return 0;
866 }
867
868 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
869 {
870         const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
871         u16 reg;
872         int err;
873
874         if (fid >= mv88e6xxx_num_databases(chip))
875                 return -EINVAL;
876
877         /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
878         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
879         if (err)
880                 return err;
881
882         reg &= 0x0fff;
883         reg |= (fid & 0x000f) << 12;
884
885         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
886         if (err)
887                 return err;
888
889         /* Port's default FID upper bits are located in reg 0x05, offset 0 */
890         if (upper_mask) {
891                 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
892                                           &reg);
893                 if (err)
894                         return err;
895
896                 reg &= ~upper_mask;
897                 reg |= (fid >> 4) & upper_mask;
898
899                 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
900                                            reg);
901                 if (err)
902                         return err;
903         }
904
905         dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
906
907         return 0;
908 }
909
910 /* Offset 0x07: Default Port VLAN ID & Priority */
911
912 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
913 {
914         u16 reg;
915         int err;
916
917         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
918                                   &reg);
919         if (err)
920                 return err;
921
922         *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
923
924         return 0;
925 }
926
927 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
928 {
929         u16 reg;
930         int err;
931
932         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
933                                   &reg);
934         if (err)
935                 return err;
936
937         reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
938         reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
939
940         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
941                                    reg);
942         if (err)
943                 return err;
944
945         dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
946
947         return 0;
948 }
949
950 /* Offset 0x08: Port Control 2 Register */
951
952 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
953         [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
954         [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
955         [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
956         [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
957 };
958
959 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
960                                               int port, bool multicast)
961 {
962         int err;
963         u16 reg;
964
965         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
966         if (err)
967                 return err;
968
969         if (multicast)
970                 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
971         else
972                 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
973
974         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
975 }
976
977 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
978                                      bool unicast, bool multicast)
979 {
980         int err;
981
982         err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
983         if (err)
984                 return err;
985
986         return mv88e6185_port_set_default_forward(chip, port, multicast);
987 }
988
989 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
990                                      int upstream_port)
991 {
992         int err;
993         u16 reg;
994
995         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
996         if (err)
997                 return err;
998
999         reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
1000         reg |= upstream_port;
1001
1002         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1003 }
1004
1005 int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
1006                               enum mv88e6xxx_egress_direction direction,
1007                               bool mirror)
1008 {
1009         bool *mirror_port;
1010         u16 reg;
1011         u16 bit;
1012         int err;
1013
1014         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1015         if (err)
1016                 return err;
1017
1018         switch (direction) {
1019         case MV88E6XXX_EGRESS_DIR_INGRESS:
1020                 bit = MV88E6XXX_PORT_CTL2_INGRESS_MONITOR;
1021                 mirror_port = &chip->ports[port].mirror_ingress;
1022                 break;
1023         case MV88E6XXX_EGRESS_DIR_EGRESS:
1024                 bit = MV88E6XXX_PORT_CTL2_EGRESS_MONITOR;
1025                 mirror_port = &chip->ports[port].mirror_egress;
1026                 break;
1027         default:
1028                 return -EINVAL;
1029         }
1030
1031         reg &= ~bit;
1032         if (mirror)
1033                 reg |= bit;
1034
1035         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1036         if (!err)
1037                 *mirror_port = mirror;
1038
1039         return err;
1040 }
1041
1042 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
1043                                   u16 mode)
1044 {
1045         u16 reg;
1046         int err;
1047
1048         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1049         if (err)
1050                 return err;
1051
1052         reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
1053         reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
1054
1055         err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1056         if (err)
1057                 return err;
1058
1059         dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
1060                 mv88e6xxx_port_8021q_mode_names[mode]);
1061
1062         return 0;
1063 }
1064
1065 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
1066 {
1067         u16 reg;
1068         int err;
1069
1070         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1071         if (err)
1072                 return err;
1073
1074         reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
1075
1076         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1077 }
1078
1079 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
1080                                   size_t size)
1081 {
1082         u16 reg;
1083         int err;
1084
1085         size += VLAN_ETH_HLEN + ETH_FCS_LEN;
1086
1087         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1088         if (err)
1089                 return err;
1090
1091         reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
1092
1093         if (size <= 1522)
1094                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
1095         else if (size <= 2048)
1096                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
1097         else if (size <= 10240)
1098                 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
1099         else
1100                 return -ERANGE;
1101
1102         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1103 }
1104
1105 /* Offset 0x09: Port Rate Control */
1106
1107 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1108 {
1109         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1110                                     0x0000);
1111 }
1112
1113 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1114 {
1115         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1116                                     0x0001);
1117 }
1118
1119 /* Offset 0x0C: Port ATU Control */
1120
1121 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
1122 {
1123         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
1124 }
1125
1126 /* Offset 0x0D: (Priority) Override Register */
1127
1128 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
1129 {
1130         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
1131 }
1132
1133 /* Offset 0x0f: Port Ether type */
1134
1135 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1136                                   u16 etype)
1137 {
1138         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
1139 }
1140
1141 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1142  * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1143  */
1144
1145 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1146 {
1147         int err;
1148
1149         /* Use a direct priority mapping for all IEEE tagged frames */
1150         err = mv88e6xxx_port_write(chip, port,
1151                                    MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
1152                                    0x3210);
1153         if (err)
1154                 return err;
1155
1156         return mv88e6xxx_port_write(chip, port,
1157                                     MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
1158                                     0x7654);
1159 }
1160
1161 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
1162                                         int port, u16 table, u8 ptr, u16 data)
1163 {
1164         u16 reg;
1165
1166         reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
1167                 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
1168                 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
1169
1170         return mv88e6xxx_port_write(chip, port,
1171                                     MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
1172 }
1173
1174 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1175 {
1176         int err, i;
1177         u16 table;
1178
1179         for (i = 0; i <= 7; i++) {
1180                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
1181                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1182                                                    (i | i << 4));
1183                 if (err)
1184                         return err;
1185
1186                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1187                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1188                 if (err)
1189                         return err;
1190
1191                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1192                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1193                 if (err)
1194                         return err;
1195
1196                 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1197                 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1198                 if (err)
1199                         return err;
1200         }
1201
1202         return 0;
1203 }
1204
1205 /* Offset 0x0E: Policy Control Register */
1206
1207 int mv88e6352_port_set_policy(struct mv88e6xxx_chip *chip, int port,
1208                               enum mv88e6xxx_policy_mapping mapping,
1209                               enum mv88e6xxx_policy_action action)
1210 {
1211         u16 reg, mask, val;
1212         int shift;
1213         int err;
1214
1215         switch (mapping) {
1216         case MV88E6XXX_POLICY_MAPPING_DA:
1217                 shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_DA_MASK);
1218                 mask = MV88E6XXX_PORT_POLICY_CTL_DA_MASK;
1219                 break;
1220         case MV88E6XXX_POLICY_MAPPING_SA:
1221                 shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_SA_MASK);
1222                 mask = MV88E6XXX_PORT_POLICY_CTL_SA_MASK;
1223                 break;
1224         case MV88E6XXX_POLICY_MAPPING_VTU:
1225                 shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VTU_MASK);
1226                 mask = MV88E6XXX_PORT_POLICY_CTL_VTU_MASK;
1227                 break;
1228         case MV88E6XXX_POLICY_MAPPING_ETYPE:
1229                 shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK);
1230                 mask = MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK;
1231                 break;
1232         case MV88E6XXX_POLICY_MAPPING_PPPOE:
1233                 shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK);
1234                 mask = MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK;
1235                 break;
1236         case MV88E6XXX_POLICY_MAPPING_VBAS:
1237                 shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK);
1238                 mask = MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK;
1239                 break;
1240         case MV88E6XXX_POLICY_MAPPING_OPT82:
1241                 shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK);
1242                 mask = MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK;
1243                 break;
1244         case MV88E6XXX_POLICY_MAPPING_UDP:
1245                 shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_UDP_MASK);
1246                 mask = MV88E6XXX_PORT_POLICY_CTL_UDP_MASK;
1247                 break;
1248         default:
1249                 return -EOPNOTSUPP;
1250         }
1251
1252         switch (action) {
1253         case MV88E6XXX_POLICY_ACTION_NORMAL:
1254                 val = MV88E6XXX_PORT_POLICY_CTL_NORMAL;
1255                 break;
1256         case MV88E6XXX_POLICY_ACTION_MIRROR:
1257                 val = MV88E6XXX_PORT_POLICY_CTL_MIRROR;
1258                 break;
1259         case MV88E6XXX_POLICY_ACTION_TRAP:
1260                 val = MV88E6XXX_PORT_POLICY_CTL_TRAP;
1261                 break;
1262         case MV88E6XXX_POLICY_ACTION_DISCARD:
1263                 val = MV88E6XXX_PORT_POLICY_CTL_DISCARD;
1264                 break;
1265         default:
1266                 return -EOPNOTSUPP;
1267         }
1268
1269         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_POLICY_CTL, &reg);
1270         if (err)
1271                 return err;
1272
1273         reg &= ~mask;
1274         reg |= (val << shift) & mask;
1275
1276         return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_POLICY_CTL, reg);
1277 }