[lantiq] prepare Makefile for 3.6
[openwrt.git] / target / linux / lantiq / files / arch / mips / lantiq / svip / switchip_setup.c
1 /******************************************************************************
2      Copyright (c) 2007, Infineon Technologies.  All rights reserved.
3
4                                No Warranty
5    Because the program is licensed free of charge, there is no warranty for
6    the program, to the extent permitted by applicable law.  Except when
7    otherwise stated in writing the copyright holders and/or other parties
8    provide the program "as is" without warranty of any kind, either
9    expressed or implied, including, but not limited to, the implied
10    warranties of merchantability and fitness for a particular purpose. The
11    entire risk as to the quality and performance of the program is with
12    you.  should the program prove defective, you assume the cost of all
13    necessary servicing, repair or correction.
14
15    In no event unless required by applicable law or agreed to in writing
16    will any copyright holder, or any other party who may modify and/or
17    redistribute the program as permitted above, be liable to you for
18    damages, including any general, special, incidental or consequential
19    damages arising out of the use or inability to use the program
20    (including but not limited to loss of data or data being rendered
21    inaccurate or losses sustained by you or third parties or a failure of
22    the program to operate with any other programs), even if such holder or
23    other party has been advised of the possibility of such damages.
24  ******************************************************************************
25    Module      : switchip_setup.c
26    Date        : 2007-11-09
27    Description : Basic setup of embedded ethernet switch "SwitchIP"
28    Remarks: andreas.schmidt@infineon.com
29
30  *****************************************************************************/
31
32 /* TODO: get rid of #ifdef CONFIG_LANTIQ_MACH_EASY336 */
33
34 #include <linux/kernel.h>
35 #include <linux/module.h>
36 #include <linux/version.h>
37 #include <linux/init.h>
38 #include <linux/delay.h>
39 #include <linux/workqueue.h>
40 #include <linux/time.h>
41
42 #include <base_reg.h>
43 #include <es_reg.h>
44 #include <sys1_reg.h>
45 #include <dma_reg.h>
46 #include <lantiq_soc.h>
47
48 static struct svip_reg_sys1 *const sys1 = (struct svip_reg_sys1 *)LTQ_SYS1_BASE;
49 static struct svip_reg_es *const es = (struct svip_reg_es *)LTQ_ES_BASE;
50
51 /* PHY Organizationally Unique Identifier (OUI) */
52 #define PHY_OUI_PMC           0x00E004
53 #define PHY_OUI_VITESSE       0x008083
54 #define PHY_OUI_DEFAULT       0xFFFFFF
55
56 unsigned short switchip_phy_read(unsigned int phyaddr, unsigned int regaddr);
57 void switchip_phy_write(unsigned int phyaddr, unsigned int regaddr,
58                         unsigned short data);
59
60 static int phy_address[2] = {0, 1};
61 static u32 phy_oui;
62 static void switchip_mdio_poll_init(void);
63 static void _switchip_mdio_poll(struct work_struct *work);
64
65 /* struct workqueue_struct mdio_poll_task; */
66 static struct workqueue_struct *mdio_poll_workqueue;
67 DECLARE_DELAYED_WORK(mdio_poll_work, _switchip_mdio_poll);
68 static int old_link_status[2] = {-1, -1};
69
70 /**
71  * Autonegotiation check.
72  * This funtion checks for link changes. If a link change has occured it will
73  * update certain switch registers.
74  */
75 static void _switchip_check_phy_status(int port)
76 {
77         int new_link_status;
78         unsigned short reg1;
79
80         reg1 = switchip_phy_read(phy_address[port], 1);
81         if ((reg1 == 0xFFFF) || (reg1 == 0x0000))
82                 return; /* no PHY connected */
83
84         new_link_status = reg1 & 4;
85         if (old_link_status[port] ^ new_link_status) {
86                 /* link status change */
87                 if (!new_link_status) {
88                         if (port == 0)
89                                 es_w32_mask(LTQ_ES_P0_CTL_REG_FLP, 0, p0_ctl);
90                         else
91                                 es_w32_mask(LTQ_ES_P0_CTL_REG_FLP, 0, p1_ctl);
92
93                         /* read again; link bit is latched low! */
94                         reg1 = switchip_phy_read(phy_address[port], 1);
95                         new_link_status = reg1 & 4;
96                 }
97
98                 if (new_link_status) {
99                         unsigned short reg0, reg4, reg5, reg9, reg10;
100                         int phy_pause, phy_speed, phy_duplex;
101                         int aneg_enable, aneg_cmpt;
102
103                         reg0 = switchip_phy_read(phy_address[port], 0);
104                         reg4 = switchip_phy_read(phy_address[port], 4);
105                         aneg_enable = reg0 & 0x1000;
106                         aneg_cmpt = reg1 & 0x20;
107
108                         if (aneg_enable && aneg_cmpt) {
109                                 reg5 = switchip_phy_read(phy_address[port], 5);
110                                 switch (phy_oui) {
111 #ifdef CONFIG_LANTIQ_MACH_EASY336
112                                 case PHY_OUI_PMC:
113                                         /* PMC Sierra supports 1Gigabit FD,
114                                          * only. On successful
115                                          * auto-negotiation, we are sure this
116                                          * is what the LP can. */
117                                         phy_pause = ((reg4 & reg5) & 0x0080) >> 7;
118                                         phy_speed = 2;
119                                         phy_duplex = 1;
120                                         break;
121 #endif
122                                 case PHY_OUI_VITESSE:
123                                 case PHY_OUI_DEFAULT:
124                                         reg9 = switchip_phy_read(phy_address[port], 9);
125                                         reg10 = switchip_phy_read(phy_address[port], 10);
126
127                                         /* Check if advertise and partner
128                                          * agree on pause */
129                                         phy_pause = ((reg4 & reg5) & 0x0400) >> 10;
130
131                                         /* Find the best mode both partners
132                                          * support
133                                          * Priority: 1GB-FD, 1GB-HD, 100MB-FD,
134                                          * 100MB-HD, 10MB-FD, 10MB-HD */
135                                         phy_speed = ((((reg9<<2) & reg10)
136                                                       & 0x0c00) >> 6) |
137                                                 (((reg4 & reg5) & 0x01e0) >> 5);
138
139                                         if (phy_speed >= 0x0020) {
140                                                 phy_speed = 2;
141                                                 phy_duplex = 1;
142                                         } else if (phy_speed >= 0x0010) {
143                                                 phy_speed = 2;
144                                                 phy_duplex = 0;
145                                         } else if (phy_speed >= 0x0008) {
146                                                 phy_speed = 1;
147                                                 phy_duplex = 1;
148                                         } else if (phy_speed >= 0x0004) {
149                                                 phy_speed = 1;
150                                                 phy_duplex = 0;
151                                         } else if (phy_speed >= 0x0002) {
152                                                 phy_speed = 0;
153                                                 phy_duplex = 1;
154                                         } else {
155                                                 phy_speed = 0;
156                                                 phy_duplex = 0;
157                                         }
158                                         break;
159                                 default:
160                                         phy_pause = (reg4 & 0x0400) >> 10;
161                                         phy_speed = (reg0 & 0x40 ? 2 : (reg0 >> 13)&1);
162                                         phy_duplex = (reg0 >> 8)&1;
163                                         break;
164                                 }
165                         } else {
166                                 /* parallel detection or fixed speed */
167                                 phy_pause = (reg4 & 0x0400) >> 10;
168                                 phy_speed = (reg0 & 0x40 ? 2 : (reg0 >> 13)&1);
169                                 phy_duplex = (reg0 >> 8)&1;
170                         }
171
172                         if (port == 0) {
173                                 es_w32_mask(LTQ_ES_RGMII_CTL_REG_P0SPD,
174                                             LTQ_ES_RGMII_CTL_REG_P0SPD_VAL(phy_speed),
175                                             rgmii_ctl);
176                                 es_w32_mask(LTQ_ES_RGMII_CTL_REG_P0DUP,
177                                             LTQ_ES_RGMII_CTL_REG_P0DUP_VAL(phy_duplex),
178                                             rgmii_ctl);
179                                 es_w32_mask(LTQ_ES_RGMII_CTL_REG_P0FCE,
180                                             LTQ_ES_RGMII_CTL_REG_P0FCE_VAL(phy_pause),
181                                             rgmii_ctl);
182
183                                 es_w32_mask(0, LTQ_ES_P0_CTL_REG_FLP, p0_ctl);
184                         } else {
185                                 es_w32_mask(LTQ_ES_RGMII_CTL_REG_P1SPD,
186                                             LTQ_ES_RGMII_CTL_REG_P1SPD_VAL(phy_speed),
187                                             rgmii_ctl);
188                                 es_w32_mask(LTQ_ES_RGMII_CTL_REG_P1DUP,
189                                             LTQ_ES_RGMII_CTL_REG_P1DUP_VAL(phy_duplex),
190                                             rgmii_ctl);
191                                 es_w32_mask(LTQ_ES_RGMII_CTL_REG_P1FCE,
192                                             LTQ_ES_RGMII_CTL_REG_P0FCE_VAL(phy_pause),
193                                             rgmii_ctl);
194
195                                 es_w32_mask(1, LTQ_ES_P0_CTL_REG_FLP, p1_ctl);
196                         }
197                 }
198         }
199         old_link_status[port] = new_link_status;
200 }
201
202 static void _switchip_mdio_poll(struct work_struct *work)
203 {
204         if (es_r32(sw_gctl0) & LTQ_ES_SW_GCTL0_REG_SE) {
205                 _switchip_check_phy_status(0);
206                 _switchip_check_phy_status(1);
207         }
208
209         queue_delayed_work(mdio_poll_workqueue, &mdio_poll_work, HZ/2);
210 }
211
212 static void switchip_mdio_poll_init(void)
213 {
214         mdio_poll_workqueue = create_workqueue("SVIP MDIP poll");
215         INIT_DELAYED_WORK(&mdio_poll_work, _switchip_mdio_poll);
216
217         queue_delayed_work(mdio_poll_workqueue, &mdio_poll_work, HZ/2);
218
219 }
220
221 unsigned short switchip_phy_read(unsigned int phyaddr, unsigned int regaddr)
222 {
223         /* TODO: protect MDIO access with semaphore */
224         es_w32(LTQ_ES_MDIO_CTL_REG_MBUSY
225                | LTQ_ES_MDIO_CTL_REG_OP_VAL(2) /* read operation */
226                | LTQ_ES_MDIO_CTL_REG_PHYAD_VAL(phyaddr)
227                | LTQ_ES_MDIO_CTL_REG_REGAD_VAL(regaddr), mdio_ctl);
228         while (es_r32(mdio_ctl) & LTQ_ES_MDIO_CTL_REG_MBUSY);
229
230         return es_r32(mdio_data) & 0xFFFF;
231 }
232 EXPORT_SYMBOL(switchip_phy_read);
233
234 void switchip_phy_write(unsigned int phyaddr, unsigned int regaddr,
235                         unsigned short data)
236 {
237         /* TODO: protect MDIO access with semaphore */
238         es_w32(LTQ_ES_MDIO_CTL_REG_WD_VAL(data)
239                | LTQ_ES_MDIO_CTL_REG_MBUSY
240                | LTQ_ES_MDIO_CTL_REG_OP_VAL(1) /* write operation */
241                | LTQ_ES_MDIO_CTL_REG_PHYAD_VAL(phyaddr)
242                | LTQ_ES_MDIO_CTL_REG_REGAD_VAL(regaddr), mdio_ctl);
243         while (es_r32(mdio_ctl) & LTQ_ES_MDIO_CTL_REG_MBUSY);
244
245         return;
246 }
247 EXPORT_SYMBOL(switchip_phy_write);
248
249 const static u32 switch_reset_offset_000[] = {
250         /*b8000000:*/ 0xffffffff, 0x00000001, 0x00000001, 0x00000003,
251         /*b8000010:*/ 0x04070001, 0x04070001, 0x04070001, 0xffffffff,
252         /*b8000020:*/ 0x00001be8, 0x00001be8, 0x00001be8, 0xffffffff,
253         /*b8000030:*/ 0x00000000, 0x00000000, 0x00080004, 0x00020001,
254         /*b8000040:*/ 0x00000000, 0x00000000, 0x00080004, 0x00020001,
255         /*b8000050:*/ 0x00000000, 0x00000000, 0x00080004, 0x00020001,
256         /*b8000060:*/ 0x00000000, 0x00000000, 0x00081000, 0x001f7777,
257         /*b8000070:*/ 0x00000000, 0x00000000, 0x0c00ac2b, 0x0000fa50,
258         /*b8000080:*/ 0x00001000, 0x00001800, 0x00000000, 0x00000000,
259         /*b8000090:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
260         /*b80000a0:*/ 0x00000000, 0x00000050, 0x00000010, 0x00000000,
261         /*b80000b0:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
262         /*b80000c0:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
263         /*b80000d0:*/ 0xffffffff, 0x00000000, 0x00000000
264 };
265 const static u32 switch_reset_offset_100[] = {
266         /*b8000100:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
267         /*b8000110:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
268         /*b8000120:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
269         /*b8000130:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
270         /*b8000140:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
271         /*b8000150:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
272         /*b8000160:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
273         /*b8000170:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
274         /*b8000180:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
275         /*b8000190:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
276         /*b80001a0:*/ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
277         /*b80001b0:*/ 0x00000000, 0x00000000
278 };
279
280 /*
281  * Switch Reset.
282  */
283 void switchip_reset(void)
284 {
285         volatile unsigned int *reg;
286         volatile unsigned int rdreg;
287         int i;
288
289         sys1_w32(SYS1_CLKENR_ETHSW, clkenr);
290         asm("sync");
291
292         /* disable P0 */
293         es_w32_mask(0, LTQ_ES_P0_CTL_REG_SPS_VAL(1), p0_ctl);
294         /* disable P1 */
295         es_w32_mask(0, LTQ_ES_P0_CTL_REG_SPS_VAL(1), p1_ctl);
296         /* disable P2 */
297         es_w32_mask(0, LTQ_ES_P0_CTL_REG_SPS_VAL(1), p2_ctl);
298
299         /**************************************
300          * BEGIN: Procedure to clear MAC table
301          **************************************/
302         for (i = 0; i < 3; i++) {
303                 int result;
304
305                 /* check if access engine is available */
306                 while (es_r32(adr_tb_st2) & LTQ_ES_ADR_TB_ST2_REG_BUSY);
307
308                 /* initialise to first address */
309                 es_w32(LTQ_ES_ADR_TB_CTL2_REG_CMD_VAL(3)
310                        | LTQ_ES_ADR_TB_CTL2_REG_AC_VAL(0), adr_tb_ctl2);
311
312                 /* wait while busy */
313                 while (es_r32(adr_tb_st2) & LTQ_ES_ADR_TB_ST2_REG_BUSY);
314
315                 /* setup the portmap */
316                 es_w32_mask(0, LTQ_ES_ADR_TB_CTL1_REG_PMAP_VAL(1 << i),
317                             adr_tb_ctl1);
318
319                 do {
320                         /* search for addresses by port */
321                         es_w32(LTQ_ES_ADR_TB_CTL2_REG_CMD_VAL(2)
322                                | LTQ_ES_ADR_TB_CTL2_REG_AC_VAL(9), adr_tb_ctl2);
323
324                         /* wait while busy */
325                         while (es_r32(adr_tb_st2) & LTQ_ES_ADR_TB_ST2_REG_BUSY);
326
327                         result = LTQ_ES_ADR_TB_ST2_REG_RSLT_GET(es_r32(adr_tb_st2));
328                         if (result == 0x101) {
329                                 printk(KERN_ERR "%s, cmd error\n", __func__);
330                                 return;
331                         }
332                         /* if Command OK, address found... */
333                         if (result == 0) {
334                                 unsigned char mac[6];
335
336                                 mac[5] = (es_r32(adr_tb_st0) >> 0) & 0xff;
337                                 mac[4] = (es_r32(adr_tb_st0) >> 8) & 0xff;
338                                 mac[3] = (es_r32(adr_tb_st0) >> 16) & 0xff;
339                                 mac[2] = (es_r32(adr_tb_st0) >> 24) & 0xff;
340                                 mac[1] = (es_r32(adr_tb_st1) >> 0) & 0xff;
341                                 mac[0] = (es_r32(adr_tb_st1) >> 8) & 0xff;
342
343                                 /* setup address */
344                                 es_w32((mac[5] << 0) |
345                                        (mac[4] << 8) |
346                                        (mac[3] << 16) |
347                                        (mac[2] << 24), adr_tb_ctl0);
348                                 es_w32(LTQ_ES_ADR_TB_CTL1_REG_PMAP_VAL(1<<i) |
349                                        LTQ_ES_ADR_TB_CTL1_REG_FID_VAL(0) |
350                                        (mac[0] << 8) |
351                                        (mac[1] << 0), adr_tb_ctl1);
352                                 /* erase address */
353
354                                 es_w32(LTQ_ES_ADR_TB_CTL2_REG_CMD_VAL(1) |
355                                        LTQ_ES_ADR_TB_CTL2_REG_AC_VAL(15),
356                                        adr_tb_ctl2);
357
358                                 /* wait, while busy */
359                                 while (es_r32(adr_tb_st2) &
360                                        LTQ_ES_ADR_TB_ST2_REG_BUSY);
361                         }
362                 } while (result == 0);
363         }
364         /**************************************
365          * END: Procedure to clear MAC table
366          **************************************/
367
368         /* reset RMON counters */
369         es_w32(LTQ_ES_RMON_CTL_REG_BAS | LTQ_ES_RMON_CTL_REG_CAC_VAL(3),
370                rmon_ctl);
371
372         /* bring all registers to reset state */
373         reg = LTQ_ES_PS_REG;
374         for (i = 0; i < ARRAY_SIZE(switch_reset_offset_000); i++) {
375                 if ((reg == LTQ_ES_PS_REG) ||
376                     (reg >= LTQ_ES_ADR_TB_CTL0_REG &&
377                      reg <= LTQ_ES_ADR_TB_ST2_REG))
378                         continue;
379
380                 if (switch_reset_offset_000[i] != 0xFFFFFFFF) {
381                         /* write reset value to register */
382                         *reg = switch_reset_offset_000[i];
383                         /* read register value back */
384                         rdreg = *reg;
385                         if (reg == LTQ_ES_SW_GCTL1_REG)
386                                 rdreg &= ~LTQ_ES_SW_GCTL1_REG_BISTDN;
387                         /* compare read value with written one */
388                         if (rdreg != switch_reset_offset_000[i]) {
389                                 printk(KERN_ERR "%s,%d: reg %08x mismatch "
390                                        "[has:%08x, expect:%08x]\n",
391                                        __func__, __LINE__,
392                                        (unsigned int)reg, rdreg,
393                                        switch_reset_offset_000[i]);
394                         }
395                 }
396                 reg++;
397         }
398
399         reg = LTQ_ES_VLAN_FLT0_REG;
400         for (i = 0; i < ARRAY_SIZE(switch_reset_offset_100); i++) {
401                 *reg = switch_reset_offset_100[i];
402                 rdreg = *reg;
403                 if (rdreg != switch_reset_offset_100[i]) {
404                         printk(KERN_ERR "%s,%d: reg %08x mismatch "
405                                "[has:%08x, expect:%08x]\n", __func__, __LINE__,
406                                (unsigned int)reg, rdreg,
407                                switch_reset_offset_100[i]);
408                 }
409                 reg++;
410         }
411 }
412 EXPORT_SYMBOL(switchip_reset);
413
414 static u32 get_phy_oui(unsigned char phy_addr)
415 {
416         u32 oui;
417         int i, bit, byte, shift, w;
418         u16 reg_id[2];
419
420         /* read PHY identifier registers 1 and 2 */
421         reg_id[0] = switchip_phy_read(phy_addr, 2);
422         reg_id[1] = switchip_phy_read(phy_addr, 3);
423
424         oui = 0;
425         w = 1;
426         shift = 7;
427         byte = 1;
428         for (i = 0, bit = 10; i <= 21; i++, bit++) {
429                 oui |= ((reg_id[w] & (1<<bit)) ? 1 : 0) << shift;
430                 if (!(shift % 8)) {
431                         byte++;
432                         if (byte == 2)
433                                 shift = 15;
434                         else
435                                 shift = 21;
436                 } else {
437                         shift--;
438                 }
439                 if (w == 1 && bit == 15) {
440                         bit = -1;
441                         w = 0;
442                 }
443         }
444         return oui;
445 }
446
447 /*
448  * Switch Initialization.
449  */
450 int switchip_init(void)
451 {
452         int eth_port, phy_present = 0;
453         u16 reg, mode;
454
455         sys1_w32(SYS1_CLKENR_ETHSW, clkenr);
456         asm("sync");
457
458         /* Enable Switch, if not already done so */
459         if ((es_r32(sw_gctl0) & LTQ_ES_SW_GCTL0_REG_SE) == 0)
460                 es_w32_mask(0, LTQ_ES_SW_GCTL0_REG_SE, sw_gctl0);
461         /* Wait for completion of MBIST */
462         while (LTQ_ES_SW_GCTL1_REG_BISTDN_GET(es_r32(sw_gctl1)) == 0);
463
464         switchip_reset();
465
466         mode = LTQ_ES_RGMII_CTL_REG_IS_GET(es_r32(rgmii_ctl));
467         eth_port = (mode == 2 ? 1 : 0);
468
469         /* Set the primary port(port toward backplane) as sniffer port,
470            changing from P2 which is the reset setting */
471         es_w32_mask(LTQ_ES_SW_GCTL0_REG_SNIFFPN,
472                     LTQ_ES_SW_GCTL0_REG_SNIFFPN_VAL(eth_port),
473                     sw_gctl0);
474
475         /* Point MDIO state machine to invalid PHY addresses 8 and 9 */
476         es_w32_mask(0, LTQ_ES_SW_GCTL0_REG_PHYBA, sw_gctl0);
477
478         /* Add CRC for packets from DMA to PMAC.
479            Remove CRC for packets from PMAC to DMA. */
480         es_w32(LTQ_ES_PMAC_HD_CTL_RC | LTQ_ES_PMAC_HD_CTL_AC, pmac_hd_ctl);
481
482         phy_oui = get_phy_oui(0);
483         switch (phy_oui) {
484 #ifdef CONFIG_LANTIQ_MACH_EASY336
485         case PHY_OUI_PMC:
486                 phy_address[0] = (mode == 2 ? -1 : 2);
487                 phy_address[1] = (mode == 2 ? 2 : -1);
488                 break;
489 #endif
490         case PHY_OUI_VITESSE:
491         default:
492                 phy_oui = PHY_OUI_DEFAULT;
493                 phy_address[0] = (mode == 2 ? 1 : 0);
494                 phy_address[1] = (mode == 2 ? 0 : 1);
495                 break;
496         }
497
498         /****** PORT 0 *****/
499         reg = switchip_phy_read(phy_address[0], 1);
500         if ((reg != 0x0000) && (reg != 0xffff)) {
501                 /* PHY connected? */
502                 phy_present |= 1;
503                 /* Set Rx- and TxDelay in case of RGMII */
504                 switch (mode) {
505                 case 0: /* *RGMII,RGMII */
506                 case 2: /* RGMII,*GMII */
507                         /* program clock delay in PHY, not in SVIP */
508
509                         es_w32_mask(LTQ_ES_RGMII_CTL_REG_P0RDLY, 0, rgmii_ctl);
510                         es_w32_mask(LTQ_ES_RGMII_CTL_REG_P0TDLY, 0, rgmii_ctl);
511                         if (phy_oui == PHY_OUI_VITESSE ||
512                             phy_oui == PHY_OUI_DEFAULT) {
513                                 switchip_phy_write(phy_address[0], 31, 0x0001);
514                                 switchip_phy_write(phy_address[0], 28, 0xA000);
515                                 switchip_phy_write(phy_address[0], 31, 0x0000);
516                         }
517                 default:
518                         break;
519                 }
520                 if (phy_oui == PHY_OUI_VITESSE ||
521                     phy_oui == PHY_OUI_DEFAULT) {
522                         /* Program PHY advertisements and
523                          * restart auto-negotiation */
524                         switchip_phy_write(phy_address[0], 4, 0x05E1);
525                         switchip_phy_write(phy_address[0], 9, 0x0300);
526                         switchip_phy_write(phy_address[0], 0, 0x3300);
527                 } else {
528                         reg = switchip_phy_read(phy_address[1], 0);
529                         reg |= 0x1000; /* auto-negotiation enable */
530                         switchip_phy_write(phy_address[1], 0, reg);
531                         reg |= 0x0200; /* auto-negotiation restart */
532                         switchip_phy_write(phy_address[1], 0, reg);
533                 }
534         } else {
535                 /* Force SWITCH link with highest capability:
536                  * 100M FD for MII
537                  * 1G FD for GMII/RGMII
538                  */
539                 switch (mode) {
540                 case 1: /* *MII,MII */
541                 case 3: /* *MII,RGMII */
542                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P0SPD_VAL(1),
543                                     rgmii_ctl);
544                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P0DUP_VAL(1),
545                                     rgmii_ctl);
546                         break;
547                 case 0: /* *RGMII,RGMII */
548                 case 2: /* RGMII,*GMII */
549                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P0SPD_VAL(2),
550                                     rgmii_ctl);
551                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P0DUP_VAL(1),
552                                     rgmii_ctl);
553
554                         es_w32_mask(LTQ_ES_RGMII_CTL_REG_P0RDLY, 0, rgmii_ctl);
555                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P0TDLY_VAL(2),
556                                     rgmii_ctl);
557                         break;
558                 }
559
560                 es_w32_mask(0, LTQ_ES_P0_CTL_REG_FLP, p0_ctl);
561         }
562
563         /****** PORT 1 *****/
564         reg = switchip_phy_read(phy_address[1], 1);
565         if ((reg != 0x0000) && (reg != 0xffff)) {
566                 /* PHY connected? */
567                 phy_present |= 2;
568                 /* Set Rx- and TxDelay in case of RGMII */
569                 switch (mode) {
570                 case 0: /* *RGMII,RGMII */
571                 case 3: /* *MII,RGMII */
572                         /* program clock delay in PHY, not in SVIP */
573
574                         es_w32_mask(LTQ_ES_RGMII_CTL_REG_P1RDLY, 0, rgmii_ctl);
575                         es_w32_mask(LTQ_ES_RGMII_CTL_REG_P1TDLY, 0, rgmii_ctl);
576                         if (phy_oui == PHY_OUI_VITESSE ||
577                             phy_oui == PHY_OUI_DEFAULT) {
578                                 switchip_phy_write(phy_address[1], 31, 0x0001);
579                                 switchip_phy_write(phy_address[1], 28, 0xA000);
580                                 switchip_phy_write(phy_address[1], 31, 0x0000);
581                         }
582                         break;
583                 case 2: /* RGMII,*GMII */
584
585                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1SPD_VAL(2),
586                                     rgmii_ctl);
587                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1DUP, rgmii_ctl);
588 #ifdef CONFIG_LANTIQ_MACH_EASY336
589                         if (phy_oui == PHY_OUI_PMC) {
590                                 switchip_phy_write(phy_address[1], 24, 0x0510);
591                                 switchip_phy_write(phy_address[1], 17, 0xA38C);
592                                 switchip_phy_write(phy_address[1], 17, 0xA384);
593                         }
594 #endif
595                         break;
596                 default:
597                         break;
598                 }
599                 /* Program PHY advertisements and restart auto-negotiation */
600                 if (phy_oui == PHY_OUI_VITESSE ||
601                     phy_oui == PHY_OUI_DEFAULT) {
602                         switchip_phy_write(phy_address[1], 4, 0x05E1);
603                         switchip_phy_write(phy_address[1], 9, 0x0300);
604                         switchip_phy_write(phy_address[1], 0, 0x3300);
605                 } else {
606                         reg = switchip_phy_read(phy_address[1], 0);
607                         reg |= 0x1000; /* auto-negotiation enable */
608                         switchip_phy_write(phy_address[1], 0, reg);
609                         reg |= 0x0200; /* auto-negotiation restart */
610                         switchip_phy_write(phy_address[1], 0, reg);
611                 }
612         } else {
613                 /* Force SWITCH link with highest capability:
614                  * 100M FD for MII
615                  * 1G FD for GMII/RGMII
616                  */
617                 switch (mode) {
618                 case 1: /* *MII,MII */
619                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1SPD_VAL(1),
620                                     rgmii_ctl);
621                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1DUP, rgmii_ctl);
622                         break;
623                 case 0: /* *RGMII,RGMII */
624                 case 3: /* *MII,RGMII */
625                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1SPD_VAL(2),
626                                     rgmii_ctl);
627                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1DUP, rgmii_ctl);
628                         es_w32_mask(LTQ_ES_RGMII_CTL_REG_P1RDLY, 0, rgmii_ctl);
629                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1TDLY_VAL(2),
630                                     rgmii_ctl);
631                         break;
632                 case 2: /* RGMII,*GMII */
633                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1SPD_VAL(2),
634                                     rgmii_ctl);
635                         es_w32_mask(0, LTQ_ES_RGMII_CTL_REG_P1DUP, rgmii_ctl);
636                         break;
637                 }
638                 es_w32_mask(0, LTQ_ES_P0_CTL_REG_FLP, p0_ctl);
639         }
640
641         /*
642          * Allow unknown unicast/multicast and broadcasts
643          * on all ports.
644          */
645
646         es_w32_mask(0, LTQ_ES_SW_GCTL1_REG_UP_VAL(7), sw_gctl1);
647         es_w32_mask(0, LTQ_ES_SW_GCTL1_REG_BP_VAL(7), sw_gctl1);
648         es_w32_mask(0, LTQ_ES_SW_GCTL1_REG_MP_VAL(7), sw_gctl1);
649         es_w32_mask(0, LTQ_ES_SW_GCTL1_REG_RP_VAL(7), sw_gctl1);
650
651         /* Enable LAN port(s) */
652         if (eth_port == 0)
653                 es_w32_mask(LTQ_ES_P0_CTL_REG_SPS, 0, p0_ctl);
654         else
655                 es_w32_mask(LTQ_ES_P0_CTL_REG_SPS, 0, p1_ctl);
656         /* Enable CPU Port (Forwarding State) */
657         es_w32_mask(LTQ_ES_P0_CTL_REG_SPS, 0, p2_ctl);
658
659         if (phy_present)
660                 switchip_mdio_poll_init();
661
662         return 0;
663 }
664 EXPORT_SYMBOL(switchip_init);
665
666 device_initcall(switchip_init);