1 #include <linux/ioport.h>
2 #include <linux/switch.h>
5 #include <rt305x_regs.h>
6 #include <rt305x_esw_platform.h>
9 * HW limitations for this switch:
10 * - No large frame support (PKT_MAX_LEN at most 1536)
11 * - Can't have untagged vlan and tagged vlan on one port at the same time,
12 * though this might be possible using the undocumented PPE.
15 #define RT305X_ESW_REG_FCT0 0x08
16 #define RT305X_ESW_REG_PFC1 0x14
17 #define RT305X_ESW_REG_ATS 0x24
18 #define RT305X_ESW_REG_ATS0 0x28
19 #define RT305X_ESW_REG_ATS1 0x2c
20 #define RT305X_ESW_REG_ATS2 0x30
21 #define RT305X_ESW_REG_PVIDC(_n) (0x40 + 4 * (_n))
22 #define RT305X_ESW_REG_VLANI(_n) (0x50 + 4 * (_n))
23 #define RT305X_ESW_REG_VMSC(_n) (0x70 + 4 * (_n))
24 #define RT305X_ESW_REG_POA 0x80
25 #define RT305X_ESW_REG_FPA 0x84
26 #define RT305X_ESW_REG_SOCPC 0x8c
27 #define RT305X_ESW_REG_POC0 0x90
28 #define RT305X_ESW_REG_POC1 0x94
29 #define RT305X_ESW_REG_POC2 0x98
30 #define RT305X_ESW_REG_SGC 0x9c
31 #define RT305X_ESW_REG_STRT 0xa0
32 #define RT305X_ESW_REG_PCR0 0xc0
33 #define RT305X_ESW_REG_PCR1 0xc4
34 #define RT305X_ESW_REG_FPA2 0xc8
35 #define RT305X_ESW_REG_FCT2 0xcc
36 #define RT305X_ESW_REG_SGC2 0xe4
37 #define RT305X_ESW_REG_P0LED 0xa4
38 #define RT305X_ESW_REG_P1LED 0xa8
39 #define RT305X_ESW_REG_P2LED 0xac
40 #define RT305X_ESW_REG_P3LED 0xb0
41 #define RT305X_ESW_REG_P4LED 0xb4
42 #define RT305X_ESW_REG_P0PC 0xe8
43 #define RT305X_ESW_REG_P1PC 0xec
44 #define RT305X_ESW_REG_P2PC 0xf0
45 #define RT305X_ESW_REG_P3PC 0xf4
46 #define RT305X_ESW_REG_P4PC 0xf8
47 #define RT305X_ESW_REG_P5PC 0xfc
49 #define RT305X_ESW_LED_LINK 0
50 #define RT305X_ESW_LED_100M 1
51 #define RT305X_ESW_LED_DUPLEX 2
52 #define RT305X_ESW_LED_ACTIVITY 3
53 #define RT305X_ESW_LED_COLLISION 4
54 #define RT305X_ESW_LED_LINKACT 5
55 #define RT305X_ESW_LED_DUPLCOLL 6
56 #define RT305X_ESW_LED_10MACT 7
57 #define RT305X_ESW_LED_100MACT 8
58 /* Additional led states not in datasheet: */
59 #define RT305X_ESW_LED_BLINK 10
60 #define RT305X_ESW_LED_ON 12
62 #define RT305X_ESW_LINK_S 25
63 #define RT305X_ESW_DUPLEX_S 9
64 #define RT305X_ESW_SPD_S 0
66 #define RT305X_ESW_PCR0_WT_NWAY_DATA_S 16
67 #define RT305X_ESW_PCR0_WT_PHY_CMD BIT(13)
68 #define RT305X_ESW_PCR0_CPU_PHY_REG_S 8
70 #define RT305X_ESW_PCR1_WT_DONE BIT(0)
72 #define RT305X_ESW_ATS_TIMEOUT (5 * HZ)
73 #define RT305X_ESW_PHY_TIMEOUT (5 * HZ)
75 #define RT305X_ESW_PVIDC_PVID_M 0xfff
76 #define RT305X_ESW_PVIDC_PVID_S 12
78 #define RT305X_ESW_VLANI_VID_M 0xfff
79 #define RT305X_ESW_VLANI_VID_S 12
81 #define RT305X_ESW_VMSC_MSC_M 0xff
82 #define RT305X_ESW_VMSC_MSC_S 8
84 #define RT305X_ESW_SOCPC_DISUN2CPU_S 0
85 #define RT305X_ESW_SOCPC_DISMC2CPU_S 8
86 #define RT305X_ESW_SOCPC_DISBC2CPU_S 16
87 #define RT305X_ESW_SOCPC_CRC_PADDING BIT(25)
89 #define RT305X_ESW_POC0_EN_BP_S 0
90 #define RT305X_ESW_POC0_EN_FC_S 8
91 #define RT305X_ESW_POC0_DIS_RMC2CPU_S 16
92 #define RT305X_ESW_POC0_DIS_PORT_M 0x7f
93 #define RT305X_ESW_POC0_DIS_PORT_S 23
95 #define RT305X_ESW_POC2_UNTAG_EN_M 0xff
96 #define RT305X_ESW_POC2_UNTAG_EN_S 0
97 #define RT305X_ESW_POC2_ENAGING_S 8
98 #define RT305X_ESW_POC2_DIS_UC_PAUSE_S 16
100 #define RT305X_ESW_SGC2_DOUBLE_TAG_M 0x7f
101 #define RT305X_ESW_SGC2_DOUBLE_TAG_S 0
102 #define RT305X_ESW_SGC2_LAN_PMAP_M 0x3f
103 #define RT305X_ESW_SGC2_LAN_PMAP_S 24
105 #define RT305X_ESW_PFC1_EN_VLAN_M 0xff
106 #define RT305X_ESW_PFC1_EN_VLAN_S 16
107 #define RT305X_ESW_PFC1_EN_TOS_S 24
109 #define RT305X_ESW_VLAN_NONE 0xfff
111 #define RT305X_ESW_PORT0 0
112 #define RT305X_ESW_PORT1 1
113 #define RT305X_ESW_PORT2 2
114 #define RT305X_ESW_PORT3 3
115 #define RT305X_ESW_PORT4 4
116 #define RT305X_ESW_PORT5 5
117 #define RT305X_ESW_PORT6 6
119 #define RT305X_ESW_PORTS_NONE 0
121 #define RT305X_ESW_PMAP_LLLLLL 0x3f
122 #define RT305X_ESW_PMAP_LLLLWL 0x2f
123 #define RT305X_ESW_PMAP_WLLLLL 0x3e
125 #define RT305X_ESW_PORTS_INTERNAL \
126 (BIT(RT305X_ESW_PORT0) | BIT(RT305X_ESW_PORT1) | \
127 BIT(RT305X_ESW_PORT2) | BIT(RT305X_ESW_PORT3) | \
128 BIT(RT305X_ESW_PORT4))
130 #define RT305X_ESW_PORTS_NOCPU \
131 (RT305X_ESW_PORTS_INTERNAL | BIT(RT305X_ESW_PORT5))
133 #define RT305X_ESW_PORTS_CPU BIT(RT305X_ESW_PORT6)
135 #define RT305X_ESW_PORTS_ALL \
136 (RT305X_ESW_PORTS_NOCPU | RT305X_ESW_PORTS_CPU)
138 #define RT305X_ESW_NUM_VLANS 16
139 #define RT305X_ESW_NUM_VIDS 4096
140 #define RT305X_ESW_NUM_PORTS 7
141 #define RT305X_ESW_NUM_LANWAN 6
142 #define RT305X_ESW_NUM_LEDS 5
145 /* Global attributes. */
146 RT305X_ESW_ATTR_ENABLE_VLAN
,
147 RT305X_ESW_ATTR_ALT_VLAN_DISABLE
,
148 /* Port attributes. */
149 RT305X_ESW_ATTR_PORT_DISABLE
,
150 RT305X_ESW_ATTR_PORT_DOUBLETAG
,
151 RT305X_ESW_ATTR_PORT_UNTAG
,
152 RT305X_ESW_ATTR_PORT_LED
,
153 RT305X_ESW_ATTR_PORT_LAN
,
154 RT305X_ESW_ATTR_PORT_RECV_BAD
,
155 RT305X_ESW_ATTR_PORT_RECV_GOOD
,
158 struct rt305x_esw_port
{
166 struct rt305x_esw_vlan
{
173 struct rt305x_esw_platform_data
*pdata
;
174 /* Protects against concurrent register rmw operations. */
175 spinlock_t reg_rw_lock
;
177 struct switch_dev swdev
;
178 bool global_vlan_enable
;
179 bool alt_vlan_disable
;
180 struct rt305x_esw_vlan vlans
[RT305X_ESW_NUM_VLANS
];
181 struct rt305x_esw_port ports
[RT305X_ESW_NUM_PORTS
];
186 rt305x_esw_wr(struct rt305x_esw
*esw
, u32 val
, unsigned reg
)
188 __raw_writel(val
, esw
->base
+ reg
);
192 rt305x_esw_rr(struct rt305x_esw
*esw
, unsigned reg
)
194 return __raw_readl(esw
->base
+ reg
);
198 rt305x_esw_rmw_raw(struct rt305x_esw
*esw
, unsigned reg
, unsigned long mask
,
203 t
= __raw_readl(esw
->base
+ reg
) & ~mask
;
204 __raw_writel(t
| val
, esw
->base
+ reg
);
208 rt305x_esw_rmw(struct rt305x_esw
*esw
, unsigned reg
, unsigned long mask
,
213 spin_lock_irqsave(&esw
->reg_rw_lock
, flags
);
214 rt305x_esw_rmw_raw(esw
, reg
, mask
, val
);
215 spin_unlock_irqrestore(&esw
->reg_rw_lock
, flags
);
219 rt305x_mii_write(struct rt305x_esw
*esw
, u32 phy_addr
, u32 phy_register
,
222 unsigned long t_start
= jiffies
;
226 if (!(rt305x_esw_rr(esw
, RT305X_ESW_REG_PCR1
) &
227 RT305X_ESW_PCR1_WT_DONE
))
229 if (time_after(jiffies
, t_start
+ RT305X_ESW_PHY_TIMEOUT
)) {
235 write_data
&= 0xffff;
237 (write_data
<< RT305X_ESW_PCR0_WT_NWAY_DATA_S
) |
238 (phy_register
<< RT305X_ESW_PCR0_CPU_PHY_REG_S
) |
239 (phy_addr
) | RT305X_ESW_PCR0_WT_PHY_CMD
,
240 RT305X_ESW_REG_PCR0
);
244 if (rt305x_esw_rr(esw
, RT305X_ESW_REG_PCR1
) &
245 RT305X_ESW_PCR1_WT_DONE
)
248 if (time_after(jiffies
, t_start
+ RT305X_ESW_PHY_TIMEOUT
)) {
255 printk(KERN_ERR
"ramips_eth: MDIO timeout\n");
260 rt305x_esw_get_vlan_id(struct rt305x_esw
*esw
, unsigned vlan
)
265 s
= RT305X_ESW_VLANI_VID_S
* (vlan
% 2);
266 val
= rt305x_esw_rr(esw
, RT305X_ESW_REG_VLANI(vlan
/ 2));
267 val
= (val
>> s
) & RT305X_ESW_VLANI_VID_M
;
273 rt305x_esw_set_vlan_id(struct rt305x_esw
*esw
, unsigned vlan
, unsigned vid
)
277 s
= RT305X_ESW_VLANI_VID_S
* (vlan
% 2);
279 RT305X_ESW_REG_VLANI(vlan
/ 2),
280 RT305X_ESW_VLANI_VID_M
<< s
,
281 (vid
& RT305X_ESW_VLANI_VID_M
) << s
);
285 rt305x_esw_get_pvid(struct rt305x_esw
*esw
, unsigned port
)
289 s
= RT305X_ESW_PVIDC_PVID_S
* (port
% 2);
290 val
= rt305x_esw_rr(esw
, RT305X_ESW_REG_PVIDC(port
/ 2));
291 return (val
>> s
) & RT305X_ESW_PVIDC_PVID_M
;
295 rt305x_esw_set_pvid(struct rt305x_esw
*esw
, unsigned port
, unsigned pvid
)
299 s
= RT305X_ESW_PVIDC_PVID_S
* (port
% 2);
301 RT305X_ESW_REG_PVIDC(port
/ 2),
302 RT305X_ESW_PVIDC_PVID_M
<< s
,
303 (pvid
& RT305X_ESW_PVIDC_PVID_M
) << s
);
307 rt305x_esw_get_vmsc(struct rt305x_esw
*esw
, unsigned vlan
)
311 s
= RT305X_ESW_VMSC_MSC_S
* (vlan
% 4);
312 val
= rt305x_esw_rr(esw
, RT305X_ESW_REG_VMSC(vlan
/ 4));
313 val
= (val
>> s
) & RT305X_ESW_VMSC_MSC_M
;
319 rt305x_esw_set_vmsc(struct rt305x_esw
*esw
, unsigned vlan
, unsigned msc
)
323 s
= RT305X_ESW_VMSC_MSC_S
* (vlan
% 4);
325 RT305X_ESW_REG_VMSC(vlan
/ 4),
326 RT305X_ESW_VMSC_MSC_M
<< s
,
327 (msc
& RT305X_ESW_VMSC_MSC_M
) << s
);
331 rt305x_esw_get_port_disable(struct rt305x_esw
*esw
)
334 reg
= rt305x_esw_rr(esw
, RT305X_ESW_REG_POC0
);
335 return (reg
>> RT305X_ESW_POC0_DIS_PORT_S
) &
336 RT305X_ESW_POC0_DIS_PORT_M
;
340 rt305x_esw_set_port_disable(struct rt305x_esw
*esw
, unsigned disable_mask
)
343 unsigned enable_mask
;
347 old_mask
= rt305x_esw_get_port_disable(esw
);
348 changed
= old_mask
^ disable_mask
;
349 enable_mask
= old_mask
& disable_mask
;
351 /* enable before writing to MII */
352 rt305x_esw_rmw(esw
, RT305X_ESW_REG_POC0
,
353 (RT305X_ESW_POC0_DIS_PORT_M
<<
354 RT305X_ESW_POC0_DIS_PORT_S
),
355 enable_mask
<< RT305X_ESW_POC0_DIS_PORT_S
);
357 for (i
= 0; i
< RT305X_ESW_NUM_LEDS
; i
++) {
358 if (!(changed
& (1 << i
)))
360 if (disable_mask
& (1 << i
)) {
362 rt305x_mii_write(esw
, i
, MII_BMCR
,
366 rt305x_mii_write(esw
, i
, MII_BMCR
,
374 /* disable after writing to MII */
375 rt305x_esw_rmw(esw
, RT305X_ESW_REG_POC0
,
376 (RT305X_ESW_POC0_DIS_PORT_M
<<
377 RT305X_ESW_POC0_DIS_PORT_S
),
378 disable_mask
<< RT305X_ESW_POC0_DIS_PORT_S
);
382 rt305x_esw_apply_config(struct switch_dev
*dev
);
385 rt305x_esw_hw_init(struct rt305x_esw
*esw
)
389 u8 port_map
= RT305X_ESW_PMAP_LLLLLL
;
391 /* vodoo from original driver */
392 rt305x_esw_wr(esw
, 0xC8A07850, RT305X_ESW_REG_FCT0
);
393 rt305x_esw_wr(esw
, 0x00000000, RT305X_ESW_REG_SGC2
);
394 /* Port priority 1 for all ports, vlan enabled. */
395 rt305x_esw_wr(esw
, 0x00005555 |
396 (RT305X_ESW_PORTS_ALL
<< RT305X_ESW_PFC1_EN_VLAN_S
),
397 RT305X_ESW_REG_PFC1
);
399 /* Enable Back Pressure, and Flow Control */
401 ((RT305X_ESW_PORTS_ALL
<< RT305X_ESW_POC0_EN_BP_S
) |
402 (RT305X_ESW_PORTS_ALL
<< RT305X_ESW_POC0_EN_FC_S
)),
403 RT305X_ESW_REG_POC0
);
405 /* Enable Aging, and VLAN TAG removal */
407 ((RT305X_ESW_PORTS_ALL
<< RT305X_ESW_POC2_ENAGING_S
) |
408 (RT305X_ESW_PORTS_NOCPU
<< RT305X_ESW_POC2_UNTAG_EN_S
)),
409 RT305X_ESW_REG_POC2
);
411 rt305x_esw_wr(esw
, esw
->pdata
->reg_initval_fct2
, RT305X_ESW_REG_FCT2
);
414 * 300s aging timer, max packet len 1536, broadcast storm prevention
415 * disabled, disable collision abort, mac xor48 hash, 10 packet back
416 * pressure jam, GMII disable was_transmit, back pressure disabled,
417 * 30ms led flash, unmatched IGMP as broadcast, rmc tb fault to all
420 rt305x_esw_wr(esw
, 0x0008a301, RT305X_ESW_REG_SGC
);
422 /* Setup SoC Port control register */
424 (RT305X_ESW_SOCPC_CRC_PADDING
|
425 (RT305X_ESW_PORTS_CPU
<< RT305X_ESW_SOCPC_DISUN2CPU_S
) |
426 (RT305X_ESW_PORTS_CPU
<< RT305X_ESW_SOCPC_DISMC2CPU_S
) |
427 (RT305X_ESW_PORTS_CPU
<< RT305X_ESW_SOCPC_DISBC2CPU_S
)),
428 RT305X_ESW_REG_SOCPC
);
430 rt305x_esw_wr(esw
, esw
->pdata
->reg_initval_fpa2
, RT305X_ESW_REG_FPA2
);
431 rt305x_esw_wr(esw
, 0x00000000, RT305X_ESW_REG_FPA
);
433 /* Force Link/Activity on ports */
434 rt305x_esw_wr(esw
, 0x00000005, RT305X_ESW_REG_P0LED
);
435 rt305x_esw_wr(esw
, 0x00000005, RT305X_ESW_REG_P1LED
);
436 rt305x_esw_wr(esw
, 0x00000005, RT305X_ESW_REG_P2LED
);
437 rt305x_esw_wr(esw
, 0x00000005, RT305X_ESW_REG_P3LED
);
438 rt305x_esw_wr(esw
, 0x00000005, RT305X_ESW_REG_P4LED
);
440 /* Copy disabled port configuration from bootloader setup */
441 port_disable
= rt305x_esw_get_port_disable(esw
);
442 for (i
= 0; i
< 6; i
++)
443 esw
->ports
[i
].disable
= (port_disable
& (1 << i
)) != 0;
445 rt305x_mii_write(esw
, 0, 31, 0x8000);
446 for (i
= 0; i
< 5; i
++) {
447 if (esw
->ports
[i
].disable
) {
448 rt305x_mii_write(esw
, i
, MII_BMCR
, BMCR_PDOWN
);
450 rt305x_mii_write(esw
, i
, MII_BMCR
,
455 /* TX10 waveform coefficient */
456 rt305x_mii_write(esw
, i
, 26, 0x1601);
457 /* TX100/TX10 AD/DA current bias */
458 rt305x_mii_write(esw
, i
, 29, 0x7058);
459 /* TX100 slew rate control */
460 rt305x_mii_write(esw
, i
, 30, 0x0018);
464 /* select global register */
465 rt305x_mii_write(esw
, 0, 31, 0x0);
466 /* tune TP_IDL tail and head waveform */
467 rt305x_mii_write(esw
, 0, 22, 0x052f);
468 /* set TX10 signal amplitude threshold to minimum */
469 rt305x_mii_write(esw
, 0, 17, 0x0fe0);
470 /* set squelch amplitude to higher threshold */
471 rt305x_mii_write(esw
, 0, 18, 0x40ba);
472 /* longer TP_IDL tail length */
473 rt305x_mii_write(esw
, 0, 14, 0x65);
474 /* select local register */
475 rt305x_mii_write(esw
, 0, 31, 0x8000);
477 switch (esw
->pdata
->vlan_config
) {
478 case RT305X_ESW_VLAN_CONFIG_NONE
:
479 port_map
= RT305X_ESW_PMAP_LLLLLL
;
481 case RT305X_ESW_VLAN_CONFIG_LLLLW
:
482 port_map
= RT305X_ESW_PMAP_LLLLWL
;
484 case RT305X_ESW_VLAN_CONFIG_WLLLL
:
485 port_map
= RT305X_ESW_PMAP_WLLLLL
;
492 * Unused HW feature, but still nice to be consistent here...
493 * This is also exported to userspace ('lan' attribute) so it's
494 * conveniently usable to decide which ports go into the wan vlan by
497 rt305x_esw_rmw(esw
, RT305X_ESW_REG_SGC2
,
498 RT305X_ESW_SGC2_LAN_PMAP_M
<< RT305X_ESW_SGC2_LAN_PMAP_S
,
499 port_map
<< RT305X_ESW_SGC2_LAN_PMAP_S
);
501 /* make the switch leds blink */
502 for (i
= 0; i
< RT305X_ESW_NUM_LEDS
; i
++)
503 esw
->ports
[i
].led
= 0x05;
505 /* Apply the empty config. */
506 rt305x_esw_apply_config(&esw
->swdev
);
510 rt305x_esw_apply_config(struct switch_dev
*dev
)
512 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
519 for (i
= 0; i
< RT305X_ESW_NUM_VLANS
; i
++) {
521 if (esw
->global_vlan_enable
) {
522 vid
= esw
->vlans
[i
].vid
;
523 vmsc
= esw
->vlans
[i
].ports
;
525 vid
= RT305X_ESW_VLAN_NONE
;
526 vmsc
= RT305X_ESW_PORTS_NONE
;
528 rt305x_esw_set_vlan_id(esw
, i
, vid
);
529 rt305x_esw_set_vmsc(esw
, i
, vmsc
);
532 for (i
= 0; i
< RT305X_ESW_NUM_PORTS
; i
++) {
534 disable
|= esw
->ports
[i
].disable
<< i
;
535 if (esw
->global_vlan_enable
) {
536 doubletag
|= esw
->ports
[i
].doubletag
<< i
;
538 untag
|= esw
->ports
[i
].untag
<< i
;
539 pvid
= esw
->ports
[i
].pvid
;
541 int x
= esw
->alt_vlan_disable
? 0 : 1;
547 rt305x_esw_set_pvid(esw
, i
, pvid
);
548 if (i
< RT305X_ESW_NUM_LEDS
)
549 rt305x_esw_wr(esw
, esw
->ports
[i
].led
,
550 RT305X_ESW_REG_P0LED
+ 4*i
);
553 rt305x_esw_set_port_disable(esw
, disable
);
554 rt305x_esw_rmw(esw
, RT305X_ESW_REG_SGC2
,
555 (RT305X_ESW_SGC2_DOUBLE_TAG_M
<<
556 RT305X_ESW_SGC2_DOUBLE_TAG_S
),
557 doubletag
<< RT305X_ESW_SGC2_DOUBLE_TAG_S
);
558 rt305x_esw_rmw(esw
, RT305X_ESW_REG_PFC1
,
559 RT305X_ESW_PFC1_EN_VLAN_M
<< RT305X_ESW_PFC1_EN_VLAN_S
,
560 en_vlan
<< RT305X_ESW_PFC1_EN_VLAN_S
);
561 rt305x_esw_rmw(esw
, RT305X_ESW_REG_POC2
,
562 RT305X_ESW_POC2_UNTAG_EN_M
<< RT305X_ESW_POC2_UNTAG_EN_S
,
563 untag
<< RT305X_ESW_POC2_UNTAG_EN_S
);
565 if (!esw
->global_vlan_enable
) {
567 * Still need to put all ports into vlan 0 or they'll be
569 * NOTE: vlan 0 is special, no vlan tag is prepended
571 rt305x_esw_set_vlan_id(esw
, 0, 0);
572 rt305x_esw_set_vmsc(esw
, 0, RT305X_ESW_PORTS_ALL
);
579 rt305x_esw_reset_switch(struct switch_dev
*dev
)
581 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
582 esw
->global_vlan_enable
= 0;
583 memset(esw
->ports
, 0, sizeof(esw
->ports
));
584 memset(esw
->vlans
, 0, sizeof(esw
->vlans
));
585 rt305x_esw_hw_init(esw
);
591 rt305x_esw_get_vlan_enable(struct switch_dev
*dev
,
592 const struct switch_attr
*attr
,
593 struct switch_val
*val
)
595 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
597 val
->value
.i
= esw
->global_vlan_enable
;
603 rt305x_esw_set_vlan_enable(struct switch_dev
*dev
,
604 const struct switch_attr
*attr
,
605 struct switch_val
*val
)
607 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
609 esw
->global_vlan_enable
= val
->value
.i
!= 0;
615 rt305x_esw_get_alt_vlan_disable(struct switch_dev
*dev
,
616 const struct switch_attr
*attr
,
617 struct switch_val
*val
)
619 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
621 val
->value
.i
= esw
->alt_vlan_disable
;
627 rt305x_esw_set_alt_vlan_disable(struct switch_dev
*dev
,
628 const struct switch_attr
*attr
,
629 struct switch_val
*val
)
631 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
633 esw
->alt_vlan_disable
= val
->value
.i
!= 0;
639 rt305x_esw_get_port_link(struct switch_dev
*dev
,
641 struct switch_port_link
*link
)
643 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
646 if (port
< 0 || port
>= RT305X_ESW_NUM_PORTS
)
649 poa
= rt305x_esw_rr(esw
, RT305X_ESW_REG_POA
) >> port
;
651 link
->link
= (poa
>> RT305X_ESW_LINK_S
) & 1;
652 link
->duplex
= (poa
>> RT305X_ESW_DUPLEX_S
) & 1;
653 if (port
< RT305X_ESW_NUM_LEDS
) {
654 speed
= (poa
>> RT305X_ESW_SPD_S
) & 1;
656 if (port
== RT305X_ESW_NUM_PORTS
- 1)
658 speed
= (poa
>> RT305X_ESW_SPD_S
) & 3;
662 link
->speed
= SWITCH_PORT_SPEED_10
;
665 link
->speed
= SWITCH_PORT_SPEED_100
;
668 case 3: /* forced gige speed can be 2 or 3 */
669 link
->speed
= SWITCH_PORT_SPEED_1000
;
672 link
->speed
= SWITCH_PORT_SPEED_UNKNOWN
;
680 rt305x_esw_get_port_bool(struct switch_dev
*dev
,
681 const struct switch_attr
*attr
,
682 struct switch_val
*val
)
684 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
685 int idx
= val
->port_vlan
;
688 if (idx
< 0 || idx
>= RT305X_ESW_NUM_PORTS
)
692 case RT305X_ESW_ATTR_PORT_DISABLE
:
693 reg
= RT305X_ESW_REG_POC0
;
694 shift
= RT305X_ESW_POC0_DIS_PORT_S
;
696 case RT305X_ESW_ATTR_PORT_DOUBLETAG
:
697 reg
= RT305X_ESW_REG_SGC2
;
698 shift
= RT305X_ESW_SGC2_DOUBLE_TAG_S
;
700 case RT305X_ESW_ATTR_PORT_UNTAG
:
701 reg
= RT305X_ESW_REG_POC2
;
702 shift
= RT305X_ESW_POC2_UNTAG_EN_S
;
704 case RT305X_ESW_ATTR_PORT_LAN
:
705 reg
= RT305X_ESW_REG_SGC2
;
706 shift
= RT305X_ESW_SGC2_LAN_PMAP_S
;
707 if (idx
>= RT305X_ESW_NUM_LANWAN
)
714 x
= rt305x_esw_rr(esw
, reg
);
715 val
->value
.i
= (x
>> (idx
+ shift
)) & 1;
721 rt305x_esw_set_port_bool(struct switch_dev
*dev
,
722 const struct switch_attr
*attr
,
723 struct switch_val
*val
)
725 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
726 int idx
= val
->port_vlan
;
728 if (idx
< 0 || idx
>= RT305X_ESW_NUM_PORTS
||
729 val
->value
.i
< 0 || val
->value
.i
> 1)
733 case RT305X_ESW_ATTR_PORT_DISABLE
:
734 esw
->ports
[idx
].disable
= val
->value
.i
;
736 case RT305X_ESW_ATTR_PORT_DOUBLETAG
:
737 esw
->ports
[idx
].doubletag
= val
->value
.i
;
739 case RT305X_ESW_ATTR_PORT_UNTAG
:
740 esw
->ports
[idx
].untag
= val
->value
.i
;
750 rt305x_esw_get_port_recv_badgood(struct switch_dev
*dev
,
751 const struct switch_attr
*attr
,
752 struct switch_val
*val
)
754 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
755 int idx
= val
->port_vlan
;
756 int shift
= attr
->id
== RT305X_ESW_ATTR_PORT_RECV_GOOD
? 0 : 16;
759 if (idx
< 0 || idx
>= RT305X_ESW_NUM_LANWAN
)
762 reg
= rt305x_esw_rr(esw
, RT305X_ESW_REG_P0PC
+ 4*idx
);
763 val
->value
.i
= (reg
>> shift
) & 0xffff;
769 rt305x_esw_get_port_led(struct switch_dev
*dev
,
770 const struct switch_attr
*attr
,
771 struct switch_val
*val
)
773 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
774 int idx
= val
->port_vlan
;
776 if (idx
< 0 || idx
>= RT305X_ESW_NUM_PORTS
||
777 idx
>= RT305X_ESW_NUM_LEDS
)
780 val
->value
.i
= rt305x_esw_rr(esw
, RT305X_ESW_REG_P0LED
+ 4*idx
);
786 rt305x_esw_set_port_led(struct switch_dev
*dev
,
787 const struct switch_attr
*attr
,
788 struct switch_val
*val
)
790 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
791 int idx
= val
->port_vlan
;
793 if (idx
< 0 || idx
>= RT305X_ESW_NUM_LEDS
)
796 esw
->ports
[idx
].led
= val
->value
.i
;
802 rt305x_esw_get_port_pvid(struct switch_dev
*dev
, int port
, int *val
)
804 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
806 if (port
>= RT305X_ESW_NUM_PORTS
)
809 *val
= rt305x_esw_get_pvid(esw
, port
);
815 rt305x_esw_set_port_pvid(struct switch_dev
*dev
, int port
, int val
)
817 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
819 if (port
>= RT305X_ESW_NUM_PORTS
)
822 esw
->ports
[port
].pvid
= val
;
828 rt305x_esw_get_vlan_ports(struct switch_dev
*dev
, struct switch_val
*val
)
830 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
837 if (val
->port_vlan
< 0 || val
->port_vlan
>= RT305X_ESW_NUM_VIDS
)
841 for (i
= 0; i
< RT305X_ESW_NUM_VLANS
; i
++) {
842 if (rt305x_esw_get_vlan_id(esw
, i
) == val
->port_vlan
&&
843 rt305x_esw_get_vmsc(esw
, i
) != RT305X_ESW_PORTS_NONE
) {
852 vmsc
= rt305x_esw_get_vmsc(esw
, vlan_idx
);
853 poc2
= rt305x_esw_rr(esw
, RT305X_ESW_REG_POC2
);
855 for (i
= 0; i
< RT305X_ESW_NUM_PORTS
; i
++) {
856 struct switch_port
*p
;
857 int port_mask
= 1 << i
;
859 if (!(vmsc
& port_mask
))
862 p
= &val
->value
.ports
[val
->len
++];
864 if (poc2
& (port_mask
<< RT305X_ESW_POC2_UNTAG_EN_S
))
867 p
->flags
= 1 << SWITCH_PORT_FLAG_TAGGED
;
874 rt305x_esw_set_vlan_ports(struct switch_dev
*dev
, struct switch_val
*val
)
876 struct rt305x_esw
*esw
= container_of(dev
, struct rt305x_esw
, swdev
);
881 if (val
->port_vlan
< 0 || val
->port_vlan
>= RT305X_ESW_NUM_VIDS
||
882 val
->len
> RT305X_ESW_NUM_PORTS
)
885 /* one of the already defined vlans? */
886 for (i
= 0; i
< RT305X_ESW_NUM_VLANS
; i
++) {
887 if (esw
->vlans
[i
].vid
== val
->port_vlan
&&
888 esw
->vlans
[i
].ports
!= RT305X_ESW_PORTS_NONE
) {
894 /* select a free slot */
895 for (i
= 0; vlan_idx
== -1 && i
< RT305X_ESW_NUM_VLANS
; i
++) {
896 if (esw
->vlans
[i
].ports
== RT305X_ESW_PORTS_NONE
)
900 /* bail if all slots are in use */
904 ports
= RT305X_ESW_PORTS_NONE
;
905 for (i
= 0; i
< val
->len
; i
++) {
906 struct switch_port
*p
= &val
->value
.ports
[i
];
907 int port_mask
= 1 << p
->id
;
908 bool untagged
= !(p
->flags
& (1 << SWITCH_PORT_FLAG_TAGGED
));
910 if (p
->id
>= RT305X_ESW_NUM_PORTS
)
914 esw
->ports
[p
->id
].untag
= untagged
;
916 esw
->vlans
[vlan_idx
].ports
= ports
;
917 if (ports
== RT305X_ESW_PORTS_NONE
)
918 esw
->vlans
[vlan_idx
].vid
= RT305X_ESW_VLAN_NONE
;
920 esw
->vlans
[vlan_idx
].vid
= val
->port_vlan
;
925 static const struct switch_attr rt305x_esw_global
[] = {
927 .type
= SWITCH_TYPE_INT
,
928 .name
= "enable_vlan",
929 .description
= "VLAN mode (1:enabled)",
931 .id
= RT305X_ESW_ATTR_ENABLE_VLAN
,
932 .get
= rt305x_esw_get_vlan_enable
,
933 .set
= rt305x_esw_set_vlan_enable
,
936 .type
= SWITCH_TYPE_INT
,
937 .name
= "alternate_vlan_disable",
938 .description
= "Use en_vlan instead of doubletag to disable"
941 .id
= RT305X_ESW_ATTR_ALT_VLAN_DISABLE
,
942 .get
= rt305x_esw_get_alt_vlan_disable
,
943 .set
= rt305x_esw_set_alt_vlan_disable
,
947 static const struct switch_attr rt305x_esw_port
[] = {
949 .type
= SWITCH_TYPE_INT
,
951 .description
= "Port state (1:disabled)",
953 .id
= RT305X_ESW_ATTR_PORT_DISABLE
,
954 .get
= rt305x_esw_get_port_bool
,
955 .set
= rt305x_esw_set_port_bool
,
958 .type
= SWITCH_TYPE_INT
,
960 .description
= "Double tagging for incoming vlan packets "
963 .id
= RT305X_ESW_ATTR_PORT_DOUBLETAG
,
964 .get
= rt305x_esw_get_port_bool
,
965 .set
= rt305x_esw_set_port_bool
,
968 .type
= SWITCH_TYPE_INT
,
970 .description
= "Untag (1:strip outgoing vlan tag)",
972 .id
= RT305X_ESW_ATTR_PORT_UNTAG
,
973 .get
= rt305x_esw_get_port_bool
,
974 .set
= rt305x_esw_set_port_bool
,
977 .type
= SWITCH_TYPE_INT
,
979 .description
= "LED mode (0:link, 1:100m, 2:duplex, 3:activity,"
980 " 4:collision, 5:linkact, 6:duplcoll, 7:10mact,"
981 " 8:100mact, 10:blink, 12:on)",
983 .id
= RT305X_ESW_ATTR_PORT_LED
,
984 .get
= rt305x_esw_get_port_led
,
985 .set
= rt305x_esw_set_port_led
,
988 .type
= SWITCH_TYPE_INT
,
990 .description
= "HW port group (0:wan, 1:lan)",
992 .id
= RT305X_ESW_ATTR_PORT_LAN
,
993 .get
= rt305x_esw_get_port_bool
,
996 .type
= SWITCH_TYPE_INT
,
998 .description
= "Receive bad packet counter",
999 .id
= RT305X_ESW_ATTR_PORT_RECV_BAD
,
1000 .get
= rt305x_esw_get_port_recv_badgood
,
1003 .type
= SWITCH_TYPE_INT
,
1004 .name
= "recv_good",
1005 .description
= "Receive good packet counter",
1006 .id
= RT305X_ESW_ATTR_PORT_RECV_GOOD
,
1007 .get
= rt305x_esw_get_port_recv_badgood
,
1011 static const struct switch_attr rt305x_esw_vlan
[] = {
1014 static const struct switch_dev_ops rt305x_esw_ops
= {
1016 .attr
= rt305x_esw_global
,
1017 .n_attr
= ARRAY_SIZE(rt305x_esw_global
),
1020 .attr
= rt305x_esw_port
,
1021 .n_attr
= ARRAY_SIZE(rt305x_esw_port
),
1024 .attr
= rt305x_esw_vlan
,
1025 .n_attr
= ARRAY_SIZE(rt305x_esw_vlan
),
1027 .get_vlan_ports
= rt305x_esw_get_vlan_ports
,
1028 .set_vlan_ports
= rt305x_esw_set_vlan_ports
,
1029 .get_port_pvid
= rt305x_esw_get_port_pvid
,
1030 .set_port_pvid
= rt305x_esw_set_port_pvid
,
1031 .get_port_link
= rt305x_esw_get_port_link
,
1032 .apply_config
= rt305x_esw_apply_config
,
1033 .reset_switch
= rt305x_esw_reset_switch
,
1037 rt305x_esw_probe(struct platform_device
*pdev
)
1039 struct rt305x_esw_platform_data
*pdata
;
1040 struct rt305x_esw
*esw
;
1041 struct switch_dev
*swdev
;
1042 struct resource
*res
;
1045 pdata
= pdev
->dev
.platform_data
;
1049 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1051 dev_err(&pdev
->dev
, "no memory resource found\n");
1055 esw
= kzalloc(sizeof(struct rt305x_esw
), GFP_KERNEL
);
1057 dev_err(&pdev
->dev
, "no memory for private data\n");
1061 esw
->base
= ioremap(res
->start
, resource_size(res
));
1063 dev_err(&pdev
->dev
, "ioremap failed\n");
1068 swdev
= &esw
->swdev
;
1069 swdev
->name
= "rt305x-esw";
1070 swdev
->alias
= "rt305x";
1071 swdev
->cpu_port
= RT305X_ESW_PORT6
;
1072 swdev
->ports
= RT305X_ESW_NUM_PORTS
;
1073 swdev
->vlans
= RT305X_ESW_NUM_VIDS
;
1074 swdev
->ops
= &rt305x_esw_ops
;
1076 err
= register_switch(swdev
, NULL
);
1078 dev_err(&pdev
->dev
, "register_switch failed\n");
1082 platform_set_drvdata(pdev
, esw
);
1085 spin_lock_init(&esw
->reg_rw_lock
);
1086 rt305x_esw_hw_init(esw
);
1098 rt305x_esw_remove(struct platform_device
*pdev
)
1100 struct rt305x_esw
*esw
;
1102 esw
= platform_get_drvdata(pdev
);
1104 unregister_switch(&esw
->swdev
);
1105 platform_set_drvdata(pdev
, NULL
);
1113 static struct platform_driver rt305x_esw_driver
= {
1114 .probe
= rt305x_esw_probe
,
1115 .remove
= rt305x_esw_remove
,
1117 .name
= "rt305x-esw",
1118 .owner
= THIS_MODULE
,
1123 rt305x_esw_init(void)
1125 return platform_driver_register(&rt305x_esw_driver
);
1129 rt305x_esw_exit(void)
1131 platform_driver_unregister(&rt305x_esw_driver
);