source: trunk/target/linux/generic/files/drivers/net/phy/rtl8306.c @ 23419

Last change on this file since 23419 was 23419, checked in by jow, 6 years ago

[generic] unify extended vlan id swconfig attributes.
AR8216 and PSB6970 used "pvid", IP17xx used "tag" and RTL8306 called it "vid".
Change all to "vid" and annotate the description with the valid ID range.

File size: 24.2 KB
Line 
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
Note: See TracBrowser for help on using the repository browser.