#include <Copyright.h>

/********************************************************************************
* gtWeight.c
*
* DESCRIPTION:
*       API definitions for Round Robin Weight table access
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*       $Revision: $
*******************************************************************************/

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


/*******************************************************************************
* gsysSetQoSWeight
*
* DESCRIPTION:
*       Programmable Round Robin Weights.
*        Each port has 4 output Queues. Queue 3 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.
*        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;

    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 (weight->len > 128)
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

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

    len = weight->len/4;

    /* program QoS Weight Table, 4 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;
      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)
      {
        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;
            }
        }

        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
    }

    /* program remaining sequences if any */
    i = weight->len % 4;
    if (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;
          data =  (GT_U16)((1 << 15) | (len << 8));
          switch (i)
          {
            case 3:
                data |= ((weight->queue[len*4+2] & 0x3) << 4);
            case 2:
                data |= ((weight->queue[len*4+1] & 0x3) << 2);
            case 1:
                data |= ((weight->queue[len*4+0] & 0x3) << 0);
            break;
            default:
                DBG_INFO(("Should not come to this point.\n"));
                gtSemGive(dev,dev->tblRegsSem);
            return GT_FALSE;
          }
          regAccess.rw_reg_list[1].data = data;
          retVal = hwAccessMultiRegs(dev, &regAccess);
          if(retVal != GT_OK)
          {
            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;
            }
        }
        
        data =  (GT_U16)((1 << 15) | (len << 8));
        
        switch (i)
        {
            case 3:
                data |= ((weight->queue[len*4+2] & 0x3) << 4);
            case 2:
                data |= ((weight->queue[len*4+1] & 0x3) << 2);
            case 1:
                data |= ((weight->queue[len*4+0] & 0x3) << 0);
                break;
            default:
                   DBG_INFO(("Should not come to this point.\n"));
                gtSemGive(dev,dev->tblRegsSem);
                return GT_FALSE;
        }

        retVal = hwWriteGlobal2Reg(dev, QD_REG_QOS_WEIGHT, data);
        if(retVal != GT_OK)
        {
               DBG_INFO(("Failed.\n"));
            gtSemGive(dev,dev->tblRegsSem);
            return retVal;
        }
#endif
    }

    /* Write the lengh of the sequence */

    /* 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;
      data =  (GT_U16)((1 << 15) | (0x20 << 8) | weight->len);
      regAccess.rw_reg_list[1].data = data;
      retVal = hwAccessMultiRegs(dev, &regAccess);
    }
#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;
           }
    }

    data =  (GT_U16)((1 << 15) | (0x20 << 8) | weight->len);
        
    retVal = hwWriteGlobal2Reg(dev, QD_REG_QOS_WEIGHT, data);
#endif

    gtSemGive(dev,dev->tblRegsSem);

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

    return GT_OK;
}


/*******************************************************************************
* gsysGetQoSWeight
*
* DESCRIPTION:
*       Programmable Round Robin Weights.
*        Each port has 4 output Queues. Queue 3 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.
*        This routine retrieves the access sequence of the Queue.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       weight - access sequence of the queue
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gsysGetQoSWeight
(
    IN  GT_QD_DEV         *dev,
    OUT GT_QoS_WEIGHT    *weight
)
{
    GT_STATUS    retVal;         /* Functions return value.      */
    GT_U16        data, i;
    GT_U32        len;

    DBG_INFO(("gsysGetQoSWeight 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;
    }

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

    /* Read the lengh of the sequence */

    /* Wait until the QoS Weight Table is ready. */
#ifdef GT_RMGMT_ACCESS
    {
      HW_DEV_REG_ACCESS regAccess;

      regAccess.entries = 3;

      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;
      data = (0x20 << 8);
      regAccess.rw_reg_list[1].data = data;
      regAccess.rw_reg_list[2].cmd = HW_REG_READ;
      regAccess.rw_reg_list[2].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS);
      regAccess.rw_reg_list[2].reg = QD_REG_QOS_WEIGHT;
      regAccess.rw_reg_list[2].data = 0;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      data = qdLong2Short(regAccess.rw_reg_list[2].data);
    }
#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;
           }
    }

    data = (0x20 << 8);
        
    retVal = hwWriteGlobal2Reg(dev, QD_REG_QOS_WEIGHT, data);
    if(retVal != GT_OK)
       {
           DBG_INFO(("Failed.\n"));
        gtSemGive(dev,dev->tblRegsSem);
           return retVal;
    }

    retVal = hwReadGlobal2Reg(dev, QD_REG_QOS_WEIGHT, &data);
#endif
    if(retVal != GT_OK)
       {
           DBG_INFO(("Failed.\n"));
        gtSemGive(dev,dev->tblRegsSem);
           return retVal;
    }

    weight->len = data & 0xFF;

    len = weight->len/4;

    /* read QoS Weight Table, 4 sequences at a time */

    for(i=0; i<len; i++)
    {
        data = i << 8;

#ifdef GT_RMGMT_ACCESS
    {
      HW_DEV_REG_ACCESS regAccess;

      regAccess.entries = 2;

      regAccess.rw_reg_list[0].cmd = HW_REG_WRITE;
      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 = data;
      regAccess.rw_reg_list[1].cmd = HW_REG_READ;
      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;
      regAccess.rw_reg_list[1].data = 0;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      data = qdLong2Short(regAccess.rw_reg_list[1].data);
    }
#else
        retVal = hwWriteGlobal2Reg(dev, QD_REG_QOS_WEIGHT, data);
        if(retVal != GT_OK)
        {
               DBG_INFO(("Failed.\n"));
            gtSemGive(dev,dev->tblRegsSem);
            return retVal;
        }

        retVal = hwReadGlobal2Reg(dev, QD_REG_QOS_WEIGHT, &data);
#endif
        if(retVal != GT_OK)
           {
               DBG_INFO(("Failed.\n"));
            gtSemGive(dev,dev->tblRegsSem);
               return retVal;
        }

        weight->queue[i*4] = data & 0x3;
        weight->queue[i*4+1] = (data >> 2) & 0x3;
        weight->queue[i*4+2] = (data >> 4) & 0x3;
        weight->queue[i*4+3] = (data >> 6) & 0x3;

    }

    /* read remaining sequences if any */
    i = (GT_U16) (weight->len % 4);
    if (i)
    {
        data = (GT_U16)(len << 8);
        
#ifdef GT_RMGMT_ACCESS
        {
          HW_DEV_REG_ACCESS regAccess;

          regAccess.entries = 2;

          regAccess.rw_reg_list[0].cmd = HW_REG_WRITE;
          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 = data;
          regAccess.rw_reg_list[1].cmd = HW_REG_READ;
          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;
          regAccess.rw_reg_list[1].data = 0;
          retVal = hwAccessMultiRegs(dev, &regAccess);
          data = qdLong2Short(regAccess.rw_reg_list[1].data);
        }
#else
        retVal = hwWriteGlobal2Reg(dev, QD_REG_QOS_WEIGHT, data);
        if(retVal != GT_OK)
        {
               DBG_INFO(("Failed.\n"));
            gtSemGive(dev,dev->tblRegsSem);
            return retVal;
        }

        retVal = hwReadGlobal2Reg(dev, QD_REG_QOS_WEIGHT, &data);
#endif
        if(retVal != GT_OK)
           {
               DBG_INFO(("Failed.\n"));
            gtSemGive(dev,dev->tblRegsSem);
               return retVal;
        }

        switch (i)
        {
            case 3:
                weight->queue[len*4+2] = (data >> 4) & 0x3;
            case 2:
                weight->queue[len*4+1] = (data >> 2) & 0x3;
            case 1:
                weight->queue[len*4] = data & 0x3;
                break;
            default:
                   DBG_INFO(("Should not come to this point.\n"));
                gtSemGive(dev,dev->tblRegsSem);
                return GT_FALSE;
        }
    }

    gtSemGive(dev,dev->tblRegsSem);

    return GT_OK;
}

