xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/port.c (revision 2d2e1dd2)
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 	chip->ports[port].cmode = cmode;
389 
390 	return 0;
391 }
392 
393 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
394 {
395 	int err;
396 	u16 reg;
397 
398 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
399 	if (err)
400 		return err;
401 
402 	*cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
403 
404 	return 0;
405 }
406 
407 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
408 {
409 	int err;
410 	u16 reg;
411 
412 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
413 	if (err)
414 		return err;
415 
416 	*cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
417 
418 	return 0;
419 }
420 
421 int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
422 			      struct phylink_link_state *state)
423 {
424 	int err;
425 	u16 reg;
426 
427 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
428 	if (err)
429 		return err;
430 
431 	switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
432 	case MV88E6XXX_PORT_STS_SPEED_10:
433 		state->speed = SPEED_10;
434 		break;
435 	case MV88E6XXX_PORT_STS_SPEED_100:
436 		state->speed = SPEED_100;
437 		break;
438 	case MV88E6XXX_PORT_STS_SPEED_1000:
439 		state->speed = SPEED_1000;
440 		break;
441 	case MV88E6XXX_PORT_STS_SPEED_10000:
442 		if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
443 		    MV88E6XXX_PORT_STS_CMODE_2500BASEX)
444 			state->speed = SPEED_2500;
445 		else
446 			state->speed = SPEED_10000;
447 		break;
448 	}
449 
450 	state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
451 			DUPLEX_FULL : DUPLEX_HALF;
452 	state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
453 	state->an_enabled = 1;
454 	state->an_complete = state->link;
455 
456 	return 0;
457 }
458 
459 int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
460 			      struct phylink_link_state *state)
461 {
462 	if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
463 		u8 cmode = chip->ports[port].cmode;
464 
465 		/* When a port is in "Cross-chip serdes" mode, it uses
466 		 * 1000Base-X full duplex mode, but there is no automatic
467 		 * link detection. Use the sync OK status for link (as it
468 		 * would do for 1000Base-X mode.)
469 		 */
470 		if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
471 			u16 mac;
472 			int err;
473 
474 			err = mv88e6xxx_port_read(chip, port,
475 						  MV88E6XXX_PORT_MAC_CTL, &mac);
476 			if (err)
477 				return err;
478 
479 			state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
480 			state->an_enabled = 1;
481 			state->an_complete =
482 				!!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
483 			state->duplex =
484 				state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
485 			state->speed =
486 				state->link ? SPEED_1000 : SPEED_UNKNOWN;
487 
488 			return 0;
489 		}
490 	}
491 
492 	return mv88e6352_port_link_state(chip, port, state);
493 }
494 
495 /* Offset 0x02: Jamming Control
496  *
497  * Do not limit the period of time that this port can be paused for by
498  * the remote end or the period of time that this port can pause the
499  * remote end.
500  */
501 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
502 			       u8 out)
503 {
504 	return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
505 				    out << 8 | in);
506 }
507 
508 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
509 			       u8 out)
510 {
511 	int err;
512 
513 	err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
514 				   MV88E6390_PORT_FLOW_CTL_UPDATE |
515 				   MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
516 	if (err)
517 		return err;
518 
519 	return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
520 				    MV88E6390_PORT_FLOW_CTL_UPDATE |
521 				    MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
522 }
523 
524 /* Offset 0x04: Port Control Register */
525 
526 static const char * const mv88e6xxx_port_state_names[] = {
527 	[MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
528 	[MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
529 	[MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
530 	[MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
531 };
532 
533 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
534 {
535 	u16 reg;
536 	int err;
537 
538 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
539 	if (err)
540 		return err;
541 
542 	reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
543 
544 	switch (state) {
545 	case BR_STATE_DISABLED:
546 		state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
547 		break;
548 	case BR_STATE_BLOCKING:
549 	case BR_STATE_LISTENING:
550 		state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
551 		break;
552 	case BR_STATE_LEARNING:
553 		state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
554 		break;
555 	case BR_STATE_FORWARDING:
556 		state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
557 		break;
558 	default:
559 		return -EINVAL;
560 	}
561 
562 	reg |= state;
563 
564 	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
565 	if (err)
566 		return err;
567 
568 	dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
569 		mv88e6xxx_port_state_names[state]);
570 
571 	return 0;
572 }
573 
574 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
575 				   enum mv88e6xxx_egress_mode mode)
576 {
577 	int err;
578 	u16 reg;
579 
580 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
581 	if (err)
582 		return err;
583 
584 	reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
585 
586 	switch (mode) {
587 	case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
588 		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
589 		break;
590 	case MV88E6XXX_EGRESS_MODE_UNTAGGED:
591 		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
592 		break;
593 	case MV88E6XXX_EGRESS_MODE_TAGGED:
594 		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
595 		break;
596 	case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
597 		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
598 		break;
599 	default:
600 		return -EINVAL;
601 	}
602 
603 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
604 }
605 
606 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
607 				  enum mv88e6xxx_frame_mode mode)
608 {
609 	int err;
610 	u16 reg;
611 
612 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
613 	if (err)
614 		return err;
615 
616 	reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
617 
618 	switch (mode) {
619 	case MV88E6XXX_FRAME_MODE_NORMAL:
620 		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
621 		break;
622 	case MV88E6XXX_FRAME_MODE_DSA:
623 		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
624 		break;
625 	default:
626 		return -EINVAL;
627 	}
628 
629 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
630 }
631 
632 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
633 				  enum mv88e6xxx_frame_mode mode)
634 {
635 	int err;
636 	u16 reg;
637 
638 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
639 	if (err)
640 		return err;
641 
642 	reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
643 
644 	switch (mode) {
645 	case MV88E6XXX_FRAME_MODE_NORMAL:
646 		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
647 		break;
648 	case MV88E6XXX_FRAME_MODE_DSA:
649 		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
650 		break;
651 	case MV88E6XXX_FRAME_MODE_PROVIDER:
652 		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
653 		break;
654 	case MV88E6XXX_FRAME_MODE_ETHERTYPE:
655 		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
656 		break;
657 	default:
658 		return -EINVAL;
659 	}
660 
661 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
662 }
663 
664 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
665 					      int port, bool unicast)
666 {
667 	int err;
668 	u16 reg;
669 
670 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
671 	if (err)
672 		return err;
673 
674 	if (unicast)
675 		reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
676 	else
677 		reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
678 
679 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
680 }
681 
682 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
683 				     bool unicast, bool multicast)
684 {
685 	int err;
686 	u16 reg;
687 
688 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
689 	if (err)
690 		return err;
691 
692 	reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
693 
694 	if (unicast && multicast)
695 		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
696 	else if (unicast)
697 		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
698 	else if (multicast)
699 		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
700 	else
701 		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
702 
703 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
704 }
705 
706 /* Offset 0x05: Port Control 1 */
707 
708 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
709 				    bool message_port)
710 {
711 	u16 val;
712 	int err;
713 
714 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
715 	if (err)
716 		return err;
717 
718 	if (message_port)
719 		val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
720 	else
721 		val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
722 
723 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
724 }
725 
726 /* Offset 0x06: Port Based VLAN Map */
727 
728 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
729 {
730 	const u16 mask = mv88e6xxx_port_mask(chip);
731 	u16 reg;
732 	int err;
733 
734 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
735 	if (err)
736 		return err;
737 
738 	reg &= ~mask;
739 	reg |= map & mask;
740 
741 	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
742 	if (err)
743 		return err;
744 
745 	dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
746 
747 	return 0;
748 }
749 
750 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
751 {
752 	const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
753 	u16 reg;
754 	int err;
755 
756 	/* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
757 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
758 	if (err)
759 		return err;
760 
761 	*fid = (reg & 0xf000) >> 12;
762 
763 	/* Port's default FID upper bits are located in reg 0x05, offset 0 */
764 	if (upper_mask) {
765 		err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
766 					  &reg);
767 		if (err)
768 			return err;
769 
770 		*fid |= (reg & upper_mask) << 4;
771 	}
772 
773 	return 0;
774 }
775 
776 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
777 {
778 	const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
779 	u16 reg;
780 	int err;
781 
782 	if (fid >= mv88e6xxx_num_databases(chip))
783 		return -EINVAL;
784 
785 	/* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
786 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
787 	if (err)
788 		return err;
789 
790 	reg &= 0x0fff;
791 	reg |= (fid & 0x000f) << 12;
792 
793 	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
794 	if (err)
795 		return err;
796 
797 	/* Port's default FID upper bits are located in reg 0x05, offset 0 */
798 	if (upper_mask) {
799 		err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
800 					  &reg);
801 		if (err)
802 			return err;
803 
804 		reg &= ~upper_mask;
805 		reg |= (fid >> 4) & upper_mask;
806 
807 		err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
808 					   reg);
809 		if (err)
810 			return err;
811 	}
812 
813 	dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
814 
815 	return 0;
816 }
817 
818 /* Offset 0x07: Default Port VLAN ID & Priority */
819 
820 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
821 {
822 	u16 reg;
823 	int err;
824 
825 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
826 				  &reg);
827 	if (err)
828 		return err;
829 
830 	*pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
831 
832 	return 0;
833 }
834 
835 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
836 {
837 	u16 reg;
838 	int err;
839 
840 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
841 				  &reg);
842 	if (err)
843 		return err;
844 
845 	reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
846 	reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
847 
848 	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
849 				   reg);
850 	if (err)
851 		return err;
852 
853 	dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
854 
855 	return 0;
856 }
857 
858 /* Offset 0x08: Port Control 2 Register */
859 
860 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
861 	[MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
862 	[MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
863 	[MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
864 	[MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
865 };
866 
867 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
868 					      int port, bool multicast)
869 {
870 	int err;
871 	u16 reg;
872 
873 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
874 	if (err)
875 		return err;
876 
877 	if (multicast)
878 		reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
879 	else
880 		reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
881 
882 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
883 }
884 
885 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
886 				     bool unicast, bool multicast)
887 {
888 	int err;
889 
890 	err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
891 	if (err)
892 		return err;
893 
894 	return mv88e6185_port_set_default_forward(chip, port, multicast);
895 }
896 
897 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
898 				     int upstream_port)
899 {
900 	int err;
901 	u16 reg;
902 
903 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
904 	if (err)
905 		return err;
906 
907 	reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
908 	reg |= upstream_port;
909 
910 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
911 }
912 
913 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
914 				  u16 mode)
915 {
916 	u16 reg;
917 	int err;
918 
919 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
920 	if (err)
921 		return err;
922 
923 	reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
924 	reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
925 
926 	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
927 	if (err)
928 		return err;
929 
930 	dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
931 		mv88e6xxx_port_8021q_mode_names[mode]);
932 
933 	return 0;
934 }
935 
936 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
937 {
938 	u16 reg;
939 	int err;
940 
941 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
942 	if (err)
943 		return err;
944 
945 	reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
946 
947 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
948 }
949 
950 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
951 				  size_t size)
952 {
953 	u16 reg;
954 	int err;
955 
956 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
957 	if (err)
958 		return err;
959 
960 	reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
961 
962 	if (size <= 1522)
963 		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
964 	else if (size <= 2048)
965 		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
966 	else if (size <= 10240)
967 		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
968 	else
969 		return -ERANGE;
970 
971 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
972 }
973 
974 /* Offset 0x09: Port Rate Control */
975 
976 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
977 {
978 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
979 				    0x0000);
980 }
981 
982 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
983 {
984 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
985 				    0x0001);
986 }
987 
988 /* Offset 0x0C: Port ATU Control */
989 
990 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
991 {
992 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
993 }
994 
995 /* Offset 0x0D: (Priority) Override Register */
996 
997 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
998 {
999 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
1000 }
1001 
1002 /* Offset 0x0f: Port Ether type */
1003 
1004 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1005 				  u16 etype)
1006 {
1007 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
1008 }
1009 
1010 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1011  * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1012  */
1013 
1014 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1015 {
1016 	int err;
1017 
1018 	/* Use a direct priority mapping for all IEEE tagged frames */
1019 	err = mv88e6xxx_port_write(chip, port,
1020 				   MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
1021 				   0x3210);
1022 	if (err)
1023 		return err;
1024 
1025 	return mv88e6xxx_port_write(chip, port,
1026 				    MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
1027 				    0x7654);
1028 }
1029 
1030 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
1031 					int port, u16 table, u8 ptr, u16 data)
1032 {
1033 	u16 reg;
1034 
1035 	reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
1036 		(ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
1037 		(data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
1038 
1039 	return mv88e6xxx_port_write(chip, port,
1040 				    MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
1041 }
1042 
1043 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1044 {
1045 	int err, i;
1046 	u16 table;
1047 
1048 	for (i = 0; i <= 7; i++) {
1049 		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
1050 		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1051 						   (i | i << 4));
1052 		if (err)
1053 			return err;
1054 
1055 		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1056 		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1057 		if (err)
1058 			return err;
1059 
1060 		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1061 		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1062 		if (err)
1063 			return err;
1064 
1065 		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1066 		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1067 		if (err)
1068 			return err;
1069 	}
1070 
1071 	return 0;
1072 }
1073