2 * Marvell 88E6xxx Switch Global (1) Registers support
4 * Copyright (c) 2008 Marvell Semiconductor
6 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
7 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
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.
15 #include <linux/bitfield.h>
20 int mv88e6xxx_g1_read(struct mv88e6xxx_chip
*chip
, int reg
, u16
*val
)
22 int addr
= chip
->info
->global1_addr
;
24 return mv88e6xxx_read(chip
, addr
, reg
, val
);
27 int mv88e6xxx_g1_write(struct mv88e6xxx_chip
*chip
, int reg
, u16 val
)
29 int addr
= chip
->info
->global1_addr
;
31 return mv88e6xxx_write(chip
, addr
, reg
, val
);
34 int mv88e6xxx_g1_wait(struct mv88e6xxx_chip
*chip
, int reg
, u16 mask
)
36 return mv88e6xxx_wait(chip
, chip
->info
->global1_addr
, reg
, mask
);
39 /* Offset 0x00: Switch Global Status Register */
41 static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip
*chip
)
46 for (i
= 0; i
< 16; i
++) {
47 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STS
, &state
);
51 /* Check the value of the PPUState bits 15:14 */
52 state
&= MV88E6185_G1_STS_PPU_STATE_MASK
;
53 if (state
!= MV88E6185_G1_STS_PPU_STATE_POLLING
)
56 usleep_range(1000, 2000);
62 static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip
*chip
)
67 for (i
= 0; i
< 16; ++i
) {
68 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STS
, &state
);
72 /* Check the value of the PPUState bits 15:14 */
73 state
&= MV88E6185_G1_STS_PPU_STATE_MASK
;
74 if (state
== MV88E6185_G1_STS_PPU_STATE_POLLING
)
77 usleep_range(1000, 2000);
83 static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip
*chip
)
88 for (i
= 0; i
< 16; ++i
) {
89 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STS
, &state
);
93 /* Check the value of the PPUState (or InitState) bit 15 */
94 if (state
& MV88E6352_G1_STS_PPU_STATE
)
97 usleep_range(1000, 2000);
103 static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip
*chip
)
105 const unsigned long timeout
= jiffies
+ 1 * HZ
;
109 /* Wait up to 1 second for the switch to be ready. The InitReady bit 11
110 * is set to a one when all units inside the device (ATU, VTU, etc.)
111 * have finished their initialization and are ready to accept frames.
113 while (time_before(jiffies
, timeout
)) {
114 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STS
, &val
);
118 if (val
& MV88E6XXX_G1_STS_INIT_READY
)
121 usleep_range(1000, 2000);
124 if (time_after(jiffies
, timeout
))
130 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
131 * Offset 0x02: Switch MAC Address Register Bytes 2 & 3
132 * Offset 0x03: Switch MAC Address Register Bytes 4 & 5
134 int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip
*chip
, u8
*addr
)
139 reg
= (addr
[0] << 8) | addr
[1];
140 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_MAC_01
, reg
);
144 reg
= (addr
[2] << 8) | addr
[3];
145 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_MAC_23
, reg
);
149 reg
= (addr
[4] << 8) | addr
[5];
150 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_MAC_45
, reg
);
157 /* Offset 0x04: Switch Global Control Register */
159 int mv88e6185_g1_reset(struct mv88e6xxx_chip
*chip
)
164 /* Set the SWReset bit 15 along with the PPUEn bit 14, to also restart
165 * the PPU, including re-doing PHY detection and initialization
167 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
171 val
|= MV88E6XXX_G1_CTL1_SW_RESET
;
172 val
|= MV88E6XXX_G1_CTL1_PPU_ENABLE
;
174 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
178 err
= mv88e6xxx_g1_wait_init_ready(chip
);
182 return mv88e6185_g1_wait_ppu_polling(chip
);
185 int mv88e6250_g1_reset(struct mv88e6xxx_chip
*chip
)
190 /* Set the SWReset bit 15 */
191 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
195 val
|= MV88E6XXX_G1_CTL1_SW_RESET
;
197 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
201 return mv88e6xxx_g1_wait_init_ready(chip
);
204 int mv88e6352_g1_reset(struct mv88e6xxx_chip
*chip
)
209 /* Set the SWReset bit 15 */
210 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
214 val
|= MV88E6XXX_G1_CTL1_SW_RESET
;
216 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
220 err
= mv88e6xxx_g1_wait_init_ready(chip
);
224 return mv88e6352_g1_wait_ppu_polling(chip
);
227 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip
*chip
)
232 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
236 val
|= MV88E6XXX_G1_CTL1_PPU_ENABLE
;
238 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
242 return mv88e6185_g1_wait_ppu_polling(chip
);
245 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip
*chip
)
250 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
254 val
&= ~MV88E6XXX_G1_CTL1_PPU_ENABLE
;
256 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
260 return mv88e6185_g1_wait_ppu_disabled(chip
);
263 /* Offset 0x10: IP-PRI Mapping Register 0
264 * Offset 0x11: IP-PRI Mapping Register 1
265 * Offset 0x12: IP-PRI Mapping Register 2
266 * Offset 0x13: IP-PRI Mapping Register 3
267 * Offset 0x14: IP-PRI Mapping Register 4
268 * Offset 0x15: IP-PRI Mapping Register 5
269 * Offset 0x16: IP-PRI Mapping Register 6
270 * Offset 0x17: IP-PRI Mapping Register 7
273 int mv88e6085_g1_ip_pri_map(struct mv88e6xxx_chip
*chip
)
277 /* Reset the IP TOS/DiffServ/Traffic priorities to defaults */
278 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_0
, 0x0000);
282 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_1
, 0x0000);
286 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_2
, 0x5555);
290 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_3
, 0x5555);
294 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_4
, 0xaaaa);
298 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_5
, 0xaaaa);
302 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_6
, 0xffff);
306 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_7
, 0xffff);
313 /* Offset 0x18: IEEE-PRI Register */
315 int mv88e6085_g1_ieee_pri_map(struct mv88e6xxx_chip
*chip
)
317 /* Reset the IEEE Tag priorities to defaults */
318 return mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IEEE_PRI
, 0xfa41);
321 int mv88e6250_g1_ieee_pri_map(struct mv88e6xxx_chip
*chip
)
323 /* Reset the IEEE Tag priorities to defaults */
324 return mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IEEE_PRI
, 0xfa50);
327 /* Offset 0x1a: Monitor Control */
328 /* Offset 0x1a: Monitor & MGMT Control on some devices */
330 int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip
*chip
, int port
)
335 err
= mv88e6xxx_g1_read(chip
, MV88E6185_G1_MONITOR_CTL
, ®
);
339 reg
&= ~(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK
|
340 MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK
);
342 reg
|= port
<< __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK
) |
343 port
<< __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK
);
345 return mv88e6xxx_g1_write(chip
, MV88E6185_G1_MONITOR_CTL
, reg
);
348 /* Older generations also call this the ARP destination. It has been
349 * generalized in more modern devices such that more than ARP can
352 int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip
*chip
, int port
)
357 err
= mv88e6xxx_g1_read(chip
, MV88E6185_G1_MONITOR_CTL
, ®
);
361 reg
&= ~MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK
;
362 reg
|= port
<< __bf_shf(MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK
);
364 return mv88e6xxx_g1_write(chip
, MV88E6185_G1_MONITOR_CTL
, reg
);
367 static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip
*chip
,
368 u16 pointer
, u8 data
)
372 reg
= MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE
| pointer
| data
;
374 return mv88e6xxx_g1_write(chip
, MV88E6390_G1_MONITOR_MGMT_CTL
, reg
);
377 int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip
*chip
, int port
)
382 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST
;
383 err
= mv88e6390_g1_monitor_write(chip
, ptr
, port
);
387 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST
;
388 err
= mv88e6390_g1_monitor_write(chip
, ptr
, port
);
395 int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip
*chip
, int port
)
397 u16 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST
;
399 return mv88e6390_g1_monitor_write(chip
, ptr
, port
);
402 int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip
*chip
)
407 /* 01:80:c2:00:00:00-01:80:c2:00:00:07 are Management */
408 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XLO
;
409 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
413 /* 01:80:c2:00:00:08-01:80:c2:00:00:0f are Management */
414 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XHI
;
415 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
419 /* 01:80:c2:00:00:20-01:80:c2:00:00:27 are Management */
420 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XLO
;
421 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
425 /* 01:80:c2:00:00:28-01:80:c2:00:00:2f are Management */
426 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XHI
;
427 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
434 /* Offset 0x1c: Global Control 2 */
436 static int mv88e6xxx_g1_ctl2_mask(struct mv88e6xxx_chip
*chip
, u16 mask
,
442 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL2
, ®
);
449 return mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL2
, reg
);
452 int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip
*chip
, int port
)
454 const u16 mask
= MV88E6185_G1_CTL2_CASCADE_PORT_MASK
;
456 return mv88e6xxx_g1_ctl2_mask(chip
, mask
, port
<< __bf_shf(mask
));
459 int mv88e6085_g1_rmu_disable(struct mv88e6xxx_chip
*chip
)
461 return mv88e6xxx_g1_ctl2_mask(chip
, MV88E6085_G1_CTL2_P10RM
|
462 MV88E6085_G1_CTL2_RM_ENABLE
, 0);
465 int mv88e6352_g1_rmu_disable(struct mv88e6xxx_chip
*chip
)
467 return mv88e6xxx_g1_ctl2_mask(chip
, MV88E6352_G1_CTL2_RMU_MODE_MASK
,
468 MV88E6352_G1_CTL2_RMU_MODE_DISABLED
);
471 int mv88e6390_g1_rmu_disable(struct mv88e6xxx_chip
*chip
)
473 return mv88e6xxx_g1_ctl2_mask(chip
, MV88E6390_G1_CTL2_RMU_MODE_MASK
,
474 MV88E6390_G1_CTL2_RMU_MODE_DISABLED
);
477 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip
*chip
)
479 return mv88e6xxx_g1_ctl2_mask(chip
, MV88E6390_G1_CTL2_HIST_MODE_MASK
,
480 MV88E6390_G1_CTL2_HIST_MODE_RX
|
481 MV88E6390_G1_CTL2_HIST_MODE_TX
);
484 int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip
*chip
, int index
)
486 return mv88e6xxx_g1_ctl2_mask(chip
,
487 MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK
,
491 /* Offset 0x1d: Statistics Operation 2 */
493 static int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip
*chip
)
495 return mv88e6xxx_g1_wait(chip
, MV88E6XXX_G1_STATS_OP
,
496 MV88E6XXX_G1_STATS_OP_BUSY
);
499 int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip
*chip
)
504 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_OP
, &val
);
508 val
|= MV88E6XXX_G1_STATS_OP_HIST_RX_TX
;
510 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
, val
);
515 int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
519 /* Snapshot the hardware statistics counters for this port. */
520 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
521 MV88E6XXX_G1_STATS_OP_BUSY
|
522 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT
|
523 MV88E6XXX_G1_STATS_OP_HIST_RX_TX
| port
);
527 /* Wait for the snapshotting to complete. */
528 return mv88e6xxx_g1_stats_wait(chip
);
531 int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
533 port
= (port
+ 1) << 5;
535 return mv88e6xxx_g1_stats_snapshot(chip
, port
);
538 int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
542 port
= (port
+ 1) << 5;
544 /* Snapshot the hardware statistics counters for this port. */
545 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
546 MV88E6XXX_G1_STATS_OP_BUSY
|
547 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT
| port
);
551 /* Wait for the snapshotting to complete. */
552 return mv88e6xxx_g1_stats_wait(chip
);
555 void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip
*chip
, int stat
, u32
*val
)
563 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
564 MV88E6XXX_G1_STATS_OP_BUSY
|
565 MV88E6XXX_G1_STATS_OP_READ_CAPTURED
| stat
);
569 err
= mv88e6xxx_g1_stats_wait(chip
);
573 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_COUNTER_32
, ®
);
579 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_COUNTER_01
, ®
);
586 int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip
*chip
)
591 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_OP
, &val
);
595 /* Keep the histogram mode bits */
596 val
&= MV88E6XXX_G1_STATS_OP_HIST_RX_TX
;
597 val
|= MV88E6XXX_G1_STATS_OP_BUSY
| MV88E6XXX_G1_STATS_OP_FLUSH_ALL
;
599 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
, val
);
603 /* Wait for the flush to complete. */
604 return mv88e6xxx_g1_stats_wait(chip
);