2 * rtl8306.c: RTL8306S switch driver
4 * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/list.h>
20 #include <linux/if_ether.h>
21 #include <linux/skbuff.h>
22 #include <linux/netdevice.h>
23 #include <linux/netlink.h>
24 #include <net/genetlink.h>
25 #include <linux/switch.h>
26 #include <linux/delay.h>
27 #include <linux/phy.h>
28 #include <linux/version.h>
33 #define RTL8306_REG_PAGE 16
34 #define RTL8306_REG_PAGE_LO (1 << 15)
35 #define RTL8306_REG_PAGE_HI (1 << 1) /* inverted */
37 #define RTL8306_NUM_VLANS 16
38 #define RTL8306_NUM_PORTS 6
39 #define RTL8306_PORT_CPU 5
40 #define RTL8306_NUM_PAGES 4
41 #define RTL8306_NUM_REGS 32
43 #define RTL_NAME_S "RTL8306S"
44 #define RTL_NAME_SD "RTL8306SD"
45 #define RTL_NAME_SDM "RTL8306SDM"
46 #define RTL_NAME_UNKNOWN "RTL8306(unknown)"
48 #define RTL8306_MAGIC 0x8306
50 static LIST_HEAD(phydevs
);
53 struct list_head list
;
54 struct switch_dev dev
;
59 char hwname
[sizeof(RTL_NAME_UNKNOWN
)];
69 #define to_rtl(_dev) container_of(_dev, struct rtl_priv, dev)
86 #define RTL_VLAN_REGOFS(name) \
87 (RTL_REG_VLAN1_##name - RTL_REG_VLAN0_##name)
89 #define RTL_PORT_REGOFS(name) \
90 (RTL_REG_PORT1_##name - RTL_REG_PORT0_##name)
92 #define RTL_PORT_REG(id, reg) \
93 (RTL_REG_PORT0_##reg + (id * RTL_PORT_REGOFS(reg)))
95 #define RTL_VLAN_REG(id, reg) \
96 (RTL_REG_VLAN0_##reg + (id * RTL_VLAN_REGOFS(reg)))
98 #define RTL_GLOBAL_REGATTR(reg) \
99 .id = RTL_REG_##reg, \
100 .type = SWITCH_TYPE_INT, \
102 .set = rtl_attr_set_int, \
103 .get = rtl_attr_get_int
105 #define RTL_PORT_REGATTR(reg) \
106 .id = RTL_REG_PORT0_##reg, \
107 .type = SWITCH_TYPE_INT, \
108 .ofs = RTL_PORT_REGOFS(reg), \
109 .set = rtl_attr_set_port_int, \
110 .get = rtl_attr_get_port_int
112 #define RTL_VLAN_REGATTR(reg) \
113 .id = RTL_REG_VLAN0_##reg, \
114 .type = SWITCH_TYPE_INT, \
115 .ofs = RTL_VLAN_REGOFS(reg), \
116 .set = rtl_attr_set_vlan_int, \
117 .get = rtl_attr_get_vlan_int
131 RTL_REG_TRUNK_PORTSEL
,
137 RTL_REG_VLAN_TAG_ONLY
,
138 RTL_REG_VLAN_TAG_AWARE
,
139 #define RTL_VLAN_ENUM(id) \
140 RTL_REG_VLAN##id##_VID, \
141 RTL_REG_VLAN##id##_PORTMASK
158 #define RTL_PORT_ENUM(id) \
159 RTL_REG_PORT##id##_PVID, \
160 RTL_REG_PORT##id##_NULL_VID_REPLACE, \
161 RTL_REG_PORT##id##_NON_PVID_DISCARD, \
162 RTL_REG_PORT##id##_VID_INSERT, \
163 RTL_REG_PORT##id##_TAG_INSERT, \
164 RTL_REG_PORT##id##_LINK, \
165 RTL_REG_PORT##id##_SPEED, \
166 RTL_REG_PORT##id##_NWAY, \
167 RTL_REG_PORT##id##_NRESTART, \
168 RTL_REG_PORT##id##_DUPLEX, \
169 RTL_REG_PORT##id##_RXEN, \
170 RTL_REG_PORT##id##_TXEN
179 static const struct rtl_reg rtl_regs
[] = {
180 [RTL_REG_CHIPID
] = { 0, 4, 30, 16, 0, 0 },
181 [RTL_REG_CHIPVER
] = { 0, 4, 31, 8, 0, 0 },
182 [RTL_REG_CHIPTYPE
] = { 0, 4, 31, 2, 8, 0 },
184 /* CPU port number */
185 [RTL_REG_CPUPORT
] = { 2, 4, 21, 3, 0, 0 },
186 /* Enable CPU port function */
187 [RTL_REG_EN_CPUPORT
] = { 3, 2, 21, 1, 15, 1 },
188 /* Enable CPU port tag insertion */
189 [RTL_REG_EN_TAG_OUT
] = { 3, 2, 21, 1, 12, 0 },
190 /* Enable CPU port tag removal */
191 [RTL_REG_EN_TAG_CLR
] = { 3, 2, 21, 1, 11, 0 },
192 /* Enable CPU port tag checking */
193 [RTL_REG_EN_TAG_IN
] = { 0, 4, 21, 1, 7, 0 },
194 [RTL_REG_EN_TRUNK
] = { 0, 0, 19, 1, 11, 1 },
195 [RTL_REG_TRUNK_PORTSEL
] = { 0, 0, 16, 1, 6, 1 },
196 [RTL_REG_RESET
] = { 0, 0, 16, 1, 12, 0 },
198 [RTL_REG_TRAP_CPU
] = { 3, 2, 22, 1, 6, 0 },
199 [RTL_REG_CPU_LINKUP
] = { 0, 6, 22, 1, 15, 0 },
201 [RTL_REG_VLAN_TAG_ONLY
] = { 0, 0, 16, 1, 8, 1 },
202 [RTL_REG_VLAN_FILTER
] = { 0, 0, 16, 1, 9, 1 },
203 [RTL_REG_VLAN_TAG_AWARE
] = { 0, 0, 16, 1, 10, 1 },
204 [RTL_REG_VLAN_ENABLE
] = { 0, 0, 18, 1, 8, 1 },
206 #define RTL_VLAN_REGS(id, phy, page, regofs) \
207 [RTL_REG_VLAN##id##_VID] = { page, phy, 25 + regofs, 12, 0, 0 }, \
208 [RTL_REG_VLAN##id##_PORTMASK] = { page, phy, 24 + regofs, 6, 0, 0 }
209 RTL_VLAN_REGS( 0, 0, 0, 0),
210 RTL_VLAN_REGS( 1, 1, 0, 0),
211 RTL_VLAN_REGS( 2, 2, 0, 0),
212 RTL_VLAN_REGS( 3, 3, 0, 0),
213 RTL_VLAN_REGS( 4, 4, 0, 0),
214 RTL_VLAN_REGS( 5, 0, 1, 2),
215 RTL_VLAN_REGS( 6, 1, 1, 2),
216 RTL_VLAN_REGS( 7, 2, 1, 2),
217 RTL_VLAN_REGS( 8, 3, 1, 2),
218 RTL_VLAN_REGS( 9, 4, 1, 2),
219 RTL_VLAN_REGS(10, 0, 1, 4),
220 RTL_VLAN_REGS(11, 1, 1, 4),
221 RTL_VLAN_REGS(12, 2, 1, 4),
222 RTL_VLAN_REGS(13, 3, 1, 4),
223 RTL_VLAN_REGS(14, 4, 1, 4),
224 RTL_VLAN_REGS(15, 0, 1, 6),
226 #define REG_PORT_SETTING(port, phy) \
227 [RTL_REG_PORT##port##_SPEED] = { 0, phy, 0, 1, 13, 0 }, \
228 [RTL_REG_PORT##port##_NWAY] = { 0, phy, 0, 1, 12, 0 }, \
229 [RTL_REG_PORT##port##_NRESTART] = { 0, phy, 0, 1, 9, 0 }, \
230 [RTL_REG_PORT##port##_DUPLEX] = { 0, phy, 0, 1, 8, 0 }, \
231 [RTL_REG_PORT##port##_TXEN] = { 0, phy, 24, 1, 11, 0 }, \
232 [RTL_REG_PORT##port##_RXEN] = { 0, phy, 24, 1, 10, 0 }, \
233 [RTL_REG_PORT##port##_LINK] = { 0, phy, 1, 1, 2, 0 }, \
234 [RTL_REG_PORT##port##_NULL_VID_REPLACE] = { 0, phy, 22, 1, 12, 0 }, \
235 [RTL_REG_PORT##port##_NON_PVID_DISCARD] = { 0, phy, 22, 1, 11, 0 }, \
236 [RTL_REG_PORT##port##_VID_INSERT] = { 0, phy, 22, 2, 9, 0 }, \
237 [RTL_REG_PORT##port##_TAG_INSERT] = { 0, phy, 22, 2, 0, 0 }
239 REG_PORT_SETTING(0, 0),
240 REG_PORT_SETTING(1, 1),
241 REG_PORT_SETTING(2, 2),
242 REG_PORT_SETTING(3, 3),
243 REG_PORT_SETTING(4, 4),
244 REG_PORT_SETTING(5, 6),
246 #define REG_PORT_PVID(phy, page, regofs) \
247 { page, phy, 24 + regofs, 4, 12, 0 }
248 [RTL_REG_PORT0_PVID
] = REG_PORT_PVID(0, 0, 0),
249 [RTL_REG_PORT1_PVID
] = REG_PORT_PVID(1, 0, 0),
250 [RTL_REG_PORT2_PVID
] = REG_PORT_PVID(2, 0, 0),
251 [RTL_REG_PORT3_PVID
] = REG_PORT_PVID(3, 0, 0),
252 [RTL_REG_PORT4_PVID
] = REG_PORT_PVID(4, 0, 0),
253 [RTL_REG_PORT5_PVID
] = REG_PORT_PVID(0, 1, 2),
258 rtl_set_page(struct rtl_priv
*priv
, unsigned int page
)
260 struct mii_bus
*bus
= priv
->bus
;
266 if (priv
->page
== page
)
269 BUG_ON(page
> RTL8306_NUM_PAGES
);
270 pgsel
= bus
->read(bus
, 0, RTL8306_REG_PAGE
);
271 pgsel
&= ~(RTL8306_REG_PAGE_LO
| RTL8306_REG_PAGE_HI
);
273 pgsel
|= RTL8306_REG_PAGE_LO
;
274 if (!(page
& (1 << 1))) /* bit is inverted */
275 pgsel
|= RTL8306_REG_PAGE_HI
;
276 bus
->write(bus
, 0, RTL8306_REG_PAGE
, pgsel
);
280 rtl_w16(struct switch_dev
*dev
, unsigned int page
, unsigned int phy
, unsigned int reg
, u16 val
)
282 struct rtl_priv
*priv
= to_rtl(dev
);
283 struct mii_bus
*bus
= priv
->bus
;
285 rtl_set_page(priv
, page
);
286 bus
->write(bus
, phy
, reg
, val
);
287 bus
->read(bus
, phy
, reg
); /* flush */
292 rtl_r16(struct switch_dev
*dev
, unsigned int page
, unsigned int phy
, unsigned int reg
)
294 struct rtl_priv
*priv
= to_rtl(dev
);
295 struct mii_bus
*bus
= priv
->bus
;
297 rtl_set_page(priv
, page
);
298 return bus
->read(bus
, phy
, reg
);
302 rtl_rmw(struct switch_dev
*dev
, unsigned int page
, unsigned int phy
, unsigned int reg
, u16 mask
, u16 val
)
304 struct rtl_priv
*priv
= to_rtl(dev
);
305 struct mii_bus
*bus
= priv
->bus
;
308 rtl_set_page(priv
, page
);
309 r
= bus
->read(bus
, phy
, reg
);
312 bus
->write(bus
, phy
, reg
, r
);
313 return bus
->read(bus
, phy
, reg
); /* flush */
318 rtl_get(struct switch_dev
*dev
, enum rtl_regidx s
)
320 const struct rtl_reg
*r
= &rtl_regs
[s
];
323 BUG_ON(s
>= ARRAY_SIZE(rtl_regs
));
324 if (r
->bits
== 0) /* unimplemented */
327 val
= rtl_r16(dev
, r
->page
, r
->phy
, r
->reg
);
335 val
&= (1 << r
->bits
) - 1;
341 rtl_set(struct switch_dev
*dev
, enum rtl_regidx s
, unsigned int val
)
343 const struct rtl_reg
*r
= &rtl_regs
[s
];
346 BUG_ON(s
>= ARRAY_SIZE(rtl_regs
));
348 if (r
->bits
== 0) /* unimplemented */
358 mask
= (1 << r
->bits
) - 1;
362 return rtl_rmw(dev
, r
->page
, r
->phy
, r
->reg
, mask
, val
);
366 rtl_phy_save(struct switch_dev
*dev
, int port
, struct rtl_phyregs
*regs
)
368 regs
->nway
= rtl_get(dev
, RTL_PORT_REG(port
, NWAY
));
369 regs
->speed
= rtl_get(dev
, RTL_PORT_REG(port
, SPEED
));
370 regs
->duplex
= rtl_get(dev
, RTL_PORT_REG(port
, DUPLEX
));
374 rtl_phy_restore(struct switch_dev
*dev
, int port
, struct rtl_phyregs
*regs
)
376 rtl_set(dev
, RTL_PORT_REG(port
, NWAY
), regs
->nway
);
377 rtl_set(dev
, RTL_PORT_REG(port
, SPEED
), regs
->speed
);
378 rtl_set(dev
, RTL_PORT_REG(port
, DUPLEX
), regs
->duplex
);
382 rtl_port_set_enable(struct switch_dev
*dev
, int port
, int enabled
)
384 rtl_set(dev
, RTL_PORT_REG(port
, RXEN
), enabled
);
385 rtl_set(dev
, RTL_PORT_REG(port
, TXEN
), enabled
);
387 if ((port
>= 5) || !enabled
)
390 /* restart autonegotiation if enabled */
391 rtl_set(dev
, RTL_PORT_REG(port
, NRESTART
), 1);
395 rtl_hw_apply(struct switch_dev
*dev
)
398 int trunk_en
, trunk_psel
;
399 struct rtl_phyregs port5
;
401 rtl_phy_save(dev
, 5, &port5
);
403 /* disable rx/tx from PHYs */
404 for (i
= 0; i
< RTL8306_NUM_PORTS
- 1; i
++) {
405 rtl_port_set_enable(dev
, i
, 0);
408 /* save trunking status */
409 trunk_en
= rtl_get(dev
, RTL_REG_EN_TRUNK
);
410 trunk_psel
= rtl_get(dev
, RTL_REG_TRUNK_PORTSEL
);
412 /* trunk port 3 and 4
413 * XXX: Big WTF, but RealTek seems to do it */
414 rtl_set(dev
, RTL_REG_EN_TRUNK
, 1);
415 rtl_set(dev
, RTL_REG_TRUNK_PORTSEL
, 1);
417 /* execute the software reset */
418 rtl_set(dev
, RTL_REG_RESET
, 1);
420 /* wait for the reset to complete,
421 * but don't wait for too long */
422 for (i
= 0; i
< 10; i
++) {
423 if (rtl_get(dev
, RTL_REG_RESET
) == 0)
429 /* enable rx/tx from PHYs */
430 for (i
= 0; i
< RTL8306_NUM_PORTS
- 1; i
++) {
431 rtl_port_set_enable(dev
, i
, 1);
434 /* restore trunking settings */
435 rtl_set(dev
, RTL_REG_EN_TRUNK
, trunk_en
);
436 rtl_set(dev
, RTL_REG_TRUNK_PORTSEL
, trunk_psel
);
437 rtl_phy_restore(dev
, 5, &port5
);
439 rtl_set(dev
, RTL_REG_CPU_LINKUP
, 1);
445 rtl_hw_init(struct switch_dev
*dev
)
447 struct rtl_priv
*priv
= to_rtl(dev
);
448 int cpu_mask
= 1 << dev
->cpu_port
;
451 rtl_set(dev
, RTL_REG_VLAN_ENABLE
, 0);
452 rtl_set(dev
, RTL_REG_VLAN_FILTER
, 0);
453 rtl_set(dev
, RTL_REG_EN_TRUNK
, 0);
454 rtl_set(dev
, RTL_REG_TRUNK_PORTSEL
, 0);
456 /* initialize cpu port settings */
458 rtl_set(dev
, RTL_REG_CPUPORT
, dev
->cpu_port
);
459 rtl_set(dev
, RTL_REG_EN_CPUPORT
, 1);
461 rtl_set(dev
, RTL_REG_CPUPORT
, 7);
462 rtl_set(dev
, RTL_REG_EN_CPUPORT
, 0);
464 rtl_set(dev
, RTL_REG_EN_TAG_OUT
, 0);
465 rtl_set(dev
, RTL_REG_EN_TAG_IN
, 0);
466 rtl_set(dev
, RTL_REG_EN_TAG_CLR
, 0);
468 /* reset all vlans */
469 for (i
= 0; i
< RTL8306_NUM_VLANS
; i
++) {
470 rtl_set(dev
, RTL_VLAN_REG(i
, VID
), i
);
471 rtl_set(dev
, RTL_VLAN_REG(i
, PORTMASK
), 0);
474 /* default to port isolation */
475 for (i
= 0; i
< RTL8306_NUM_PORTS
; i
++) {
478 if ((1 << i
) == cpu_mask
)
479 mask
= ((1 << RTL8306_NUM_PORTS
) - 1) & ~cpu_mask
; /* all bits set */
481 mask
= cpu_mask
| (1 << i
);
483 rtl_set(dev
, RTL_VLAN_REG(i
, PORTMASK
), mask
);
484 rtl_set(dev
, RTL_PORT_REG(i
, PVID
), i
);
485 rtl_set(dev
, RTL_PORT_REG(i
, NULL_VID_REPLACE
), 1);
486 rtl_set(dev
, RTL_PORT_REG(i
, VID_INSERT
), 1);
487 rtl_set(dev
, RTL_PORT_REG(i
, TAG_INSERT
), 3);
494 rtl_set_use_cpuport(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
496 struct rtl_priv
*priv
= to_rtl(dev
);
497 priv
->do_cpu
= val
->value
.i
;
503 rtl_get_use_cpuport(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
505 struct rtl_priv
*priv
= to_rtl(dev
);
506 val
->value
.i
= priv
->do_cpu
;
511 rtl_set_cpuport(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
513 dev
->cpu_port
= val
->value
.i
;
519 rtl_get_cpuport(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
521 val
->value
.i
= dev
->cpu_port
;
527 rtl_reset(struct switch_dev
*dev
)
534 rtl_attr_set_int(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
536 int idx
= attr
->id
+ (val
->port_vlan
* attr
->ofs
);
537 struct rtl_phyregs port
;
539 if (attr
->id
>= ARRAY_SIZE(rtl_regs
))
542 if ((attr
->max
> 0) && (val
->value
.i
> attr
->max
))
545 /* access to phy register 22 on port 4/5
546 * needs phy status save/restore */
547 if ((val
->port_vlan
> 3) &&
548 (rtl_regs
[idx
].reg
== 22) &&
549 (rtl_regs
[idx
].page
== 0)) {
551 rtl_phy_save(dev
, val
->port_vlan
, &port
);
552 rtl_set(dev
, idx
, val
->value
.i
);
553 rtl_phy_restore(dev
, val
->port_vlan
, &port
);
555 rtl_set(dev
, idx
, val
->value
.i
);
562 rtl_attr_get_int(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
564 int idx
= attr
->id
+ (val
->port_vlan
* attr
->ofs
);
566 if (idx
>= ARRAY_SIZE(rtl_regs
))
569 val
->value
.i
= rtl_get(dev
, idx
);
574 rtl_attr_set_port_int(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
576 if (val
->port_vlan
>= RTL8306_NUM_PORTS
)
579 return rtl_attr_set_int(dev
, attr
, val
);
583 rtl_attr_get_port_int(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
585 if (val
->port_vlan
>= RTL8306_NUM_PORTS
)
587 return rtl_attr_get_int(dev
, attr
, val
);
591 rtl_get_port_link(struct switch_dev
*dev
, int port
, struct switch_port_link
*link
)
593 if (port
>= RTL8306_NUM_PORTS
)
596 /* in case the link changes from down to up, the register is only updated on read */
597 link
->link
= rtl_get(dev
, RTL_PORT_REG(port
, LINK
));
599 link
->link
= rtl_get(dev
, RTL_PORT_REG(port
, LINK
));
604 link
->duplex
= rtl_get(dev
, RTL_PORT_REG(port
, DUPLEX
));
605 link
->aneg
= rtl_get(dev
, RTL_PORT_REG(port
, NWAY
));
607 if (rtl_get(dev
, RTL_PORT_REG(port
, SPEED
)))
608 link
->speed
= SWITCH_PORT_SPEED_100
;
610 link
->speed
= SWITCH_PORT_SPEED_10
;
616 rtl_attr_set_vlan_int(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
618 if (val
->port_vlan
>= dev
->vlans
)
621 return rtl_attr_set_int(dev
, attr
, val
);
625 rtl_attr_get_vlan_int(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
627 if (val
->port_vlan
>= dev
->vlans
)
630 return rtl_attr_get_int(dev
, attr
, val
);
634 rtl_get_ports(struct switch_dev
*dev
, struct switch_val
*val
)
636 unsigned int i
, mask
;
638 mask
= rtl_get(dev
, RTL_VLAN_REG(val
->port_vlan
, PORTMASK
));
639 for (i
= 0; i
< RTL8306_NUM_PORTS
; i
++) {
640 struct switch_port
*port
;
642 if (!(mask
& (1 << i
)))
645 port
= &val
->value
.ports
[val
->len
];
647 if (rtl_get(dev
, RTL_PORT_REG(i
, TAG_INSERT
)) == 2 || i
== dev
->cpu_port
)
648 port
->flags
= (1 << SWITCH_PORT_FLAG_TAGGED
);
656 rtl_set_vlan(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
658 struct rtl_priv
*priv
= to_rtl(dev
);
659 struct rtl_phyregs port
;
660 int en
= val
->value
.i
;
663 rtl_set(dev
, RTL_REG_EN_TAG_OUT
, en
&& priv
->do_cpu
);
664 rtl_set(dev
, RTL_REG_EN_TAG_IN
, en
&& priv
->do_cpu
);
665 rtl_set(dev
, RTL_REG_EN_TAG_CLR
, en
&& priv
->do_cpu
);
666 rtl_set(dev
, RTL_REG_VLAN_TAG_AWARE
, en
);
668 rtl_set(dev
, RTL_REG_VLAN_FILTER
, en
);
670 for (i
= 0; i
< RTL8306_NUM_PORTS
; i
++) {
672 rtl_phy_save(dev
, val
->port_vlan
, &port
);
673 rtl_set(dev
, RTL_PORT_REG(i
, NULL_VID_REPLACE
), 1);
674 rtl_set(dev
, RTL_PORT_REG(i
, VID_INSERT
), (en
? (i
== dev
->cpu_port
? 0 : 1) : 1));
675 rtl_set(dev
, RTL_PORT_REG(i
, TAG_INSERT
), (en
? (i
== dev
->cpu_port
? 2 : 1) : 3));
677 rtl_phy_restore(dev
, val
->port_vlan
, &port
);
679 rtl_set(dev
, RTL_REG_VLAN_ENABLE
, en
);
685 rtl_get_vlan(struct switch_dev
*dev
, const struct switch_attr
*attr
, struct switch_val
*val
)
687 val
->value
.i
= rtl_get(dev
, RTL_REG_VLAN_ENABLE
);
692 rtl_set_ports(struct switch_dev
*dev
, struct switch_val
*val
)
694 unsigned int mask
= 0;
695 unsigned int oldmask
;
698 for(i
= 0; i
< val
->len
; i
++)
700 struct switch_port
*port
= &val
->value
.ports
[i
];
703 mask
|= (1 << port
->id
);
705 if (port
->id
== dev
->cpu_port
)
708 if ((i
== dev
->cpu_port
) ||
709 (port
->flags
& (1 << SWITCH_PORT_FLAG_TAGGED
)))
712 /* fix up PVIDs for added ports */
714 rtl_set(dev
, RTL_PORT_REG(port
->id
, PVID
), val
->port_vlan
);
716 rtl_set(dev
, RTL_PORT_REG(port
->id
, NON_PVID_DISCARD
), (tagged
? 0 : 1));
717 rtl_set(dev
, RTL_PORT_REG(port
->id
, VID_INSERT
), (tagged
? 0 : 1));
718 rtl_set(dev
, RTL_PORT_REG(port
->id
, TAG_INSERT
), (tagged
? 2 : 1));
721 oldmask
= rtl_get(dev
, RTL_VLAN_REG(val
->port_vlan
, PORTMASK
));
722 rtl_set(dev
, RTL_VLAN_REG(val
->port_vlan
, PORTMASK
), mask
);
724 /* fix up PVIDs for removed ports, default to last vlan */
726 for (i
= 0; i
< RTL8306_NUM_PORTS
; i
++) {
727 if (!(oldmask
& (1 << i
)))
730 if (i
== dev
->cpu_port
)
733 if (rtl_get(dev
, RTL_PORT_REG(i
, PVID
)) == val
->port_vlan
)
734 rtl_set(dev
, RTL_PORT_REG(i
, PVID
), dev
->vlans
- 1);
740 static struct switch_attr rtl_globals
[] = {
742 .type
= SWITCH_TYPE_INT
,
743 .name
= "enable_vlan",
744 .description
= "Enable VLAN mode",
750 RTL_GLOBAL_REGATTR(EN_TRUNK
),
752 .description
= "Enable port trunking",
756 RTL_GLOBAL_REGATTR(TRUNK_PORTSEL
),
758 .description
= "Select ports for trunking (0: 0,1 - 1: 3,4)",
763 RTL_GLOBAL_REGATTR(VLAN_FILTER
),
764 .name
= "vlan_filter",
765 .description
= "Filter incoming packets for allowed VLANS",
769 .type
= SWITCH_TYPE_INT
,
771 .description
= "CPU Port",
772 .set
= rtl_set_cpuport
,
773 .get
= rtl_get_cpuport
,
774 .max
= RTL8306_NUM_PORTS
,
777 .type
= SWITCH_TYPE_INT
,
778 .name
= "use_cpuport",
779 .description
= "CPU Port handling flag",
780 .set
= rtl_set_use_cpuport
,
781 .get
= rtl_get_use_cpuport
,
782 .max
= RTL8306_NUM_PORTS
,
785 RTL_GLOBAL_REGATTR(TRAP_CPU
),
787 .description
= "VLAN trap to CPU",
791 RTL_GLOBAL_REGATTR(VLAN_TAG_AWARE
),
792 .name
= "vlan_tag_aware",
793 .description
= "Enable VLAN tag awareness",
797 RTL_GLOBAL_REGATTR(VLAN_TAG_ONLY
),
799 .description
= "Only accept tagged packets",
804 static struct switch_attr rtl_port
[] = {
806 RTL_PORT_REGATTR(PVID
),
808 .description
= "Port VLAN ID",
809 .max
= RTL8306_NUM_VLANS
- 1,
813 RTL_PORT_REGATTR(NULL_VID_REPLACE
),
815 .description
= "NULL VID gets replaced by port default vid",
819 RTL_PORT_REGATTR(NON_PVID_DISCARD
),
820 .name
= "non_pvid_discard",
821 .description
= "discard packets with VID != PVID",
825 RTL_PORT_REGATTR(VID_INSERT
),
826 .name
= "vid_insert_remove",
827 .description
= "how should the switch insert and remove vids ?",
831 RTL_PORT_REGATTR(TAG_INSERT
),
832 .name
= "tag_insert",
833 .description
= "tag insertion handling",
839 static struct switch_attr rtl_vlan
[] = {
841 RTL_VLAN_REGATTR(VID
),
843 .description
= "VLAN ID (1-4095)",
848 static const struct switch_dev_ops rtl8306_ops
= {
851 .n_attr
= ARRAY_SIZE(rtl_globals
),
855 .n_attr
= ARRAY_SIZE(rtl_port
),
859 .n_attr
= ARRAY_SIZE(rtl_vlan
),
862 .get_vlan_ports
= rtl_get_ports
,
863 .set_vlan_ports
= rtl_set_ports
,
864 .apply_config
= rtl_hw_apply
,
865 .reset_switch
= rtl_reset
,
866 .get_port_link
= rtl_get_port_link
,
870 rtl8306_config_init(struct phy_device
*pdev
)
872 struct net_device
*netdev
= pdev
->attached_dev
;
873 struct rtl_priv
*priv
= pdev
->priv
;
874 struct switch_dev
*dev
= &priv
->dev
;
875 struct switch_val val
;
876 unsigned int chipid
, chipver
, chiptype
;
879 /* Only init the switch for the primary PHY */
880 if (pdev
->mdio
.addr
!= 0)
884 priv
->dev
.cpu_port
= RTL8306_PORT_CPU
;
885 priv
->dev
.ports
= RTL8306_NUM_PORTS
;
886 priv
->dev
.vlans
= RTL8306_NUM_VLANS
;
887 priv
->dev
.ops
= &rtl8306_ops
;
890 priv
->bus
= pdev
->mdio
.bus
;
892 chipid
= rtl_get(dev
, RTL_REG_CHIPID
);
893 chipver
= rtl_get(dev
, RTL_REG_CHIPVER
);
894 chiptype
= rtl_get(dev
, RTL_REG_CHIPTYPE
);
898 strncpy(priv
->hwname
, RTL_NAME_S
, sizeof(priv
->hwname
));
899 priv
->type
= RTL_TYPE_S
;
902 strncpy(priv
->hwname
, RTL_NAME_SD
, sizeof(priv
->hwname
));
903 priv
->type
= RTL_TYPE_SD
;
906 strncpy(priv
->hwname
, RTL_NAME_SDM
, sizeof(priv
->hwname
));
907 priv
->type
= RTL_TYPE_SDM
;
910 strncpy(priv
->hwname
, RTL_NAME_UNKNOWN
, sizeof(priv
->hwname
));
914 dev
->name
= priv
->hwname
;
917 printk(KERN_INFO
"Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv
->hwname
, chipid
, chipver
);
919 err
= register_switch(dev
, netdev
);
930 rtl8306_fixup(struct phy_device
*pdev
)
932 struct rtl_priv priv
;
935 /* Attach to primary LAN port and WAN port */
936 if (pdev
->mdio
.addr
!= 0 && pdev
->mdio
.addr
!= 4)
939 memset(&priv
, 0, sizeof(priv
));
942 priv
.bus
= pdev
->mdio
.bus
;
943 chipid
= rtl_get(&priv
.dev
, RTL_REG_CHIPID
);
944 if (chipid
== 0x5988)
945 pdev
->phy_id
= RTL8306_MAGIC
;
951 rtl8306_probe(struct phy_device
*pdev
)
953 struct rtl_priv
*priv
;
955 list_for_each_entry(priv
, &phydevs
, list
) {
957 * share one rtl_priv instance between virtual phy
958 * devices on the same bus
960 if (priv
->bus
== pdev
->mdio
.bus
)
963 priv
= kzalloc(sizeof(struct rtl_priv
), GFP_KERNEL
);
967 priv
->bus
= pdev
->mdio
.bus
;
975 rtl8306_remove(struct phy_device
*pdev
)
977 struct rtl_priv
*priv
= pdev
->priv
;
978 unregister_switch(&priv
->dev
);
983 rtl8306_config_aneg(struct phy_device
*pdev
)
985 struct rtl_priv
*priv
= pdev
->priv
;
988 if (pdev
->mdio
.addr
== 0)
991 /* Restart autonegotiation */
992 rtl_set(&priv
->dev
, RTL_PORT_REG(4, NWAY
), 1);
993 rtl_set(&priv
->dev
, RTL_PORT_REG(4, NRESTART
), 1);
999 rtl8306_read_status(struct phy_device
*pdev
)
1001 struct rtl_priv
*priv
= pdev
->priv
;
1002 struct switch_dev
*dev
= &priv
->dev
;
1004 if (pdev
->mdio
.addr
== 4) {
1006 pdev
->speed
= rtl_get(dev
, RTL_PORT_REG(4, SPEED
)) ? SPEED_100
: SPEED_10
;
1007 pdev
->duplex
= rtl_get(dev
, RTL_PORT_REG(4, DUPLEX
)) ? DUPLEX_FULL
: DUPLEX_HALF
;
1008 pdev
->link
= !!rtl_get(dev
, RTL_PORT_REG(4, LINK
));
1011 pdev
->speed
= SPEED_100
;
1012 pdev
->duplex
= DUPLEX_FULL
;
1017 * Bypass generic PHY status read,
1018 * it doesn't work with this switch
1021 pdev
->state
= PHY_RUNNING
;
1022 netif_carrier_on(pdev
->attached_dev
);
1023 pdev
->adjust_link(pdev
->attached_dev
);
1025 pdev
->state
= PHY_NOLINK
;
1026 netif_carrier_off(pdev
->attached_dev
);
1027 pdev
->adjust_link(pdev
->attached_dev
);
1034 static struct phy_driver rtl8306_driver
= {
1035 .name
= "Realtek RTL8306S",
1036 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0))
1037 .flags
= PHY_HAS_MAGICANEG
,
1039 .phy_id
= RTL8306_MAGIC
,
1040 .phy_id_mask
= 0xffffffff,
1041 .features
= PHY_BASIC_FEATURES
,
1042 .probe
= &rtl8306_probe
,
1043 .remove
= &rtl8306_remove
,
1044 .config_init
= &rtl8306_config_init
,
1045 .config_aneg
= &rtl8306_config_aneg
,
1046 .read_status
= &rtl8306_read_status
,
1053 phy_register_fixup_for_id(PHY_ANY_ID
, rtl8306_fixup
);
1054 return phy_driver_register(&rtl8306_driver
, THIS_MODULE
);
1060 phy_driver_unregister(&rtl8306_driver
);
1063 module_init(rtl_init
);
1064 module_exit(rtl_exit
);
1065 MODULE_LICENSE("GPL");