void config_vlan(void) { UINT32 phyBase; UINT32 phyAddr; UINT32 reg = 0; int phyUnit; /* * Set PVID for the ports, Port 0-3 are LAN ports and * Port 4 is WAN Port */ for (phyUnit = 0; phyUnit < ADM_PHY_MAX; phyUnit++) { phyAddr = ADM_CONFIG_REG(phyUnit) / ADM_PHY_BASE_REG_NUM; reg = getPhy(phyAddr, ADM_CONFIG_REG(phyUnit)); if (ADM_IS_LAN_PORT(phyUnit)) { reg = ADM_SW_LAN_PORT_CONFIG; } else if (ADM_IS_WAN_PORT(phyUnit)) { reg = ADM_SW_WAN_PORT_CONFIG; } else { reg |= ADM_SW_OUT_PKT_TAG_EN; } setPhy(phyAddr, ADM_CONFIG_REG(phyUnit), reg); } /* * Set up the port memberships for the VLAN Groups 1 and 2 */ phyAddr = (ADM_SW_VLAN_MAP_REG + ADM_LAN_PORT_VLAN) / ADM_PHY_BASE_REG_NUM; setPhy(phyAddr, (ADM_SW_VLAN_MAP_REG + ADM_LAN_PORT_VLAN), ADM_SW_LAN_MAP_TAB); phyAddr = (ADM_SW_VLAN_MAP_REG + ADM_WAN_PORT_VLAN) / ADM_PHY_BASE_REG_NUM; setPhy(phyAddr, (ADM_SW_VLAN_MAP_REG + ADM_WAN_PORT_VLAN), ADM_SW_WAN_MAP_TAB); /* * Put the chip in 802.1q mode */ phyAddr = ADM_SW_VLAN_MODE_REG / ADM_PHY_BASE_REG_NUM; #if defined(HAVE_ADMTEKNESTEDVLAN) setPhy(phyAddr, ADM_SW_VLAN_MODE_REG, (ADM_SW_MAC_CLONE_EN | ADM_SW_SIZE_SEL)); #else setPhy(phyAddr, ADM_SW_VLAN_MODE_REG, (ADM_SW_MAC_CLONE_EN | ADM_SW_VLAN_MODE_SEL)); #endif }
static void adm_verifyReady(int ethUnit) { UINT32 phyBase = 0; UINT16 phyID1; UINT16 phyID2; phyID1 = getPhy(0x5, 0x0); phyID2 = getPhy(0x5, 0x1); if (((phyID1 & 0xfff0) == ADM_CHIP_ID1_EXPECTATION) && (phyID2 == ADM_CHIP_ID2_EXPECTATION)) { fprintf(stderr, "Found ADM6996FC! PHYID1 is 0x%x, PHYID2 is 0x%x\n", phyID1, phyID2); } else { fprintf(stderr, "Couldn't find ADM6996FC!\n, PHYID1 is 0x%x, PHYID2 is 0x%x\n", phyID1, phyID2); } }
int adm_phyIsLinkAlive(int phyUnit) { unsigned short phyHwStatus; unsigned int phyBase; unsigned int phyAddr; phyAddr = ADM_PHYADDR(phyUnit); phyHwStatus = getPhy(phyAddr, ADM_PHY_STATUS); if (phyHwStatus & ADM_STATUS_LINK_PASS) { return TRUE; } else { return FALSE; } }
void vlan_init(int numports) { int phyUnit; UINT16 phyHwStatus; UINT16 timeout; int liveLinks = 0; UINT32 phyBase = 0; BOOL foundPhy = FALSE; UINT32 phyAddr; UINT32 reg = 0; /* * Reset PHYs */ for (phyUnit = 0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, 0)) { continue; } phyAddr = ADM_PHYADDR(phyUnit); setPhy(phyAddr, ADM_PHY_CONTROL, ADM_CTRL_SOFTWARE_RESET); } /* * After the phy is reset, it takes a little while before * it can respond properly. */ sleep(1); /* * Verify that the switch is what we think it is, and that it's ready */ adm_verifyReady(0); /* * LAN SETTING: enable Auto-MDIX */ phyAddr = ADM_SW_PHY_PORT0_REG / ADM_PHY_BASE_REG_NUM; reg = getPhy(phyAddr, ADM_SW_PHY_PORT0_REG); reg |= ADM_SW_AUTO_MDIX_EN; setPhy(phyAddr, ADM_SW_PHY_PORT0_REG, reg); phyAddr = ADM_SW_PHY_PORT1_REG / ADM_PHY_BASE_REG_NUM; reg = getPhy(phyAddr, ADM_SW_PHY_PORT1_REG); reg |= ADM_SW_AUTO_MDIX_EN; setPhy(phyAddr, ADM_SW_PHY_PORT1_REG, reg); phyAddr = ADM_SW_PHY_PORT2_REG / ADM_PHY_BASE_REG_NUM; getPhy(phyAddr, ADM_SW_PHY_PORT2_REG); reg |= ADM_SW_AUTO_MDIX_EN; setPhy(phyAddr, ADM_SW_PHY_PORT2_REG, reg); phyAddr = ADM_SW_PHY_PORT3_REG / ADM_PHY_BASE_REG_NUM; reg = getPhy(phyAddr, ADM_SW_PHY_PORT3_REG); reg |= ADM_SW_AUTO_MDIX_EN; setPhy(phyAddr, ADM_SW_PHY_PORT3_REG, reg); phyAddr = ADM_SW_PHY_PORT4_REG / ADM_PHY_BASE_REG_NUM; reg = getPhy(phyAddr, ADM_SW_PHY_PORT4_REG); reg |= ADM_SW_AUTO_MDIX_EN; setPhy(phyAddr, ADM_SW_PHY_PORT4_REG, reg); phyAddr = ADM_SW_PHY_PORT5_REG / ADM_PHY_BASE_REG_NUM; reg = getPhy(phyAddr, ADM_SW_PHY_PORT5_REG); reg |= ADM_SW_AUTO_MDIX_EN; setPhy(phyAddr, ADM_SW_PHY_PORT5_REG, reg); /* * See if there's any configuration data for this enet */ for (phyUnit = 0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (ADM_ETHUNIT(phyUnit) != 0) { continue; } foundPhy = TRUE; break; } if (!foundPhy) { return FALSE; /* No PHY's configured for this ethUnit */ } /* * start auto negogiation on each phy */ for (phyUnit = 0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, 0)) { continue; } phyAddr = ADM_PHYADDR(phyUnit); setPhy(phyAddr, ADM_AUTONEG_ADVERT, ADM_ADVERTISE_ALL); setPhy(phyAddr, ADM_PHY_CONTROL, ADM_CTRL_AUTONEGOTIATION_ENABLE | ADM_CTRL_START_AUTONEGOTIATION); } /* * Wait up to .75 seconds for ALL associated PHYs to finish * autonegotiation. The only way we get out of here sooner is * if ALL PHYs are connected AND finish autonegotiation. */ timeout = 15; for (phyUnit = 0; (phyUnit < ADM_PHY_MAX) /* && (timeout > 0) */ ; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, 0)) { continue; } for (;;) { phyAddr = ADM_PHYADDR(phyUnit); phyHwStatus = getPhy(phyAddr, ADM_PHY_STATUS); if (ADM_AUTONEG_DONE(phyHwStatus)) { fprintf(stderr, "Port %d, Negotiation Success\n", phyUnit); break; } if (timeout == 0) { fprintf(stderr, "Port %d, Negotiation timeout\n", phyUnit); break; } if (--timeout == 0) { fprintf(stderr, "Port %d, Negotiation timeout\n", phyUnit); break; } usleep(75); } } /* * All PHYs have had adequate time to autonegotiate. * Now initialize software status. * * It's possible that some ports may take a bit longer * to autonegotiate; but we can't wait forever. They'll * get noticed by mv_phyCheckStatusChange during regular * polling activities. */ for (phyUnit = 0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (adm_phyIsLinkAlive(phyUnit)) { liveLinks++; ADM_IS_PHY_ALIVE(phyUnit) = TRUE; } else { ADM_IS_PHY_ALIVE(phyUnit) = FALSE; } fprintf(stderr, "adm_phySetup: eth%d phy%d: Phy Status=%4.4x\n", 0, phyUnit, getPhy(ADM_PHYADDR(phyUnit), ADM_PHY_STATUS)); } config_vlan(); eval("vconfig", "set_name_type", "VLAN_PLUS_VID_NO_PAD"); eval("vconfig", "add", "eth0", "1"); eval("vconfig", "add", "eth0", "2"); struct ifreq ifr; int s; if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) { char eabuf[32]; strncpy(ifr.ifr_name, "eth0", IFNAMSIZ); ioctl(s, SIOCGIFHWADDR, &ifr); char macaddr[32]; strcpy(macaddr, ether_etoa((unsigned char *)ifr.ifr_hwaddr.sa_data, eabuf)); nvram_set("et0macaddr", macaddr); MAC_ADD(macaddr); ether_atoe(macaddr, (unsigned char *)ifr.ifr_hwaddr.sa_data); strncpy(ifr.ifr_name, "vlan2", IFNAMSIZ); ioctl(s, SIOCSIFHWADDR, &ifr); close(s); } }
void vlan_init(int portmask) { int phyUnit; unsigned int phyBase; unsigned int phyReg; unsigned int phyAddr; int i; int numports = 5; for (i = 0; i < numports - 1; i++) // last one will be wan port { ipPhyInfo[i].VLANTableSetting = IP_LAN_PORT_VLAN; } ipPhyInfo[i++].VLANTableSetting = IP_WAN_PORT_VLAN; ipPhyInfo[i].VLANTableSetting = IP_LAN_PORT_VLAN; ipPhyInfo[i].isEnetPort = FALSE; ipPhyInfo[i].isPhyAlive = TRUE; ipPhyInfo[i++].phyAddr = 0x0; numports = i; fprintf(stderr, "Reset ICPLUS Phy\n"); for (phyUnit = 0; phyUnit < numports; phyUnit++) { if (((1 << phyUnit) & portmask)) { phyAddr = IP_PHYADDR(phyUnit); setPhy(phyAddr, IP_PHY_CONTROL, IP_CTRL_SOFTWARE_RESET); } } sleep(1); fprintf(stderr, "Start Autonegotiation\n"); for (phyUnit = 0; phyUnit < numports; phyUnit++) { if (((1 << phyUnit) & portmask)) { phyAddr = IP_PHYADDR(phyUnit); setPhy(phyAddr, IP_AUTONEG_ADVERT, IP_ADVERTISE_ALL); setPhy(phyAddr, IP_PHY_CONTROL, IP_CTRL_AUTONEGOTIATION_ENABLE | IP_CTRL_START_AUTONEGOTIATION); } } int timeout = 5; for (phyUnit = 0; (phyUnit < numports); phyUnit++) { if (((1 << phyUnit) & portmask)) { for (;;) { phyAddr = IP_PHYADDR(phyUnit); int phyHwStatus = getPhy(phyAddr, IP_PHY_STATUS); if (IP_AUTONEG_DONE(phyHwStatus)) { fprintf(stderr, "Port %d, Neg Success\n", phyUnit); break; } if (timeout == 0) { fprintf(stderr, "Port %d, Negogiation timeout\n", phyUnit); break; } if (--timeout == 0) { fprintf(stderr, "Port %d, Negogiation timeout\n", phyUnit); break; } usleep(150); } } } fprintf(stderr, "Setup VLANS\n"); /* * setPhy(29,24,0); setPhy(29,25,0); setPhy(29,26,0); setPhy(29,27,0); * setPhy(29,28,2); setPhy(29,30,0); setPhy(29,23,0x07c2); * setPhy(30,1,0x002f); setPhy(30,2,0x0030); setPhy(30,9,0x1089); */ unsigned int phy1Reg = 0; unsigned int phy2Reg = 0; unsigned int phy23Reg = 0; unsigned int phy9Reg = 0; for (phyUnit = 0; phyUnit < numports; phyUnit++) { if (((1 << phyUnit) & portmask)) { setPhy(IP_GLOBAL_PHY29_ADDR, IP_GLOBAL_PHY29_24_REG + ((phyUnit == 5) ? (phyUnit + 1) : phyUnit), IP_VLAN_TABLE_SETTING(phyUnit)); fprintf(stderr, "write register %d, addr %d with %X\n", IP_GLOBAL_PHY29_ADDR, IP_GLOBAL_PHY29_24_REG + ((phyUnit == 5) ? (phyUnit + 1) : phyUnit), IP_VLAN_TABLE_SETTING(phyUnit)); if (IP_IS_ENET_PORT(phyUnit)) { if (IP_IS_WAN_PORT(phyUnit)) { phy2Reg |= ((1 << phyUnit) << IP_VLAN2_OUTPUT_PORT_MASK_S); } else { phy1Reg |= ((1 << phyUnit) << IP_VLAN0_OUTPUT_PORT_MASK_S); } phy23Reg = phy23Reg | ((1 << phyUnit) << IP_PORTX_REMOVE_TAG_S); phy23Reg = phy23Reg & ~((1 << phyUnit) << IP_PORTX_ADD_TAG_S); } else { phy1Reg |= ((1 << phyUnit) << IP_VLAN0_OUTPUT_PORT_MASK_S); phy2Reg |= ((1 << phyUnit) << IP_VLAN2_OUTPUT_PORT_MASK_S); phy23Reg = phy23Reg | (1 << IP_PORT5_ADD_TAG_S); phy23Reg = phy23Reg & ~(1 << IP_PORT5_REMOVE_TAG_S); } } } phy9Reg = 0; //getPhy(IP_GLOBAL_PHY30_ADDR,IP_GLOBAL_PHY30_9_REG); phy9Reg = phy9Reg | TAG_VLAN_ENABLE; phy9Reg = phy9Reg & ~VID_INDX_SEL_M; phy9Reg = phy9Reg | 1; //1 vlan group used for lan phy9Reg = phy9Reg | 1 << 3; //enable smart mac phy9Reg = phy9Reg | 1 << 12; //port 4 is a wan port (required for smart mac) fprintf(stderr, "write register %d, addr %d with %X\n", IP_GLOBAL_PHY29_ADDR, IP_GLOBAL_PHY29_23_REG, phy23Reg); fprintf(stderr, "write register %d, addr %d with %X\n", IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG, phy1Reg); fprintf(stderr, "write register %d, addr %d with %X\n", IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_2_REG, phy2Reg); fprintf(stderr, "write register %d, addr %d with %X\n", IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG, phy9Reg); setPhy(IP_GLOBAL_PHY29_ADDR, IP_GLOBAL_PHY29_23_REG, phy23Reg); setPhy(IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG, phy1Reg); setPhy(IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_2_REG, phy2Reg); setPhy(IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG, phy9Reg); // // echo "echo \"WRITE 29 23 07c2\" > ".$mii_dev."\n"; // // echo "echo \"WRITE 29 24 0\" > ".$mii_dev."\n"; /* PORT0 Default VLAN ID */ // echo "echo \"WRITE 29 25 0\" > ".$mii_dev."\n"; /* PORT1 Default VLAN ID */ // echo "echo \"WRITE 29 26 0\" > ".$mii_dev."\n"; /* PORT2 Default VLAN ID */ // echo "echo \"WRITE 29 27 0\" > ".$mii_dev."\n"; /* PORT3 Default VLAN ID */ // echo "echo \"WRITE 29 28 2\" > ".$mii_dev."\n"; /* PORT4 Default VLAN ID */ // echo "echo \"WRITE 29 30 0\" > ".$mii_dev."\n"; /* PORT5 Default VLAN ID (CPU) */ // echo "echo \"WRITE 29 23 07c2\" > ".$mii_dev."\n"; // echo "echo \"WRITE 30 1 002f\" > ".$mii_dev."\n"; /* Port 5,3,2,1,0 = VLAN 0 */ // echo "echo \"WRITE 30 2 0030\" > ".$mii_dev."\n"; /* Port 5,4 = VLAN 2 */ // echo "echo \"WRITE 30 9 1089\" > ".$mii_dev."\n"; eval("vconfig", "set_name_type", "VLAN_PLUS_VID_NO_PAD"); eval("vconfig", "add", "eth0", "0"); eval("vconfig", "add", "eth0", "2"); struct ifreq ifr; int s; if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) { char eabuf[32]; strncpy(ifr.ifr_name, "eth0", IFNAMSIZ); ioctl(s, SIOCGIFHWADDR, &ifr); char macaddr[32]; strcpy(macaddr, ether_etoa((unsigned char *)ifr.ifr_hwaddr.sa_data, eabuf)); nvram_set("et0macaddr", macaddr); // MAC_ADD (macaddr); ether_atoe(macaddr, (unsigned char *)ifr.ifr_hwaddr.sa_data); strncpy(ifr.ifr_name, "vlan2", IFNAMSIZ); ioctl(s, SIOCSIFHWADDR, &ifr); close(s); } eval("ifconfig", "vlan0", "promisc"); eval("ifconfig", "vlan2", "promisc"); }