#include <Copyright.h>

/*******************************************************************************
* gtCCPVT.c
*
* DESCRIPTION:
*       API definitions for Cross Chip Port Vlan Data Table
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*******************************************************************************/

#include <msApi.h>
#include <gtSem.h>
#include <gtHwCntl.h>
#include <gtDrvSwRegs.h>

/****************************************************************************/
/* Cross Chip Port Vlan operation function declaration.                                    */
/****************************************************************************/
static GT_STATUS pvtOperationPerform
(
    IN   GT_QD_DEV             *dev,
    IN   GT_PVT_OPERATION    pvtOp,
    INOUT GT_PVT_OP_DATA    *opData
);


/*******************************************************************************
* gpvtInitialize
*
* DESCRIPTION:
*       This routine initializes the PVT Table to all one's (initial state)
*
* INPUTS:
*        None.
*
* 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 gpvtInitialize
(
    IN  GT_QD_DEV     *dev
)
{
    GT_STATUS           retVal;
    GT_PVT_OPERATION    op;

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

    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_CROSS_CHIP_PORT_VLAN))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Program Tuning register */
    op = PVT_INITIALIZE;
    retVal = pvtOperationPerform(dev,op,NULL);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (pvtOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}


/*******************************************************************************
* gpvtWritePVTData
*
* DESCRIPTION:
*       This routine write Cross Chip Port Vlan Data.
*        Cross chip Port VLAN Data used as a bit mask to limit where cross chip
*        frames can egress (in chip Port VLANs are masked using gvlnSetPortVlanPorts
*        API). Cross chip frames are Forward frames that ingress a DSA or Ether 
*        Type DSA port (see gprtSetFrameMode API). Bit 0 is a mask for port 0, 
*        bit 1 for port 1, etc. When a port's mask bit is one, frames are allowed 
*        to egress that port on this device. When a port's mask bit is zero,
*        frames are not allowed to egress that port on this device.
*
*        The Cross Chip Port VLAN Table is accessed by ingressing frames based
*        upon the original source port of the frame using the Forward frame's DSA tag
*        fields Src_Dev, Src_Port/Src_Trunk and Src_Is_Trunk. The 1 entry of the 512
*        that is accessed by the frame is:
*            If 5 Bit Port (in Global 2, offset 0x1D) = 0:
*                If Src_Is_Trunk = 0   Src_Dev[4:0], Src_Port[3:0]119
*                If Src_Is_Trunk = 1   Device Number (global offset 0x1C), Src_Trunk[3:0]
*            If 5 Bit Port (in Global 2, offset 0x1D) = 1:
*                If Src_Is_Trunk = 0   Src_Dev[3:0], Src_Port[4:0]120
*                If Src_Is_Trunk = 1   Device Number[3:0], Src_Trunk[4:0]
*
*        Cross chip port VLANs with Trunks are supported in the table where this
*        device's entries would be stored (defined by this device's Device Number).
*        This portion of the table is available for Trunk entries because this device's
*        port VLAN mappings to ports inside this device are masked by the port's
*        VLAN Table (see gvlnSetPortVlanPorts API).
*
*
* INPUTS:
*        pvtPointer - pointer to the desired entry of PVT (0 ~ 511)
*        pvtData    - Cross Chip Port Vlan Data
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpvtWritePVTData
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32        pvtPointer,
    IN  GT_U32        pvtData
)
{
    GT_STATUS           retVal;
    GT_PVT_OPERATION    op;
    GT_PVT_OP_DATA        opData;

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

    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_CROSS_CHIP_PORT_VLAN))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* check if the given pointer is valid */
    if (pvtPointer > 0x1FF)
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* check if the given pvtData is valid */
    if (pvtData >= (GT_U32)(1 << dev->maxPorts))
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* Program Tuning register */
    op = PVT_WRITE;
    opData.pvtAddr = pvtPointer;

    if((opData.pvtData = GT_LPORTVEC_2_PORTVEC(pvtData)) == GT_INVALID_PORT_VEC)
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }


    retVal = pvtOperationPerform(dev,op,&opData);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (pvtOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}


/*******************************************************************************
* gpvtReadPVTData
*
* DESCRIPTION:
*       This routine reads Cross Chip Port Vlan Data.
*        Cross chip Port VLAN Data used as a bit mask to limit where cross chip
*        frames can egress (in chip Port VLANs are masked using gvlnSetPortVlanPorts
*        API). Cross chip frames are Forward frames that ingress a DSA or Ether 
*        Type DSA port (see gprtSetFrameMode API). Bit 0 is a mask for port 0, 
*        bit 1 for port 1, etc. When a port's mask bit is one, frames are allowed 
*        to egress that port on this device. When a port's mask bit is zero,
*        frames are not allowed to egress that port on this device.
*
*        The Cross Chip Port VLAN Table is accessed by ingressing frames based
*        upon the original source port of the frame using the Forward frame's DSA tag
*        fields Src_Dev, Src_Port/Src_Trunk and Src_Is_Trunk. The 1 entry of the 512
*        that is accessed by the frame is:
*            If 5 Bit Port (in Global 2, offset 0x1D) = 0:
*                If Src_Is_Trunk = 0   Src_Dev[4:0], Src_Port[3:0]119
*                If Src_Is_Trunk = 1   Device Number (global offset 0x1C), Src_Trunk[3:0]
*            If 5 Bit Port (in Global 2, offset 0x1D) = 1:
*                If Src_Is_Trunk = 0   Src_Dev[3:0], Src_Port[4:0]120
*                If Src_Is_Trunk = 1   Device Number[3:0], Src_Trunk[4:0]
*
*        Cross chip port VLANs with Trunks are supported in the table where this
*        device's entries would be stored (defined by this device's Device Number).
*        This portion of the table is available for Trunk entries because this device's
*        port VLAN mappings to ports inside this device are masked by the port's
*        VLAN Table (see gvlnSetPortVlanPorts API).
*
*
* INPUTS:
*        pvtPointer - pointer to the desired entry of PVT (0 ~ 511)
*
* OUTPUTS:
*        pvtData    - Cross Chip Port Vlan Data
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpvtReadPVTData
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32        pvtPointer,
    OUT GT_U32        *pvtData
)
{
    GT_STATUS           retVal;
    GT_PVT_OPERATION    op;
    GT_PVT_OP_DATA        opData;

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

    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_CROSS_CHIP_PORT_VLAN))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* check if the given pointer is valid */
    if (pvtPointer > 0x1FF)
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* Program Tuning register */
    op = PVT_READ;
    opData.pvtAddr = pvtPointer;
    retVal = pvtOperationPerform(dev,op,&opData);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (pvtOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    opData.pvtData &= (1 << dev->maxPorts) - 1;
    *pvtData = GT_PORTVEC_2_LPORTVEC(opData.pvtData);

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

}


/****************************************************************************/
/* Internal functions.                                                  */
/****************************************************************************/


/*******************************************************************************
* pvtOperationPerform
*
* DESCRIPTION:
*       This function accesses PVT Table
*
* INPUTS:
*       pvtOp   - The pvt operation
*       pvtData - address and data to be written into PVT
*
* OUTPUTS:
*       pvtData - data read from PVT pointed by address
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*
*******************************************************************************/
static GT_STATUS pvtOperationPerform
(
    IN    GT_QD_DEV           *dev,
    IN    GT_PVT_OPERATION   pvtOp,
    INOUT GT_PVT_OP_DATA     *opData
)
{
    GT_STATUS       retVal;    /* Functions return value */
    GT_U16          data;     /* temporary Data storage */

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

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

      regAccess.entries = 1;
  
      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_PVT_ADDR;
      regAccess.rw_reg_list[0].data = 15;
      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_PVT_ADDR,15,1,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->tblRegsSem);
            return retVal;
        }
    }
#endif

    /* Set the PVT Operation register */
    switch (pvtOp)
    {
        case PVT_INITIALIZE:
            data = (1 << 15) | (pvtOp << 12);
            retVal = hwWriteGlobal2Reg(dev,QD_REG_PVT_ADDR,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->tblRegsSem);
                return retVal;
            }
            break;

        case PVT_WRITE:
            data = (GT_U16)opData->pvtData;
            retVal = hwWriteGlobal2Reg(dev,QD_REG_PVT_DATA,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->tblRegsSem);
                return retVal;
            }

            data = (GT_U16)((1 << 15) | (pvtOp << 12) | opData->pvtAddr);
            retVal = hwWriteGlobal2Reg(dev,QD_REG_PVT_ADDR,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->tblRegsSem);
                return retVal;
            }
            break;

        case PVT_READ:
            data = (GT_U16)((1 << 15) | (pvtOp << 12) | opData->pvtAddr);
            retVal = hwWriteGlobal2Reg(dev,QD_REG_PVT_ADDR,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->tblRegsSem);
                return retVal;
            }

#ifdef GT_RMGMT_ACCESS
            {
              HW_DEV_REG_ACCESS regAccess;

              regAccess.entries = 1;
  
              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_PVT_ADDR;
              regAccess.rw_reg_list[0].data = 15;
              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_PVT_ADDR,15,1,&data);
                if(retVal != GT_OK)
                {
                    gtSemGive(dev,dev->tblRegsSem);
                    return retVal;
                }
            }
#endif

            retVal = hwReadGlobal2Reg(dev,QD_REG_PVT_DATA,&data);
            opData->pvtData = (GT_U32)data;
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->tblRegsSem);
                return retVal;
            }
    
            break;

        default:
            
            gtSemGive(dev,dev->tblRegsSem);
            return GT_FAIL;
    }

    gtSemGive(dev,dev->tblRegsSem);
    return retVal;
}

