/*
 * Copyright (c) 2012, 2015, 2018, 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.
 */


#ifdef KVER32
#include <linux/kconfig.h> 
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#endif
#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/netfilter_arp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <net/netfilter/nf_conntrack.h>

#include "fal_nat.h"
#include "fal_ip.h"

#include "hsl_api.h"
#include "hsl.h"
#include "hsl_shared_api.h"
#include "../nat_helper.h"
#include "nat_helper_dt.h"
#include "nat_helper_hsl.h"
#include "../napt_acl.h"

int nat_chip_ver = 0;
a_bool_t napt_add_bypass_check = A_TRUE;

/* support 4 different interfaces (or 4 VLANs) */
static fal_intf_mac_entry_t global_if_mac_entry[MAX_INTF_NUM] = {{0}};
static a_uint8_t if_mac_count = 0;

extern int setup_wan_if;
extern int setup_lan_if;

#define DESS_CHIP(ver) ((((ver)&0xffff)>>8) == NAT_CHIP_VER_DESS)

#define ARP_HW_COUNTER_OFFSET  8

static a_uint8_t
nat_hw_debug_counter_get(void)
{
    static a_uint32_t nat_debug_counter = 0;

    return ((nat_debug_counter++) & 0x7);
}

static a_uint8_t
arp_hw_debug_counter_get(void)
{
    static a_uint32_t ip_debug_counter = 0;

    return ((ip_debug_counter++) & 0x7) + ARP_HW_COUNTER_OFFSET;
}


a_int32_t
nat_hw_add(nat_entry_t *nat)
{
    fal_nat_entry_t hw_nat = {0};

    hw_nat.flags = nat->flags;
    hw_nat.src_addr = nat->src_addr;
    hw_nat.trans_addr = nat->trans_addr;
    hw_nat.port_num = nat->port_num;
    hw_nat.port_range = nat->port_range;
    hw_nat.counter_en = 1;
    hw_nat.counter_id = nat_hw_debug_counter_get();

    if(NAT_ADD(0, &hw_nat) != 0)
    {
        return -1;
    }
    nat->entry_id = hw_nat.entry_id;

    return 0;
}

a_int32_t
nat_hw_del_by_index(a_uint32_t index)
{
    fal_nat_entry_t nat_entry = {0};

    HNAT_PRINTK("NAT_DEL(1) index=%d########\n", index);

    nat_entry.entry_id = index;
    if(NAT_DEL(0, FAL_NAT_ENTRY_ID_EN, &nat_entry)!= 0)
    {
        return -1;
    }

    return 0;
}

a_int32_t
nat_hw_flush(void)
{
    if(NAT_DEL(0, 0, 0)!= 0)
    {
        return -1;
    }

    return 0;
}

a_int32_t
napt_hw_flush(void)
{
    if(NAPT_DEL(0, 0, 0)!= 0)
    {
        return -1;
    }

    return 0;
}

static a_uint32_t private_ip_can_update = 1;
a_int32_t
nat_hw_prv_base_can_update(void)
{
    return private_ip_can_update;
}

void
nat_hw_prv_base_update_enable(void)
{
    private_ip_can_update = 1;
}

void
nat_hw_prv_base_update_disable(void)
{
    private_ip_can_update = 0;
}

static a_uint32_t private_ip_base = 0xc0a80000;
static a_uint32_t private_net_mask = 0xffffff00;
a_int32_t
nat_hw_prv_base_set(a_uint32_t ip)
{
#define PRIVATE_IP_MASK 0xffffff00

    ip = ntohl(ip);

	if (((nat_chip_ver & 0xffff) >> 8) == NAT_CHIP_VER_8327)
    		private_ip_base = ip & PRIVATE_IP_MASK;
	else
		private_ip_base = ip & nat_hw_prv_mask_get();


	if(DESS_CHIP(nat_chip_ver)) {
		if (IP_PRV_BASE_ADDR_SET(0, 0, (fal_ip4_addr_t)ip) != 0)
	    {
	        return -1;
	    }
	} else {
	    if (NAT_PRV_BASE_ADDR_SET(0, (fal_ip4_addr_t)ip) != 0)
	    {
	        return -1;
	    }
	}

    HNAT_PRINTK("%s: private_ip_base:%x private_ip_can_update:%d\n",
                __func__, private_ip_base, private_ip_can_update);

    return 0;
}

a_uint32_t
nat_hw_prv_base_get(void)
{
    return private_ip_base;
}


a_int32_t
nat_hw_prv_mask_set(a_uint32_t ipmask)
{
    ipmask = ntohl(ipmask);

	if(DESS_CHIP(nat_chip_ver)) {
		if (IP_PRV_BASE_MASK_SET(0, 0, (fal_ip4_addr_t)ipmask) != 0)
	    {
	        return -1;
	    }
	} else if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8337) {
	    if (NAT_PRV_BASE_MASK_SET(0, (fal_ip4_addr_t)ipmask) != 0)
	    {
	        return -1;
	    }
	}
    private_net_mask = ipmask;

    HNAT_PRINTK("%s: 0x%08x\n", __FUNCTION__, private_net_mask);

    return 0;
}

a_uint32_t
nat_hw_prv_mask_get(void)
{
    return private_net_mask;
}


a_int32_t
nat_hw_prv_base_is_match(a_uint32_t ip)
{
#define PRIVATE_IP_MASK 0xffffff00

    a_uint32_t prv_base = private_ip_base;
    a_uint32_t prv_mask;

	if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8327) {
    		if((prv_base & PRIVATE_IP_MASK) == (ip & PRIVATE_IP_MASK))
				return 1;
	} else {
		prv_mask = nat_hw_prv_mask_get();
		if((prv_base & prv_mask) == (ip & prv_mask))
        		return 1;
	}

    HNAT_PRINTK("%s: private_ip_base:%x usaddr:%x mismatch\n",
                __func__, prv_base, ip);

    return 0;
}

static a_int32_t
_arp_hw_if_mac_add(fal_intf_mac_entry_t *if_mac_entry)
{
    return IP_INTF_ENTRY_ADD(0, if_mac_entry);
}

static a_int32_t
_arp_hw_if_mac_del(fal_intf_mac_entry_t *if_mac_entry)
{
    return IP_INTF_ENTRY_DEL(0, FAL_IP_ENTRY_ID_EN, if_mac_entry);
}

a_int32_t
if_mac_cleanup(void)
{
	a_uint8_t i = 0;

	if_mac_count = 0;
	for(i = 0; i < MAX_INTF_NUM; i++)
	{
		if(_arp_hw_if_mac_del(&global_if_mac_entry[i]) != 0) {
			printk("mac del fail!\n");
			return -1;
		}
		memset(&global_if_mac_entry[i], 0, sizeof(fal_intf_mac_entry_t));
	}

	setup_wan_if = 0;
	setup_lan_if = 0;

	return 0;
}

#define MACADDR_LEN	6
a_int32_t
if_mac_add(a_uint8_t *mac, a_uint32_t vid, uint32_t ipv6)
{
    a_uint8_t i = 0;
    a_uint8_t zero_mac[MACADDR_LEN] = {0};

    if (!memcmp(mac, zero_mac, MACADDR_LEN))
        return 0;

    if(if_mac_count > MAX_INTF_NUM)
        return -1;

    for(i = 0; i < if_mac_count; i++)
    {
        if((!memcmp(global_if_mac_entry[i].mac_addr.uc, mac, 6)) &&
                (global_if_mac_entry[i].vid_low == vid))
        {
            HNAT_PRINTK("%s: mac exist id:%d\n", __func__,
                        global_if_mac_entry[i].entry_id);
            return 0;
        }
    }

    if(if_mac_count == MAX_INTF_NUM)
    {
        HNAT_ERR_PRINTK("%s: reach mac count max\n", __func__);
        return -1;
    }

    memset(&global_if_mac_entry[if_mac_count], 0, sizeof(fal_intf_mac_entry_t));
    memcpy(global_if_mac_entry[if_mac_count].mac_addr.uc, mac, 6);

    global_if_mac_entry[if_mac_count].entry_id = if_mac_count;
    if (1 == ipv6)
    {
        global_if_mac_entry[if_mac_count].ip6_route = 1;
    }
    else
    {
        global_if_mac_entry[if_mac_count].ip6_route = 0;
    }
    global_if_mac_entry[if_mac_count].ip4_route = 1;

    if (vid == 0)
    {
        global_if_mac_entry[if_mac_count].vid_low = 0;
        global_if_mac_entry[if_mac_count].vid_high = 511;
    }
    else
    {
        global_if_mac_entry[if_mac_count].vid_low = vid;
        global_if_mac_entry[if_mac_count].vid_high = vid;
    }

    if(_arp_hw_if_mac_add(&global_if_mac_entry[if_mac_count])!= 0)
    {
        return -1;
    }

    HNAT_PRINTK("%s: count:%d index:%d vid:%d  mac:%02x-%02x-%02x-%02x-%02x-%02x\n",
                __func__, if_mac_count, global_if_mac_entry[if_mac_count].entry_id, vid,
                mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
    if_mac_count ++;

    return 0;
}

static a_int32_t
_arp_hw_add(fal_host_entry_t *arp_entry)
{
    return IP_HOST_ADD(0, arp_entry);
}

a_int32_t
arp_hw_add(a_uint32_t port, a_uint32_t intf_id, a_uint8_t *ip, a_uint8_t *mac, int is_ipv6_entry)
{
    fal_host_entry_t arp_entry;


#ifdef ISIS /* Only for AR8337(S17) */
    if (NF_S17_WAN_TYPE_PPPOEV6 == nf_athrs17_hnat_wan_type)
    {
        memset(&arp_entry,0,sizeof(arp_entry));
        memcpy(&arp_entry.ip4_addr, ip, 4);
        memcpy(arp_entry.mac_addr.uc, mac, 6);
        arp_entry.status = ARP_AGE_NEVER;
        if (port == S17_WAN_PORT)
        {
            arp_entry.port_id = port;
        }
	 else
        {
            arp_entry.port_id = 6; /* always assigned to MAC 6 */
        }
        arp_entry.flags = FAL_IP_IP4_ADDR;
    }
    else
#endif /* not ISIS */
    {
        memset(&arp_entry,0,sizeof(arp_entry));
        if (0 == is_ipv6_entry)
        {
            memcpy(&arp_entry.ip4_addr, ip, 4);
            arp_entry.ip4_addr = ntohl(arp_entry.ip4_addr);
            arp_entry.flags = FAL_IP_IP4_ADDR;
        }
        else
        {
            memcpy(&arp_entry.ip6_addr, ip, 16);
            arp_entry.flags = FAL_IP_IP6_ADDR;
        }
        memcpy(arp_entry.mac_addr.uc, mac, 6);
        if ((NF_S17_WAN_TYPE_PPPOE == nf_athrs17_hnat_wan_type) && \
            (S17_WAN_PORT == port))
        {
            arp_entry.status = ARP_AGE_NEVER;
        }
        else
        {
            arp_entry.status = ARP_AGE;
        }
        arp_entry.port_id = port;
    }

    arp_entry.intf_id = intf_id;

    arp_entry.counter_en = 1;
    if (S17_WAN_PORT == port)
    {
        arp_entry.counter_id = 0xf;
    }
    else
    {
        arp_entry.counter_id = arp_hw_debug_counter_get();
    }

	if (IP_HOST_GET(0, 0x10, &arp_entry)) {
		HNAT_PRINTK("new arp for 0x%x\n", arp_entry.ip4_addr);
		if(_arp_hw_add(&arp_entry) != 0)
		{
			HNAT_ERR_PRINTK("%s: fail\n", __func__);
			return -1;
		}
	}

    if (0 == is_ipv6_entry)
    {
        HNAT_PRINTK("%s: index:%x  port:%d ip:%d.%d.%d.%d\n",
                    __func__, arp_entry.entry_id, port,
                    *(ip), *(ip+1), *(ip+2), *(ip+3));
    }
    
    if (0 != (arp_entry.entry_id & 0xFFFFFC00))
    {
        printk("Warning: arp_entry id should be only 10 bits!\n");
    }

    return arp_entry.entry_id;
}

#define AOS_HEADER_MAGIC 0xC0DE

a_int32_t
arp_if_info_get(void *data, a_uint32_t *sport, a_uint32_t *vid)
{
	aos_header_t *athr_header = NULL;
    if((data==0) || (sport==0) || (vid==0))
    {
        return -1;
    }

	athr_header = (aos_header_t *)data;

#if 0
    /*atheros header magic check*/
    if(athr_header->magic != AOS_HEADER_MAGIC)
    {
        return -1;
    }
#endif

    *sport = athr_header->sport;
    *vid = athr_header->vid;

    return 0;
}

#define MAX_PUBLIC_IP_CNT 16
struct public_ip_shadow
{
    a_uint32_t   ip;
    a_uint32_t   use_cnt;
};

static struct public_ip_shadow public_ip_shadow[MAX_PUBLIC_IP_CNT]= {{0}};
static a_uint32_t public_ip_cnt = 0;

a_int32_t
nat_hw_pub_ip_add(a_uint32_t ip, a_uint32_t *index)
{
    sw_error_t rv;
    a_uint32_t hw_index;
    a_uint32_t i;
	fal_nat_pub_addr_t ip_entry;

    for(i=0; i<MAX_PUBLIC_IP_CNT; i++)
    {
        if((ip == public_ip_shadow[i].ip) && (public_ip_shadow[i].use_cnt))
        {
            public_ip_shadow[i].use_cnt++;
            *index = i;
            return 0;
        }
    }

    if(public_ip_cnt >= MAX_PUBLIC_IP_CNT)
    {
        return -1;
    }

	memset(&ip_entry, 0, sizeof(ip_entry));
    ip_entry.pub_addr = ip;
    rv = NAT_PUB_ADDR_ADD(0,&ip_entry);
    if(rv != 0)
    {
        return -1;
    }

    public_ip_cnt++;
    hw_index = ip_entry.entry_id;
    public_ip_shadow[hw_index].ip = ip;
    public_ip_shadow[hw_index].use_cnt++;
    *index = hw_index;

    HNAT_PRINTK("%s: public_ip_cnt:%d index:%d ip:0x%x\n",
                __func__, public_ip_cnt, hw_index, public_ip_shadow[hw_index].ip);
    return 0;
}


void
napt_hw_mode_init(void)
{
    sw_error_t rv;
    /* age_speedup+age_thres_1/4+age_step_4+age_timer_28s*1+
       stop_age_when1+overwrite_disable */
    /* Also set NAT mode Port strict mode/symmetric mode */
    a_uint32_t entry = 0x15F01CB;

    REG_ENTRY_SET(rv, 0, NAT_CTRL, 0, (a_uint8_t *) (&entry),
                      sizeof (a_uint32_t));

    REG_ENTRY_GET(rv, 0, ROUTER_CTRL, 0,
                      (a_uint8_t *) (&entry), sizeof (a_uint32_t));

    /*set locktime 100us*/
    SW_SET_REG_BY_FIELD(ROUTER_CTRL, GLB_LOCKTIME, 1, entry);
    SW_SET_REG_BY_FIELD(ROUTER_CTRL, ARP_AGE_MODE, 1, entry);

    REG_ENTRY_SET(rv, 0, ROUTER_CTRL, 0,
                      (a_uint8_t *) (&entry), sizeof (a_uint32_t));
    REG_ENTRY_GET(rv, 0, MOD_ENABLE, 0,
                      (a_uint8_t *) (&entry), sizeof (a_uint32_t));
    SW_SET_REG_BY_FIELD(MOD_ENABLE, L3_EN, 1, entry);
    REG_ENTRY_SET(rv, 0, MOD_ENABLE, 0,
                      (a_uint8_t *) (&entry), sizeof (a_uint32_t));

    ACL_STATUS_SET(0, A_TRUE);
}

void
napt_hw_mode_cleanup(void)
{
	a_uint32_t entry;
	sw_error_t rv;
	if (!DESS_CHIP(nat_chip_ver)) {
		IP_ROUTE_STATUS_SET(0, A_FALSE);
		entry = 0;
	} else {
		REG_ENTRY_GET(rv, 0, NAT_CTRL, 0,
                      		(a_uint8_t *) (&entry), sizeof (a_uint32_t));
		SW_SET_REG_BY_FIELD(NAT_CTRL, NAT_EN, 0, entry);
	}
	REG_ENTRY_SET(rv, 0, NAT_CTRL, 0,
                      (a_uint8_t *) (&entry), sizeof (a_uint32_t));
	ACL_STATUS_SET(0, A_FALSE);
}

a_int32_t
nat_hw_pub_ip_del(a_uint32_t index)
{
    sw_error_t rv;

    if(public_ip_shadow[index].use_cnt>0)
    {
        public_ip_shadow[index].use_cnt--;
        if(public_ip_shadow[index].use_cnt == 0)
        {
			fal_nat_pub_addr_t ip_entry;
            HNAT_PRINTK("%s: public_ip_cnt:%d index:%d ip:0x%x\n",
                        __func__, public_ip_cnt, index, public_ip_shadow[index].ip);
            memset(&ip_entry,0,sizeof(ip_entry));
            ip_entry.pub_addr = public_ip_shadow[index].ip;
            rv = NAT_PUB_ADDR_DEL(0, 1, &ip_entry);
            if(rv != 0)
            {
                return -1;
            }

            public_ip_cnt--;
        }
        return 0;
    }

    return -1;
}

#define napt_entry_cp(to, from) \
{ \
    (to)->entry_id = (from)->entry_id; \
    (to)->status = (from)->status; \
    (to)->flags = (from)->flags; \
    (to)->src_addr = (from)->src_addr; \
    (to)->src_port = (from)->src_port; \
    (to)->dst_addr = (from)->dst_addr; \
    (to)->dst_port = (from)->dst_port; \
    (to)->trans_addr = (from)->trans_addr; \
    (to)->trans_port = (from)->trans_port; \
    (to)->ingress_packet = (from)->ingress_packet; \
    (to)->ingress_byte = (from)->ingress_byte; \
    (to)->egress_packet = (from)->egress_packet; \
    (to)->egress_byte = (from)->egress_byte; \
}

a_int32_t
napt_hw_add(napt_entry_t *napt)
{
	a_int32_t ret = 0;
	fal_napt_entry_t fal_napt = {0};
	fal_host_entry_t host_entry = {0};
	a_uint32_t next_hop = 0;

	napt_entry_cp(&fal_napt, napt);

	fal_napt.flags |= FAL_NAT_ENTRY_TRANS_IPADDR_INDEX;
	fal_napt.counter_en = 1;
	fal_napt.counter_id = nat_hw_debug_counter_get();
	fal_napt.action = FAL_MAC_FRWRD;

	if (!napt_add_bypass_check) {
		/*check arp entry*/
		host_entry.flags = FAL_IP_IP4_ADDR;
		host_entry.ip4_addr = fal_napt.src_addr;
		ret = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &host_entry);
		if (ret) {
			HNAT_ERR_PRINTK("can not find src host entry!\n");
			return ret;
		}
		if (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOE) {
			next_hop = get_next_hop(fal_napt.dst_addr, fal_napt.src_addr);
			host_entry.ip4_addr =  next_hop ? next_hop : fal_napt.dst_addr;
			ret = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &host_entry);
			if (ret) {
				HNAT_ERR_PRINTK("can not find dst host entry!\n");
				return ret;
			}
		}
	}

	ret = NAPT_ADD(0, &fal_napt);

	napt->entry_id = fal_napt.entry_id;
	return ret;
}

a_int32_t
napt_hw_get(napt_entry_t *napt, fal_napt_entry_t *entry)
{
	a_int32_t ret = 0;
	fal_napt_entry_t fal_napt = {0};

	napt_entry_cp(&fal_napt, napt);

	ret = NAPT_GET(0, 0, &fal_napt);

	if(!ret)
		*entry = fal_napt;
	return ret;
}

a_int32_t
napt_hw_dnat_cookie_add(napt_entry_t *napt, a_uint32_t cookie)
{
	a_int32_t ret = 0;
	fal_napt_entry_t fal_napt = {0};
	fal_napt.flags = napt->flags | 0x10;
	fal_napt.status = 0xf;
	fal_napt.dst_addr = napt->dst_addr;
	fal_napt.dst_port = napt->dst_port;
	fal_napt.trans_addr = napt->trans_addr;
	fal_napt.trans_port = napt->trans_port;
	fal_napt.src_port = napt->src_port;
	fal_napt.action = FAL_MAC_RDT_TO_CPU;
	fal_napt.flow_cookie = cookie;
	ret = NAPT_ADD(0, &fal_napt);
	return ret;
}

a_int32_t
napt_hw_snat_cookie_add(napt_entry_t *napt, a_uint32_t cookie)
{
	a_int32_t ret = 0;
	fal_napt_entry_t fal_napt = {0};
	fal_napt.flags = napt->flags | 0x10;
	fal_napt.status = 0xf;
	fal_napt.dst_addr = napt->dst_addr;
	fal_napt.dst_port = napt->dst_port;
	fal_napt.src_addr = napt->src_addr;
	fal_napt.src_port = napt->src_port;
	fal_napt.trans_port = napt->trans_port;
	fal_napt.action = FAL_MAC_RDT_TO_CPU;
	fal_napt.flow_cookie = cookie;
	ret = NAPT_ADD(0, &fal_napt);
	return ret;
}




a_int32_t
napt_hw_del(napt_entry_t *napt)
{
    a_int32_t ret = 0;

    fal_napt_entry_t fal_napt = {0};

    napt_entry_cp(&fal_napt, napt);
	napt_ct_counter_decrease();

    ret = NAPT_DEL(0, FAL_NAT_ENTRY_KEY_EN, &fal_napt);

    if(ret != 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

a_int32_t
napt_hw_first_by_age(napt_entry_t *napt, a_uint32_t age)
{
    a_int32_t ret = 0;
    fal_napt_entry_t fal_napt = {0};

    fal_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
    fal_napt.status = age;

    if(NAPT_NEXT(0, FAL_NAT_ENTRY_AGE_EN ,&fal_napt) !=0)
    {
        ret = -1;
    }

    napt_entry_cp(napt, &fal_napt);

    return ret;
}

a_int32_t
napt_hw_next_by_age(napt_entry_t *napt, a_uint32_t age)
{
    a_int32_t ret = 0;
    fal_napt_entry_t fal_napt = {0};

    fal_napt.entry_id = napt->entry_id;
    fal_napt.status = age;

    if(NAPT_NEXT(0, FAL_NAT_ENTRY_AGE_EN ,&fal_napt) !=0)
    {
        ret = -1;
    }

    napt_entry_cp(napt, &fal_napt);

    return ret;
}

a_int32_t
napt_hw_get_by_index(napt_entry_t *napt, a_uint16_t hw_index)
{
    fal_napt_entry_t fal_napt = {0};
	sw_error_t rv;

    if(hw_index == 0)
    {
        fal_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
    }
    else
    {
        fal_napt.entry_id = hw_index - 1;
    }

    if((rv = NAPT_NEXT(0, 0, &fal_napt)) != 0)
    {
        HNAT_ERR_PRINTK("<napt_hw_get_by_index>[rv:%d] error hw:%x sw:%x\n",
                        rv, napt->entry_id, hw_index);
        return -1;
    }

    napt_entry_cp(napt, &fal_napt);

    if(napt->entry_id != hw_index)
    {
        HNAT_ERR_PRINTK("<napt_hw_get_by_index>hw_index error hw:%x sw:%x\n",
                        napt->entry_id, hw_index);
        return -1;
    }

    return 0;
}

a_int32_t napt_hw_get_by_sip(a_uint32_t sip)
{
	fal_napt_entry_t napt;

	memset(&napt, 0, sizeof(fal_napt_entry_t));
	napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
	napt.src_addr = sip;
	if (NAPT_NEXT(0, FAL_NAT_ENTRY_SOURCE_IP_EN, &napt) == SW_OK) {
		return 0;
	}

	return -1;
}

a_uint32_t
napt_hw_used_count_get(void)
{
#define NAPT_USED_COUNT
#define NAPT_USED_COUNT_OFFSET                       0x0e44 /*was:0x0e38*/
#define NAPT_USED_COUNT_E_LENGTH                     11
#define NAPT_USED_COUNT_E_OFFSET                     0x0
#define NAPT_USED_COUNT_NR_E                         1
    sw_error_t rv;

    a_uint32_t count = 0;
    REG_ENTRY_GET(rv, 0, NAPT_USED_COUNT, 0, (a_uint8_t *) (&count),
                      sizeof (a_uint32_t));

    return count;
}

sw_error_t napt_l3_status_set(a_uint32_t dev_id, a_bool_t enable)
{
    sw_error_t rv;
    a_uint32_t val;

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

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

sw_error_t napt_l3_status_get(a_uint32_t dev_id, a_bool_t * enable)
{
    sw_error_t rv;
    a_uint32_t val;

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

    if (val)
    {
        *enable = A_TRUE;
    }
    else
    {
        *enable = A_FALSE;
    }

    return SW_OK;
}

sw_error_t napt_helper_hsl_init()
{
	return SW_OK;
}


