Esempio n. 1
0
/*******************************************************************************
* gprtGetSerdesMode
*
* DESCRIPTION:
*       This routine reads Serdes Interface Mode.
*
* INPUTS:
*        port -  The physical SERDES device address(4/5)
*
* OUTPUTS:
*       mode    - Serdes Interface Mode
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       logical port number is supported only for the devices made production 
*       before 2009. 
*  (Serdes devices: 88E6131, 88E6122, 88E6108, 88E6161, 88E6165, 88E6352 and 88E320 family)
*
*******************************************************************************/
GT_STATUS gprtGetSerdesMode
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT     port,
    IN  GT_SERDES_MODE *mode
)
{
    GT_U16          u16Data;           /* The register's read data.    */
    GT_U8           hwPort,  serdesPort;         /* the physical port number     */
	  GT_U8           pageNum = _getSerdesPageNumber(dev);
    GT_PHY_INFO        serdesInfo;


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

    if(!IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE))
    {
        return GT_NOT_SUPPORTED;
    }

    /* check if input is logical port number */    
    hwPort = GT_LPORT_2_PORT(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);



    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }


    /* Get Serdes Register. */
    if(hwReadPagedPhyReg(dev,serdesPort,pageNum, 16,serdesInfo.anyPage,&u16Data) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    *mode = u16Data&0x3;

    gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;
}
Esempio n. 2
0
GT_STATUS gprtGetSerdesPowerDownSt
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
OUT GT_BOOL  *state
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort, serdesPort;         /* the physical port number     */
    GT_U16             u16Data;
	  GT_U8           pageNum = _getSerdesPageNumber(dev);
    GT_PHY_INFO        serdesInfo;

    DBG_INFO(("gprtGetSerdesPowerDownSt Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    /* check if the port is configurable */
    if(!IS_CONFIGURABLE_PHY(dev,hwPort))
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }


    if((retVal=hwGetPagedPhyRegField(dev,serdesPort, pageNum,QD_SERDES_CONTROL_REG,11,1,serdesInfo.anyPage,&u16Data)) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return retVal;
    }
    BIT_2_BOOL(u16Data, *state);

    gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;
}
Esempio n. 3
0
/*******************************************************************************
* gprtSetSerdesReg
*
* DESCRIPTION:
*       This routine writes Phy Serdes Registers.
*
* INPUTS:
*       port -    The logical port number.
*       regAddr - The register's address.
*
* OUTPUTS:
*       data    - The read register's data.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtSetSerdesReg
(
    IN  GT_QD_DEV        *dev,
    IN  GT_LPORT        port,
    IN  GT_U32            regAddr,
    IN  GT_U16            data
)
{
    GT_U8           hwPort, serdesPort;         /* the physical port number     */
	GT_U8           pageNum = _getSerdesPageNumber(dev);
    GT_PHY_INFO        serdesInfo;


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

    if(!IS_IN_DEV_GROUP(dev,DEV_SERDES_UP_PORT))
    {
        return GT_NOT_SUPPORTED;
    }

/*    hwPort = GT_LPORT_2_PHY(port); */
    hwPort = qdLong2Char(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }


    /* Write to Serdes Register */
    if(hwWritePagedPhyReg(dev,serdesPort,pageNum, (GT_U8)regAddr,serdesInfo.anyPage,data) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;
}
Esempio n. 4
0
GT_STATUS gprtSetSerdesLoopback
(
    IN GT_QD_DEV *dev,
    IN GT_LPORT  port,
    IN GT_BOOL   enable
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort, serdesPort;         /* the physical port number     */
    GT_U16             u16Data;
    GT_PHY_INFO        serdesInfo;
	  GT_U8           pageNum = _getSerdesPageNumber(dev);

    DBG_INFO(("gprtSetSerdesLoopback Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);

    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown SERDES device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    BOOL_2_BIT(enable,u16Data);

    /* Write to Phy Control Register.  */
    retVal = hwSetPagedPhyRegField(dev,serdesPort, pageNum,QD_SERDES_CONTROL_REG,14,1,serdesInfo.anyPage,u16Data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
    }
    else
    {
        DBG_INFO(("OK.\n"));
    }
    gtSemGive(dev,dev->phyRegsSem);
    return retVal;
}
Esempio n. 5
0
GT_STATUS gprtSerdesReset
(
    IN GT_QD_DEV *dev,
    IN GT_LPORT  port
)
{

    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort, serdesPort;         /* the physical port number     */
    GT_PHY_INFO        serdesInfo;

    DBG_INFO(("gprtSerdesReset Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);

    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown SERDES device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    /* set Auto Negotiation AD Register */
    retVal = serdesSetAutoMode(dev,hwPort,&serdesInfo,SPEED_AUTO_DUPLEX_AUTO);

    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
    }
    else
    {
        DBG_INFO(("OK.\n"));
    }

    gtSemGive(dev,dev->phyRegsSem);

    return retVal;
}
Esempio n. 6
0
/*******************************************************************************
* gprtGetSerdesRegField
*
* DESCRIPTION:
*		This routine gets Serdes Register.
*
* INPUTS:
*       portNum     - Port number to write the register for.
*       regAddr     - The register's address.
*       fieldOffset - The field start bit index. (0 - 15)
*       fieldLength - Number of bits to write.
*
* OUTPUTS:
*       data        - Data to be read.	
*
* RETURNS:
*		GT_OK			- on success
*		GT_FAIL 		- on error
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gprtGetSerdesRegField
(
IN GT_QD_DEV *dev,
    IN  GT_LPORT  port,
    IN  GT_U8    regAddr,
    IN  GT_U8    fieldOffset,
    IN  GT_U8    fieldLength,
    OUT  GT_U16   *data
)
{
    GT_U8           hwPort, serdesPort;         /* the physical port number     */
	  GT_U8           pageNum = _getSerdesPageNumber(dev);
    GT_PHY_INFO        serdesInfo;

	hwPort = GT_LPORT_2_PORT(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);
    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }


		
    if(hwGetPagedPhyRegField(dev,serdesPort,pageNum,regAddr,fieldOffset,fieldLength,serdesInfo.anyPage,data) != GT_OK)
    	{
     	   DBG_INFO(("Failed.\n"));
           return GT_FAIL;
    	}
		return GT_OK;
}
Esempio n. 7
0
/*******************************************************************************
* gsysSetQoSWeight
*
* DESCRIPTION:
*       Programmable Round Robin Weights.
*        Each port has 4/8 output Queues. Queue 3/7 has the highest priority and 
*        Queue 0 has the lowest priority. When a scheduling mode of port is 
*        configured as Weighted Round Robin queuing mode, the access sequece of the 
*        Queue is 3,2,3,1,3,2,3,0,3,2,3,1,3,2,3 by default.
*        (Queue is 7,6,5,7,1,6,7,4 by default. That is after 6390.)
*        This sequence can be configured with this API.
*
* INPUTS:
*       weight - access sequence of the queue
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gsysSetQoSWeight
(
    IN  GT_QD_DEV         *dev,
    IN  GT_QoS_WEIGHT    *weight
)
{
    GT_STATUS    retVal;         /* Functions return value.      */
    GT_U16        data;
    GT_U32        len, i;
	int length_loc, entry_num;

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

    /* Check if Switch supports this feature. */
    if (!IS_IN_DEV_GROUP(dev,DEV_QoS_WEIGHT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    if (IS_IN_DEV_GROUP(dev,DEV_QoS_WEIGHT_1))
    {
      length_loc = 0x40;
      entry_num = 2;

    }
	else
    {
      length_loc = 0x20;
      entry_num = 4;
    }


    if (weight->len > 128)
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    gtSemTake(dev,dev->tblRegsSem,OS_WAIT_FOREVER);

    len = weight->len/entry_num;

    /* program QoS Weight Table, 4/2 sequences at a time */

    for(i=0; i<len; i++)
    {
        /* Wait until the QoS Weight Table is ready. */
#ifdef GT_RMGMT_ACCESS
    {
      HW_DEV_REG_ACCESS regAccess;

      regAccess.entries = 2;

      regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0;
      regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
      regAccess.rw_reg_list[0].reg = QD_REG_QOS_WEIGHT;
      regAccess.rw_reg_list[0].data = 15;
      regAccess.rw_reg_list[1].cmd = HW_REG_WRITE;
      regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
      regAccess.rw_reg_list[1].reg = QD_REG_QOS_WEIGHT;
    if (IS_IN_DEV_GROUP(dev,DEV_QoS_WEIGHT_1))
	{
      data =  (GT_U16)((1 << 15) | (i << 8) | 
            (weight->queue[i*2] & 0x7) |
            ((weight->queue[i*2+1] & 0x7) << 4);
	}
	else
	{
      data =  (GT_U16)((1 << 15) | (i << 8) | 
            (weight->queue[i*4] & 0x3) |
            ((weight->queue[i*4+1] & 0x3) << 2) |
            ((weight->queue[i*4+2] & 0x3) << 4) |
            ((weight->queue[i*4+3] & 0x3) << 6));
	}
      regAccess.rw_reg_list[1].data = data;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
            gtSemGive(dev,dev->tblRegsSem);
        return retVal;
      }
    }
#else
        data = 1;
        while(data == 1)
        {
            retVal = hwGetGlobal2RegField(dev,QD_REG_QOS_WEIGHT,15,1,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->tblRegsSem);
                return retVal;
            }
        }

        if (IS_IN_DEV_GROUP(dev,DEV_QoS_WEIGHT_1))
		{
          data =  (GT_U16)((1 << 15) | (i << 8) | 
            (weight->queue[i*2] & 0x7) |
            ((weight->queue[i*2+1] & 0x7) << 4));
		}
    	else
		{
          data =  (GT_U16)((1 << 15) | (i << 8) | 
                (weight->queue[i*4] & 0x3) |
                ((weight->queue[i*4+1] & 0x3) << 2) |
                ((weight->queue[i*4+2] & 0x3) << 4) |
                ((weight->queue[i*4+3] & 0x3) << 6));
		}

        retVal = hwWriteGlobal2Reg(dev, QD_REG_QOS_WEIGHT, data);
        if(retVal != GT_OK)
        {
               DBG_INFO(("Failed.\n"));
            gtSemGive(dev,dev->tblRegsSem);
            return retVal;
        }
#endif
    }
Esempio n. 8
0
/*******************************************************************************
* gprtGetSerdesReg
*
* DESCRIPTION:
*       This routine reads Phy Serdes Registers.
*
* INPUTS:
*       port -    The logical port number.
*       regAddr - The register's address.
*
* OUTPUTS:
*       data    - The read register's data.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtGetSerdesReg
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT     port,
    IN  GT_U32         regAddr,
    OUT GT_U16         *data
)
{
    GT_U8           hwPort, serdesPort;         /* the physical port number     */
	GT_U8           pageNum = _getSerdesPageNumber(dev);
    GT_PHY_INFO        serdesInfo;

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

    if(!IS_IN_DEV_GROUP(dev,DEV_SERDES_UP_PORT))
    {
        return GT_NOT_SUPPORTED;
    }

    /* check if input is logical port number */    
/*    hwPort = GT_LPORT_2_PORT(port);
    GT_GET_SERDES_PORT(dev,&hwPort);
*/
    hwPort = qdLong2Char(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);
	
    if(hwPort > dev->maxPhyNum)
    {
        /* check if input is physical serdes address */    
        if(dev->validSerdesVec & (1<<port))
        {
            hwPort = (GT_U8)port;
        }
        else
            return GT_NOT_SUPPORTED;
    }
	//printf("===GT_GET_SERDES_PORT serdesPort = %d ,hwPort = %d\r\n",serdesPort,hwPort);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }


    /* Get Serdes Register. */
    /* Write to Serdes Register */
	//printf("===hwReadPagedPhyReg serdesPort= %d, pageNum = %d,regAddr = %x,serdesInfo.anyPage = %d \r\n",serdesPort,pageNum,(GT_U8)regAddr,serdesInfo.anyPage);
    if(hwReadPagedPhyReg(dev,serdesPort,pageNum,(GT_U8)regAddr,serdesInfo.anyPage,data) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;

}
Esempio n. 9
0
GT_STATUS gprtSetSerdesPause
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_PHY_PAUSE_MODE state
)
{
  GT_U8           hwPort, serdesPort;         /* the physical port number     */
  GT_U16             u16Data,regStart;
  GT_STATUS        retVal = GT_OK;
  GT_PHY_INFO        serdesInfo;
  GT_U8           pageNum = _getSerdesPageNumber(dev);

  GT_SERDES_MODE  serdes_mode;

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

    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

   if((retVal=gprtGetSerdesMode(dev,serdesPort, &serdes_mode)) != GT_OK)
   {
      DBG_INFO(("Not able to get Serdes mode(port:%d).\n",serdes_mode));
      gtSemGive(dev,dev->phyRegsSem);
      return GT_FAIL;
   }
   if(serdes_mode != PHY_SERDES_1000X)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    regStart = 7;

    if(state & GT_PHY_ASYMMETRIC_PAUSE)
    {
        if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
        {
            DBG_INFO(("Unknown SERDES device.\n"));
            gtSemGive(dev,dev->phyRegsSem);
            return GT_FAIL;
        }

        if (!(serdesInfo.flag & GT_PHY_GIGABIT))
        {
            DBG_INFO(("Not Supported\n"));
            gtSemGive(dev,dev->phyRegsSem);
            return GT_BAD_PARAM;
        }

    }

    u16Data = state;

    /* Write to Phy AutoNegotiation Advertisement Register.  */
    if((retVal=hwSetPagedPhyRegField(dev,serdesPort, pageNum,QD_SERDES_AUTONEGO_AD_REG,(GT_U8)regStart,2,serdesInfo.anyPage,u16Data)) != GT_OK)
    {
        DBG_INFO(("Not able to write Serdes Reg(port:%d,offset:%d).\n",serdesPort,QD_SERDES_AUTONEGO_AD_REG));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    /* Restart Auto Negotiation */
    if((retVal=hwSetPagedPhyRegField(dev,serdesPort, pageNum,QD_SERDES_CONTROL_REG,9,1,serdesInfo.anyPage,1)) != GT_OK)
    {
        DBG_INFO(("Not able to write Serdes Reg(port:%d,offset:%d,data:%#x).\n",serdesPort,QD_SERDES_AUTONEGO_AD_REG,serdesInfo.anyPage,u16Data));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    gtSemGive(dev,dev->phyRegsSem);
    return retVal;
}
Esempio n. 10
0
/*******************************************************************************
* gprtSetSerdesDuplexMode
*
* DESCRIPTION:
*         Sets duplex mode for a specific logical port. This function will keep 
*        the speed and loopback mode to the previous value, but disable others,
*        such as Autonegotiation.
*
* INPUTS:
*        port -    The logical port number, unless SERDES device is accessed
*                The physical address, if SERDES device is accessed
*         dMode    - dulpex mode
*
* OUTPUTS:
*         None.
*
* RETURNS:
*         GT_OK     - on success
*         GT_FAIL     - on error
*
* COMMENTS:
*         data sheet register 0.8 - Duplex Mode
*
*******************************************************************************/
GT_STATUS gprtSetSerdesDuplexMode
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_BOOL   dMode
)
{
    GT_U8           hwPort, serdesPort;         /* the physical port number     */
    GT_U16             u16Data;
    GT_STATUS        retVal;
	  GT_U8           pageNum = _getSerdesPageNumber(dev);
    GT_PHY_INFO        serdesInfo;

    DBG_INFO(("gprtSetSerdesDuplexMode Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }


    /* check if the port is configurable */
    if(!IS_CONFIGURABLE_PHY(dev,hwPort))
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(hwReadPagedPhyReg(dev,serdesPort,pageNum,QD_SERDES_CONTROL_REG,serdesInfo.anyPage,&u16Data) != GT_OK)
    {
        DBG_INFO(("Not able to read Serdes Reg(port:%d,offset:%d).\n",serdesPort,QD_SERDES_CONTROL_REG));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    if(dMode)
    {
        u16Data = (u16Data & (QD_SERDES_LOOPBACK | QD_SERDES_SPEED | QD_SERDES_SPEED_MSB)) | QD_SERDES_DUPLEX;
    }
    else
    {
        u16Data = u16Data & (QD_SERDES_LOOPBACK | QD_SERDES_SPEED | QD_SERDES_SPEED_MSB);
    }


    DBG_INFO(("Write to serdes(%d) register: regAddr 0x%x, data %#x",
              serdesPort,QD_SERDES_CONTROL_REG,u16Data));

    /* Write to Phy Control Register.  */
    retVal = hwSerdesReset(dev,serdesPort,pageNum, u16Data);
    gtSemGive(dev,dev->phyRegsSem);
    return retVal;
}
Esempio n. 11
0
GT_STATUS gprtSetSerdesSpeed
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_PHY_SPEED speed
)
{
    GT_U8           hwPort, serdesPort;         /* the physical port number     */
    GT_U16             u16Data;
    GT_PHY_INFO        serdesInfo;
    GT_STATUS        retVal;
	  GT_U8           pageNum = _getSerdesPageNumber(dev);

    DBG_INFO(("gprtSetSerdesSpeed Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
	serdesPort = hwPort;
    GT_GET_SERDES_PORT(dev,&serdesPort);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);

    /* check if the port is configurable */
    if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK)
    {
        DBG_INFO(("Unknown SERDES device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    if(hwReadPagedPhyReg(dev,serdesPort,pageNum,QD_SERDES_CONTROL_REG,serdesInfo.anyPage,&u16Data) != GT_OK)
    {
        DBG_INFO(("Not able to read Serdes Reg(port:%d,offset:%d).\n",serdesPort,QD_SERDES_CONTROL_REG));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    switch(speed)
    {
        case PHY_SPEED_10_MBPS:
            if ((serdesInfo.flag & GT_PHY_GIGABIT) && !(serdesInfo.flag & GT_PHY_COPPER))
            {
                gtSemGive(dev,dev->phyRegsSem);
                return GT_BAD_PARAM;
            }
            u16Data = u16Data & (QD_SERDES_LOOPBACK | QD_SERDES_DUPLEX);
            break;
        case PHY_SPEED_100_MBPS:
            u16Data = (u16Data & (QD_SERDES_LOOPBACK | QD_SERDES_DUPLEX)) | QD_SERDES_SPEED;
            break;
        case PHY_SPEED_1000_MBPS:
            if (!(serdesInfo.flag & GT_PHY_GIGABIT))
            {
                gtSemGive(dev,dev->phyRegsSem);
                return GT_BAD_PARAM;
            }
            u16Data = (u16Data & (QD_SERDES_LOOPBACK | QD_SERDES_DUPLEX)) | QD_SERDES_SPEED_MSB;
            break;
        default:
            gtSemGive(dev,dev->phyRegsSem);
            return GT_FAIL;
    }

    DBG_INFO(("Write to serdes(%d) register: regAddr 0x%x, data %#x",
              serdesPort,QD_SERDES_CONTROL_REG,u16Data));

    retVal = hwSerdesReset(dev,serdesPort,pageNum, u16Data);
    gtSemGive(dev,dev->phyRegsSem);
    return retVal;
}
Esempio n. 12
0
static GT_STATUS statsOperationPerform
(
    IN   GT_QD_DEV            *dev,
    IN   GT_STATS_OPERATION   statsOp,
    IN   GT_U8                port,
    IN   GT_STATS_COUNTERS    counter,
    OUT  GT_VOID              *statsData
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data,histoData; /* Data to be set into the      */
                                    /* register.                    */
    GT_U32 statsCounter;
    GT_U32 lastCounter;
    GT_U16            portNum;

    gtSemTake(dev,dev->statsRegsSem,OS_WAIT_FOREVER);

    if (!((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_RMON_REALTIME_SUPPORT))))
    {
      if (IS_IN_DEV_GROUP(dev,DEV_MELODY_SWITCH))
        lastCounter = (GT_U32)STATS2_Late;
      else
        lastCounter = (GT_U32)STATS_OutDiscards;
    }
    else
    {
        lastCounter = (GT_U32)STATS2_Late;
    }

    if (IS_IN_DEV_GROUP(dev,DEV_RMON_PORT_BITS))
    {
        portNum = (port + 1) << 5;
    }
    else
    {
        portNum = (GT_U16)port;
    }

    /* Wait until the stats in ready. */
#ifdef GT_RMGMT_ACCESS
    {
      HW_DEV_REG_ACCESS regAccess;

      regAccess.entries = 2;

      regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0;
      regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
      regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      regAccess.rw_reg_list[1].cmd = HW_REG_READ;
      regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
      regAccess.rw_reg_list[1].reg = QD_REG_STATS_OPERATION;
      regAccess.rw_reg_list[1].data = 0;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        gtSemGive(dev,dev->statsRegsSem);
        return retVal;
      }
      histoData = qdLong2Short(regAccess.rw_reg_list[1].data);
    }
#else
    data = 1;
    while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->statsRegsSem);
            return retVal;
        }
    }

    /* Get the Histogram mode bit.                */
    retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData);
    if(retVal != GT_OK)
    {
        gtSemGive(dev,dev->statsRegsSem);
        return retVal;
    }

#endif
    histoData &= 0xC00;

    /* Set the STAT Operation register */
    switch (statsOp)
    {
        case STATS_FLUSH_ALL:
            data = (1 << 15) | (GT_STATS_FLUSH_ALL << 12) | histoData;
            retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data);
            gtSemGive(dev,dev->statsRegsSem);
            return retVal;

        case STATS_FLUSH_PORT:
            data = (1 << 15) | (GT_STATS_FLUSH_PORT << 12) | portNum | histoData;
            retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data);
            gtSemGive(dev,dev->statsRegsSem);
            return retVal;

        case STATS_READ_COUNTER:
            retVal = statsCapture(dev,port);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->statsRegsSem);
                return retVal;
            }

            retVal = statsReadCounter(dev,counter,(GT_U32*)statsData);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->statsRegsSem);
                return retVal;
            }
            break;

        case STATS_READ_REALTIME_COUNTER:
            retVal = statsReadRealtimeCounter(dev,port,counter,(GT_U32*)statsData);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->statsRegsSem);
                return retVal;
            }

            break;

        case STATS_READ_ALL:
            retVal = statsCapture(dev,port);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->statsRegsSem);
                return retVal;
            }

            for(statsCounter=0; statsCounter<=lastCounter; statsCounter++)
            {
                retVal = statsReadCounter(dev,statsCounter,((GT_U32*)statsData + statsCounter));
                if(retVal != GT_OK)
                {
                    gtSemGive(dev,dev->statsRegsSem);
                    return retVal;
                }
            }
            break;

        default:

            gtSemGive(dev,dev->statsRegsSem);
            return GT_FAIL;
    }

    gtSemGive(dev,dev->statsRegsSem);
    return GT_OK;
}
Esempio n. 13
0
static GT_STATUS stuOperationPerform
(
    IN	    GT_QD_DEV           *dev,
    IN      GT_STU_OPERATION    stuOp,
    INOUT   GT_U8               *valid,
	INOUT	GT_STU_ENTRY    	*entry
)
{
	GT_STATUS       retVal;         /* Functions return value.      */
	GT_U16          data;           /* Data to be set into the      */
                                /* register.                    */

	gtSemTake(dev,dev->vtuRegsSem,OS_WAIT_FOREVER);

	/* Wait until the VTU in ready. */
	data = 1;
    while(data == 1)
    {
		retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,15,1,&data);
		if(retVal != GT_OK)
		{
			gtSemGive(dev,dev->vtuRegsSem);
			return retVal;
		}
	}

	/* Set the VTU data register if Load operation is required. */
	if (stuOp == LOAD_PURGE_STU_ENTRY)
	{
		if (*valid == 1)
		{
			/* set the Port State for all the ports */
			retVal = stuSetSTUData(dev,entry);
			if(retVal != GT_OK)
			{
				gtSemGive(dev,dev->vtuRegsSem);
				return retVal;
			}

			/* Set the valid bit (QD_REG_VTU_VID_REG) */
	   		data= *valid << 12 ;
    	    retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_VTU_VID_REG),data);
	   		if(retVal != GT_OK)
    	    {
	   			gtSemGive(dev,dev->vtuRegsSem);
	    		return retVal;
   		   	}		
		}
		else
		{
			/* Clear the valid bit (QD_REG_VTU_VID_REG) */
	   		data= 0 ;
    	    retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_VTU_VID_REG),data);
	   		if(retVal != GT_OK)
    	    {
	   			gtSemGive(dev,dev->vtuRegsSem);
	    		return retVal;
   		   	}		
		}
    }

	/* Set the SID register (QD_REG_STU_SID_REG) */
   	data= (entry->sid) & 0x3F;
    retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_STU_SID_REG),data);
   	if(retVal != GT_OK)
    {
   		gtSemGive(dev,dev->vtuRegsSem);
    	return retVal;
   	}		

	/* Start the STU Operation by defining the stuOp and VTUBusy */
	data = (1 << 15) | (stuOp << 12);

	retVal = hwWriteGlobalReg(dev,QD_REG_VTU_OPERATION,data);
	if(retVal != GT_OK)
	{
		gtSemGive(dev,dev->vtuRegsSem);
		return retVal;
	}

	/* If the operation is a get next operation wait for the response   */
	if(stuOp == GET_NEXT_STU_ENTRY)
	{
		/* Wait until the STU in ready. */
		data = 1;
		while(data == 1)
		{
			retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,15,1,&data);
			if(retVal != GT_OK)
			{
				gtSemGive(dev,dev->vtuRegsSem);
				return retVal;
			}
		}

		/****************** get the valid bit *******************/
		retVal = hwGetGlobalRegField(dev,QD_REG_VTU_VID_REG,12,1,&data);
		if(retVal != GT_OK)
		{
			gtSemGive(dev,dev->vtuRegsSem);
			return retVal;
		}

		*valid = (GT_U8)data;

		/****************** get the sid *******************/

		retVal = hwReadGlobalReg(dev,QD_REG_STU_SID_REG,&data);
		if(retVal != GT_OK)
		{
			gtSemGive(dev,dev->vtuRegsSem);
			return retVal;
		}

		/* the sid is bits 0-5 */
		entry->sid   = data & 0x3F;

		if (*valid)
		{
			/* get the Port State for all the ports */
			retVal = stuGetSTUData(dev,entry);
			if(retVal != GT_OK)
			{
				gtSemGive(dev,dev->vtuRegsSem);
				return retVal;
			}

		} /* entry is valid */

	} /* end of get next entry */

	gtSemGive(dev,dev->vtuRegsSem);
	return GT_OK;
}
Esempio n. 14
0
/*******************************************************************************
* gvctGetCableStatus_mad
*
* DESCRIPTION:
*       This routine perform the virtual cable test for the requested port,
*       and returns the the status per MDI pair.
*
* INPUTS:
*       port - logical port number.
*
* OUTPUTS:
*       cableStatus - the port copper cable status.
*       cableLen    - the port copper cable length.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       Internal Gigabit Phys in 88E6165 family and 88E6351 family devices
*        are not supported by this API. For those devices, gvctGetAdvCableDiag 
*        API can be used, instead.
*
*******************************************************************************/
GT_STATUS gvctGetCableDiag_mad
(
    IN  GT_QD_DEV *dev,
    IN  GT_LPORT        port,
    OUT GT_CABLE_STATUS *cableStatus
)
{
    GT_STATUS status=GT_OK;
    GT_U8 hwPort;
    GT_BOOL ppuEn;
    GT_PHY_INFO    phyInfo;

    DBG_INFO(("gvctGetCableDiag_mad Called.\n"));
    hwPort = GT_LPORT_2_PHY(port);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);

    /* check if the port is configurable */
    if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    /* check if the port supports VCT */
    if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    if (!(phyInfo.flag & GT_PHY_VCT_CAPABLE))
    {
        DBG_INFO(("Not Supported\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    /* Need to disable PPUEn for safe. */
    if(gsysGetPPUEn(dev,&ppuEn) != GT_OK)
    {
        ppuEn = GT_FALSE;
    }

    if(ppuEn != GT_FALSE)
    {
        if((status= gsysSetPPUEn(dev,GT_FALSE)) != GT_OK)
        {
            DBG_INFO(("Not able to disable PPUEn.\n"));
            gtSemGive(dev,dev->phyRegsSem);
            return status;
        }
        gtDelay(250);
    }
        
    if ( mdDiagGetCableStatus(&(dev->mad_dev),port, (MAD_CABLE_STATUS*)cableStatus) != MAD_OK)
    {
      DBG_INFO(("Failed to run mdDiagGetCableStatus.\n"));
      gtSemGive(dev,dev->phyRegsSem);
      return GT_FALSE;
    }

    if(ppuEn != GT_FALSE)
    {
        if(gsysSetPPUEn(dev,ppuEn) != GT_OK)
        {
            DBG_INFO(("Not able to enable PPUEn.\n"));
            status = GT_FAIL;
        }
    }

    gtSemGive(dev,dev->phyRegsSem);
    return status;    
}