/******************************************************************************* * 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; }
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; } #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; }
/******************************************************************************* * 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; }