This source file includes following definitions.
- mv88e6xxx_g2_read
- mv88e6xxx_g2_write
- mv88e6xxx_g2_wait_bit
- mv88e6xxx_g2_int_source
- mv88e6xxx_g2_int_mask
- mv88e6xxx_g2_mgmt_enable_2x
- mv88e6xxx_g2_mgmt_enable_0x
- mv88e6xxx_g2_switch_mgmt_rsvd2cpu
- mv88e6185_g2_mgmt_rsvd2cpu
- mv88e6352_g2_mgmt_rsvd2cpu
- mv88e6xxx_g2_device_mapping_write
- mv88e6xxx_g2_trunk_mask_write
- mv88e6xxx_g2_trunk_mapping_write
- mv88e6xxx_g2_trunk_clear
- mv88e6xxx_g2_irl_wait
- mv88e6xxx_g2_irl_op
- mv88e6352_g2_irl_init_all
- mv88e6390_g2_irl_init_all
- mv88e6xxx_g2_pvt_op_wait
- mv88e6xxx_g2_pvt_op
- mv88e6xxx_g2_pvt_write
- mv88e6xxx_g2_switch_mac_write
- mv88e6xxx_g2_set_switch_mac
- mv88e6xxx_g2_pot_write
- mv88e6xxx_g2_pot_clear
- mv88e6xxx_g2_eeprom_wait
- mv88e6xxx_g2_eeprom_cmd
- mv88e6xxx_g2_eeprom_read8
- mv88e6xxx_g2_eeprom_write8
- mv88e6xxx_g2_eeprom_read16
- mv88e6xxx_g2_eeprom_write16
- mv88e6xxx_g2_get_eeprom8
- mv88e6xxx_g2_set_eeprom8
- mv88e6xxx_g2_get_eeprom16
- mv88e6xxx_g2_set_eeprom16
- mv88e6xxx_g2_smi_phy_wait
- mv88e6xxx_g2_smi_phy_cmd
- mv88e6xxx_g2_smi_phy_access
- mv88e6xxx_g2_smi_phy_access_c22
- mv88e6xxx_g2_smi_phy_read_data_c22
- mv88e6xxx_g2_smi_phy_write_data_c22
- mv88e6xxx_g2_smi_phy_access_c45
- mv88e6xxx_g2_smi_phy_write_addr_c45
- mv88e6xxx_g2_smi_phy_read_data_c45
- mv88e6xxx_g2_smi_phy_read_c45
- mv88e6xxx_g2_smi_phy_write_data_c45
- mv88e6xxx_g2_smi_phy_write_c45
- mv88e6xxx_g2_smi_phy_read
- mv88e6xxx_g2_smi_phy_write
- mv88e6097_watchdog_action
- mv88e6097_watchdog_free
- mv88e6097_watchdog_setup
- mv88e6250_watchdog_free
- mv88e6250_watchdog_setup
- mv88e6390_watchdog_setup
- mv88e6390_watchdog_action
- mv88e6390_watchdog_free
- mv88e6xxx_g2_watchdog_thread_fn
- mv88e6xxx_g2_watchdog_free
- mv88e6xxx_g2_watchdog_setup
- mv88e6xxx_g2_misc_5_bit_port
- mv88e6xxx_g2_misc_4_bit_port
- mv88e6xxx_g2_irq_mask
- mv88e6xxx_g2_irq_unmask
- mv88e6xxx_g2_irq_thread_fn
- mv88e6xxx_g2_irq_bus_lock
- mv88e6xxx_g2_irq_bus_sync_unlock
- mv88e6xxx_g2_irq_domain_map
- mv88e6xxx_g2_irq_free
- mv88e6xxx_g2_irq_setup
- mv88e6xxx_g2_irq_mdio_setup
- mv88e6xxx_g2_irq_mdio_free
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
19 int 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
24 int 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
29 int 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
38 static 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
46 static 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
53 static 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
60 static 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
67 static 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
85 int 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
99 int 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
115 int 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
129 static 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
143 static 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
153 int 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
179 static 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
186 static 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
200 int 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
206 int 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
216 static 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
223 static 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
242 int 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
261 static 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
270 int 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
285 static 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
294 int 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
313 static 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
327 static 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
339 static 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
366 static 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
384 static 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
401 static 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
418 int 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
441 int 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
464 int 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
514 int 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
584 static 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
591 static 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
603 static 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
626 static 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
634 static 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
653 static 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
671 static 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
679 static 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
698 static 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
712 static 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
730 static 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
744 static 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
761 int 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
775 int 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
790 static 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
801 static 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
813 static 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
821 const 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
827 static 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
839 static 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
847 const 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
853 static 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
864 static 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
892 static 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
899 const 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
905 static 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
918 static 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
929 static 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
955 static 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
973 int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
974 {
975 return mv88e6xxx_g2_misc_5_bit_port(chip, false);
976 }
977
978 static 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
986 static 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
994 static 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 }
1016 out:
1017 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
1018 }
1019
1020 static 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
1027 static 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
1039 static 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
1047 static 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
1060 static 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
1065 void 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
1082 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
1083 {
1084 int err, irq, virq;
1085
1086 chip->g2_irq.masked = ~0;
1087 mv88e6xxx_reg_lock(chip);
1088 err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
1089 mv88e6xxx_reg_unlock(chip);
1090 if (err)
1091 return err;
1092
1093 chip->g2_irq.domain = irq_domain_add_simple(
1094 chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
1095 if (!chip->g2_irq.domain)
1096 return -ENOMEM;
1097
1098 for (irq = 0; irq < 16; irq++)
1099 irq_create_mapping(chip->g2_irq.domain, irq);
1100
1101 chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
1102
1103 chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
1104 MV88E6XXX_G1_STS_IRQ_DEVICE);
1105 if (chip->device_irq < 0) {
1106 err = chip->device_irq;
1107 goto out;
1108 }
1109
1110 err = request_threaded_irq(chip->device_irq, NULL,
1111 mv88e6xxx_g2_irq_thread_fn,
1112 IRQF_ONESHOT, "mv88e6xxx-g2", chip);
1113 if (err)
1114 goto out;
1115
1116 return mv88e6xxx_g2_watchdog_setup(chip);
1117
1118 out:
1119 for (irq = 0; irq < 16; irq++) {
1120 virq = irq_find_mapping(chip->g2_irq.domain, irq);
1121 irq_dispose_mapping(virq);
1122 }
1123
1124 irq_domain_remove(chip->g2_irq.domain);
1125
1126 return err;
1127 }
1128
1129 int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
1130 struct mii_bus *bus)
1131 {
1132 int phy, irq, err, err_phy;
1133
1134 for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
1135 irq = irq_find_mapping(chip->g2_irq.domain, phy);
1136 if (irq < 0) {
1137 err = irq;
1138 goto out;
1139 }
1140 bus->irq[chip->info->phy_base_addr + phy] = irq;
1141 }
1142 return 0;
1143 out:
1144 err_phy = phy;
1145
1146 for (phy = 0; phy < err_phy; phy++)
1147 irq_dispose_mapping(bus->irq[phy]);
1148
1149 return err;
1150 }
1151
1152 void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
1153 struct mii_bus *bus)
1154 {
1155 int phy;
1156
1157 for (phy = 0; phy < chip->info->num_internal_phys; phy++)
1158 irq_dispose_mapping(bus->irq[phy]);
1159 }