static void ag7240_get_ethaddr(struct eth_device *dev) { unsigned char *eeprom; unsigned char *mac = dev->enetaddr; #ifndef CONFIG_AR7240_EMU #ifdef CONFIG_ATH_NAND_BR unsigned char sectorBuff[ATH_ETH_MAC_READ_SIZE]; eeprom = ath_eth_mac_addr(sectorBuff); if(eeprom == NULL) { /* mac address will be set to default mac address */ mac[0] = 0xff; } else { #else /* CONFIG_ATH_NAND_BR */ eeprom = ag7240_mac_addr_loc(); #endif /* CONFIG_ATH_NAND_BR */ if (strcmp(dev->name, "eth0") == 0) { memcpy(mac, eeprom, 6); } else if (strcmp(dev->name, "eth1") == 0) { eeprom += 6; memcpy(mac, eeprom, 6); } else { printf("%s: unknown ethernet device %s\n", __func__, dev->name); return; } #ifdef CONFIG_ATH_NAND_BR } #endif /* CONFIG_ATH_NAND_BR */ /* Use fixed address if the above address is invalid */ if (mac[0] != 0x00 || (mac[0] == 0xff && mac[5] == 0xff)) { #else if (1) { #endif mac[0] = 0x00; mac[1] = 0x03; mac[2] = 0x7f; mac[3] = 0x09; mac[4] = 0x0b; mac[5] = 0xad; printf("No valid address in Flash. Using fixed address\n"); } else { printf("Fetching MAC Address from 0x%p\n", __func__, eeprom); } } int ag7240_enet_initialize(bd_t * bis) { struct eth_device *dev[CFG_AG7240_NMACS]; u32 mask, mac_h, mac_l; int i; printf("ag934x_enet_initialize...\n"); if(is_ar933x() && (ar7240_reg_rd(AR7240_RESET)!=0)) ar7240_reg_wr(AR7240_RESET,0); if(is_ar933x()) //Turn on LED ar7240_reg_wr(AR7240_GPIO_BASE + 0x28 , ar7240_reg_rd(AR7240_GPIO_BASE + 0x28) | (0xF8)); for (i = 0; i < CFG_AG7240_NMACS; i++) { if ((dev[i] = (struct eth_device *) malloc(sizeof (struct eth_device))) == NULL) { puts("malloc failed\n"); return 0; } if ((ag7240_macs[i] = (ag7240_mac_t *) malloc(sizeof (ag7240_mac_t))) == NULL) { puts("malloc failed\n"); return 0; } memset(ag7240_macs[i], 0, sizeof(ag7240_macs[i])); memset(dev[i], 0, sizeof(dev[i])); sprintf(dev[i]->name, "eth%d", i); ag7240_get_ethaddr(dev[i]); ag7240_macs[i]->mac_unit = i; ag7240_macs[i]->mac_base = i ? AR7240_GE1_BASE : AR7240_GE0_BASE ; ag7240_macs[i]->dev = dev[i]; dev[i]->iobase = 0; dev[i]->init = ag7240_clean_rx; dev[i]->halt = ag7240_halt; dev[i]->send = ag7240_send; dev[i]->recv = ag7240_recv; dev[i]->priv = (void *)ag7240_macs[i]; } #if !defined(CONFIG_ATH_NAND_BR) mask = AR7240_RESET_GE1_PHY; ar7240_reg_rmw_set(AR7240_RESET, mask); udelay(1000 * 100); ar7240_reg_rmw_clear(AR7240_RESET, mask); udelay(100); #endif mask = AR7240_RESET_GE0_PHY; ar7240_reg_rmw_set(AR7240_RESET, mask); udelay(1000 * 100); ar7240_reg_rmw_clear(AR7240_RESET, mask); udelay(100); for (i = 0; i < CFG_AG7240_NMACS; i++) { eth_register(dev[i]); #if(CONFIG_COMMANDS & CFG_CMD_MII) miiphy_register(dev[i]->name, ag7240_miiphy_read, ag7240_miiphy_write); #endif 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); if(!i) { mask = (AR7240_RESET_GE0_MAC | AR7240_RESET_GE1_MAC); if (is_ar7241() || is_ar7242() || is_wasp()) mask = mask | AR7240_RESET_GE0_MDIO | AR7240_RESET_GE1_MDIO; printf(" wasp reset mask:%x \n",mask); ar7240_reg_rmw_set(AR7240_RESET, mask); udelay(1000 * 100); ar7240_reg_rmw_clear(AR7240_RESET, mask); udelay(1000 * 100); udelay(10 * 1000); } ag7240_mii_setup(ag7240_macs[i]); /* if using header for register configuration, we have to */ /* configure s26 register after frame transmission is enabled */ if (ag7240_macs[i]->mac_unit == 0) { /* WAN Phy */ #ifdef CONFIG_AR7242_S16_PHY if (is_ar7242() || is_wasp()) { athrs16_reg_init(); } else #endif { #ifdef CONFIG_ATHRS17_PHY athrs17_reg_init(); #endif #ifdef CFG_ATHRS26_PHY athrs26_reg_init(); #endif #ifdef CFG_ATHRS27_PHY printf("s27 reg init \n"); athrs27_reg_init(); #endif #ifdef CONFIG_F1E_PHY printf("F1Phy reg init \n"); athr_reg_init(); #endif #ifdef CONFIG_VIR_PHY printf("VIRPhy reg init \n"); athr_vir_reg_init(); #endif #ifdef CONFIG_F2E_PHY printf("F2Phy reg init \n"); athr_reg_init(); #endif } } else { #ifdef CFG_ATHRS26_PHY athrs26_reg_init_lan(); #endif #ifdef CFG_ATHRS27_PHY printf("s27 reg init lan \n"); athrs27_reg_init_lan(); #endif } ag7240_hw_start(ag7240_macs[i]); ag7240_setup_fifos(ag7240_macs[i]); udelay(100 * 1000); { unsigned char *mac = dev[i]->enetaddr; 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); } mac_l = (dev[i]->enetaddr[4] << 8) | (dev[i]->enetaddr[5]); mac_h = (dev[i]->enetaddr[0] << 24) | (dev[i]->enetaddr[1] << 16) | (dev[i]->enetaddr[2] << 8) | (dev[i]->enetaddr[3] << 0); ag7240_reg_wr(ag7240_macs[i], AG7240_GE_MAC_ADDR1, mac_l); ag7240_reg_wr(ag7240_macs[i], AG7240_GE_MAC_ADDR2, mac_h); ag7240_phy_setup(ag7240_macs[i]->mac_unit); printf("%s up\n",dev[i]->name); } return 1; } #if (CONFIG_COMMANDS & CFG_CMD_MII) int ag7240_miiphy_read(char *devname, uint32_t phy_addr, uint8_t reg, uint16_t *data) { ag7240_mac_t *mac = ag7240_name2mac(devname); uint16_t addr = (phy_addr << AG7240_ADDR_SHIFT) | reg, val; volatile int rddata; uint16_t ii = 0xFFFF; /* * Check for previous transactions are complete. Added to avoid * race condition while running at higher frequencies. */ do { udelay(5); rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1; } while(rddata && --ii); if (ii == 0) printf("ERROR:%s:%d transaction failed\n",__func__,__LINE__); ag7240_reg_wr(mac, AG7240_MII_MGMT_CMD, 0x0); ag7240_reg_wr(mac, AG7240_MII_MGMT_ADDRESS, addr); ag7240_reg_wr(mac, AG7240_MII_MGMT_CMD, AG7240_MGMT_CMD_READ); do { udelay(5); rddata = ag7240_reg_rd(mac, AG7240_MII_MGMT_IND) & 0x1; } while(rddata && --ii); if(ii==0) printf("Error!!! Leave ag7240_miiphy_read without polling correct status!\n"); val = ag7240_reg_rd(mac, AG7240_MII_MGMT_STATUS); ag7240_reg_wr(mac, AG7240_MII_MGMT_CMD, 0x0); if(data != NULL) *data = val; return val; }
int ag7240_enet_initialize(bd_t * bis){ struct eth_device *dev[CFG_AG7240_NMACS]; u32 mask, mac_h, mac_l; int i; //printf("ag934x_enet_initialize...\n"); /* if(is_ar933x() && (ar7240_reg_rd(AR7240_RESET)!=0)){ ar7240_reg_wr(AR7240_RESET,0); } if(is_ar933x()) //Turn on LED ar7240_reg_wr(AR7240_GPIO_BASE + 0x28 , ar7240_reg_rd(AR7240_GPIO_BASE + 0x28) | (0xF8)); */ for(i = 0;i < CFG_AG7240_NMACS;i++){ if((dev[i] = (struct eth_device *)malloc(sizeof(struct eth_device))) == NULL){ //puts("malloc failed\n"); return(0); } if((ag7240_macs[i] = (ag7240_mac_t *)malloc(sizeof(ag7240_mac_t))) == NULL){ //puts("malloc failed\n"); return(0); } memset(ag7240_macs[i], 0, sizeof(ag7240_macs[i])); memset(dev[i], 0, sizeof(dev[i])); sprintf(dev[i]->name, "eth%d", i); ag7240_get_ethaddr(dev[i]); ag7240_macs[i]->mac_unit = i; ag7240_macs[i]->mac_base = i ? AR7240_GE1_BASE : AR7240_GE0_BASE ; ag7240_macs[i]->dev = dev[i]; dev[i]->iobase = 0; dev[i]->init = ag7240_clean_rx; dev[i]->halt = ag7240_halt; dev[i]->send = ag7240_send; dev[i]->recv = ag7240_recv; dev[i]->priv = (void *)ag7240_macs[i]; } for(i = 0;i < CFG_AG7240_NMACS;i++){ eth_register(dev[i]); #if(CONFIG_COMMANDS & CFG_CMD_MII) miiphy_register(dev[i]->name, ag7240_miiphy_read, ag7240_miiphy_write); #endif 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); if(!i){ mask = (AR7240_RESET_GE0_MAC | AR7240_RESET_GE0_PHY | AR7240_RESET_GE1_MAC | AR7240_RESET_GE1_PHY); if(is_ar7241() || is_ar7242() || is_wasp()){ mask = mask | AR7240_RESET_GE0_MDIO | AR7240_RESET_GE1_MDIO; } //printf(" wasp reset mask:%x \n",mask); ar7240_reg_rmw_set(AR7240_RESET, mask); udelay(1000 * 100); ar7240_reg_rmw_clear(AR7240_RESET, mask); udelay(1000 * 100); udelay(10 * 1000); } ag7240_hw_start(ag7240_macs[i]); ag7240_setup_fifos(ag7240_macs[i]); udelay(100 * 1000); //unsigned char *mac = dev[i]->enetaddr; //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); mac_l = (dev[i]->enetaddr[4] << 8) | (dev[i]->enetaddr[5]); mac_h = (dev[i]->enetaddr[0] << 24) | (dev[i]->enetaddr[1] << 16) | (dev[i]->enetaddr[2] << 8) | (dev[i]->enetaddr[3] << 0); ag7240_reg_wr(ag7240_macs[i], AG7240_GE_MAC_ADDR1, mac_l); ag7240_reg_wr(ag7240_macs[i], AG7240_GE_MAC_ADDR2, mac_h); /* if using header for register configuration, we have to */ /* configure s26 register after frame transmission is enabled */ if(ag7240_macs[i]->mac_unit == 0){ /* WAN Phy */ #ifdef CONFIG_AR7242_S16_PHY if(is_ar7242() || is_wasp()){ athrs16_reg_init(); } else #endif { #ifdef CFG_ATHRS17_PHY athrs17_reg_init(); #endif #ifdef CFG_ATHRS26_PHY athrs26_reg_init(); #endif #ifdef CFG_ATHRS27_PHY //printf("s27 reg init \n"); athrs27_reg_init(); #endif #ifdef CONFIG_F1E_PHY //printf("F1Phy reg init \n"); athr_reg_init(); #endif #ifdef CONFIG_VIR_PHY //printf("VIRPhy reg init \n"); athr_vir_reg_init(); #endif #ifdef CONFIG_F2E_PHY //printf("F2Phy reg init \n"); athr_reg_init(); #endif } } else { #ifdef CFG_ATHRS26_PHY athrs26_reg_init_lan(); #endif #ifdef CFG_ATHRS27_PHY //printf("s27 reg init lan \n"); athrs27_reg_init_lan(); #endif } ag7240_phy_setup(ag7240_macs[i]->mac_unit); //printf("%s up\n",dev[i]->name); } return(1); }