Example #1
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;
}
Example #2
0
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=&gtw_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, &gt_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;
}
Example #3
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;
}