From 2a42ad20b9730706ad371ae3787d4597c4e42276 Mon Sep 17 00:00:00 2001 From: sharath reddy Date: Tue, 4 Jun 2019 11:53:49 +0530 Subject: Feature: 19.04 part-2 Change-Id: I0b52a6bb67c25c7955d58e29eb81a3cc9efea9e9 Signed-off-by: sharath reddy --- stacks/lwip_stack/lwip_src/netif/spl_hal.c | 1755 ++++++++++++++++++++++++++++ 1 file changed, 1755 insertions(+) create mode 100644 stacks/lwip_stack/lwip_src/netif/spl_hal.c (limited to 'stacks/lwip_stack/lwip_src/netif/spl_hal.c') diff --git a/stacks/lwip_stack/lwip_src/netif/spl_hal.c b/stacks/lwip_stack/lwip_src/netif/spl_hal.c new file mode 100644 index 0000000..71d5c06 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/netif/spl_hal.c @@ -0,0 +1,1755 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "sys_arch.h" +#include "netif.h" +#include "spl_sockets.h" +//#include + +#include "stackx_spl_share.h" +#include "stackx_pbuf.h" +#include "spl_api.h" +#include "sharedmemory.h" +//#include "nettool.h" +#include "lwip/etharp.h" +#include "ip_module_api.h" +#include "sc_dpdk.h" +#include "nstack_log.h" +#include "common.h" +#include "nstack_securec.h" +//#include "ip.h" +#include "configuration_reader.h" +#include "spl_hal.h" +#include "nsfw_maintain_api.h" +#include "stackx_common.h" +#include "spl_instance.h" +#include +#include "prot/tcp.h" +#include "nsfw_shmem_mng.h" + +extern u32_t g_mbuf_size[MAX_THREAD_NUM]; +extern u32_t uStackArgIndex; +extern void smp_parse_stack_args(int argc, char **argv); +extern void spl_do_dump(struct spl_pbuf *p, u16 direction); + +#define SPL_HAL_SEND_TRY 100000 + +#define SPL_HAL_MODULE "SPL_HAL_MODULE" +extern u16_t g_offSetArry[SPL_PBUF_MAX_LAYER]; + +/* structure to store the rx and tx packets. Put two per cache line as ports + * used in pairs */ +struct port_stats +{ + unsigned rx; + unsigned tx; + unsigned drop; + u64_t rx_size; + u64_t tx_size; + u64_t recv_last_cycles; + u64_t send_last_cycles; +} __attribute__ ((aligned(COMMON_CACHE_LINE_SIZE / 2))); + +struct port_capa +{ + u32_t tx_ipv4_cksum_offload; + u32_t tx_udp_cksum_offload; + u32_t tx_tcp_cksum_offload; +}; + +struct rx_pkts +{ + u16_t num; + u16_t index; + struct common_mem_mbuf *pkts[PKT_BURST]; +}; + +struct tx_pkts +{ + u16_t num; + struct common_mem_mbuf *pkts[PKT_BURST]; +}; + +struct port_pkts +{ + struct rx_pkts rx; + struct tx_pkts tx; +}; + +struct psd_header +{ + u32_t src_addr; /* IPaddress of source host. */ + u32_t dst_addr; /* IPaddress of destination host(s). */ + u8_t zero; /* zero. */ + u8_t proto; /* L4 protocol type. */ + u16_t len; /* L4 length. */ +} __attribute__ ((__packed__)); + +NSTACK_STATIC unsigned num_ports_NIC = 0; +NSTACK_STATIC unsigned num_ports_NIC_start = 0; + +struct stackx_port_info *head_used_port_list; +struct stackx_port_zone *p_stackx_port_zone = NULL; + +struct bond_ports_info bond_ports_array = {.cnt = 0 }; + +static u8_t bond_ports_array_cnt_start = 0; + +static struct port_capa spl_hal_capa = { 0 }; + +static struct port_pkts spl_hal_pkts[HAL_MAX_NIC_NUM]; + +NSTACK_STATIC inline u16_t get_ipv4_16b_sum(u16_t * ptr16, u32_t nr) +{ + u32_t sum = 0; + + while (nr > 1) + { + sum += *ptr16; + nr -= sizeof(u16_t); + ptr16++; + + if (sum > UINT16_MAX) + { + sum -= UINT16_MAX; + } + } + + /* If length is in odd bytes */ + if (nr) + { + sum += *((u8_t *) ptr16); + } + + sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff); + sum &= 0x0ffff; + return (u16_t) sum; +} + +NSTACK_STATIC inline u16_t get_ipv4_bswap16(u16_t x) +{ + return (u16_t) (((x & 0x00ffU) << 8) | ((x & 0xff00U) >> 8)); +} + +NSTACK_STATIC inline u16_t +get_ipv4_psd_sum(struct ip_hdr * iphdr, u64_t ol_flags) +{ + struct psd_header psd_hdr; + + psd_hdr.src_addr = iphdr->src.addr; + psd_hdr.dst_addr = iphdr->dest.addr; + psd_hdr.zero = 0; + psd_hdr.proto = iphdr->_proto; + + if (ol_flags & PKT_TX_TCP_SEG) + { + psd_hdr.len = 0; + } + else + { + psd_hdr.len = get_ipv4_bswap16((get_ipv4_bswap16(iphdr->_len) + - sizeof(struct ip_hdr))); + } + + return get_ipv4_16b_sum((u16_t *) & psd_hdr, sizeof(struct psd_header)); +} + +/* should be called after head_used_port_list is initialized */ +NSTACK_STATIC hal_hdl_t get_port_hdl_by_name(const char *name) +{ + unsigned int i = 0; + struct stackx_port_info *p = p_stackx_port_zone->stackx_one_port; + + while (i < p_stackx_port_zone->port_num) + { + if (!strncasecmp(p->linux_ip.if_name, name, strlen(name))) + { + return p->linux_ip.hdl; + } + + p = &p_stackx_port_zone->stackx_one_port[++i]; + } + + NSPOL_LOGERR("failed to find port id]name=%s", name); + return hal_get_invalid_hdl(); +} + +NSTACK_STATIC struct stackx_port_info *get_port_info_by_name(const char *name) +{ + struct stackx_port_info *p = p_stackx_port_zone->stackx_one_port; + unsigned int i = 0; + + while (i < p_stackx_port_zone->port_num) + { + if (!strncasecmp(p->linux_ip.if_name, name, strlen(name))) + { + return p; + } + + p = &p_stackx_port_zone->stackx_one_port[++i]; + } + + return NULL; +} + +NSTACK_STATIC int del_port_in_port_list(const char *name) +{ + struct stackx_port_info *inf = head_used_port_list; + struct stackx_port_info *prev = NULL; + + while (inf) + { + if (!strncasecmp(inf->linux_ip.if_name, name, strlen(name))) + { + if (prev != NULL) + { + prev->next_use_port = inf->next_use_port; + } + else + { + head_used_port_list = inf->next_use_port; + } + + break; + } + + prev = inf; + inf = inf->next_use_port; + } + + return 0; +} + +extern void create_netif(struct stackx_port_info *p_port_info); + +NSTACK_STATIC int add_port_in_port_list(struct stackx_port_info *p) +{ + char *name; + struct stackx_port_info *inf = head_used_port_list; + struct stackx_port_info *prev = NULL; + + name = p->linux_ip.if_name; + + while (inf) + { + if (!strncasecmp(inf->linux_ip.if_name, name, strlen(name))) + { + NSPOL_LOGERR("ERROR: add an existing port!"); + return -1; + } + + prev = inf; + inf = inf->next_use_port; + } + + if (prev == NULL) + { + head_used_port_list = p; + } + else + { + prev->next_use_port = p; + } + + p->next_use_port = NULL; + create_netif(p); + return 0; +} + +/* Queries the link status of a port and prints it to screen */ +NSTACK_STATIC void report_port_link_status(struct stackx_port_info *p) +{ + /* get link status */ + u32 status; + + status = hal_link_status(p->linux_ip.hdl); + + if (status) + { + NSPOL_LOGINF(SC_DPDK_INFO, "Port=%s: Link Up", p->linux_ip.if_name); + } + else + { + NSPOL_LOGINF(SC_DPDK_INFO, "Port=%s: Link Down", p->linux_ip.if_name); + } +} + +int spl_hal_ether_etoa(const unsigned char *e, int e_len, char *a, int a_len) +{ + char *c = a; + int i; + int retVal; + + if (!e || !a || e_len < 0) + return -1; + + if (e_len > NETIF_ETH_ADDR_LEN) + e_len = NETIF_ETH_ADDR_LEN; + + if (a_len < e_len * 3) + return -1; + + for (i = 0; i < e_len; i++) + { + if (i) + { + *c++ = ':'; + } + retVal = sprintf_s(c, a_len - (c - a), "%02x", e[i] & 0xff); + if (-1 == retVal) + { + NSPOL_LOGERR("SPRINTF_S failed]ret=%d.", retVal); + return -1; + } + c = c + retVal; + } + + return 0; +} + +NSTACK_STATIC inline void +spl_hal_buf_convert(struct common_mem_mbuf *mbuf, struct spl_pbuf **buf) +{ + struct common_mem_mbuf *before = NULL; + struct spl_pbuf *last = NULL; + struct spl_pbuf *first = NULL; + struct spl_pbuf *tmp = NULL; + + while (mbuf != NULL) + { + //dpdk 2.1 + tmp = + (struct spl_pbuf *) ((char *) mbuf + + sizeof(struct common_mem_mbuf)); + res_alloc(&tmp->res_chk); + tmp->payload = common_pktmbuf_mtod(mbuf, void *); + tmp->tot_len = mbuf->pkt_len; + tmp->len = mbuf->data_len; + tmp->type = SPL_PBUF_HUGE; + tmp->proto_type = SPL_PBUF_PROTO_NONE; + tmp->next = NULL; + tmp->flags = 0; + + if (first == NULL) + { + first = tmp; + last = first; + } + else + { + /* Always the "if(first == NULL)" code segment is executed and then + "else" segment code is executed, so the "last" variable is not + NULL always when "else" case is executed */ + last->next = tmp; + last = tmp; + } + + before = mbuf; + mbuf = mbuf->next; + + before->next = NULL; + } + + *buf = first; +} + +NSTACK_STATIC int spl_hal_port_zone_init() +{ + int retVal; + nsfw_mem_zone create_port_zone; + nsfw_mem_zone create_port_info; + struct stackx_port_info *mz_port_info; + INITPOL_LOGINF("HAL", "spl_hal_port_zone_init", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_START); + + if ((CUR_CFG_HAL_PORT_NUM < 1) + || (SIZE_MAX / sizeof(struct stackx_port_info) < + CUR_CFG_HAL_PORT_NUM)) + { + NSPOL_LOGERR("malloc parameter incorrect]max_linux_port=%u", + CUR_CFG_HAL_PORT_NUM); + return -1; + } + + if (spl_snprintf + (create_port_zone.stname.aname, NSFW_MEM_NAME_LENTH - 1, "%s", + MP_STACKX_PORT_ZONE) < 0) + { + NSPOL_LOGERR("spl_snprintf fail"); + + return -1; + } + + create_port_zone.stname.entype = NSFW_SHMEM; + create_port_zone.isocket_id = SOCKET_ID_ANY; + create_port_zone.lenth = sizeof(struct stackx_port_zone); + create_port_zone.ireserv = 0; + p_stackx_port_zone = + (struct stackx_port_zone *) nsfw_mem_zone_create(&create_port_zone); + + if (NULL == p_stackx_port_zone) + { + INITPOL_LOGERR("HAL", "spl_hal_port_zone_init", + "Cannot create memory zone for MP_STACKX_PORT_ZONE information", + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + common_exit(EXIT_FAILURE, + "Cannot create memory zone for MP_STACKX_PORT_ZONE information"); + } + + retVal = + memset_s(p_stackx_port_zone, sizeof(struct stackx_port_zone), 0, + sizeof(struct stackx_port_zone)); + + if (EOK != retVal) + { + INITPOL_LOGERR("HAL", "spl_hal_port_zone_init", + "MEMSET_S return fail", retVal, MODULE_INIT_FAIL); + nsfw_mem_zone_release(&create_port_zone.stname); + return -1; + } + + if (spl_snprintf + (create_port_info.stname.aname, NSFW_MEM_NAME_LENTH - 1, "%s", + MP_STACKX_PORT_INFO) < 0) + { + NSPOL_LOGERR("VSNPRINTF_S fail"); + return -1; + } + + create_port_info.stname.entype = NSFW_SHMEM; + create_port_info.isocket_id = SOCKET_ID_ANY; + create_port_info.lenth = + CUR_CFG_HAL_PORT_NUM * sizeof(struct stackx_port_info); + create_port_info.ireserv = 0; + mz_port_info = + (struct stackx_port_info *) nsfw_mem_zone_create(&create_port_info); + + if (NULL == mz_port_info) + { + INITPOL_LOGERR("HAL", "spl_hal_port_zone_init", + "Cannot create memory zone for MP_STACKX_PORT_INFO information", + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + common_exit(EXIT_FAILURE, + "Cannot create memory zone for MP_STACKX_PORT_INFO information"); + } + + retVal = + memset_s(mz_port_info, create_port_info.length, 0, + create_port_info.lenth); + + if (EOK != retVal) + { + INITPOL_LOGERR("HAL", "spl_hal_port_zone_init", + "MEMSET_S return fail", retVal, MODULE_INIT_FAIL); + nsfw_mem_zone_release(&create_port_info.stname); + nsfw_mem_zone_release(&create_port_zone.stname); + return -1; + } + + MEM_STAT(SPL_HAL_MODULE, create_port_zone.stname.aname, NSFW_SHMEM, + create_port_info.lenth); + + p_stackx_port_zone->stackx_one_port = mz_port_info; + + INITPOL_LOGINF("HAL", "spl_hal_port_zone_init", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_SUCCESS); + + return 0; +} + +int spl_hal_init(int argc, char *argv[]) +{ + int retval = -1; + int idx_init; + + NSPOL_LOGINF(SC_DPDK_INFO, "spl_hal_init start"); + + /* Get nstack args */ + smp_parse_stack_args(argc, argv); + + if (0 == uStackArgIndex) + { + NSPOL_LOGERR("uStackArgIndex is 0, can lead to long loop]"); + return retval; + } + + /* Init DPDK */ + argc = uStackArgIndex--; + INITPOL_LOGINF("HAL", "hal_init_global", NULL_STRING, LOG_INVALID_VALUE, + MODULE_INIT_START); + + for (idx_init = 0; idx_init < argc; idx_init++) + { + NSPOL_LOGINF(SC_DPDK_INFO, + "hal_init_global]idx_init=%d,argv[idx_init]=%s", + idx_init, argv[idx_init]); + } + + retval = hal_init_global(argc, argv); + + if (0 != retval) + { + NSPOL_LOGERR("call hal_init_global fail]retval = %d", retval); + return -1; + } + + retval = hal_init_local(); + + if (0 != retval) + { + NSPOL_LOGERR("call hal_init_local fail]retval = %d", retval); + return -1; + } + + retval = spl_hal_port_zone_init(); + if (0 != retval) + { + NSPOL_LOGERR("call hal_init_local fail]retval = %d", retval); + return -1; + } + + NSPOL_LOGDBG(SC_DPDK_INFO, "Finished Process Init"); + + return 0; + +} + +static inline int spl_hal_rx_mbuf_free(void *data, void *arg) +{ + struct spl_pbuf *tmp = NULL; + struct common_mem_mbuf *mbuf = (struct common_mem_mbuf *) data; + (void) arg; + + tmp = + (struct spl_pbuf *) ((char *) mbuf + sizeof(struct common_mem_mbuf)); + if (tmp->res_chk.alloc_flag == TRUE) + return 1; + + if (common_mbuf_refcnt_read(mbuf) == 0) + return 1; + + NSPOL_LOGDBG(SC_DPDK_INFO, "rx_pool init in fault case: free mbuf=%p", + mbuf); + spl_mbuf_free(mbuf); + return 0; +} + +struct common_mem_mempool *spl_hal_rx_pool_create(int nic_id, int queue_id, + int start_type) +{ + int retval; + struct common_mem_mempool *mp; + nsfw_mem_mbfpool create_mbuf_pool; + nsfw_mem_name lookup_mbuf_pool; + struct common_mem_ring *ring; + + if (start_type == 1) + { + create_mbuf_pool.stname.entype = NSFW_SHMEM; + create_mbuf_pool.uscash_size = 0; + create_mbuf_pool.uspriv_size = 0; + create_mbuf_pool.isocket_id = SOCKET_ID_ANY; + create_mbuf_pool.enmptype = NSFW_MRING_SPSC; + + retval = + spl_snprintf(create_mbuf_pool.stname.aname, + NSFW_MEM_NAME_LENTH - 1, "%s", + get_mempoll_rx_name(queue_id, nic_id)); + + if (-1 == retval) + { + NSPOL_LOGERR("spl_snprintf fail"); + return NULL; + } + + create_mbuf_pool.usnum = RX_MBUF_POOL_SIZE - 1; + /*performance, rx buf cap is special, ((size - HEADROOM) >> 10) <<10, see ixgbe_dev_rx_init; + if want cap size == TX_MBUF_MAX_LEN, must let data_root=TX_MBUF_MAX_LEN+COMMON_PKTMBUF_HEADROOM and + TX_MBUF_MAX_LEN must N*1024; + */ + create_mbuf_pool.usdata_room = + TX_MBUF_MAX_LEN + COMMON_PKTMBUF_HEADROOM; + + NSPOL_LOGDBG(SC_DPDK_INFO, "hal_rx_pool.usnum=%u, usdata_room=%u", + create_mbuf_pool.usnum, create_mbuf_pool.usdata_room); + + mp = (struct common_mem_mempool *) + nsfw_mem_mbfmp_create(&create_mbuf_pool); + + if (mp == NULL) + { + NSPOL_LOGERR("nsfw_mem_mbfmp_create fail"); + return NULL; + } + + MEM_STAT(SPL_HAL_MODULE, create_mbuf_pool.stname.aname, NSFW_SHMEM, + nsfw_mem_get_len(mp, NSFW_MEM_MBUF)); + NSPOL_LOGDBG(SC_DPDK_INFO, "create:thread=%d,nic_id=%d,mp=%p,size=%d", + queue_id, nic_id, mp, nsfw_mem_get_len(mp, + NSFW_MEM_MBUF)); + + char rx_msg_arr_name[NSFW_MEM_NAME_LENTH]; + data_com_msg *rx_msg_array = NULL; + retval = spl_snprintf(rx_msg_arr_name, NSFW_MEM_NAME_LENTH, "%s", + get_mempoll_rxmsg_name(queue_id, nic_id)); + + if (-1 != retval) + { + rx_msg_array = (data_com_msg *) sbr_create_mzone(rx_msg_arr_name, + (size_t) + sizeof + (data_com_msg) * + RX_MBUF_POOL_SIZE); + } + + if (!rx_msg_array) + { + NSSBR_LOGERR + ("Create rx_msg_array zone fail]name=%s, num=%u, size=%zu", + rx_msg_arr_name, RX_MBUF_POOL_SIZE, + (size_t) sizeof(data_com_msg) * RX_MBUF_POOL_SIZE); + } + else + { + /*bind msg to pbuf */ + MEM_STAT(SPL_HAL_MODULE, rx_msg_arr_name, NSFW_SHMEM, + (size_t) sizeof(data_com_msg) * RX_MBUF_POOL_SIZE); + NSSBR_LOGINF + ("Create rx_msg_array zone ok]name=%s, ptr=%p, num=%u, size=%zu", + rx_msg_arr_name, rx_msg_array, RX_MBUF_POOL_SIZE, + sizeof(data_com_msg) * RX_MBUF_POOL_SIZE); + + struct common_mem_mbuf *mbuf = NULL; + struct spl_pbuf *buf = NULL; + u32 loop = 0; + + for (; loop < RX_MBUF_POOL_SIZE; loop++) + { + mbuf = nsfw_shmem_mbfalloc(mp); + + if (!mbuf) + { + /* alloc failed , still can work, no prebind success just not so faster */ + NSSBR_LOGERR + ("nsfw_mem_mbf_alloc failed,this can not happen"); + break; + } + + buf = + (struct spl_pbuf *) ((char *) mbuf + + sizeof(struct common_mem_mbuf)); + sys_sem_init(&rx_msg_array[loop].param.op_completed); + rx_msg_array[loop].param.msg_from = NULL; + buf->msg = (void *) &rx_msg_array[loop]; + (void) res_free(&buf->res_chk); //no need to check return value, as it will do free operation depends on alloc_flag + + if (nsfw_shmem_mbffree(mbuf) < 0) + { + /* free failed , still can work, no prebind work just not so faster */ + NSSBR_LOGERR + ("nsfw_mem_mbf_free failed,this can not happen"); + break; + } + } + + } + + } + else + { + retval = + spl_snprintf(lookup_mbuf_pool.aname, NSFW_MEM_NAME_LENTH - 1, + "%s", get_mempoll_rx_name(queue_id, nic_id)); + + if (-1 == retval) + { + NSPOL_LOGERR("spl_snprintf fail"); + return NULL; + } + + lookup_mbuf_pool.entype = NSFW_SHMEM; + lookup_mbuf_pool.enowner = NSFW_PROC_MAIN; + mp = (struct common_mem_mempool *) + nsfw_mem_mbfmp_lookup(&lookup_mbuf_pool); + + if (mp == NULL) + { + NSPOL_LOGERR("nsfw_mem_mbfmp_lookup fail, name=%s, try to create", + lookup_mbuf_pool.aname); + return spl_hal_rx_pool_create(nic_id, queue_id, 1); + } + + NSPOL_LOGDBG(SC_DPDK_INFO, "lookup:thread=%d,nic_id=%d,mp=%p,size=%d", + queue_id, nic_id, mp, nsfw_mem_get_len(mp, + NSFW_MEM_MBUF)); + + /*We have to recycle RX mbufs hold by DPDK when fault recovering of upgrading nstack */ + if (start_type == 3 || start_type == 2) + { + ring = (struct common_mem_ring *) (mp->pool_data); + NSPOL_LOGINF(SC_DPDK_INFO, + "BEFORE clear rx_mpool]prod.head=%u, prod.tail=%u, " + "cons.head=%u, cons.tail=%u", ring->prod.head, + ring->prod.tail, ring->cons.head, ring->cons.tail); + + if (nsfw_mem_mbuf_iterator(mp, 0, mp->size, + spl_hal_rx_mbuf_free, NULL) < 0) + { + NSPOL_LOGERR("nsfw_mem_mbuf_iterator return fail"); + return NULL; + } + + NSPOL_LOGINF(SC_DPDK_INFO, + "AFTER clear rx_mpool]prod.head=%u, prod.tail=%u, " + "cons.head=%u, cons.tail=%u", ring->prod.head, + ring->prod.tail, ring->cons.head, ring->cons.tail); + } + + } + + return mp; + +} + +int spl_hal_bond_config(struct network_configuration *network) +{ + struct phy_net *phynet = network->phy_net; + struct ref_nic *phead = phynet->header; + static u8_t bond_index = 0; /* for auto-generating bond_name */ + unsigned int check_bond = 0, check_name; + int retVal; + u8_t j, k, idx = 0; + + /* get bond info from network configuration */ + if (phynet->bond_mode != -1 && bond_ports_array.cnt < MAX_BOND_PORT_NUM) + { + struct ref_nic *phead_bond = phead; + char *name = phynet->bond_name; + struct bond_set *s = &bond_ports_array.ports[bond_ports_array.cnt]; + + while (phead_bond != NULL) + { + /* check slave name, repeated slave nic cannot be added to bond set. */ + check_name = 0; + + for (j = 0; j < idx; j++) + { + if (strcmp(s->slave_ports[j], phead_bond->nic_name) == 0) + { + check_name = 1; + break; + } + } + + if (check_name) + { + break; + } + + /* if this nic has been added to a bond_set, ignore it */ + check_bond = 0; + + for (k = 0; k < bond_ports_array.cnt && !check_bond; k++) + { + for (j = 0; + j < bond_ports_array.ports[k].slave_port_cnt + && !check_bond; j++) + { + if (strcmp + (bond_ports_array.ports[k].slave_ports[j], + phead_bond->nic_name) == 0) + { + check_bond = 1; + + if (name[0] == 0) + { + retVal = + strncpy_s(name, IP_MODULE_MAX_NAME_LEN, + bond_ports_array. + ports[k].bond_port_name, + strlen(bond_ports_array. + ports[k].bond_port_name)); + if (EOK != retVal) + { + NSPOL_LOGERR("STRNCPY_S failed]ret=%d.", + retVal); + return -1; + } + } + + if (strcmp + (name, + bond_ports_array.ports[k].bond_port_name) != 0) + { + NSOPR_SET_ERRINFO(-1, "%s init failed!\n", name); + NSPOL_LOGERR + ("%s init failed! %s in both %s and %s", name, + phead_bond->nic_name, name, + bond_ports_array.ports[k].bond_port_name); + return -1; + } + } + } + } + + if (check_bond == 1) + { + break; + } + + /* copy slave ports name to bond array */ + retVal = + strncpy_s(s->slave_ports[idx], HAL_MAX_NIC_NAME_LEN, + phead_bond->nic_name, strlen(phead_bond->nic_name)); + + if (EOK != retVal) + { + NSPOL_LOGERR("STRNCPY_S failed]ret=%d.", retVal); + return -1; + } + + idx++; + phead_bond = phead_bond->next; + + if (idx >= HAL_MAX_SLAVES_PER_BOND) + { + break; + } + } + + if (check_bond == 0) + { + if (name[0] == 0) + { + /* if bond_name is a empty string, generate a new bond name */ + retVal = + sprintf_s(name, HAL_MAX_NIC_NAME_LEN, "bond%u_auto", + bond_index++); + + if (-1 == retVal) + { + NSPOL_LOGERR("SPRINTF_S failed]ret=%d.", retVal); + return -1; + } + } + + /* copy bond_name to bond array */ + retVal = + strncpy_s(s->bond_port_name, HAL_MAX_NIC_NAME_LEN, name, + strlen(name)); + + if (EOK != retVal) + { + NSPOL_LOGERR("STRNCPY_S failed]ret=%d.", retVal); + return -1; + } + + s->slave_port_cnt = idx; + bond_ports_array.cnt++; + NSPOL_LOGINF(SC_DPDK_INFO, + "bond_ports_array.cnt=%u,slave_port_cnt=%u", + bond_ports_array.cnt, s->slave_port_cnt); + } + } + + return 0; +} + +int spl_hal_port_config(unsigned int *port_num) +{ + int retVal; + unsigned int check; + struct phy_net *phynet; + + struct network_configuration *network = get_network_list(); + + if (!network) + { + NSPOL_LOGERR("fail to get_provider_node"); + return -1; + } + + unsigned int port_index = p_stackx_port_zone->port_num; + + while (network && (phynet = network->phy_net)) + { + struct ref_nic *phead = phynet->header; + NSPOL_LOGINF(SC_DPDK_INFO, "network=%p,network_name=%s", network, + network->network_name); + + if (spl_hal_bond_config(network) < 0) + { + NSPOL_LOGERR("spl_hal_bond_config fail."); + return -1; + } + + while (phead != NULL) + { + /* check if the NIC is inited */ + for (check = 0; check < port_index; ++check) + { + if (strcmp + (p_stackx_port_zone->stackx_one_port[check]. + linux_ip.if_name, phead->nic_name) == 0) + { + break; + } + } + + if (check != port_index) + { + phead = phead->next; + continue; + } + + /* check if the number of VF exceeds MAX_VF_NUM */ + if (port_index >= + MAX_VF_NUM + p_stackx_port_zone->bonded_port_num) + { + NSOPR_SET_ERRINFO(-1, "Support Only %d VF. %s init failed!\n", + MAX_VF_NUM, phead->nic_name); + NSPOL_LOGERR("Support Only %d VF. %s init failed!", + MAX_VF_NUM, phead->nic_name); + NSOPR_SET_ERRINFO(-1, "Add network %s failed!\n", + network->network_name); + break; + } + + if (strlen(phead->nic_name) >= + sizeof(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_name) - 1 + || strlen(phead->nic_name) <= 3) + { + NSPOL_LOGERR("Invalid configuration"); + return -1; + } + + retVal = + strcpy_s(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_name, + sizeof(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_name), + phead->nic_name); + + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d.", retVal); + return -1; + } + + NSPOL_LOGINF(SC_DPDK_INFO, "if_name %s", + p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_name); + + retVal = + strcpy_s(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_type, + sizeof(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_type), + network->nic_type_name); + if (EOK != retVal) + { + NSPOL_LOGERR("strcpy_s failed]ret=%d.", retVal); + return -1; + } + + NSPOL_LOGINF(SC_DPDK_INFO, "if_type %s", + p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_type); + + retVal = + strcpy_s(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.ip_addr_linux, + sizeof(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip. + ip_addr_linux), "0.0.0.0"); + + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d.", retVal); + return -1; + } + + retVal = + strcpy_s(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.mask_linux, + sizeof(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip. + mask_linux), "0.0.0.0"); + + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d.", retVal); + return -1; + } + + retVal = + strcpy_s(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.bcast_linux, + sizeof(p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip. + bcast_linux), "0.0.0.0"); + + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d.", retVal); + return -1; + } + + ++port_index; + NSPOL_LOGINF(SC_DPDK_INFO, "port_index=%u", port_index); + + if (CUR_CFG_HAL_PORT_NUM <= port_index + bond_ports_array.cnt) + { + // TODO: Invalid configuration received, return immediately + NSPOL_LOGERR + ("Insufficient nStack configuration when compared to configuration from network.json"); + return -1; + } + + /* [TA33636] [2017-04-11] Do not need provider.json */ + if (phynet->bond_mode == -1 /*&& strncmp(network->network_name, "provider", 8) != 0 */ + ) + { + break; + } + else + { + phead = phead->next; + } + } + + network = network->next; + } + + *port_num = port_index; + + return ERR_OK; +} + +void spl_hal_capa_init() +{ + u32_t ipv4_cksum_offload = 1; + u32_t udp_cksum_offload = 1; + u32_t tcp_cksum_offload = 1; + struct hal_netif_hw_feature info = { 0 }; + struct stackx_port_info *p_port_info = head_used_port_list; + + while (p_port_info) + { + hal_get_capability(p_port_info->linux_ip.hdl, &info); + + if (info.tx_csum_ip == 0) + { + ipv4_cksum_offload = 0; + + NSPOL_LOGDBG(SC_DPDK_INFO, + "Port %s TX_OFFLOAD_IPV4_CKSUM Disable", + p_port_info->linux_ip.if_name); + } + + if (info.tx_csum_udp == 0) + { + udp_cksum_offload = 0; + + NSPOL_LOGDBG(SC_DPDK_INFO, "Port %s TX_OFFLOAD_UDP_CKSUM Disable", + p_port_info->linux_ip.if_name); + } + + if (info.tx_csum_tcp == 0) + { + tcp_cksum_offload = 0; + + NSPOL_LOGDBG(SC_DPDK_INFO, "Port %s TX_OFFLOAD_TCP_CKSUM Disable", + p_port_info->linux_ip.if_name); + } + + p_port_info = p_port_info->next_use_port; + } + + spl_hal_capa.tx_ipv4_cksum_offload = ipv4_cksum_offload; + spl_hal_capa.tx_udp_cksum_offload = udp_cksum_offload; + spl_hal_capa.tx_tcp_cksum_offload = tcp_cksum_offload; + + NSPOL_LOGINF(SC_DPDK_INFO, + "ipv4_cksum_offload(%u),udp_cksum_offload(%u),tcp_cksum_offload(%u)", + ipv4_cksum_offload, udp_cksum_offload, tcp_cksum_offload); + +} + +NSTACK_STATIC void +spl_hal_bond_info_init(hal_hdl_t hdl, struct bond_set *s, + struct stackx_port_info *p) +{ +#define MAX_MAC_STR_LEN 20 + char mac_string[MAX_MAC_STR_LEN]; + int retVal; + struct ether_addr addr; + + p->linux_ip.hdl = hdl; + + struct stackx_port_info *slave_port; + slave_port = get_port_info_by_name(s->slave_ports[0]); + + if (slave_port == NULL) + { + NSPOL_LOGERR("get_port_info_by_name failed]bond_port_name=%s", + s->bond_port_name); + return; + } + + /* check the lenght of bond_port_name */ + retVal = + strcpy_s(p->linux_ip.if_name, sizeof(p->linux_ip.if_name), + s->bond_port_name); + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d", retVal); + return; + } + + hal_get_macaddr(hdl, &addr); + retVal = + spl_hal_ether_etoa(addr.addr_bytes, sizeof(addr.addr_bytes), + mac_string, sizeof(mac_string)); + if (retVal < 0) + { + NSPOL_LOGERR("spl_hal_ether_etoa failed]ret=%d", retVal); + return; + } + + retVal = + strcpy_s(p->linux_ip.mac_addr, sizeof(p->linux_ip.mac_addr), + mac_string); + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d", retVal); + return; + } + + retVal = + strcpy_s(p->linux_ip.ip_addr_linux, sizeof(p->linux_ip.ip_addr_linux), + slave_port->linux_ip.ip_addr_linux); + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d", retVal); + return; + } + + retVal = + strcpy_s(p->linux_ip.mask_linux, sizeof(p->linux_ip.mask_linux), + slave_port->linux_ip.mask_linux); + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d", retVal); + return; + } + + retVal = + strcpy_s(p->linux_ip.bcast_linux, sizeof(p->linux_ip.bcast_linux), + slave_port->linux_ip.bcast_linux); + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d", retVal); + return; + } + + NSPOL_LOGINF(SC_DPDK_INFO, "===== the bond port info ======"); + NSPOL_LOGINF(SC_DPDK_INFO, "bond port name=%s", p->linux_ip.if_name); + NSPOL_LOGINF(SC_DPDK_INFO, "bond port mac=%s", p->linux_ip.mac_addr); + NSPOL_LOGINF(SC_DPDK_INFO, "bond port ip=%s", p->linux_ip.ip_addr_linux); + NSPOL_LOGINF(SC_DPDK_INFO, "bond port netmask=%s", + p->linux_ip.mask_linux); + NSPOL_LOGINF(SC_DPDK_INFO, "bond port broad_cast addr=%s", + p->linux_ip.bcast_linux); + +} + +NSTACK_STATIC int spl_hal_bond_start(void) +{ + u8_t i, j = 0; + struct stackx_port_info *bond_port = NULL; + hal_hdl_t hdl; + hal_hdl_t slave_hdl[HAL_MAX_SLAVES_PER_BOND]; + + NSPOL_LOGINF(SC_DPDK_INFO, "bond_ports_array.cnt=%u", + bond_ports_array.cnt); + + for (i = bond_ports_array_cnt_start; i < bond_ports_array.cnt; i++) + { + struct bond_set *s = &bond_ports_array.ports[i]; + NSPOL_LOGINF(SC_DPDK_INFO, "i=%u,bond_port_name=%s", i, + s->bond_port_name); + + u8_t slave_num = 0; + for (j = 0; j < s->slave_port_cnt; j++) + { + NSPOL_LOGINF(SC_DPDK_INFO, "s->slave_ports[%u]=%s", j, + s->slave_ports[j]); + hdl = get_port_hdl_by_name(s->slave_ports[j]); + + if (!hal_is_valid(hdl)) + { + continue; + } + + slave_hdl[slave_num++] = hdl; + + /* here we didn't release the port mem allocated in p_stackx_port_zone */ + del_port_in_port_list(s->slave_ports[j]); + } + + hdl = hal_bond(s->bond_port_name, slave_num, slave_hdl); + + if (!hal_is_valid(hdl)) + { + NSPOL_LOGERR("hal_bond fail: bond_name =%s", s->bond_port_name); + return -1; + } + + bond_port = + &p_stackx_port_zone-> + stackx_one_port[p_stackx_port_zone->port_num]; + num_ports_NIC++; + p_stackx_port_zone->port_num++; + p_stackx_port_zone->bonded_port_num++; + + spl_hal_bond_info_init(hdl, s, bond_port); + add_port_in_port_list(bond_port); + + } + + bond_ports_array_cnt_start = bond_ports_array.cnt; + return 0; +} + +/* + * Initialises a given port using global settings and with the rx buffers + * coming from the mbuf_pool passed as parameter + */ + +NSTACK_STATIC inline int +spl_hal_port_start(uint16_t nic_id, struct stackx_port_info *p_port_info, + u16_t num_queues) +{ + u16_t num_queues_request, q; + hal_hdl_t hdl; + struct common_mem_mempool *mp; + hal_netif_config_t conf; +#define MAX_MAC_STR_LEN 20 + char mac_string[MAX_MAC_STR_LEN]; + int retVal; + struct ether_addr addr; + + // change the queues number per configuration. + // even we only receive packets from one rx queue when dispatch mode is on, the tx queue + // shoule set to the queues number requested. + num_queues_request = num_queues; + if (num_queues_request > HAL_ETH_MAX_QUEUE_NUM) + { + NSPOL_LOGERR + ("no enougth queue num for thread!]num_queues_request=%u,MAX_QUEUE_NUM=%u", + num_queues_request, HAL_ETH_MAX_QUEUE_NUM); + return -1; + } + + NSPOL_LOGDBG(SC_DPDK_INFO, "# Initialising index=%s... ", + p_port_info->linux_ip.if_name); + /* used to have fflush,no use code ,remove it. */ + + conf.bit.hw_vlan_filter = 1; + conf.bit.hw_vlan_strip = 1; + + conf.rx.queue_num = num_queues_request; + conf.tx.queue_num = num_queues_request; + + for (q = 0; q < num_queues_request; q++) + { + mp = (struct common_mem_mempool *) spl_hal_rx_pool_create(nic_id, q, + 1); + + if (mp == NULL) + { + NSPOL_LOGERR + ("spl_hal_rx_pool_create fail]mp=NULL,nic_id=%u,if_name=%s", + nic_id, p_port_info->linux_ip.if_name); + return -1; + } + + (void) spl_reg_res_txrx_mgr((mpool_handle *) mp); // will only return 0, no need to check return value + conf.rx.ring_pool[q] = mp; + conf.rx.ring_size[q] = HAL_RX_RING_SIZE; + conf.tx.ring_size[q] = HAL_TX_RING_SIZE; + } + + hdl = + hal_create(p_port_info->linux_ip.if_name, + p_port_info->linux_ip.if_type, &conf); + + if (!hal_is_valid(hdl)) + { + NSPOL_LOGERR("hal_create fail]if_name =%s", + p_port_info->linux_ip.if_name); + return -1; + } + + p_port_info->linux_ip.hdl = hdl; + + /* add mac address */ + hal_get_macaddr(hdl, &addr); + retVal = + spl_hal_ether_etoa(addr.addr_bytes, sizeof(addr.addr_bytes), + mac_string, sizeof(mac_string)); + if (retVal < 0) + { + NSPOL_LOGERR("spl_hal_ether_etoa failed]ret=%d", retVal); + return -1; + } + + retVal = + strcpy_s(p_port_info->linux_ip.mac_addr, + sizeof(p_port_info->linux_ip.mac_addr), mac_string); + if (EOK != retVal) + { + NSPOL_LOGERR("STRCPY_S failed]ret=%d", retVal); + return -1; + } + + return 0; +} + +NSTACK_STATIC int spl_hal_port_setup() +{ + unsigned int i; + struct stackx_port_info *p_port_info = NULL; + + INITPOL_LOGINF("HAL", "spl_hal_port_setup", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_START); + + for (i = num_ports_NIC_start; i < num_ports_NIC; i++) + { + p_port_info = &(p_stackx_port_zone->stackx_one_port[i]); + + if (spl_hal_port_start(i, p_port_info, (u16_t) 1) < 0) + { + NSPOL_LOGERR("Error initialising]nic_id=%u", i); + + INITPOL_LOGERR("HAL", "spl_hal_port_setup", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + + return -1; + } + else + { + report_port_link_status(p_port_info); + add_port_in_port_list(p_port_info); + } + } + + if (spl_hal_bond_start() < 0) + { + NSPOL_LOGERR("bond port init failed!"); + + INITPOL_LOGERR("HAL", "spl_hal_port_setup", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + + return -1; + } + + spl_hal_capa_init(); + + INITPOL_LOGINF("HAL", "spl_hal_port_setup", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_SUCCESS); + + return 0; + +} + +int spl_hal_port_init() +{ + int retval; + unsigned int i, port_num = 0; + + int port_num_start = p_stackx_port_zone->port_num; + num_ports_NIC_start = num_ports_NIC; + + //Read network info + INITPOL_LOGINF("IP", "spl_hal_port_config", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_START); + retval = spl_hal_port_config(&port_num); + + if (retval != ERR_OK) + { + INITPOL_LOGERR("IP", "spl_hal_port_config", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + return -1; + } + + p_stackx_port_zone->port_num = port_num; + + NSPOL_LOGINF(SC_DPDK_INFO, "port_num=%u", port_num); + INITPOL_LOGINF("IP", "spl_hal_port_config", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_SUCCESS); + + if (port_num_start == p_stackx_port_zone->port_num) + { + NSPOL_LOGERR("No new NIC find."); + return 0; + } + + //Get ports num + for (i = port_num_start; i < p_stackx_port_zone->port_num; i++) + { + if (p_stackx_port_zone->stackx_one_port[i].linux_ip.if_name[0] != 0) + { + /* right now hard coded, */ + int eth_num = + atoi(p_stackx_port_zone->stackx_one_port[i].linux_ip.if_name + + 3); + + num_ports_NIC++; + + NSPOL_LOGDBG(SC_DPDK_INFO, "port_mask=%d ,eth_name=%s", eth_num, + p_stackx_port_zone->stackx_one_port[i]. + linux_ip.if_name); + } + } + + if (num_ports_NIC > HAL_MAX_NIC_NUM) + { + NSPOL_LOGERR("just support one eth"); + common_exit(EXIT_FAILURE, "just surport one eth"); + } + + if (num_ports_NIC == num_ports_NIC_start) + { + NSPOL_LOGERR("No new NIC find."); + return 0; + } + + retval = spl_hal_port_setup(); + + if (retval == -1) + { + return -1; + } + + NSPOL_LOGDBG(SC_DPDK_INFO, "Finished Process Init."); + + return 1; +} + +inline NSTACK_STATIC void spl_hal_send(struct netif *pnetif) +{ + u16_t i, sent = 0; + struct netifExt *pnetifExt = NULL; + u16_t netif_id = pnetif->num; + u16_t tx_num = spl_hal_pkts[netif_id].tx.num; + struct common_mem_mbuf **tx_ptks = spl_hal_pkts[netif_id].tx.pkts; + + for (i = 0; i < tx_num; i++) + { + (void) + res_free(& + (((struct spl_pbuf *) (((char *) tx_ptks[i]) + + sizeof(struct + common_mem_mbuf)))->res_chk)); + } + + int _retry = 0; + + pnetifExt = getNetifExt(pnetif->num); + if (NULL == pnetifExt) + return; + + do + { + sent += + hal_send_packet(pnetifExt->hdl, 0, (void **) &(tx_ptks[sent]), + tx_num - sent); + _retry++; + + if (_retry > SPL_HAL_SEND_TRY) + { + NSPOL_LOGERR("send loop %d times but dpdk send data fail ", + SPL_HAL_SEND_TRY); + break; + } + } + while (unlikely(sent != tx_num)); + + if (unlikely(sent != tx_num)) + { + for (i = sent; i < tx_num; i++) + { + (void) nsfw_shmem_mbffree((mbuf_handle) (tx_ptks[i])); + } + } + for (i = 0; i < tx_num; i++) + { + /* set dpdk_send flag */ + ((struct spl_pbuf *) (((char *) tx_ptks[i]) + + sizeof(struct common_mem_mbuf)))-> + res_chk.u8Reserve |= DPDK_SEND_FLAG; + } + + spl_hal_pkts[netif_id].tx.num = 0; + +} + +inline u16_t spl_hal_recv(struct netif *pnetif, u8_t id) +{ + u16_t netif_id, rx_c = 0; + struct netifExt *pnetifExt = NULL; + + netif_id = pnetif->num; + + pnetifExt = getNetifExt(pnetif->num); + if (NULL == pnetifExt) + return 0; + + rx_c = + hal_recv_packet(pnetifExt->hdl, 0, + (void **) spl_hal_pkts[netif_id].rx.pkts, PKT_BURST); + + if (rx_c <= 0) + { + return 0; + } + + spl_hal_pkts[netif_id].rx.num = rx_c; + spl_hal_pkts[netif_id].rx.index = 0; + + return rx_c; +} + +/*needflush set 1 has pbuf release problem, ref maybe set 0 before release*/ +NSTACK_STATIC inline void +spl_hal_set_cksum(struct spl_pbuf *buf, struct common_mem_mbuf *mbuf) +{ + + //need to be careful, special when small packet oversize + if (buf->tot_len > mbuf->pkt_len) + { + NSPOL_LOGWAR(SC_DPDK_INFO, + "small packet OVERSIZE]pbuf_len=%u,mbuf_len=%u", + buf->len, mbuf->pkt_len); + mbuf->pkt_len = buf->len; + } + + if (!spl_hal_tx_ip_cksum_enable() || !spl_hal_tx_tcp_cksum_enable() + || !spl_hal_tx_udp_cksum_enable()) + { + struct tcp_hdr *t_hdr; + struct udp_hdr *u_hdr; + u16_t flag_offset; + u64_t ol_flags = (mbuf->ol_flags); //& (~PKT_TX_L4_MASK)); + + struct eth_hdr *ethhdr = (struct eth_hdr *) ((char *) buf->payload); + + if (ethhdr->type == 8) + { + struct ip_hdr *iphdr = + (struct ip_hdr *) ((char *) buf->payload + + sizeof(struct eth_hdr)); + + if (!spl_hal_tx_ip_cksum_enable()) + { + ol_flags |= PKT_TX_IPV4 | PKT_TX_IP_CKSUM; + iphdr->_chksum = 0; + } + + flag_offset = spl_ntohs(iphdr->_offset); + + /*ip frag, only the first packet has udp or tcp head */ + if (0 == (flag_offset & IP_OFFMASK)) + { + switch (iphdr->_proto) + { + case IPPROTO_TCP: + if (!spl_hal_tx_tcp_cksum_enable()) + { + t_hdr = + (struct tcp_hdr *) ((char *) buf->payload + + sizeof(struct eth_hdr) + + sizeof(struct ip_hdr)); + t_hdr->chksum = get_ipv4_psd_sum(iphdr, ol_flags); + ol_flags |= PKT_TX_TCP_CKSUM; + } + + break; + + case IPPROTO_UDP: + { + if ((mbuf->ol_flags & PKT_TX_UDP_CKSUM) == + PKT_TX_UDP_CKSUM) + { + u_hdr = (struct udp_hdr *) ((char *) buf->payload + sizeof(struct eth_hdr) + sizeof(struct ip_hdr)); //l2_len + l3_len); + u_hdr->chksum = + get_ipv4_psd_sum(iphdr, mbuf->ol_flags); + } + } + + break; + + default: + + break; + } + } + mbuf->l2_len = sizeof(struct eth_hdr); //l2_len; + mbuf->l3_len = sizeof(struct ip_hdr); + mbuf->ol_flags = ol_flags; + } + } +} + +/*needflush set 1 has pbuf release problem, ref maybe set 0 before release*/ +err_t spl_hal_output(struct netif *pnetif, struct pbuf *buf) +{ + u16_t netif_id, idx; + struct common_mem_mbuf *mbuf; + struct spl_pbuf *spbuf = NULL; + //spl_pbuf_layer layer = SPL_PBUF_TRANSPORT; + //u16_t offset; + + if (!p_def_stack_instance) + { + NSPOL_LOGERR("p_def_stack_instance is NULL"); + return -1; + } + + u16_t proc_id = spl_get_lcore_id(); + + NSPOL_LOGINF(SC_DPDK_INFO, "spl_hal_output. len %d totlen %d", buf->len, + buf->tot_len); + print_pbuf_payload_info(buf, true); + + if (buf->tot_len > DEF_MBUF_DATA_SIZE) + { + NSPOL_LOGINF(TCP_DEBUG, "spl_pbuf_alloc_hugepage Failed!!!"); + return ERR_MEM; + + } + spbuf = spl_pbuf_alloc_hugepage(SPL_PBUF_RAW, + buf->tot_len, + SPL_PBUF_HUGE, proc_id, NULL); + + if (!spbuf) + { + NSPOL_LOGINF(TCP_DEBUG, "spl_pbuf_alloc_hugepage Failed!!!"); + return ERR_MEM; + } + + if (ERR_OK != pbuf_to_splpbuf_copy(spbuf, buf)) + { + NSPOL_LOGERR("pbuf to splpbuf copy failed"); + return -1; + } + + mbuf = + (struct common_mem_mbuf *) ((char *) spbuf - + sizeof(struct common_mem_mbuf)); + + if (spbuf->tot_len > mbuf->pkt_len) + { + NSPOL_LOGWAR(SC_DPDK_INFO, + "small packet OVERSIZE]pbuf_len=%u,mbuf_len=%u", + spbuf->len, mbuf->pkt_len); + mbuf->pkt_len = spbuf->len; + } + + spl_hal_set_cksum(spbuf, mbuf); + + netif_id = pnetif->num; + idx = spl_hal_pkts[netif_id].tx.num++; + spl_hal_pkts[netif_id].tx.pkts[idx] = mbuf; + spl_do_dump(spbuf, DUMP_SEND); + spl_hal_send(pnetif); + + return 0; +} + +void spl_hal_input(struct netif *pnetif, struct spl_pbuf **buf) +{ + u16_t netif_id; + + struct common_mem_mbuf *mbuf; + + netif_id = pnetif->num; + + if (likely + (spl_hal_pkts[netif_id].rx.num > spl_hal_pkts[netif_id].rx.index)) + { + mbuf = + spl_hal_pkts[netif_id].rx.pkts[spl_hal_pkts[netif_id].rx.index]; + spl_hal_pkts[netif_id].rx.index++; + spl_hal_buf_convert(mbuf, buf); + spl_do_dump(*buf, DUMP_RECV); + } + else + { + NSPOL_LOGERR + ("recv from spl_dev has a problem]pnetif=%p, num=%u, index=%u", + pnetif, spl_hal_pkts[netif_id].rx.num, + spl_hal_pkts[netif_id].rx.index); + *buf = NULL; + } + return; +} + +int spl_hal_tx_ip_cksum_enable() +{ + return !spl_hal_capa.tx_ipv4_cksum_offload; +} + +int spl_hal_tx_udp_cksum_enable() +{ + return !spl_hal_capa.tx_udp_cksum_offload; +} + +int spl_hal_tx_tcp_cksum_enable() +{ + return !spl_hal_capa.tx_tcp_cksum_offload; +} + +u32 spl_hal_is_nic_exist(const char *name) +{ + return hal_is_nic_exist(name); +} + +int spl_hal_is_bond_netif(struct netif *pnetif) +{ + int i; + struct bond_set *s; + struct netifExt *pnetifExt = NULL; + + pnetifExt = getNetifExt(pnetif->num); + if (NULL == pnetifExt) + return 0; + + for (i = 0; i < bond_ports_array.cnt; i++) + { + s = &bond_ports_array.ports[i]; + if (!strncmp + (pnetifExt->if_name, s->bond_port_name, HAL_MAX_NIC_NAME_LEN)) + { + return 1; + } + } + + return 0; +} -- cgit 1.2.3-korg