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 mv88e6352_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 err
= mv88e6xxx_g1_wait_init_ready(chip
);
205 return mv88e6352_g1_wait_ppu_polling(chip
);
208 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip
*chip
)
213 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
217 val
|= MV88E6XXX_G1_CTL1_PPU_ENABLE
;
219 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
223 return mv88e6185_g1_wait_ppu_polling(chip
);
226 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip
*chip
)
231 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL1
, &val
);
235 val
&= ~MV88E6XXX_G1_CTL1_PPU_ENABLE
;
237 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL1
, val
);
241 return mv88e6185_g1_wait_ppu_disabled(chip
);
244 /* Offset 0x1a: Monitor Control */
245 /* Offset 0x1a: Monitor & MGMT Control on some devices */
247 int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip
*chip
, int port
)
252 err
= mv88e6xxx_g1_read(chip
, MV88E6185_G1_MONITOR_CTL
, ®
);
256 reg
&= ~(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK
|
257 MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK
);
259 reg
|= port
<< __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK
) |
260 port
<< __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK
);
262 return mv88e6xxx_g1_write(chip
, MV88E6185_G1_MONITOR_CTL
, reg
);
265 /* Older generations also call this the ARP destination. It has been
266 * generalized in more modern devices such that more than ARP can
269 int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip
*chip
, int port
)
274 err
= mv88e6xxx_g1_read(chip
, MV88E6185_G1_MONITOR_CTL
, ®
);
278 reg
&= ~MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK
;
279 reg
|= port
<< __bf_shf(MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK
);
281 return mv88e6xxx_g1_write(chip
, MV88E6185_G1_MONITOR_CTL
, reg
);
284 static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip
*chip
,
285 u16 pointer
, u8 data
)
289 reg
= MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE
| pointer
| data
;
291 return mv88e6xxx_g1_write(chip
, MV88E6390_G1_MONITOR_MGMT_CTL
, reg
);
294 int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip
*chip
, int port
)
299 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST
;
300 err
= mv88e6390_g1_monitor_write(chip
, ptr
, port
);
304 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST
;
305 err
= mv88e6390_g1_monitor_write(chip
, ptr
, port
);
312 int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip
*chip
, int port
)
314 u16 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST
;
316 return mv88e6390_g1_monitor_write(chip
, ptr
, port
);
319 int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip
*chip
)
324 /* 01:c2:80:00:00:00:00-01:c2:80:00:00:00:07 are Management */
325 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000000XLO
;
326 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
330 /* 01:c2:80:00:00:00:08-01:c2:80:00:00:00:0f are Management */
331 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000000XHI
;
332 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
336 /* 01:c2:80:00:00:00:20-01:c2:80:00:00:00:27 are Management */
337 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000002XLO
;
338 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
342 /* 01:c2:80:00:00:00:28-01:c2:80:00:00:00:2f are Management */
343 ptr
= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000002XHI
;
344 err
= mv88e6390_g1_monitor_write(chip
, ptr
, 0xff);
351 /* Offset 0x1c: Global Control 2 */
353 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip
*chip
)
358 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_CTL2
, &val
);
362 val
|= MV88E6XXX_G1_CTL2_HIST_RX_TX
;
364 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_CTL2
, val
);
369 /* Offset 0x1d: Statistics Operation 2 */
371 int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip
*chip
)
373 return mv88e6xxx_g1_wait(chip
, MV88E6XXX_G1_STATS_OP
,
374 MV88E6XXX_G1_STATS_OP_BUSY
);
377 int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip
*chip
)
382 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_OP
, &val
);
386 val
|= MV88E6XXX_G1_STATS_OP_HIST_RX_TX
;
388 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
, val
);
393 int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
397 /* Snapshot the hardware statistics counters for this port. */
398 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
399 MV88E6XXX_G1_STATS_OP_BUSY
|
400 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT
|
401 MV88E6XXX_G1_STATS_OP_HIST_RX_TX
| port
);
405 /* Wait for the snapshotting to complete. */
406 return mv88e6xxx_g1_stats_wait(chip
);
409 int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
411 port
= (port
+ 1) << 5;
413 return mv88e6xxx_g1_stats_snapshot(chip
, port
);
416 int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip
*chip
, int port
)
420 port
= (port
+ 1) << 5;
422 /* Snapshot the hardware statistics counters for this port. */
423 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
424 MV88E6XXX_G1_STATS_OP_BUSY
|
425 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT
| port
);
429 /* Wait for the snapshotting to complete. */
430 return mv88e6xxx_g1_stats_wait(chip
);
433 void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip
*chip
, int stat
, u32
*val
)
441 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
,
442 MV88E6XXX_G1_STATS_OP_BUSY
|
443 MV88E6XXX_G1_STATS_OP_READ_CAPTURED
| stat
);
447 err
= mv88e6xxx_g1_stats_wait(chip
);
451 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_COUNTER_32
, ®
);
457 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_COUNTER_01
, ®
);
464 int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip
*chip
)
469 err
= mv88e6xxx_g1_read(chip
, MV88E6XXX_G1_STATS_OP
, &val
);
473 val
|= MV88E6XXX_G1_STATS_OP_BUSY
| MV88E6XXX_G1_STATS_OP_FLUSH_ALL
;
475 err
= mv88e6xxx_g1_write(chip
, MV88E6XXX_G1_STATS_OP
, val
);
479 /* Wait for the flush to complete. */
480 return mv88e6xxx_g1_stats_wait(chip
);