1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Marvell 88E6xxx Switch Global (1) Registers support
5 * Copyright (c) 2008 Marvell Semiconductor
7 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
8 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
11 #include <linux/bitfield.h>
16 int mv88e6xxx_g1_read(struct mv88e6xxx_chip
*chip
, int reg
, u16
*val
)
18 int addr
= chip
->info
->global1_addr
;
20 return mv88e6xxx_read(chip
, addr
, reg
, val
);
23 int mv88e6xxx_g1_write(struct mv88e6xxx_chip
*chip
, int reg
, u16 val
)
25 int addr
= chip
->info
->global1_addr
;
27 return mv88e6xxx_write(chip
, addr
, reg
, val
);
30 int mv88e6xxx_g1_wait_bit(struct mv88e6xxx_chip
*chip
, int reg
, int
33 return mv88e6xxx_wait_bit(chip
, chip
->info
->global1_addr
, reg
,
37 int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip
*chip
, int reg
,
40 return mv88e6xxx_wait_mask(chip
, chip
->info
->global1_addr
, reg
,
44 /* Offset 0x00: Switch Global Status Register */
46 static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip
*chip
)
48 return mv88e6xxx_g1_wait_mask(chip
, MV88E6XXX_G1_STS
,
49 MV88E6185_G1_STS_PPU_STATE_MASK
,
50 MV88E6185_G1_STS_PPU_STATE_DISABLED
);
53 static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip
*chip
)
55 return mv88e6xxx_g1_wait_mask(chip
, MV88E6XXX_G1_STS
,
56 MV88E6185_G1_STS_PPU_STATE_MASK
,
57 MV88E6185_G1_STS_PPU_STATE_POLLING
);
60 static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip
*chip
)
62 int bit
= __bf_shf(MV88E6352_G1_STS_PPU_STATE
);
64 return mv88e6xxx_g1_wait_bit(chip
, MV88E6XXX_G1_STS
, bit
, 1);
67 static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip
*chip
)
69 int bit
= __bf_shf(MV88E6XXX_G1_STS_INIT_READY
);
71 /* Wait up to 1 second for the switch to be ready. The InitReady bit 11
72 * is set to a one when all units inside the device (ATU, VTU, etc.)
73 * have finished their initialization and are ready to accept frames.
75 return mv88e6xxx_g1_wait_bit(chip
, MV88E6XXX_G1_STS
, bit
, 1);
78 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
79 * Offset 0x02: Switch MAC Address Register Bytes 2 & 3
80 * Offset 0x03: Switch MAC Address Register Bytes 4 & 5
82 int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip
*chip
, u8
*addr
)
87 reg
= (addr
[0] << 8) | addr
[1];
88 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_MAC_01
, reg
);
92 reg
= (addr
[2] << 8) | addr
[3];
93 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_MAC_23
, reg
);
97 reg
= (addr
[4] << 8) | addr
[5];
98 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_MAC_45
, reg
);
105 /* Offset 0x04: Switch Global Control Register */
107 int mv88e6185_g1_reset(struct mv88e6xxx_chip
*chip
)
112 /* Set the SWReset bit 15 along with the PPUEn bit 14, to also restart
113 * the PPU, including re-doing PHY detection and initialization
115 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
119 val
|= MV88E6XXX_G1_CTL1_SW_RESET
;
120 val
|= MV88E6XXX_G1_CTL1_PPU_ENABLE
;
122 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
126 err
= mv88e6xxx_g1_wait_init_ready(chip
);
130 return mv88e6185_g1_wait_ppu_polling(chip
);
133 int mv88e6250_g1_reset(struct mv88e6xxx_chip
*chip
)
138 /* Set the SWReset bit 15 */
139 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
143 val
|= MV88E6XXX_G1_CTL1_SW_RESET
;
145 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
149 return mv88e6xxx_g1_wait_init_ready(chip
);
152 int mv88e6352_g1_reset(struct mv88e6xxx_chip
*chip
)
156 err
= mv88e6250_g1_reset(chip
);
160 return mv88e6352_g1_wait_ppu_polling(chip
);
163 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip
*chip
)
168 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
172 val
|= MV88E6XXX_G1_CTL1_PPU_ENABLE
;
174 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
178 return mv88e6185_g1_wait_ppu_polling(chip
);
181 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip
*chip
)
186 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
190 val
&= ~MV88E6XXX_G1_CTL1_PPU_ENABLE
;
192 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
196 return mv88e6185_g1_wait_ppu_disabled(chip
);
199 /* Offset 0x10: IP-PRI Mapping Register 0
200 * Offset 0x11: IP-PRI Mapping Register 1
201 * Offset 0x12: IP-PRI Mapping Register 2
202 * Offset 0x13: IP-PRI Mapping Register 3
203 * Offset 0x14: IP-PRI Mapping Register 4
204 * Offset 0x15: IP-PRI Mapping Register 5
205 * Offset 0x16: IP-PRI Mapping Register 6
206 * Offset 0x17: IP-PRI Mapping Register 7
209 int mv88e6085_g1_ip_pri_map(struct mv88e6xxx_chip
*chip
)
213 /* Reset the IP TOS/DiffServ/Traffic priorities to defaults */
214 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_0
, 0x0000);
218 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_1
, 0x0000);
222 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_2
, 0x5555);
226 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_3
, 0x5555);
230 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_4
, 0xaaaa);
234 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_5
, 0xaaaa);
238 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_6
, 0xffff);
242 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IP_PRI_7
, 0xffff);
249 /* Offset 0x18: IEEE-PRI Register */
251 int mv88e6085_g1_ieee_pri_map(struct mv88e6xxx_chip
*chip
)
253 /* Reset the IEEE Tag priorities to defaults */
254 return mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IEEE_PRI
, 0xfa41);
257 int mv88e6250_g1_ieee_pri_map(struct mv88e6xxx_chip
*chip
)
259 /* Reset the IEEE Tag priorities to defaults */
260 return mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_IEEE_PRI
, 0xfa50);
263 /* Offset 0x1a: Monitor Control */
264 /* Offset 0x1a: Monitor & MGMT Control on some devices */
266 int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip
*chip
,
267 enum mv88e6xxx_egress_direction direction
,
274 err
= mv88e6xxx_g1_read(chip
, MV88E6185_G1_MONITOR_CTL
, ®
);
279 case MV88E6XXX_EGRESS_DIR_INGRESS
:
280 dest_port_chip
= &chip
->ingress_dest_port
;
281 reg
&= MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK
;
283 __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK
);
285 case MV88E6XXX_EGRESS_DIR_EGRESS
:
286 dest_port_chip
= &chip
->egress_dest_port
;
287 reg
&= MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK
;
289 __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK
);
295 err
= mv88e6xxx_g1_write(chip
, MV88E6185_G1_MONITOR_CTL
, reg
);
297 *dest_port_chip
= port
;
302 /* Older generations also call this the ARP destination. It has been
303 * generalized in more modern devices such that more than ARP can
306 int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip
*chip
, int port
)
311 err
= mv88e6xxx_g1_read(chip
, MV88E6185_G1_MONITOR_CTL
, ®
);
315 reg
&= ~MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK
;
316 reg
|= port
<< __bf_shf(MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK
);
318 return mv88e6xxx_g1_write(chip
, MV88E6185_G1_MONITOR_CTL
, reg
);
321 static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip
*chip
,
322 u16 pointer
, u8 data
)
326 reg
= MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE
| pointer
| data
;
328 return mv88e6xxx_g1_write(chip
, MV88E6390_G1_MONITOR_MGMT_CTL
, reg
);
331 int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip
*chip
,
332 enum mv88e6xxx_egress_direction direction
,
340 case MV88E6XXX_EGRESS_DIR_INGRESS
:
341 dest_port_chip
= &chip
->ingress_dest_port
;
342 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST
;
344 case MV88E6XXX_EGRESS_DIR_EGRESS
:
345 dest_port_chip
= &chip
->egress_dest_port
;
346 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST
;
352 err
= mv88e6390_g1_monitor_write(chip
, ptr
, port
);
354 *dest_port_chip
= port
;
359 int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip
*chip
, int port
)
361 u16 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST
;
363 /* Use the default high priority for management frames sent to
366 port
|= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI
;
368 return mv88e6390_g1_monitor_write(chip
, ptr
, port
);
371 int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip
*chip
)
376 /* 01:80:c2:00:00:00-01:80:c2:00:00:07 are Management */
377 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XLO
;
378 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
382 /* 01:80:c2:00:00:08-01:80:c2:00:00:0f are Management */
383 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XHI
;
384 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
388 /* 01:80:c2:00:00:20-01:80:c2:00:00:27 are Management */
389 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XLO
;
390 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
394 /* 01:80:c2:00:00:28-01:80:c2:00:00:2f are Management */
395 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XHI
;
396 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
403 /* Offset 0x1c: Global Control 2 */
405 static int mv88e6xxx_g1_ctl2_mask(struct mv88e6xxx_chip
*chip
, u16 mask
,
411 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL2
, ®
);
418 return mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL2
, reg
);
421 int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip
*chip
, int port
)
423 const u16 mask
= MV88E6185_G1_CTL2_CASCADE_PORT_MASK
;
425 return mv88e6xxx_g1_ctl2_mask(chip
, mask
, port
<< __bf_shf(mask
));
428 int mv88e6085_g1_rmu_disable(struct mv88e6xxx_chip
*chip
)
430 return mv88e6xxx_g1_ctl2_mask(chip
, MV88E6085_G1_CTL2_P10RM
|
431 MV88E6085_G1_CTL2_RM_ENABLE
, 0);
434 int mv88e6352_g1_rmu_disable(struct mv88e6xxx_chip
*chip
)
436 return mv88e6xxx_g1_ctl2_mask(chip
, MV88E6352_G1_CTL2_RMU_MODE_MASK
,
437 MV88E6352_G1_CTL2_RMU_MODE_DISABLED
);
440 int mv88e6390_g1_rmu_disable(struct mv88e6xxx_chip
*chip
)
442 return mv88e6xxx_g1_ctl2_mask(chip
, MV88E6390_G1_CTL2_RMU_MODE_MASK
,
443 MV88E6390_G1_CTL2_RMU_MODE_DISABLED
);
446 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip
*chip
)
448 return mv88e6xxx_g1_ctl2_mask(chip
, MV88E6390_G1_CTL2_HIST_MODE_MASK
,
449 MV88E6390_G1_CTL2_HIST_MODE_RX
|
450 MV88E6390_G1_CTL2_HIST_MODE_TX
);
453 int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip
*chip
, int index
)
455 return mv88e6xxx_g1_ctl2_mask(chip
,
456 MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK
,
460 /* Offset 0x1d: Statistics Operation 2 */
462 static int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip
*chip
)
464 int bit
= __bf_shf(MV88E6XXX_G1_STATS_OP_BUSY
);
466 return mv88e6xxx_g1_wait_bit(chip
, MV88E6XXX_G1_STATS_OP
, bit
, 0);
469 int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip
*chip
)
474 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_OP
, &val
);
478 val
|= MV88E6XXX_G1_STATS_OP_HIST_RX_TX
;
480 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
, val
);
485 int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
489 /* Snapshot the hardware statistics counters for this port. */
490 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
491 MV88E6XXX_G1_STATS_OP_BUSY
|
492 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT
|
493 MV88E6XXX_G1_STATS_OP_HIST_RX_TX
| port
);
497 /* Wait for the snapshotting to complete. */
498 return mv88e6xxx_g1_stats_wait(chip
);
501 int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
503 port
= (port
+ 1) << 5;
505 return mv88e6xxx_g1_stats_snapshot(chip
, port
);
508 int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
512 port
= (port
+ 1) << 5;
514 /* Snapshot the hardware statistics counters for this port. */
515 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
516 MV88E6XXX_G1_STATS_OP_BUSY
|
517 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT
| port
);
521 /* Wait for the snapshotting to complete. */
522 return mv88e6xxx_g1_stats_wait(chip
);
525 void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip
*chip
, int stat
, u32
*val
)
533 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
534 MV88E6XXX_G1_STATS_OP_BUSY
|
535 MV88E6XXX_G1_STATS_OP_READ_CAPTURED
| stat
);
539 err
= mv88e6xxx_g1_stats_wait(chip
);
543 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_COUNTER_32
, ®
);
549 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_COUNTER_01
, ®
);
556 int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip
*chip
)
561 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_OP
, &val
);
565 /* Keep the histogram mode bits */
566 val
&= MV88E6XXX_G1_STATS_OP_HIST_RX_TX
;
567 val
|= MV88E6XXX_G1_STATS_OP_BUSY
| MV88E6XXX_G1_STATS_OP_FLUSH_ALL
;
569 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
, val
);
573 /* Wait for the flush to complete. */
574 return mv88e6xxx_g1_stats_wait(chip
);