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

Archive Download this file



interactive