/*
 * 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_ip ISISC_IP
 * @{
 */

#include "sw.h"
#include "hsl.h"
#include "hsl_dev.h"
#include "hsl_port_prop.h"
#include "isisc_ip.h"
#include "isisc_reg.h"

#define ISISC_HOST_ENTRY_DATA0_ADDR              0x0e80
#define ISISC_HOST_ENTRY_DATA1_ADDR              0x0e84
#define ISISC_HOST_ENTRY_DATA2_ADDR              0x0e88
#define ISISC_HOST_ENTRY_DATA3_ADDR              0x0e8c
#define ISISC_HOST_ENTRY_DATA4_ADDR              0x0e90
#define ISISC_HOST_ENTRY_DATA5_ADDR              0x0e94
#define ISISC_HOST_ENTRY_DATA6_ADDR              0x0e98
#define ISISC_HOST_ENTRY_DATA7_ADDR              0x0e58

#define ISISC_HOST_ENTRY_REG_NUM                 8

#define ISISC_HOST_ENTRY_FLUSH                   1
#define ISISC_HOST_ENTRY_ADD                     2
#define ISISC_HOST_ENTRY_DEL                     3
#define ISISC_HOST_ENTRY_NEXT                    4
#define ISISC_HOST_ENTRY_SEARCH                  5

#define ISISC_ENTRY_ARP                          3

#define ISISC_INTF_MAC_ADDR_NUM                  8
#define ISISC_INTF_MAC_TBL0_ADDR                 0x5a900
#define ISISC_INTF_MAC_TBL1_ADDR                 0x5a904
#define ISISC_INTF_MAC_TBL2_ADDR                 0x5a908
#define ISISC_INTF_MAC_EDIT0_ADDR                0x02000
#define ISISC_INTF_MAC_EDIT1_ADDR                0x02004
#define ISISC_INTF_MAC_EDIT2_ADDR                0x02008

#define ISISC_IP6_BASE_ADDR                      0x0470

#define ISISC_HOST_ENTRY_NUM                     128

#define ISISC_IP_COUTER_ADDR                     0x2b000

static a_uint32_t isisc_mac_snap[SW_MAX_NR_DEV] = { 0 };
static fal_intf_mac_entry_t isisc_intf_snap[SW_MAX_NR_DEV][ISISC_INTF_MAC_ADDR_NUM];

static void
_isisc_ip_pt_learn_save(a_uint32_t dev_id, a_uint32_t * status)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    if (SW_OK != rv)
    {
        return;
    }

    *status = (data & 0x7f7f);

    data &= 0xffff8080;
    HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return;
}

static void
_isisc_ip_pt_learn_restore(a_uint32_t dev_id, a_uint32_t status)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    if (SW_OK != rv)
    {
        return;
    }

    data &= 0xffff8080;
    data |= (status & 0x7f7f);

    HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return;
}

static sw_error_t
_isisc_ip_feature_check(a_uint32_t dev_id)
{
    sw_error_t rv;
    a_uint32_t entry = 0;

    HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID,
                      (a_uint8_t *) (&entry), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (S17C_DEVICE_ID == entry)
    {
        return SW_OK;
    }
    else
    {
        return SW_NOT_SUPPORTED;
    }
}

static sw_error_t
_isisc_ip_counter_get(a_uint32_t dev_id, a_uint32_t cnt_id,
                     a_uint32_t counter[2])
{
    sw_error_t rv;
    a_uint32_t i, addr;

    addr = ISISC_IP_COUTER_ADDR + (cnt_id << 3);
    for (i = 0; i < 2; i++)
    {
        HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t),
                              (a_uint8_t *) (&(counter[i])),
                              sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);

        addr += 4;
    }

    return SW_OK;
}

static sw_error_t
_isisc_host_entry_commit(a_uint32_t dev_id, a_uint32_t entry_type, a_uint32_t op)
{
    a_uint32_t busy = 1, i = 0x100, entry = 0, j, try_num;
    a_uint32_t learn_status = 0;
    sw_error_t rv;

    while (busy && --i)
    {
        HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry),
                          sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
        SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry);
    }

    if (i == 0)
    {
        return SW_BUSY;
    }

    SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_BUSY, 1, entry);
    SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_SEL, entry_type, entry);
    SW_SET_REG_BY_FIELD(HOST_ENTRY7, ENTRY_FUNC, op, entry);

    HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry),
                      sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    /* hardware requirements, we should disable ARP learn at first */
    /* and maybe we should try several times... */
    _isisc_ip_pt_learn_save(dev_id, &learn_status);
    if (learn_status)
    {
        try_num = 10;
    }
    else
    {
        try_num = 1;
    }

    for (j = 0; j < try_num; j++)
    {
        busy = 1;
        i = 0x1000;
        while (busy && --i)
        {
            HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry),
                              sizeof (a_uint32_t));
            if (SW_OK != rv)
            {
                _isisc_ip_pt_learn_restore(dev_id, learn_status);
                return rv;
            }
            SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry);
        }

        if (i == 0)
        {
            _isisc_ip_pt_learn_restore(dev_id, learn_status);
            return SW_BUSY;
        }

        /* hardware requirement, we should read again... */
        HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry),
                          sizeof (a_uint32_t));
        if (SW_OK != rv)
        {
            _isisc_ip_pt_learn_restore(dev_id, learn_status);
            return rv;
        }

        /* operation success...... */
        SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, busy, entry);
        if (busy)
        {
            _isisc_ip_pt_learn_restore(dev_id, learn_status);
            return SW_OK;
        }
    }

    _isisc_ip_pt_learn_restore(dev_id, learn_status);
    if (ISISC_HOST_ENTRY_NEXT == op)
    {
        return SW_NO_MORE;
    }
    else if (ISISC_HOST_ENTRY_SEARCH == op)
    {
        return SW_NOT_FOUND;
    }
    else if (ISISC_HOST_ENTRY_DEL == op)
    {
        return SW_NOT_FOUND;
    }
    else
    {
        return SW_FAIL;
    }
}

static sw_error_t
_isisc_ip_intf_sw_to_hw(a_uint32_t dev_id, fal_host_entry_t * entry,
                       a_uint32_t * hw_intf)
{
    sw_error_t rv;
    a_uint32_t addr, lvid, hvid, tbl[3] = {0}, i;
    a_uint32_t sw_intf = entry->intf_id;
    a_uint32_t vid_offset;

    for (i = 0; i < ISISC_INTF_MAC_ADDR_NUM; i++)
    {
        if (isisc_mac_snap[dev_id] & (0x1 << i))
        {
            addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + 4;
            HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t),
                                  (a_uint8_t *) (&(tbl[1])),
                                  sizeof (a_uint32_t));
            SW_RTN_ON_ERROR(rv);

            addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + 8;
            HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t),
                                  (a_uint8_t *) (&(tbl[2])),
                                  sizeof (a_uint32_t));
            SW_RTN_ON_ERROR(rv);

            SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_HIGH0, hvid, tbl[1]);
            SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VID_HIGH1, lvid, tbl[2]);
            hvid |= ((lvid & 0xff) << 4);

            SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, lvid, tbl[1]);

            if ((lvid <= sw_intf) && (hvid >= sw_intf))
            {
                vid_offset = entry->expect_vid ? (entry->expect_vid - lvid) : (sw_intf - lvid);
                *hw_intf = (vid_offset << 3) | i;
                return SW_OK;
            }
        }
    }

    return SW_BAD_PARAM;
}

static sw_error_t
_isisc_ip_intf_hw_to_sw(a_uint32_t dev_id, a_uint32_t hw_intf,
                       a_uint32_t * sw_intf)
{
    sw_error_t rv;
    a_uint32_t addr, lvid, tbl = 0, i;

    i = hw_intf & 0x7;

    addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + 4;
    HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t),
                          (a_uint8_t *) (&tbl), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, lvid, tbl);
    *sw_intf = lvid + (hw_intf >> 3);

    return SW_OK;
}

static sw_error_t
_isisc_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time)
{
    sw_error_t rv;
    a_uint32_t data;

    if (255 < ((*time + 5) / 6))
    {
        return SW_BAD_PARAM;
    }

    data = ((*time + 5) / 6);
    *time = data * 6;

    HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ARP_AGE_TIME,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ARP_AGE_TIME,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    *time = data * 6;
    return SW_OK;
}

static sw_error_t
_isisc_host_sw_to_hw(a_uint32_t dev_id, fal_host_entry_t * entry,
                    a_uint32_t reg[])
{
    sw_error_t rv;
    a_uint32_t data;

    if (FAL_IP_IP4_ADDR & entry->flags)
    {
        reg[0] = entry->ip4_addr;
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 0, reg[6]);
    }

    if (FAL_IP_IP6_ADDR & entry->flags)
    {
        reg[0] = entry->ip6_addr.ul[3];
        reg[1] = entry->ip6_addr.ul[2];
        reg[2] = entry->ip6_addr.ul[1];
        reg[3] = entry->ip6_addr.ul[0];
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]);
    }

    SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR2, entry->mac_addr.uc[2], reg[4]);
    SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR3, entry->mac_addr.uc[3], reg[4]);
    SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR4, entry->mac_addr.uc[4], reg[4]);
    SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR5, entry->mac_addr.uc[5], reg[4]);
    SW_SET_REG_BY_FIELD(HOST_ENTRY5, MAC_ADDR0, entry->mac_addr.uc[0], reg[5]);
    SW_SET_REG_BY_FIELD(HOST_ENTRY5, MAC_ADDR1, entry->mac_addr.uc[1], reg[5]);

    rv = _isisc_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data);

    SW_RTN_ON_ERROR(rv);
    SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]);

#if 0
    if (A_TRUE != hsl_port_prop_check(dev_id, entry->port_id, HSL_PP_INCL_CPU))
    {
        return SW_BAD_PARAM;
    }
#endif

    SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]);

    if (FAL_IP_CPU_ADDR & entry->flags)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY5, CPU_ADDR, 1, reg[5]);
    }

    SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]);

    if ((A_TRUE == entry->mirror_en) && (FAL_MAC_FRWRD != entry->action))
    {
        return SW_NOT_SUPPORTED;
    }

    if (A_TRUE == entry->counter_en)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 1, reg[6]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_IDX, entry->counter_id, reg[6]);
    }

    if (FAL_MAC_DROP == entry->action)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, 7, reg[5]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 3, reg[6]);
    }
    else if (FAL_MAC_RDT_TO_CPU == entry->action)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 1, reg[6]);
    }
    else if (FAL_MAC_CPY_TO_CPU == entry->action)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 2, reg[6]);
    }
    else
    {
        if (A_TRUE == entry->mirror_en)
        {
            SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 0, reg[6]);
        }
        else
        {
            SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 3, reg[6]);
        }
    }

    return SW_OK;
}

static sw_error_t
_isisc_host_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[],
                    fal_host_entry_t * entry)
{
    sw_error_t rv;
    a_uint32_t data, cnt[2] = {0};

    SW_GET_FIELD_BY_REG(HOST_ENTRY6, IP_VER, data, reg[6]);
    if (data)
    {
        entry->ip6_addr.ul[0] = reg[3];
        entry->ip6_addr.ul[1] = reg[2];
        entry->ip6_addr.ul[2] = reg[1];
        entry->ip6_addr.ul[3] = reg[0];
        entry->flags |= FAL_IP_IP6_ADDR;
    }
    else
    {
        entry->ip4_addr = reg[0];
        entry->flags |= FAL_IP_IP4_ADDR;
    }

    SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR2, entry->mac_addr.uc[2], reg[4]);
    SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR3, entry->mac_addr.uc[3], reg[4]);
    SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR4, entry->mac_addr.uc[4], reg[4]);
    SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR5, entry->mac_addr.uc[5], reg[4]);
    SW_GET_FIELD_BY_REG(HOST_ENTRY5, MAC_ADDR0, entry->mac_addr.uc[0], reg[5]);
    SW_GET_FIELD_BY_REG(HOST_ENTRY5, MAC_ADDR1, entry->mac_addr.uc[1], reg[5]);

    SW_GET_FIELD_BY_REG(HOST_ENTRY5, INTF_ID, data, reg[5]);
    rv = _isisc_ip_intf_hw_to_sw(dev_id, data, &(entry->intf_id));
    SW_RTN_ON_ERROR(rv);

    SW_GET_FIELD_BY_REG(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]);

    SW_GET_FIELD_BY_REG(HOST_ENTRY5, CPU_ADDR, data, reg[5]);
    if (data)
    {
        entry->flags |= FAL_IP_CPU_ADDR;
    }

    SW_GET_FIELD_BY_REG(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]);

    SW_GET_FIELD_BY_REG(HOST_ENTRY6, CNT_EN, data, reg[6]);
    if (data)
    {
        entry->counter_en = A_TRUE;
        SW_GET_FIELD_BY_REG(HOST_ENTRY6, CNT_IDX, entry->counter_id, reg[6]);

        rv = _isisc_ip_counter_get(dev_id, entry->counter_id, cnt);
        SW_RTN_ON_ERROR(rv);

        entry->packet = cnt[0];
        entry->byte = cnt[1];
    }
    else
    {
        entry->counter_en = A_FALSE;
    }

    SW_GET_FIELD_BY_REG(HOST_ENTRY6, PPPOE_EN, data, reg[6]);
    if (data)
    {
        entry->pppoe_en = A_TRUE;
        SW_GET_FIELD_BY_REG(HOST_ENTRY6, PPPOE_IDX, data, reg[6]);
        entry->pppoe_id = data;
    }
    else
    {
        entry->pppoe_en = A_FALSE;
    }

    if (7 == entry->port_id)
    {
        entry->port_id = 0;
        entry->action = FAL_MAC_DROP;
    }
    else
    {
        SW_GET_FIELD_BY_REG(HOST_ENTRY6, ACTION, data, reg[6]);
        entry->action = FAL_MAC_FRWRD;
        if (0 == data)
        {
            entry->mirror_en = A_TRUE;
        }
        else if (1 == data)
        {
            entry->action = FAL_MAC_RDT_TO_CPU;
        }
        else if (2 == data)
        {
            entry->action = FAL_MAC_CPY_TO_CPU;
        }
    }

    return SW_OK;
}

static sw_error_t
_isisc_host_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[])
{
    sw_error_t rv;
    a_uint32_t i, addr;

    for (i = 0; i < ISISC_HOST_ENTRY_REG_NUM; i++)
    {
        if((ISISC_HOST_ENTRY_REG_NUM - 1) == i)
        {
            addr = ISISC_HOST_ENTRY_DATA7_ADDR;
        }
        else
        {
            addr = ISISC_HOST_ENTRY_DATA0_ADDR + (i << 2);
        }

        HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t),
                              (a_uint8_t *) (&reg[i]), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    return SW_OK;
}

static sw_error_t
_isisc_host_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[])
{
    sw_error_t rv;
    a_uint32_t i, addr;

    for (i = 0; i < ISISC_HOST_ENTRY_REG_NUM; i++)
    {
        if((ISISC_HOST_ENTRY_REG_NUM - 1) == i)
        {
            addr = ISISC_HOST_ENTRY_DATA7_ADDR;
        }
        else
        {
            addr = ISISC_HOST_ENTRY_DATA0_ADDR + (i << 2);
        }
        HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t),
                              (a_uint8_t *) (&reg[i]), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    return SW_OK;
}

static sw_error_t
_isisc_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * entry)
{
    sw_error_t rv;
    a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_sw_to_hw(dev_id, entry, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_down_to_hw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_ADD);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&reg[7]),
                      sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]);
    return SW_OK;
}

static sw_error_t
_isisc_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode,
                  fal_host_entry_t * entry)
{
    sw_error_t rv;
    a_uint32_t data, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, op = ISISC_HOST_ENTRY_FLUSH;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (FAL_IP_ENTRY_ID_EN & del_mode)
    {
        return SW_NOT_SUPPORTED;
    }

    if (FAL_IP_ENTRY_IPADDR_EN & del_mode)
    {
        op = ISISC_HOST_ENTRY_DEL;
        if (FAL_IP_IP4_ADDR & entry->flags)
        {
            reg[0] = entry->ip4_addr;
        }

        if (FAL_IP_IP6_ADDR & entry->flags)
        {
            reg[0] = entry->ip6_addr.ul[3];
            reg[1] = entry->ip6_addr.ul[2];
            reg[2] = entry->ip6_addr.ul[1];
            reg[3] = entry->ip6_addr.ul[0];
            SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]);
        }
    }

    if (FAL_IP_ENTRY_INTF_EN & del_mode)
    {
        rv = _isisc_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data);
        SW_RTN_ON_ERROR(rv);

        SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_VID, 1, reg[7]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]);
    }

    if (FAL_IP_ENTRY_PORT_EN & del_mode)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SP, 1, reg[7]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]);
    }

    if (FAL_IP_ENTRY_STATUS_EN & del_mode)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]);
    }

    rv = _isisc_host_down_to_hw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, op);
    return rv;
}

static sw_error_t
_isisc_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode,
                  fal_host_entry_t * entry)
{
    sw_error_t rv;
    a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (FAL_IP_ENTRY_IPADDR_EN != get_mode)
    {
        return SW_NOT_SUPPORTED;
    }

    if (FAL_IP_IP4_ADDR & entry->flags)
    {
        reg[0] = entry->ip4_addr;
    }
    else
    {
        reg[0] = entry->ip6_addr.ul[3];
        reg[1] = entry->ip6_addr.ul[2];
        reg[2] = entry->ip6_addr.ul[1];
        reg[3] = entry->ip6_addr.ul[0];
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]);
    }

    rv = _isisc_host_down_to_hw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP,
                                 ISISC_HOST_ENTRY_SEARCH);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_up_to_sw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    aos_mem_zero(entry, sizeof (fal_host_entry_t));

    rv = _isisc_host_hw_to_sw(dev_id, reg, entry);
    SW_RTN_ON_ERROR(rv);

    if (!(entry->status))
    {
        return SW_NOT_FOUND;
    }

    HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&reg[7]),
                      sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]);
    return SW_OK;
}

static sw_error_t
_isisc_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode,
                   fal_host_entry_t * entry)
{
    sw_error_t rv;
    a_uint32_t idx, data, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id)
    {
        idx = ISISC_HOST_ENTRY_NUM - 1;
    }
    else
    {
        if ((ISISC_HOST_ENTRY_NUM - 1) == entry->entry_id)
        {
            return SW_NO_MORE;
        }
        else
        {
            idx = entry->entry_id;
        }
    }

    SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, idx, reg[7]);

    if (FAL_IP_ENTRY_INTF_EN & next_mode)
    {
        rv = _isisc_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data);
        SW_RTN_ON_ERROR(rv);

        SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_VID, 1, reg[7]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]);
    }

    if (FAL_IP_ENTRY_PORT_EN & next_mode)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SP, 1, reg[7]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]);
    }

    if (FAL_IP_ENTRY_STATUS_EN & next_mode)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]);
    }

    rv = _isisc_host_down_to_hw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_NEXT);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_up_to_sw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    aos_mem_zero(entry, sizeof (fal_host_entry_t));

    rv = _isisc_host_hw_to_sw(dev_id, reg, entry);
    SW_RTN_ON_ERROR(rv);

    if (!(entry->status))
    {
        return SW_NO_MORE;
    }

    SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]);
    return SW_OK;
}

static sw_error_t
_isisc_ip_host_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id,
                           a_uint32_t cnt_id, a_bool_t enable)
{
    sw_error_t rv;
    a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    tbl_idx = (entry_id - 1) & 0x7f;
    SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]);

    rv = _isisc_host_down_to_hw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_NEXT);
    if (SW_OK != rv)
    {
        return SW_NOT_FOUND;
    }

    rv = _isisc_host_up_to_sw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]);
    if (entry_id != tbl_idx)
    {
        return SW_NOT_FOUND;
    }

    tbl[0] = reg[0];
    tbl[1] = reg[1];
    tbl[2] = reg[2];
    tbl[3] = reg[3];
    tbl[6] = (reg[6] >> 15) << 15;
    rv = _isisc_host_down_to_hw(dev_id, tbl);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_DEL);
    SW_RTN_ON_ERROR(rv);

    if (A_FALSE == enable)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 0, reg[6]);
    }
    else if (A_TRUE == enable)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 1, reg[6]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_IDX, cnt_id, reg[6]);
    }
    else
    {
        return SW_BAD_PARAM;
    }

    reg[7] = 0x0;
    rv = _isisc_host_down_to_hw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_ADD);
    return rv;
}

static sw_error_t
_isisc_ip_host_pppoe_bind(a_uint32_t dev_id, a_uint32_t entry_id,
                         a_uint32_t pppoe_id, a_bool_t enable)
{
    sw_error_t rv;
    a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    tbl_idx = (entry_id - 1) & 0x7f;
    SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]);

    rv = _isisc_host_down_to_hw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_NEXT);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_up_to_sw(dev_id, reg);
    if (SW_OK != rv)
    {
        return SW_NOT_FOUND;
    }

    SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]);
    if (entry_id != tbl_idx)
    {
        return SW_NOT_FOUND;
    }

    if (A_FALSE == enable)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_EN, 0, reg[6]);
    }
    else if (A_TRUE == enable)
    {
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_EN, 1, reg[6]);
        SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_IDX, pppoe_id, reg[6]);
    }
    else
    {
        return SW_BAD_PARAM;
    }

    tbl[0] = reg[0];
    tbl[1] = reg[1];
    tbl[2] = reg[2];
    tbl[3] = reg[3];
    tbl[6] = (reg[6] >> 15) << 15;
    rv = _isisc_host_down_to_hw(dev_id, tbl);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_DEL);
    SW_RTN_ON_ERROR(rv);

    reg[7] = 0x0;
    rv = _isisc_host_down_to_hw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_ADD);
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_up_to_sw(dev_id, reg);
    SW_RTN_ON_ERROR(rv);

    return SW_OK;
}

static sw_error_t
_isisc_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id,
                          a_uint32_t flags)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (FAL_ARP_LEARN_REQ & flags)
    {
        data |= (0x1 << port_id);
    }
    else
    {
        data &= (~(0x1 << port_id));
    }

    if (FAL_ARP_LEARN_ACK & flags)
    {
        data |= (0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id));
    }
    else
    {
        data &= (~(0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id)));
    }

    HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id,
                          a_uint32_t * flags)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    *flags = 0;

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (data & (0x1 << port_id))
    {
        *flags |= FAL_ARP_LEARN_REQ;
    }

    if (data & (0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id)))
    {
        *flags |= FAL_ARP_LEARN_ACK;
    }

    return SW_OK;
}

static sw_error_t
_isisc_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode)
{
    sw_error_t rv;
    a_uint32_t data;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (FAL_ARP_LEARN_ALL == mode)
    {
        data = 1;
    }
    else if (FAL_ARP_LEARN_LOCAL == mode)
    {
        data = 0;
    }
    else
    {
        return SW_BAD_PARAM;
    }

    HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ARP_LEARN_MODE,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ARP_LEARN_MODE,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (data)
    {
        *mode = FAL_ARP_LEARN_ALL;
    }
    else
    {
        *mode = FAL_ARP_LEARN_LOCAL;
    }

    return SW_OK;
}

static sw_error_t
_isisc_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id,
                          fal_source_guard_mode_t mode)
{
    sw_error_t rv;
    a_uint32_t reg = 0, data;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL1, 0,
                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (FAL_NO_SOURCE_GUARD < mode)
    {
        return SW_BAD_PARAM;
    }

    data = 0;
    if (FAL_MAC_IP_GUARD == mode)
    {
        data = 1;
    }
    else if (FAL_MAC_IP_PORT_GUARD == mode)
    {
        data = 2;
    }
    else if (FAL_MAC_IP_VLAN_GUARD == mode)
    {
        data = 3;
    }
    else if (FAL_MAC_IP_PORT_VLAN_GUARD == mode)
    {
        data = 4;
    }
    reg &= (~(0x7 << (port_id * 3)));
    reg |= ((data & 0x7) << (port_id * 3));

    HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL1, 0,
                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    data = 1;
    if (FAL_NO_SOURCE_GUARD == mode)
    {
        data = 0;
    }

    HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, SP_CHECK_EN,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id,
                          fal_source_guard_mode_t * mode)
{
    sw_error_t rv;
    a_uint32_t reg = 0, data;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL1, 0,
                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    data = (reg >> (port_id * 3)) & 0x7;

    *mode = FAL_NO_SOURCE_GUARD;
    if (1 == data)
    {
        *mode = FAL_MAC_IP_GUARD;
    }
    else if (2 == data)
    {
        *mode = FAL_MAC_IP_PORT_GUARD;
    }
    else if (3 == data)
    {
        *mode = FAL_MAC_IP_VLAN_GUARD;
    }
    else if (4 == data)
    {
        *mode = FAL_MAC_IP_PORT_VLAN_GUARD;
    }

    return SW_OK;
}

static sw_error_t
_isisc_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd)
{
    sw_error_t rv;
    a_uint32_t data;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (FAL_MAC_FRWRD == cmd)
    {
        data = 0;
    }
    else if (FAL_MAC_DROP == cmd)
    {
        data = 1;
    }
    else if (FAL_MAC_RDT_TO_CPU == cmd)
    {
        data = 2;
    }
    else
    {
        return SW_NOT_SUPPORTED;
    }

    HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, IP_NOT_FOUND,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, IP_NOT_FOUND,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (0 == data)
    {
        *cmd = FAL_MAC_FRWRD;
    }
    else if (1 == data)
    {
        *cmd = FAL_MAC_DROP;
    }
    else
    {
        *cmd = FAL_MAC_RDT_TO_CPU;
    }

    return SW_OK;
}

static sw_error_t
_isisc_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id,
                       fal_source_guard_mode_t mode)
{
    sw_error_t rv;
    a_uint32_t reg = 0, data;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_DEV_ID_CHECK(dev_id);

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL0, 0,
                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (FAL_NO_SOURCE_GUARD < mode)
    {
        return SW_BAD_PARAM;
    }

    data = 0;
    if (FAL_MAC_IP_GUARD == mode)
    {
        data = 1;
    }
    else if (FAL_MAC_IP_PORT_GUARD == mode)
    {
        data = 2;
    }
    else if (FAL_MAC_IP_VLAN_GUARD == mode)
    {
        data = 3;
    }
    else if (FAL_MAC_IP_PORT_VLAN_GUARD == mode)
    {
        data = 4;
    }
    reg &= (~(0x7 << (port_id * 3)));
    reg |= ((data & 0x7) << (port_id * 3));

    HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL0, 0,
                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id,
                       fal_source_guard_mode_t * mode)
{
    sw_error_t rv;
    a_uint32_t reg = 0, data;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_DEV_ID_CHECK(dev_id);

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL0, 0,
                      (a_uint8_t *) (&reg), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    data = (reg >> (port_id * 3)) & 0x7;

    *mode = FAL_NO_SOURCE_GUARD;
    if (1 == data)
    {
        *mode = FAL_MAC_IP_GUARD;
    }
    else if (2 == data)
    {
        *mode = FAL_MAC_IP_PORT_GUARD;
    }
    else if (3 == data)
    {
        *mode = FAL_MAC_IP_VLAN_GUARD;
    }
    else if (4 == data)
    {
        *mode = FAL_MAC_IP_PORT_VLAN_GUARD;
    }

    return SW_OK;
}

static sw_error_t
_isisc_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd)
{
    sw_error_t rv;
    a_uint32_t data;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (FAL_MAC_FRWRD == cmd)
    {
        data = 0;
    }
    else if (FAL_MAC_DROP == cmd)
    {
        data = 1;
    }
    else if (FAL_MAC_RDT_TO_CPU == cmd)
    {
        data = 2;
    }
    else
    {
        return SW_NOT_SUPPORTED;
    }

    HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARP_NOT_FOUND,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARP_NOT_FOUND,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (0 == data)
    {
        *cmd = FAL_MAC_FRWRD;
    }
    else if (1 == data)
    {
        *cmd = FAL_MAC_DROP;
    }
    else
    {
        *cmd = FAL_MAC_RDT_TO_CPU;
    }

    return SW_OK;
}

static sw_error_t
_isisc_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable)
{
    sw_error_t rv;
    a_uint32_t data;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (A_TRUE == enable)
    {
        data = 1;
    }
    else if (A_FALSE == enable)
    {
        data = 0;
    }
    else
    {
        return SW_BAD_PARAM;
    }

    HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, L3_EN,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable)
{
    sw_error_t rv;
    a_uint32_t route_en = 0, l3_en = 0;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN,
                      (a_uint8_t *) (&route_en), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, L3_EN,
                      (a_uint8_t *) (&l3_en), sizeof (a_uint32_t))
    SW_RTN_ON_ERROR(rv);

    if (route_en && l3_en)
    {
        *enable = A_TRUE;
    }
    else
    {
        *enable = A_FALSE;
    }

    return rv;
}

static sw_error_t
_isisc_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry)
{
    sw_error_t rv;
    a_uint32_t i, j, found = 0, addr, tbl[3] = { 0 };
    fal_intf_mac_entry_t * intf_entry = NULL;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    for (i = 0; i < ISISC_INTF_MAC_ADDR_NUM; i++)
    {
        if (isisc_mac_snap[dev_id] & (0x1 << i))
        {
            intf_entry = &(isisc_intf_snap[dev_id][i]);
            if ((entry->vid_low == intf_entry->vid_low)
                    && (entry->vid_high == intf_entry->vid_high))
            {
                /* all same, return OK directly */
                if (!aos_mem_cmp(intf_entry, entry, sizeof(fal_intf_mac_entry_t)))
                {
                    return SW_OK;
                }
                else
                {
                    /* update entry */
                    found = 1;
                    break;
                }
            }
            else
            {
                /* entry VID cross border, not support */
                if ((entry->vid_low >= intf_entry->vid_low) && (entry->vid_low <= intf_entry->vid_high))
                {
                    return SW_BAD_PARAM;
                }

                /* entry VID cross border, not support */
                if ((entry->vid_high >= intf_entry->vid_low) && (entry->vid_low <= intf_entry->vid_high))
                {
                    return SW_BAD_PARAM;
                }
            }
        }
    }

    if (!found)
    {
        for (i = 0; i < ISISC_INTF_MAC_ADDR_NUM; i++)
        {
            if (!(isisc_mac_snap[dev_id] & (0x1 << i)))
            {
                intf_entry = &(isisc_intf_snap[dev_id][i]);
                break;
            }
        }
    }

    if (ISISC_INTF_MAC_ADDR_NUM == i)
    {
        return SW_NO_RESOURCE;
    }

    if ((A_FALSE == entry->ip4_route) && (A_FALSE == entry->ip6_route))
    {
        return SW_NOT_SUPPORTED;
    }

    if (512 <= (entry->vid_high - entry->vid_low))
    {
        return SW_BAD_PARAM;
    }

    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR2, entry->mac_addr.uc[2],
                        tbl[0]);
    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR3, entry->mac_addr.uc[3],
                        tbl[0]);
    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR4, entry->mac_addr.uc[4],
                        tbl[0]);
    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR5, entry->mac_addr.uc[5],
                        tbl[0]);
    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, MAC_ADDR0, entry->mac_addr.uc[0],
                        tbl[1]);
    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, MAC_ADDR1, entry->mac_addr.uc[1],
                        tbl[1]);

    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, VID_LOW, entry->vid_low, tbl[1]);
    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, VID_HIGH0, (entry->vid_high & 0xf),
                        tbl[1]);
    SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, VID_HIGH1, (entry->vid_high >> 4),
                        tbl[2]);

    if (A_TRUE == entry->ip4_route)
    {
        SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, IP4_ROUTE, 1, tbl[2]);
    }

    if (A_TRUE == entry->ip6_route)
    {
        SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, IP6_ROUTE, 1, tbl[2]);
    }

    for (j = 0; j < 2; j++)
    {
        addr = ISISC_INTF_MAC_EDIT0_ADDR + (i << 4) + (j << 2);
        HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t),
                              (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    for (j = 0; j < 3; j++)
    {
        addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + (j << 2);
        HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t),
                              (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    isisc_mac_snap[dev_id] |= (0x1 << i);
    *intf_entry = *entry;
    entry->entry_id = i;
    return SW_OK;
}

static sw_error_t
_isisc_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode,
                        fal_intf_mac_entry_t * entry)
{
    sw_error_t rv;
    a_uint32_t addr, tbl[3] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (!(FAL_IP_ENTRY_ID_EN & del_mode))
    {
        return SW_NOT_SUPPORTED;
    }

    if (ISISC_INTF_MAC_ADDR_NUM <= entry->entry_id)
    {
        return SW_BAD_PARAM;
    }

    /* clear valid bits */
    addr = ISISC_INTF_MAC_TBL2_ADDR + (entry->entry_id << 4);
    HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t),
                          (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    isisc_mac_snap[dev_id] &= (~(0x1 << entry->entry_id));
    return SW_OK;
}

static sw_error_t
_isisc_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode,
                         fal_intf_mac_entry_t * entry)
{
    sw_error_t rv;
    a_uint32_t i, j, idx, addr, tbl[3] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id)
    {
        idx = 0;
    }
    else
    {
        if ((ISISC_INTF_MAC_ADDR_NUM - 1) == entry->entry_id)
        {
            return SW_NO_MORE;
        }
        else
        {
            idx = entry->entry_id + 1;
        }
    }

    for (i = idx; i < ISISC_INTF_MAC_ADDR_NUM; i++)
    {
        if (isisc_mac_snap[dev_id] & (0x1 << i))
        {
            break;
        }
    }

    if (ISISC_INTF_MAC_ADDR_NUM == i)
    {
        return SW_NO_MORE;
    }

    for (j = 0; j < 3; j++)
    {
        addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + (j << 2);
        HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t),
                              (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    aos_mem_zero(entry, sizeof (fal_intf_mac_entry_t));

    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR2, entry->mac_addr.uc[2],
                        tbl[0]);
    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR3, entry->mac_addr.uc[3],
                        tbl[0]);
    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR4, entry->mac_addr.uc[4],
                        tbl[0]);
    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR5, entry->mac_addr.uc[5],
                        tbl[0]);
    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, MAC_ADDR0, entry->mac_addr.uc[0],
                        tbl[1]);
    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, MAC_ADDR1, entry->mac_addr.uc[1],
                        tbl[1]);

    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, entry->vid_low, tbl[1]);
    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_HIGH0, j, tbl[1]);
    entry->vid_high = j & 0xf;
    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VID_HIGH1, j, tbl[2]);
    entry->vid_high |= ((j & 0xff) << 4);

    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, IP4_ROUTE, j, tbl[2]);
    if (j)
    {
        entry->ip4_route = A_TRUE;
    }

    SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, IP6_ROUTE, j, tbl[2]);
    if (j)
    {
        entry->ip6_route = A_TRUE;
    }

    entry->entry_id = i;
    return SW_OK;
}

#define ISISC_WCMP_ENTRY_MAX_ID    3
#define ISISC_WCMP_HASH_MAX_NUM    16
#define ISISC_IP_ENTRY_MAX_ID      127

#define ISISC_WCMP_HASH_TBL_ADDR   0x0e10
#define ISISC_WCMP_NHOP_TBL_ADDR   0x0e20

#if 0
static sw_error_t
_isisc_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp)
{
    sw_error_t rv;
    a_uint32_t i, j, addr, data;
    a_uint8_t  idx, ptr[4] = { 0 }, pos[16] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (ISISC_WCMP_ENTRY_MAX_ID < wcmp_id)
    {
        return SW_BAD_PARAM;
    }

    if (ISISC_WCMP_HASH_MAX_NUM < wcmp->nh_nr)
    {
        return SW_BAD_PARAM;
    }

    for (i = 0; i < wcmp->nh_nr; i++)
    {
        if (ISISC_IP_ENTRY_MAX_ID < wcmp->nh_id[i])
        {
            return SW_BAD_PARAM;
        }

        idx = 4;
        for (j = 0; j < 4; j++)
        {
            if (ptr[j] & 0x80)
            {
                if ((ptr[j] & 0x7f) == wcmp->nh_id[i])
                {
                    idx = j;
                    break;
                }
            }
            else
            {
                idx = j;
            }
        }

        if (4 == idx)
        {
            return SW_BAD_PARAM;
        }
        else
        {
            ptr[idx] = (wcmp->nh_id[i] & 0x7f) | 0x80;
            pos[i]   = idx;
        }
    }

    data = 0;
    for (j = 0; j < 4; j++)
    {
        data |= (ptr[j] << (j << 3));
    }

    addr = ISISC_WCMP_NHOP_TBL_ADDR + (wcmp_id << 2);
    HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t),
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    data = 0;
    for (j = 0; j < 16; j++)
    {
        data |= (pos[j] << (j << 1));
    }

    addr = ISISC_WCMP_HASH_TBL_ADDR + (wcmp_id << 2);
    HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t),
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    return SW_OK;
}

static sw_error_t
_isisc_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp)
{
    sw_error_t rv;
    a_uint32_t i, addr, data = 0;
    a_uint8_t  ptr[4] = { 0 }, pos[16] = { 0 };

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    if (ISISC_WCMP_ENTRY_MAX_ID < wcmp_id)
    {
        return SW_BAD_PARAM;
    }

    wcmp->nh_nr = ISISC_WCMP_HASH_MAX_NUM;

    addr = ISISC_WCMP_NHOP_TBL_ADDR + (wcmp_id << 2);
    HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t),
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    for (i = 0; i < 4; i++)
    {
        ptr[i] = (data >> (i << 3)) & 0x7f;
    }

    addr = ISISC_WCMP_HASH_TBL_ADDR + (wcmp_id << 2);
    HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t),
                          (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    for (i = 0; i < 16; i++)
    {
        pos[i] = (data >> (i << 1)) & 0x3;
    }

    for (i = 0; i < 16; i++)
    {
        wcmp->nh_id[i] = ptr[pos[i]];
    }

    return SW_OK;
}
#endif

static sw_error_t
_isisc_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode)
{
    sw_error_t rv;
    a_uint32_t data = 0;

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_CTRL, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    if (FAL_WCMP_HASH_KEY_SIP & hash_mode)
    {
        SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SIP, 1, data);
    }
    else
    {
        SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SIP, 0, data);
    }

    if (FAL_WCMP_HASH_KEY_DIP & hash_mode)
    {
        SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DIP, 1, data);
    }
    else
    {
        SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DIP, 0, data);
    }

    if (FAL_WCMP_HASH_KEY_SPORT & hash_mode)
    {
        SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SP, 1, data);
    }
    else
    {
        SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SP, 0, data);
    }

    if (FAL_WCMP_HASH_KEY_DPORT & hash_mode)
    {
        SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DP, 1, data);
    }
    else
    {
        SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DP, 0, data);
    }


    HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_CTRL, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    return rv;
}

static sw_error_t
_isisc_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode)
{
    sw_error_t rv;
    a_uint32_t data = 0, field;

    *hash_mode = 0;

    HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_CTRL, 0,
                      (a_uint8_t *) (&data), sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_SIP, field, data);
    if (field)
    {
        *hash_mode |= FAL_WCMP_HASH_KEY_SIP;
    }

    SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_DIP, field, data);
    if (field)
    {
        *hash_mode |= FAL_WCMP_HASH_KEY_DIP;
    }

    SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_SP, field, data);
    if (field)
    {
        *hash_mode |= FAL_WCMP_HASH_KEY_SPORT;
    }

    SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_DP, field, data);
    if (field)
    {
        *hash_mode |= FAL_WCMP_HASH_KEY_DPORT;
    }

    return SW_OK;
}

sw_error_t
isisc_ip_reset(a_uint32_t dev_id)
{
    sw_error_t rv;
    a_uint32_t i, addr, data = 0;

    HSL_DEV_ID_CHECK(dev_id);

    rv = _isisc_ip_feature_check(dev_id);
    SW_RTN_ON_ERROR(rv);

    HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&data),
                      sizeof (a_uint32_t));
    SW_RTN_ON_ERROR(rv);

    rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_FLUSH);
    SW_RTN_ON_ERROR(rv);

    isisc_mac_snap[dev_id] = 0;
    for (i = 0; i < ISISC_INTF_MAC_ADDR_NUM; i++)
    {
        addr = ISISC_INTF_MAC_TBL2_ADDR + (i << 4);
        HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t),
                              (a_uint8_t *) (&data), sizeof (a_uint32_t));
        SW_RTN_ON_ERROR(rv);
    }

    return SW_OK;
}

/**
 * @brief Add one host entry to one particular device.
 *   @details Comments:
 *     For ISIS the intf_id parameter in host_entry means vlan id.
       Before host entry added related interface entry and ip6 base address
       must be set at first.
       Hardware entry id will be returned.
 * @param[in] dev_id device id
 * @param[in] host_entry host entry parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_host_add(dev_id, host_entry);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Delete one host entry from one particular device.
 *   @details Comments:
 *     For ISIS the intf_id parameter in host_entry means vlan id.
       Before host entry deleted related interface entry and ip6 base address
       must be set atfirst.
       For del_mode please refer IP entry operation flags.
 * @param[in] dev_id device id
 * @param[in] del_mode delete operation mode
 * @param[in] host_entry host entry parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode,
                 fal_host_entry_t * host_entry)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_host_del(dev_id, del_mode, host_entry);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get one host entry from one particular device.
 *   @details Comments:
 *     For ISIS the intf_id parameter in host_entry means vlan id.
       Before host entry deleted related interface entry and ip6 base address
       must be set atfirst.
       For get_mode please refer IP entry operation flags.
 * @param[in] dev_id device id
 * @param[in] get_mode get operation mode
 * @param[out] host_entry host entry parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode,
                 fal_host_entry_t * host_entry)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_host_get(dev_id, get_mode, host_entry);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Next one host entry from one particular device.
 *   @details Comments:
 *     For ISIS the intf_id parameter in host_entry means vlan id.
       Before host entry deleted related interface entry and ip6 base address
       must be set atfirst.
       For next_mode please refer IP entry operation flags.
       For get the first entry please set entry id as FAL_NEXT_ENTRY_FIRST_ID
 * @param[in] dev_id device id
 * @param[in] next_mode next operation mode
 * @param[out] host_entry host entry parameter
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode,
                  fal_host_entry_t * host_entry)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_host_next(dev_id, next_mode, host_entry);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Bind one counter entry to one host entry on one particular device.
 * @param[in] dev_id device id
 * @param[in] entry_id host entry id
 * @param[in] cnt_id counter entry id
 * @param[in] enable A_TRUE means bind, A_FALSE means unbind
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_host_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id,
                          a_uint32_t cnt_id, a_bool_t enable)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_host_counter_bind(dev_id, entry_id, cnt_id, enable);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Bind one pppoe session entry to one host entry on one particular device.
 * @param[in] dev_id device id
 * @param[in] entry_id host entry id
 * @param[in] pppoe_id pppoe session entry id
 * @param[in] enable A_TRUE means bind, A_FALSE means unbind
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_host_pppoe_bind(a_uint32_t dev_id, a_uint32_t entry_id,
                        a_uint32_t pppoe_id, a_bool_t enable)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_host_pppoe_bind(dev_id, entry_id, pppoe_id, enable);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set arp packets type to learn on one particular port.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[in] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id,
                         a_uint32_t flags)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_pt_arp_learn_set(dev_id, port_id, flags);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get arp packets type to learn on one particular port.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[out] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id,
                         a_uint32_t * flags)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_pt_arp_learn_get(dev_id, port_id, flags);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set arp packets type to learn on one particular device.
 * @param[in] dev_id device id
 * @param[in] mode learning mode
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_arp_learn_set(dev_id, mode);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get arp packets type to learn on one particular device.
 * @param[in] dev_id device id
 * @param[out] mode learning mode
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_arp_learn_get(dev_id, mode);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set ip packets source guarding mode on one particular port.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[in] mode source guarding mode
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id,
                         fal_source_guard_mode_t mode)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_source_guard_set(dev_id, port_id, mode);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get ip packets source guarding mode on one particular port.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[out] mode source guarding mode
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id,
                         fal_source_guard_mode_t * mode)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_source_guard_get(dev_id, port_id, mode);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set unkonw source ip packets forwarding command on one particular device.
 *   @details Comments:
 *     This settin is no meaning when ip source guard not enable
 * @param[in] dev_id device id
 * @param[in] cmd forwarding command
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_unk_source_cmd_set(dev_id, cmd);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get unkonw source ip packets forwarding command on one particular device.
 * @param[in] dev_id device id
 * @param[out] cmd forwarding command
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_unk_source_cmd_get(dev_id, cmd);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set arp packets source guarding mode on one particular port.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[in] mode source guarding mode
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id,
                      fal_source_guard_mode_t mode)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_arp_guard_set(dev_id, port_id, mode);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get arp packets source guarding mode on one particular port.
 * @param[in] dev_id device id
 * @param[in] port_id port id
 * @param[out] mode source guarding mode
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id,
                      fal_source_guard_mode_t * mode)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_arp_guard_get(dev_id, port_id, mode);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set unkonw source arp packets forwarding command on one particular device.
 *   @details Comments:
 *     This settin is no meaning when arp source guard not enable
 * @param[in] dev_id device id
 * @param[in] cmd forwarding command
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_arp_unk_source_cmd_set(dev_id, cmd);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get unkonw source arp packets forwarding command on one particular device.
 * @param[in] dev_id device id
 * @param[out] cmd forwarding command
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_arp_unk_source_cmd_get(dev_id, cmd);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set IP unicast routing status on one particular device.
 * @param[in] dev_id device id
 * @param[in] enable A_TRUE or A_FALSE
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable)
{
    sw_error_t rv;

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

/**
 * @brief Get IP unicast routing status on one particular device.
 * @param[in] dev_id device id
 * @param[out] enable A_TRUE or A_FALSE
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable)
{
    sw_error_t rv;

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

/**
 * @brief Add one interface entry to one particular device.
 * @param[in] dev_id device id
 * @param[in] entry interface entry
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_intf_entry_add(dev_id, entry);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Delete one interface entry from one particular device.
 * @param[in] dev_id device id
 * @param[in] del_mode delete operation mode
 * @param[in] entry interface entry
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode,
                       fal_intf_mac_entry_t * entry)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_intf_entry_del(dev_id, del_mode, entry);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Next one interface entry from one particular device.
 * @param[in] dev_id device id
 * @param[in] next_mode next operation mode
 * @param[out] entry interface entry
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode,
                        fal_intf_mac_entry_t * entry)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_intf_entry_next(dev_id, next_mode, entry);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Set IP host entry aging time on one particular device.
 * @details   Comments:
 *       This operation will set dynamic entry aging time on a particular device.
 *       The unit of time is second. Because different device has differnet
 *       hardware granularity function will return actual time in hardware.
 * @param[in] dev_id device id
 * @param[in] time aging time
 * @param[out] time actual aging time
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_age_time_set(dev_id, time);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get IP host entry aging time on one particular device.
 * @param[in] dev_id device id
 * @param[out] time aging time
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_age_time_get(dev_id, time);
    HSL_API_UNLOCK;
    return rv;
}

#if 0
/**
 * @brief Set IP WCMP table one particular device.
 *   @details Comments:
 *     Hardware only support 0 - 15 hash values and 4 different host tables.
 * @param[in] dev_id device id
 * @param[in] wcmp_id wcmp entry id
 * @param[in] wcmp wcmp entry
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_wcmp_entry_set(dev_id, wcmp_id, wcmp);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get IP WCMP table one particular device.
 *   @details Comments:
 *     Hardware only support 0 - 15 hash values and 4 different host tables.
 * @param[in] dev_id device id
 * @param[in] wcmp_id wcmp entry id
 * @param[out] wcmp wcmp entry
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_wcmp_entry_get(dev_id, wcmp_id, wcmp);
    HSL_API_UNLOCK;
    return rv;
}
#endif

/**
 * @brief Set IP WCMP hash key mode.
 * @param[in] dev_id device id
 * @param[in] hash_mode hash mode
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_wcmp_hash_mode_set(dev_id, hash_mode);
    HSL_API_UNLOCK;
    return rv;
}

/**
 * @brief Get IP WCMP hash key mode.
 * @param[in] dev_id device id
 * @param[out] hash_mode hash mode
 * @return SW_OK or error code
 */
HSL_LOCAL sw_error_t
isisc_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode)
{
    sw_error_t rv;

    HSL_API_LOCK;
    rv = _isisc_ip_wcmp_hash_mode_get(dev_id, hash_mode);
    HSL_API_UNLOCK;
    return rv;
}

sw_error_t
isisc_ip_init(a_uint32_t dev_id)
{
    sw_error_t rv;

    HSL_DEV_ID_CHECK(dev_id);

    rv = isisc_ip_reset(dev_id);
    SW_RTN_ON_ERROR(rv);

#ifndef HSL_STANDALONG
    {
        hsl_api_t *p_api;

        SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id));

        p_api->ip_host_add = isisc_ip_host_add;
        p_api->ip_host_del = isisc_ip_host_del;
        p_api->ip_host_get = isisc_ip_host_get;
        p_api->ip_host_next = isisc_ip_host_next;
        p_api->ip_host_counter_bind = isisc_ip_host_counter_bind;
        p_api->ip_host_pppoe_bind = isisc_ip_host_pppoe_bind;
        p_api->ip_pt_arp_learn_set = isisc_ip_pt_arp_learn_set;
        p_api->ip_pt_arp_learn_get = isisc_ip_pt_arp_learn_get;
        p_api->ip_arp_learn_set = isisc_ip_arp_learn_set;
        p_api->ip_arp_learn_get = isisc_ip_arp_learn_get;
        p_api->ip_source_guard_set = isisc_ip_source_guard_set;
        p_api->ip_source_guard_get = isisc_ip_source_guard_get;
        p_api->ip_unk_source_cmd_set = isisc_ip_unk_source_cmd_set;
        p_api->ip_unk_source_cmd_get = isisc_ip_unk_source_cmd_get;
        p_api->ip_arp_guard_set = isisc_ip_arp_guard_set;
        p_api->ip_arp_guard_get = isisc_ip_arp_guard_get;
        p_api->arp_unk_source_cmd_set = isisc_arp_unk_source_cmd_set;
        p_api->arp_unk_source_cmd_get = isisc_arp_unk_source_cmd_get;
        p_api->ip_route_status_set = isisc_ip_route_status_set;
        p_api->ip_route_status_get = isisc_ip_route_status_get;
        p_api->ip_intf_entry_add = isisc_ip_intf_entry_add;
        p_api->ip_intf_entry_del = isisc_ip_intf_entry_del;
        p_api->ip_intf_entry_next = isisc_ip_intf_entry_next;
        p_api->ip_age_time_set = isisc_ip_age_time_set;
        p_api->ip_age_time_get = isisc_ip_age_time_get;
        p_api->ip_wcmp_hash_mode_set = isisc_ip_wcmp_hash_mode_set;
        p_api->ip_wcmp_hash_mode_get = isisc_ip_wcmp_hash_mode_get;
    }
#endif

    return SW_OK;
}

/**
 * @}
 */

