treewide: drop executable file attrib for non-executable files
[oweals/u-boot_mod.git] / u-boot / cpu / mips / ar7240 / ag7240.c
1 #include <config.h>
2 #include <common.h>
3 #include <malloc.h>
4 #include <net.h>
5 #include <command.h>
6 #include <asm/io.h>
7 #include <asm/addrspace.h>
8 #include <asm/types.h>
9 #include "ar7240_soc.h"
10 #include "ag7240.h"
11 #include "ag7240_phy.h"
12
13 #if (CONFIG_COMMANDS & CFG_CMD_MII)
14 #include <miiphy.h>
15 #else
16 #define _1000BASET      1000
17 #define _100BASET       100
18 #define _10BASET        10
19 #endif
20
21 #define ag7240_unit2mac(_unit)     ag7240_macs[(_unit)]
22 #define ag7240_name2mac(name)      strcmp(name,"eth0") ? ag7240_unit2mac(1) : ag7240_unit2mac(0)
23 #define CHECK_BIT(var,pos)                      ((var) & (1<<(pos)))
24
25 uint16_t ag7240_miiphy_read(char *devname, uint32_t phaddr, uint8_t reg);
26
27 void ag7240_miiphy_write(char *devname, uint32_t phaddr, uint8_t reg, uint16_t data);
28
29 ag7240_mac_t *ag7240_macs[CFG_AG7240_NMACS];
30
31 extern void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq);
32
33 extern int athrs26_phy_setup(int unit);
34 extern int athrs26_phy_is_up(int unit);
35 extern int athrs26_phy_is_fdx(int unit);
36 extern int athrs26_phy_speed(int unit);
37 extern void athrs26_reg_init(void);
38 extern void athrs26_reg_init_lan(void);
39 extern int athrs26_mdc_check(void);
40
41 #ifdef CONFIG_F1E_PHY
42 extern int athr_phy_setup(int unit);
43 extern int athr_phy_is_up(int unit);
44 extern int athr_phy_is_fdx(int unit);
45 extern int athr_phy_speed(int unit);
46 extern void athr_reg_init(void);
47 #endif
48
49 //#define AG7240_DEBUG
50
51 static int ag7240_send(struct eth_device *dev, volatile void *packet, int length) {
52         int i;
53
54         ag7240_mac_t *mac = (ag7240_mac_t *) dev->priv;
55
56         ag7240_desc_t *f = mac->fifo_tx[mac->next_tx];
57
58         f->pkt_size = length;
59         f->res1 = 0;
60         f->pkt_start_addr = virt_to_phys(packet);
61
62         ag7240_tx_give_to_dma(f);
63         flush_cache((u32) packet, length);
64         ag7240_reg_wr(mac, AG7240_DMA_TX_DESC, virt_to_phys(f));
65         ag7240_reg_wr(mac, AG7240_DMA_TX_CTRL, AG7240_TXE);
66
67         for (i = 0; i < MAX_WAIT; i++) {
68                 udelay(10);
69                 if (!ag7240_tx_owned_by_dma(f))
70                         break;
71         }
72
73         if (i == MAX_WAIT) {
74                 printf("Tx Timed out\n");
75         }
76
77         f->pkt_start_addr = 0;
78         f->pkt_size = 0;
79
80         if (++mac->next_tx >= NO_OF_TX_FIFOS) {
81                 mac->next_tx = 0;
82         }
83
84         return (0);
85 }
86
87 static int ag7240_recv(struct eth_device *dev) {
88         int length;
89         ag7240_desc_t *f;
90         ag7240_mac_t *mac;
91
92         mac = (ag7240_mac_t *) dev->priv;
93
94         for (;;) {
95                 f = mac->fifo_rx[mac->next_rx];
96
97                 if (ag7240_rx_owned_by_dma(f)) {
98                         break;
99                 }
100
101                 length = f->pkt_size;
102
103                 NetReceive(NetRxPackets[mac->next_rx], length - 4);
104                 flush_cache((u32) NetRxPackets[mac->next_rx], PKTSIZE_ALIGN);
105
106                 ag7240_rx_give_to_dma(f);
107
108                 if (++mac->next_rx >= NO_OF_RX_FIFOS) {
109                         mac->next_rx = 0;
110                 }
111         }
112
113         if (!(ag7240_reg_rd(mac, AG7240_DMA_RX_CTRL))) {
114                 ag7240_reg_wr(mac, AG7240_DMA_RX_DESC, virt_to_phys(f));
115                 ag7240_reg_wr(mac, AG7240_DMA_RX_CTRL, 1);
116         }
117
118         return (0);
119 }
120
121 /*
122  * Called in ag7240_hw_start() function
123  * */
124 void ag7240_mii_setup(ag7240_mac_t *mac) {
125         u32 mgmt_cfg_val;
126         u32 cpu_freq, ddr_freq, ahb_freq;
127         u32 check_cnt;
128
129 #ifdef CFG_ATHRS27_PHY
130         if (is_wasp()) {
131                 printf("WASP ----> S27 PHY \n");
132                 mgmt_cfg_val = 2;
133                 ar7240_reg_wr(0xb8050024, 0x271); // 25MHz ref clock
134                 //ar7240_reg_wr(0xb8050024, 0x570);     // 40MHz ref clock
135                 ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
136                 ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val);
137                 return;
138         }
139 #endif
140
141 #ifdef CONFIG_AR7242_S16_PHY
142         if (is_wasp()) {
143                 printf("WASP  ----> S16 PHY *\n");
144                 mgmt_cfg_val = 4;
145                 if(mac->mac_unit == 0)
146                 ar7240_reg_wr(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0);
147
148                 ar7240_reg_rmw_clear(AG7240_ETH_SWITCH_CLK_SPARE, (1 << 6));
149                 ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
150                 ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val);
151
152                 return;
153         }
154 #endif
155
156 #ifdef CONFIG_F1E_PHY
157         if (is_wasp()) {
158                 printf("WASP  ----> F1 PHY *\n");
159                 mgmt_cfg_val = 6;
160                 if(mac->mac_unit == 0)
161                 ar7240_reg_wr(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0);
162
163                 ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
164                 ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val);
165
166                 return;
167         }
168 #endif
169
170         if ((ar7240_reg_rd(AR7240_REV_ID) & AR7240_REV_ID_MASK) == AR7240_REV_1_2) {
171                 mgmt_cfg_val = 0x2;
172                 if (mac->mac_unit == 0) {
173                         ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
174                         ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val);
175                 }
176         } else {
177                 ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq);
178
179                 switch (ahb_freq / 1000000) {
180                 case 150:
181                         mgmt_cfg_val = 0x7;
182                         break;
183                 case 175:
184                         mgmt_cfg_val = 0x5;
185                         break;
186                 case 200:
187                         mgmt_cfg_val = 0x4;
188                         break;
189                 case 210:
190                         mgmt_cfg_val = 0x9;
191                         break;
192                 case 220:
193                         mgmt_cfg_val = 0x9;
194                         break;
195                 default:
196                         mgmt_cfg_val = 0x7;
197                 }
198                 if ((is_ar7241() || is_ar7242())) {
199
200                         /* External MII mode */
201                         if (mac->mac_unit == 0 && is_ar7242()) {
202                                 mgmt_cfg_val = 0x6;
203                                 ar7240_reg_rmw_set(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0);
204                                 ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
205                                 ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val);
206                         }
207                         /* Virian */
208                         mgmt_cfg_val = 0x4;
209                         ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
210                         ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val);
211                         printf("Virian MDC CFG Value ==> %x\n", mgmt_cfg_val);
212
213                 } else if (is_ar933x()) {
214                         //GE0 receives Rx/Tx clock, and use S26 phy
215                         ar7240_reg_rmw_set(AG7240_ETH_CFG, AG7240_ETH_CFG_MII_GE0_SLAVE);
216                         mgmt_cfg_val = 0xF;
217                         if (mac->mac_unit == 1) {
218                                 check_cnt = 0;
219                                 while (check_cnt++ < 10) {
220                                         ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
221                                         ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val);
222 #ifdef CFG_ATHRS26_PHY
223                                         if (athrs26_mdc_check() == 0) {
224                                                 break;
225                                         }
226 #endif
227                                 }
228                                 if (check_cnt == 11) {
229                                         printf("%s: MDC check failed\n", __func__);
230                                 }
231                         }
232                 } else { /* Python 1.0 & 1.1 */
233                         if (mac->mac_unit == 0) {
234                                 check_cnt = 0;
235                                 while (check_cnt++ < 10) {
236                                         ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
237                                         ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val);
238 #ifdef CFG_ATHRS26_PHY
239                                         if (athrs26_mdc_check() == 0) {
240                                                 break;
241                                         }
242 #endif
243                                 }
244                                 if (check_cnt == 11) {
245                                         printf("%s: MDC check failed\n", __func__);
246                                 }
247                         }
248                 }
249
250         }
251 }
252
253 static void ag7240_hw_start(ag7240_mac_t *mac) {
254
255         if (mac->mac_unit) {
256                 ag7240_reg_wr(mac, AG7240_MAC_CFG1, (AG7240_MAC_CFG1_RX_EN | AG7240_MAC_CFG1_TX_EN));
257                 ag7240_reg_rmw_set(mac, AG7240_MAC_CFG2, (AG7240_MAC_CFG2_PAD_CRC_EN | AG7240_MAC_CFG2_LEN_CHECK | AG7240_MAC_CFG2_IF_1000));
258         } else {
259                 ag7240_reg_wr(mac, AG7240_MAC_CFG1, (AG7240_MAC_CFG1_RX_EN | AG7240_MAC_CFG1_TX_EN));
260                 ag7240_reg_rmw_set(mac, AG7240_MAC_CFG2, (AG7240_MAC_CFG2_PAD_CRC_EN | AG7240_MAC_CFG2_LEN_CHECK | AG7240_MAC_CFG2_IF_10_100));
261         }
262
263         ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_0, 0x1f00);
264         ag7240_mii_setup(mac);
265
266         ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_1, 0x10ffff);
267         ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_2, 0xAAA0555);
268
269         ag7240_reg_rmw_set(mac, AG7240_MAC_FIFO_CFG_4, 0x3ffff);
270
271         // TODO: check this register
272         /*
273          * When enable the web failsafe mode in uboot,you can't drop the broadcast
274          * frames now,the PC first will tx a ARP request packet, it's a broadcast packet.
275          */
276         ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_5, 0x66b82);
277         /* 
278          * Setting Drop CRC Errors, Pause Frames, Length Error frames
279          * and Multi/Broad cast frames.
280          */
281         //ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_5, 0x7eccf);
282
283
284         ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_3, 0x1f00140);
285         //printf("cfg1:\t%#x\ncfg2:\t%#x\n", ag7240_reg_rd(mac, AG7240_MAC_CFG1), ag7240_reg_rd(mac, AG7240_MAC_CFG2));
286 }
287
288 static int ag7240_check_link(ag7240_mac_t *mac) {
289         int link = 0, duplex = 0, speed = 0;
290         char *s;
291
292         s = getenv("stdin");
293
294         ag7240_phy_link(mac->mac_unit, &link);
295         ag7240_phy_duplex(mac->mac_unit, &duplex);
296         ag7240_phy_speed(mac->mac_unit, &speed);
297
298         mac->link = link;
299
300         if (!mac->link) {
301                 if((s != NULL) && (strcmp(s, "nc") != 0)){
302                         printf("Link down: %s\n", mac->dev->name);
303                 }
304                 return 0;
305         }
306
307         switch (speed) {
308         case _1000BASET:
309                 ag7240_set_mac_if(mac, 1);
310                 ag7240_reg_rmw_set(mac, AG7240_MAC_FIFO_CFG_5, (1 << 19));
311                 if (is_ar7242() && (mac->mac_unit == 0)) {
312                         ar7240_reg_wr(AR7242_ETH_XMII_CONFIG, 0x1c000000);
313                 }
314 #ifdef CONFIG_F1E_PHY
315                 if (is_wasp() && (mac->mac_unit == 0)) {
316                         ar7240_reg_wr(AR7242_ETH_XMII_CONFIG,0x0e000000);
317                 }
318 #else      
319                 if (is_wasp() && (mac->mac_unit == 0)) {
320                         ar7240_reg_wr(AR7242_ETH_XMII_CONFIG, 0x06000000);
321                 }
322 #endif
323                 break;
324
325         case _100BASET:
326                 ag7240_set_mac_if(mac, 0);
327                 ag7240_set_mac_speed(mac, 1);
328                 ag7240_reg_rmw_clear(mac, AG7240_MAC_FIFO_CFG_5, (1 << 19));
329                 if ((is_ar7242() || is_wasp()) && (mac->mac_unit == 0)){
330                         ar7240_reg_wr(AR7242_ETH_XMII_CONFIG, 0x0101);
331                 }
332                 break;
333
334         case _10BASET:
335                 ag7240_set_mac_if(mac, 0);
336                 ag7240_set_mac_speed(mac, 0);
337                 ag7240_reg_rmw_clear(mac, AG7240_MAC_FIFO_CFG_5, (1 << 19));
338                 if ((is_ar7242() || is_wasp()) && (mac->mac_unit == 0)){
339                         ar7240_reg_wr(AR7242_ETH_XMII_CONFIG, 0x1616);
340                 }
341                 break;
342
343         default:
344                 if((s != NULL) && (strcmp(s, "nc") != 0)){
345                         printf("## Error: invalid speed detected\n");
346                 }
347                 return 0;
348         }
349
350         if (mac->link && (duplex == mac->duplex) && (speed == mac->speed)){
351                 return 1;
352         }
353
354         mac->duplex = duplex;
355         mac->speed = speed;
356
357         if((s != NULL) && (strcmp(s, "nc") != 0)){
358                 printf("Ethernet mode (duplex/speed): %d/%d Mbps\n", duplex, speed);
359         }
360
361         ag7240_set_mac_duplex(mac, duplex);
362
363         return 1;
364 }
365
366 /*
367  * For every command we re-setup the ring and start with clean h/w rx state
368  */
369 static int ag7240_clean_rx(struct eth_device *dev, bd_t * bd) {
370
371         int i;
372         ag7240_desc_t *fr;
373         ag7240_mac_t *mac = (ag7240_mac_t*)dev->priv;
374
375         if (!ag7240_check_link(mac)){
376                 return 0;
377         }
378
379         mac->next_rx = 0;
380
381         for (i = 0; i < NO_OF_RX_FIFOS; i++) {
382                 fr = mac->fifo_rx[i];
383                 fr->pkt_start_addr = virt_to_phys(NetRxPackets[i]);
384                 flush_cache((u32) NetRxPackets[i], PKTSIZE_ALIGN);
385                 ag7240_rx_give_to_dma(fr);
386         }
387
388         ag7240_reg_wr(mac, AG7240_DMA_RX_DESC, virt_to_phys(mac->fifo_rx[0]));
389         ag7240_reg_wr(mac, AG7240_DMA_RX_CTRL, AG7240_RXE);
390         /* rx start */
391
392         if (!is_ar933x()){
393                 // TODO: do we need this?
394                 udelay(1000 * 1000);
395         }
396
397         return 1;
398
399 }
400
401 static int ag7240_alloc_fifo(int ndesc, ag7240_desc_t ** fifo) {
402         int i;
403         u32 size;
404         uchar *p = NULL;
405
406         size = sizeof(ag7240_desc_t) * ndesc;
407         size += CFG_CACHELINE_SIZE - 1;
408
409         if ((p = malloc(size)) == NULL) {
410                 printf("Cant allocate fifos\n");
411                 return -1;
412         }
413
414         p = (uchar *) (((u32) p + CFG_CACHELINE_SIZE - 1) & ~(CFG_CACHELINE_SIZE - 1));
415         p = UNCACHED_SDRAM(p);
416
417         for (i = 0; i < ndesc; i++)
418                 fifo[i] = (ag7240_desc_t *) p + i;
419
420         return 0;
421 }
422
423 static int ag7240_setup_fifos(ag7240_mac_t *mac) {
424         int i;
425
426         if (ag7240_alloc_fifo(NO_OF_TX_FIFOS, mac->fifo_tx))
427                 return 1;
428
429         for (i = 0; i < NO_OF_TX_FIFOS; i++) {
430                 mac->fifo_tx[i]->next_desc = (i == NO_OF_TX_FIFOS - 1) ? virt_to_phys(mac->fifo_tx[0]) : virt_to_phys(mac->fifo_tx[i + 1]);
431                 ag7240_tx_own(mac->fifo_tx[i]);
432         }
433
434         if (ag7240_alloc_fifo(NO_OF_RX_FIFOS, mac->fifo_rx))
435                 return 1;
436
437         for (i = 0; i < NO_OF_RX_FIFOS; i++) {
438                 mac->fifo_rx[i]->next_desc = (i == NO_OF_RX_FIFOS - 1) ? virt_to_phys(mac->fifo_rx[0]) : virt_to_phys(mac->fifo_rx[i + 1]);
439         }
440
441         return (1);
442 }
443
444 static void ag7240_halt(struct eth_device *dev) {
445         ag7240_mac_t *mac = (ag7240_mac_t *) dev->priv;
446         ag7240_reg_wr(mac, AG7240_DMA_RX_CTRL, 0);
447         while (ag7240_reg_rd(mac, AG7240_DMA_RX_CTRL))
448                 ;
449 }
450
451 /*
452  * Get MAC address stored in flash
453  */
454 static void ag7240_get_ethaddr(struct eth_device *dev) {
455         unsigned char *mac = dev->enetaddr;
456 #ifdef OFFSET_MAC_ADDRESS
457         unsigned char buffer[6];
458
459         // get MAC address from flash and check it
460         memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), 6);
461
462         /*
463          * check first LSBit (I/G bit) and second LSBit (U/L bit) in MSByte of vendor part
464          * both of them should be 0:
465          * I/G bit == 0 -> Individual MAC address (unicast address)
466          * U/L bit == 0 -> Burned-In-Address (BIA) MAC address
467          */
468         if(CHECK_BIT((buffer[0] & 0xFF), 0) == 0 && CHECK_BIT((buffer[0] & 0xFF), 1) == 0){
469                 mac[0] = (buffer[0] & 0xFF);
470                 mac[1] = (buffer[1] & 0xFF);
471                 mac[2] = (buffer[2] & 0xFF);
472                 mac[3] = (buffer[3] & 0xFF);
473                 mac[4] = (buffer[4] & 0xFF);
474                 mac[5] = (buffer[5] & 0xFF);
475         } else {
476                 // 00-03-7F (Atheros Communications, Inc.)
477                 mac[0] = 0x00;
478                 mac[1] = 0x03;
479                 mac[2] = 0x7f;
480                 mac[3] = 0x09;
481                 mac[4] = 0x0b;
482                 mac[5] = 0xad;
483
484                 printf("## Error: MAC address in FLASH is invalid, using fixed!\n");
485         }
486 #else
487         // 00-03-7F (Atheros Communications, Inc.)
488         mac[0] = 0x00;
489         mac[1] = 0x03;
490         mac[2] = 0x7f;
491         mac[3] = 0x09;
492         mac[4] = 0x0b;
493         mac[5] = 0xad;
494 #endif
495 }
496
497 int ag7240_enet_initialize(bd_t * bis) {
498         struct eth_device *dev[CFG_AG7240_NMACS];
499         u32 mask, mac_h, mac_l;
500         int i;
501
502 #ifdef AG7240_DEBUG
503         printf("ag7240_enet_initialize...\n");
504 #endif
505
506         // TODO check this register!
507         ar7240_reg_wr(HORNET_BOOTSTRAP_STATUS, ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS) & ~HORNET_BOOTSTRAP_MDIO_SLAVE_MASK);
508
509         if (is_ar933x()) {
510                 u32 rd = 0x0;
511
512                 /* 
513                  * To get s26 out of reset, we have to...
514                  * bit0~bit3: has to be deasserted
515                  * bit4:      has to be asserted
516                  */
517                 rd = ar7240_reg_rd(AR7240_S26_CLK_CTRL_OFFSET) & ~(0x1f);
518                 rd |= 0x10;
519                 ar7240_reg_wr(AR7240_S26_CLK_CTRL_OFFSET, rd);
520
521                 if (ar7240_reg_rd(AR7240_RESET) != 0) {
522                         ar7240_reg_wr(AR7240_RESET, 0);
523                 }
524         }
525
526         for (i = 0; i < CFG_AG7240_NMACS; i++) {
527
528                 if ((dev[i] = (struct eth_device *) malloc(sizeof(struct eth_device))) == NULL) {
529                         puts("## Error: malloc failed\n");
530                         return 0;
531                 }
532
533                 if ((ag7240_macs[i] = (ag7240_mac_t *) malloc(sizeof(ag7240_mac_t))) == NULL) {
534                         puts("## Error: malloc failed\n");
535                         return 0;
536                 }
537
538                 memset(ag7240_macs[i], 0, sizeof(ag7240_macs[i]));
539                 memset(dev[i], 0, sizeof(dev[i]));
540
541                 sprintf(dev[i]->name, "eth%d", i);
542                 ag7240_get_ethaddr(dev[i]);
543
544                 ag7240_macs[i]->mac_unit = i;
545                 ag7240_macs[i]->mac_base = i ? AR7240_GE1_BASE : AR7240_GE0_BASE;
546                 ag7240_macs[i]->dev = dev[i];
547
548                 dev[i]->iobase = 0;
549                 dev[i]->init = ag7240_clean_rx;
550                 dev[i]->halt = ag7240_halt;
551                 dev[i]->send = ag7240_send;
552                 dev[i]->recv = ag7240_recv;
553                 dev[i]->priv = (void *) ag7240_macs[i];
554         }
555
556         for (i = 0; i < CFG_AG7240_NMACS; i++) {
557
558                 eth_register(dev[i]);
559
560 #if(CONFIG_COMMANDS & CFG_CMD_MII)
561                 miiphy_register(dev[i]->name, ag7240_miiphy_read, ag7240_miiphy_write);
562 #endif
563
564                 ag7240_reg_rmw_set(ag7240_macs[i], AG7240_MAC_CFG1, AG7240_MAC_CFG1_SOFT_RST | AG7240_MAC_CFG1_RX_RST | AG7240_MAC_CFG1_TX_RST);
565
566                 if (!i) {
567                         mask = (AR7240_RESET_GE0_MAC | AR7240_RESET_GE0_PHY | AR7240_RESET_GE1_MAC | AR7240_RESET_GE1_PHY);
568
569                         if (is_ar7241() || is_ar7242() || is_wasp()){
570                                 mask = mask | AR7240_RESET_GE0_MDIO | AR7240_RESET_GE1_MDIO;
571                         }
572
573                         ar7240_reg_rmw_set(AR7240_RESET, mask);
574
575                         if (!is_ar933x()){
576                                 udelay(1000 * 100);
577                         }
578
579                         ar7240_reg_rmw_clear(AR7240_RESET, mask);
580
581                         if (!is_ar933x()){
582                                 udelay(1000 * 100);
583                         }
584
585                         if (!is_ar933x()){
586                                 udelay(10 * 1000);
587                         }
588                 }
589
590                 ag7240_hw_start(ag7240_macs[i]);
591
592                 ag7240_setup_fifos(ag7240_macs[i]);
593
594                 if (!is_ar933x()){
595                         udelay(100 * 1000);
596                 }
597
598 #ifdef AG7240_DEBUG
599                 unsigned char *mac = dev[i]->enetaddr;
600                 printf("\nInterface %s MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", dev[i]->name, mac[0] & 0xff, mac[1] & 0xff, mac[2] & 0xff, mac[3] & 0xff, mac[4] & 0xff, mac[5] & 0xff);
601 #endif
602
603                 mac_l = (dev[i]->enetaddr[4] << 8) | (dev[i]->enetaddr[5]);
604                 mac_h = (dev[i]->enetaddr[0] << 24) | (dev[i]->enetaddr[1] << 16) | (dev[i]->enetaddr[2] << 8) | (dev[i]->enetaddr[3] << 0);
605
606                 ag7240_reg_wr(ag7240_macs[i], AG7240_GE_MAC_ADDR1, mac_l);
607                 ag7240_reg_wr(ag7240_macs[i], AG7240_GE_MAC_ADDR2, mac_h);
608
609                 /* if using header for register configuration, we have to     */
610                 /* configure s26 register after frame transmission is enabled */
611
612                 if (ag7240_macs[i]->mac_unit == 0) { /* WAN Phy */
613 #ifdef CONFIG_AR7242_S16_PHY
614                         if (is_ar7242() || is_wasp()) {
615                                 athrs16_reg_init();
616                         } else
617 #endif
618                         {
619 #ifdef CFG_ATHRS26_PHY
620         #ifdef AG7240_DEBUG
621                                 printf("s26 reg init \n");
622         #endif
623                                 athrs26_reg_init();
624 #endif
625 #ifdef CFG_ATHRS27_PHY
626         #ifdef AG7240_DEBUG
627                                 printf("s27 reg init \n");
628         #endif
629                                 athrs27_reg_init();
630 #endif
631 #ifdef CONFIG_F1E_PHY
632         #ifdef AG7240_DEBUG
633                                 printf("F1Phy reg init \n");
634         #endif
635                                 athr_reg_init();
636 #endif
637                         }
638                 } else {
639 #ifdef CFG_ATHRS26_PHY
640         #ifdef AG7240_DEBUG
641                         printf("athrs26_reg_init_lan\n");
642         #endif
643                         athrs26_reg_init_lan();
644 #endif
645 #ifdef CFG_ATHRS27_PHY
646         #ifdef AG7240_DEBUG
647                         printf("s27 reg init lan \n");
648         #endif
649                         athrs27_reg_init_lan();
650 #endif
651                 }
652
653 #ifdef AG7240_DEBUG
654                 printf("ag7240_phy_setup\n");
655 #endif
656                 //udelay(100*1000);
657
658                 ag7240_phy_setup(ag7240_macs[i]->mac_unit);
659
660 #ifdef AG7240_DEBUG
661                 printf("Interface %s is up\n", dev[i]->name);
662 #endif
663         }
664
665         return 1;
666 }
667
668 /* Modified by lsz for reduceing CMD_MII, but ag7240 need this 090306 */
669 uint16_t ag7240_miiphy_read(char *devname, uint32_t phy_addr, uint8_t reg) {
670         ag7240_mac_t *mac = ag7240_name2mac(devname);
671         uint16_t addr = (phy_addr << AG7240_ADDR_SHIFT) | reg, val;
672         volatile int rddata;
673         uint16_t ii = 0xFFFF;
674
675         /*
676          * Check for previous transactions are complete. Added to avoid
677          * race condition while running at higher frequencies.
678          */
679         do {
680                 udelay(5);
681                 rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1;
682         } while (rddata && --ii);
683
684         if (ii == 0)
685                 printf("ERROR:%s:%d transaction failed\n", __func__, __LINE__);
686
687         ag7240_reg_wr(mac, AG7240_MII_MGMT_CMD, 0x0);
688         ag7240_reg_wr(mac, AG7240_MII_MGMT_ADDRESS, addr);
689         ag7240_reg_wr(mac, AG7240_MII_MGMT_CMD, AG7240_MGMT_CMD_READ);
690
691         do {
692                 udelay(5);
693                 rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1;
694         } while (rddata && --ii);
695
696         if (ii == 0)
697                 printf("ERROR! Leave ag7240_miiphy_read without polling correct status!\n");
698
699         val = ag7240_reg_rd(mac, AG7240_MII_MGMT_STATUS);
700         ag7240_reg_wr(mac, AG7240_MII_MGMT_CMD, 0x0);
701
702         return val;
703 }
704
705 void ag7240_miiphy_write(char *devname, uint32_t phy_addr, uint8_t reg, uint16_t data) {
706         ag7240_mac_t *mac = ag7240_name2mac(devname);
707         uint16_t addr = (phy_addr << AG7240_ADDR_SHIFT) | reg;
708         volatile int rddata;
709         uint16_t ii = 0xFFFF;
710
711         /*
712          * Check for previous transactions are complete. Added to avoid
713          * race condition while running at higher frequencies.
714          */
715         do {
716                 udelay(5);
717                 rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1;
718         } while (rddata && --ii);
719
720         if (ii == 0)
721                 printf("ERROR:%s:%d transaction failed\n", __func__, __LINE__);
722
723         ag7240_reg_wr(mac, AG7240_MII_MGMT_ADDRESS, addr);
724         ag7240_reg_wr(mac, AG7240_MII_MGMT_CTRL, data);
725
726         do {
727                 rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1;
728         } while (rddata && --ii);
729
730         if (ii == 0)
731                 printf("ERROR! Leave ag7240_miiphy_write without polling correct status!\n");
732 }