示例#1
0
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

}
示例#2
0
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);
	}
}
示例#3
0
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;
	}
}
示例#4
0
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);
	}

}
示例#5
0
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");
}