e3c5316543b98acddf04dc9557eed0d4e8ce3b7b
[openwrt.git] / 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
46 static 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
57 static 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
90 static 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
121 static 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
140 static 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
163 static 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
176 static 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
222 static 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 //-------------------------------------------------------------------
269 static 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
288 static 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
300 static 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 //-------------------------------------------------------------------
324 static 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
356 static 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
382 static 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
403 static 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
419 int 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
432 int 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
445 int 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
466 int 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
518 int 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
528 int rtl8366s_setCPUDisableInsTag(uint32_t enable)
529 {
530         return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
531                 RTL8366S_CPU_INSTAG_BIT, enable);
532 }
533
534 int rtl8366s_setCPUDropUnda(uint32_t enable)
535 {
536         return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
537                 RTL8366S_CPU_DRP_BIT, enable);
538 }
539
540 int 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
576 int 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
606 int 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
626 int 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
646 int 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
753 int 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 }