xref: /linux/drivers/net/dsa/mv88e6xxx/global2.c (revision e58e871becec2d3b04ed91c0c16fe8deac9c9dfa)
1 /*
2  * Marvell 88E6xxx Switch Global 2 Registers support (device address
3  * 0x1C)
4  *
5  * Copyright (c) 2008 Marvell Semiconductor
6  *
7  * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
8  *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  */
15 
16 #include <linux/interrupt.h>
17 #include <linux/irqdomain.h>
18 #include "mv88e6xxx.h"
19 #include "global2.h"
20 
21 #define ADDR_GLOBAL2	0x1c
22 
23 static int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
24 {
25 	return mv88e6xxx_read(chip, ADDR_GLOBAL2, reg, val);
26 }
27 
28 static int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
29 {
30 	return mv88e6xxx_write(chip, ADDR_GLOBAL2, reg, val);
31 }
32 
33 static int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
34 {
35 	return mv88e6xxx_update(chip, ADDR_GLOBAL2, reg, update);
36 }
37 
38 static int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
39 {
40 	return mv88e6xxx_wait(chip, ADDR_GLOBAL2, reg, mask);
41 }
42 
43 /* Offset 0x02: Management Enable 2x */
44 /* Offset 0x03: Management Enable 0x */
45 
46 int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
47 {
48 	int err;
49 
50 	/* Consider the frames with reserved multicast destination
51 	 * addresses matching 01:80:c2:00:00:2x as MGMT.
52 	 */
53 	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) {
54 		err = mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_2X, 0xffff);
55 		if (err)
56 			return err;
57 	}
58 
59 	/* Consider the frames with reserved multicast destination
60 	 * addresses matching 01:80:c2:00:00:0x as MGMT.
61 	 */
62 	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X))
63 		return mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_0X, 0xffff);
64 
65 	return 0;
66 }
67 
68 /* Offset 0x06: Device Mapping Table register */
69 
70 static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip,
71 					     int target, int port)
72 {
73 	u16 val = (target << 8) | (port & 0xf);
74 
75 	return mv88e6xxx_g2_update(chip, GLOBAL2_DEVICE_MAPPING, val);
76 }
77 
78 static int mv88e6xxx_g2_set_device_mapping(struct mv88e6xxx_chip *chip)
79 {
80 	int target, port;
81 	int err;
82 
83 	/* Initialize the routing port to the 32 possible target devices */
84 	for (target = 0; target < 32; ++target) {
85 		port = 0xf;
86 
87 		if (target < DSA_MAX_SWITCHES) {
88 			port = chip->ds->rtable[target];
89 			if (port == DSA_RTABLE_NONE)
90 				port = 0xf;
91 		}
92 
93 		err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
94 		if (err)
95 			break;
96 	}
97 
98 	return err;
99 }
100 
101 /* Offset 0x07: Trunk Mask Table register */
102 
103 static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
104 					 bool hask, u16 mask)
105 {
106 	const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
107 	u16 val = (num << 12) | (mask & port_mask);
108 
109 	if (hask)
110 		val |= GLOBAL2_TRUNK_MASK_HASK;
111 
112 	return mv88e6xxx_g2_update(chip, GLOBAL2_TRUNK_MASK, val);
113 }
114 
115 /* Offset 0x08: Trunk Mapping Table register */
116 
117 static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
118 					    u16 map)
119 {
120 	const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
121 	u16 val = (id << 11) | (map & port_mask);
122 
123 	return mv88e6xxx_g2_update(chip, GLOBAL2_TRUNK_MAPPING, val);
124 }
125 
126 static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip)
127 {
128 	const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
129 	int i, err;
130 
131 	/* Clear all eight possible Trunk Mask vectors */
132 	for (i = 0; i < 8; ++i) {
133 		err = mv88e6xxx_g2_trunk_mask_write(chip, i, false, port_mask);
134 		if (err)
135 			return err;
136 	}
137 
138 	/* Clear all sixteen possible Trunk ID routing vectors */
139 	for (i = 0; i < 16; ++i) {
140 		err = mv88e6xxx_g2_trunk_mapping_write(chip, i, 0);
141 		if (err)
142 			return err;
143 	}
144 
145 	return 0;
146 }
147 
148 /* Offset 0x09: Ingress Rate Command register
149  * Offset 0x0A: Ingress Rate Data register
150  */
151 
152 static int mv88e6xxx_g2_clear_irl(struct mv88e6xxx_chip *chip)
153 {
154 	int port, err;
155 
156 	/* Init all Ingress Rate Limit resources of all ports */
157 	for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
158 		/* XXX newer chips (like 88E6390) have different 2-bit ops */
159 		err = mv88e6xxx_g2_write(chip, GLOBAL2_IRL_CMD,
160 					 GLOBAL2_IRL_CMD_OP_INIT_ALL |
161 					 (port << 8));
162 		if (err)
163 			break;
164 
165 		/* Wait for the operation to complete */
166 		err = mv88e6xxx_g2_wait(chip, GLOBAL2_IRL_CMD,
167 					GLOBAL2_IRL_CMD_BUSY);
168 		if (err)
169 			break;
170 	}
171 
172 	return err;
173 }
174 
175 /* Offset 0x0B: Cross-chip Port VLAN (Addr) Register
176  * Offset 0x0C: Cross-chip Port VLAN Data Register
177  */
178 
179 static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
180 {
181 	return mv88e6xxx_g2_wait(chip, GLOBAL2_PVT_ADDR, GLOBAL2_PVT_ADDR_BUSY);
182 }
183 
184 static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
185 			       int src_port, u16 op)
186 {
187 	int err;
188 
189 	/* 9-bit Cross-chip PVT pointer: with GLOBAL2_MISC_5_BIT_PORT cleared,
190 	 * source device is 5-bit, source port is 4-bit.
191 	 */
192 	op |= (src_dev & 0x1f) << 4;
193 	op |= (src_port & 0xf);
194 
195 	err = mv88e6xxx_g2_write(chip, GLOBAL2_PVT_ADDR, op);
196 	if (err)
197 		return err;
198 
199 	return mv88e6xxx_g2_pvt_op_wait(chip);
200 }
201 
202 int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
203 			   int src_port, u16 data)
204 {
205 	int err;
206 
207 	err = mv88e6xxx_g2_pvt_op_wait(chip);
208 	if (err)
209 		return err;
210 
211 	err = mv88e6xxx_g2_write(chip, GLOBAL2_PVT_DATA, data);
212 	if (err)
213 		return err;
214 
215 	return mv88e6xxx_g2_pvt_op(chip, src_dev, src_port,
216 				   GLOBAL2_PVT_ADDR_OP_WRITE_PVLAN);
217 }
218 
219 /* Offset 0x0D: Switch MAC/WoL/WoF register */
220 
221 static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
222 					 unsigned int pointer, u8 data)
223 {
224 	u16 val = (pointer << 8) | data;
225 
226 	return mv88e6xxx_g2_update(chip, GLOBAL2_SWITCH_MAC, val);
227 }
228 
229 int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
230 {
231 	int i, err;
232 
233 	for (i = 0; i < 6; i++) {
234 		err = mv88e6xxx_g2_switch_mac_write(chip, i, addr[i]);
235 		if (err)
236 			break;
237 	}
238 
239 	return err;
240 }
241 
242 /* Offset 0x0F: Priority Override Table */
243 
244 static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
245 				  u8 data)
246 {
247 	u16 val = (pointer << 8) | (data & 0x7);
248 
249 	return mv88e6xxx_g2_update(chip, GLOBAL2_PRIO_OVERRIDE, val);
250 }
251 
252 static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip)
253 {
254 	int i, err;
255 
256 	/* Clear all sixteen possible Priority Override entries */
257 	for (i = 0; i < 16; i++) {
258 		err = mv88e6xxx_g2_pot_write(chip, i, 0);
259 		if (err)
260 			break;
261 	}
262 
263 	return err;
264 }
265 
266 /* Offset 0x14: EEPROM Command
267  * Offset 0x15: EEPROM Data (for 16-bit data access)
268  * Offset 0x15: EEPROM Addr (for 8-bit data access)
269  */
270 
271 static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
272 {
273 	return mv88e6xxx_g2_wait(chip, GLOBAL2_EEPROM_CMD,
274 				 GLOBAL2_EEPROM_CMD_BUSY |
275 				 GLOBAL2_EEPROM_CMD_RUNNING);
276 }
277 
278 static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
279 {
280 	int err;
281 
282 	err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_CMD, cmd);
283 	if (err)
284 		return err;
285 
286 	return mv88e6xxx_g2_eeprom_wait(chip);
287 }
288 
289 static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
290 				     u16 addr, u8 *data)
291 {
292 	u16 cmd = GLOBAL2_EEPROM_CMD_OP_READ;
293 	int err;
294 
295 	err = mv88e6xxx_g2_eeprom_wait(chip);
296 	if (err)
297 		return err;
298 
299 	err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_ADDR, addr);
300 	if (err)
301 		return err;
302 
303 	err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
304 	if (err)
305 		return err;
306 
307 	err = mv88e6xxx_g2_read(chip, GLOBAL2_EEPROM_CMD, &cmd);
308 	if (err)
309 		return err;
310 
311 	*data = cmd & 0xff;
312 
313 	return 0;
314 }
315 
316 static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
317 				      u16 addr, u8 data)
318 {
319 	u16 cmd = GLOBAL2_EEPROM_CMD_OP_WRITE | GLOBAL2_EEPROM_CMD_WRITE_EN;
320 	int err;
321 
322 	err = mv88e6xxx_g2_eeprom_wait(chip);
323 	if (err)
324 		return err;
325 
326 	err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_ADDR, addr);
327 	if (err)
328 		return err;
329 
330 	return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
331 }
332 
333 static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
334 				      u8 addr, u16 *data)
335 {
336 	u16 cmd = GLOBAL2_EEPROM_CMD_OP_READ | addr;
337 	int err;
338 
339 	err = mv88e6xxx_g2_eeprom_wait(chip);
340 	if (err)
341 		return err;
342 
343 	err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
344 	if (err)
345 		return err;
346 
347 	return mv88e6xxx_g2_read(chip, GLOBAL2_EEPROM_DATA, data);
348 }
349 
350 static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
351 				       u8 addr, u16 data)
352 {
353 	u16 cmd = GLOBAL2_EEPROM_CMD_OP_WRITE | addr;
354 	int err;
355 
356 	err = mv88e6xxx_g2_eeprom_wait(chip);
357 	if (err)
358 		return err;
359 
360 	err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_DATA, data);
361 	if (err)
362 		return err;
363 
364 	return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
365 }
366 
367 int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
368 			     struct ethtool_eeprom *eeprom, u8 *data)
369 {
370 	unsigned int offset = eeprom->offset;
371 	unsigned int len = eeprom->len;
372 	int err;
373 
374 	eeprom->len = 0;
375 
376 	while (len) {
377 		err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
378 		if (err)
379 			return err;
380 
381 		eeprom->len++;
382 		offset++;
383 		data++;
384 		len--;
385 	}
386 
387 	return 0;
388 }
389 
390 int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
391 			     struct ethtool_eeprom *eeprom, u8 *data)
392 {
393 	unsigned int offset = eeprom->offset;
394 	unsigned int len = eeprom->len;
395 	int err;
396 
397 	eeprom->len = 0;
398 
399 	while (len) {
400 		err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
401 		if (err)
402 			return err;
403 
404 		eeprom->len++;
405 		offset++;
406 		data++;
407 		len--;
408 	}
409 
410 	return 0;
411 }
412 
413 int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
414 			      struct ethtool_eeprom *eeprom, u8 *data)
415 {
416 	unsigned int offset = eeprom->offset;
417 	unsigned int len = eeprom->len;
418 	u16 val;
419 	int err;
420 
421 	eeprom->len = 0;
422 
423 	if (offset & 1) {
424 		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
425 		if (err)
426 			return err;
427 
428 		*data++ = (val >> 8) & 0xff;
429 
430 		offset++;
431 		len--;
432 		eeprom->len++;
433 	}
434 
435 	while (len >= 2) {
436 		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
437 		if (err)
438 			return err;
439 
440 		*data++ = val & 0xff;
441 		*data++ = (val >> 8) & 0xff;
442 
443 		offset += 2;
444 		len -= 2;
445 		eeprom->len += 2;
446 	}
447 
448 	if (len) {
449 		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
450 		if (err)
451 			return err;
452 
453 		*data++ = val & 0xff;
454 
455 		offset++;
456 		len--;
457 		eeprom->len++;
458 	}
459 
460 	return 0;
461 }
462 
463 int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
464 			      struct ethtool_eeprom *eeprom, u8 *data)
465 {
466 	unsigned int offset = eeprom->offset;
467 	unsigned int len = eeprom->len;
468 	u16 val;
469 	int err;
470 
471 	/* Ensure the RO WriteEn bit is set */
472 	err = mv88e6xxx_g2_read(chip, GLOBAL2_EEPROM_CMD, &val);
473 	if (err)
474 		return err;
475 
476 	if (!(val & GLOBAL2_EEPROM_CMD_WRITE_EN))
477 		return -EROFS;
478 
479 	eeprom->len = 0;
480 
481 	if (offset & 1) {
482 		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
483 		if (err)
484 			return err;
485 
486 		val = (*data++ << 8) | (val & 0xff);
487 
488 		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
489 		if (err)
490 			return err;
491 
492 		offset++;
493 		len--;
494 		eeprom->len++;
495 	}
496 
497 	while (len >= 2) {
498 		val = *data++;
499 		val |= *data++ << 8;
500 
501 		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
502 		if (err)
503 			return err;
504 
505 		offset += 2;
506 		len -= 2;
507 		eeprom->len += 2;
508 	}
509 
510 	if (len) {
511 		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
512 		if (err)
513 			return err;
514 
515 		val = (val & 0xff00) | *data++;
516 
517 		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
518 		if (err)
519 			return err;
520 
521 		offset++;
522 		len--;
523 		eeprom->len++;
524 	}
525 
526 	return 0;
527 }
528 
529 /* Offset 0x18: SMI PHY Command Register
530  * Offset 0x19: SMI PHY Data Register
531  */
532 
533 static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
534 {
535 	return mv88e6xxx_g2_wait(chip, GLOBAL2_SMI_PHY_CMD,
536 				 GLOBAL2_SMI_PHY_CMD_BUSY);
537 }
538 
539 static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
540 {
541 	int err;
542 
543 	err = mv88e6xxx_g2_write(chip, GLOBAL2_SMI_PHY_CMD, cmd);
544 	if (err)
545 		return err;
546 
547 	return mv88e6xxx_g2_smi_phy_wait(chip);
548 }
549 
550 static int mv88e6xxx_g2_smi_phy_write_addr(struct mv88e6xxx_chip *chip,
551 					   int addr, int device, int reg,
552 					   bool external)
553 {
554 	int cmd = SMI_CMD_OP_45_WRITE_ADDR | (addr << 5) | device;
555 	int err;
556 
557 	if (external)
558 		cmd |= GLOBAL2_SMI_PHY_CMD_EXTERNAL;
559 
560 	err = mv88e6xxx_g2_smi_phy_wait(chip);
561 	if (err)
562 		return err;
563 
564 	err = mv88e6xxx_g2_write(chip, GLOBAL2_SMI_PHY_DATA, reg);
565 	if (err)
566 		return err;
567 
568 	return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
569 }
570 
571 static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,
572 					 int addr, int reg_c45, u16 *val,
573 					 bool external)
574 {
575 	int device = (reg_c45 >> 16) & 0x1f;
576 	int reg = reg_c45 & 0xffff;
577 	int err;
578 	u16 cmd;
579 
580 	err = mv88e6xxx_g2_smi_phy_write_addr(chip, addr, device, reg,
581 					      external);
582 	if (err)
583 		return err;
584 
585 	cmd = GLOBAL2_SMI_PHY_CMD_OP_45_READ_DATA | (addr << 5) | device;
586 
587 	if (external)
588 		cmd |= GLOBAL2_SMI_PHY_CMD_EXTERNAL;
589 
590 	err = mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
591 	if (err)
592 		return err;
593 
594 	err = mv88e6xxx_g2_read(chip, GLOBAL2_SMI_PHY_DATA, val);
595 	if (err)
596 		return err;
597 
598 	err = *val;
599 
600 	return 0;
601 }
602 
603 static int mv88e6xxx_g2_smi_phy_read_c22(struct mv88e6xxx_chip *chip,
604 					 int addr, int reg, u16 *val,
605 					 bool external)
606 {
607 	u16 cmd = GLOBAL2_SMI_PHY_CMD_OP_22_READ_DATA | (addr << 5) | reg;
608 	int err;
609 
610 	if (external)
611 		cmd |= GLOBAL2_SMI_PHY_CMD_EXTERNAL;
612 
613 	err = mv88e6xxx_g2_smi_phy_wait(chip);
614 	if (err)
615 		return err;
616 
617 	err = mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
618 	if (err)
619 		return err;
620 
621 	return mv88e6xxx_g2_read(chip, GLOBAL2_SMI_PHY_DATA, val);
622 }
623 
624 int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip,
625 			      struct mii_bus *bus,
626 			      int addr, int reg, u16 *val)
627 {
628 	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
629 	bool external = mdio_bus->external;
630 
631 	if (reg & MII_ADDR_C45)
632 		return mv88e6xxx_g2_smi_phy_read_c45(chip, addr, reg, val,
633 						     external);
634 	return mv88e6xxx_g2_smi_phy_read_c22(chip, addr, reg, val, external);
635 }
636 
637 static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,
638 					  int addr, int reg_c45, u16 val,
639 					  bool external)
640 {
641 	int device = (reg_c45 >> 16) & 0x1f;
642 	int reg = reg_c45 & 0xffff;
643 	int err;
644 	u16 cmd;
645 
646 	err = mv88e6xxx_g2_smi_phy_write_addr(chip, addr, device, reg,
647 					      external);
648 	if (err)
649 		return err;
650 
651 	cmd = GLOBAL2_SMI_PHY_CMD_OP_45_WRITE_DATA | (addr << 5) | device;
652 
653 	if (external)
654 		cmd |= GLOBAL2_SMI_PHY_CMD_EXTERNAL;
655 
656 	err = mv88e6xxx_g2_write(chip, GLOBAL2_SMI_PHY_DATA, val);
657 	if (err)
658 		return err;
659 
660 	err = mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
661 	if (err)
662 		return err;
663 
664 	return 0;
665 }
666 
667 static int mv88e6xxx_g2_smi_phy_write_c22(struct mv88e6xxx_chip *chip,
668 					  int addr, int reg, u16 val,
669 					  bool external)
670 {
671 	u16 cmd = GLOBAL2_SMI_PHY_CMD_OP_22_WRITE_DATA | (addr << 5) | reg;
672 	int err;
673 
674 	if (external)
675 		cmd |= GLOBAL2_SMI_PHY_CMD_EXTERNAL;
676 
677 	err = mv88e6xxx_g2_smi_phy_wait(chip);
678 	if (err)
679 		return err;
680 
681 	err = mv88e6xxx_g2_write(chip, GLOBAL2_SMI_PHY_DATA, val);
682 	if (err)
683 		return err;
684 
685 	return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
686 }
687 
688 int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip,
689 			       struct mii_bus *bus,
690 			       int addr, int reg, u16 val)
691 {
692 	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
693 	bool external = mdio_bus->external;
694 
695 	if (reg & MII_ADDR_C45)
696 		return mv88e6xxx_g2_smi_phy_write_c45(chip, addr, reg, val,
697 						      external);
698 
699 	return mv88e6xxx_g2_smi_phy_write_c22(chip, addr, reg, val, external);
700 }
701 
702 static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
703 {
704 	u16 reg;
705 
706 	mv88e6xxx_g2_read(chip, GLOBAL2_WDOG_CONTROL, &reg);
707 
708 	dev_info(chip->dev, "Watchdog event: 0x%04x", reg);
709 
710 	return IRQ_HANDLED;
711 }
712 
713 static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
714 {
715 	u16 reg;
716 
717 	mv88e6xxx_g2_read(chip, GLOBAL2_WDOG_CONTROL, &reg);
718 
719 	reg &= ~(GLOBAL2_WDOG_CONTROL_EGRESS_ENABLE |
720 		 GLOBAL2_WDOG_CONTROL_QC_ENABLE);
721 
722 	mv88e6xxx_g2_write(chip, GLOBAL2_WDOG_CONTROL, reg);
723 }
724 
725 static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
726 {
727 	return mv88e6xxx_g2_write(chip, GLOBAL2_WDOG_CONTROL,
728 				  GLOBAL2_WDOG_CONTROL_EGRESS_ENABLE |
729 				  GLOBAL2_WDOG_CONTROL_QC_ENABLE |
730 				  GLOBAL2_WDOG_CONTROL_SWRESET);
731 }
732 
733 const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
734 	.irq_action = mv88e6097_watchdog_action,
735 	.irq_setup = mv88e6097_watchdog_setup,
736 	.irq_free = mv88e6097_watchdog_free,
737 };
738 
739 static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
740 {
741 	return mv88e6xxx_g2_update(chip, GLOBAL2_WDOG_CONTROL,
742 				   GLOBAL2_WDOG_INT_ENABLE |
743 				   GLOBAL2_WDOG_CUT_THROUGH |
744 				   GLOBAL2_WDOG_QUEUE_CONTROLLER |
745 				   GLOBAL2_WDOG_EGRESS |
746 				   GLOBAL2_WDOG_FORCE_IRQ);
747 }
748 
749 static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
750 {
751 	int err;
752 	u16 reg;
753 
754 	mv88e6xxx_g2_write(chip, GLOBAL2_WDOG_CONTROL, GLOBAL2_WDOG_EVENT);
755 	err = mv88e6xxx_g2_read(chip, GLOBAL2_WDOG_CONTROL, &reg);
756 
757 	dev_info(chip->dev, "Watchdog event: 0x%04x",
758 		 reg & GLOBAL2_WDOG_DATA_MASK);
759 
760 	mv88e6xxx_g2_write(chip, GLOBAL2_WDOG_CONTROL, GLOBAL2_WDOG_HISTORY);
761 	err = mv88e6xxx_g2_read(chip, GLOBAL2_WDOG_CONTROL, &reg);
762 
763 	dev_info(chip->dev, "Watchdog history: 0x%04x",
764 		 reg & GLOBAL2_WDOG_DATA_MASK);
765 
766 	/* Trigger a software reset to try to recover the switch */
767 	if (chip->info->ops->reset)
768 		chip->info->ops->reset(chip);
769 
770 	mv88e6390_watchdog_setup(chip);
771 
772 	return IRQ_HANDLED;
773 }
774 
775 static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
776 {
777 	mv88e6xxx_g2_update(chip, GLOBAL2_WDOG_CONTROL,
778 			    GLOBAL2_WDOG_INT_ENABLE);
779 }
780 
781 const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
782 	.irq_action = mv88e6390_watchdog_action,
783 	.irq_setup = mv88e6390_watchdog_setup,
784 	.irq_free = mv88e6390_watchdog_free,
785 };
786 
787 static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
788 {
789 	struct mv88e6xxx_chip *chip = dev_id;
790 	irqreturn_t ret = IRQ_NONE;
791 
792 	mutex_lock(&chip->reg_lock);
793 	if (chip->info->ops->watchdog_ops->irq_action)
794 		ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
795 	mutex_unlock(&chip->reg_lock);
796 
797 	return ret;
798 }
799 
800 static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
801 {
802 	mutex_lock(&chip->reg_lock);
803 	if (chip->info->ops->watchdog_ops->irq_free)
804 		chip->info->ops->watchdog_ops->irq_free(chip);
805 	mutex_unlock(&chip->reg_lock);
806 
807 	free_irq(chip->watchdog_irq, chip);
808 	irq_dispose_mapping(chip->watchdog_irq);
809 }
810 
811 static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
812 {
813 	int err;
814 
815 	chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
816 					      GLOBAL2_INT_SOURCE_WATCHDOG);
817 	if (chip->watchdog_irq < 0)
818 		return chip->watchdog_irq;
819 
820 	err = request_threaded_irq(chip->watchdog_irq, NULL,
821 				   mv88e6xxx_g2_watchdog_thread_fn,
822 				   IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
823 				   "mv88e6xxx-watchdog", chip);
824 	if (err)
825 		return err;
826 
827 	mutex_lock(&chip->reg_lock);
828 	if (chip->info->ops->watchdog_ops->irq_setup)
829 		err = chip->info->ops->watchdog_ops->irq_setup(chip);
830 	mutex_unlock(&chip->reg_lock);
831 
832 	return err;
833 }
834 
835 /* Offset 0x1D: Misc Register */
836 
837 static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
838 					bool port_5_bit)
839 {
840 	u16 val;
841 	int err;
842 
843 	err = mv88e6xxx_g2_read(chip, GLOBAL2_MISC, &val);
844 	if (err)
845 		return err;
846 
847 	if (port_5_bit)
848 		val |= GLOBAL2_MISC_5_BIT_PORT;
849 	else
850 		val &= ~GLOBAL2_MISC_5_BIT_PORT;
851 
852 	return mv88e6xxx_g2_write(chip, GLOBAL2_MISC, val);
853 }
854 
855 int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
856 {
857 	return mv88e6xxx_g2_misc_5_bit_port(chip, false);
858 }
859 
860 static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
861 {
862 	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
863 	unsigned int n = d->hwirq;
864 
865 	chip->g2_irq.masked |= (1 << n);
866 }
867 
868 static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
869 {
870 	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
871 	unsigned int n = d->hwirq;
872 
873 	chip->g2_irq.masked &= ~(1 << n);
874 }
875 
876 static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
877 {
878 	struct mv88e6xxx_chip *chip = dev_id;
879 	unsigned int nhandled = 0;
880 	unsigned int sub_irq;
881 	unsigned int n;
882 	int err;
883 	u16 reg;
884 
885 	mutex_lock(&chip->reg_lock);
886 	err = mv88e6xxx_g2_read(chip, GLOBAL2_INT_SOURCE, &reg);
887 	mutex_unlock(&chip->reg_lock);
888 	if (err)
889 		goto out;
890 
891 	for (n = 0; n < 16; ++n) {
892 		if (reg & (1 << n)) {
893 			sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
894 			handle_nested_irq(sub_irq);
895 			++nhandled;
896 		}
897 	}
898 out:
899 	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
900 }
901 
902 static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
903 {
904 	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
905 
906 	mutex_lock(&chip->reg_lock);
907 }
908 
909 static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
910 {
911 	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
912 
913 	mv88e6xxx_g2_write(chip, GLOBAL2_INT_MASK, ~chip->g2_irq.masked);
914 
915 	mutex_unlock(&chip->reg_lock);
916 }
917 
918 static struct irq_chip mv88e6xxx_g2_irq_chip = {
919 	.name			= "mv88e6xxx-g2",
920 	.irq_mask		= mv88e6xxx_g2_irq_mask,
921 	.irq_unmask		= mv88e6xxx_g2_irq_unmask,
922 	.irq_bus_lock		= mv88e6xxx_g2_irq_bus_lock,
923 	.irq_bus_sync_unlock	= mv88e6xxx_g2_irq_bus_sync_unlock,
924 };
925 
926 static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
927 				       unsigned int irq,
928 				       irq_hw_number_t hwirq)
929 {
930 	struct mv88e6xxx_chip *chip = d->host_data;
931 
932 	irq_set_chip_data(irq, d->host_data);
933 	irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
934 	irq_set_noprobe(irq);
935 
936 	return 0;
937 }
938 
939 static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
940 	.map	= mv88e6xxx_g2_irq_domain_map,
941 	.xlate	= irq_domain_xlate_twocell,
942 };
943 
944 void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
945 {
946 	int irq, virq;
947 
948 	mv88e6xxx_g2_watchdog_free(chip);
949 
950 	free_irq(chip->device_irq, chip);
951 	irq_dispose_mapping(chip->device_irq);
952 
953 	for (irq = 0; irq < 16; irq++) {
954 		virq = irq_find_mapping(chip->g2_irq.domain, irq);
955 		irq_dispose_mapping(virq);
956 	}
957 
958 	irq_domain_remove(chip->g2_irq.domain);
959 }
960 
961 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
962 {
963 	int err, irq, virq;
964 
965 	if (!chip->dev->of_node)
966 		return -EINVAL;
967 
968 	chip->g2_irq.domain = irq_domain_add_simple(
969 		chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
970 	if (!chip->g2_irq.domain)
971 		return -ENOMEM;
972 
973 	for (irq = 0; irq < 16; irq++)
974 		irq_create_mapping(chip->g2_irq.domain, irq);
975 
976 	chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
977 	chip->g2_irq.masked = ~0;
978 
979 	chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
980 					    GLOBAL_STATUS_IRQ_DEVICE);
981 	if (chip->device_irq < 0) {
982 		err = chip->device_irq;
983 		goto out;
984 	}
985 
986 	err = request_threaded_irq(chip->device_irq, NULL,
987 				   mv88e6xxx_g2_irq_thread_fn,
988 				   IRQF_ONESHOT, "mv88e6xxx-g1", chip);
989 	if (err)
990 		goto out;
991 
992 	return mv88e6xxx_g2_watchdog_setup(chip);
993 
994 out:
995 	for (irq = 0; irq < 16; irq++) {
996 		virq = irq_find_mapping(chip->g2_irq.domain, irq);
997 		irq_dispose_mapping(virq);
998 	}
999 
1000 	irq_domain_remove(chip->g2_irq.domain);
1001 
1002 	return err;
1003 }
1004 
1005 int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
1006 {
1007 	u16 reg;
1008 	int err;
1009 
1010 	/* Ignore removed tag data on doubly tagged packets, disable
1011 	 * flow control messages, force flow control priority to the
1012 	 * highest, and send all special multicast frames to the CPU
1013 	 * port at the highest priority.
1014 	 */
1015 	reg = GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI | (0x7 << 4);
1016 	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X) ||
1017 	    mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X))
1018 		reg |= GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x7;
1019 	err = mv88e6xxx_g2_write(chip, GLOBAL2_SWITCH_MGMT, reg);
1020 	if (err)
1021 		return err;
1022 
1023 	/* Program the DSA routing table. */
1024 	err = mv88e6xxx_g2_set_device_mapping(chip);
1025 	if (err)
1026 		return err;
1027 
1028 	/* Clear all trunk masks and mapping. */
1029 	err = mv88e6xxx_g2_clear_trunk(chip);
1030 	if (err)
1031 		return err;
1032 
1033 	if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_IRL)) {
1034 		/* Disable ingress rate limiting by resetting all per port
1035 		 * ingress rate limit resources to their initial state.
1036 		 */
1037 		err = mv88e6xxx_g2_clear_irl(chip);
1038 			if (err)
1039 				return err;
1040 	}
1041 
1042 	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_POT)) {
1043 		/* Clear the priority override table. */
1044 		err = mv88e6xxx_g2_clear_pot(chip);
1045 		if (err)
1046 			return err;
1047 	}
1048 
1049 	return 0;
1050 }
1051