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