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_switch_port_del(int switch_port, u16 vlan_grp_id, u16 port_map) { int p; #ifdef CONFIG_MV_ETH_SWITCH_LINK if (!qsgmii_module) { /* Disable link change interrupts on unmapped port */ if (gprtPhyIntEnable(qd_dev, switch_port, 0) != GT_OK) printk(KERN_ERR "gprtPhyIntEnable failed on port #%d\n", switch_port); } #endif /* CONFIG_MV_ETH_SWITCH_LINK */ /* Disable unmapped port */ if (gstpSetPortState(qd_dev, switch_port, GT_PORT_DISABLE) != GT_OK) printk(KERN_ERR "gstpSetPortState failed on port #%d\n", switch_port); /* Remove port from 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_gtw_set_port_based_vlan failed\n"); /* Remove port from 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))) != 0) { printk(KERN_ERR "mv_gtw_set_vlan_in_vtu failed\n"); } /* Remove port from vtu of 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_gtw_set_vlan_in_vtu failed\n"); } } return 0; }
/******************************************************************************* * qdLoadDriver * * DESCRIPTION: * QuarterDeck Driver Initialization Routine. * This is the first routine that needs be called by system software. * It takes *cfg from system software, and retures a pointer (*dev) * to a data structure which includes infomation related to this QuarterDeck * device. This pointer (*dev) is then used for all the API functions. * * INPUTS: * cfg - Holds device configuration parameters provided by system software. * * OUTPUTS: * dev - Holds device information to be used for each API call. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_ALREADY_EXIST - if device already started * GT_BAD_PARAM - on bad parameters * * COMMENTS: * qdUnloadDriver is also provided to do driver cleanup. * *******************************************************************************/ GT_STATUS qdLoadDriver ( IN GT_SYS_CONFIG *cfg, OUT GT_QD_DEV *dev ) { GT_STATUS retVal; GT_LPORT port; DBG_INFO(("qdLoadDriver Called.\n")); /* Check for parameters validity */ if(dev == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* Check for parameters validity */ if(cfg == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* The initialization was already done. */ if(dev->devEnabled) { DBG_INFO(("QuarterDeck already started.\n")); return GT_ALREADY_EXIST; } if(gtRegister(dev,&(cfg->BSPFunctions)) != GT_TRUE) { DBG_INFO(("gtRegister Failed.\n")); return GT_FAIL; } dev->accessMode = cfg->mode.scanMode; if (dev->accessMode == SMI_MULTI_ADDR_MODE) { dev->baseRegAddr = 0; dev->phyAddr = cfg->mode.baseAddr; } else { dev->baseRegAddr = cfg->mode.baseAddr; dev->phyAddr = 0; } /* Initialize the driver */ retVal = driverConfig(dev); if(retVal != GT_OK) { DBG_INFO(("driverConfig Failed.\n")); return retVal; } /* Initialize dev fields. */ dev->cpuPortNum = cfg->cpuPortNum; dev->maxPhyNum = 5; dev->devGroup = 0; /* Assign Device Name */ switch(dev->deviceId) { case GT_88E6021: dev->numOfPorts = 3; dev->maxPorts = 3; dev->maxPhyNum = 2; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6021; break; case GT_88E6051: dev->numOfPorts = 5; dev->maxPorts = 5; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6051; break; case GT_88E6052: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6052; break; case GT_88E6060: if((dev->cpuPortNum != 4)&&(dev->cpuPortNum != 5)) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6060; break; case GT_88E6031: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6061; break; case GT_88E6061: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6061; break; case GT_88E6035: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6055: dev->numOfPorts = 5; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = 0x2F; /* port 0,1,2,3, and 5 */ dev->validPhyVec = 0x2F; /* port 0,1,2,3, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6065: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6065; break; case GT_88E6063: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6063; break; case GT_FH_VPN: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FH_VPN; break; case GT_FF_EG: if(dev->cpuPortNum != 5) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_EG; break; case GT_FF_HG: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_HG; break; case GT_88E6083: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6083; break; case GT_88E6153: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6181: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6181; break; case GT_88E6183: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6093: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6093; break; case GT_88E6092: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6092; break; case GT_88E6095: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6095; break; case GT_88E6152: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6155: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6182: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6185: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6131: case GT_88E6108: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6108; break; default: DBG_INFO(("Unknown Device. Initialization failed\n")); return GT_FAIL; } /* Initialize the MultiAddress Register Access semaphore. */ if((dev->multiAddrSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ATU semaphore. */ if((dev->atuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the VTU semaphore. */ if((dev->vtuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the STATS semaphore. */ if((dev->statsRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PIRL semaphore. */ if((dev->pirlRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ports states to forwarding mode. */ if(cfg->initPorts == GT_TRUE) { for (port=0; port<dev->numOfPorts; port++) { if((retVal = gstpSetPortState(dev,port,GT_PORT_FORWARDING)) != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(IS_IN_DEV_GROUP(dev,DEV_ENHANCED_CPU_PORT)) { if((retVal = gsysSetRsvd2CpuEnables(dev,0)) != GT_OK) { DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n")); qdUnloadDriver(dev); return retVal; } if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) { for (port=0; port<dev->numOfPorts; port++) { retVal = gprtSetCPUPort(dev,port,dev->cpuPortNum); if((retVal != GT_OK) && (retVal != GT_NOT_SUPPORTED)) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT)) { retVal = gsysSetCPUPort(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_MULTICAST)) { if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) { retVal = gpirlInitialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * qdLoadDriver * * DESCRIPTION: * QuarterDeck Driver Initialization Routine. * This is the first routine that needs be called by system software. * It takes *cfg from system software, and retures a pointer (*dev) * to a data structure which includes infomation related to this QuarterDeck * device. This pointer (*dev) is then used for all the API functions. * * INPUTS: * cfg - Holds device configuration parameters provided by system software. * * OUTPUTS: * dev - Holds device information to be used for each API call. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_ALREADY_EXIST - if device already started * GT_BAD_PARAM - on bad parameters * * COMMENTS: * qdUnloadDriver is also provided to do driver cleanup. * *******************************************************************************/ GT_STATUS qdLoadDriver ( IN GT_SYS_CONFIG *cfg, OUT GT_QD_DEV *dev ) { GT_STATUS retVal; GT_LPORT port; DBG_INFO(("qdLoadDriver Called.\n")); /* Check for parameters validity */ if(dev == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* Check for parameters validity */ if(cfg == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* The initialization was already done. */ if(dev->devEnabled) { DBG_INFO(("QuarterDeck already started.\n")); return GT_ALREADY_EXIST; } #ifdef GT_PORT_MAP_IN_DEV /* Modified to add port mapping functions into device ssystem configuration. */ if (dev->lport2port == NULL) { dev->lport2port = lport2port; } if (dev->port2lport == NULL) { dev->port2lport = port2lport; } if (dev->lportvec2portvec == NULL) { dev->lportvec2portvec = lportvec2portvec; } if (dev->portvec2lportvec == NULL) { dev->portvec2lportvec = portvec2lportvec; } #endif if(gtRegister(dev,&(cfg->BSPFunctions)) != GT_TRUE) { DBG_INFO(("gtRegister Failed.\n")); return GT_FAIL; } dev->accessMode = (GT_U8)cfg->mode.scanMode; if (dev->accessMode == SMI_MULTI_ADDR_MODE) { dev->baseRegAddr = 0; dev->phyAddr = (GT_U8)cfg->mode.baseAddr; } else { dev->baseRegAddr = (GT_U8)cfg->mode.baseAddr; dev->phyAddr = 0; } /* Initialize the driver */ retVal = driverConfig(dev); if(retVal != GT_OK) { DBG_INFO(("driverConfig Failed.\n")); return retVal; } /* Initialize dev fields. */ dev->cpuPortNum = cfg->cpuPortNum; dev->maxPhyNum = 5; dev->devGroup = 0; dev->devStorage = 0; /* Assign Device Name */ dev->devName = 0; dev->devName1 = 0; dev->validSerdesVec = 0; if((dev->deviceId&0xfff8)==GT_88EC000) /* device id 0xc00 - 0xc07 are GT_88EC0XX */ dev->deviceId=GT_88EC000; switch(dev->deviceId) { case GT_88E6021: dev->numOfPorts = 3; dev->maxPorts = 3; dev->maxPhyNum = 2; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6021; break; case GT_88E6051: dev->numOfPorts = 5; dev->maxPorts = 5; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6051; break; case GT_88E6052: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6052; break; case GT_88E6060: if((dev->cpuPortNum != 4)&&(dev->cpuPortNum != 5)) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6060; break; case GT_88E6031: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6061; break; case GT_88E6061: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6061; break; case GT_88E6035: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6065: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6065; break; case GT_88E6063: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6063; break; case GT_FH_VPN: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FH_VPN; break; case GT_FF_EG: if(dev->cpuPortNum != 5) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_EG; break; case GT_FF_HG: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_HG; break; case GT_88E6083: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6083; break; case GT_88E6153: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6181: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6181; break; case GT_88E6183: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6093: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6093; break; case GT_88E6092: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6092; break; case GT_88E6095: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6095; break; case GT_88E6097: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6097; break; case GT_88E6096: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6096; break; case GT_88E6046: dev->numOfPorts = 6; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x60F; dev->validPhyVec = 0x60F; dev->devName = DEV_88E6096; break; case GT_88E6085: dev->numOfPorts = 10; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x6FF; dev->validPhyVec = 0x6FF; dev->devName = DEV_88E6096; break; case GT_88E6152: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = 0x28F; dev->validPhyVec = 0x28F; dev->devName = DEV_88E6182; break; case GT_88E6155: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = 0x28F; dev->validPhyVec = 0x28F; dev->devName = DEV_88E6185; break; case GT_88E6182: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6185: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6121: dev->numOfPorts = 3; dev->maxPorts = 8; dev->maxPhyNum = 3; dev->validPortVec = 0xE; /* port 1, 2, and 3 */ dev->validPhyVec = 0xE; /* port 1, 2, and 3 */ dev->devName = DEV_88E6108; break; case GT_88E6122: dev->numOfPorts = 6; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = 0x7E; /* port 1 ~ 6 */ dev->validPhyVec = 0xF07E; /* port 1 ~ 6, 12 ~ 15 (serdes) */ dev->validSerdesVec = 0xF000; dev->devName = DEV_88E6108; break; case GT_88E6131: case GT_88E6108: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->validSerdesVec = 0xF000; dev->devName = DEV_88E6108; break; case GT_88E6123: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = 0x23; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6161; break; case GT_88E6161: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6161; break; case GT_88E6165: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6165; break; case GT_88E6351: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName = DEV_88E6351; break; case GT_88E6175: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E6175; /* test device group 1 */ break; case GT_88E6171 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName = DEV_88E6171; break; case GT_88E6350 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName = DEV_88E6371; break; case GT_88EC000 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88EC000; break; case GT_88E6020: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6070: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6071: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6220: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6250: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6172: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->validSerdesVec = 0x8000; dev->devName = DEV_88E6172; break; case GT_88E6176: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->validSerdesVec = 0x8000; dev->devName = DEV_88E6176; break; case GT_88E6240: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->validSerdesVec = 0x8000; dev->devName = DEV_88E6240; break; case GT_88E6352: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->validSerdesVec = 0x8000; dev->devName = DEV_88E6352; break; case GT_88E6320: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x18; dev->validSerdesVec = 0x3000; dev->devName1 = DEV_88E6320; break; case GT_88E6321: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 12; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x18; dev->validSerdesVec = 0x3000; dev->devName1 = DEV_88E6321; break; case GT_88E6999: /* Opus */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6999; break; case GT_88E6390: /* Peridot Full Featured Device */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6390; break; case GT_88E6360: /* Peridot 5 GE PHY version */ dev->numOfPorts = 5; dev->maxPorts = 5; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6390; break; case GT_88E6290: /* Peridot FE PHY version */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6290; break; case GT_88E6290A: /* Peridot Forced FE PHY (no AutoNeg) for Automotive */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6290A; break; case GT_88E6191: /* Peridot No AVB */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6190; break; case GT_88E6190: /* Peridot No AVB, Z80 NIC, TCAM nor Cut Through */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6191; break; default: DBG_INFO(("Unknown Device. Initialization failed\n")); return GT_FAIL; } dev->cpuPortNum = GT_PORT_2_LPORT(cfg->cpuPortNum); if(dev->cpuPortNum == GT_INVALID_PORT) { if(GT_LPORT_2_PORT((GT_LPORT)cfg->cpuPortNum) != GT_INVALID_PORT) { dev->cpuPortNum = cfg->cpuPortNum; } else { return GT_BAD_CPU_PORT; } } /* Initialize the MultiAddress Register Access semaphore. */ if((dev->multiAddrSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ATU semaphore. */ if((dev->atuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the VTU semaphore. */ if((dev->vtuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the STATS semaphore. */ if((dev->statsRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PIRL semaphore. */ if((dev->pirlRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PTP semaphore. */ if((dev->ptpRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the Table semaphore. */ if((dev->tblRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the EEPROM Configuration semaphore. */ if((dev->eepromRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PHY Device Register Access semaphore. */ if((dev->phyRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the Remote management Register Access semaphore. */ if((dev->hwAccessRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ports states to forwarding mode. */ if(cfg->initPorts == GT_TRUE) { for (port=0; port<dev->numOfPorts; port++) { if((retVal = gstpSetPortState(dev,port,GT_PORT_FORWARDING)) != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } dev->use_mad = GT_FALSE; #ifdef GT_USE_MAD { int portPhyAddr=0; unsigned int validPhyVec = dev->validPhyVec; while((validPhyVec&1)==0) { validPhyVec >>= 1; portPhyAddr++; } DBG_INFO(("@@@@@@@@@@ qd_madInit\n")); if((retVal = qd_madInit(dev, portPhyAddr)) != GT_OK) { DBG_INFO(("Initialize MAD failed.\n")); qdUnloadDriver(dev); return retVal; } } #endif if(cfg->skipInitSetup == GT_SKIP_INIT_SETUP) { dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; } if(IS_IN_DEV_GROUP(dev,DEV_ENHANCED_CPU_PORT)) { if((retVal = gsysSetRsvd2CpuEnables(dev,0)) != GT_OK) { DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n")); qdUnloadDriver(dev); return retVal; } if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_CPU_DEST_PER_PORT)) { for (port=0; port<dev->numOfPorts; port++) { retVal = gprtSetCPUPort(dev,port,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT)) { retVal = gsysSetCPUPort(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_DEST)) { retVal = gsysSetCPUDest(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_MULTICAST)) { if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) { retVal = gpirlInitialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL2_RESOURCE)) { retVal = gpirl2Initialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } else if (IS_IN_DEV_GROUP(dev,DEV_PIRL3_RESOURCE)) { retVal = gpirl3Initialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT_NEED_INIT)) { retVal = gsysInitCPUPort(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); 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; }
/******************************************************************************* * qdLoadDriver * * DESCRIPTION: * QuarterDeck Driver Initialization Routine. * This is the first routine that needs be called by system software. * It takes *cfg from system software, and retures a pointer (*dev) * to a data structure which includes infomation related to this QuarterDeck * device. This pointer (*dev) is then used for all the API functions. * * INPUTS: * cfg - Holds device configuration parameters provided by system software. * * OUTPUTS: * dev - Holds device information to be used for each API call. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_ALREADY_EXIST - if device already started * GT_BAD_PARAM - on bad parameters * * COMMENTS: * qdUnloadDriver is also provided to do driver cleanup. * *******************************************************************************/ GT_STATUS qdLoadDriver ( IN GT_SYS_CONFIG *cfg, OUT GT_QD_DEV *dev ) { GT_STATUS retVal; GT_LPORT port; DBG_INFO(("qdLoadDriver Called.\n")); /* Check for parameters validity */ if(dev == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* Check for parameters validity */ if(cfg == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* The initialization was already done. */ if(dev->devEnabled) { DBG_INFO(("QuarterDeck already started.\n")); return GT_ALREADY_EXIST; } if(gtRegister(dev,&(cfg->BSPFunctions)) != GT_TRUE) { DBG_INFO(("gtRegister Failed.\n")); return GT_FAIL; } dev->accessMode = (GT_U8)cfg->mode.scanMode; if (dev->accessMode == SMI_MULTI_ADDR_MODE) { dev->baseRegAddr = 0; dev->phyAddr = (GT_U8)cfg->mode.baseAddr; } else { dev->baseRegAddr = (GT_U8)cfg->mode.baseAddr; dev->phyAddr = 0; } /* Initialize the driver */ retVal = driverConfig(dev); if(retVal != GT_OK) { DBG_INFO(("driverConfig Failed.\n")); return retVal; } /* Initialize dev fields. */ dev->cpuPortNum = cfg->cpuPortNum; dev->maxPhyNum = 5; dev->devGroup = 0; dev->devStorage = 0; /* Assign Device Name */ switch(dev->deviceId) { case GT_88E6021: dev->numOfPorts = 3; dev->maxPorts = 3; dev->maxPhyNum = 2; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6021; break; case GT_88E6051: dev->numOfPorts = 5; dev->maxPorts = 5; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6051; break; case GT_88E6052: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6052; break; case GT_88E6060: if((dev->cpuPortNum != 4)&&(dev->cpuPortNum != 5)) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6060; break; case GT_88E6031: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6061; break; case GT_88E6061: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6061; break; case GT_88E6035: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6055: dev->numOfPorts = 5; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = 0x2F; /* port 0,1,2,3, and 5 */ dev->validPhyVec = 0x2F; /* port 0,1,2,3, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6065: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6065; break; case GT_88E6063: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6063; break; case GT_FH_VPN: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FH_VPN; break; case GT_FF_EG: if(dev->cpuPortNum != 5) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_EG; break; case GT_FF_HG: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_HG; break; case GT_88E6083: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6083; break; case GT_88E6153: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6181: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6181; break; case GT_88E6183: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6093: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6093; break; case GT_88E6092: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6092; break; case GT_88E6095: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6095; break; case GT_88E6045: dev->numOfPorts = 6; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x60F; dev->validPhyVec = 0x60F; dev->devName = DEV_88E6095; break; case GT_88E6097: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6097; break; case GT_88E6096: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6096; break; case GT_88E6047: dev->numOfPorts = 6; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x60F; dev->validPhyVec = 0x60F; dev->devName = DEV_88E6097; break; case GT_88E6046: dev->numOfPorts = 6; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x60F; dev->validPhyVec = 0x60F; dev->devName = DEV_88E6096; break; case GT_88E6085: dev->numOfPorts = 10; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x6FF; dev->validPhyVec = 0x6FF; dev->devName = DEV_88E6096; break; case GT_88E6152: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6155: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6182: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6185: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6121: dev->numOfPorts = 3; dev->maxPorts = 8; dev->maxPhyNum = 3; dev->validPortVec = 0xE; /* port 1, 2, and 3 */ dev->validPhyVec = 0xE; /* port 1, 2, and 3 */ dev->devName = DEV_88E6108; break; case GT_88E6122: dev->numOfPorts = 6; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = 0x7E; /* port 1 ~ 6 */ dev->validPhyVec = 0xF07E; /* port 1 ~ 6, 12 ~ 15 (serdes) */ dev->validSerdesVec = 0xF000; dev->devName = DEV_88E6108; break; case GT_88E6131: case GT_88E6108: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->validSerdesVec = 0xF000; dev->devName = DEV_88E6108; break; case GT_88E6123: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = 0x23; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6161; break; case GT_88E6140: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6165; break; case GT_88E6161: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6161; break; case GT_88E6165: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6165; break; case GT_KW2_INT : dev->deviceId = GT_88E6351; /* fall through */ case GT_88E6351: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->devName = DEV_88E6351; break; case GT_88E6175: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->devName = DEV_88E6175; break; case GT_88E6125 : dev->numOfPorts = 4; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPortVec &= ~(0x7); dev->validPhyVec = 0x78; dev->devName = DEV_88E6171; break; case GT_88E6171 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->devName = DEV_88E6171; break; case GT_88E6321 : dev->numOfPorts = 4; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPortVec &= ~(0x7); dev->validPhyVec = 0x78; dev->devName = DEV_88E6371; break; case GT_88E6350 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->devName = DEV_88E6371; break; default: DBG_INFO(("Unknown Device. Initialization failed\n")); return GT_FAIL; } dev->cpuPortNum = GT_PORT_2_LPORT(cfg->cpuPortNum); if(dev->cpuPortNum == GT_INVALID_PORT) { if(GT_LPORT_2_PORT((GT_LPORT)cfg->cpuPortNum) != GT_INVALID_PORT) { dev->cpuPortNum = cfg->cpuPortNum; } else { return GT_BAD_CPU_PORT; } } /* Initialize the MultiAddress Register Access semaphore. */ if((dev->multiAddrSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ATU semaphore. */ if((dev->atuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the VTU semaphore. */ if((dev->vtuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the STATS semaphore. */ if((dev->statsRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PIRL semaphore. */ if((dev->pirlRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PTP semaphore. */ if((dev->ptpRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the Table semaphore. */ if((dev->tblRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the EEPROM Configuration semaphore. */ if((dev->eepromRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PHY Device Register Access semaphore. */ if((dev->phyRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ports states to forwarding mode. */ if(cfg->initPorts == GT_TRUE) { for (port=0; port<dev->numOfPorts; port++) { if((retVal = gstpSetPortState(dev,port,GT_PORT_FORWARDING)) != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(cfg->skipInitSetup == GT_SKIP_INIT_SETUP) { dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; } if(IS_IN_DEV_GROUP(dev,DEV_ENHANCED_CPU_PORT)) { if((retVal = gsysSetRsvd2CpuEnables(dev,0)) != GT_OK) { DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n")); qdUnloadDriver(dev); return retVal; } if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_CPU_DEST_PER_PORT)) { for (port=0; port<dev->numOfPorts; port++) { retVal = gprtSetCPUPort(dev,port,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT)) { retVal = gsysSetCPUPort(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_DEST)) { retVal = gsysSetCPUDest(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_MULTICAST)) { if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) { retVal = gpirlInitialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL2_RESOURCE)) { retVal = gpirl2Initialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gstpSetMode * * DESCRIPTION: * This routine Enable the Spanning tree. * * INPUTS: * en - GT_TRUE for enable, GT_FALSE for disable. * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * when enabled, this function sets all port to blocking state, and inserts * the BPDU MAC into the ATU to be captured to CPU, on disable all port are * being modified to be in forwarding state. * * GalTis: * *******************************************************************************/ GT_STATUS gstpSetMode ( IN GT_QD_DEV *dev, IN GT_BOOL en ) { GT_STATUS retVal; /* Functions return value. */ GT_PORT_STP_STATE state; /* STP state to be set. */ GT_ATU_ENTRY atuEntry; /* The ATU entry data to be set */ GT_U8 i; DBG_INFO(("gstpSetMode Called.\n")); if(dev->deviceId == GT_88E6051) { DBG_INFO(("Failed.\n")); return GT_FAIL; } if((en == GT_TRUE) && (dev->stpMode == 1)) { DBG_INFO(("OK.\n")); return GT_OK; } /* Set the STP state in the relevant register. */ if(en == GT_TRUE) state = GT_PORT_BLOCKING; else state = GT_PORT_FORWARDING; for(i = 0; i < dev->numOfPorts; i++) { retVal = gstpSetPortState(dev,i,state); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } } /* Set the Atu entry parameters. */ atuEntry.macAddr.arEther[0] = 0x01; atuEntry.macAddr.arEther[1] = 0x80; atuEntry.macAddr.arEther[2] = 0xC2; atuEntry.macAddr.arEther[3] = 0x00; atuEntry.macAddr.arEther[4] = 0x00; atuEntry.macAddr.arEther[5] = 0x00; atuEntry.portVec = ( 1 << GT_PORT_2_LPORT(dev->cpuPortNum)); atuEntry.prio = 3; atuEntry.DBNum = 0; atuEntry.entryState.mcEntryState = GT_MC_PRIO_MGM_STATIC; if(en == GT_TRUE) { retVal = gfdbAddMacEntry(dev,&atuEntry); } else if((en == GT_FALSE) && (dev->stpMode != 0)) retVal = gfdbDelMacEntry(dev,&(atuEntry.macAddr)); else retVal = GT_OK; if(en == GT_TRUE) dev->stpMode = 1; else dev->stpMode = 2; if(retVal == GT_OK) DBG_INFO(("OK.\n")); else DBG_INFO(("Failed.\n")); return retVal; }
GT_STATUS qdInit(void) { GT_STATUS status = GT_OK; unsigned int i; status = qdStart(); if (GT_OK != status) { gtOsPrintf("qdStart is failed: status = 0x%x\n", status); return status; } #ifdef DB_6093_88E6218 /* start 88E6090 device, assumes SMI Address 0x11 and CPU Port 10 */ if(loadDev(qd_ext, SMI_MULTI_ADDR_MODE, 0x11, 10) == NULL) { gtOsPrintf("Failed to start External Device. Please check the SMI Address 0x11!\n"); } /* allow larger than 1522 bytes of frame (header + marvell tag) */ gsysSetMaxFrameSize(qd_dev,GT_FALSE); #endif for (i=0; i<qd_dev->numOfPorts; i++) { /* default port prio to three */ gcosSetPortDefaultTc(qd_dev, i, 3); /* disable IP TOS Prio */ gqosIpPrioMapEn(qd_dev, i, GT_FALSE); /* disable QOS Prio */ gqosUserPrioMapEn(qd_dev, i, GT_FALSE); /* Force flow control for all ports */ gprtSetForceFc(qd_dev, i, GT_FALSE); } /* Enable port #6 */ status = gstpSetPortState(qd_dev, 6, GT_PORT_FORWARDING); if((status = gprtClearAllCtr(qd_dev)) != GT_OK) { return status; } for (i=0; i<GT_CPU_SWITCH_PORT; i++) { gprtSetMcRateLimit(qd_dev, i, GT_MC_100_PERCENT_RL); } #ifdef QD_DEBUG for (i=0; i<qd_dev->numOfPorts; i++) { short sdata; hwReadPortReg(qd_dev, i, 0x4, &sdata); gtOsPrintf("Control reg for port[%d] is: %x\n",i,sdata); hwReadPortReg(qd_dev, i, 0x0, &sdata); gtOsPrintf("Status reg for port[%d] is: %x\n",i,sdata); } qdStatus(); #endif /* QD_DEBUG */ gtOsPrintf("QD initiated\n"); return status; }
int mv_switch_init(int mtu, unsigned int switch_ports_mask) { unsigned int p; unsigned char cnt; GT_LPORT port_list[MAX_SWITCH_PORTS]; if (qd_dev == NULL) { printk(KERN_ERR "%s: qd_dev not initialized, call mv_switch_load() first\n", __func__); return -1; } /* general Switch initialization - relevant for all Switch devices */ /* disable all ports */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_ports_mask, p)) if (gstpSetPortState(qd_dev, p, GT_PORT_DISABLE) != GT_OK) { printk(KERN_ERR "gstpSetPortState failed\n"); return -1; } } /* flush All counters for all ports */ if (gstatsFlushAll(qd_dev) != GT_OK) printk(KERN_ERR "gstatsFlushAll failed\n"); /* set all ports not to unmodify the vlan tag on egress */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_ports_mask, p)) { if (gprtSetEgressMode(qd_dev, p, GT_UNMODIFY_EGRESS) != GT_OK) { printk(KERN_ERR "gprtSetEgressMode GT_UNMODIFY_EGRESS failed\n"); return -1; } } } /* initializes the PVT Table (cross-chip port based VLAN) to all one's (initial state) */ if (gpvtInitialize(qd_dev) != GT_OK) { printk(KERN_ERR "gpvtInitialize failed\n"); return -1; } /* set all ports to work in Normal mode */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_ports_mask, p)) { if (gprtSetFrameMode(qd_dev, p, GT_FRAME_MODE_NORMAL) != GT_OK) { printk(KERN_ERR "gprtSetFrameMode GT_FRAME_MODE_NORMAL failed\n"); return -1; } } } /* set priorities rules */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_ports_mask, p)) { /* default port priority to queue zero */ if (gcosSetPortDefaultTc(qd_dev, p, 0) != GT_OK) printk(KERN_ERR "gcosSetPortDefaultTc failed (port %d)\n", p); /* enable IP TOS Prio */ if (gqosIpPrioMapEn(qd_dev, p, GT_TRUE) != GT_OK) printk(KERN_ERR "gqosIpPrioMapEn failed (port %d)\n", p); /* set IP QoS */ if (gqosSetPrioMapRule(qd_dev, p, GT_FALSE) != GT_OK) printk(KERN_ERR "gqosSetPrioMapRule failed (port %d)\n", p); /* disable Vlan QoS Prio */ if (gqosUserPrioMapEn(qd_dev, p, GT_FALSE) != GT_OK) printk(KERN_ERR "gqosUserPrioMapEn failed (port %d)\n", p); } } /* specific Switch initialization according to Switch ID */ switch (qd_dev->deviceId) { case GT_88E6161: case GT_88E6165: case GT_88E6171: case GT_88E6351: case GT_88E6172: case GT_88E6176: /* set Header Mode in all ports to False */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_ports_mask, p)) { if (gprtSetHeaderMode(qd_dev, p, GT_FALSE) != GT_OK) { printk(KERN_ERR "gprtSetHeaderMode GT_FALSE failed\n"); return -1; } } } if (gprtSetHeaderMode(qd_dev, qd_cpu_port, GT_TRUE) != GT_OK) { printk(KERN_ERR "gprtSetHeaderMode GT_TRUE failed\n"); return -1; } mv_switch_jumbo_mode_set(mtu); break; default: printk(KERN_ERR "Unsupported Switch. Switch ID is 0x%X.\n", qd_dev->deviceId); return -1; } /* 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. */ SWITCH_DBG(SWITCH_DBG_LOAD, ("Enabling Tunneling on ports: ")); for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_ports_mask, p) && (p != qd_cpu_port)) { if (gprtSetVlanTunnel(qd_dev, p, GT_TRUE) != GT_OK) { printk(KERN_ERR "gprtSetVlanTunnel failed (port %d)\n", p); return -1; } else { SWITCH_DBG(SWITCH_DBG_LOAD, ("%d ", p)); } } } SWITCH_DBG(SWITCH_DBG_LOAD, ("\n")); /* set cpu-port with port-based vlan to all other ports */ SWITCH_DBG(SWITCH_DBG_LOAD, ("cpu port-based vlan:")); for (p = 0, cnt = 0; p < qd_dev->numOfPorts; p++) { if (p != qd_cpu_port) { SWITCH_DBG(SWITCH_DBG_LOAD, ("%d ", p)); port_list[cnt] = p; cnt++; } } SWITCH_DBG(SWITCH_DBG_LOAD, ("\n")); if (gvlnSetPortVlanPorts(qd_dev, qd_cpu_port, port_list, cnt) != GT_OK) { printk(KERN_ERR "gvlnSetPortVlanPorts failed\n"); return -1; } if (gfdbFlush(qd_dev, GT_FLUSH_ALL) != GT_OK) printk(KERN_ERR "gfdbFlush failed\n"); mv_switch_link_detection_init(); /* Configure Ethernet related LEDs, currently according to Switch ID */ switch (qd_dev->deviceId) { case GT_88E6161: case GT_88E6165: case GT_88E6171: case GT_88E6351: case GT_88E6172: case GT_88E6176: break; /* do nothing */ default: for (p = 0; p < qd_dev->numOfPorts; p++) { if ((p != qd_cpu_port) && ((p))) { if (gprtSetPhyReg(qd_dev, p, 22, 0x1FFA)) { /* Configure Register 22 LED0 to 0xA for Link/Act */ printk(KERN_ERR "gprtSetPhyReg failed (port=%d)\n", p); } } } break; } /* enable all relevant ports (ports connected to the MAC or external ports) */ for (p = 0; p < qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_ports_mask, p)) { if ((mvBoardSwitchPortMap(MV_SWITCH_DEF_INDEX, p) != -1) || (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_0) == p) || (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_1) == p)) { if (gstpSetPortState(qd_dev, p, GT_PORT_FORWARDING) != GT_OK) { printk(KERN_ERR "gstpSetPortState failed\n"); return -1; } } } } #ifdef SWITCH_DEBUG /* for debug: */ mv_switch_status_print(); #endif return 0; }
int mv_switch_load(unsigned int switch_ports_mask) { int p; GT_STU_ENTRY stuEntry; printk(KERN_ERR " o Loading Switch QuarterDeck driver\n"); if (qd_dev) { printk(KERN_ERR " o %s: Already initialized\n", __func__); return 0; } memset((char *)&qd_cfg, 0, sizeof(GT_SYS_CONFIG)); spin_lock_init(&switch_lock); /* init config structure for qd package */ qd_cfg.BSPFunctions.readMii = mv_switch_mii_read; qd_cfg.BSPFunctions.writeMii = mv_switch_mii_write; qd_cfg.BSPFunctions.semCreate = NULL; qd_cfg.BSPFunctions.semDelete = NULL; qd_cfg.BSPFunctions.semTake = NULL; qd_cfg.BSPFunctions.semGive = NULL; qd_cfg.initPorts = GT_TRUE; qd_cfg.cpuPortNum = mvBoardSwitchCpuPortGet(MV_SWITCH_DEF_INDEX); if (mvBoardSmiScanModeGet(MV_SWITCH_DEF_INDEX) == 1) { qd_cfg.mode.baseAddr = 0; qd_cfg.mode.scanMode = SMI_MANUAL_MODE; } else if (mvBoardSmiScanModeGet(MV_SWITCH_DEF_INDEX) == 2) { qd_cfg.mode.scanMode = SMI_MULTI_ADDR_MODE; if (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_0) != -1) { qd_cfg.mode.baseAddr = mvBoardPhyAddrGet(MV_ETH_PORT_0); } else if (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_1) != -1) { qd_cfg.mode.baseAddr = mvBoardPhyAddrGet(MV_ETH_PORT_1); } else { printk(KERN_ERR "mv_switch_load failed: Wrong SCAN mode\n"); return -1; } } /* load switch sw package */ if (qdLoadDriver(&qd_cfg, &qddev) != GT_OK) { printk(KERN_ERR "qdLoadDriver failed\n"); return -1; } qd_dev = &qddev; qd_cpu_port = qd_cfg.cpuPortNum; /* Create entry in STU table */ memset(&stuEntry, 0, sizeof(GT_STU_ENTRY)); stuEntry.sid = 1; /* required: ((sid > 0) && (sid < 0x3F)) */ gstuAddEntry(qd_dev, &stuEntry); printk(KERN_ERR " o Device ID : 0x%x\n", qd_dev->deviceId); printk(KERN_ERR " o No. of Ports : %d\n", qd_dev->numOfPorts); printk(KERN_ERR " o CPU Port : %ld\n", qd_dev->cpuPortNum); qsgmii_module = mvBoardIsQsgmiiModuleConnected(); if (qsgmii_module) printk(KERN_ERR " o QSGMII Module Detected\n"); gephy_on_port = mvBoardGePhySwitchPortGet(); if (gephy_on_port >= 0) printk(KERN_ERR " o Internal GE PHY Connected to Switch Port %d Detected\n", gephy_on_port); rgmiia_on_port = mvBoardRgmiiASwitchPortGet(); if (rgmiia_on_port >= 0) printk(KERN_ERR " o RGMII-A Connected to Switch Port %d Detected\n", rgmiia_on_port); /* disable all disconnected ports */ for (p = 0; p < qd_dev->numOfPorts; p++) { /* Do nothing for ports that are not part of the given switch_port_mask */ if (!MV_BIT_CHECK(switch_ports_mask, p)) continue; if (mvBoardSwitchPortMap(MV_SWITCH_DEF_INDEX, p) != -1) { /* Switch port mapped to connector on the board */ if ((gpcsSetFCValue(qd_dev, p, GT_FALSE) != GT_OK) || (gpcsSetForcedFC(qd_dev, p, GT_FALSE) != GT_OK)) { printk(KERN_ERR "Force Flow Control - Failed\n"); return -1; } #if 0 /* TODO - decide if we want to enable auto-negotiation of Flow Control for external ports */ if (qsgmii_module) { /* TODO - configure ports via QSGMII registers */ } else { GT_STATUS status; status = gprtSetPause(qd_dev, p, GT_PHY_PAUSE); if (status != GT_OK) printk(KERN_ERR "Failed set pause for switch port #%d: status = %d\n", p, status); } #endif continue; } if ((mvBoardSwitchConnectedPortGet(MV_ETH_PORT_0) == p) || (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_1) == p)) { /* Switch port connected to GMAC - force link UP - 1000 Full with FC */ printk(KERN_ERR " o Setting Switch Port #%d connected to GMAC port for 1000 Full with FC\n", p); if (gpcsSetForceSpeed(qd_dev, p, PORT_FORCE_SPEED_1000_MBPS) != GT_OK) { printk(KERN_ERR "Force speed 1000mbps - Failed\n"); return -1; } if ((gpcsSetDpxValue(qd_dev, p, GT_TRUE) != GT_OK) || (gpcsSetForcedDpx(qd_dev, p, GT_TRUE) != GT_OK)) { printk(KERN_ERR "Force duplex FULL - Failed\n"); return -1; } if ((gpcsSetFCValue(qd_dev, p, GT_TRUE) != GT_OK) || (gpcsSetForcedFC(qd_dev, p, GT_TRUE) != GT_OK)) { printk(KERN_ERR "Force Flow Control - Failed\n"); return -1; } if ((gpcsSetLinkValue(qd_dev, p, GT_TRUE) != GT_OK) || (gpcsSetForcedLink(qd_dev, p, GT_TRUE) != GT_OK)) { printk(KERN_ERR "Force Link UP - Failed\n"); return -1; } continue; } printk(KERN_ERR " o Disable disconnected Switch Port #%d and force link down\n", p); if (gstpSetPortState(qd_dev, p, GT_PORT_DISABLE) != GT_OK) { printk(KERN_ERR "gstpSetPortState failed\n"); return -1; } if ((gpcsSetLinkValue(qd_dev, p, GT_FALSE) != GT_OK) || (gpcsSetForcedLink(qd_dev, p, GT_TRUE) != GT_OK)) { printk(KERN_ERR "Force Link DOWN - Failed\n"); return -1; } } return 0; }