/* * Initialize the QuarterDeck. This should be done in BSP driver init routine. * Since BSP is not combined with QuarterDeck driver, we are doing here. */ GT_STATUS qdStart(void) /* devId is used for simulator only */ { GT_STATUS status; /* * Register all the required functions to QuarterDeck Driver. */ cfg.BSPFunctions.readMii = ffReadMii; cfg.BSPFunctions.writeMii = ffWriteMii; #ifdef USE_SEMAPHORE cfg.BSPFunctions.semCreate = osSemCreate; cfg.BSPFunctions.semDelete = osSemDelete; cfg.BSPFunctions.semTake = osSemWait; cfg.BSPFunctions.semGive = osSemSignal; #else /* USE_SEMAPHORE */ cfg.BSPFunctions.semCreate = NULL; cfg.BSPFunctions.semDelete = NULL; cfg.BSPFunctions.semTake = NULL; cfg.BSPFunctions.semGive = NULL; #endif /* USE_SEMAPHORE */ cfg.initPorts = GT_TRUE; cfg.cpuPortNum = GT_CPU_SWITCH_PORT; qd_dev->cpuPortNum = GT_CPU_SWITCH_PORT; if((status = qdLoadDriver(&cfg, qd_dev)) != GT_OK) { gtOsPrintf("qdLoadDriver is failed: status = 0x%x\n", status); return status; } /* * start the QuarterDeck */ if (qd_dev->deviceId == GT_88E6063) { phyPatch(qd_dev); } /* to which VID should we set the CPU_PORT? (1 is temporary)*/ if((status = gvlnSetPortVid(qd_dev, GT_CPU_SWITCH_PORT, 5)) != GT_OK) { gtOsPrintf("gprtSetPortVid returned fail for CPU port.\n"); return status; } #ifdef QD_TRAILER_MODE /* set ingress trailer mode*/ gprtSetIngressMode(qd_dev, GT_CPU_SWITCH_PORT, GT_TRAILER_INGRESS); /* set egress trailer*/ gprtSetTrailerMode(qd_dev, GT_CPU_SWITCH_PORT, GT_TRUE); #endif #ifdef QD_HEADER_MODE if((status = gprtSetHeaderMode(qd_dev, GT_CPU_SWITCH_PORT, GT_TRUE)) != GT_OK) { gtOsPrintf("gprtSetHeaderMode return Failed\n"); return status; } #endif return GT_OK; }
/***************************************************************************** * sampleAdmitOnlyTaggedFrame * * DESCRIPTION: * This routine will show how to configure a port to accept only vlan * tagged frames. * This routine assumes that 802.1Q has been enabled for the given port. * * INPUTS: * port - logical port to be configured. * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * Some device support Discard Untagged feature. If so, gprtSetDiscardUntagged * function will do the work. * *******************************************************************************/ GT_STATUS sampleAdmitOnlyTaggedFrame(GT_QD_DEV *dev,GT_LPORT port) { GT_STATUS status; GT_VTU_ENTRY vtuEntry; int i; /* * 0) If device support gprtSetDiscardUntagged, call the function. */ status = gprtSetDiscardUntagged(dev, port, GT_TRUE); switch (status) { case GT_OK: MSG_PRINT(("Done.\n")); return status; case GT_NOT_SUPPORTED: MSG_PRINT(("Try other method.\n")); break; default: MSG_PRINT(("Failure accessing device.\n")); return status; } /* * 1) Add VLAN ID 0xFFF with the given port as a member. */ gtMemSet(&vtuEntry,0,sizeof(GT_VTU_ENTRY)); vtuEntry.DBNum = 0; vtuEntry.vid = 0xFFF; for(i=0; i<dev->numOfPorts; i++) { vtuEntry.vtuData.memberTagP[i] = NOT_A_MEMBER; } vtuEntry.vtuData.memberTagP[port] = MEMBER_EGRESS_TAGGED; if((status = gvtuAddEntry(dev,&vtuEntry)) != GT_OK) { MSG_PRINT(("gvtuAddEntry returned fail.\n")); return status; } /* * 2) Configure the default vid for the given port with VID 0xFFF */ if((status = gvlnSetPortVid(dev,port,0xFFF)) != GT_OK) { MSG_PRINT(("gvlnSetPortVid returned fail.\n")); return status; } return GT_OK; }
int mv_switch_port_add(int switch_port, u16 vlan_grp_id, u16 port_map) { int p; /* Set default VLAN_ID for port */ if (gvlnSetPortVid(qd_dev, switch_port, MV_SWITCH_PORT_VLAN_ID(vlan_grp_id, switch_port)) != GT_OK) { printk(KERN_ERR "gvlnSetPortVid failed\n"); return -1; } /* Map port to VLAN DB */ if (gvlnSetPortVlanDBNum(qd_dev, switch_port, MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id)) != GT_OK) { printk(KERN_ERR "gvlnSetPortVlanDBNum failed\n"); return -1; } /* Add port to the VLAN (CPU port is not part of VLAN) */ if (mv_switch_port_based_vlan_set((port_map & ~(1 << qd_cpu_port)), 0) != 0) printk(KERN_ERR "mv_switch_port_based_vlan_set failed\n"); /* Add port to vtu (used in tx) */ if (mv_switch_vlan_in_vtu_set(vlan_grp_id, MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id), (port_map | (1 << qd_cpu_port)))) { printk(KERN_ERR "mv_switch_vlan_in_vtu_set failed\n"); } /* set vtu with each port private vlan id (used in rx) */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(port_map, p) && (p != qd_cpu_port)) { if (mv_switch_vlan_in_vtu_set(MV_SWITCH_PORT_VLAN_ID(vlan_grp_id, p), MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id), port_map & ~(1 << qd_cpu_port)) != 0) { printk(KERN_ERR "mv_switch_vlan_in_vtu_set failed\n"); } } } /* Enable port */ if (gstpSetPortState(qd_dev, switch_port, GT_PORT_FORWARDING) != GT_OK) printk(KERN_ERR "gstpSetPortState failed\n"); #ifdef CONFIG_MV_ETH_SWITCH_LINK if (!qsgmii_module) { /* Enable Phy Link Status Changed interrupt at Phy level for the port */ if (gprtPhyIntEnable(qd_dev, switch_port, (GT_LINK_STATUS_CHANGED)) != GT_OK) printk(KERN_ERR "gprtPhyIntEnable failed port %d\n", switch_port); } #endif /* CONFIG_MV_ETH_SWITCH_LINK */ return 0; }
int mv_eth_switch_vlan_set(u16 vlan_grp_id, u16 port_map, u16 cpu_port) { int p; /* set port's default private vlan id and database number (DB per group): */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(port_map, p) && (p != cpu_port)) { if (gvlnSetPortVid(qd_dev, p, MV_SWITCH_PORT_VLAN_ID(vlan_grp_id, p)) != GT_OK) { printk(KERN_ERR "gvlnSetPortVid failed\n"); return -1; } if (gvlnSetPortVlanDBNum(qd_dev, p, MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id)) != GT_OK) { printk(KERN_ERR "gvlnSetPortVlanDBNum failed\n"); return -1; } } } /* set port's port-based vlan (CPU port is not part of VLAN) */ if (mv_switch_port_based_vlan_set((port_map & ~(1 << cpu_port)), 0) != 0) printk(KERN_ERR "mv_switch_port_based_vlan_set failed\n"); /* set vtu with group vlan id (used in tx) */ if (mv_switch_vlan_in_vtu_set(vlan_grp_id, MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id), port_map | (1 << cpu_port)) != 0) printk(KERN_ERR "mv_switch_vlan_in_vtu_set failed\n"); /* set vtu with each port private vlan id (used in rx) */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(port_map, p) && (p != cpu_port)) { if (mv_switch_vlan_in_vtu_set(MV_SWITCH_PORT_VLAN_ID(vlan_grp_id, p), MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id), port_map & ~(1 << cpu_port)) != 0) { printk(KERN_ERR "mv_switch_vlan_in_vtu_set failed\n"); } } } return 0; }
/***************************************************************************** * sample802_1qSetup * * DESCRIPTION: * This routine will show how to configure the switch device so that it * can be a Home Gateway. This example assumes that all the frames are not * VLAN-Tagged. * 1) to clear VLAN ID Table, * 2) to enable 802.1Q in SECURE mode for each port except CPU port, * 3) to enable 802.1Q in FALL BACK mode for the CPU port. * 4) to add VLAN ID 1 with member port 0 and CPU port * (untagged egress), * 5) to add VLAN ID 2 with member the rest of the ports and CPU port * (untagged egress), * 6) to configure the default vid of each port: * Port 0 have PVID 1, CPU port has PVID 3, and the rest ports have PVID 2. * Note: CPU port's PVID should be unknown VID, so that QuarterDeck can use * VlanTable (header info) for TX. * * * INPUTS: * None. * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * WARNING!! * If you create just two VLAN for this setup, Trailer mode or Header mode * for the CPU port has to be enabled and Ethernet driver which connects to * CPU port should understand VLAN-TAGGING, Trailer mode, or Header mode. * *******************************************************************************/ GT_STATUS sample802_1qSetup(GT_QD_DEV *dev) { GT_STATUS status; GT_DOT1Q_MODE mode; GT_VTU_ENTRY vtuEntry; GT_U16 vid; GT_LPORT port; int i; /* * 1) Clear VLAN ID Table */ if((status = gvtuFlush(dev)) != GT_OK) { MSG_PRINT(("gvtuFlush returned fail.\n")); return status; } /* * 2) Enable 802.1Q for each port as GT_SECURE mode except CPU port. */ mode = GT_SECURE; for(i=0; i<dev->numOfPorts; i++) { port = i; if (port == dev->cpuPortNum) continue; if((status = gvlnSetPortVlanDot1qMode(dev,port, mode)) != GT_OK) { MSG_PRINT(("gvlnSetPortVlanDot1qMode return Failed\n")); return status; } } /* * 3) Enable 802.1Q for CPU port as GT_FALLBACK mode */ if((status = gvlnSetPortVlanDot1qMode(dev, dev->cpuPortNum, GT_FALLBACK)) != GT_OK) { MSG_PRINT(("gvlnSetPortVlanDot1qMode return Failed\n")); return status; } /* * 4) Add VLAN ID 1 with Port 0 and CPU Port as members of the Vlan. */ gtMemSet(&vtuEntry,0,sizeof(GT_VTU_ENTRY)); vtuEntry.DBNum = 0; vtuEntry.vid = 1; for(i=0; i<dev->numOfPorts; i++) { port = i; if((i==0) || (port == dev->cpuPortNum)) vtuEntry.vtuData.memberTagP[port] = MEMBER_EGRESS_UNTAGGED; else vtuEntry.vtuData.memberTagP[port] = NOT_A_MEMBER; } if((status = gvtuAddEntry(dev,&vtuEntry)) != GT_OK) { MSG_PRINT(("gvtuAddEntry returned fail.\n")); return status; } /* * 5) Add VLAN ID 2 with the rest of the Ports and CPU Port as members of * the Vlan. */ gtMemSet(&vtuEntry,0,sizeof(GT_VTU_ENTRY)); vtuEntry.DBNum = 0; vtuEntry.vid = 2; for(i=0; i<dev->numOfPorts; i++) { port = i; if(i == 0) vtuEntry.vtuData.memberTagP[port] = NOT_A_MEMBER; else vtuEntry.vtuData.memberTagP[port] = MEMBER_EGRESS_UNTAGGED; } if((status = gvtuAddEntry(dev,&vtuEntry)) != GT_OK) { MSG_PRINT(("gvtuAddEntry returned fail.\n")); return status; } /* * 6) Configure the default vid for each port. * Port 0 has PVID 1, CPU port has PVID 3, and the rest ports have PVID 2. */ for(i=0; i<dev->numOfPorts; i++) { port = i; if(i==0) vid = 1; else if(port == dev->cpuPortNum) vid = 3; else vid = 2; if((status = gvlnSetPortVid(dev,port,vid)) != GT_OK) { MSG_PRINT(("gvlnSetPortVid returned fail.\n")); return status; } } return GT_OK; }
static int mv_gw_switch_init(int port) { unsigned int i, p; unsigned char cnt; GT_LPORT port_list[MAX_SWITCH_PORTS]; struct mv_vlan_cfg *nc; GT_JUMBO_MODE jumbo_mode; GT_DEV_EVENT gt_event; printk("init switch layer... "); if (!qd_dev) { printk("qd_dev is NULL in %s\n",__func__); return -1; } ETH_DBG( ETH_DBG_LOAD, ("Device ID : 0x%x\n",qd_dev->deviceId)); ETH_DBG( ETH_DBG_LOAD, ("Base Reg Addr : 0x%x\n",qd_dev->baseRegAddr)); ETH_DBG( ETH_DBG_LOAD, ("No. of Ports : %d\n",qd_dev->numOfPorts)); ETH_DBG( ETH_DBG_LOAD, ("CPU Ports : %ld\n",qd_dev->cpuPortNum)); /* disable all ports */ for(p=0; p<qd_dev->numOfPorts; p++) { gstpSetPortState(qd_dev, p, GT_PORT_DISABLE); } /* set all ports to not modify the vlan tag on egress */ for(i=0; i<qd_dev->numOfPorts; i++) { if(gprtSetEgressMode(qd_dev, i, GT_UNMODIFY_EGRESS) != GT_OK) { printk("gprtSetEgressMode GT_UNMODIFY_EGRESS failed\n"); return -1; } } /* initialize Switch according to Switch ID */ switch (qd_dev->deviceId) { case GT_88E6065: /* set CPU port number */ if(gsysSetCPUPort(qd_dev, SWITCH_PORT_CPU) != GT_OK) { printk("gsysSetCPUPort failed\n"); return -1; } /* flush all counters for all ports */ if(gstatsFlushAll(qd_dev) != GT_OK) printk("gstatsFlushAll failed\n"); /* use Marvell Header mode */ if(gprtSetHeaderMode(qd_dev, SWITCH_PORT_CPU, GT_TRUE) != GT_OK) { printk("gprtSetHeaderMode GT_TRUE failed\n"); return -1; } /* init counters */ if(gprtClearAllCtr(qd_dev) != GT_OK) printk("gprtClearAllCtr failed\n"); if(gprtSetCtrMode(qd_dev, GT_CTR_ALL) != GT_OK) printk("gprtSetCtrMode failed\n"); break; case GT_88E6061: /* set CPU port number */ if(gsysSetCPUPort(qd_dev, SWITCH_PORT_CPU) != GT_OK) { printk("gsysSetCPUPort failed\n"); return -1; } /* use Marvell Header mode */ if(gprtSetHeaderMode(qd_dev,SWITCH_PORT_CPU,GT_TRUE) != GT_OK) { printk("gprtSetHeaderMode GT_TRUE failed\n"); return -1; } /* init counters */ if(gprtClearAllCtr(qd_dev) != GT_OK) printk("gprtClearAllCtr failed\n"); if(gprtSetCtrMode(qd_dev, GT_CTR_ALL) != GT_OK) printk("gprtSetCtrMode failed\n"); break; case GT_88E6161: case GT_88E6165: case GT_88E6171: /* flush all counters for all ports */ if(gstatsFlushAll(qd_dev) != GT_OK) { printk("gstatsFlushAll failed\n"); } /* use Marvell Header mode */ if(gprtSetHeaderMode(qd_dev,SWITCH_PORT_CPU,GT_TRUE) != GT_OK) { printk("gprtSetHeaderMode GT_TRUE failed\n"); return -1; } /* set all ports to work in Normal mode (non-DSA tag) */ for(i=0; i<qd_dev->numOfPorts; i++) { if (gprtSetFrameMode(qd_dev, i, GT_FRAME_MODE_NORMAL) != GT_OK) { printk("gprtSetFrameMode to GT_FRAME_MODE_NORMAL on port %d failed\n", i); return -1; } } /* Setup jumbo frames mode */ if( MV_RX_BUF_SIZE(gtw_config.mtu) <= 1522) jumbo_mode = GT_JUMBO_MODE_1522; else if( MV_RX_BUF_SIZE(gtw_config.mtu) <= 2048) jumbo_mode = GT_JUMBO_MODE_2048; else jumbo_mode = GT_JUMBO_MODE_10240; for(i=0; i<qd_dev->numOfPorts; i++) { if(gsysSetJumboMode(qd_dev, i, jumbo_mode) != GT_OK) { printk("gsysSetJumboMode %d failed\n",jumbo_mode); return -1; } } break; default: printk("Unsupported Switch. Switch ID is 0x%X.\n", qd_dev->deviceId); return -1; } /* set priorities rules */ for(i=0; i<qd_dev->numOfPorts; i++) { /* default port priority to queue zero */ if(gcosSetPortDefaultTc(qd_dev, i, 0) != GT_OK) printk("gcosSetPortDefaultTc failed (port %d)\n", i); /* enable IP TOS Prio */ if(gqosIpPrioMapEn(qd_dev, i, GT_TRUE) != GT_OK) printk("gqosIpPrioMapEn failed (port %d)\n",i); /* set IP QoS */ if(gqosSetPrioMapRule(qd_dev, i, GT_FALSE) != GT_OK) printk("gqosSetPrioMapRule failed (port %d)\n",i); /* disable Vlan QoS Prio */ if(gqosUserPrioMapEn(qd_dev, i, GT_FALSE) != GT_OK) printk("gqosUserPrioMapEn failed (port %d)\n",i); /* Set force flow control to FALSE for all ports */ if(gprtSetForceFc(qd_dev, i, GT_FALSE) != GT_OK) printk("gprtSetForceFc failed (port %d)\n",i); } /* The switch CPU port is not part of the VLAN, but rather connected by tunneling to each */ /* of the VLAN's ports. Our MAC addr will be added during start operation to the VLAN DB */ /* at switch level to forward packets with this DA to CPU port. */ ETH_DBG( ETH_DBG_LOAD, ("Enabling Tunneling on ports: ")); for(i=0; i<qd_dev->numOfPorts; i++) { if(i != SWITCH_PORT_CPU) { if(gprtSetVlanTunnel(qd_dev, i, GT_TRUE) != GT_OK) { printk("gprtSetVlanTunnel failed (port %d)\n",i); return -1; } else { ETH_DBG( ETH_DBG_LOAD, ("%d ",i)); } } } ETH_DBG( ETH_DBG_LOAD, ("\n")); /* configure ports (excluding CPU port) for each network interface (VLAN): */ for(i=0, nc=>w_config.vlan_cfg[i]; i<gtw_config.vlans_num; i++,nc++) { ETH_DBG( ETH_DBG_LOAD, ("vlan%d configuration (nc->ports_mask = 0x%08x) \n", i, nc->ports_mask)); /* set port's defaul private vlan id and database number (DB per group): */ for(p=0; p<qd_dev->numOfPorts; p++) { if( MV_BIT_CHECK(nc->ports_mask, p) && (p != SWITCH_PORT_CPU) ) { ETH_DBG(ETH_DBG_LOAD,("port %d default private vlan id: 0x%x\n", p, MV_GTW_PORT_VLAN_ID(nc->vlan_grp_id,p))); if( gvlnSetPortVid(qd_dev, p, MV_GTW_PORT_VLAN_ID(nc->vlan_grp_id,p)) != GT_OK ) { printk("gvlnSetPortVid failed"); return -1; } if( gvlnSetPortVlanDBNum(qd_dev, p, MV_GTW_VLAN_TO_GROUP(nc->vlan_grp_id)) != GT_OK) { printk("gvlnSetPortVlanDBNum failed\n"); return -1; } } } /* set port's port-based vlan (CPU port is not part of VLAN) */ if(mv_gtw_set_port_based_vlan(nc->ports_mask & ~(1<<SWITCH_PORT_CPU)) != 0) { printk("mv_gtw_set_port_based_vlan failed\n"); } /* set vtu with group vlan id (used in tx) */ if(mv_gtw_set_vlan_in_vtu(nc->vlan_grp_id, nc->ports_mask | (1<<SWITCH_PORT_CPU)) != 0) { printk("mv_gtw_set_vlan_in_vtu failed\n"); } /* set vtu with each port private vlan id (used in rx) */ for(p=0; p<qd_dev->numOfPorts; p++) { if(MV_BIT_CHECK(nc->ports_mask, p) && (p!=SWITCH_PORT_CPU)) { if(mv_gtw_set_vlan_in_vtu(MV_GTW_PORT_VLAN_ID(nc->vlan_grp_id,p), nc->ports_mask & ~(1<<SWITCH_PORT_CPU)) != 0) { printk("mv_gtw_set_vlan_in_vtu failed\n"); } } } } /* set cpu-port with port-based vlan to all other ports */ ETH_DBG( ETH_DBG_LOAD, ("cpu port-based vlan:")); for(p=0,cnt=0; p<qd_dev->numOfPorts; p++) { if(p != SWITCH_PORT_CPU) { ETH_DBG( ETH_DBG_LOAD, ("%d ",p)); port_list[cnt] = p; cnt++; } } ETH_DBG( ETH_DBG_LOAD, ("\n")); if(gvlnSetPortVlanPorts(qd_dev, SWITCH_PORT_CPU, port_list, cnt) != GT_OK) { printk("gvlnSetPortVlanPorts failed\n"); return -1; } if(gfdbFlush(qd_dev,GT_FLUSH_ALL) != GT_OK) { printk("gfdbFlush failed\n"); } /* done! enable all Switch ports according to the net config table */ ETH_DBG( ETH_DBG_LOAD, ("enabling: ports ")); for(p=0; p<qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_enabled_ports, p)) { ETH_DBG( ETH_DBG_LOAD, ("%d ",p)); if(gstpSetPortState(qd_dev, p, GT_PORT_FORWARDING) != GT_OK) { printk("gstpSetPortState failed\n"); } } } ETH_DBG( ETH_DBG_LOAD, ("\n")); #ifdef CONFIG_MV_GTW_LINK_STATUS /* Enable Phy Link Status Changed interrupt at Phy level for the all enabled ports */ for(p=0; p<qd_dev->numOfPorts; p++) { if(MV_BIT_CHECK(switch_enabled_ports, p) && (p != SWITCH_PORT_CPU)) { if(gprtPhyIntEnable(qd_dev, p, (GT_LINK_STATUS_CHANGED)) != GT_OK) { printk("gprtPhyIntEnable failed port %d\n", p); } } } if ((qd_dev->deviceId != GT_88E6161) && (qd_dev->deviceId != GT_88E6165) && (qd_dev->deviceId != GT_88E6171)) { if (switch_irq != -1) { if(eventSetActive(qd_dev, GT_PHY_INTERRUPT) != GT_OK) { printk("eventSetActive failed\n"); } } } else { gt_event.event = GT_DEV_INT_PHY; gt_event.portList = 0; gt_event.phyList = 0x1F; /* 0x1F is a bit mask for ports 0-4 */ if (switch_irq != -1) { if(eventSetDevInt(qd_dev, >_event) != GT_OK) { printk("eventSetDevInt failed\n"); } if(eventSetActive(qd_dev, GT_DEVICE_INT) != GT_OK) { printk("eventSetActive failed\n"); } } } #endif /* CONFIG_MV_GTW_LINK_STATUS */ /* Configure Ethernet related LEDs, currently according to Switch ID */ switch (qd_dev->deviceId) { case GT_88E6161: case GT_88E6165: case GT_88E6171: break; /* do nothing */ default: for(p=0; p<qd_dev->numOfPorts; p++) { if( (p != SWITCH_PORT_CPU) && (SWITCH_IS_PORT_CONNECTED(p)) ) { if(gprtSetPhyReg(qd_dev,p,22,0x1FFA)) { /* Configure Register 22 LED0 to 0xA for Link/Act */ printk("gprtSetPhyReg failed (port=%d)\n", p); } } } break; } /* printk("done\n"); */ return 0; }
/* * WAN Port (Port 0) and CPU Port (Port 5) are in VLAN 1 and * all ports (including CPU Port) except WAN Port are in VLAN 2. * 1) Set PVID for each port. (CPU port has PVID 2, which is the same as LAN) * 2) Set Port Based VLAN Map for each port. (CPU port's VLAN Map is set for all LAN ports) * Notes: * 1) Trailer Mode * When Ethernet Device, which is directly connected to CPU port, sends out a packet * to WAN, DPV in Trailer Tag should have WAN port bit set (bit 0 in this case), and * to LAN, Trailer Tag should be set to 0. * Restriction : Only one group of VLAN can have multiple ports. * 2) Header Mode * When Ethernet Device, which is directly connected to CPU port, sends out a packet * to WAN, VlanTable in Header Tag should have WAN ports bits set (bit 0 in this case), and * to LAN, VlanTable in Header Tag should have LAN ports bits set (bit 1~4 and 6 in this case) */ static GT_STATUS sampleHomeGatewayVlan(GT_QD_DEV *dev,GT_LPORT numOfPorts, GT_LPORT cpuPort) { GT_STATUS status; GT_LPORT index,port,portToSet; GT_LPORT portList[MAX_SWITCH_PORTS]; /* * set PVID for each port. * the first port(port 0, WAN) has default VID 2 and all others has 1. */ if((status = gvlnSetPortVid(dev,0,2)) != GT_OK) { MSG_PRINT(("gprtSetPortVid returned fail.\n")); return status; } for (port=1; port<numOfPorts; port++) { if((status = gvlnSetPortVid(dev,port,1)) != GT_OK) { MSG_PRINT(("gprtSetPortVid returned fail.\n")); return status; } } /* * set Port VLAN Mapping. * port 0 (WAN) and cpu port are in a vlan 2. * And all the rest ports (LAN) and cpu port are in a vlan 1. */ /* port 0 : set cpuPort only */ portList[0] = cpuPort; if((status = gvlnSetPortVlanPorts(dev,0,portList,1)) != GT_OK) { MSG_PRINT(("gvlnSetPortVlanPorts returned fail.\n")); return status; } /* set all ports except port 0 and itself */ for (portToSet=1; portToSet<numOfPorts; portToSet++) { /* port 0 and cpuPort will be taken cared seperately. */ if (portToSet == cpuPort) { continue; } index = 0; for (port=1; port<numOfPorts; port++) { if (port == portToSet) { continue; } portList[index++] = port; } if((status = gvlnSetPortVlanPorts(dev,(GT_U8)portToSet,portList,index)) != GT_OK) { MSG_PRINT(("gvlnSetPortVlanPorts returned fail.\n")); return status; } } /* cpuPort : set all port except cpuPort and WAN port */ index = 0; for (port=1; port<numOfPorts; port++) { if (port == cpuPort) { continue; } portList[index++] = port; } if((status = gvlnSetPortVlanPorts(dev,cpuPort,portList,index)) != GT_OK) { MSG_PRINT(("gvlnSetPortVlanPorts returned fail.\n")); return status; } return GT_OK; }
int mv_switch_unload(unsigned int switch_ports_mask) { int i; printk(KERN_ERR " o Unloading Switch QuarterDeck driver\n"); if (qd_dev == NULL) { printk(KERN_ERR " o %s: Already un-initialized\n", __func__); return 0; } /* Flush all addresses from the MAC address table */ /* this also happens in mv_switch_init() but we call it here to clean-up nicely */ /* Note: per DB address flush (gfdbFlushInDB) happens when doing ifconfig down on a Switch interface */ if (gfdbFlush(qd_dev, GT_FLUSH_ALL) != GT_OK) printk(KERN_ERR "gfdbFlush failed\n"); /* Reset VLAN tunnel mode */ for (i = 0; i < qd_dev->numOfPorts; i++) { if (MV_BIT_CHECK(switch_ports_mask, i) && (i != qd_cpu_port)) if (gprtSetVlanTunnel(qd_dev, i, GT_FALSE) != GT_OK) printk(KERN_ERR "gprtSetVlanTunnel failed (port %d)\n", i); } /* restore port's default private vlan id and database number to their default values after reset: */ for (i = 0; i < qd_dev->numOfPorts; i++) { if (gvlnSetPortVid(qd_dev, i, 0x0001) != GT_OK) { /* that's the default according to the spec */ printk(KERN_ERR "gvlnSetPortVid failed\n"); return -1; } if (gvlnSetPortVlanDBNum(qd_dev, i, 0) != GT_OK) { printk(KERN_ERR "gvlnSetPortVlanDBNum failed\n"); return -1; } } /* Port based VLAN */ if (mv_switch_port_based_vlan_set(switch_ports_mask, 1)) printk(KERN_ERR "mv_switch_port_based_vlan_set failed\n"); /* Remove all entries from the VTU table */ if (gvtuFlush(qd_dev) != GT_OK) printk(KERN_ERR "gvtuFlush failed\n"); /* unload switch sw package */ if (qdUnloadDriver(qd_dev) != GT_OK) { printk(KERN_ERR "qdUnloadDriver failed\n"); return -1; } qd_dev = NULL; qd_cpu_port = -1; qsgmii_module = 0; gephy_on_port = -1; rgmiia_on_port = -1; #ifdef CONFIG_MV_ETH_SWITCH_LINK switch_irq = -1; switch_link_poll = 0; del_timer(&switch_link_timer); #endif /* CONFIG_MV_ETH_SWITCH_LINK */ return 0; }