7 #include <asm/addrspace.h>
\r
8 #include <asm/types.h>
\r
9 #include "ar7240_soc.h"
\r
11 #include "ag934x_phy.h"
\r
13 #define _1000BASET 1000
\r
14 #define _100BASET 100
\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
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
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
36 #ifdef CFG_ATHRS17_PHY
\r
37 extern void athrs17_reg_init(void);
\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
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
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
67 static int ag7240_send(struct eth_device *dev, volatile void *packet, int length){
\r
70 ag7240_mac_t *mac = (ag7240_mac_t *)dev->priv;
\r
72 ag7240_desc_t *f = mac->fifo_tx[mac->next_tx];
\r
74 f->pkt_size = length;
\r
76 f->pkt_start_addr = virt_to_phys(packet);
\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
83 for(i = 0; i < MAX_WAIT; i++){
\r
85 if(!ag7240_tx_owned_by_dma(f)){
\r
90 f->pkt_start_addr = 0;
\r
93 if(++mac->next_tx >= NO_OF_TX_FIFOS){
\r
100 static int ag7240_recv(struct eth_device *dev){
\r
105 mac = (ag7240_mac_t *)dev->priv;
\r
108 f = mac->fifo_rx[mac->next_rx];
\r
109 if(ag7240_rx_owned_by_dma(f)){
\r
113 length = f->pkt_size;
\r
115 NetReceive(NetRxPackets[mac->next_rx] , length - 4);
\r
116 flush_cache((u32)NetRxPackets[mac->next_rx] , PKTSIZE_ALIGN);
\r
118 ag7240_rx_give_to_dma(f);
\r
120 if(++mac->next_rx >= NO_OF_RX_FIFOS)
\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
133 * Called in ag7240_hw_start() function
\r
135 void ag7240_mii_setup(ag7240_mac_t *mac){
\r
137 u32 cpu_freq,ddr_freq,ahb_freq;
\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
145 ar7240_reg_wr(AR934X_SWITCH_CLOCK_SPARE, 0x570);
\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
153 //printf("WASP ----> S17 PHY *\n");
\r
157 if(mac->mac_unit == 0){
\r
158 ar7240_reg_wr(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0);
\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
170 #ifdef CFG_ATHRS27_PHY
\r
172 //printf("WASP ----> S27 PHY \n");
\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
180 #ifdef CONFIG_F2E_PHY
\r
182 //printf("WASP ----> F2 PHY *\n");
\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
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
193 #if defined(CONFIG_F1E_PHY) || defined(CONFIG_VIR_PHY)
\r
195 #ifdef CONFIG_VIR_PHY
\r
196 //printf("WASP ----> VIR PHY *\n");
\r
198 //printf("WASP ----> F1 PHY *\n");
\r
200 if(mac->mac_unit == 0){
\r
201 ar7240_reg_wr(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0);
\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
213 if((ar7240_reg_rd(AR7240_REV_ID) & AR7240_REV_ID_MASK) == AR7240_REV_1_2){
\r
214 mgmt_cfg_val = 0x2;
\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
221 ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq);
\r
224 switch(ahb_freq/1000000){
\r
226 mgmt_cfg_val = 0x7;
\r
229 mgmt_cfg_val = 0x5;
\r
232 mgmt_cfg_val = 0x4;
\r
235 mgmt_cfg_val = 0x9;
\r
238 mgmt_cfg_val = 0x9;
\r
241 mgmt_cfg_val = 0x7;
\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
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
263 if(mac->mac_unit == 1){
\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
275 //if(check_cnt == 11)
\r
276 //printf("%s: MDC check failed\n", __func__);
\r
278 } else { /* Python 1.0 & 1.1 */
\r
279 if(mac->mac_unit == 0){
\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
292 //if(check_cnt == 11)
\r
293 //printf("%s: MDC check failed\n", __func__);
\r
299 static void ag7240_hw_start(ag7240_mac_t *mac){
\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
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
309 ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_0, 0x1f00);
\r
310 ag7240_mii_setup(mac);
\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
315 ag7240_reg_rmw_set(mac, AG7240_MAC_FIFO_CFG_4, 0x3ffff);
\r
317 // TODO: check this register
\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
322 ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_5, 0x66b82);
\r
324 * Setting Drop CRC Errors, Pause Frames,Length Error frames
\r
325 * and Multi/Broad cast frames.
\r
327 //ag7240_reg_wr(mac, AG7240_MAC_FIFO_CFG_5, 0x7eccf);
\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
333 static int ag7240_check_link(ag7240_mac_t *mac){
\r
334 int link = 0, duplex = 0, speed = 0;
\r
337 s = getenv("stdin");
\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
346 if((s != NULL) && (strcmp(s, "nc") != 0)){
\r
347 printf("Link down: %s\n", mac->dev->name);
\r
354 ag7240_set_mac_if(mac, 1);
\r
355 ag7240_reg_rmw_set(mac, AG7240_MAC_FIFO_CFG_5, (1 << 19));
\r
357 if(is_ar7242() && (mac->mac_unit == 0)){
\r
358 ar7240_reg_wr(AR7242_ETH_XMII_CONFIG, 0x1c000000);
\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
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
370 if(is_wasp() && (mac->mac_unit == 0) && !is_f2e()){
\r
371 ar7240_reg_wr(AR7242_ETH_XMII_CONFIG, 0x06000000);
\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
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
385 if((is_ar7242() || is_wasp()) && (mac->mac_unit == 0) && !is_f2e()){
\r
386 ar7240_reg_wr(AR7242_ETH_XMII_CONFIG, 0x0101);
\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
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
400 if((is_ar7242() || is_wasp()) && (mac->mac_unit == 0) && !is_f2e()){
\r
401 ar7240_reg_wr(AR7242_ETH_XMII_CONFIG,0x1616);
\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
410 ar7240_reg_rmw_clear(AG7240_ETH_CFG, AG7240_ETH_CFG_RMII_HISPD_GE0);
\r
415 if((s != NULL) && (strcmp(s, "nc") != 0)){
\r
416 printf("## Error: invalid speed detected\n");
\r
421 if(mac->link && (duplex == mac->duplex) && (speed == mac->speed)){
\r
425 mac->duplex = duplex;
\r
426 mac->speed = speed;
\r
428 if((s != NULL) && (strcmp(s, "nc") != 0)){
\r
429 printf("Ethernet mode (duplex/speed): %d/%d Mbps\n", duplex, speed);
\r
432 ag7240_set_mac_duplex(mac, duplex);
\r
438 * For every command we re-setup the ring and start with clean h/w rx state
\r
440 static int ag7240_clean_rx(struct eth_device *dev, bd_t * bd){
\r
443 ag7240_mac_t *mac = (ag7240_mac_t*)dev->priv;
\r
445 if(!ag7240_check_link(mac)){
\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
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
461 udelay(1000 * 1000);
\r
465 static int ag7240_alloc_fifo(int ndesc, ag7240_desc_t ** fifo){
\r
470 size = sizeof(ag7240_desc_t) * ndesc;
\r
471 size += CFG_CACHELINE_SIZE - 1;
\r
473 if((p = malloc(size)) == NULL){
\r
474 printf("## Error: cant allocate fifos\n");
\r
478 p = (uchar *)(((u32)p + CFG_CACHELINE_SIZE - 1) & ~(CFG_CACHELINE_SIZE - 1));
\r
479 p = UNCACHED_SDRAM(p);
\r
481 for(i = 0; i < ndesc; i++){
\r
482 fifo[i] = (ag7240_desc_t *)p + i;
\r
488 static int ag7240_setup_fifos(ag7240_mac_t *mac){
\r
491 if(ag7240_alloc_fifo(NO_OF_TX_FIFOS, mac->fifo_tx)){
\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
500 if(ag7240_alloc_fifo(NO_OF_RX_FIFOS, mac->fifo_rx)){
\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
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
518 * Get MAC address stored in flash
\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
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
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
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
542 // 00-03-7F (Atheros Communications, Inc.)
\r
550 printf("## Error: MAC address in FLASH is invalid, using fixed!\n");
553 // 00-03-7F (Atheros Communications, Inc.)
\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
568 //printf("ag934x_enet_initialize...\n");
\r
571 if(is_ar933x() && (ar7240_reg_rd(AR7240_RESET)!=0)){
\r
572 ar7240_reg_wr(AR7240_RESET,0);
\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
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
585 if((ag7240_macs[i] = (ag7240_mac_t *)malloc(sizeof(ag7240_mac_t))) == NULL){
\r
586 //puts("malloc failed\n");
\r
590 memset(ag7240_macs[i], 0, sizeof(ag7240_macs[i]));
\r
591 memset(dev[i], 0, sizeof(dev[i]));
\r
593 sprintf(dev[i]->name, "eth%d", i);
\r
594 ag7240_get_ethaddr(dev[i]);
\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
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
608 for(i = 0;i < CFG_AG7240_NMACS;i++){
\r
609 eth_register(dev[i]);
\r
611 #if(CONFIG_COMMANDS & CFG_CMD_MII)
\r
612 miiphy_register(dev[i]->name, ag7240_miiphy_read, ag7240_miiphy_write);
\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
618 mask = (AR7240_RESET_GE0_MAC | AR7240_RESET_GE0_PHY | AR7240_RESET_GE1_MAC | AR7240_RESET_GE1_PHY);
\r
620 if(is_ar7241() || is_ar7242() || is_wasp()){
\r
621 mask = mask | AR7240_RESET_GE0_MDIO | AR7240_RESET_GE1_MDIO;
\r
624 //printf(" wasp reset mask:%x \n",mask);
\r
626 ar7240_reg_rmw_set(AR7240_RESET, mask);
\r
627 udelay(1000 * 100);
\r
629 ar7240_reg_rmw_clear(AR7240_RESET, mask);
\r
630 udelay(1000 * 100);
\r
635 ag7240_hw_start(ag7240_macs[i]);
\r
636 ag7240_setup_fifos(ag7240_macs[i]);
\r
638 udelay(100 * 1000);
\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
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
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
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
658 #ifdef CFG_ATHRS17_PHY
\r
659 athrs17_reg_init();
\r
662 #ifdef CFG_ATHRS26_PHY
\r
663 athrs26_reg_init();
\r
666 #ifdef CFG_ATHRS27_PHY
\r
667 //printf("s27 reg init \n");
\r
668 athrs27_reg_init();
\r
671 #ifdef CONFIG_F1E_PHY
\r
672 //printf("F1Phy reg init \n");
\r
676 #ifdef CONFIG_VIR_PHY
\r
677 //printf("VIRPhy reg init \n");
\r
678 athr_vir_reg_init();
\r
681 #ifdef CONFIG_F2E_PHY
\r
682 //printf("F2Phy reg init \n");
\r
688 #ifdef CFG_ATHRS26_PHY
\r
689 athrs26_reg_init_lan();
\r
692 #ifdef CFG_ATHRS27_PHY
\r
693 //printf("s27 reg init lan \n");
\r
694 athrs27_reg_init_lan();
\r
698 ag7240_phy_setup(ag7240_macs[i]->mac_unit);
\r
699 //printf("%s up\n",dev[i]->name);
\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
712 * Check for previous transactions are complete. Added to avoid
\r
713 * race condition while running at higher frequencies.
\r
717 rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1;
\r
718 } while(rddata && --ii);
\r
721 //printf("ERROR:%s:%d transaction failed\n",__func__,__LINE__);
\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
729 rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1;
\r
730 } while(rddata && --ii);
\r
733 //printf("Error!!! Leave ag7240_miiphy_read without polling correct status!\n");
\r
735 val = ag7240_reg_rd(mac, AG7240_MII_MGMT_STATUS);
\r
736 ag7240_reg_wr(mac, AG7240_MII_MGMT_CMD, 0x0);
\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
748 * Check for previous transactions are complete. Added to avoid
\r
749 * race condition while running at higher frequencies.
\r
753 rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1;
\r
754 } while(rddata && --ii);
\r
757 //printf("ERROR:%s:%d transaction failed\n",__func__,__LINE__);
\r
759 ag7240_reg_wr(mac, AG7240_MII_MGMT_ADDRESS, addr);
\r
760 ag7240_reg_wr(mac, AG7240_MII_MGMT_CTRL, data);
\r
763 rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1;
\r
764 } while(rddata && --ii);
\r