Root/package/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c

1/*
2 * (C) Copyright 2010
3 * Michael Kurz <michi.kurz@googlemail.com>.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24
25#include <common.h>
26#include <net.h>
27#include <netdev.h>
28#include <miiphy.h>
29#include MII_GPIOINCLUDE
30
31#include "rtl8366.h"
32
33#ifdef DEBUG_RTL8366
34    #define DBG(fmt,args...) printf (fmt ,##args)
35#else
36    #define DBG(fmt,args...)
37#endif
38
39
40//-------------------------------------------------------------------
41// Soft SMI functions
42//-------------------------------------------------------------------
43
44#define DELAY 2
45
46static void smi_init(void)
47{
48    MII_SDAINPUT;
49    MII_SCKINPUT;
50
51    MII_SETSDA(1);
52    MII_SETSCK(1);
53
54    udelay(20);
55}
56
57static void smi_start(void)
58{
59/*
60 * rtl8366 chip needs a extra clock with
61 * SDA high before start condition
62 */
63
64    /* set gpio pins output */
65    MII_SDAOUTPUT;
66    MII_SCKOUTPUT;
67    udelay(DELAY);
68
69    /* set initial state: SCK:0, SDA:1 */
70    MII_SETSCK(0);
71    MII_SETSDA(1);
72    udelay(DELAY);
73
74    /* toggle clock */
75    MII_SETSCK(1);
76    udelay(DELAY);
77    MII_SETSCK(0);
78    udelay(DELAY);
79
80    /* start condition */
81    MII_SETSCK(1);
82    udelay(DELAY);
83    MII_SETSDA(0);
84    udelay(DELAY);
85    MII_SETSCK(0);
86    udelay(DELAY);
87    MII_SETSDA(1);
88}
89
90static void smi_stop(void)
91{
92/*
93 * rtl8366 chip needs a extra clock with
94 * SDA high after stop condition
95 */
96
97    /* stop condition */
98    udelay(DELAY);
99    MII_SETSDA(0);
100    MII_SETSCK(1);
101    udelay(DELAY);
102    MII_SETSDA(1);
103    udelay(DELAY);
104    MII_SETSCK(1);
105    udelay(DELAY);
106    MII_SETSCK(0);
107    udelay(DELAY);
108
109    /* toggle clock */
110    MII_SETSCK(1);
111    udelay(DELAY);
112    MII_SETSCK(0);
113    udelay(DELAY);
114    MII_SETSCK(1);
115
116    /* set gpio pins input */
117    MII_SDAINPUT;
118    MII_SCKINPUT;
119}
120
121static void smi_writeBits(uint32_t data, uint8_t length)
122{
123    uint8_t test;
124
125    for( ; length > 0; length--) {
126        udelay(DELAY);
127
128        /* output data */
129        test = (((data & (1 << (length - 1))) != 0) ? 1 : 0);
130        MII_SETSDA(test);
131        udelay(DELAY);
132
133        /* toogle clock */
134        MII_SETSCK(1);
135        udelay(DELAY);
136        MII_SETSCK(0);
137    }
138}
139
140static uint32_t smi_readBits(uint8_t length)
141{
142    uint32_t ret;
143
144    MII_SDAINPUT;
145
146    for(ret = 0 ; length > 0; length--) {
147        udelay(DELAY);
148
149        ret <<= 1;
150
151        /* toogle clock */
152        MII_SETSCK(1);
153        udelay(DELAY);
154        ret |= MII_GETSDA;
155        MII_SETSCK(0);
156    }
157
158    MII_SDAOUTPUT;
159
160    return ret;
161}
162
163static int smi_waitAck(void)
164{
165    uint32_t retry = 0;
166
167    while (smi_readBits(1)) {
168        if (retry++ == 5)
169            return -1;
170    }
171
172    return 0;
173
174}
175
176static int smi_read(uint32_t reg, uint32_t *data)
177{
178    uint32_t rawData;
179
180    /* send start condition */
181    smi_start();
182    /* send CTRL1 code: 0b1010*/
183    smi_writeBits(0x0a, 4);
184    /* send CTRL2 code: 0b100 */
185    smi_writeBits(0x04, 3);
186    /* send READ command */
187    smi_writeBits(0x01, 1);
188
189    /* wait for ACK */
190    if (smi_waitAck())
191        return -1;
192
193    /* send address low */
194    smi_writeBits(reg & 0xFF, 8);
195    /* wait for ACK */
196    if (smi_waitAck())
197        return -1;
198    /* send address high */
199    smi_writeBits((reg & 0xFF00) >> 8, 8);
200    /* wait for ACK */
201    if (smi_waitAck())
202        return -1;
203
204    /* read data low */
205    rawData = (smi_readBits(8) & 0xFF);
206    /* send ACK */
207    smi_writeBits(0, 1);
208    /* read data high */
209    rawData |= (smi_readBits(8) & 0xFF) << 8;
210    /* send NACK */
211    smi_writeBits(1, 1);
212
213    /* send stop condition */
214    smi_stop();
215
216    if (data)
217        *data = rawData;
218
219    return 0;
220}
221
222static int smi_write(uint32_t reg, uint32_t data)
223{
224    /* send start condition */
225    smi_start();
226    /* send CTRL1 code: 0b1010*/
227    smi_writeBits(0x0a, 4);
228    /* send CTRL2 code: 0b100 */
229    smi_writeBits(0x04, 3);
230    /* send WRITE command */
231    smi_writeBits(0x00, 1);
232
233    /* wait for ACK */
234    if (smi_waitAck())
235        return -1;
236
237    /* send address low */
238    smi_writeBits(reg & 0xFF, 8);
239    /* wait for ACK */
240    if (smi_waitAck())
241        return -1;
242    /* send address high */
243    smi_writeBits((reg & 0xFF00) >> 8, 8);
244    /* wait for ACK */
245    if (smi_waitAck())
246        return -1;
247
248    /* send data low */
249    smi_writeBits(data & 0xFF, 8);
250    /* wait for ACK */
251    if (smi_waitAck())
252        return -1;
253    /* send data high */
254    smi_writeBits((data & 0xFF00) >> 8, 8);
255    /* wait for ACK */
256    if (smi_waitAck())
257        return -1;
258
259    /* send stop condition */
260    smi_stop();
261
262    return 0;
263}
264
265
266//-------------------------------------------------------------------
267// Switch register read / write functions
268//-------------------------------------------------------------------
269static int rtl8366_readRegister(uint32_t reg, uint16_t *data)
270{
271    uint32_t regData;
272
273    DBG("rtl8366: read register=%#04x, data=", reg);
274
275    if (smi_read(reg, &regData)) {
276        printf("\nrtl8366 smi read failed!\n");
277        return -1;
278    }
279
280    if (data)
281        *data = regData;
282
283    DBG("%#04x\n", regData);
284
285    return 0;
286}
287
288static int rtl8366_writeRegister(uint32_t reg, uint16_t data)
289{
290    DBG("rtl8366: write register=%#04x, data=%#04x\n", reg, data);
291
292    if (smi_write(reg, data)) {
293        printf("rtl8366 smi write failed!\n");
294        return -1;
295    }
296
297    return 0;
298}
299
300static int rtl8366_setRegisterBit(uint32_t reg, uint32_t bitNum, uint32_t value)
301{
302    uint16_t regData;
303
304    if (bitNum >= 16)
305        return -1;
306
307    if (rtl8366_readRegister(reg, &regData))
308        return -1;
309
310    if (value)
311        regData |= (1 << bitNum);
312    else
313        regData &= ~(1 << bitNum);
314
315    if (rtl8366_writeRegister(reg, regData))
316        return -1;
317
318    return 0;
319}
320
321//-------------------------------------------------------------------
322// MII PHY read / write functions
323//-------------------------------------------------------------------
324static int rtl8366_getPhyReg(uint32_t phyNum, uint32_t reg, uint16_t *data)
325{
326    uint16_t phyAddr, regData;
327
328    if (phyNum > RTL8366S_PHY_NO_MAX) {
329        printf("rtl8366s: invalid phy number!\n");
330        return -1;
331    }
332
333    if (phyNum > RTL8366S_PHY_ADDR_MAX) {
334        printf("rtl8366s: invalid phy register number!\n");
335        return -1;
336    }
337
338    if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
339                           RTL8366S_PHY_CTRL_READ))
340        return -1;
341
342    phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
343                     | (reg & RTL8366S_PHY_REG_MASK);
344    if (rtl8366_writeRegister(phyAddr, 0))
345        return -1;
346
347    if (rtl8366_readRegister(RTL8366S_PHY_ACCESS_DATA_REG, &regData))
348        return -1;
349
350    if (data)
351        *data = regData;
352
353    return 0;
354}
355
356static int rtl8366_setPhyReg(uint32_t phyNum, uint32_t reg, uint16_t data)
357{
358    uint16_t phyAddr;
359
360    if (phyNum > RTL8366S_PHY_NO_MAX) {
361        printf("rtl8366s: invalid phy number!\n");
362        return -1;
363    }
364
365    if (phyNum > RTL8366S_PHY_ADDR_MAX) {
366        printf("rtl8366s: invalid phy register number!\n");
367        return -1;
368    }
369
370    if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
371                           RTL8366S_PHY_CTRL_WRITE))
372        return -1;
373
374    phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
375                     | (reg & RTL8366S_PHY_REG_MASK);
376    if (rtl8366_writeRegister(phyAddr, data))
377        return -1;
378
379    return 0;
380}
381
382static int rtl8366_miiread(char *devname, uchar phy_adr, uchar reg, ushort *data)
383{
384    uint16_t regData;
385
386    DBG("rtl8366_miiread: devname=%s, addr=%#02x, reg=%#02x\n",
387          devname, phy_adr, reg);
388
389    if (strcmp(devname, RTL8366_DEVNAME) != 0)
390        return -1;
391
392    if (rtl8366_getPhyReg(phy_adr, reg, &regData)) {
393        printf("rtl8366_miiread: write failed!\n");
394        return -1;
395    }
396
397    if (data)
398        *data = regData;
399
400    return 0;
401}
402
403static int rtl8366_miiwrite(char *devname, uchar phy_adr, uchar reg, ushort data)
404{
405    DBG("rtl8366_miiwrite: devname=%s, addr=%#02x, reg=%#02x, data=%#04x\n",
406          devname, phy_adr, reg, data);
407
408    if (strcmp(devname, RTL8366_DEVNAME) != 0)
409        return -1;
410
411    if (rtl8366_setPhyReg(phy_adr, reg, data)) {
412        printf("rtl8366_miiwrite: write failed!\n");
413        return -1;
414    }
415
416    return 0;
417}
418
419int rtl8366_mii_register(bd_t *bis)
420{
421    miiphy_register(strdup(RTL8366_DEVNAME), rtl8366_miiread,
422            rtl8366_miiwrite);
423
424    return 0;
425}
426
427
428//-------------------------------------------------------------------
429// Switch management functions
430//-------------------------------------------------------------------
431
432int rtl8366s_setGreenFeature(uint32_t tx, uint32_t rx)
433{
434    if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
435                               RTL8366S_GREEN_FEATURE_TX_BIT, tx))
436        return -1;
437
438    if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
439                               RTL8366S_GREEN_FEATURE_RX_BIT, rx))
440        return -1;
441
442    return 0;
443}
444
445int rtl8366s_setPowerSaving(uint32_t phyNum, uint32_t enabled)
446{
447    uint16_t regData;
448
449    if (phyNum > RTL8366S_PHY_NO_MAX)
450        return -1;
451
452    if (rtl8366_getPhyReg(phyNum, 12, &regData))
453        return -1;
454
455    if (enabled)
456        regData |= (1 << 12);
457    else
458        regData &= ~(1 << 12);
459
460    if (rtl8366_setPhyReg(phyNum, 12, regData))
461        return -1;
462
463    return 0;
464}
465
466int rtl8366s_setGreenEthernet(uint32_t greenFeature, uint32_t powerSaving)
467{
468    uint32_t phyNum, i;
469    uint16_t regData;
470
471    const uint16_t greenSettings[][2] =
472    {
473        {0xBE5B,0x3500},
474        {0xBE5C,0xB975},
475        {0xBE5D,0xB9B9},
476        {0xBE77,0xA500},
477        {0xBE78,0x5A78},
478        {0xBE79,0x6478}
479    };
480
481    if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, &regData))
482        return -1;
483
484    switch (regData)
485    {
486        case 0x0000:
487            for (i = 0; i < 6; i++) {
488                if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
489                    return -1;
490                if (rtl8366_writeRegister(greenSettings[i][0], greenSettings[i][1]))
491                    return -1;
492            }
493            break;
494
495        case RTL8366S_MODEL_8366SR:
496            if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
497                return -1;
498            if (rtl8366_writeRegister(greenSettings[0][0], greenSettings[0][1]))
499                return -1;
500            break;
501
502        default:
503            printf("rtl8366s_initChip: unsupported chip found!\n");
504            return -1;
505    }
506
507    if (rtl8366s_setGreenFeature(greenFeature, powerSaving))
508        return -1;
509
510    for (phyNum = 0; phyNum <= RTL8366S_PHY_NO_MAX; phyNum++) {
511        if (rtl8366s_setPowerSaving(phyNum, powerSaving))
512            return -1;
513    }
514
515    return 0;
516}
517
518int rtl8366s_setCPUPortMask(uint8_t port, uint32_t enabled)
519{
520    if(port >= 6){
521        printf("rtl8366s_setCPUPortMask: invalid port number\n");
522        return -1;
523    }
524
525    return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG, port, enabled);
526}
527
528int rtl8366s_setCPUDisableInsTag(uint32_t enable)
529{
530    return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
531        RTL8366S_CPU_INSTAG_BIT, enable);
532}
533
534int rtl8366s_setCPUDropUnda(uint32_t enable)
535{
536    return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
537        RTL8366S_CPU_DRP_BIT, enable);
538}
539
540int rtl8366s_setCPUPort(uint8_t port, uint32_t noTag, uint32_t dropUnda)
541{
542    uint32_t i;
543
544    if(port >= 6){
545        printf("rtl8366s_setCPUPort: invalid port number\n");
546        return -1;
547    }
548
549    /* reset register */
550    for(i = 0; i < 6; i++)
551    {
552        if(rtl8366s_setCPUPortMask(i, 0)){
553            printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
554            return -1;
555        }
556    }
557
558    if(rtl8366s_setCPUPortMask(port, 1)){
559        printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
560        return -1;
561    }
562
563    if(rtl8366s_setCPUDisableInsTag(noTag)){
564        printf("rtl8366s_setCPUPort: rtl8366s_setCPUDisableInsTag fail\n");
565        return -1;
566    }
567
568    if(rtl8366s_setCPUDropUnda(dropUnda)){
569        printf("rtl8366s_setCPUPort: rtl8366s_setCPUDropUnda fail\n");
570        return -1;
571    }
572
573    return 0;
574}
575
576int rtl8366s_setLedConfig(uint32_t ledNum, uint8_t config)
577{
578    uint16_t regData;
579
580    if(ledNum >= RTL8366S_LED_GROUP_MAX) {
581        DBG("rtl8366s_setLedConfig: invalid led group\n");
582        return -1;
583    }
584
585    if(config > RTL8366S_LEDCONF_LEDFORCE) {
586        DBG("rtl8366s_setLedConfig: invalid led config\n");
587        return -1;
588    }
589
590    if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, &regData)) {
591        printf("rtl8366s_setLedConfig: failed to get led register!\n");
592        return -1;
593    }
594
595    regData &= ~(0xF << (ledNum * 4));
596    regData |= config << (ledNum * 4);
597
598    if (rtl8366_writeRegister(RTL8366S_LED_INDICATED_CONF_REG, regData)) {
599        printf("rtl8366s_setLedConfig: failed to set led register!\n");
600        return -1;
601    }
602
603    return 0;
604}
605
606int rtl8366s_getLedConfig(uint32_t ledNum, uint8_t *config)
607{
608    uint16_t regData;
609
610    if(ledNum >= RTL8366S_LED_GROUP_MAX) {
611        DBG("rtl8366s_getLedConfig: invalid led group\n");
612        return -1;
613    }
614
615    if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, &regData)) {
616        printf("rtl8366s_getLedConfig: failed to get led register!\n");
617        return -1;
618    }
619
620    if (config)
621        *config = (regData >> (ledNum * 4)) & 0xF;
622
623    return 0;
624}
625
626int rtl8366s_setLedForceValue(uint32_t group0, uint32_t group1,
627                              uint32_t group2, uint32_t group3)
628{
629    uint16_t regData;
630
631    regData = (group0 & 0x3F) | ((group1 & 0x3F) << 6);
632    if (rtl8366_writeRegister(RTL8366S_LED_0_1_FORCE_REG, regData)) {
633        printf("rtl8366s_setLedForceValue: failed to set led register!\n");
634        return -1;
635    }
636
637    regData = (group2 & 0x3F) | ((group3 & 0x3F) << 6);
638    if (rtl8366_writeRegister(RTL8366S_LED_2_3_FORCE_REG, regData)) {
639        printf("rtl8366s_setLedForceValue: failed to set led register!\n");
640        return -1;
641    }
642
643    return 0;
644}
645
646int rtl8366s_initChip(void)
647{
648    uint32_t ledGroup, i = 0;
649    uint16_t regData;
650    uint8_t ledData[RTL8366S_LED_GROUP_MAX];
651    const uint16_t (*chipData)[2];
652
653    const uint16_t chipB[][2] =
654    {
655        {0x0000, 0x0038},{0x8100, 0x1B37},{0xBE2E, 0x7B9F},{0xBE2B, 0xA4C8},
656        {0xBE74, 0xAD14},{0xBE2C, 0xDC00},{0xBE69, 0xD20F},{0xBE3B, 0xB414},
657        {0xBE24, 0x0000},{0xBE23, 0x00A1},{0xBE22, 0x0008},{0xBE21, 0x0120},
658        {0xBE20, 0x1000},{0xBE24, 0x0800},{0xBE24, 0x0000},{0xBE24, 0xF000},
659        {0xBE23, 0xDF01},{0xBE22, 0xDF20},{0xBE21, 0x101A},{0xBE20, 0xA0FF},
660        {0xBE24, 0xF800},{0xBE24, 0xF000},{0x0242, 0x02BF},{0x0245, 0x02BF},
661        {0x0248, 0x02BF},{0x024B, 0x02BF},{0x024E, 0x02BF},{0x0251, 0x02BF},
662        {0x0230, 0x0A32},{0x0233, 0x0A32},{0x0236, 0x0A32},{0x0239, 0x0A32},
663        {0x023C, 0x0A32},{0x023F, 0x0A32},{0x0254, 0x0A3F},{0x0255, 0x0064},
664        {0x0256, 0x0A3F},{0x0257, 0x0064},{0x0258, 0x0A3F},{0x0259, 0x0064},
665        {0x025A, 0x0A3F},{0x025B, 0x0064},{0x025C, 0x0A3F},{0x025D, 0x0064},
666        {0x025E, 0x0A3F},{0x025F, 0x0064},{0x0260, 0x0178},{0x0261, 0x01F4},
667        {0x0262, 0x0320},{0x0263, 0x0014},{0x021D, 0x9249},{0x021E, 0x0000},
668        {0x0100, 0x0004},{0xBE4A, 0xA0B4},{0xBE40, 0x9C00},{0xBE41, 0x501D},
669        {0xBE48, 0x3602},{0xBE47, 0x8051},{0xBE4C, 0x6465},{0x8000, 0x1F00},
670        {0x8001, 0x000C},{0x8008, 0x0000},{0x8007, 0x0000},{0x800C, 0x00A5},
671        {0x8101, 0x02BC},{0xBE53, 0x0005},{0x8E45, 0xAFE8},{0x8013, 0x0005},
672        {0xBE4B, 0x6700},{0x800B, 0x7000},{0xBE09, 0x0E00},
673        {0xFFFF, 0xABCD}
674    };
675
676    const uint16_t chipDefault[][2] =
677    {
678        {0x0242, 0x02BF},{0x0245, 0x02BF},{0x0248, 0x02BF},{0x024B, 0x02BF},
679        {0x024E, 0x02BF},{0x0251, 0x02BF},
680        {0x0254, 0x0A3F},{0x0256, 0x0A3F},{0x0258, 0x0A3F},{0x025A, 0x0A3F},
681        {0x025C, 0x0A3F},{0x025E, 0x0A3F},
682        {0x0263, 0x007C},{0x0100, 0x0004},
683        {0xBE5B, 0x3500},{0x800E, 0x200F},{0xBE1D, 0x0F00},{0x8001, 0x5011},
684        {0x800A, 0xA2F4},{0x800B, 0x17A3},{0xBE4B, 0x17A3},{0xBE41, 0x5011},
685        {0xBE17, 0x2100},{0x8000, 0x8304},{0xBE40, 0x8304},{0xBE4A, 0xA2F4},
686        {0x800C, 0xA8D5},{0x8014, 0x5500},{0x8015, 0x0004},{0xBE4C, 0xA8D5},
687        {0xBE59, 0x0008},{0xBE09, 0x0E00},{0xBE36, 0x1036},{0xBE37, 0x1036},
688        {0x800D, 0x00FF},{0xBE4D, 0x00FF},
689        {0xFFFF, 0xABCD}
690    };
691
692    DBG("rtl8366s_initChip\n");
693
694    /* save current led config and set to led force */
695    for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
696        if (rtl8366s_getLedConfig(ledGroup, &ledData[ledGroup]))
697            return -1;
698
699        if (rtl8366s_setLedConfig(ledGroup, RTL8366S_LEDCONF_LEDFORCE))
700            return -1;
701    }
702
703    if (rtl8366s_setLedForceValue(0,0,0,0))
704        return -1;
705
706    if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, &regData))
707        return -1;
708
709    switch (regData)
710    {
711        case 0x0000:
712            chipData = chipB;
713            break;
714
715        case RTL8366S_MODEL_8366SR:
716            chipData = chipDefault;
717            break;
718
719        default:
720            printf("rtl8366s_initChip: unsupported chip found!\n");
721            return -1;
722    }
723
724    DBG("rtl8366s_initChip: found %x chip\n", regData);
725
726    while ((chipData[i][0] != 0xFFFF) && (chipData[i][1] != 0xABCD)) {
727
728        /* phy settings*/
729        if ((chipData[i][0] & 0xBE00) == 0xBE00) {
730            if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
731                                      RTL8366S_PHY_CTRL_WRITE))
732                return -1;
733        }
734
735        if (rtl8366_writeRegister(chipData[i][0], chipData[i][1]))
736            return -1;
737
738        i++;
739    }
740
741    /* chip needs some time */
742    udelay(100 * 1000);
743
744    /* restore led config */
745    for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
746        if (rtl8366s_setLedConfig(ledGroup, ledData[ledGroup]))
747            return -1;
748    }
749
750    return 0;
751}
752
753int rtl8366s_initialize(void)
754{
755    uint16_t regData;
756
757    DBG("rtl8366s_initialize: start setup\n");
758
759    smi_init();
760
761    rtl8366_readRegister(RTL8366S_CHIP_ID_REG, &regData);
762    DBG("Realtek 8366SR switch ID %#04x\n", regData);
763
764    if (regData != 0x8366) {
765        printf("rtl8366s_initialize: found unsupported switch\n");
766        return -1;
767    }
768
769    if (rtl8366s_initChip()) {
770        printf("rtl8366s_initialize: init chip failed\n");
771        return -1;
772    }
773
774    if (rtl8366s_setGreenEthernet(1, 1)) {
775       printf("rtl8366s_initialize: set green ethernet failed\n");
776       return -1;
777   }
778
779       /* Set port 5 noTag and don't dropUnda */
780    if (rtl8366s_setCPUPort(5, 1, 0)) {
781        printf("rtl8366s_initialize: set CPU port failed\n");
782        return -1;
783    }
784
785    return 0;
786}
787

Archive Download this file



interactive