Exemple #1
0
int mv_switch_port_add(int switch_port, u16 vlan_grp_id, u16 port_map)
{
	int p;

	/* Set default VLAN_ID for port */
	if (gvlnSetPortVid(qd_dev, switch_port, MV_SWITCH_PORT_VLAN_ID(vlan_grp_id, switch_port)) != GT_OK) {
		printk(KERN_ERR "gvlnSetPortVid failed\n");
		return -1;
	}
	/* Map port to VLAN DB */
	if (gvlnSetPortVlanDBNum(qd_dev, switch_port, MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id)) != GT_OK) {
		printk(KERN_ERR "gvlnSetPortVlanDBNum failed\n");
		return -1;
	}

	/* Add port to the VLAN (CPU port is not part of VLAN) */
	if (mv_switch_port_based_vlan_set((port_map & ~(1 << qd_cpu_port)), 0) != 0)
		printk(KERN_ERR "mv_switch_port_based_vlan_set failed\n");

	/* Add port to vtu (used in tx) */
	if (mv_switch_vlan_in_vtu_set(vlan_grp_id, MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id),
				      (port_map | (1 << qd_cpu_port)))) {
		printk(KERN_ERR "mv_switch_vlan_in_vtu_set failed\n");
	}

	/* set vtu with each port private vlan id (used in rx) */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(port_map, p) && (p != qd_cpu_port)) {
			if (mv_switch_vlan_in_vtu_set(MV_SWITCH_PORT_VLAN_ID(vlan_grp_id, p),
						      MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id),
						      port_map & ~(1 << qd_cpu_port)) != 0) {
				printk(KERN_ERR "mv_switch_vlan_in_vtu_set failed\n");
			}
		}
	}

	/* Enable port */
	if (gstpSetPortState(qd_dev, switch_port, GT_PORT_FORWARDING) != GT_OK)
		printk(KERN_ERR "gstpSetPortState failed\n");
#ifdef CONFIG_MV_ETH_SWITCH_LINK
	if (!qsgmii_module) {
		/* Enable Phy Link Status Changed interrupt at Phy level for the port */
		if (gprtPhyIntEnable(qd_dev, switch_port, (GT_LINK_STATUS_CHANGED)) != GT_OK)
			printk(KERN_ERR "gprtPhyIntEnable failed port %d\n", switch_port);
	}
#endif /* CONFIG_MV_ETH_SWITCH_LINK */

	return 0;
}
Exemple #2
0
int mv_switch_port_del(int switch_port, u16 vlan_grp_id, u16 port_map)
{
	int p;

#ifdef CONFIG_MV_ETH_SWITCH_LINK
	if (!qsgmii_module) {
		/* Disable link change interrupts on unmapped port */
		if (gprtPhyIntEnable(qd_dev, switch_port, 0) != GT_OK)
			printk(KERN_ERR "gprtPhyIntEnable failed on port #%d\n", switch_port);
	}
#endif /* CONFIG_MV_ETH_SWITCH_LINK */

	/* Disable unmapped port */
	if (gstpSetPortState(qd_dev, switch_port, GT_PORT_DISABLE) != GT_OK)
		printk(KERN_ERR "gstpSetPortState failed on port #%d\n", switch_port);

	/* Remove port from the VLAN (CPU port is not part of VLAN) */
	if (mv_switch_port_based_vlan_set((port_map & ~(1 << qd_cpu_port)), 0) != 0)
		printk(KERN_ERR "mv_gtw_set_port_based_vlan failed\n");

	/* Remove port from vtu (used in tx) */
	if (mv_switch_vlan_in_vtu_set(vlan_grp_id, MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id),
				      (port_map | (1 << qd_cpu_port))) != 0) {
		printk(KERN_ERR "mv_gtw_set_vlan_in_vtu failed\n");
	}

	/* Remove port from vtu of each port private vlan id (used in rx) */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(port_map, p) && (p != qd_cpu_port)) {
			if (mv_switch_vlan_in_vtu_set(MV_SWITCH_PORT_VLAN_ID(vlan_grp_id, p),
						      MV_SWITCH_VLAN_TO_GROUP(vlan_grp_id),
						      (port_map & ~(1 << qd_cpu_port))) != 0)
				printk(KERN_ERR "mv_gtw_set_vlan_in_vtu failed\n");
		}
	}

	return 0;
}
Exemple #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;
    }

    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;
}
Exemple #4
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;
}
Exemple #5
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;
}
/*******************************************************************************
* qdLoadDriver
*
* DESCRIPTION:
*       QuarterDeck Driver Initialization Routine. 
*       This is the first routine that needs be called by system software. 
*       It takes *cfg from system software, and retures a pointer (*dev) 
*       to a data structure which includes infomation related to this QuarterDeck
*       device. This pointer (*dev) is then used for all the API functions. 
*
* INPUTS:
*       cfg  - Holds device configuration parameters provided by system software.
*
* OUTPUTS:
*       dev  - Holds device information to be used for each API call.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_ALREADY_EXIST    - if device already started
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
* 	qdUnloadDriver is also provided to do driver cleanup.
*
*******************************************************************************/
GT_STATUS qdLoadDriver
(
    IN  GT_SYS_CONFIG   *cfg,
    OUT GT_QD_DEV	*dev
)
{
    GT_STATUS   retVal;
	GT_LPORT	port;

    DBG_INFO(("qdLoadDriver Called.\n"));

    /* Check for parameters validity        */
    if(dev == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    /* Check for parameters validity        */
    if(cfg == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    /* The initialization was already done. */
    if(dev->devEnabled)
    {
        DBG_INFO(("QuarterDeck already started.\n"));
        return GT_ALREADY_EXIST;
    }

    if(gtRegister(dev,&(cfg->BSPFunctions)) != GT_TRUE)
    {
       DBG_INFO(("gtRegister Failed.\n"));
       return GT_FAIL;
    }
	dev->accessMode = (GT_U8)cfg->mode.scanMode;
	if (dev->accessMode == SMI_MULTI_ADDR_MODE)
	{
		dev->baseRegAddr = 0;
		dev->phyAddr = (GT_U8)cfg->mode.baseAddr;
	}
	else
	{
		dev->baseRegAddr = (GT_U8)cfg->mode.baseAddr;
		dev->phyAddr = 0;
	}

    /* Initialize the driver    */
    retVal = driverConfig(dev);
    if(retVal != GT_OK)
    {
        DBG_INFO(("driverConfig Failed.\n"));
        return retVal;
    }

    /* Initialize dev fields.         */
    dev->cpuPortNum = cfg->cpuPortNum;
    dev->maxPhyNum = 5;
    dev->devGroup = 0;
    dev->devStorage = 0;

    /* Assign Device Name */
    switch(dev->deviceId)
    {
		case GT_88E6021:
				dev->numOfPorts = 3;
				dev->maxPorts = 3;
				dev->maxPhyNum = 2;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6021;
				break;

		case GT_88E6051:
				dev->numOfPorts = 5;
				dev->maxPorts = 5;
				dev->maxPhyNum = 5;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6051;
				break;

		case GT_88E6052:
				dev->numOfPorts = 7;
				dev->maxPorts = 7;
				dev->maxPhyNum = 5;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6052;
				break;

		case GT_88E6060:
				if((dev->cpuPortNum != 4)&&(dev->cpuPortNum != 5))
				{
					return GT_FAIL;
				}
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 5;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6060;
				break;

		case GT_88E6031:
				dev->numOfPorts = 3;
				dev->maxPorts = 6;
				dev->maxPhyNum = 3;
				dev->validPortVec = 0x31;	/* port 0, 4, and 5 */
				dev->validPhyVec = 0x31;	/* port 0, 4, and 5 */
				dev->devName = DEV_88E6061;
				break;

		case GT_88E6061:
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 6;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6061;
				break;

		case GT_88E6035:
				dev->numOfPorts = 3;
				dev->maxPorts = 6;
				dev->maxPhyNum = 3;
				dev->validPortVec = 0x31;	/* port 0, 4, and 5 */
				dev->validPhyVec = 0x31;	/* port 0, 4, and 5 */
				dev->devName = DEV_88E6065;
				break;

		case GT_88E6055:
				dev->numOfPorts = 5;
				dev->maxPorts = 6;
				dev->maxPhyNum = 5;
				dev->validPortVec = 0x2F;	/* port 0,1,2,3, and 5 */
				dev->validPhyVec = 0x2F;	/* port 0,1,2,3, and 5 */
				dev->devName = DEV_88E6065;
				break;

		case GT_88E6065:
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 6;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6065;
				break;

		case GT_88E6063:
				dev->numOfPorts = 7;
				dev->maxPorts = 7;
				dev->maxPhyNum = 5;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6063;
				break;

		case GT_FH_VPN:
				dev->numOfPorts = 7;
				dev->maxPorts = 7;
				dev->maxPhyNum = 5;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_FH_VPN;
				break;

		case GT_FF_EG:
				if(dev->cpuPortNum != 5)
				{
					return GT_FAIL;
				}
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 5;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_FF_EG;
				break;

		case GT_FF_HG:
				dev->numOfPorts = 7;
				dev->maxPorts = 7;
				dev->maxPhyNum = 5;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_FF_HG;
				break;

		case GT_88E6083:
				dev->numOfPorts = 10;
				dev->maxPorts = 10;
				dev->maxPhyNum = 8;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6083;
				break;

		case GT_88E6153:
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 6;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6183;
				break;

		case GT_88E6181:
				dev->numOfPorts = 8;
				dev->maxPorts = 8;
				dev->maxPhyNum = 8;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6181;
				break;

		case GT_88E6183:
				dev->numOfPorts = 10;
				dev->maxPorts = 10;
				dev->maxPhyNum = 10;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6183;
				break;

		case GT_88E6093:
				dev->numOfPorts = 11;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6093;
				break;

		case GT_88E6092:
				dev->numOfPorts = 11;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6092;
				break;

		case GT_88E6095:
				dev->numOfPorts = 11;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6095;
				break;

		case GT_88E6045:
				dev->numOfPorts = 6;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = 0x60F;
				dev->validPhyVec = 0x60F;
				dev->devName = DEV_88E6095;
				break;

		case GT_88E6097:
				dev->numOfPorts = 11;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6097;
				break;

		case GT_88E6096:
				dev->numOfPorts = 11;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6096;
				break;

		case GT_88E6047:
				dev->numOfPorts = 6;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = 0x60F;
				dev->validPhyVec = 0x60F;
				dev->devName = DEV_88E6097;
				break;

		case GT_88E6046:
				dev->numOfPorts = 6;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = 0x60F;
				dev->validPhyVec = 0x60F;
				dev->devName = DEV_88E6096;
				break;

		case GT_88E6085:
				dev->numOfPorts = 10;
				dev->maxPorts = 11;
				dev->maxPhyNum = 11;
				dev->validPortVec = 0x6FF;
				dev->validPhyVec = 0x6FF;
				dev->devName = DEV_88E6096;
				break;

		case GT_88E6152:
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 6;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6182;
				break;

		case GT_88E6155:
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 6;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6185;
				break;

		case GT_88E6182:
				dev->numOfPorts = 10;
				dev->maxPorts = 10;
				dev->maxPhyNum = 10;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6182;
				break;

		case GT_88E6185:
				dev->numOfPorts = 10;
				dev->maxPorts = 10;
				dev->maxPhyNum = 10;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->devName = DEV_88E6185;
				break;

		case GT_88E6121:
				dev->numOfPorts = 3;
				dev->maxPorts = 8;
				dev->maxPhyNum = 3;
				dev->validPortVec = 0xE;	/* port 1, 2, and 3 */
				dev->validPhyVec = 0xE;		/* port 1, 2, and 3 */
				dev->devName = DEV_88E6108;
				break;

		case GT_88E6122:
				dev->numOfPorts = 6;
				dev->maxPorts = 8;
				dev->maxPhyNum = 16;
				dev->validPortVec = 0x7E;	/* port 1 ~ 6 */
				dev->validPhyVec = 0xF07E;	/* port 1 ~ 6, 12 ~ 15 (serdes) */
				dev->validSerdesVec = 0xF000;
				dev->devName = DEV_88E6108;
				break;

		case GT_88E6131:
		case GT_88E6108:
				dev->numOfPorts = 8;
				dev->maxPorts = 8;
				dev->maxPhyNum = 16;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = (1 << dev->maxPhyNum) - 1;
				dev->validSerdesVec = 0xF000;
				dev->devName = DEV_88E6108;
				break;

		case GT_88E6123:
				dev->numOfPorts = 3;
				dev->maxPorts = 6;
				dev->maxPhyNum = 14;
				dev->validPortVec = 0x23;
				dev->validPhyVec = 0x303F;
				dev->validSerdesVec = 0x3000;
				dev->devName = DEV_88E6161;
				break;

		case GT_88E6140:
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 14;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = 0x303F;
				dev->validSerdesVec = 0x3000;
				dev->devName = DEV_88E6165;
				break;

		case GT_88E6161:
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 14;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = 0x303F;
				dev->validSerdesVec = 0x3000;
				dev->devName = DEV_88E6161;
				break;

		case GT_88E6165:
				dev->numOfPorts = 6;
				dev->maxPorts = 6;
				dev->maxPhyNum = 14;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = 0x303F;
				dev->validSerdesVec = 0x3000;
				dev->devName = DEV_88E6165;
				break;

		case GT_KW2_INT :
				dev->deviceId = GT_88E6351;
				/* fall through */
		case GT_88E6351:
				dev->numOfPorts = 7;
				dev->maxPorts = 7;
				dev->maxPhyNum = 7;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = 0x7F;
				dev->devName = DEV_88E6351;
				break;

		case GT_88E6175:
				dev->numOfPorts = 7;
				dev->maxPorts = 7;
				dev->maxPhyNum = 7;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = 0x7F;
				dev->devName = DEV_88E6175;
				break;

		case GT_88E6125 :
				dev->numOfPorts = 4;
				dev->maxPorts = 7;
				dev->maxPhyNum = 7;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPortVec &= ~(0x7);
				dev->validPhyVec = 0x78;
				dev->devName = DEV_88E6171;
				break;

		case GT_88E6171 :
				dev->numOfPorts = 7;
				dev->maxPorts = 7;
				dev->maxPhyNum = 7;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = 0x7F;
				dev->devName = DEV_88E6171;
				break;

		case GT_88E6321 :
				dev->numOfPorts = 4;
				dev->maxPorts = 7;
				dev->maxPhyNum = 7;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPortVec &= ~(0x7);
				dev->validPhyVec = 0x78;
				dev->devName = DEV_88E6371;
				break;

		case GT_88E6350 :
				dev->numOfPorts = 7;
				dev->maxPorts = 7;
				dev->maxPhyNum = 7;
				dev->validPortVec = (1 << dev->numOfPorts) - 1;
				dev->validPhyVec = 0x7F;
				dev->devName = DEV_88E6371;
				break;

		default:
				DBG_INFO(("Unknown Device. Initialization failed\n"));
				return GT_FAIL;
    }

    dev->cpuPortNum = GT_PORT_2_LPORT(cfg->cpuPortNum);

    if(dev->cpuPortNum == GT_INVALID_PORT)
	{
    	if(GT_LPORT_2_PORT((GT_LPORT)cfg->cpuPortNum) != GT_INVALID_PORT)
		{
		    dev->cpuPortNum = cfg->cpuPortNum;
		}
		else
		{
			return GT_BAD_CPU_PORT;
		}
	}

    /* Initialize the MultiAddress Register Access semaphore.    */
    if((dev->multiAddrSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
        DBG_INFO(("semCreate Failed.\n"));
        qdUnloadDriver(dev);
        return GT_FAIL;
    }

    /* Initialize the ATU semaphore.    */
    if((dev->atuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
        DBG_INFO(("semCreate Failed.\n"));
        qdUnloadDriver(dev);
        return GT_FAIL;
    }

    /* Initialize the VTU semaphore.    */
    if((dev->vtuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
        DBG_INFO(("semCreate Failed.\n"));
		qdUnloadDriver(dev);
        return GT_FAIL;
    }

    /* Initialize the STATS semaphore.    */
    if((dev->statsRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
        DBG_INFO(("semCreate Failed.\n"));
		qdUnloadDriver(dev);
        return GT_FAIL;
    }

    /* Initialize the PIRL semaphore.    */
    if((dev->pirlRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
        DBG_INFO(("semCreate Failed.\n"));
		qdUnloadDriver(dev);
        return GT_FAIL;
    }

    /* Initialize the PTP semaphore.    */
    if((dev->ptpRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
        DBG_INFO(("semCreate Failed.\n"));
		qdUnloadDriver(dev);
        return GT_FAIL;
    }

    /* Initialize the Table semaphore.    */
    if((dev->tblRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
		DBG_INFO(("semCreate Failed.\n"));
		qdUnloadDriver(dev);
		return GT_FAIL;
    }

    /* Initialize the EEPROM Configuration semaphore.    */
    if((dev->eepromRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
		DBG_INFO(("semCreate Failed.\n"));
		qdUnloadDriver(dev);
		return GT_FAIL;
    }

    /* Initialize the PHY Device Register Access semaphore.    */
    if((dev->phyRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0)
    {
        DBG_INFO(("semCreate Failed.\n"));
        qdUnloadDriver(dev);
        return GT_FAIL;
    }

    /* Initialize the ports states to forwarding mode. */
    if(cfg->initPorts == GT_TRUE)
    {
		for (port=0; port<dev->numOfPorts; port++)
		{
			if((retVal = gstpSetPortState(dev,port,GT_PORT_FORWARDING)) != GT_OK)
   			{
	    	    DBG_INFO(("Failed.\n"));
				qdUnloadDriver(dev);
   		    	return retVal;
	    	}
		}
    }

    if(cfg->skipInitSetup == GT_SKIP_INIT_SETUP)
	{
	    dev->devEnabled = 1;
    	dev->devNum = cfg->devNum;

	    DBG_INFO(("OK.\n"));
    	return GT_OK;
	}

	if(IS_IN_DEV_GROUP(dev,DEV_ENHANCED_CPU_PORT))
	{
		if((retVal = gsysSetRsvd2CpuEnables(dev,0)) != GT_OK)
		{
	        DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n"));
			qdUnloadDriver(dev);
			return retVal;
		}

		if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK)
		{
	        DBG_INFO(("gsysSetRsvd2Cpu failed.\n"));
			qdUnloadDriver(dev);
			return retVal;
		}
	}

	if (IS_IN_DEV_GROUP(dev,DEV_CPU_DEST_PER_PORT))
	{
		for (port=0; port<dev->numOfPorts; port++)
		{
			retVal = gprtSetCPUPort(dev,port,dev->cpuPortNum);
		    if(retVal != GT_OK)
    		{
	    	    DBG_INFO(("Failed.\n"));
				qdUnloadDriver(dev);
	   	    	return retVal;
		    }
		}
	}

	if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT))
	{
		retVal = gsysSetCPUPort(dev,dev->cpuPortNum);
	    if(retVal != GT_OK)
   		{
    	    DBG_INFO(("Failed.\n"));
			qdUnloadDriver(dev);
   	    	return retVal;
	    }
	}

	if(IS_IN_DEV_GROUP(dev,DEV_CPU_DEST))
	{
		retVal = gsysSetCPUDest(dev,dev->cpuPortNum);
	    if(retVal != GT_OK)
   		{
    	    DBG_INFO(("Failed.\n"));
			qdUnloadDriver(dev);
   	    	return retVal;
	    }
	}

	if(IS_IN_DEV_GROUP(dev,DEV_MULTICAST))
	{
		if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK)
		{
	        DBG_INFO(("gsysSetRsvd2Cpu failed.\n"));
			qdUnloadDriver(dev);
			return retVal;
		}
	}

	if (IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE))
	{
		retVal = gpirlInitialize(dev);
	    if(retVal != GT_OK)
   		{
    	    DBG_INFO(("Failed.\n"));
			qdUnloadDriver(dev);
   	    	return retVal;
	    }
	}

	if (IS_IN_DEV_GROUP(dev,DEV_PIRL2_RESOURCE))
	{
		retVal = gpirl2Initialize(dev);
	    if(retVal != GT_OK)
   		{
    	    DBG_INFO(("Failed.\n"));
			qdUnloadDriver(dev);
   	    	return retVal;
	    }
	}

    dev->devEnabled = 1;
    dev->devNum = cfg->devNum;

    DBG_INFO(("OK.\n"));
    return GT_OK;
}
/*******************************************************************************
* gstpSetMode
*
* DESCRIPTION:
*       This routine Enable the Spanning tree.
*
* INPUTS:
*       en - GT_TRUE for enable, GT_FALSE for disable.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       when enabled, this function sets all port to blocking state, and inserts
*       the BPDU MAC into the ATU to be captured to CPU, on disable all port are
*       being modified to be in forwarding state.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gstpSetMode
(
    IN GT_QD_DEV *dev,
    IN GT_BOOL  en
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_PORT_STP_STATE   state;      /* STP state to be set.         */
    GT_ATU_ENTRY        atuEntry;   /* The ATU entry data to be set */
    GT_U8           i;

    DBG_INFO(("gstpSetMode Called.\n"));
    if(dev->deviceId == GT_88E6051)
    {
        DBG_INFO(("Failed.\n"));
        return GT_FAIL;
    }

    if((en == GT_TRUE) && (dev->stpMode == 1))
    {
        DBG_INFO(("OK.\n"));
        return GT_OK;
    }

    /* Set the STP state in the relevant register.  */
    if(en == GT_TRUE)
        state = GT_PORT_BLOCKING;
    else
        state = GT_PORT_FORWARDING;

    for(i = 0; i < dev->numOfPorts; i++)
    {
        retVal = gstpSetPortState(dev,i,state);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }
    }

    /* Set the Atu entry parameters.    */
    atuEntry.macAddr.arEther[0] = 0x01;
    atuEntry.macAddr.arEther[1] = 0x80;
    atuEntry.macAddr.arEther[2] = 0xC2;
    atuEntry.macAddr.arEther[3] = 0x00;
    atuEntry.macAddr.arEther[4] = 0x00;
    atuEntry.macAddr.arEther[5] = 0x00;
    atuEntry.portVec = ( 1 << GT_PORT_2_LPORT(dev->cpuPortNum));
    atuEntry.prio    = 3;
	atuEntry.DBNum = 0;
    atuEntry.entryState.mcEntryState = GT_MC_PRIO_MGM_STATIC;

    if(en == GT_TRUE)
    {
        retVal = gfdbAddMacEntry(dev,&atuEntry);
    }
    else if((en == GT_FALSE) && (dev->stpMode != 0))
        retVal = gfdbDelMacEntry(dev,&(atuEntry.macAddr));
    else
        retVal = GT_OK;

    if(en == GT_TRUE)
        dev->stpMode = 1;
    else
        dev->stpMode = 2;
    if(retVal == GT_OK)
        DBG_INFO(("OK.\n"));
    else
        DBG_INFO(("Failed.\n"));
    return retVal;
}
Exemple #8
0
GT_STATUS qdInit(void)
{
	GT_STATUS	 status = GT_OK;	
	unsigned int i;

	status = qdStart();
	if (GT_OK != status)
	{
		gtOsPrintf("qdStart is failed: status = 0x%x\n", status);
		return status;
	}

#ifdef DB_6093_88E6218
	/* start 88E6090 device, assumes SMI Address 0x11 and CPU Port 10 */

	if(loadDev(qd_ext, SMI_MULTI_ADDR_MODE, 0x11, 10) == NULL)
	{
		gtOsPrintf("Failed to start External Device. Please check the SMI Address 0x11!\n");
	}

	/* allow larger than 1522 bytes of frame (header + marvell tag) */
	gsysSetMaxFrameSize(qd_dev,GT_FALSE);

#endif

    for (i=0; i<qd_dev->numOfPorts; i++) 
    {
      /* default port prio to three */
      gcosSetPortDefaultTc(qd_dev, i, 3);       
      /* disable IP TOS Prio */
      gqosIpPrioMapEn(qd_dev, i, GT_FALSE);  
      /* disable QOS Prio */
      gqosUserPrioMapEn(qd_dev, i, GT_FALSE);
      /* Force flow control for all ports */
      gprtSetForceFc(qd_dev, i, GT_FALSE);
    }

	/* Enable port #6 */
	status = gstpSetPortState(qd_dev, 6, GT_PORT_FORWARDING);

	if((status = gprtClearAllCtr(qd_dev)) != GT_OK)
	{		
		return status;
	}	
	for (i=0; i<GT_CPU_SWITCH_PORT; i++)
	{
		gprtSetMcRateLimit(qd_dev, i, GT_MC_100_PERCENT_RL);
	}

#ifdef QD_DEBUG
    for (i=0; i<qd_dev->numOfPorts; i++) 
	{
		short sdata;
	  
	  	hwReadPortReg(qd_dev, i, 0x4, &sdata);
	  	gtOsPrintf("Control reg for port[%d] is: %x\n",i,sdata);

	  	hwReadPortReg(qd_dev, i, 0x0, &sdata);
	  	gtOsPrintf("Status reg for port[%d] is: %x\n",i,sdata);

	}
    qdStatus();
#endif /* QD_DEBUG */

    gtOsPrintf("QD initiated\n");

	return status;    
}
Exemple #9
0
int mv_switch_init(int mtu, unsigned int switch_ports_mask)
{
	unsigned int p;
	unsigned char cnt;
	GT_LPORT port_list[MAX_SWITCH_PORTS];

	if (qd_dev == NULL) {
		printk(KERN_ERR "%s: qd_dev not initialized, call mv_switch_load() first\n", __func__);
		return -1;
	}

	/* general Switch initialization - relevant for all Switch devices */

	/* disable all ports */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p))
			if (gstpSetPortState(qd_dev, p, GT_PORT_DISABLE) != GT_OK) {
				printk(KERN_ERR "gstpSetPortState failed\n");
				return -1;
			}
	}

	/* flush All counters for all ports */
	if (gstatsFlushAll(qd_dev) != GT_OK)
		printk(KERN_ERR "gstatsFlushAll failed\n");

	/* set all ports not to unmodify the vlan tag on egress */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p)) {
			if (gprtSetEgressMode(qd_dev, p, GT_UNMODIFY_EGRESS) != GT_OK) {
				printk(KERN_ERR "gprtSetEgressMode GT_UNMODIFY_EGRESS failed\n");
				return -1;
			}
		}
	}

	/* initializes the PVT Table (cross-chip port based VLAN) to all one's (initial state) */
	if (gpvtInitialize(qd_dev) != GT_OK) {
		printk(KERN_ERR "gpvtInitialize failed\n");
		return -1;
	}

	/* set all ports to work in Normal mode */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p)) {
			if (gprtSetFrameMode(qd_dev, p, GT_FRAME_MODE_NORMAL) != GT_OK) {
				printk(KERN_ERR "gprtSetFrameMode GT_FRAME_MODE_NORMAL failed\n");
				return -1;
			}
		}
	}

	/* set priorities rules */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p)) {
			/* default port priority to queue zero */
			if (gcosSetPortDefaultTc(qd_dev, p, 0) != GT_OK)
				printk(KERN_ERR "gcosSetPortDefaultTc failed (port %d)\n", p);

			/* enable IP TOS Prio */
			if (gqosIpPrioMapEn(qd_dev, p, GT_TRUE) != GT_OK)
				printk(KERN_ERR "gqosIpPrioMapEn failed (port %d)\n", p);

			/* set IP QoS */
			if (gqosSetPrioMapRule(qd_dev, p, GT_FALSE) != GT_OK)
				printk(KERN_ERR "gqosSetPrioMapRule failed (port %d)\n", p);

			/* disable Vlan QoS Prio */
			if (gqosUserPrioMapEn(qd_dev, p, GT_FALSE) != GT_OK)
				printk(KERN_ERR "gqosUserPrioMapEn failed (port %d)\n", p);
		}
	}

	/* specific Switch initialization according to Switch ID */
	switch (qd_dev->deviceId) {
	case GT_88E6161:
	case GT_88E6165:
	case GT_88E6171:
	case GT_88E6351:
	case GT_88E6172:
	case GT_88E6176:
		/* set Header Mode in all ports to False */
		for (p = 0; p < qd_dev->numOfPorts; p++) {
			if (MV_BIT_CHECK(switch_ports_mask, p)) {
				if (gprtSetHeaderMode(qd_dev, p, GT_FALSE) != GT_OK) {
					printk(KERN_ERR "gprtSetHeaderMode GT_FALSE failed\n");
					return -1;
				}
			}
		}

		if (gprtSetHeaderMode(qd_dev, qd_cpu_port, GT_TRUE) != GT_OK) {
			printk(KERN_ERR "gprtSetHeaderMode GT_TRUE failed\n");
			return -1;
		}

		mv_switch_jumbo_mode_set(mtu);
		break;

	default:
		printk(KERN_ERR "Unsupported Switch. Switch ID is 0x%X.\n", qd_dev->deviceId);
		return -1;
	}

	/* The switch CPU port is not part of the VLAN, but rather connected by tunneling to each */
	/* of the VLAN's ports. Our MAC addr will be added during start operation to the VLAN DB  */
	/* at switch level to forward packets with this DA to CPU port.                           */
	SWITCH_DBG(SWITCH_DBG_LOAD, ("Enabling Tunneling on ports: "));
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p) && (p != qd_cpu_port)) {
			if (gprtSetVlanTunnel(qd_dev, p, GT_TRUE) != GT_OK) {
				printk(KERN_ERR "gprtSetVlanTunnel failed (port %d)\n", p);
				return -1;
			} else {
				SWITCH_DBG(SWITCH_DBG_LOAD, ("%d ", p));
			}
		}
	}
	SWITCH_DBG(SWITCH_DBG_LOAD, ("\n"));

	/* set cpu-port with port-based vlan to all other ports */
	SWITCH_DBG(SWITCH_DBG_LOAD, ("cpu port-based vlan:"));
	for (p = 0, cnt = 0; p < qd_dev->numOfPorts; p++) {
		if (p != qd_cpu_port) {
			SWITCH_DBG(SWITCH_DBG_LOAD, ("%d ", p));
			port_list[cnt] = p;
			cnt++;
		}
	}
	SWITCH_DBG(SWITCH_DBG_LOAD, ("\n"));
	if (gvlnSetPortVlanPorts(qd_dev, qd_cpu_port, port_list, cnt) != GT_OK) {
		printk(KERN_ERR "gvlnSetPortVlanPorts failed\n");
		return -1;
	}

	if (gfdbFlush(qd_dev, GT_FLUSH_ALL) != GT_OK)
		printk(KERN_ERR "gfdbFlush failed\n");

	mv_switch_link_detection_init();

	/* Configure Ethernet related LEDs, currently according to Switch ID */
	switch (qd_dev->deviceId) {
	case GT_88E6161:
	case GT_88E6165:
	case GT_88E6171:
	case GT_88E6351:
	case GT_88E6172:
	case GT_88E6176:
		break;		/* do nothing */

	default:
		for (p = 0; p < qd_dev->numOfPorts; p++) {
			if ((p != qd_cpu_port) && ((p))) {
				if (gprtSetPhyReg(qd_dev, p, 22, 0x1FFA)) {
					/* Configure Register 22 LED0 to 0xA for Link/Act */
					printk(KERN_ERR "gprtSetPhyReg failed (port=%d)\n", p);
				}
			}
		}
		break;
	}

	/* enable all relevant ports (ports connected to the MAC or external ports) */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p)) {
			if ((mvBoardSwitchPortMap(MV_SWITCH_DEF_INDEX, p) != -1) ||
			    (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_0) == p) ||
			    (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_1) == p)) {
				if (gstpSetPortState(qd_dev, p, GT_PORT_FORWARDING) != GT_OK) {
					printk(KERN_ERR "gstpSetPortState failed\n");
					return -1;
				}
			}
		}
	}

#ifdef SWITCH_DEBUG
	/* for debug: */
	mv_switch_status_print();
#endif

	return 0;
}
Exemple #10
0
int mv_switch_load(unsigned int switch_ports_mask)
{
	int p;
	GT_STU_ENTRY	stuEntry;

	printk(KERN_ERR "  o Loading Switch QuarterDeck driver\n");

	if (qd_dev) {
		printk(KERN_ERR "    o %s: Already initialized\n", __func__);
		return 0;
	}

	memset((char *)&qd_cfg, 0, sizeof(GT_SYS_CONFIG));
	spin_lock_init(&switch_lock);

	/* init config structure for qd package */
	qd_cfg.BSPFunctions.readMii = mv_switch_mii_read;
	qd_cfg.BSPFunctions.writeMii = mv_switch_mii_write;
	qd_cfg.BSPFunctions.semCreate = NULL;
	qd_cfg.BSPFunctions.semDelete = NULL;
	qd_cfg.BSPFunctions.semTake = NULL;
	qd_cfg.BSPFunctions.semGive = NULL;
	qd_cfg.initPorts = GT_TRUE;
	qd_cfg.cpuPortNum = mvBoardSwitchCpuPortGet(MV_SWITCH_DEF_INDEX);
	if (mvBoardSmiScanModeGet(MV_SWITCH_DEF_INDEX) == 1) {
		qd_cfg.mode.baseAddr = 0;
		qd_cfg.mode.scanMode = SMI_MANUAL_MODE;
	} else if (mvBoardSmiScanModeGet(MV_SWITCH_DEF_INDEX) == 2) {
		qd_cfg.mode.scanMode = SMI_MULTI_ADDR_MODE;
		if (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_0) != -1) {
			qd_cfg.mode.baseAddr = mvBoardPhyAddrGet(MV_ETH_PORT_0);
		} else if (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_1) != -1) {
			qd_cfg.mode.baseAddr = mvBoardPhyAddrGet(MV_ETH_PORT_1);
		} else {
			printk(KERN_ERR "mv_switch_load failed: Wrong SCAN mode\n");
			return -1;
		}
	}

	/* load switch sw package */
	if (qdLoadDriver(&qd_cfg, &qddev) != GT_OK) {
		printk(KERN_ERR "qdLoadDriver failed\n");
		return -1;
	}
	qd_dev = &qddev;
	qd_cpu_port = qd_cfg.cpuPortNum;

	/* Create entry in STU table  */
	memset(&stuEntry, 0, sizeof(GT_STU_ENTRY));
	stuEntry.sid = 1; /* required: ((sid > 0) && (sid < 0x3F)) */
	gstuAddEntry(qd_dev, &stuEntry);

	printk(KERN_ERR "    o Device ID     : 0x%x\n", qd_dev->deviceId);
	printk(KERN_ERR "    o No. of Ports  : %d\n", qd_dev->numOfPorts);
	printk(KERN_ERR "    o CPU Port      : %ld\n", qd_dev->cpuPortNum);

	qsgmii_module = mvBoardIsQsgmiiModuleConnected();
	if (qsgmii_module)
		printk(KERN_ERR "    o QSGMII Module Detected\n");

	gephy_on_port = mvBoardGePhySwitchPortGet();
	if (gephy_on_port >= 0)
		printk(KERN_ERR "    o Internal GE PHY Connected to Switch Port %d Detected\n", gephy_on_port);

	rgmiia_on_port = mvBoardRgmiiASwitchPortGet();
	if (rgmiia_on_port >= 0)
		printk(KERN_ERR "    o RGMII-A Connected to Switch Port %d Detected\n", rgmiia_on_port);

	/* disable all disconnected ports */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		/* Do nothing for ports that are not part of the given switch_port_mask */
		if (!MV_BIT_CHECK(switch_ports_mask, p))
			continue;

		if (mvBoardSwitchPortMap(MV_SWITCH_DEF_INDEX, p) != -1) {
			/* Switch port mapped to connector on the board */

			if ((gpcsSetFCValue(qd_dev, p, GT_FALSE) != GT_OK) ||
			    (gpcsSetForcedFC(qd_dev, p, GT_FALSE) != GT_OK)) {
				printk(KERN_ERR "Force Flow Control - Failed\n");
				return -1;
			}
#if 0
			/* TODO - decide if we want to enable auto-negotiation of Flow Control for external ports */
			if (qsgmii_module) {
				/* TODO - configure ports via QSGMII registers */
			} else {
				GT_STATUS status;

				status = gprtSetPause(qd_dev, p, GT_PHY_PAUSE);
				if (status != GT_OK)
					printk(KERN_ERR "Failed set pause for switch port #%d: status = %d\n", p, status);
			}
#endif
			continue;
		}

		if ((mvBoardSwitchConnectedPortGet(MV_ETH_PORT_0) == p) ||
		    (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_1) == p)) {
			/* Switch port connected to GMAC - force link UP - 1000 Full with FC */
			printk(KERN_ERR "    o Setting Switch Port #%d connected to GMAC port for 1000 Full with FC\n", p);
			if (gpcsSetForceSpeed(qd_dev, p, PORT_FORCE_SPEED_1000_MBPS) != GT_OK) {
				printk(KERN_ERR "Force speed 1000mbps - Failed\n");
				return -1;
			}

			if ((gpcsSetDpxValue(qd_dev, p, GT_TRUE) != GT_OK) ||
			    (gpcsSetForcedDpx(qd_dev, p, GT_TRUE) != GT_OK)) {
				printk(KERN_ERR "Force duplex FULL - Failed\n");
				return -1;
			}

			if ((gpcsSetFCValue(qd_dev, p, GT_TRUE) != GT_OK) ||
			    (gpcsSetForcedFC(qd_dev, p, GT_TRUE) != GT_OK)) {
				printk(KERN_ERR "Force Flow Control - Failed\n");
				return -1;
			}

			if ((gpcsSetLinkValue(qd_dev, p, GT_TRUE) != GT_OK) ||
			    (gpcsSetForcedLink(qd_dev, p, GT_TRUE) != GT_OK)) {
				printk(KERN_ERR "Force Link UP - Failed\n");
				return -1;
			}
			continue;
		}
		printk(KERN_ERR "    o Disable disconnected Switch Port #%d and force link down\n", p);

		if (gstpSetPortState(qd_dev, p, GT_PORT_DISABLE) != GT_OK) {
			printk(KERN_ERR "gstpSetPortState failed\n");
			return -1;
		}
		if ((gpcsSetLinkValue(qd_dev, p, GT_FALSE) != GT_OK) ||
		    (gpcsSetForcedLink(qd_dev, p, GT_TRUE) != GT_OK)) {
			printk(KERN_ERR "Force Link DOWN - Failed\n");
			return -1;
		}
	}
	return 0;
}