/*
 * Copyright (c) 2012, 2016 The Linux Foundation. All rights reserved.
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */


/**
 * @defgroup isisc_rate ISISC_RATE
 * @{
 */
#include "sw.h"
#include "hsl.h"
#include "hsl_dev.h"
#include "hsl_port_prop.h"
#include "isisc_rate.h"
#include "isisc_reg.h"

#define ISISC_MAX_POLICER_ID          31
#define ISISC_MAX_QUEUE               3
#define ISISC_MAX_EH_QUEUE            5

#define ACL_POLICER_CNT_SEL_ADDR          0x09f0
#define ACL_POLICER_CNT_MODE_ADDR         0x09f4
#define ACL_POLICER_CNT_RST_ADDR          0x09f8

static sw_error_t
_isisc_rate_port_queue_check(fal_port_t port_id, fal_queue_t queue_id)
{
    if ((0 == port_id) || (5 == port_id) || (6 == port_id))
    {
        if (ISISC_MAX_EH_QUEUE < queue_id)
        {
            return SW_BAD_PARAM;
        }
    }
    else
    {
        if (ISISC_MAX_QUEUE < queue_id)
        {
            return SW_BAD_PARAM;
        }
    }

    return SW_OK;
}

static void
_isisc_egress_bs_byte_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs)
{
    a_int32_t i;
    a_uint32_t data[8] =
    {
        0, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 128 * 1024,
        512 * 1024
    };

    for (i = 7; i >= 0; i--)
    {
        if (sw_bs >= data[i])
        {
            *hw_bs = i;
            break;
        }
    }
}

static void
_isisc_egress_bs_byte_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs)
{
    a_uint32_t data[8] =
    {
        0, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 128 * 1024,
        512 * 1024
    };

    *sw_bs = data[hw_bs & 0x7];
}

static void
_isisc_egress_bs_frame_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs)
{
    a_uint32_t data[8] = { 0, 2, 4, 16, 64, 256, 512, 1024 };
    a_int32_t i;

    for (i = 7; i >= 0; i--)
    {
        if (sw_bs >= data[i])
        {
            *hw_bs = i;
            break;
        }
    }
}

static void
_isisc_egress_bs_frame_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs)
{
    a_uint32_t data[8] = { 0, 2, 4, 16, 64, 256, 512, 1024 };

    *sw_bs = data[hw_bs & 0x7];
}

static void
_isisc_ingress_bs_byte_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs)
{
    a_int32_t i;
    a_uint32_t data[8] =
    {
        0, 4 * 1024, 32 * 1024, 128 * 1024, 512 * 1024, 2 * 1024 * 1024,
        8 * 1024 * 1024, 32 * 1024 * 1024
    };

    for (i = 7; i >= 0; i--)
    {
        if (sw_bs >= data[i])
        {
            *hw_bs = i;
            break;
        }
    }
}

static void
_isisc_ingress_bs_byte_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs)
{
    a_uint32_t data[8] =
    {
        0, 4 * 1024, 32 * 1024, 128 * 1024, 512 * 1024, 2 * 1024 * 1024,
        8 * 1024 * 1024, 32 * 1024 * 1024
    };

    *sw_bs = data[hw_bs & 0x7];
}

static void
_isisc_ingress_bs_frame_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs)
{
    a_uint32_t data[8] = { 0, 4, 16, 64, 256, 1024, 4096, 16384 };
    a_int32_t i;

    for (i = 7; i >= 0; i--)
    {
        if (sw_bs >= data[i])
        {
            *hw_bs = i;
            break;
        }
    }
}

static void
_isisc_ingress_bs_frame_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs)
{
    a_uint32_t data[8] = { 0, 4, 16, 64, 256, 1024, 4096, 16384 };

    *sw_bs = data[hw_bs & 0x7];
}

static void
_isisc_rate_flag_parse(a_uint32_t sw_flag, a_uint32_t * hw_flag)
{
    *hw_flag = 0;

    if (FAL_INGRESS_POLICING_TCP_CTRL & sw_flag)
    {
        *hw_flag |= (0x1 << 1);
    }

    if (FAL_INGRESS_POLICING_MANAGEMENT & sw_flag)
    {
        *hw_flag |= (0x1 << 2);
    }

    if (FAL_INGRESS_POLICING_BROAD & sw_flag)
    {
        *hw_flag |= (0x1 << 3);
    }

    if (FAL_INGRESS_POLICING_UNK_UNI & sw_flag)
    {
        *hw_flag |= (0x1 << 4);
    }

    if (FAL_INGRESS_POLICING_UNK_MUL & sw_flag)
    {
        *hw_flag |= (0x1 << 5);
    }

    if (FAL_INGRESS_POLICING_UNI & sw_flag)
    {
        *hw_flag |= (0x1 << 6);
    }

    if (FAL_INGRESS_POLICING_MUL & sw_flag)
    {
        *hw_flag |= (0x1 << 7);
    }
}

static void
_isisc_rate_flag_reparse(a_uint32_t hw_flag, a_uint32_t * sw_flag)
{
    *sw_flag = 0;

    if (hw_flag & 0x2)
    {
        *sw_flag |= FAL_INGRESS_POLICING_TCP_CTRL;
    }

    if (hw_flag & 0x4)
    {
        *sw_flag |= FAL_INGRESS_POLICING_MANAGEMENT;
    }

    if (hw_flag & 0x8)
    {
        *sw_flag |= FAL_INGRESS_POLICING_BROAD;
    }

    if (hw_flag & 0x10)
    {
        *sw_flag |= FAL_INGRESS_POLICING_UNK_UNI;
    }

    if (hw_flag & 0x20)
    {
        *sw_flag |= FAL_INGRESS_POLICING_UNK_MUL;
    }

    if (hw_flag & 0x40)
    {
        *sw_flag |= FAL_INGRESS_POLICING_UNI;
    }

    if (hw_flag & 0x80)
    {
        *sw_flag |= FAL_INGRESS_POLICING_MUL;
    }
}

static void
_isisc_rate_ts_parse(fal_rate_mt_t sw, a_uint32_t * hw)
{
    if (FAL_RATE_MI_100US == sw)
    {
        *hw = 0;
    }
    else if (FAL_RATE_MI_1MS == sw)
    {
        *hw = 1;
    }
    else if (FAL_RATE_MI_10MS == sw)
    {
        *hw = 2;
    }
    else if (FAL_RATE_MI_100MS)
    {
        *hw = 3;
    }
    else
    {
        *hw = 0;
    }
}

static void
_isisc_rate_ts_reparse(a_uint32_t hw, fal_rate_mt_t * sw)
{
    if (0 == hw)
    {
        *sw = FAL_RATE_MI_100US;
    }
    else if (1 == hw)
    {
        *sw = FAL_RATE_MI_1MS;
    }
    else if (2 == hw)
    {
        *sw = FAL_RATE_MI_10MS;
    }
    else
    {
        *sw = FAL_RATE_MI_100MS;
    }
}

static sw_error_t
_isisc_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id,
                            fal_port_policer_t * policer)
{
    sw_error_t rv;
    a_uint32_t cir = 0x7fff, eir = 0x7fff, cbs = 0, ebs = 0, tmp, data[3] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    data[0] = 0x18000000;
    if (FAL_BYTE_BASED == policer->meter_unit)
    {
        if (A_TRUE == policer->c_enable)
        {
            cir = policer->cir >> 5;
            policer->cir = cir << 5;
            _isisc_ingress_bs_byte_sw_to_hw(policer->cbs, &cbs);
            _isisc_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs));
        }

        if (A_TRUE == policer->e_enable)
        {
            eir = policer->eir >> 5;
            policer->eir = eir << 5;
            _isisc_ingress_bs_byte_sw_to_hw(policer->ebs, &ebs);
            _isisc_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs));
        }

        SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_UNIT, 0, data[1]);
    }
    else if (FAL_FRAME_BASED == policer->meter_unit)
    {
        if (A_TRUE == policer->c_enable)
        {
            cir = (policer->cir * 2) / 125;
            policer->cir = cir / 2 * 125 + cir % 2 * 63;
            _isisc_ingress_bs_frame_sw_to_hw(policer->cbs, &cbs);
            _isisc_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs));
        }

        if (A_TRUE == policer->e_enable)
        {
            eir = (policer->eir * 2) / 125;
            policer->eir = eir / 2 * 125 + eir % 2 * 63;
            _isisc_ingress_bs_frame_sw_to_hw(policer->ebs, &ebs);
            _isisc_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs));
        }

        SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_UNIT, 1, data[1]);
    }
    else
    {
        return SW_BAD_PARAM;
    }

    SW_SET_REG_BY_FIELD(INGRESS_POLICER0, INGRESS_CIR, cir, data[0]);
    SW_SET_REG_BY_FIELD(INGRESS_POLICER0, INGRESS_CBS, cbs, data[0]);
    SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_EIR, eir, data[1]);
    SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_EBS, ebs, data[1]);

    if (A_TRUE == policer->combine_mode)
    {
        SW_SET_REG_BY_FIELD(INGRESS_POLICER0, RATE_MODE, 1, data[0]);
    }

    if (A_TRUE == policer->deficit_en)
    {
        SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_BORROW, 1, data[1]);
    }

    if (A_TRUE == policer->color_mode)
    {
        SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_CM, 1, data[1]);
    }

    if (A_TRUE == policer->couple_flag)
    {
        SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_CF, 1, data[1]);
    }

    _isisc_rate_ts_parse(policer->c_meter_interval, &tmp);
    SW_SET_REG_BY_FIELD(INGRESS_POLICER0, C_ING_TS, tmp, data[0]);

    _isisc_rate_ts_parse(policer->e_meter_interval, &tmp);
    SW_SET_REG_BY_FIELD(INGRESS_POLICER1, E_ING_TS, tmp, data[1]);

    _isisc_rate_flag_parse(policer->c_rate_flag, &tmp);
    data[2] = (tmp << 8) & 0xff00;

    _isisc_rate_flag_parse(policer->e_rate_flag, &tmp);
    data[2] |= (tmp & 0xff);

    HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER0, port_id,
                      (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER1, port_id,
                      (a_uint8_t *) (&data[1]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER2, port_id,
                      (a_uint8_t *) (&data[2]), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id,
                            fal_port_policer_t * policer)
{
    sw_error_t rv;
    a_uint32_t unit, ts, cir, eir, cbs, ebs, data[3] = {0};

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER0, port_id,
                      (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER1, port_id,
                      (a_uint8_t *) (&data[1]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER2, port_id,
                      (a_uint8_t *) (&data[2]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    SW_GET_FIELD_BY_REG(INGRESS_POLICER0, INGRESS_CIR, cir, data[0]);
    SW_GET_FIELD_BY_REG(INGRESS_POLICER0, INGRESS_CBS, cbs, data[0]);
    SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_EIR, eir, data[1]);
    SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_EBS, ebs, data[1]);
    SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_UNIT, unit, data[1]);

    policer->c_enable = A_TRUE;
    if (0x7fff == cir)
    {
        policer->c_enable = A_FALSE;
        cir = 0;
    }

    policer->e_enable = A_TRUE;
    if (0x7fff == eir)
    {
        policer->e_enable = A_FALSE;
        eir = 0;
    }

    if (unit)
    {
        policer->meter_unit = FAL_FRAME_BASED;
        policer->cir = cir / 2 * 125 + cir % 2 * 63;
        policer->eir = eir / 2 * 125 + eir % 2 * 63;
        _isisc_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs));
        _isisc_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs));
    }
    else
    {
        policer->meter_unit = FAL_BYTE_BASED;
        policer->cir = cir << 5;
        policer->eir = eir << 5;
        _isisc_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs));
        _isisc_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs));
    }

    SW_GET_FIELD_BY_REG(INGRESS_POLICER0, RATE_MODE, policer->combine_mode,
                        data[0]);
    SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_BORROW, policer->deficit_en,
                        data[1]);
    SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_CF, policer->couple_flag,
                        data[1]);
    SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_CM, policer->color_mode,
                        data[1]);

    ts = (data[2] >> 8) & 0xff;
    _isisc_rate_flag_reparse(ts, &(policer->c_rate_flag));

    ts = data[2] & 0xff;
    _isisc_rate_flag_reparse(ts, &(policer->e_rate_flag));

    SW_GET_FIELD_BY_REG(INGRESS_POLICER0, C_ING_TS, ts, data[0]);
    _isisc_rate_ts_reparse(ts, &(policer->c_meter_interval));

    SW_GET_FIELD_BY_REG(INGRESS_POLICER1, E_ING_TS, ts, data[1]);
    _isisc_rate_ts_reparse(ts, &(policer->e_meter_interval));

    return SW_OK;
}

static sw_error_t
_isisc_rate_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id,
                           a_bool_t enable, fal_egress_shaper_t * shaper)
{
    sw_error_t rv;
    a_uint32_t data, cir, eir, cbs = 0, ebs = 0;

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    if (A_FALSE == enable)
    {
        aos_mem_zero(shaper, sizeof (fal_egress_shaper_t));

        cir = 0x7fff;
        eir = 0x7fff;
    }
    else
    {
        if (FAL_BYTE_BASED == shaper->meter_unit)
        {
            cir = shaper->cir >> 5;
            shaper->cir = cir << 5;

            eir = shaper->eir >> 5;
            shaper->eir = eir << 5;

            _isisc_egress_bs_byte_sw_to_hw(shaper->cbs, &cbs);
            _isisc_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs));

            _isisc_egress_bs_byte_sw_to_hw(shaper->ebs, &ebs);
            _isisc_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs));

            data = 0;
        }
        else if (FAL_FRAME_BASED == shaper->meter_unit)
        {
            cir = (shaper->cir * 2) / 125;
            shaper->cir = cir / 2 * 125 + cir % 2 * 63;

            eir = (shaper->eir * 2) / 125;
            shaper->eir = eir / 2 * 125 + eir % 2 * 63;

            _isisc_egress_bs_frame_sw_to_hw(shaper->cbs, &cbs);
            _isisc_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs));

            _isisc_egress_bs_frame_sw_to_hw(shaper->ebs, &ebs);
            _isisc_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs));

            data = 1;
        }
        else
        {
            return SW_BAD_PARAM;
        }

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        data = 1;
        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_PT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR,
                      (a_uint8_t *) (&cir), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR,
                      (a_uint8_t *) (&eir), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS,
                      (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS,
                      (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_rate_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id,
                           a_bool_t * enable, fal_egress_shaper_t * shaper)
{
    sw_error_t rv;
    a_uint32_t data = 0, cir = 0, eir = 0, cbs = 0, ebs = 0;

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    aos_mem_zero(shaper, sizeof (fal_egress_shaper_t));

    HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_PT,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (!data)
    {
        *enable = A_FALSE;
        return SW_OK;
    }

    HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR,
                      (a_uint8_t *) (&cir), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR,
                      (a_uint8_t *) (&eir), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS,
                      (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS,
                      (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if ((0x7fff == cir) && (0x7fff == eir))
    {
        *enable = A_FALSE;
        return SW_OK;
    }

    *enable = A_TRUE;
    HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (data)
    {
        shaper->meter_unit = FAL_FRAME_BASED;
        shaper->cir = cir / 2 * 125 + cir % 2 * 63;
        shaper->eir = eir / 2 * 125 + eir % 2 * 63;
        _isisc_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs));
        _isisc_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs));
    }
    else
    {
        shaper->meter_unit = FAL_BYTE_BASED;
        shaper->cir = cir << 5;
        shaper->eir = eir << 5;
        _isisc_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs));
        _isisc_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs));
    }

    return SW_OK;
}

static sw_error_t
_isisc_rate_queue_shaper_set(a_uint32_t dev_id, fal_port_t port_id,
                            fal_queue_t queue_id, a_bool_t enable,
                            fal_egress_shaper_t * shaper)
{
    sw_error_t rv;
    a_uint32_t unit = 0, data, cir, eir, cbs = 0, ebs = 0;

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    rv = _isisc_rate_port_queue_check(port_id, queue_id);
    SW_RTN_ON_ERROR(rv);

    if (A_FALSE == enable)
    {
        aos_mem_zero(shaper, sizeof (fal_egress_shaper_t));

        cir = 0x7fff;
        eir = 0x7fff;
    }
    else
    {
        if (FAL_BYTE_BASED == shaper->meter_unit)
        {
            cir = shaper->cir >> 5;
            shaper->cir = cir << 5;

            eir = shaper->eir >> 5;
            shaper->eir = eir << 5;

            _isisc_egress_bs_byte_sw_to_hw(shaper->cbs, &cbs);
            _isisc_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs));

            _isisc_egress_bs_byte_sw_to_hw(shaper->ebs, &ebs);
            _isisc_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs));

            unit = 0;
        }
        else if (FAL_FRAME_BASED == shaper->meter_unit)
        {
            cir = (shaper->cir * 2) / 125;
            shaper->cir = cir / 2 * 125 + cir % 2 * 63;

            eir = (shaper->eir * 2) / 125;
            shaper->eir = eir / 2 * 125 + eir % 2 * 63;

            _isisc_egress_bs_frame_sw_to_hw(shaper->cbs, &cbs);
            _isisc_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs));

            _isisc_egress_bs_frame_sw_to_hw(shaper->ebs, &ebs);
            _isisc_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs));

            unit = 1;
        }

        data = 0;
        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_PT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    if (0 == queue_id)
    {
        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT,
                          (a_uint8_t *) (&unit), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else if (1 == queue_id)
    {
        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q1_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q1_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q1_UNIT,
                          (a_uint8_t *) (&unit), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else if (2 == queue_id)
    {
        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER1, port_id, EG_Q2_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER4, port_id, EG_Q2_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q2_UNIT,
                          (a_uint8_t *) (&unit), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else if (3 == queue_id)
    {
        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER1, port_id, EG_Q3_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER4, port_id, EG_Q3_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q3_UNIT,
                          (a_uint8_t *) (&unit), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else if (4 == queue_id)
    {
        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER2, port_id, EG_Q4_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER5, port_id, EG_Q4_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_UNIT,
                          (a_uint8_t *) (&unit), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else
    {
        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER2, port_id, EG_Q5_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER5, port_id, EG_Q5_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_UNIT,
                          (a_uint8_t *) (&unit), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    return SW_OK;
}

static sw_error_t
_isisc_rate_queue_shaper_get(a_uint32_t dev_id, fal_port_t port_id,
                            fal_queue_t queue_id, a_bool_t * enable,
                            fal_egress_shaper_t * shaper)
{
    sw_error_t rv;
    a_uint32_t data = 0, cir = 0, eir = 0, cbs = 0, ebs = 0;

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    rv = _isisc_rate_port_queue_check(port_id, queue_id);
    SW_RTN_ON_ERROR(rv);

    aos_mem_zero(shaper, sizeof (fal_egress_shaper_t));

    HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_PT,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (data)
    {
        *enable = A_FALSE;
        return SW_OK;
    }

    if (0 == queue_id)
    {
        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else if (1 == queue_id)
    {
        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q1_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q1_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q1_UNIT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else if (2 == queue_id)
    {
        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER1, port_id, EG_Q2_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER4, port_id, EG_Q2_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q2_UNIT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else if (3 == queue_id)
    {
        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER1, port_id, EG_Q3_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER4, port_id, EG_Q3_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q3_UNIT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else if (4 == queue_id)
    {
        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER2, port_id, EG_Q4_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER5, port_id, EG_Q4_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_UNIT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }
    else
    {
        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER2, port_id, EG_Q5_CIR,
                          (a_uint8_t *) (&cir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER5, port_id, EG_Q5_EIR,
                          (a_uint8_t *) (&eir), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_CBS,
                          (a_uint8_t *) (&cbs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_EBS,
                          (a_uint8_t *) (&ebs), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_UNIT,
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    if ((0x7fff == cir) && (0x7fff == eir))
    {
        *enable = A_FALSE;
        return SW_OK;
    }

    *enable = A_TRUE;
    if (data)
    {
        shaper->meter_unit = FAL_FRAME_BASED;
        shaper->cir = cir / 2 * 125 + cir % 2 * 63;
        shaper->eir = eir / 2 * 125 + eir % 2 * 63;
        _isisc_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs));
        _isisc_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs));
    }
    else
    {
        shaper->meter_unit = FAL_BYTE_BASED;
        shaper->cir = cir << 5;
        shaper->eir = eir << 5;
        _isisc_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs));
        _isisc_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs));
    }

    return SW_OK;
}

static sw_error_t
_isisc_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id,
                           fal_acl_policer_t * policer)
{
    sw_error_t rv;
    a_uint32_t ts, cir, eir, cbs = 0, ebs = 0, addr, data[2] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    if (ISISC_MAX_POLICER_ID < policer_id)
    {
        return SW_BAD_PARAM;
    }

    if (A_TRUE == policer->counter_mode)
    {
        addr = ACL_POLICER_CNT_SEL_ADDR;
        data[0] = 0x1;
        HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id,
                              (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        addr = ACL_POLICER_CNT_MODE_ADDR;
        if (FAL_FRAME_BASED == policer->meter_unit)
        {
            data[0] = 0x0;
        }
        else
        {
            data[0] = 0x1;
        }
        HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id,
                              (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        addr = ACL_POLICER_CNT_RST_ADDR;
        data[0] = 0x1;
        HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id,
                              (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        data[0] = 0x0;
        HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id,
                              (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
        return rv;
    }

    addr = ACL_POLICER_CNT_SEL_ADDR;
    data[0] = 0x0;
    HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id,
                          (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (FAL_BYTE_BASED == policer->meter_unit)
    {
        cir = policer->cir >> 5;
        policer->cir = cir << 5;

        eir = policer->eir >> 5;
        policer->eir = eir << 5;

        _isisc_ingress_bs_byte_sw_to_hw(policer->cbs, &cbs);
        _isisc_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs));

        _isisc_ingress_bs_byte_sw_to_hw(policer->ebs, &ebs);
        _isisc_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs));

        SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_UNIT, 0, data[1]);
    }
    else if (FAL_FRAME_BASED == policer->meter_unit)
    {
        cir = (policer->cir * 2) / 125;
        policer->cir = cir / 2 * 125 + cir % 2 * 63;

        eir = (policer->eir * 2) / 125;
        policer->eir = eir / 2 * 125 + eir % 2 * 63;

        _isisc_ingress_bs_frame_sw_to_hw(policer->cbs, &cbs);
        _isisc_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs));

        _isisc_ingress_bs_frame_sw_to_hw(policer->ebs, &ebs);
        _isisc_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs));

        SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_UNIT, 1, data[1]);
    }
    else
    {
        return SW_BAD_PARAM;
    }

    SW_SET_REG_BY_FIELD(ACL_POLICER0, ACL_CIR, cir, data[0]);
    SW_SET_REG_BY_FIELD(ACL_POLICER0, ACL_CBS, cbs, data[0]);
    SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_EIR, eir, data[1]);
    SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_EBS, ebs, data[1]);

    if (A_TRUE == policer->deficit_en)
    {
        SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_BORROW, 1, data[1]);
    }

    if (A_TRUE == policer->color_mode)
    {
        SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_CM, 1, data[1]);
    }

    if (A_TRUE == policer->couple_flag)
    {
        SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_CF, 1, data[1]);
    }

    _isisc_rate_ts_parse(policer->meter_interval, &ts);
    SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_TS, ts, data[1]);

    HSL_REG_ENTRY_SET(rv, dev_id, ACL_POLICER0, policer_id,
                      (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_SET(rv, dev_id, ACL_POLICER1, policer_id,
                      (a_uint8_t *) (&data[1]), sizeof (a_uint32_t));

    return rv;
}

static sw_error_t
_isisc_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id,
                           fal_acl_policer_t * policer)
{
    sw_error_t rv;
    a_uint32_t unit, ts, cir, eir, cbs, ebs, addr, data[2] = {0};

    HSL_DEV_ID_CHECK(dev_id);

    if (ISISC_MAX_POLICER_ID < policer_id)
    {
        return SW_BAD_PARAM;
    }

    aos_mem_zero(policer, sizeof (policer));

    addr = ACL_POLICER_CNT_SEL_ADDR;
    HSL_REG_FIELD_GEN_GET(rv, dev_id, addr, 1, policer_id,
                          (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (data[0])
    {
        policer->counter_mode = A_TRUE;

        addr = ACL_POLICER_CNT_MODE_ADDR;
        HSL_REG_FIELD_GEN_GET(rv, dev_id, addr, 1, policer_id,
                              (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        if (data[0])
        {
            policer->meter_unit = FAL_BYTE_BASED;
        }
        else
        {
            policer->meter_unit = FAL_FRAME_BASED;
        }

        HSL_REG_ENTRY_GET(rv, dev_id, ACL_COUNTER0, policer_id,
                          (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        HSL_REG_ENTRY_GET(rv, dev_id, ACL_COUNTER1, policer_id,
                          (a_uint8_t *) (&data[1]), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        policer->counter_low = data[0];
        policer->counter_high = data[1];

        return SW_OK;
    }

    HSL_REG_ENTRY_GET(rv, dev_id, ACL_POLICER0, policer_id,
                      (a_uint8_t *) (&data[0]), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_GET(rv, dev_id, ACL_POLICER1, policer_id,
                      (a_uint8_t *) (&data[1]), sizeof (a_uint32_t));

    SW_GET_FIELD_BY_REG(ACL_POLICER0, ACL_CIR, cir, data[0]);
    SW_GET_FIELD_BY_REG(ACL_POLICER0, ACL_CBS, cbs, data[0]);
    SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_EIR, eir, data[1]);
    SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_EBS, ebs, data[1]);
    SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_UNIT, unit, data[1]);
    if (unit)
    {
        policer->meter_unit = FAL_FRAME_BASED;
        policer->cir = cir / 2 * 125 + cir % 2 * 63;
        policer->eir = eir / 2 * 125 + eir % 2 * 63;
        _isisc_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs));
        _isisc_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs));

    }
    else
    {
        policer->meter_unit = FAL_BYTE_BASED;
        policer->cir = cir << 5;
        policer->eir = eir << 5;
        _isisc_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs));
        _isisc_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs));
    }

    SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_BORROW, policer->deficit_en,
                        data[1]);
    SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_CF, policer->couple_flag, data[1]);
    SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_CM, policer->color_mode, data[1]);

    SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_TS, ts, data[1]);
    _isisc_rate_ts_reparse(ts, &(policer->meter_interval));

    return SW_OK;
}

sw_error_t
_isisc_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id,
                                  a_uint32_t  number)
{
    a_uint32_t val = number;
    sw_error_t rv;

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    if (val>255)
        return SW_BAD_PARAM;

    HSL_REG_FIELD_SET(rv, dev_id, INGRESS_POLICER0, port_id, ADD_RATE_BYTE,
                      (a_uint8_t *) (&val), sizeof (a_uint32_t));

    return rv;
}

sw_error_t
_isisc_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id,
                                  a_uint32_t  *number)
{
    a_uint32_t val = 0;
    sw_error_t rv = SW_OK;

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }


    HSL_REG_FIELD_GET(rv, dev_id, INGRESS_POLICER0, port_id, ADD_RATE_BYTE,
                      (a_uint8_t *) (&val), sizeof (a_uint32_t));
    *number = val;

    return rv;
}

sw_error_t
_isisc_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id,
                                a_bool_t  enable)
{
    a_uint32_t val = 0;
    sw_error_t rv;

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    HSL_REG_ENTRY_GET(rv, dev_id, QM_CTRL_REG, 0,
                      (a_uint8_t *) (&val), sizeof (a_uint32_t));

    SW_RTN_ON_ERROR(rv);


    if (A_TRUE == enable)
    {
        val |= (0x1<<(16+port_id));
    }
    else if (A_FALSE == enable)
    {
        val &= ~(0x1<<(16+port_id));
    }
    else
    {
        return SW_BAD_PARAM;
    }

    HSL_REG_ENTRY_SET(rv, dev_id, QM_CTRL_REG, 0,
                      (a_uint8_t *) (&val), sizeof (a_uint32_t));

    return rv;
}

sw_error_t
_isisc_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id,
                                a_bool_t*  enable)
{
    a_uint32_t val = 0;
    sw_error_t rv;

    HSL_DEV_ID_CHECK(dev_id);

    if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }

    HSL_REG_ENTRY_GET(rv, dev_id, QM_CTRL_REG, 0,
                      (a_uint8_t *) (&val), sizeof (a_uint32_t));

    SW_RTN_ON_ERROR(rv);

    if (val&(0x1<<(16+port_id)))
    {
        *enable = A_TRUE;
    }
    else
    {
        *enable = A_FALSE;
    }

    return rv;
}



/**
 * @brief Set port ingress policer parameters on one particular port.
 * @details   Comments:
    The granularity of speed is 32kbps or 62.5fps.
    Because of hardware granularity function will return actual speed in hardware.
    When disable port ingress policer input parameter speed is meaningless.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[in] policer port ingress policer parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id,
                           fal_port_policer_t * policer)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_port_policer_set(dev_id, port_id, policer);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get port ingress policer parameters on one particular port.
 * @details   Comments:
    The granularity of speed is 32kbps or 62.5fps.
    Because of hardware granularity function will return actual speed in hardware.
    When disable port ingress policer input parameter speed is meaningless.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[out] policer port ingress policer parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id,
                           fal_port_policer_t * policer)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_port_policer_get(dev_id, port_id, policer);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set port egress shaper parameters on one particular port.
 * @details   Comments:
    The granularity of speed is 32kbps or 62.5fps.
    Because of hardware granularity function will return actual speed in hardware.
    When disable port egress shaper parameters is meaningless.
 * @param[in] port_id port id
 * @param[in] enable A_TRUE or A_FALSE
 * @param[in] shaper port egress shaper parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id,
                          a_bool_t enable, fal_egress_shaper_t * shaper)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_port_shaper_set(dev_id, port_id, enable, shaper);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get port egress shaper parameters on one particular port.
 * @details   Comments:
    The granularity of speed is 32kbps or 62.5fps.
    Because of hardware granularity function will return actual speed in hardware.
    When disable port egress shaper parameters is meaningless.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[out] enable A_TRUE or A_FALSE
 * @param[out] shaper port egress shaper parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id,
                          a_bool_t * enable, fal_egress_shaper_t * shaper)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_port_shaper_get(dev_id, port_id, enable, shaper);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set queue egress shaper parameters on one particular port.
 * @details   Comments:
    The granularity of speed is 32kbps or 62.5fps.
    Because of hardware granularity function will return actual speed in hardware.
    When disable queue egress shaper parameters is meaningless.
 * @param[in] port_id port id
 * @param[in] queue_id queue id
 * @param[in] enable A_TRUE or A_FALSE
 * @param[in] shaper port egress shaper parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_queue_shaper_set(a_uint32_t dev_id, fal_port_t port_id,
                           fal_queue_t queue_id, a_bool_t enable,
                           fal_egress_shaper_t * shaper)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_queue_shaper_set(dev_id, port_id, queue_id, enable, shaper);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get queue egress shaper parameters on one particular port.
 * @details   Comments:
    The granularity of speed is 32kbps or 62.5fps.
    Because of hardware granularity function will return actual speed in hardware.
    When disable queue egress shaper parameters is meaningless.
 * @param[in] port_id port id
 * @param[in] queue_id queue id
 * @param[out] enable A_TRUE or A_FALSE
 * @param[out] shaper port egress shaper parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_queue_shaper_get(a_uint32_t dev_id, fal_port_t port_id,
                           fal_queue_t queue_id, a_bool_t * enable,
                           fal_egress_shaper_t * shaper)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_queue_shaper_get(dev_id, port_id, queue_id, enable, shaper);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set ACL ingress policer parameters.
 * @details   Comments:
    The granularity of speed is 32kbps or 62.5fps.
    Because of hardware granularity function will return actual speed in hardware.
 * @param[in] dev_id device id
 * @param[in] policer_id ACL policer id
 * @param[in] policer ACL ingress policer parameters
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id,
                          fal_acl_policer_t * policer)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_acl_policer_set(dev_id, policer_id, policer);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get ACL ingress policer parameters.
 * @details   Comments:
    The granularity of speed is 32kbps or 62.5fps.
    Because of hardware granularity function will return actual speed in hardware.
 * @param[in] dev_id device id
 * @param[in] policer_id ACL policer id
 * @param[in] policer ACL ingress policer parameters
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id,
                          fal_acl_policer_t * policer)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_acl_policer_get(dev_id, policer_id, policer);
    HSL_API_UNLOCK;
    return rv;
}

HSL_LOCAL sw_error_t
isisc_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id,
                                 a_uint32_t  number)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_port_add_rate_byte_set(dev_id, port_id, number);
    HSL_API_UNLOCK;
    return rv;
}

HSL_LOCAL sw_error_t
isisc_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id,
                                 a_uint32_t  *number)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_port_add_rate_byte_get(dev_id, port_id, number);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set status of port global flow control when global threshold is reached.
  * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[in] enable A_TRUE or A_FALSE
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id,
                               a_bool_t enable)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_port_gol_flow_en_set(dev_id, port_id, enable);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief get status of port global flow control when global threshold is reached.
  * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[out] enable A_TRUE or A_FALSE
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id,
                               a_bool_t* enable)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_rate_port_gol_flow_en_get(dev_id, port_id, enable);
    HSL_API_UNLOCK;
    return rv;
}



sw_error_t
isisc_rate_init(a_uint32_t dev_id)
{
    HSL_DEV_ID_CHECK(dev_id);

#ifndef HSL_STANDALONG
    {
        hsl_api_t *p_api;

        SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id));

        p_api->rate_port_policer_set = isisc_rate_port_policer_set;
        p_api->rate_port_policer_get = isisc_rate_port_policer_get;
        p_api->rate_port_shaper_set = isisc_rate_port_shaper_set;
        p_api->rate_port_shaper_get = isisc_rate_port_shaper_get;
        p_api->rate_queue_shaper_set = isisc_rate_queue_shaper_set;
        p_api->rate_queue_shaper_get = isisc_rate_queue_shaper_get;
        p_api->rate_acl_policer_set = isisc_rate_acl_policer_set;
        p_api->rate_acl_policer_get = isisc_rate_acl_policer_get;
        p_api->rate_port_gol_flow_en_set = isisc_rate_port_gol_flow_en_set;
        p_api->rate_port_gol_flow_en_get = isisc_rate_port_gol_flow_en_get;
        p_api->rate_port_add_rate_byte_set=isisc_rate_port_add_rate_byte_set;
        p_api->rate_port_add_rate_byte_get=isisc_rate_port_add_rate_byte_get;
    }
#endif

    return SW_OK;
}

/**
 * @}
 */

