source: trunk/target/linux/generic/files/drivers/net/phy/rtl8366s.c @ 28267

Last change on this file since 28267 was 28267, checked in by juhosg, 5 years ago

generic: jumbo frames support for rtl8366s

This patch adds the option to enable jumbo frames on the rtl8366s
switch. This is almost exactly the same as the first patch at
https://dev.openwrt.org/ticket/7977 and it has been requested
in a comment there.

I have tested this and it successfully allows devices on the switch
using jumbo frames to communicate.

Signed-off-by: Ash Hughes <ashley.hughes@…>

File size: 29.5 KB
Line 
1/*
2 * Platform driver for the Realtek RTL8366S ethernet switch
3 *
4 * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2010 Antti SeppÀlÀ <a.seppala@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/delay.h>
17#include <linux/skbuff.h>
18#include <linux/rtl8366.h>
19
20#include "rtl8366_smi.h"
21
22#define RTL8366S_DRIVER_DESC    "Realtek RTL8366S ethernet switch driver"
23#define RTL8366S_DRIVER_VER     "0.2.2"
24
25#define RTL8366S_PHY_NO_MAX     4
26#define RTL8366S_PHY_PAGE_MAX   7
27#define RTL8366S_PHY_ADDR_MAX   31
28
29/* Switch Global Configuration register */
30#define RTL8366S_SGCR                           0x0000
31#define RTL8366S_SGCR_EN_BC_STORM_CTRL          BIT(0)
32#define RTL8366S_SGCR_MAX_LENGTH(_x)            (_x << 4)
33#define RTL8366S_SGCR_MAX_LENGTH_MASK           RTL8366S_SGCR_MAX_LENGTH(0x3)
34#define RTL8366S_SGCR_MAX_LENGTH_1522           RTL8366S_SGCR_MAX_LENGTH(0x0)
35#define RTL8366S_SGCR_MAX_LENGTH_1536           RTL8366S_SGCR_MAX_LENGTH(0x1)
36#define RTL8366S_SGCR_MAX_LENGTH_1552           RTL8366S_SGCR_MAX_LENGTH(0x2)
37#define RTL8366S_SGCR_MAX_LENGTH_16000          RTL8366S_SGCR_MAX_LENGTH(0x3)
38#define RTL8366S_SGCR_EN_VLAN                   BIT(13)
39
40/* Port Enable Control register */
41#define RTL8366S_PECR                           0x0001
42
43/* Switch Security Control registers */
44#define RTL8366S_SSCR0                          0x0002
45#define RTL8366S_SSCR1                          0x0003
46#define RTL8366S_SSCR2                          0x0004
47#define RTL8366S_SSCR2_DROP_UNKNOWN_DA          BIT(0)
48
49#define RTL8366S_RESET_CTRL_REG                 0x0100
50#define RTL8366S_CHIP_CTRL_RESET_HW             1
51#define RTL8366S_CHIP_CTRL_RESET_SW             (1 << 1)
52
53#define RTL8366S_CHIP_VERSION_CTRL_REG          0x0104
54#define RTL8366S_CHIP_VERSION_MASK              0xf
55#define RTL8366S_CHIP_ID_REG                    0x0105
56#define RTL8366S_CHIP_ID_8366                   0x8366
57
58/* PHY registers control */
59#define RTL8366S_PHY_ACCESS_CTRL_REG            0x8028
60#define RTL8366S_PHY_ACCESS_DATA_REG            0x8029
61
62#define RTL8366S_PHY_CTRL_READ                  1
63#define RTL8366S_PHY_CTRL_WRITE                 0
64
65#define RTL8366S_PHY_REG_MASK                   0x1f
66#define RTL8366S_PHY_PAGE_OFFSET                5
67#define RTL8366S_PHY_PAGE_MASK                  (0x7 << 5)
68#define RTL8366S_PHY_NO_OFFSET                  9
69#define RTL8366S_PHY_NO_MASK                    (0x1f << 9)
70
71/* LED control registers */
72#define RTL8366S_LED_BLINKRATE_REG              0x0420
73#define RTL8366S_LED_BLINKRATE_BIT              0
74#define RTL8366S_LED_BLINKRATE_MASK             0x0007
75
76#define RTL8366S_LED_CTRL_REG                   0x0421
77#define RTL8366S_LED_0_1_CTRL_REG               0x0422
78#define RTL8366S_LED_2_3_CTRL_REG               0x0423
79
80#define RTL8366S_MIB_COUNT                      33
81#define RTL8366S_GLOBAL_MIB_COUNT               1
82#define RTL8366S_MIB_COUNTER_PORT_OFFSET        0x0040
83#define RTL8366S_MIB_COUNTER_BASE               0x1000
84#define RTL8366S_MIB_COUNTER_PORT_OFFSET2       0x0008
85#define RTL8366S_MIB_COUNTER_BASE2              0x1180
86#define RTL8366S_MIB_CTRL_REG                   0x11F0
87#define RTL8366S_MIB_CTRL_USER_MASK             0x01FF
88#define RTL8366S_MIB_CTRL_BUSY_MASK             0x0001
89#define RTL8366S_MIB_CTRL_RESET_MASK            0x0002
90
91#define RTL8366S_MIB_CTRL_GLOBAL_RESET_MASK     0x0004
92#define RTL8366S_MIB_CTRL_PORT_RESET_BIT        0x0003
93#define RTL8366S_MIB_CTRL_PORT_RESET_MASK       0x01FC
94
95
96#define RTL8366S_PORT_VLAN_CTRL_BASE            0x0058
97#define RTL8366S_PORT_VLAN_CTRL_REG(_p)  \
98                (RTL8366S_PORT_VLAN_CTRL_BASE + (_p) / 4)
99#define RTL8366S_PORT_VLAN_CTRL_MASK            0xf
100#define RTL8366S_PORT_VLAN_CTRL_SHIFT(_p)       (4 * ((_p) % 4))
101
102
103#define RTL8366S_VLAN_TABLE_READ_BASE           0x018B
104#define RTL8366S_VLAN_TABLE_WRITE_BASE          0x0185
105
106#define RTL8366S_VLAN_TB_CTRL_REG               0x010F
107
108#define RTL8366S_TABLE_ACCESS_CTRL_REG          0x0180
109#define RTL8366S_TABLE_VLAN_READ_CTRL           0x0E01
110#define RTL8366S_TABLE_VLAN_WRITE_CTRL          0x0F01
111
112#define RTL8366S_VLAN_MC_BASE(_x)               (0x0016 + (_x) * 2)
113
114#define RTL8366S_VLAN_MEMBERINGRESS_REG         0x0379
115
116#define RTL8366S_PORT_LINK_STATUS_BASE          0x0060
117#define RTL8366S_PORT_STATUS_SPEED_MASK         0x0003
118#define RTL8366S_PORT_STATUS_DUPLEX_MASK        0x0004
119#define RTL8366S_PORT_STATUS_LINK_MASK          0x0010
120#define RTL8366S_PORT_STATUS_TXPAUSE_MASK       0x0020
121#define RTL8366S_PORT_STATUS_RXPAUSE_MASK       0x0040
122#define RTL8366S_PORT_STATUS_AN_MASK            0x0080
123
124
125#define RTL8366S_PORT_NUM_CPU           5
126#define RTL8366S_NUM_PORTS              6
127#define RTL8366S_NUM_VLANS              16
128#define RTL8366S_NUM_LEDGROUPS          4
129#define RTL8366S_NUM_VIDS               4096
130#define RTL8366S_PRIORITYMAX            7
131#define RTL8366S_FIDMAX                 7
132
133
134#define RTL8366S_PORT_1                 (1 << 0) /* In userspace port 0 */
135#define RTL8366S_PORT_2                 (1 << 1) /* In userspace port 1 */
136#define RTL8366S_PORT_3                 (1 << 2) /* In userspace port 2 */
137#define RTL8366S_PORT_4                 (1 << 3) /* In userspace port 3 */
138
139#define RTL8366S_PORT_UNKNOWN           (1 << 4) /* No known connection */
140#define RTL8366S_PORT_CPU               (1 << 5) /* CPU port */
141
142#define RTL8366S_PORT_ALL               (RTL8366S_PORT_1 |      \
143                                         RTL8366S_PORT_2 |      \
144                                         RTL8366S_PORT_3 |      \
145                                         RTL8366S_PORT_4 |      \
146                                         RTL8366S_PORT_UNKNOWN | \
147                                         RTL8366S_PORT_CPU)
148
149#define RTL8366S_PORT_ALL_BUT_CPU       (RTL8366S_PORT_1 |      \
150                                         RTL8366S_PORT_2 |      \
151                                         RTL8366S_PORT_3 |      \
152                                         RTL8366S_PORT_4 |      \
153                                         RTL8366S_PORT_UNKNOWN)
154
155#define RTL8366S_PORT_ALL_EXTERNAL      (RTL8366S_PORT_1 |      \
156                                         RTL8366S_PORT_2 |      \
157                                         RTL8366S_PORT_3 |      \
158                                         RTL8366S_PORT_4)
159
160#define RTL8366S_PORT_ALL_INTERNAL      (RTL8366S_PORT_UNKNOWN | \
161                                         RTL8366S_PORT_CPU)
162
163#define RTL8366S_VLAN_VID_MASK          0xfff
164#define RTL8366S_VLAN_PRIORITY_SHIFT    12
165#define RTL8366S_VLAN_PRIORITY_MASK     0x7
166#define RTL8366S_VLAN_MEMBER_MASK       0x3f
167#define RTL8366S_VLAN_UNTAG_SHIFT       6
168#define RTL8366S_VLAN_UNTAG_MASK        0x3f
169#define RTL8366S_VLAN_FID_SHIFT         12
170#define RTL8366S_VLAN_FID_MASK          0x7
171
172static struct rtl8366_mib_counter rtl8366s_mib_counters[] = {
173        { 0,  0, 4, "IfInOctets"                                },
174        { 0,  4, 4, "EtherStatsOctets"                          },
175        { 0,  8, 2, "EtherStatsUnderSizePkts"                   },
176        { 0, 10, 2, "EtherFragments"                            },
177        { 0, 12, 2, "EtherStatsPkts64Octets"                    },
178        { 0, 14, 2, "EtherStatsPkts65to127Octets"               },
179        { 0, 16, 2, "EtherStatsPkts128to255Octets"              },
180        { 0, 18, 2, "EtherStatsPkts256to511Octets"              },
181        { 0, 20, 2, "EtherStatsPkts512to1023Octets"             },
182        { 0, 22, 2, "EtherStatsPkts1024to1518Octets"            },
183        { 0, 24, 2, "EtherOversizeStats"                        },
184        { 0, 26, 2, "EtherStatsJabbers"                         },
185        { 0, 28, 2, "IfInUcastPkts"                             },
186        { 0, 30, 2, "EtherStatsMulticastPkts"                   },
187        { 0, 32, 2, "EtherStatsBroadcastPkts"                   },
188        { 0, 34, 2, "EtherStatsDropEvents"                      },
189        { 0, 36, 2, "Dot3StatsFCSErrors"                        },
190        { 0, 38, 2, "Dot3StatsSymbolErrors"                     },
191        { 0, 40, 2, "Dot3InPauseFrames"                         },
192        { 0, 42, 2, "Dot3ControlInUnknownOpcodes"               },
193        { 0, 44, 4, "IfOutOctets"                               },
194        { 0, 48, 2, "Dot3StatsSingleCollisionFrames"            },
195        { 0, 50, 2, "Dot3StatMultipleCollisionFrames"           },
196        { 0, 52, 2, "Dot3sDeferredTransmissions"                },
197        { 0, 54, 2, "Dot3StatsLateCollisions"                   },
198        { 0, 56, 2, "EtherStatsCollisions"                      },
199        { 0, 58, 2, "Dot3StatsExcessiveCollisions"              },
200        { 0, 60, 2, "Dot3OutPauseFrames"                        },
201        { 0, 62, 2, "Dot1dBasePortDelayExceededDiscards"        },
202
203        /*
204         * The following counters are accessible at a different
205         * base address.
206         */
207        { 1,  0, 2, "Dot1dTpPortInDiscards"                     },
208        { 1,  2, 2, "IfOutUcastPkts"                            },
209        { 1,  4, 2, "IfOutMulticastPkts"                        },
210        { 1,  6, 2, "IfOutBroadcastPkts"                        },
211};
212
213#define REG_WR(_smi, _reg, _val)                                        \
214        do {                                                            \
215                err = rtl8366_smi_write_reg(_smi, _reg, _val);          \
216                if (err)                                                \
217                        return err;                                     \
218        } while (0)
219
220#define REG_RMW(_smi, _reg, _mask, _val)                                \
221        do {                                                            \
222                err = rtl8366_smi_rmwr(_smi, _reg, _mask, _val);        \
223                if (err)                                                \
224                        return err;                                     \
225        } while (0)
226
227static int rtl8366s_reset_chip(struct rtl8366_smi *smi)
228{
229        int timeout = 10;
230        u32 data;
231
232        rtl8366_smi_write_reg(smi, RTL8366S_RESET_CTRL_REG,
233                              RTL8366S_CHIP_CTRL_RESET_HW);
234        do {
235                msleep(1);
236                if (rtl8366_smi_read_reg(smi, RTL8366S_RESET_CTRL_REG, &data))
237                        return -EIO;
238
239                if (!(data & RTL8366S_CHIP_CTRL_RESET_HW))
240                        break;
241        } while (--timeout);
242
243        if (!timeout) {
244                printk("Timeout waiting for the switch to reset\n");
245                return -EIO;
246        }
247
248        return 0;
249}
250
251static int rtl8366s_hw_init(struct rtl8366_smi *smi)
252{
253        struct rtl8366_platform_data *pdata;
254        int err;
255
256        pdata = smi->parent->platform_data;
257        if (pdata->num_initvals && pdata->initvals) {
258                unsigned i;
259
260                dev_info(smi->parent, "applying initvals\n");
261                for (i = 0; i < pdata->num_initvals; i++)
262                        REG_WR(smi, pdata->initvals[i].reg,
263                               pdata->initvals[i].val);
264        }
265
266        /* set maximum packet length to 1536 bytes */
267        REG_RMW(smi, RTL8366S_SGCR, RTL8366S_SGCR_MAX_LENGTH_MASK,
268                RTL8366S_SGCR_MAX_LENGTH_1536);
269
270        /* enable learning for all ports */
271        REG_WR(smi, RTL8366S_SSCR0, 0);
272
273        /* enable auto ageing for all ports */
274        REG_WR(smi, RTL8366S_SSCR1, 0);
275
276        /*
277         * discard VLAN tagged packets if the port is not a member of
278         * the VLAN with which the packets is associated.
279         */
280        REG_WR(smi, RTL8366S_VLAN_MEMBERINGRESS_REG, RTL8366S_PORT_ALL);
281
282        /* don't drop packets whose DA has not been learned */
283        REG_RMW(smi, RTL8366S_SSCR2, RTL8366S_SSCR2_DROP_UNKNOWN_DA, 0);
284
285        return 0;
286}
287
288static int rtl8366s_read_phy_reg(struct rtl8366_smi *smi,
289                                 u32 phy_no, u32 page, u32 addr, u32 *data)
290{
291        u32 reg;
292        int ret;
293
294        if (phy_no > RTL8366S_PHY_NO_MAX)
295                return -EINVAL;
296
297        if (page > RTL8366S_PHY_PAGE_MAX)
298                return -EINVAL;
299
300        if (addr > RTL8366S_PHY_ADDR_MAX)
301                return -EINVAL;
302
303        ret = rtl8366_smi_write_reg(smi, RTL8366S_PHY_ACCESS_CTRL_REG,
304                                    RTL8366S_PHY_CTRL_READ);
305        if (ret)
306                return ret;
307
308        reg = 0x8000 | (1 << (phy_no + RTL8366S_PHY_NO_OFFSET)) |
309              ((page << RTL8366S_PHY_PAGE_OFFSET) & RTL8366S_PHY_PAGE_MASK) |
310              (addr & RTL8366S_PHY_REG_MASK);
311
312        ret = rtl8366_smi_write_reg(smi, reg, 0);
313        if (ret)
314                return ret;
315
316        ret = rtl8366_smi_read_reg(smi, RTL8366S_PHY_ACCESS_DATA_REG, data);
317        if (ret)
318                return ret;
319
320        return 0;
321}
322
323static int rtl8366s_write_phy_reg(struct rtl8366_smi *smi,
324                                  u32 phy_no, u32 page, u32 addr, u32 data)
325{
326        u32 reg;
327        int ret;
328
329        if (phy_no > RTL8366S_PHY_NO_MAX)
330                return -EINVAL;
331
332        if (page > RTL8366S_PHY_PAGE_MAX)
333                return -EINVAL;
334
335        if (addr > RTL8366S_PHY_ADDR_MAX)
336                return -EINVAL;
337
338        ret = rtl8366_smi_write_reg(smi, RTL8366S_PHY_ACCESS_CTRL_REG,
339                                    RTL8366S_PHY_CTRL_WRITE);
340        if (ret)
341                return ret;
342
343        reg = 0x8000 | (1 << (phy_no + RTL8366S_PHY_NO_OFFSET)) |
344              ((page << RTL8366S_PHY_PAGE_OFFSET) & RTL8366S_PHY_PAGE_MASK) |
345              (addr & RTL8366S_PHY_REG_MASK);
346
347        ret = rtl8366_smi_write_reg(smi, reg, data);
348        if (ret)
349                return ret;
350
351        return 0;
352}
353
354static int rtl8366_get_mib_counter(struct rtl8366_smi *smi, int counter,
355                                   int port, unsigned long long *val)
356{
357        int i;
358        int err;
359        u32 addr, data;
360        u64 mibvalue;
361
362        if (port > RTL8366S_NUM_PORTS || counter >= RTL8366S_MIB_COUNT)
363                return -EINVAL;
364
365        switch (rtl8366s_mib_counters[counter].base) {
366        case 0:
367                addr = RTL8366S_MIB_COUNTER_BASE +
368                       RTL8366S_MIB_COUNTER_PORT_OFFSET * port;
369                break;
370
371        case 1:
372                addr = RTL8366S_MIB_COUNTER_BASE2 +
373                        RTL8366S_MIB_COUNTER_PORT_OFFSET2 * port;
374                break;
375
376        default:
377                return -EINVAL;
378        }
379
380        addr += rtl8366s_mib_counters[counter].offset;
381
382        /*
383         * Writing access counter address first
384         * then ASIC will prepare 64bits counter wait for being retrived
385         */
386        data = 0; /* writing data will be discard by ASIC */
387        err = rtl8366_smi_write_reg(smi, addr, data);
388        if (err)
389                return err;
390
391        /* read MIB control register */
392        err =  rtl8366_smi_read_reg(smi, RTL8366S_MIB_CTRL_REG, &data);
393        if (err)
394                return err;
395
396        if (data & RTL8366S_MIB_CTRL_BUSY_MASK)
397                return -EBUSY;
398
399        if (data & RTL8366S_MIB_CTRL_RESET_MASK)
400                return -EIO;
401
402        mibvalue = 0;
403        for (i = rtl8366s_mib_counters[counter].length; i > 0; i--) {
404                err = rtl8366_smi_read_reg(smi, addr + (i - 1), &data);
405                if (err)
406                        return err;
407
408                mibvalue = (mibvalue << 16) | (data & 0xFFFF);
409        }
410
411        *val = mibvalue;
412        return 0;
413}
414
415static int rtl8366s_get_vlan_4k(struct rtl8366_smi *smi, u32 vid,
416                                struct rtl8366_vlan_4k *vlan4k)
417{
418        u32 data[2];
419        int err;
420        int i;
421
422        memset(vlan4k, '\0', sizeof(struct rtl8366_vlan_4k));
423
424        if (vid >= RTL8366S_NUM_VIDS)
425                return -EINVAL;
426
427        /* write VID */
428        err = rtl8366_smi_write_reg(smi, RTL8366S_VLAN_TABLE_WRITE_BASE,
429                                    vid & RTL8366S_VLAN_VID_MASK);
430        if (err)
431                return err;
432
433        /* write table access control word */
434        err = rtl8366_smi_write_reg(smi, RTL8366S_TABLE_ACCESS_CTRL_REG,
435                                    RTL8366S_TABLE_VLAN_READ_CTRL);
436        if (err)
437                return err;
438
439        for (i = 0; i < 2; i++) {
440                err = rtl8366_smi_read_reg(smi,
441                                           RTL8366S_VLAN_TABLE_READ_BASE + i,
442                                           &data[i]);
443                if (err)
444                        return err;
445        }
446
447        vlan4k->vid = vid;
448        vlan4k->untag = (data[1] >> RTL8366S_VLAN_UNTAG_SHIFT) &
449                        RTL8366S_VLAN_UNTAG_MASK;
450        vlan4k->member = data[1] & RTL8366S_VLAN_MEMBER_MASK;
451        vlan4k->fid = (data[1] >> RTL8366S_VLAN_FID_SHIFT) &
452                        RTL8366S_VLAN_FID_MASK;
453
454        return 0;
455}
456
457static int rtl8366s_set_vlan_4k(struct rtl8366_smi *smi,
458                                const struct rtl8366_vlan_4k *vlan4k)
459{
460        u32 data[2];
461        int err;
462        int i;
463
464        if (vlan4k->vid >= RTL8366S_NUM_VIDS ||
465            vlan4k->member > RTL8366S_VLAN_MEMBER_MASK ||
466            vlan4k->untag > RTL8366S_VLAN_UNTAG_MASK ||
467            vlan4k->fid > RTL8366S_FIDMAX)
468                return -EINVAL;
469
470        data[0] = vlan4k->vid & RTL8366S_VLAN_VID_MASK;
471        data[1] = (vlan4k->member & RTL8366S_VLAN_MEMBER_MASK) |
472                  ((vlan4k->untag & RTL8366S_VLAN_UNTAG_MASK) <<
473                        RTL8366S_VLAN_UNTAG_SHIFT) |
474                  ((vlan4k->fid & RTL8366S_VLAN_FID_MASK) <<
475                        RTL8366S_VLAN_FID_SHIFT);
476
477        for (i = 0; i < 2; i++) {
478                err = rtl8366_smi_write_reg(smi,
479                                            RTL8366S_VLAN_TABLE_WRITE_BASE + i,
480                                            data[i]);
481                if (err)
482                        return err;
483        }
484
485        /* write table access control word */
486        err = rtl8366_smi_write_reg(smi, RTL8366S_TABLE_ACCESS_CTRL_REG,
487                                    RTL8366S_TABLE_VLAN_WRITE_CTRL);
488
489        return err;
490}
491
492static int rtl8366s_get_vlan_mc(struct rtl8366_smi *smi, u32 index,
493                                struct rtl8366_vlan_mc *vlanmc)
494{
495        u32 data[2];
496        int err;
497        int i;
498
499        memset(vlanmc, '\0', sizeof(struct rtl8366_vlan_mc));
500
501        if (index >= RTL8366S_NUM_VLANS)
502                return -EINVAL;
503
504        for (i = 0; i < 2; i++) {
505                err = rtl8366_smi_read_reg(smi,
506                                           RTL8366S_VLAN_MC_BASE(index) + i,
507                                           &data[i]);
508                if (err)
509                        return err;
510        }
511
512        vlanmc->vid = data[0] & RTL8366S_VLAN_VID_MASK;
513        vlanmc->priority = (data[0] >> RTL8366S_VLAN_PRIORITY_SHIFT) &
514                           RTL8366S_VLAN_PRIORITY_MASK;
515        vlanmc->untag = (data[1] >> RTL8366S_VLAN_UNTAG_SHIFT) &
516                        RTL8366S_VLAN_UNTAG_MASK;
517        vlanmc->member = data[1] & RTL8366S_VLAN_MEMBER_MASK;
518        vlanmc->fid = (data[1] >> RTL8366S_VLAN_FID_SHIFT) &
519                      RTL8366S_VLAN_FID_MASK;
520
521        return 0;
522}
523
524static int rtl8366s_set_vlan_mc(struct rtl8366_smi *smi, u32 index,
525                                const struct rtl8366_vlan_mc *vlanmc)
526{
527        u32 data[2];
528        int err;
529        int i;
530
531        if (index >= RTL8366S_NUM_VLANS ||
532            vlanmc->vid >= RTL8366S_NUM_VIDS ||
533            vlanmc->priority > RTL8366S_PRIORITYMAX ||
534            vlanmc->member > RTL8366S_VLAN_MEMBER_MASK ||
535            vlanmc->untag > RTL8366S_VLAN_UNTAG_MASK ||
536            vlanmc->fid > RTL8366S_FIDMAX)
537                return -EINVAL;
538
539        data[0] = (vlanmc->vid & RTL8366S_VLAN_VID_MASK) |
540                  ((vlanmc->priority & RTL8366S_VLAN_PRIORITY_MASK) <<
541                        RTL8366S_VLAN_PRIORITY_SHIFT);
542        data[1] = (vlanmc->member & RTL8366S_VLAN_MEMBER_MASK) |
543                  ((vlanmc->untag & RTL8366S_VLAN_UNTAG_MASK) <<
544                        RTL8366S_VLAN_UNTAG_SHIFT) |
545                  ((vlanmc->fid & RTL8366S_VLAN_FID_MASK) <<
546                        RTL8366S_VLAN_FID_SHIFT);
547
548        for (i = 0; i < 2; i++) {
549                err = rtl8366_smi_write_reg(smi,
550                                            RTL8366S_VLAN_MC_BASE(index) + i,
551                                            data[i]);
552                if (err)
553                        return err;
554        }
555
556        return 0;
557}
558
559static int rtl8366s_get_mc_index(struct rtl8366_smi *smi, int port, int *val)
560{
561        u32 data;
562        int err;
563
564        if (port >= RTL8366S_NUM_PORTS)
565                return -EINVAL;
566
567        err = rtl8366_smi_read_reg(smi, RTL8366S_PORT_VLAN_CTRL_REG(port),
568                                   &data);
569        if (err)
570                return err;
571
572        *val = (data >> RTL8366S_PORT_VLAN_CTRL_SHIFT(port)) &
573               RTL8366S_PORT_VLAN_CTRL_MASK;
574
575        return 0;
576}
577
578static int rtl8366s_set_mc_index(struct rtl8366_smi *smi, int port, int index)
579{
580        if (port >= RTL8366S_NUM_PORTS || index >= RTL8366S_NUM_VLANS)
581                return -EINVAL;
582
583        return rtl8366_smi_rmwr(smi, RTL8366S_PORT_VLAN_CTRL_REG(port),
584                                RTL8366S_PORT_VLAN_CTRL_MASK <<
585                                        RTL8366S_PORT_VLAN_CTRL_SHIFT(port),
586                                (index & RTL8366S_PORT_VLAN_CTRL_MASK) <<
587                                        RTL8366S_PORT_VLAN_CTRL_SHIFT(port));
588}
589
590static int rtl8366s_enable_vlan(struct rtl8366_smi *smi, int enable)
591{
592        return rtl8366_smi_rmwr(smi, RTL8366S_SGCR, RTL8366S_SGCR_EN_VLAN,
593                                (enable) ? RTL8366S_SGCR_EN_VLAN : 0);
594}
595
596static int rtl8366s_enable_vlan4k(struct rtl8366_smi *smi, int enable)
597{
598        return rtl8366_smi_rmwr(smi, RTL8366S_VLAN_TB_CTRL_REG,
599                                1, (enable) ? 1 : 0);
600}
601
602static int rtl8366s_is_vlan_valid(struct rtl8366_smi *smi, unsigned vlan)
603{
604        unsigned max = RTL8366S_NUM_VLANS;
605
606        if (smi->vlan4k_enabled)
607                max = RTL8366S_NUM_VIDS - 1;
608
609        if (vlan == 0 || vlan >= max)
610                return 0;
611
612        return 1;
613}
614
615static int rtl8366s_enable_port(struct rtl8366_smi *smi, int port, int enable)
616{
617        return rtl8366_smi_rmwr(smi, RTL8366S_PECR, (1 << port),
618                                (enable) ? 0 : (1 << port));
619}
620
621static int rtl8366s_sw_reset_mibs(struct switch_dev *dev,
622                                  const struct switch_attr *attr,
623                                  struct switch_val *val)
624{
625        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
626
627        return rtl8366_smi_rmwr(smi, RTL8366S_MIB_CTRL_REG, 0, (1 << 2));
628}
629
630static int rtl8366s_sw_get_blinkrate(struct switch_dev *dev,
631                                     const struct switch_attr *attr,
632                                     struct switch_val *val)
633{
634        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
635        u32 data;
636
637        rtl8366_smi_read_reg(smi, RTL8366S_LED_BLINKRATE_REG, &data);
638
639        val->value.i = (data & (RTL8366S_LED_BLINKRATE_MASK));
640
641        return 0;
642}
643
644static int rtl8366s_sw_set_blinkrate(struct switch_dev *dev,
645                                    const struct switch_attr *attr,
646                                    struct switch_val *val)
647{
648        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
649
650        if (val->value.i >= 6)
651                return -EINVAL;
652
653        return rtl8366_smi_rmwr(smi, RTL8366S_LED_BLINKRATE_REG,
654                                RTL8366S_LED_BLINKRATE_MASK,
655                                val->value.i);
656}
657
658static int rtl8366s_sw_get_max_length(struct switch_dev *dev,
659                                        const struct switch_attr *attr,
660                                        struct switch_val *val)
661{
662        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
663        u32 data;
664
665        rtl8366_smi_read_reg(smi, RTL8366S_SGCR, &data);
666
667        val->value.i = ((data & (RTL8366S_SGCR_MAX_LENGTH_MASK)) >> 4);
668
669        return 0;
670}
671
672static int rtl8366s_sw_set_max_length(struct switch_dev *dev,
673                                        const struct switch_attr *attr,
674                                        struct switch_val *val)
675{
676        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
677        char length_code;
678
679        switch (val->value.i) {
680                case 0:
681                        length_code = RTL8366S_SGCR_MAX_LENGTH_1522;
682                        break;
683                case 1:
684                        length_code = RTL8366S_SGCR_MAX_LENGTH_1536;
685                        break;
686                case 2:
687                        length_code = RTL8366S_SGCR_MAX_LENGTH_1552;
688                        break;
689                case 3:
690                        length_code = RTL8366S_SGCR_MAX_LENGTH_16000;
691                        break;
692                default:
693                        return -EINVAL;
694        }
695
696        return rtl8366_smi_rmwr(smi, RTL8366S_SGCR,
697                        RTL8366S_SGCR_MAX_LENGTH_MASK,
698                        length_code);
699}
700
701static int rtl8366s_sw_get_learning_enable(struct switch_dev *dev,
702                                           const struct switch_attr *attr,
703                                           struct switch_val *val)
704{
705        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
706        u32 data;
707
708        rtl8366_smi_read_reg(smi,RTL8366S_SSCR0, &data);
709        val->value.i = !data;
710
711        return 0;
712}
713
714
715static int rtl8366s_sw_set_learning_enable(struct switch_dev *dev,
716                                           const struct switch_attr *attr,
717                                           struct switch_val *val)
718{
719        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
720        u32 portmask = 0;
721        int err = 0;
722
723        if (!val->value.i)
724                portmask = RTL8366S_PORT_ALL;
725
726        /* set learning for all ports */
727        REG_WR(smi, RTL8366S_SSCR0, portmask);
728
729        /* set auto ageing for all ports */
730        REG_WR(smi, RTL8366S_SSCR1, portmask);
731
732        return 0;
733}
734
735
736static const char *rtl8366s_speed_str(unsigned speed)
737{
738        switch (speed) {
739        case 0:
740                return "10baseT";
741        case 1:
742                return "100baseT";
743        case 2:
744                return "1000baseT";
745        }
746
747        return "unknown";
748}
749
750static int rtl8366s_sw_get_port_link(struct switch_dev *dev,
751                                     const struct switch_attr *attr,
752                                     struct switch_val *val)
753{
754        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
755        u32 len = 0, data = 0;
756
757        if (val->port_vlan >= RTL8366S_NUM_PORTS)
758                return -EINVAL;
759
760        memset(smi->buf, '\0', sizeof(smi->buf));
761        rtl8366_smi_read_reg(smi, RTL8366S_PORT_LINK_STATUS_BASE +
762                             (val->port_vlan / 2), &data);
763
764        if (val->port_vlan % 2)
765                data = data >> 8;
766
767        if (data & RTL8366S_PORT_STATUS_LINK_MASK) {
768                len = snprintf(smi->buf, sizeof(smi->buf),
769                                "port:%d link:up speed:%s %s-duplex %s%s%s",
770                                val->port_vlan,
771                                rtl8366s_speed_str(data &
772                                          RTL8366S_PORT_STATUS_SPEED_MASK),
773                                (data & RTL8366S_PORT_STATUS_DUPLEX_MASK) ?
774                                        "full" : "half",
775                                (data & RTL8366S_PORT_STATUS_TXPAUSE_MASK) ?
776                                        "tx-pause ": "",
777                                (data & RTL8366S_PORT_STATUS_RXPAUSE_MASK) ?
778                                        "rx-pause " : "",
779                                (data & RTL8366S_PORT_STATUS_AN_MASK) ?
780                                        "nway ": "");
781        } else {
782                len = snprintf(smi->buf, sizeof(smi->buf), "port:%d link: down",
783                                val->port_vlan);
784        }
785
786        val->value.s = smi->buf;
787        val->len = len;
788
789        return 0;
790}
791
792static int rtl8366s_sw_set_port_led(struct switch_dev *dev,
793                                    const struct switch_attr *attr,
794                                    struct switch_val *val)
795{
796        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
797        u32 data;
798        u32 mask;
799        u32 reg;
800
801        if (val->port_vlan >= RTL8366S_NUM_PORTS ||
802            (1 << val->port_vlan) == RTL8366S_PORT_UNKNOWN)
803                return -EINVAL;
804
805        if (val->port_vlan == RTL8366S_PORT_NUM_CPU) {
806                reg = RTL8366S_LED_BLINKRATE_REG;
807                mask = 0xF << 4;
808                data = val->value.i << 4;
809        } else {
810                reg = RTL8366S_LED_CTRL_REG;
811                mask = 0xF << (val->port_vlan * 4),
812                data = val->value.i << (val->port_vlan * 4);
813        }
814
815        return rtl8366_smi_rmwr(smi, reg, mask, data);
816}
817
818static int rtl8366s_sw_get_port_led(struct switch_dev *dev,
819                                    const struct switch_attr *attr,
820                                    struct switch_val *val)
821{
822        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
823        u32 data = 0;
824
825        if (val->port_vlan >= RTL8366S_NUM_LEDGROUPS)
826                return -EINVAL;
827
828        rtl8366_smi_read_reg(smi, RTL8366S_LED_CTRL_REG, &data);
829        val->value.i = (data >> (val->port_vlan * 4)) & 0x000F;
830
831        return 0;
832}
833
834static int rtl8366s_sw_reset_port_mibs(struct switch_dev *dev,
835                                       const struct switch_attr *attr,
836                                       struct switch_val *val)
837{
838        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
839
840        if (val->port_vlan >= RTL8366S_NUM_PORTS)
841                return -EINVAL;
842
843
844        return rtl8366_smi_rmwr(smi, RTL8366S_MIB_CTRL_REG,
845                                0, (1 << (val->port_vlan + 3)));
846}
847
848static int rtl8366s_sw_reset_switch(struct switch_dev *dev)
849{
850        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
851        int err;
852
853        err = rtl8366s_reset_chip(smi);
854        if (err)
855                return err;
856
857        err = rtl8366s_hw_init(smi);
858        if (err)
859                return err;
860
861        err = rtl8366_reset_vlan(smi);
862        if (err)
863                return err;
864
865        err = rtl8366_enable_vlan(smi, 1);
866        if (err)
867                return err;
868
869        return rtl8366_enable_all_ports(smi, 1);
870}
871
872static struct switch_attr rtl8366s_globals[] = {
873        {
874                .type = SWITCH_TYPE_INT,
875                .name = "enable_learning",
876                .description = "Enable learning, enable aging",
877                .set = rtl8366s_sw_set_learning_enable,
878                .get = rtl8366s_sw_get_learning_enable,
879                .max = 1,
880        }, {
881                .type = SWITCH_TYPE_INT,
882                .name = "enable_vlan",
883                .description = "Enable VLAN mode",
884                .set = rtl8366_sw_set_vlan_enable,
885                .get = rtl8366_sw_get_vlan_enable,
886                .max = 1,
887                .ofs = 1
888        }, {
889                .type = SWITCH_TYPE_INT,
890                .name = "enable_vlan4k",
891                .description = "Enable VLAN 4K mode",
892                .set = rtl8366_sw_set_vlan_enable,
893                .get = rtl8366_sw_get_vlan_enable,
894                .max = 1,
895                .ofs = 2
896        }, {
897                .type = SWITCH_TYPE_NOVAL,
898                .name = "reset_mibs",
899                .description = "Reset all MIB counters",
900                .set = rtl8366s_sw_reset_mibs,
901        }, {
902                .type = SWITCH_TYPE_INT,
903                .name = "blinkrate",
904                .description = "Get/Set LED blinking rate (0 = 43ms, 1 = 84ms,"
905                " 2 = 120ms, 3 = 170ms, 4 = 340ms, 5 = 670ms)",
906                .set = rtl8366s_sw_set_blinkrate,
907                .get = rtl8366s_sw_get_blinkrate,
908                .max = 5
909        }, {
910                .type = SWITCH_TYPE_INT,
911                .name = "max_length",
912                .description = "Get/Set the maximum length of valid packets"
913                " (0 = 1522, 1 = 1536, 2 = 1552, 3 = 16000 (9216?))",
914                .set = rtl8366s_sw_set_max_length,
915                .get = rtl8366s_sw_get_max_length,
916                .max = 3,
917        },
918};
919
920static struct switch_attr rtl8366s_port[] = {
921        {
922                .type = SWITCH_TYPE_STRING,
923                .name = "link",
924                .description = "Get port link information",
925                .max = 1,
926                .set = NULL,
927                .get = rtl8366s_sw_get_port_link,
928        }, {
929                .type = SWITCH_TYPE_NOVAL,
930                .name = "reset_mib",
931                .description = "Reset single port MIB counters",
932                .set = rtl8366s_sw_reset_port_mibs,
933        }, {
934                .type = SWITCH_TYPE_STRING,
935                .name = "mib",
936                .description = "Get MIB counters for port",
937                .max = 33,
938                .set = NULL,
939                .get = rtl8366_sw_get_port_mib,
940        }, {
941                .type = SWITCH_TYPE_INT,
942                .name = "led",
943                .description = "Get/Set port group (0 - 3) led mode (0 - 15)",
944                .max = 15,
945                .set = rtl8366s_sw_set_port_led,
946                .get = rtl8366s_sw_get_port_led,
947        },
948};
949
950static struct switch_attr rtl8366s_vlan[] = {
951        {
952                .type = SWITCH_TYPE_STRING,
953                .name = "info",
954                .description = "Get vlan information",
955                .max = 1,
956                .set = NULL,
957                .get = rtl8366_sw_get_vlan_info,
958        }, {
959                .type = SWITCH_TYPE_INT,
960                .name = "fid",
961                .description = "Get/Set vlan FID",
962                .max = RTL8366S_FIDMAX,
963                .set = rtl8366_sw_set_vlan_fid,
964                .get = rtl8366_sw_get_vlan_fid,
965        },
966};
967
968static const struct switch_dev_ops rtl8366_ops = {
969        .attr_global = {
970                .attr = rtl8366s_globals,
971                .n_attr = ARRAY_SIZE(rtl8366s_globals),
972        },
973        .attr_port = {
974                .attr = rtl8366s_port,
975                .n_attr = ARRAY_SIZE(rtl8366s_port),
976        },
977        .attr_vlan = {
978                .attr = rtl8366s_vlan,
979                .n_attr = ARRAY_SIZE(rtl8366s_vlan),
980        },
981
982        .get_vlan_ports = rtl8366_sw_get_vlan_ports,
983        .set_vlan_ports = rtl8366_sw_set_vlan_ports,
984        .get_port_pvid = rtl8366_sw_get_port_pvid,
985        .set_port_pvid = rtl8366_sw_set_port_pvid,
986        .reset_switch = rtl8366s_sw_reset_switch,
987};
988
989static int rtl8366s_switch_init(struct rtl8366_smi *smi)
990{
991        struct switch_dev *dev = &smi->sw_dev;
992        int err;
993
994        dev->name = "RTL8366S";
995        dev->cpu_port = RTL8366S_PORT_NUM_CPU;
996        dev->ports = RTL8366S_NUM_PORTS;
997        dev->vlans = RTL8366S_NUM_VIDS;
998        dev->ops = &rtl8366_ops;
999        dev->alias = dev_name(smi->parent);
1000
1001        err = register_switch(dev, NULL);
1002        if (err)
1003                dev_err(smi->parent, "switch registration failed\n");
1004
1005        return err;
1006}
1007
1008static void rtl8366s_switch_cleanup(struct rtl8366_smi *smi)
1009{
1010        unregister_switch(&smi->sw_dev);
1011}
1012
1013static int rtl8366s_mii_read(struct mii_bus *bus, int addr, int reg)
1014{
1015        struct rtl8366_smi *smi = bus->priv;
1016        u32 val = 0;
1017        int err;
1018
1019        err = rtl8366s_read_phy_reg(smi, addr, 0, reg, &val);
1020        if (err)
1021                return 0xffff;
1022
1023        return val;
1024}
1025
1026static int rtl8366s_mii_write(struct mii_bus *bus, int addr, int reg, u16 val)
1027{
1028        struct rtl8366_smi *smi = bus->priv;
1029        u32 t;
1030        int err;
1031
1032        err = rtl8366s_write_phy_reg(smi, addr, 0, reg, val);
1033        /* flush write */
1034        (void) rtl8366s_read_phy_reg(smi, addr, 0, reg, &t);
1035
1036        return err;
1037}
1038
1039static int rtl8366s_setup(struct rtl8366_smi *smi)
1040{
1041        int ret;
1042
1043        ret = rtl8366s_reset_chip(smi);
1044        if (ret)
1045                return ret;
1046
1047        ret = rtl8366s_hw_init(smi);
1048        return ret;
1049}
1050
1051static int rtl8366s_detect(struct rtl8366_smi *smi)
1052{
1053        u32 chip_id = 0;
1054        u32 chip_ver = 0;
1055        int ret;
1056
1057        ret = rtl8366_smi_read_reg(smi, RTL8366S_CHIP_ID_REG, &chip_id);
1058        if (ret) {
1059                dev_err(smi->parent, "unable to read chip id\n");
1060                return ret;
1061        }
1062
1063        switch (chip_id) {
1064        case RTL8366S_CHIP_ID_8366:
1065                break;
1066        default:
1067                dev_err(smi->parent, "unknown chip id (%04x)\n", chip_id);
1068                return -ENODEV;
1069        }
1070
1071        ret = rtl8366_smi_read_reg(smi, RTL8366S_CHIP_VERSION_CTRL_REG,
1072                                   &chip_ver);
1073        if (ret) {
1074                dev_err(smi->parent, "unable to read chip version\n");
1075                return ret;
1076        }
1077
1078        dev_info(smi->parent, "RTL%04x ver. %u chip found\n",
1079                 chip_id, chip_ver & RTL8366S_CHIP_VERSION_MASK);
1080
1081        return 0;
1082}
1083
1084static struct rtl8366_smi_ops rtl8366s_smi_ops = {
1085        .detect         = rtl8366s_detect,
1086        .setup          = rtl8366s_setup,
1087
1088        .mii_read       = rtl8366s_mii_read,
1089        .mii_write      = rtl8366s_mii_write,
1090
1091        .get_vlan_mc    = rtl8366s_get_vlan_mc,
1092        .set_vlan_mc    = rtl8366s_set_vlan_mc,
1093        .get_vlan_4k    = rtl8366s_get_vlan_4k,
1094        .set_vlan_4k    = rtl8366s_set_vlan_4k,
1095        .get_mc_index   = rtl8366s_get_mc_index,
1096        .set_mc_index   = rtl8366s_set_mc_index,
1097        .get_mib_counter = rtl8366_get_mib_counter,
1098        .is_vlan_valid  = rtl8366s_is_vlan_valid,
1099        .enable_vlan    = rtl8366s_enable_vlan,
1100        .enable_vlan4k  = rtl8366s_enable_vlan4k,
1101        .enable_port    = rtl8366s_enable_port,
1102};
1103
1104static int __devinit rtl8366s_probe(struct platform_device *pdev)
1105{
1106        static int rtl8366_smi_version_printed;
1107        struct rtl8366_platform_data *pdata;
1108        struct rtl8366_smi *smi;
1109        int err;
1110
1111        if (!rtl8366_smi_version_printed++)
1112                printk(KERN_NOTICE RTL8366S_DRIVER_DESC
1113                       " version " RTL8366S_DRIVER_VER"\n");
1114
1115        pdata = pdev->dev.platform_data;
1116        if (!pdata) {
1117                dev_err(&pdev->dev, "no platform data specified\n");
1118                err = -EINVAL;
1119                goto err_out;
1120        }
1121
1122        smi = rtl8366_smi_alloc(&pdev->dev);
1123        if (!smi) {
1124                err = -ENOMEM;
1125                goto err_out;
1126        }
1127
1128        smi->gpio_sda = pdata->gpio_sda;
1129        smi->gpio_sck = pdata->gpio_sck;
1130        smi->ops = &rtl8366s_smi_ops;
1131        smi->cpu_port = RTL8366S_PORT_NUM_CPU;
1132        smi->num_ports = RTL8366S_NUM_PORTS;
1133        smi->num_vlan_mc = RTL8366S_NUM_VLANS;
1134        smi->mib_counters = rtl8366s_mib_counters;
1135        smi->num_mib_counters = ARRAY_SIZE(rtl8366s_mib_counters);
1136
1137        err = rtl8366_smi_init(smi);
1138        if (err)
1139                goto err_free_smi;
1140
1141        platform_set_drvdata(pdev, smi);
1142
1143        err = rtl8366s_switch_init(smi);
1144        if (err)
1145                goto err_clear_drvdata;
1146
1147        return 0;
1148
1149 err_clear_drvdata:
1150        platform_set_drvdata(pdev, NULL);
1151        rtl8366_smi_cleanup(smi);
1152 err_free_smi:
1153        kfree(smi);
1154 err_out:
1155        return err;
1156}
1157
1158static int __devexit rtl8366s_remove(struct platform_device *pdev)
1159{
1160        struct rtl8366_smi *smi = platform_get_drvdata(pdev);
1161
1162        if (smi) {
1163                rtl8366s_switch_cleanup(smi);
1164                platform_set_drvdata(pdev, NULL);
1165                rtl8366_smi_cleanup(smi);
1166                kfree(smi);
1167        }
1168
1169        return 0;
1170}
1171
1172static struct platform_driver rtl8366s_driver = {
1173        .driver = {
1174                .name           = RTL8366S_DRIVER_NAME,
1175                .owner          = THIS_MODULE,
1176        },
1177        .probe          = rtl8366s_probe,
1178        .remove         = __devexit_p(rtl8366s_remove),
1179};
1180
1181static int __init rtl8366s_module_init(void)
1182{
1183        return platform_driver_register(&rtl8366s_driver);
1184}
1185module_init(rtl8366s_module_init);
1186
1187static void __exit rtl8366s_module_exit(void)
1188{
1189        platform_driver_unregister(&rtl8366s_driver);
1190}
1191module_exit(rtl8366s_module_exit);
1192
1193MODULE_DESCRIPTION(RTL8366S_DRIVER_DESC);
1194MODULE_VERSION(RTL8366S_DRIVER_VER);
1195MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
1196MODULE_AUTHOR("Antti SeppÀlÀ <a.seppala@gmail.com>");
1197MODULE_LICENSE("GPL v2");
1198MODULE_ALIAS("platform:" RTL8366S_DRIVER_NAME);
Note: See TracBrowser for help on using the repository browser.