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