1
2
3
4
5
6
7
8
9
10
11#include <linux/bitfield.h>
12#include <linux/interrupt.h>
13#include <linux/irqdomain.h>
14
15#include "chip.h"
16#include "global1.h"
17#include "global2.h"
18
19int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
20{
21 return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
22}
23
24int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
25{
26 return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
27}
28
29int mv88e6xxx_g2_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
30 bit, int val)
31{
32 return mv88e6xxx_wait_bit(chip, chip->info->global2_addr, reg,
33 bit, val);
34}
35
36
37
38static int mv88e6xxx_g2_int_source(struct mv88e6xxx_chip *chip, u16 *src)
39{
40
41 return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SRC, src);
42}
43
44
45
46static int mv88e6xxx_g2_int_mask(struct mv88e6xxx_chip *chip, u16 mask)
47{
48 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_INT_MASK, mask);
49}
50
51
52
53static int mv88e6xxx_g2_mgmt_enable_2x(struct mv88e6xxx_chip *chip, u16 en2x)
54{
55 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_2X, en2x);
56}
57
58
59
60static int mv88e6xxx_g2_mgmt_enable_0x(struct mv88e6xxx_chip *chip, u16 en0x)
61{
62 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_0X, en0x);
63}
64
65
66
67static int mv88e6xxx_g2_switch_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip,
68 bool enable)
69{
70 u16 val;
71 int err;
72
73 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SWITCH_MGMT, &val);
74 if (err)
75 return err;
76
77 if (enable)
78 val |= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
79 else
80 val &= ~MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
81
82 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, val);
83}
84
85int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
86{
87 int err;
88
89
90
91
92 err = mv88e6xxx_g2_mgmt_enable_0x(chip, 0xffff);
93 if (err)
94 return err;
95
96 return mv88e6xxx_g2_switch_mgmt_rsvd2cpu(chip, true);
97}
98
99int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
100{
101 int err;
102
103
104
105
106 err = mv88e6xxx_g2_mgmt_enable_2x(chip, 0xffff);
107 if (err)
108 return err;
109
110 return mv88e6185_g2_mgmt_rsvd2cpu(chip);
111}
112
113
114
115int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
116 int port)
117{
118 u16 val = (target << 8) | (port & 0x1f);
119
120
121
122
123 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_DEVICE_MAPPING,
124 MV88E6XXX_G2_DEVICE_MAPPING_UPDATE | val);
125}
126
127
128
129static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
130 bool hash, u16 mask)
131{
132 u16 val = (num << 12) | (mask & mv88e6xxx_port_mask(chip));
133
134 if (hash)
135 val |= MV88E6XXX_G2_TRUNK_MASK_HASH;
136
137 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MASK,
138 MV88E6XXX_G2_TRUNK_MASK_UPDATE | val);
139}
140
141
142
143static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
144 u16 map)
145{
146 const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
147 u16 val = (id << 11) | (map & port_mask);
148
149 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MAPPING,
150 MV88E6XXX_G2_TRUNK_MAPPING_UPDATE | val);
151}
152
153int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
154{
155 const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
156 int i, err;
157
158
159 for (i = 0; i < 8; ++i) {
160 err = mv88e6xxx_g2_trunk_mask_write(chip, i, false, port_mask);
161 if (err)
162 return err;
163 }
164
165
166 for (i = 0; i < 16; ++i) {
167 err = mv88e6xxx_g2_trunk_mapping_write(chip, i, 0);
168 if (err)
169 return err;
170 }
171
172 return 0;
173}
174
175
176
177
178
179static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip)
180{
181 int bit = __bf_shf(MV88E6XXX_G2_IRL_CMD_BUSY);
182
183 return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_IRL_CMD, bit, 0);
184}
185
186static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port,
187 int res, int reg)
188{
189 int err;
190
191 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_IRL_CMD,
192 MV88E6XXX_G2_IRL_CMD_BUSY | op | (port << 8) |
193 (res << 5) | reg);
194 if (err)
195 return err;
196
197 return mv88e6xxx_g2_irl_wait(chip);
198}
199
200int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
201{
202 return mv88e6xxx_g2_irl_op(chip, MV88E6352_G2_IRL_CMD_OP_INIT_ALL, port,
203 0, 0);
204}
205
206int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
207{
208 return mv88e6xxx_g2_irl_op(chip, MV88E6390_G2_IRL_CMD_OP_INIT_ALL, port,
209 0, 0);
210}
211
212
213
214
215
216static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
217{
218 int bit = __bf_shf(MV88E6XXX_G2_PVT_ADDR_BUSY);
219
220 return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_PVT_ADDR, bit, 0);
221}
222
223static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
224 int src_port, u16 op)
225{
226 int err;
227
228
229
230
231 op |= MV88E6XXX_G2_PVT_ADDR_BUSY;
232 op |= (src_dev & 0x1f) << 4;
233 op |= (src_port & 0xf);
234
235 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_ADDR, op);
236 if (err)
237 return err;
238
239 return mv88e6xxx_g2_pvt_op_wait(chip);
240}
241
242int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
243 int src_port, u16 data)
244{
245 int err;
246
247 err = mv88e6xxx_g2_pvt_op_wait(chip);
248 if (err)
249 return err;
250
251 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_DATA, data);
252 if (err)
253 return err;
254
255 return mv88e6xxx_g2_pvt_op(chip, src_dev, src_port,
256 MV88E6XXX_G2_PVT_ADDR_OP_WRITE_PVLAN);
257}
258
259
260
261static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
262 unsigned int pointer, u8 data)
263{
264 u16 val = (pointer << 8) | data;
265
266 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MAC,
267 MV88E6XXX_G2_SWITCH_MAC_UPDATE | val);
268}
269
270int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
271{
272 int i, err;
273
274 for (i = 0; i < 6; i++) {
275 err = mv88e6xxx_g2_switch_mac_write(chip, i, addr[i]);
276 if (err)
277 break;
278 }
279
280 return err;
281}
282
283
284
285static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
286 u8 data)
287{
288 u16 val = (pointer << 8) | (data & 0x7);
289
290 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PRIO_OVERRIDE,
291 MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE | val);
292}
293
294int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
295{
296 int i, err;
297
298
299 for (i = 0; i < 16; i++) {
300 err = mv88e6xxx_g2_pot_write(chip, i, 0);
301 if (err)
302 break;
303 }
304
305 return err;
306}
307
308
309
310
311
312
313static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
314{
315 int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
316 int err;
317
318 err = mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
319 if (err)
320 return err;
321
322 bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_RUNNING);
323
324 return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
325}
326
327static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
328{
329 int err;
330
331 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_EEPROM_CMD,
332 MV88E6XXX_G2_EEPROM_CMD_BUSY | cmd);
333 if (err)
334 return err;
335
336 return mv88e6xxx_g2_eeprom_wait(chip);
337}
338
339static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
340 u16 addr, u8 *data)
341{
342 u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ;
343 int err;
344
345 err = mv88e6xxx_g2_eeprom_wait(chip);
346 if (err)
347 return err;
348
349 err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
350 if (err)
351 return err;
352
353 err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
354 if (err)
355 return err;
356
357 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &cmd);
358 if (err)
359 return err;
360
361 *data = cmd & 0xff;
362
363 return 0;
364}
365
366static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
367 u16 addr, u8 data)
368{
369 u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE |
370 MV88E6XXX_G2_EEPROM_CMD_WRITE_EN;
371 int err;
372
373 err = mv88e6xxx_g2_eeprom_wait(chip);
374 if (err)
375 return err;
376
377 err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
378 if (err)
379 return err;
380
381 return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
382}
383
384static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
385 u8 addr, u16 *data)
386{
387 u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ | addr;
388 int err;
389
390 err = mv88e6xxx_g2_eeprom_wait(chip);
391 if (err)
392 return err;
393
394 err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
395 if (err)
396 return err;
397
398 return mv88e6xxx_g2_read(chip, MV88E6352_G2_EEPROM_DATA, data);
399}
400
401static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
402 u8 addr, u16 data)
403{
404 u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE | addr;
405 int err;
406
407 err = mv88e6xxx_g2_eeprom_wait(chip);
408 if (err)
409 return err;
410
411 err = mv88e6xxx_g2_write(chip, MV88E6352_G2_EEPROM_DATA, data);
412 if (err)
413 return err;
414
415 return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
416}
417
418int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
419 struct ethtool_eeprom *eeprom, u8 *data)
420{
421 unsigned int offset = eeprom->offset;
422 unsigned int len = eeprom->len;
423 int err;
424
425 eeprom->len = 0;
426
427 while (len) {
428 err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
429 if (err)
430 return err;
431
432 eeprom->len++;
433 offset++;
434 data++;
435 len--;
436 }
437
438 return 0;
439}
440
441int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
442 struct ethtool_eeprom *eeprom, u8 *data)
443{
444 unsigned int offset = eeprom->offset;
445 unsigned int len = eeprom->len;
446 int err;
447
448 eeprom->len = 0;
449
450 while (len) {
451 err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
452 if (err)
453 return err;
454
455 eeprom->len++;
456 offset++;
457 data++;
458 len--;
459 }
460
461 return 0;
462}
463
464int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
465 struct ethtool_eeprom *eeprom, u8 *data)
466{
467 unsigned int offset = eeprom->offset;
468 unsigned int len = eeprom->len;
469 u16 val;
470 int err;
471
472 eeprom->len = 0;
473
474 if (offset & 1) {
475 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
476 if (err)
477 return err;
478
479 *data++ = (val >> 8) & 0xff;
480
481 offset++;
482 len--;
483 eeprom->len++;
484 }
485
486 while (len >= 2) {
487 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
488 if (err)
489 return err;
490
491 *data++ = val & 0xff;
492 *data++ = (val >> 8) & 0xff;
493
494 offset += 2;
495 len -= 2;
496 eeprom->len += 2;
497 }
498
499 if (len) {
500 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
501 if (err)
502 return err;
503
504 *data++ = val & 0xff;
505
506 offset++;
507 len--;
508 eeprom->len++;
509 }
510
511 return 0;
512}
513
514int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
515 struct ethtool_eeprom *eeprom, u8 *data)
516{
517 unsigned int offset = eeprom->offset;
518 unsigned int len = eeprom->len;
519 u16 val;
520 int err;
521
522
523 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &val);
524 if (err)
525 return err;
526
527 if (!(val & MV88E6XXX_G2_EEPROM_CMD_WRITE_EN))
528 return -EROFS;
529
530 eeprom->len = 0;
531
532 if (offset & 1) {
533 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
534 if (err)
535 return err;
536
537 val = (*data++ << 8) | (val & 0xff);
538
539 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
540 if (err)
541 return err;
542
543 offset++;
544 len--;
545 eeprom->len++;
546 }
547
548 while (len >= 2) {
549 val = *data++;
550 val |= *data++ << 8;
551
552 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
553 if (err)
554 return err;
555
556 offset += 2;
557 len -= 2;
558 eeprom->len += 2;
559 }
560
561 if (len) {
562 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
563 if (err)
564 return err;
565
566 val = (val & 0xff00) | *data++;
567
568 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
569 if (err)
570 return err;
571
572 offset++;
573 len--;
574 eeprom->len++;
575 }
576
577 return 0;
578}
579
580
581
582
583
584static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
585{
586 int bit = __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
587
588 return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_SMI_PHY_CMD, bit, 0);
589}
590
591static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
592{
593 int err;
594
595 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_CMD,
596 MV88E6XXX_G2_SMI_PHY_CMD_BUSY | cmd);
597 if (err)
598 return err;
599
600 return mv88e6xxx_g2_smi_phy_wait(chip);
601}
602
603static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip *chip,
604 bool external, bool c45, u16 op, int dev,
605 int reg)
606{
607 u16 cmd = op;
608
609 if (external)
610 cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL;
611 else
612 cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL;
613
614 if (c45)
615 cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45;
616 else
617 cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22;
618
619 dev <<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK);
620 cmd |= dev & MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK;
621 cmd |= reg & MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK;
622
623 return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
624}
625
626static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip *chip,
627 bool external, u16 op, int dev,
628 int reg)
629{
630 return mv88e6xxx_g2_smi_phy_access(chip, external, false, op, dev, reg);
631}
632
633
634static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip *chip,
635 bool external, int dev, int reg,
636 u16 *data)
637{
638 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA;
639 int err;
640
641 err = mv88e6xxx_g2_smi_phy_wait(chip);
642 if (err)
643 return err;
644
645 err = mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
646 if (err)
647 return err;
648
649 return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
650}
651
652
653static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip *chip,
654 bool external, int dev, int reg,
655 u16 data)
656{
657 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA;
658 int err;
659
660 err = mv88e6xxx_g2_smi_phy_wait(chip);
661 if (err)
662 return err;
663
664 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
665 if (err)
666 return err;
667
668 return mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
669}
670
671static int mv88e6xxx_g2_smi_phy_access_c45(struct mv88e6xxx_chip *chip,
672 bool external, u16 op, int port,
673 int dev)
674{
675 return mv88e6xxx_g2_smi_phy_access(chip, external, true, op, port, dev);
676}
677
678
679static int mv88e6xxx_g2_smi_phy_write_addr_c45(struct mv88e6xxx_chip *chip,
680 bool external, int port, int dev,
681 int addr)
682{
683 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR;
684 int err;
685
686 err = mv88e6xxx_g2_smi_phy_wait(chip);
687 if (err)
688 return err;
689
690 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, addr);
691 if (err)
692 return err;
693
694 return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
695}
696
697
698static int mv88e6xxx_g2_smi_phy_read_data_c45(struct mv88e6xxx_chip *chip,
699 bool external, int port, int dev,
700 u16 *data)
701{
702 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA;
703 int err;
704
705 err = mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
706 if (err)
707 return err;
708
709 return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
710}
711
712static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,
713 bool external, int port, int reg,
714 u16 *data)
715{
716 int dev = (reg >> 16) & 0x1f;
717 int addr = reg & 0xffff;
718 int err;
719
720 err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
721 addr);
722 if (err)
723 return err;
724
725 return mv88e6xxx_g2_smi_phy_read_data_c45(chip, external, port, dev,
726 data);
727}
728
729
730static int mv88e6xxx_g2_smi_phy_write_data_c45(struct mv88e6xxx_chip *chip,
731 bool external, int port, int dev,
732 u16 data)
733{
734 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA;
735 int err;
736
737 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
738 if (err)
739 return err;
740
741 return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
742}
743
744static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,
745 bool external, int port, int reg,
746 u16 data)
747{
748 int dev = (reg >> 16) & 0x1f;
749 int addr = reg & 0xffff;
750 int err;
751
752 err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
753 addr);
754 if (err)
755 return err;
756
757 return mv88e6xxx_g2_smi_phy_write_data_c45(chip, external, port, dev,
758 data);
759}
760
761int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
762 int addr, int reg, u16 *val)
763{
764 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
765 bool external = mdio_bus->external;
766
767 if (reg & MII_ADDR_C45)
768 return mv88e6xxx_g2_smi_phy_read_c45(chip, external, addr, reg,
769 val);
770
771 return mv88e6xxx_g2_smi_phy_read_data_c22(chip, external, addr, reg,
772 val);
773}
774
775int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
776 int addr, int reg, u16 val)
777{
778 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
779 bool external = mdio_bus->external;
780
781 if (reg & MII_ADDR_C45)
782 return mv88e6xxx_g2_smi_phy_write_c45(chip, external, addr, reg,
783 val);
784
785 return mv88e6xxx_g2_smi_phy_write_data_c22(chip, external, addr, reg,
786 val);
787}
788
789
790static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
791{
792 u16 reg;
793
794 mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, ®);
795
796 dev_info(chip->dev, "Watchdog event: 0x%04x", reg);
797
798 return IRQ_HANDLED;
799}
800
801static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
802{
803 u16 reg;
804
805 mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, ®);
806
807 reg &= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
808 MV88E6352_G2_WDOG_CTL_QC_ENABLE);
809
810 mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL, reg);
811}
812
813static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
814{
815 return mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL,
816 MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
817 MV88E6352_G2_WDOG_CTL_QC_ENABLE |
818 MV88E6352_G2_WDOG_CTL_SWRESET);
819}
820
821const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
822 .irq_action = mv88e6097_watchdog_action,
823 .irq_setup = mv88e6097_watchdog_setup,
824 .irq_free = mv88e6097_watchdog_free,
825};
826
827static void mv88e6250_watchdog_free(struct mv88e6xxx_chip *chip)
828{
829 u16 reg;
830
831 mv88e6xxx_g2_read(chip, MV88E6250_G2_WDOG_CTL, ®);
832
833 reg &= ~(MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
834 MV88E6250_G2_WDOG_CTL_QC_ENABLE);
835
836 mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL, reg);
837}
838
839static int mv88e6250_watchdog_setup(struct mv88e6xxx_chip *chip)
840{
841 return mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL,
842 MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
843 MV88E6250_G2_WDOG_CTL_QC_ENABLE |
844 MV88E6250_G2_WDOG_CTL_SWRESET);
845}
846
847const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops = {
848 .irq_action = mv88e6097_watchdog_action,
849 .irq_setup = mv88e6250_watchdog_setup,
850 .irq_free = mv88e6250_watchdog_free,
851};
852
853static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
854{
855 return mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
856 MV88E6390_G2_WDOG_CTL_UPDATE |
857 MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
858 MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
859 MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
860 MV88E6390_G2_WDOG_CTL_EGRESS |
861 MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
862}
863
864static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
865{
866 int err;
867 u16 reg;
868
869 mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
870 MV88E6390_G2_WDOG_CTL_PTR_EVENT);
871 err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, ®);
872
873 dev_info(chip->dev, "Watchdog event: 0x%04x",
874 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
875
876 mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
877 MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
878 err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, ®);
879
880 dev_info(chip->dev, "Watchdog history: 0x%04x",
881 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
882
883
884 if (chip->info->ops->reset)
885 chip->info->ops->reset(chip);
886
887 mv88e6390_watchdog_setup(chip);
888
889 return IRQ_HANDLED;
890}
891
892static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
893{
894 mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
895 MV88E6390_G2_WDOG_CTL_UPDATE |
896 MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
897}
898
899const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
900 .irq_action = mv88e6390_watchdog_action,
901 .irq_setup = mv88e6390_watchdog_setup,
902 .irq_free = mv88e6390_watchdog_free,
903};
904
905static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
906{
907 struct mv88e6xxx_chip *chip = dev_id;
908 irqreturn_t ret = IRQ_NONE;
909
910 mv88e6xxx_reg_lock(chip);
911 if (chip->info->ops->watchdog_ops->irq_action)
912 ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
913 mv88e6xxx_reg_unlock(chip);
914
915 return ret;
916}
917
918static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
919{
920 mv88e6xxx_reg_lock(chip);
921 if (chip->info->ops->watchdog_ops->irq_free)
922 chip->info->ops->watchdog_ops->irq_free(chip);
923 mv88e6xxx_reg_unlock(chip);
924
925 free_irq(chip->watchdog_irq, chip);
926 irq_dispose_mapping(chip->watchdog_irq);
927}
928
929static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
930{
931 int err;
932
933 chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
934 MV88E6XXX_G2_INT_SOURCE_WATCHDOG);
935 if (chip->watchdog_irq < 0)
936 return chip->watchdog_irq;
937
938 err = request_threaded_irq(chip->watchdog_irq, NULL,
939 mv88e6xxx_g2_watchdog_thread_fn,
940 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
941 "mv88e6xxx-watchdog", chip);
942 if (err)
943 return err;
944
945 mv88e6xxx_reg_lock(chip);
946 if (chip->info->ops->watchdog_ops->irq_setup)
947 err = chip->info->ops->watchdog_ops->irq_setup(chip);
948 mv88e6xxx_reg_unlock(chip);
949
950 return err;
951}
952
953
954
955static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
956 bool port_5_bit)
957{
958 u16 val;
959 int err;
960
961 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_MISC, &val);
962 if (err)
963 return err;
964
965 if (port_5_bit)
966 val |= MV88E6XXX_G2_MISC_5_BIT_PORT;
967 else
968 val &= ~MV88E6XXX_G2_MISC_5_BIT_PORT;
969
970 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MISC, val);
971}
972
973int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
974{
975 return mv88e6xxx_g2_misc_5_bit_port(chip, false);
976}
977
978static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
979{
980 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
981 unsigned int n = d->hwirq;
982
983 chip->g2_irq.masked |= (1 << n);
984}
985
986static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
987{
988 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
989 unsigned int n = d->hwirq;
990
991 chip->g2_irq.masked &= ~(1 << n);
992}
993
994static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
995{
996 struct mv88e6xxx_chip *chip = dev_id;
997 unsigned int nhandled = 0;
998 unsigned int sub_irq;
999 unsigned int n;
1000 int err;
1001 u16 reg;
1002
1003 mv88e6xxx_reg_lock(chip);
1004 err = mv88e6xxx_g2_int_source(chip, ®);
1005 mv88e6xxx_reg_unlock(chip);
1006 if (err)
1007 goto out;
1008
1009 for (n = 0; n < 16; ++n) {
1010 if (reg & (1 << n)) {
1011 sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
1012 handle_nested_irq(sub_irq);
1013 ++nhandled;
1014 }
1015 }
1016out:
1017 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
1018}
1019
1020static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
1021{
1022 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1023
1024 mv88e6xxx_reg_lock(chip);
1025}
1026
1027static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
1028{
1029 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1030 int err;
1031
1032 err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
1033 if (err)
1034 dev_err(chip->dev, "failed to mask interrupts\n");
1035
1036 mv88e6xxx_reg_unlock(chip);
1037}
1038
1039static const struct irq_chip mv88e6xxx_g2_irq_chip = {
1040 .name = "mv88e6xxx-g2",
1041 .irq_mask = mv88e6xxx_g2_irq_mask,
1042 .irq_unmask = mv88e6xxx_g2_irq_unmask,
1043 .irq_bus_lock = mv88e6xxx_g2_irq_bus_lock,
1044 .irq_bus_sync_unlock = mv88e6xxx_g2_irq_bus_sync_unlock,
1045};
1046
1047static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
1048 unsigned int irq,
1049 irq_hw_number_t hwirq)
1050{
1051 struct mv88e6xxx_chip *chip = d->host_data;
1052
1053 irq_set_chip_data(irq, d->host_data);
1054 irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
1055 irq_set_noprobe(irq);
1056
1057 return 0;
1058}
1059
1060static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
1061 .map = mv88e6xxx_g2_irq_domain_map,
1062 .xlate = irq_domain_xlate_twocell,
1063};
1064
1065void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
1066{
1067 int irq, virq;
1068
1069 mv88e6xxx_g2_watchdog_free(chip);
1070
1071 free_irq(chip->device_irq, chip);
1072 irq_dispose_mapping(chip->device_irq);
1073
1074 for (irq = 0; irq < 16; irq++) {
1075 virq = irq_find_mapping(chip->g2_irq.domain, irq);
1076 irq_dispose_mapping(virq);
1077 }
1078
1079 irq_domain_remove(chip->g2_irq.domain);
1080}
1081
1082int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
1083{
1084 int err, irq, virq;
1085
1086 chip->g2_irq.domain = irq_domain_add_simple(
1087 chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
1088 if (!chip->g2_irq.domain)
1089 return -ENOMEM;
1090
1091 for (irq = 0; irq < 16; irq++)
1092 irq_create_mapping(chip->g2_irq.domain, irq);
1093
1094 chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
1095 chip->g2_irq.masked = ~0;
1096
1097 chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
1098 MV88E6XXX_G1_STS_IRQ_DEVICE);
1099 if (chip->device_irq < 0) {
1100 err = chip->device_irq;
1101 goto out;
1102 }
1103
1104 err = request_threaded_irq(chip->device_irq, NULL,
1105 mv88e6xxx_g2_irq_thread_fn,
1106 IRQF_ONESHOT, "mv88e6xxx-g2", chip);
1107 if (err)
1108 goto out;
1109
1110 return mv88e6xxx_g2_watchdog_setup(chip);
1111
1112out:
1113 for (irq = 0; irq < 16; irq++) {
1114 virq = irq_find_mapping(chip->g2_irq.domain, irq);
1115 irq_dispose_mapping(virq);
1116 }
1117
1118 irq_domain_remove(chip->g2_irq.domain);
1119
1120 return err;
1121}
1122
1123int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
1124 struct mii_bus *bus)
1125{
1126 int phy, irq, err, err_phy;
1127
1128 for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
1129 irq = irq_find_mapping(chip->g2_irq.domain, phy);
1130 if (irq < 0) {
1131 err = irq;
1132 goto out;
1133 }
1134 bus->irq[chip->info->phy_base_addr + phy] = irq;
1135 }
1136 return 0;
1137out:
1138 err_phy = phy;
1139
1140 for (phy = 0; phy < err_phy; phy++)
1141 irq_dispose_mapping(bus->irq[phy]);
1142
1143 return err;
1144}
1145
1146void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
1147 struct mii_bus *bus)
1148{
1149 int phy;
1150
1151 for (phy = 0; phy < chip->info->num_internal_phys; phy++)
1152 irq_dispose_mapping(bus->irq[phy]);
1153}
1154