Root/target/linux/generic-2.6/files/drivers/net/phy/rtl8306.c

1/*
2 * rtl8306.c: RTL8306S switch driver
3 *
4 * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
5 *
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.
9 *
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.
14 */
15
16#include <linux/if.h>
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
29//#define DEBUG 1
30
31/* Global (PHY0) */
32#define RTL8306_REG_PAGE 16
33#define RTL8306_REG_PAGE_LO (1 << 15)
34#define RTL8306_REG_PAGE_HI (1 << 1) /* inverted */
35
36#define RTL8306_NUM_VLANS 16
37#define RTL8306_NUM_PORTS 6
38#define RTL8306_PORT_CPU 5
39#define RTL8306_NUM_PAGES 4
40#define RTL8306_NUM_REGS 32
41
42#define RTL_NAME_S "RTL8306S"
43#define RTL_NAME_SD "RTL8306SD"
44#define RTL_NAME_SDM "RTL8306SDM"
45#define RTL_NAME_UNKNOWN "RTL8306(unknown)"
46
47#define RTL8306_MAGIC 0x8306
48
49static LIST_HEAD(phydevs);
50
51struct rtl_priv {
52    struct list_head list;
53    struct switch_dev dev;
54    int page;
55    int type;
56    int do_cpu;
57    struct mii_bus *bus;
58    char hwname[sizeof(RTL_NAME_UNKNOWN)];
59};
60
61struct rtl_phyregs {
62    int nway;
63    int speed;
64    int duplex;
65};
66
67#define to_rtl(_dev) container_of(_dev, struct rtl_priv, dev)
68
69enum {
70    RTL_TYPE_S,
71    RTL_TYPE_SD,
72    RTL_TYPE_SDM,
73};
74
75struct rtl_reg {
76    int page;
77    int phy;
78    int reg;
79    int bits;
80    int shift;
81    int inverted;
82};
83
84#define RTL_VLAN_REGOFS(name) \
85    (RTL_REG_VLAN1_##name - RTL_REG_VLAN0_##name)
86
87#define RTL_PORT_REGOFS(name) \
88    (RTL_REG_PORT1_##name - RTL_REG_PORT0_##name)
89
90#define RTL_PORT_REG(id, reg) \
91    (RTL_REG_PORT0_##reg + (id * RTL_PORT_REGOFS(reg)))
92
93#define RTL_VLAN_REG(id, reg) \
94    (RTL_REG_VLAN0_##reg + (id * RTL_VLAN_REGOFS(reg)))
95
96#define RTL_GLOBAL_REGATTR(reg) \
97    .id = RTL_REG_##reg, \
98    .type = SWITCH_TYPE_INT, \
99    .ofs = 0, \
100    .set = rtl_attr_set_int, \
101    .get = rtl_attr_get_int
102
103#define RTL_PORT_REGATTR(reg) \
104    .id = RTL_REG_PORT0_##reg, \
105    .type = SWITCH_TYPE_INT, \
106    .ofs = RTL_PORT_REGOFS(reg), \
107    .set = rtl_attr_set_port_int, \
108    .get = rtl_attr_get_port_int
109
110#define RTL_VLAN_REGATTR(reg) \
111    .id = RTL_REG_VLAN0_##reg, \
112    .type = SWITCH_TYPE_INT, \
113    .ofs = RTL_VLAN_REGOFS(reg), \
114    .set = rtl_attr_set_vlan_int, \
115    .get = rtl_attr_get_vlan_int
116
117enum rtl_regidx {
118    RTL_REG_CHIPID,
119    RTL_REG_CHIPVER,
120    RTL_REG_CHIPTYPE,
121    RTL_REG_CPUPORT,
122
123    RTL_REG_EN_CPUPORT,
124    RTL_REG_EN_TAG_OUT,
125    RTL_REG_EN_TAG_CLR,
126    RTL_REG_EN_TAG_IN,
127    RTL_REG_TRAP_CPU,
128    RTL_REG_TRUNK_PORTSEL,
129    RTL_REG_EN_TRUNK,
130    RTL_REG_RESET,
131
132    RTL_REG_VLAN_ENABLE,
133    RTL_REG_VLAN_FILTER,
134    RTL_REG_VLAN_TAG_ONLY,
135    RTL_REG_VLAN_TAG_AWARE,
136#define RTL_VLAN_ENUM(id) \
137    RTL_REG_VLAN##id##_VID, \
138    RTL_REG_VLAN##id##_PORTMASK
139    RTL_VLAN_ENUM(0),
140    RTL_VLAN_ENUM(1),
141    RTL_VLAN_ENUM(2),
142    RTL_VLAN_ENUM(3),
143    RTL_VLAN_ENUM(4),
144    RTL_VLAN_ENUM(5),
145    RTL_VLAN_ENUM(6),
146    RTL_VLAN_ENUM(7),
147    RTL_VLAN_ENUM(8),
148    RTL_VLAN_ENUM(9),
149    RTL_VLAN_ENUM(10),
150    RTL_VLAN_ENUM(11),
151    RTL_VLAN_ENUM(12),
152    RTL_VLAN_ENUM(13),
153    RTL_VLAN_ENUM(14),
154    RTL_VLAN_ENUM(15),
155#define RTL_PORT_ENUM(id) \
156    RTL_REG_PORT##id##_PVID, \
157    RTL_REG_PORT##id##_NULL_VID_REPLACE, \
158    RTL_REG_PORT##id##_NON_PVID_DISCARD, \
159    RTL_REG_PORT##id##_VID_INSERT, \
160    RTL_REG_PORT##id##_TAG_INSERT, \
161    RTL_REG_PORT##id##_LINK, \
162    RTL_REG_PORT##id##_SPEED, \
163    RTL_REG_PORT##id##_NWAY, \
164    RTL_REG_PORT##id##_NRESTART, \
165    RTL_REG_PORT##id##_DUPLEX, \
166    RTL_REG_PORT##id##_RXEN, \
167    RTL_REG_PORT##id##_TXEN
168    RTL_PORT_ENUM(0),
169    RTL_PORT_ENUM(1),
170    RTL_PORT_ENUM(2),
171    RTL_PORT_ENUM(3),
172    RTL_PORT_ENUM(4),
173    RTL_PORT_ENUM(5),
174};
175
176static const struct rtl_reg rtl_regs[] = {
177    [RTL_REG_CHIPID] = { 0, 4, 30, 16, 0, 0 },
178    [RTL_REG_CHIPVER] = { 0, 4, 31, 8, 0, 0 },
179    [RTL_REG_CHIPTYPE] = { 0, 4, 31, 2, 8, 0 },
180
181    /* CPU port number */
182    [RTL_REG_CPUPORT] = { 2, 4, 21, 3, 0, 0 },
183    /* Enable CPU port function */
184    [RTL_REG_EN_CPUPORT] = { 3, 2, 21, 1, 15, 1 },
185    /* Enable CPU port tag insertion */
186    [RTL_REG_EN_TAG_OUT] = { 3, 2, 21, 1, 12, 0 },
187    /* Enable CPU port tag removal */
188    [RTL_REG_EN_TAG_CLR] = { 3, 2, 21, 1, 11, 0 },
189    /* Enable CPU port tag checking */
190    [RTL_REG_EN_TAG_IN] = { 0, 4, 21, 1, 7, 0 },
191    [RTL_REG_EN_TRUNK] = { 0, 0, 19, 1, 11, 1 },
192    [RTL_REG_TRUNK_PORTSEL] = { 0, 0, 16, 1, 6, 1 },
193    [RTL_REG_RESET] = { 0, 0, 16, 1, 12, 0 },
194
195    [RTL_REG_TRAP_CPU] = { 3, 2, 22, 1, 6, 0 },
196
197    [RTL_REG_VLAN_TAG_ONLY] = { 0, 0, 16, 1, 8, 1 },
198    [RTL_REG_VLAN_FILTER] = { 0, 0, 16, 1, 9, 1 },
199    [RTL_REG_VLAN_TAG_AWARE] = { 0, 0, 16, 1, 10, 1 },
200    [RTL_REG_VLAN_ENABLE] = { 0, 0, 18, 1, 8, 1 },
201
202#define RTL_VLAN_REGS(id, phy, page, regofs) \
203    [RTL_REG_VLAN##id##_VID] = { page, phy, 25 + regofs, 12, 0, 0 }, \
204    [RTL_REG_VLAN##id##_PORTMASK] = { page, phy, 24 + regofs, 6, 0, 0 }
205    RTL_VLAN_REGS( 0, 0, 0, 0),
206    RTL_VLAN_REGS( 1, 1, 0, 0),
207    RTL_VLAN_REGS( 2, 2, 0, 0),
208    RTL_VLAN_REGS( 3, 3, 0, 0),
209    RTL_VLAN_REGS( 4, 4, 0, 0),
210    RTL_VLAN_REGS( 5, 0, 1, 2),
211    RTL_VLAN_REGS( 6, 1, 1, 2),
212    RTL_VLAN_REGS( 7, 2, 1, 2),
213    RTL_VLAN_REGS( 8, 3, 1, 2),
214    RTL_VLAN_REGS( 9, 4, 1, 2),
215    RTL_VLAN_REGS(10, 0, 1, 4),
216    RTL_VLAN_REGS(11, 1, 1, 4),
217    RTL_VLAN_REGS(12, 2, 1, 4),
218    RTL_VLAN_REGS(13, 3, 1, 4),
219    RTL_VLAN_REGS(14, 4, 1, 4),
220    RTL_VLAN_REGS(15, 0, 1, 6),
221
222#define REG_PORT_SETTING(port, phy) \
223    [RTL_REG_PORT##port##_SPEED] = { 0, phy, 0, 1, 13, 0 }, \
224    [RTL_REG_PORT##port##_NWAY] = { 0, phy, 0, 1, 12, 0 }, \
225    [RTL_REG_PORT##port##_NRESTART] = { 0, phy, 0, 1, 9, 0 }, \
226    [RTL_REG_PORT##port##_DUPLEX] = { 0, phy, 0, 1, 8, 0 }, \
227    [RTL_REG_PORT##port##_TXEN] = { 0, phy, 24, 1, 11, 0 }, \
228    [RTL_REG_PORT##port##_RXEN] = { 0, phy, 24, 1, 10, 0 }, \
229    [RTL_REG_PORT##port##_LINK] = { 0, phy, 1, 1, 2, 0 }, \
230    [RTL_REG_PORT##port##_NULL_VID_REPLACE] = { 0, phy, 22, 1, 12, 0 }, \
231    [RTL_REG_PORT##port##_NON_PVID_DISCARD] = { 0, phy, 22, 1, 11, 0 }, \
232    [RTL_REG_PORT##port##_VID_INSERT] = { 0, phy, 22, 2, 9, 0 }, \
233    [RTL_REG_PORT##port##_TAG_INSERT] = { 0, phy, 22, 2, 0, 0 }
234
235    REG_PORT_SETTING(0, 0),
236    REG_PORT_SETTING(1, 1),
237    REG_PORT_SETTING(2, 2),
238    REG_PORT_SETTING(3, 3),
239    REG_PORT_SETTING(4, 4),
240    REG_PORT_SETTING(5, 6),
241
242#define REG_PORT_PVID(phy, page, regofs) \
243    { page, phy, 24 + regofs, 4, 12, 0 }
244    [RTL_REG_PORT0_PVID] = REG_PORT_PVID(0, 0, 0),
245    [RTL_REG_PORT1_PVID] = REG_PORT_PVID(1, 0, 0),
246    [RTL_REG_PORT2_PVID] = REG_PORT_PVID(2, 0, 0),
247    [RTL_REG_PORT3_PVID] = REG_PORT_PVID(3, 0, 0),
248    [RTL_REG_PORT4_PVID] = REG_PORT_PVID(4, 0, 0),
249    [RTL_REG_PORT5_PVID] = REG_PORT_PVID(0, 1, 2),
250};
251
252
253static inline void
254rtl_set_page(struct rtl_priv *priv, unsigned int page)
255{
256    struct mii_bus *bus = priv->bus;
257    u16 pgsel;
258
259    if (priv->page == page)
260        return;
261
262    BUG_ON(page > RTL8306_NUM_PAGES);
263    pgsel = bus->read(bus, 0, RTL8306_REG_PAGE);
264    pgsel &= ~(RTL8306_REG_PAGE_LO | RTL8306_REG_PAGE_HI);
265    if (page & (1 << 0))
266        pgsel |= RTL8306_REG_PAGE_LO;
267    if (!(page & (1 << 1))) /* bit is inverted */
268        pgsel |= RTL8306_REG_PAGE_HI;
269    bus->write(bus, 0, RTL8306_REG_PAGE, pgsel);
270}
271
272static inline int
273rtl_w16(struct switch_dev *dev, unsigned int page, unsigned int phy, unsigned int reg, u16 val)
274{
275    struct rtl_priv *priv = to_rtl(dev);
276    struct mii_bus *bus = priv->bus;
277
278    rtl_set_page(priv, page);
279    bus->write(bus, phy, reg, val);
280    bus->read(bus, phy, reg); /* flush */
281    return 0;
282}
283
284static inline int
285rtl_r16(struct switch_dev *dev, unsigned int page, unsigned int phy, unsigned int reg)
286{
287    struct rtl_priv *priv = to_rtl(dev);
288    struct mii_bus *bus = priv->bus;
289
290    rtl_set_page(priv, page);
291    return bus->read(bus, phy, reg);
292}
293
294static inline u16
295rtl_rmw(struct switch_dev *dev, unsigned int page, unsigned int phy, unsigned int reg, u16 mask, u16 val)
296{
297    struct rtl_priv *priv = to_rtl(dev);
298    struct mii_bus *bus = priv->bus;
299    u16 r;
300
301    rtl_set_page(priv, page);
302    r = bus->read(bus, phy, reg);
303    r &= ~mask;
304    r |= val;
305    bus->write(bus, phy, reg, r);
306    return bus->read(bus, phy, reg); /* flush */
307}
308
309
310static inline int
311rtl_get(struct switch_dev *dev, enum rtl_regidx s)
312{
313    const struct rtl_reg *r = &rtl_regs[s];
314    u16 val;
315
316    BUG_ON(s >= ARRAY_SIZE(rtl_regs));
317    if (r->bits == 0) /* unimplemented */
318        return 0;
319
320    val = rtl_r16(dev, r->page, r->phy, r->reg);
321
322    if (r->shift > 0)
323        val >>= r->shift;
324
325    if (r->inverted)
326        val = ~val;
327
328    val &= (1 << r->bits) - 1;
329
330    return val;
331}
332
333static int
334rtl_set(struct switch_dev *dev, enum rtl_regidx s, unsigned int val)
335{
336    const struct rtl_reg *r = &rtl_regs[s];
337    u16 mask = 0xffff;
338
339    BUG_ON(s >= ARRAY_SIZE(rtl_regs));
340
341    if (r->bits == 0) /* unimplemented */
342        return 0;
343
344    if (r->shift > 0)
345        val <<= r->shift;
346
347    if (r->inverted)
348        val = ~val;
349
350    if (r->bits != 16) {
351        mask = (1 << r->bits) - 1;
352        mask <<= r->shift;
353    }
354    val &= mask;
355    return rtl_rmw(dev, r->page, r->phy, r->reg, mask, val);
356}
357
358static void
359rtl_phy_save(struct switch_dev *dev, int port, struct rtl_phyregs *regs)
360{
361    regs->nway = rtl_get(dev, RTL_PORT_REG(port, NWAY));
362    regs->speed = rtl_get(dev, RTL_PORT_REG(port, SPEED));
363    regs->duplex = rtl_get(dev, RTL_PORT_REG(port, DUPLEX));
364}
365
366static void
367rtl_phy_restore(struct switch_dev *dev, int port, struct rtl_phyregs *regs)
368{
369    rtl_set(dev, RTL_PORT_REG(port, NWAY), regs->nway);
370    rtl_set(dev, RTL_PORT_REG(port, SPEED), regs->speed);
371    rtl_set(dev, RTL_PORT_REG(port, DUPLEX), regs->duplex);
372}
373
374static void
375rtl_port_set_enable(struct switch_dev *dev, int port, int enabled)
376{
377    rtl_set(dev, RTL_PORT_REG(port, RXEN), enabled);
378    rtl_set(dev, RTL_PORT_REG(port, TXEN), enabled);
379
380    if ((port >= 5) || !enabled)
381        return;
382
383    /* restart autonegotiation if enabled */
384    rtl_set(dev, RTL_PORT_REG(port, NRESTART), 1);
385}
386
387static int
388rtl_hw_apply(struct switch_dev *dev)
389{
390    int i;
391    int trunk_en, trunk_psel;
392    struct rtl_phyregs port5;
393
394    rtl_phy_save(dev, 5, &port5);
395
396    /* disable rx/tx from PHYs */
397    for (i = 0; i < RTL8306_NUM_PORTS - 1; i++) {
398        rtl_port_set_enable(dev, i, 0);
399    }
400
401    /* save trunking status */
402    trunk_en = rtl_get(dev, RTL_REG_EN_TRUNK);
403    trunk_psel = rtl_get(dev, RTL_REG_TRUNK_PORTSEL);
404
405    /* trunk port 3 and 4
406     * XXX: Big WTF, but RealTek seems to do it */
407    rtl_set(dev, RTL_REG_EN_TRUNK, 1);
408    rtl_set(dev, RTL_REG_TRUNK_PORTSEL, 1);
409
410    /* execute the software reset */
411    rtl_set(dev, RTL_REG_RESET, 1);
412
413    /* wait for the reset to complete,
414     * but don't wait for too long */
415    for (i = 0; i < 10; i++) {
416        if (rtl_get(dev, RTL_REG_RESET) == 0)
417            break;
418
419        msleep(1);
420    }
421
422    /* enable rx/tx from PHYs */
423    for (i = 0; i < RTL8306_NUM_PORTS - 1; i++) {
424        rtl_port_set_enable(dev, i, 1);
425    }
426
427    /* restore trunking settings */
428    rtl_set(dev, RTL_REG_EN_TRUNK, trunk_en);
429    rtl_set(dev, RTL_REG_TRUNK_PORTSEL, trunk_psel);
430    rtl_phy_restore(dev, 5, &port5);
431
432    return 0;
433}
434
435static void
436rtl_hw_init(struct switch_dev *dev)
437{
438    struct rtl_priv *priv = to_rtl(dev);
439    int cpu_mask = 1 << dev->cpu_port;
440    int i;
441
442    rtl_set(dev, RTL_REG_VLAN_ENABLE, 0);
443    rtl_set(dev, RTL_REG_VLAN_FILTER, 0);
444    rtl_set(dev, RTL_REG_EN_TRUNK, 0);
445    rtl_set(dev, RTL_REG_TRUNK_PORTSEL, 0);
446
447    /* initialize cpu port settings */
448    if (priv->do_cpu) {
449        rtl_set(dev, RTL_REG_CPUPORT, dev->cpu_port);
450        rtl_set(dev, RTL_REG_EN_CPUPORT, 1);
451    } else {
452        rtl_set(dev, RTL_REG_CPUPORT, 7);
453        rtl_set(dev, RTL_REG_EN_CPUPORT, 0);
454    }
455    rtl_set(dev, RTL_REG_EN_TAG_OUT, 0);
456    rtl_set(dev, RTL_REG_EN_TAG_IN, 0);
457    rtl_set(dev, RTL_REG_EN_TAG_CLR, 0);
458
459    /* reset all vlans */
460    for (i = 0; i < RTL8306_NUM_VLANS; i++) {
461        rtl_set(dev, RTL_VLAN_REG(i, VID), i);
462        rtl_set(dev, RTL_VLAN_REG(i, PORTMASK), 0);
463    }
464
465    /* default to port isolation */
466    for (i = 0; i < RTL8306_NUM_PORTS; i++) {
467        unsigned long mask;
468
469        if ((1 << i) == cpu_mask)
470            mask = ((1 << RTL8306_NUM_PORTS) - 1) & ~cpu_mask; /* all bits set */
471        else
472            mask = cpu_mask | (1 << i);
473
474        rtl_set(dev, RTL_VLAN_REG(i, PORTMASK), mask);
475        rtl_set(dev, RTL_PORT_REG(i, PVID), i);
476        rtl_set(dev, RTL_PORT_REG(i, NULL_VID_REPLACE), 1);
477        rtl_set(dev, RTL_PORT_REG(i, VID_INSERT), 1);
478        rtl_set(dev, RTL_PORT_REG(i, TAG_INSERT), 3);
479    }
480    rtl_hw_apply(dev);
481}
482
483#ifdef DEBUG
484static int
485rtl_set_use_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
486{
487    struct rtl_priv *priv = to_rtl(dev);
488    priv->do_cpu = val->value.i;
489    rtl_hw_init(dev);
490    return 0;
491}
492
493static int
494rtl_get_use_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
495{
496    struct rtl_priv *priv = to_rtl(dev);
497    val->value.i = priv->do_cpu;
498    return 0;
499}
500
501static int
502rtl_set_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
503{
504    dev->cpu_port = val->value.i;
505    rtl_hw_init(dev);
506    return 0;
507}
508
509static int
510rtl_get_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
511{
512    val->value.i = dev->cpu_port;
513    return 0;
514}
515#endif
516
517static int
518rtl_reset(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
519{
520    rtl_hw_init(dev);
521    return 0;
522}
523
524static int
525rtl_attr_set_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
526{
527    int idx = attr->id + (val->port_vlan * attr->ofs);
528    struct rtl_phyregs port;
529
530    if (attr->id >= ARRAY_SIZE(rtl_regs))
531        return -EINVAL;
532
533    if ((attr->max > 0) && (val->value.i > attr->max))
534        return -EINVAL;
535
536    /* access to phy register 22 on port 4/5
537     * needs phy status save/restore */
538    if ((val->port_vlan > 3) &&
539        (rtl_regs[idx].reg == 22) &&
540        (rtl_regs[idx].page == 0)) {
541
542        rtl_phy_save(dev, val->port_vlan, &port);
543        rtl_set(dev, idx, val->value.i);
544        rtl_phy_restore(dev, val->port_vlan, &port);
545    } else {
546        rtl_set(dev, idx, val->value.i);
547    }
548
549    return 0;
550}
551
552static int
553rtl_attr_get_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
554{
555    int idx = attr->id + (val->port_vlan * attr->ofs);
556
557    if (idx >= ARRAY_SIZE(rtl_regs))
558        return -EINVAL;
559
560    val->value.i = rtl_get(dev, idx);
561    return 0;
562}
563
564static int
565rtl_attr_set_port_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
566{
567    if (val->port_vlan >= RTL8306_NUM_PORTS)
568        return -EINVAL;
569
570    return rtl_attr_set_int(dev, attr, val);
571}
572
573static int
574rtl_attr_get_port_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
575{
576    if (val->port_vlan >= RTL8306_NUM_PORTS)
577        return -EINVAL;
578    return rtl_attr_get_int(dev, attr, val);
579}
580
581static int
582rtl_attr_set_vlan_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
583{
584    if (val->port_vlan >= dev->vlans)
585        return -EINVAL;
586
587    return rtl_attr_set_int(dev, attr, val);
588}
589
590static int
591rtl_attr_get_vlan_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
592{
593    if (val->port_vlan >= dev->vlans)
594        return -EINVAL;
595
596    return rtl_attr_get_int(dev, attr, val);
597}
598
599static int
600rtl_get_ports(struct switch_dev *dev, struct switch_val *val)
601{
602    unsigned int i, mask;
603
604    mask = rtl_get(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK));
605    for (i = 0; i < RTL8306_NUM_PORTS; i++) {
606        struct switch_port *port;
607
608        if (!(mask & (1 << i)))
609            continue;
610
611        port = &val->value.ports[val->len];
612        port->id = i;
613        port->flags = 0;
614        val->len++;
615    }
616
617    return 0;
618}
619
620static int
621rtl_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
622{
623    struct rtl_priv *priv = to_rtl(dev);
624    struct rtl_phyregs port;
625    int en = val->value.i;
626    int i;
627
628    rtl_set(dev, RTL_REG_EN_TAG_OUT, en && priv->do_cpu);
629    rtl_set(dev, RTL_REG_EN_TAG_IN, en && priv->do_cpu);
630    rtl_set(dev, RTL_REG_EN_TAG_CLR, en && priv->do_cpu);
631    rtl_set(dev, RTL_REG_VLAN_TAG_AWARE, en);
632    if (en)
633        rtl_set(dev, RTL_REG_VLAN_FILTER, en);
634
635    for (i = 0; i < RTL8306_NUM_PORTS; i++) {
636        if (i > 3)
637            rtl_phy_save(dev, val->port_vlan, &port);
638        rtl_set(dev, RTL_PORT_REG(i, NULL_VID_REPLACE), 1);
639        rtl_set(dev, RTL_PORT_REG(i, VID_INSERT), (en ? (i == dev->cpu_port ? 0 : 1) : 1));
640        rtl_set(dev, RTL_PORT_REG(i, TAG_INSERT), (en ? (i == dev->cpu_port ? 2 : 1) : 3));
641        if (i > 3)
642            rtl_phy_restore(dev, val->port_vlan, &port);
643    }
644    rtl_set(dev, RTL_REG_VLAN_ENABLE, en);
645
646    return 0;
647}
648
649static int
650rtl_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
651{
652    return rtl_get(dev, RTL_REG_VLAN_ENABLE);
653}
654
655static int
656rtl_set_ports(struct switch_dev *dev, struct switch_val *val)
657{
658    unsigned int mask = 0;
659    unsigned int oldmask;
660    int i;
661
662    for(i = 0; i < val->len; i++)
663    {
664        struct switch_port *port = &val->value.ports[i];
665        bool tagged = false;
666
667        mask |= (1 << port->id);
668
669        if (port->id == dev->cpu_port)
670            continue;
671
672        if ((i == dev->cpu_port) ||
673            (port->flags & (1 << SWITCH_PORT_FLAG_TAGGED)))
674            tagged = true;
675
676        /* fix up PVIDs for added ports */
677        if (!tagged)
678            rtl_set(dev, RTL_PORT_REG(port->id, PVID), val->port_vlan);
679
680        rtl_set(dev, RTL_PORT_REG(port->id, NON_PVID_DISCARD), (tagged ? 0 : 1));
681        rtl_set(dev, RTL_PORT_REG(port->id, VID_INSERT), (tagged ? 0 : 1));
682        rtl_set(dev, RTL_PORT_REG(port->id, TAG_INSERT), (tagged ? 2 : 1));
683    }
684
685    oldmask = rtl_get(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK));
686    rtl_set(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK), mask);
687
688    /* fix up PVIDs for removed ports, default to last vlan */
689    oldmask &= ~mask;
690    for (i = 0; i < RTL8306_NUM_PORTS; i++) {
691        if (!(oldmask & (1 << i)))
692            continue;
693
694        if (i == dev->cpu_port)
695            continue;
696
697        if (rtl_get(dev, RTL_PORT_REG(i, PVID)) == val->port_vlan)
698            rtl_set(dev, RTL_PORT_REG(i, PVID), dev->vlans - 1);
699    }
700
701    return 0;
702}
703
704static struct switch_attr rtl_globals[] = {
705    {
706        .type = SWITCH_TYPE_INT,
707        .name = "reset",
708        .description = "Reset the switch",
709        .set = rtl_reset,
710    },
711    {
712        .type = SWITCH_TYPE_INT,
713        .name = "enable_vlan",
714        .description = "Enable VLAN mode",
715        .max = 1,
716        .set = rtl_set_vlan,
717        .get = rtl_get_vlan,
718    },
719    {
720        RTL_GLOBAL_REGATTR(EN_TRUNK),
721        .name = "trunk",
722        .description = "Enable port trunking",
723        .max = 1,
724    },
725    {
726        RTL_GLOBAL_REGATTR(TRUNK_PORTSEL),
727        .name = "trunk_sel",
728        .description = "Select ports for trunking (0: 0,1 - 1: 3,4)",
729        .max = 1,
730    },
731#ifdef DEBUG
732    {
733        RTL_GLOBAL_REGATTR(VLAN_FILTER),
734        .name = "vlan_filter",
735        .description = "Filter incoming packets for allowed VLANS",
736        .max = 1,
737    },
738    {
739        .type = SWITCH_TYPE_INT,
740        .name = "cpuport",
741        .description = "CPU Port",
742        .set = rtl_set_cpuport,
743        .get = rtl_get_cpuport,
744        .max = RTL8306_NUM_PORTS,
745    },
746    {
747        .type = SWITCH_TYPE_INT,
748        .name = "use_cpuport",
749        .description = "CPU Port handling flag",
750        .set = rtl_set_use_cpuport,
751        .get = rtl_get_use_cpuport,
752        .max = RTL8306_NUM_PORTS,
753    },
754    {
755        RTL_GLOBAL_REGATTR(TRAP_CPU),
756        .name = "trap_cpu",
757        .description = "VLAN trap to CPU",
758        .max = 1,
759    },
760    {
761        RTL_GLOBAL_REGATTR(VLAN_TAG_AWARE),
762        .name = "vlan_tag_aware",
763        .description = "Enable VLAN tag awareness",
764        .max = 1,
765    },
766    {
767        RTL_GLOBAL_REGATTR(VLAN_TAG_ONLY),
768        .name = "tag_only",
769        .description = "Only accept tagged packets",
770        .max = 1,
771    },
772#endif
773};
774static struct switch_attr rtl_port[] = {
775    {
776        RTL_PORT_REGATTR(PVID),
777        .name = "pvid",
778        .description = "Port VLAN ID",
779        .max = RTL8306_NUM_VLANS - 1,
780    },
781    {
782        RTL_PORT_REGATTR(LINK),
783        .name = "link",
784        .description = "get the current link state",
785        .max = 1,
786        .set = NULL,
787    },
788#ifdef DEBUG
789    {
790        RTL_PORT_REGATTR(NULL_VID_REPLACE),
791        .name = "null_vid",
792        .description = "NULL VID gets replaced by port default vid",
793        .max = 1,
794    },
795    {
796        RTL_PORT_REGATTR(NON_PVID_DISCARD),
797        .name = "non_pvid_discard",
798        .description = "discard packets with VID != PVID",
799        .max = 1,
800    },
801    {
802        RTL_PORT_REGATTR(VID_INSERT),
803        .name = "vid_insert_remove",
804        .description = "how should the switch insert and remove vids ?",
805        .max = 3,
806    },
807    {
808        RTL_PORT_REGATTR(TAG_INSERT),
809        .name = "tag_insert",
810        .description = "tag insertion handling",
811        .max = 3,
812    },
813#endif
814    {
815        RTL_PORT_REGATTR(SPEED),
816        .name = "speed",
817        .description = "current link speed",
818        .max = 1,
819    },
820    {
821        RTL_PORT_REGATTR(NWAY),
822        .name = "nway",
823        .description = "enable autonegotiation",
824        .max = 1,
825    },
826};
827
828static struct switch_attr rtl_vlan[] = {
829    {
830        RTL_VLAN_REGATTR(VID),
831        .name = "vid",
832        .description = "VLAN ID (1-4095)",
833        .max = 4095,
834    },
835};
836
837static const struct switch_dev_ops rtl8306_ops = {
838    .attr_global = {
839        .attr = rtl_globals,
840        .n_attr = ARRAY_SIZE(rtl_globals),
841    },
842    .attr_port = {
843        .attr = rtl_port,
844        .n_attr = ARRAY_SIZE(rtl_port),
845    },
846    .attr_vlan = {
847        .attr = rtl_vlan,
848        .n_attr = ARRAY_SIZE(rtl_vlan),
849    },
850
851    .get_vlan_ports = rtl_get_ports,
852    .set_vlan_ports = rtl_set_ports,
853    .apply_config = rtl_hw_apply,
854};
855
856static int
857rtl8306_config_init(struct phy_device *pdev)
858{
859    struct net_device *netdev = pdev->attached_dev;
860    struct rtl_priv *priv = pdev->priv;
861    struct switch_dev *dev = &priv->dev;
862    struct switch_val val;
863    unsigned int chipid, chipver, chiptype;
864    int err;
865
866    /* Only init the switch for the primary PHY */
867    if (pdev->addr != 0)
868        return 0;
869
870    val.value.i = 1;
871    priv->dev.cpu_port = RTL8306_PORT_CPU;
872    priv->dev.ports = RTL8306_NUM_PORTS;
873    priv->dev.vlans = RTL8306_NUM_VLANS;
874    priv->dev.ops = &rtl8306_ops;
875    priv->do_cpu = 0;
876    priv->page = -1;
877    priv->bus = pdev->bus;
878
879    chipid = rtl_get(dev, RTL_REG_CHIPID);
880    chipver = rtl_get(dev, RTL_REG_CHIPVER);
881    chiptype = rtl_get(dev, RTL_REG_CHIPTYPE);
882    switch(chiptype) {
883    case 0:
884    case 2:
885        strncpy(priv->hwname, RTL_NAME_S, sizeof(priv->hwname));
886        priv->type = RTL_TYPE_S;
887        break;
888    case 1:
889        strncpy(priv->hwname, RTL_NAME_SD, sizeof(priv->hwname));
890        priv->type = RTL_TYPE_SD;
891        break;
892    case 3:
893        strncpy(priv->hwname, RTL_NAME_SDM, sizeof(priv->hwname));
894        priv->type = RTL_TYPE_SDM;
895        break;
896    default:
897        strncpy(priv->hwname, RTL_NAME_UNKNOWN, sizeof(priv->hwname));
898        break;
899    }
900
901    dev->name = priv->hwname;
902    rtl_hw_init(dev);
903
904    printk(KERN_INFO "Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv->hwname, chipid, chipver);
905
906    err = register_switch(dev, netdev);
907    if (err < 0) {
908        kfree(priv);
909        return err;
910    }
911
912    return 0;
913}
914
915
916static int
917rtl8306_fixup(struct phy_device *pdev)
918{
919    struct rtl_priv priv;
920    u16 chipid;
921
922    /* Attach to primary LAN port and WAN port */
923    if (pdev->addr != 0 && pdev->addr != 4)
924        return 0;
925
926    priv.page = -1;
927    priv.bus = pdev->bus;
928    chipid = rtl_get(&priv.dev, RTL_REG_CHIPID);
929    if (chipid == 0x5988)
930        pdev->phy_id = RTL8306_MAGIC;
931
932    return 0;
933}
934
935static int
936rtl8306_probe(struct phy_device *pdev)
937{
938    struct rtl_priv *priv;
939
940    list_for_each_entry(priv, &phydevs, list) {
941        /*
942         * share one rtl_priv instance between virtual phy
943         * devices on the same bus
944         */
945        if (priv->bus == pdev->bus)
946            goto found;
947    }
948    priv = kzalloc(sizeof(struct rtl_priv), GFP_KERNEL);
949    if (!priv)
950        return -ENOMEM;
951
952    priv->bus = pdev->bus;
953
954found:
955    pdev->priv = priv;
956    return 0;
957}
958
959static void
960rtl8306_remove(struct phy_device *pdev)
961{
962    struct rtl_priv *priv = pdev->priv;
963    unregister_switch(&priv->dev);
964    kfree(priv);
965}
966
967static int
968rtl8306_config_aneg(struct phy_device *pdev)
969{
970    struct rtl_priv *priv = pdev->priv;
971
972    /* Only for WAN */
973    if (pdev->addr == 0)
974        return 0;
975
976    /* Restart autonegotiation */
977    rtl_set(&priv->dev, RTL_PORT_REG(4, NWAY), 1);
978    rtl_set(&priv->dev, RTL_PORT_REG(4, NRESTART), 1);
979
980    return 0;
981}
982
983static int
984rtl8306_read_status(struct phy_device *pdev)
985{
986    struct rtl_priv *priv = pdev->priv;
987    struct switch_dev *dev = &priv->dev;
988
989    if (pdev->addr == 4) {
990        /* WAN */
991        pdev->speed = rtl_get(dev, RTL_PORT_REG(4, SPEED)) ? SPEED_100 : SPEED_10;
992        pdev->duplex = rtl_get(dev, RTL_PORT_REG(4, DUPLEX)) ? DUPLEX_FULL : DUPLEX_HALF;
993        pdev->link = !!rtl_get(dev, RTL_PORT_REG(4, LINK));
994    } else {
995        /* LAN */
996        pdev->speed = SPEED_100;
997        pdev->duplex = DUPLEX_FULL;
998        pdev->link = 1;
999    }
1000
1001    /*
1002     * Bypass generic PHY status read,
1003     * it doesn't work with this switch
1004     */
1005    if (pdev->link) {
1006        pdev->state = PHY_RUNNING;
1007        netif_carrier_on(pdev->attached_dev);
1008        pdev->adjust_link(pdev->attached_dev);
1009    } else {
1010        pdev->state = PHY_NOLINK;
1011        netif_carrier_off(pdev->attached_dev);
1012        pdev->adjust_link(pdev->attached_dev);
1013    }
1014
1015    return 0;
1016}
1017
1018
1019static struct phy_driver rtl8306_driver = {
1020    .name = "Realtek RTL8306S",
1021    .flags = PHY_HAS_MAGICANEG,
1022    .phy_id = RTL8306_MAGIC,
1023    .phy_id_mask = 0xffffffff,
1024    .features = PHY_BASIC_FEATURES,
1025    .probe = &rtl8306_probe,
1026    .remove = &rtl8306_remove,
1027    .config_init = &rtl8306_config_init,
1028    .config_aneg = &rtl8306_config_aneg,
1029    .read_status = &rtl8306_read_status,
1030    .driver = { .owner = THIS_MODULE,},
1031};
1032
1033
1034static int __init
1035rtl_init(void)
1036{
1037    phy_register_fixup_for_id(PHY_ANY_ID, rtl8306_fixup);
1038    return phy_driver_register(&rtl8306_driver);
1039}
1040
1041static void __exit
1042rtl_exit(void)
1043{
1044    phy_driver_unregister(&rtl8306_driver);
1045}
1046
1047module_init(rtl_init);
1048module_exit(rtl_exit);
1049MODULE_LICENSE("GPL");
1050
1051

Archive Download this file



interactive