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