Beispiel #1
0
GT_STATUS gprtPhyIntEnable
(
IN GT_QD_DEV    *dev,
IN GT_LPORT    port,
IN GT_U16    intType
)
{
    GT_STATUS       retVal;      
    GT_U8           hwPort;         /* the physical port number     */

/*
#ifdef GT_USE_MAD
    if (dev->use_mad==GT_TRUE)
        return gprtPhyIntEnable_mad(dev, port, intType);
#endif
*/
    DBG_INFO(("gprtPhyIntEnable Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

    if((IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE)) && (hwPort > 3))
    {
        if(!(dev->validSerdesVec & (1 << hwPort)))
        {
            if(!((IS_IN_DEV_GROUP(dev,DEV_SERDES_ACCESS_CONFIG)) && (hwPort == 4)))
                GT_GET_SERDES_PORT(dev,&hwPort);
        }
        if(hwPort >= dev->maxPhyNum)
        {
            return GT_NOT_SUPPORTED;
        }
    }

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

    retVal = hwWritePhyReg(dev,hwPort, QD_PHY_INT_ENABLE_REG, intType);

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

}
Beispiel #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;
}
Beispiel #3
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;
}
Beispiel #4
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;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
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;    
}