diff options
Diffstat (limited to 'src/framework/hal')
-rw-r--r-- | src/framework/hal/hal.c | 865 | ||||
-rw-r--r-- | src/framework/hal/hal.h | 182 |
2 files changed, 1047 insertions, 0 deletions
diff --git a/src/framework/hal/hal.c b/src/framework/hal/hal.c new file mode 100644 index 0000000..1adf274 --- /dev/null +++ b/src/framework/hal/hal.c @@ -0,0 +1,865 @@ +/* +* +* 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 "common_sys_config.h" +#include "common_mem_mbuf.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "hal.h" +#include "hal_api.h" + +#define HAL_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +/* *INDENT-OFF* */ +static char hal_invalid_char_script[] = {'|', ';', '&', '$', '>', '<', '`', '\\', '\"', '\'', + '(', ')', '[', ']', '~', '?', '*' + }; + +static char* hal_invalid_str_script[] = {"&&", "||", ">>", "${", ";;", "/./", "/../"}; + +static char* hal_invalid_str_script_begin[] = {"./", "../"}; + +extern const netif_ops_t dpdk_netif_ops; + +static hal_hdl_t hal_invaldi_hdl = {.id = -1}; + +static const netif_ops_t* netif_ops_table[HAL_DRV_MAX]; +static int netif_ops_init_flag = 0; + +netif_inst_t netif_tbl[HAL_MAX_NIC_NUM]; +/* *INDENT-ON* */ + +void +hal_io_adpt_register (const netif_ops_t * ops) +{ + int icnt = 0; + if (netif_ops_init_flag == 0) + { + (void) MEMSET_S (&netif_ops_table[0], sizeof (netif_ops_table), 0, + sizeof (netif_ops_table)); + netif_ops_init_flag = 1; + } + + for (icnt = 0; icnt < HAL_DRV_MAX; icnt++) + { + if (netif_ops_table[icnt] == 0) + { + netif_ops_table[icnt] = ops; + break; + } + } + return; +} + +/***************************************************************************** + Prototype : hal_snprintf + Description : create shell script + Input : char* buffer + size_t buflen + const char* format + ... + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_snprintf (char *buffer, size_t buflen, const char *format, ...) +{ + int len; + va_list ap; + + /* check buffer validity */ + if (NULL == buffer || 0 == buflen) + { + goto einval_error; + } + + if (format == NULL) + { + buffer[0] = '\0'; + + goto einval_error; + } + + (void) va_start (ap, format); + len = VSNPRINTF_S (buffer, buflen, buflen - 1, format, ap); + + if (-1 == len) + { + va_end (ap); + goto einval_error; + } + + va_end (ap); + + buffer[buflen - 1] = '\0'; + + return len; + +einval_error: + errno = EINVAL; + return -1; +} + +/***************************************************************************** + Prototype : hal_is_script_valid + Description : Check External Injection of Shell script Validation + Input : const char* cmd + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_is_script_valid (const char *cmd) +{ + unsigned int i; + + if (cmd) + { + char *cmd_str = (char *) cmd; + + /* skip space */ + while (*cmd_str == ' ' || *cmd_str == '\t') + { + cmd_str++; + } + + /* cmd can not start with ./ and ../ */ + for (i = 0; i < HAL_ARRAY_SIZE (hal_invalid_str_script_begin); i++) + { + if (strstr (cmd_str, hal_invalid_str_script_begin[i]) == cmd_str) + { + return 0; + } + } + + /* cmd can not include | ; $ and so on */ + for (i = 0; i < HAL_ARRAY_SIZE (hal_invalid_char_script); i++) + { + if (strchr (cmd, hal_invalid_char_script[i])) + { + return 0; + } + } + + /* cmd can not include && || >> and so on */ + for (i = 0; i < HAL_ARRAY_SIZE (hal_invalid_str_script); i++) + { + if (strstr (cmd, hal_invalid_str_script[i])) + { + return 0; + } + } + + return 1; + } + + return 0; +} + +/***************************************************************************** + Prototype : hal_run_script + Description : run shell script + Input : const char* cmd + char* result_buf + size_t max_result_len + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_run_script (const char *cmd, char *result_buf, size_t max_result_len) +{ + size_t n; + if (!cmd || !result_buf || max_result_len <= 1) + { + return -1; + } + + FILE *fd = popen (cmd, "r"); + + if (fd != NULL) + { + n = fread (result_buf, sizeof (char), max_result_len - 1, fd); + + if (n == 0) + { + result_buf[0] = '\0'; + } + else if ('\n' == result_buf[n - 1]) + { + result_buf[n - 1] = '\0'; + } + /* make it null terminated */ + else + { + result_buf[n] = '\0'; + } + + (void) pclose (fd); + return n; + } + + return -1; +} + +/***************************************************************************** + Prototype : hal_init_global + Description : init hal when proccess start + Input : int argc + char** argv + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_init_global (int argc, char **argv) +{ + int ret; + int netif_type; + + ret = + MEMSET_S (netif_tbl, HAL_MAX_NIC_NUM * sizeof (netif_inst_t), 0, + HAL_MAX_NIC_NUM * sizeof (netif_inst_t)); + if (EOK != ret) + { + NSHAL_LOGERR ("MEMSET_S failed"); + return -1; + } + + for (netif_type = 0; netif_ops_table[netif_type]; ++netif_type) + { + if (netif_ops_table[netif_type]->init_global) + { + if (netif_ops_table[netif_type]->init_global (argc, argv)) + { + NSHAL_LOGERR ("failed to init global]netif type=%d", + netif_type); + return -1; + } + } + } + + return 0; +} + +/***************************************************************************** + Prototype : hal_init_local + Description : init hal when process or thread start + Input : None + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_init_local () +{ + int netif_type; + + for (netif_type = 0; netif_ops_table[netif_type]; ++netif_type) + { + if (netif_ops_table[netif_type]->init_local) + { + if (netif_ops_table[netif_type]->init_local ()) + { + NSHAL_LOGERR ("failed to init local]netif type=%d", netif_type); + return -1; + } + } + } + + return 0; +} + +/***************************************************************************** + Prototype : hal_get_invalid_hdl + Description : get the invalid object + Input : None + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +hal_hdl_t +hal_get_invalid_hdl () +{ + return hal_invaldi_hdl; +} + +/***************************************************************************** + Prototype : hal_create + Description : create hal object + Input : const char* name + hal_netif_config_t* conf + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +hal_hdl_t +hal_create (const char *name, hal_netif_config_t * conf) +{ + int ret = -1; + uint32_t netif_type; + netif_inst_t *inst; + + if ((NULL == name) || (NULL == conf)) + { + NSHAL_LOGERR ("invalid para]name=%p,conf=%p", name, conf); + return hal_get_invalid_hdl (); + } + + inst = alloc_netif_inst (); + + if (NULL == inst) + { + NSHAL_LOGERR ("failed to alloc netif inst]netif name=%s", name); + + return hal_get_invalid_hdl (); + } + + /*open */ + for (netif_type = 0; NULL != netif_ops_table[netif_type]; ++netif_type) + { + ret = netif_ops_table[netif_type]->open (inst, name); + + if (0 == ret) + { + inst->ops = netif_ops_table[netif_type]; + + NSHAL_LOGINF ("netif ops]netif type=%u, netif name=%s", netif_type, + inst->ops->name); + + break; + } + } + + if (ret != 0) + { + inst->state = NETIF_STATE_FREE; + + inst->ops = NULL; + + NSHAL_LOGERR ("open fail]netif name=%s", name); + + return hal_get_invalid_hdl (); + } + + /*config */ + ret = inst->ops->config (inst, conf); + + if (ret != 0) + { + inst->state = NETIF_STATE_FREE; + + NSHAL_LOGERR ("config fail]netif name=%s", name); + + return hal_get_invalid_hdl (); + } + + /*start */ + ret = inst->ops->start (inst); + + if (ret != 0) + { + inst->state = NETIF_STATE_FREE; + + NSHAL_LOGERR ("start fail]netif name=%s", name); + + return hal_get_invalid_hdl (); + } + + return inst->hdl; +} + +/***************************************************************************** + Prototype : hal_bond + Description : create hal object for bond mode + Input : const char* bond_name + uint8_t slave_num + hal_hdl_t slave_hdl[] + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +hal_hdl_t +hal_bond (const char *bond_name, uint8_t slave_num, hal_hdl_t slave_hdl[]) +{ + int i, ret; + netif_inst_t *inst; + netif_inst_t *slave_inst[HAL_MAX_SLAVES_PER_BOND]; + + if ((0 == slave_num) || (HAL_MAX_SLAVES_PER_BOND < slave_num) + || (NULL == bond_name) || (NULL == slave_hdl)) + { + NSHAL_LOGERR ("invalid para]bond_name=%p,slave_num=%u,slave_hdl=%p,", + bond_name, slave_num, slave_hdl); + + return hal_get_invalid_hdl (); + } + + for (i = 0; i < slave_num; i++) + { + slave_inst[i] = get_netif_inst (slave_hdl[i]); + + if (NULL == slave_inst[i]) + { + NSHAL_LOGERR ("invalid para slave_hdl]index=%d, slave_inst=%d", i, + slave_hdl[i].id); + return hal_get_invalid_hdl (); + } + } + + inst = alloc_netif_inst (); + + if (NULL == inst) + { + NSHAL_LOGERR ("failed to alloc nic inst]bond_name=%s", bond_name); + return hal_get_invalid_hdl (); + } + + inst->ops = slave_inst[0]->ops; + + ret = inst->ops->bond (inst, bond_name, slave_num, slave_inst); + + if (0 != ret) + { + inst->state = NETIF_STATE_FREE; + + inst->ops = NULL; + + NSHAL_LOGERR ("bond netif fail]bond_name=%s", bond_name); + + return hal_get_invalid_hdl (); + } + + return inst->hdl; +} + +/***************************************************************************** + Prototype : hal_close + Description : destroy hal object + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_close (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + inst->state = NETIF_STATE_FREE; + + return inst->ops->close (inst); +} + +/***************************************************************************** + Prototype : hal_stop + Description : stop recv packet + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_stop (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + return inst->ops->stop (inst); +} + +/***************************************************************************** + Prototype : hal_get_mtu + Description : get the mtu from nic + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint32_t +hal_get_mtu (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return 0; + } + + return inst->ops->mtu (inst); +} + +/***************************************************************************** + Prototype : hal_get_macaddr + Description : in normal mode, get the mac addr from nic + in bond mode1, get the mac addr from primary nic + Input : hal_hdl_t hdl + void* mac_addr + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +void +hal_get_macaddr (hal_hdl_t hdl, void *mac_addr) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return; + } + + (void) inst->ops->macaddr (inst, mac_addr); +} + +/***************************************************************************** + Prototype : hal_get_capability + Description : get offload capability from nic + Input : hal_hdl_t hdl + hal_netif_capa_t* info + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +void +hal_get_capability (hal_hdl_t hdl, hal_netif_capa_t * info) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return; + } + + (void) inst->ops->capability (inst, info); +} + +/***************************************************************************** + Prototype : hal_recv_packet + Description : recv packet from nic + Input : hal_hdl_t hdl + uint16_t queue_id + struct common_mem_mbuf** rx_pkts + uint16_t nb_pkts + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint16_t +hal_recv_packet (hal_hdl_t hdl, uint16_t queue_id, + struct common_mem_mbuf **rx_pkts, uint16_t nb_pkts) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return 0; + } + + return inst->ops->recv (inst, queue_id, rx_pkts, nb_pkts); +} + +/***************************************************************************** + Prototype : hal_send_packet + Description : send packet to nic + Input : hal_hdl_t hdl + uint16_t queue_id + struct common_mem_mbuf** tx_pkts + uint16_t nb_pkts + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint16_t +hal_send_packet (hal_hdl_t hdl, uint16_t queue_id, + struct common_mem_mbuf ** tx_pkts, uint16_t nb_pkts) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return 0; + } + + return inst->ops->send (inst, queue_id, tx_pkts, nb_pkts); +} + +/***************************************************************************** + Prototype : hal_link_status + Description : get link status form nic + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint32_t +hal_link_status (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return 0; + } + + return inst->ops->link_status (inst); +} + +/***************************************************************************** + Prototype : hal_stats + Description : get link statistics form nic + Input : hal_hdl_t hdl + hal_netif_stats_t* stats + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_stats (hal_hdl_t hdl, hal_netif_stats_t * stats) +{ + netif_inst_t *inst; + + if (NULL == stats) + { + NSHAL_LOGERR ("invalid para"); + return -1; + } + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + return inst->ops->stats (inst, stats); +} + +/***************************************************************************** + Prototype : hal_stats_reset + Description : reset link statistics to nic + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +void +hal_stats_reset (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return; + } + + (void) inst->ops->stats_reset (inst); +} + +/***************************************************************************** + Prototype : hal_add_mcastaddr + Description : set multicast addrs to nic + Input : hal_hdl_t hdl + void* mc_addr_set + void* mc_addr + uint32_t nb_mc_addr + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_add_mcastaddr (hal_hdl_t hdl, void *mc_addr_set, + void *mc_addr, uint32_t nb_mc_addr) +{ + int ret; + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + ret = inst->ops->mcastaddr (inst, mc_addr_set, mc_addr, nb_mc_addr); + /* if set mcast addr failed, we have to manually add the mac addr to nic. */ + if (ret < 0) + { + ret = inst->ops->add_mac (inst, mc_addr); + } + return ret; +} + +/***************************************************************************** + Prototype : hal_del_mcastaddr + Description : delete multicast addrs to nic + Input : hal_hdl_t hdl + void* mc_addr_set + void* mc_addr + uint32_t nb_mc_addr + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_del_mcastaddr (hal_hdl_t hdl, void *mc_addr_set, + void *mc_addr, uint32_t nb_mc_addr) +{ + int ret; + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + ret = inst->ops->mcastaddr (inst, mc_addr_set, mc_addr, nb_mc_addr); + /* if set mcast addr failed, we have to manually delete the mac addr from nic. */ + if (ret < 0) + { + ret = inst->ops->rmv_mac (inst, mc_addr); + } + return ret; +} + +/***************************************************************************** + Prototype : hal_set_allmulti_mode + Description : set all multicast mode + Input : hal_hdl_t hdl + uint8_t enable + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +void +hal_set_allmulti_mode (hal_hdl_t hdl, uint8_t enable) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return; + } + + (void) inst->ops->allmcast (inst, enable); +} + +/***************************************************************************** + Prototype : hal_is_nic_exist + Description : check nic is exist + Input : const char *name + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint32_t +hal_is_nic_exist (const char *name) +{ + char script_cmmd[HAL_SCRIPT_LENGTH]; + char result_buf[HAL_SCRIPT_LENGTH]; + int len_out; + int retval; + + if (!hal_is_script_valid (name)) + { + NSHAL_LOGERR ("nic name is not valid"); + return 0; + } + + retval = + hal_snprintf (script_cmmd, sizeof (script_cmmd), + "sudo ifconfig -a | grep -w \"%s[ :]\"", name); + if (-1 == retval) + { + NSHAL_LOGERR ("rte_snprintf failed]retval=%d", retval); + return 0; + } + + len_out = hal_run_script (script_cmmd, result_buf, sizeof (result_buf) - 1); + /* buffer not initialized, should take length as decision */ + if (0 != len_out) + { + return 1; + } + + return 0; +} diff --git a/src/framework/hal/hal.h b/src/framework/hal/hal.h new file mode 100644 index 0000000..2f66914 --- /dev/null +++ b/src/framework/hal/hal.h @@ -0,0 +1,182 @@ +/* +* +* 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. +*/ + +#ifndef _HAL_H_ +#define _HAL_H_ + +#include <stdint.h> +#include "hal_api.h" +#include "nstack_log.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define HAL_DRV_MAX 32 + +#define HAL_IO_REGISTER(name, ops) \ + static __attribute__((__constructor__)) void __hal_register##name(void) \ + {\ + hal_io_adpt_register(ops); \ + } \ + + +#define HAL_MAX_PCI_ADDR_LEN 16 + +#define HAL_MAX_DRIVER_NAME_LEN 128 + +#define HAL_MAX_PATH_LEN 4096 //max path length on linux is 4096 + +#define HAL_SCRIPT_LENGTH 256 + +#define HAL_HDL_TO_ID(hdl) (hdl.id) + +/* IO using DPDK interface */ +typedef struct dpdk_if +{ + uint8_t port_id; /**< DPDK port identifier */ + uint8_t slave_num; + uint8_t slave_port[HAL_MAX_SLAVES_PER_BOND]; + + uint32_t hw_vlan_filter:1; + uint32_t hw_vlan_strip:1; + uint32_t rsv30:30; + + uint32_t rx_queue_num; + uint32_t rx_ring_size[HAL_ETH_MAX_QUEUE_NUM]; + struct rte_mempool *rx_pool[HAL_ETH_MAX_QUEUE_NUM]; + + uint32_t tx_queue_num; + uint32_t tx_ring_size[HAL_ETH_MAX_QUEUE_NUM]; + + char pci_addr[HAL_MAX_PCI_ADDR_LEN]; + char nic_name[HAL_MAX_NIC_NAME_LEN]; + char driver_name[HAL_MAX_DRIVER_NAME_LEN]; +} dpdk_if_t; + +typedef struct netif_inst +{ + enum + { + NETIF_STATE_FREE = 0, + NETIF_STATE_ACTIVE + } state; + + hal_hdl_t hdl; + + const struct netif_ops *ops; /**< Implementation specific methods */ + + union + { + dpdk_if_t dpdk_if; /**< using DPDK for IO */ + } data; + +} netif_inst_t; + +typedef struct netif_ops +{ + const char *name; + int (*init_global) (int argc, char **argv); + int (*init_local) (void); + int (*open) (netif_inst_t * inst, const char *name); + int (*close) (netif_inst_t * inst); + int (*start) (netif_inst_t * inst); + int (*stop) (netif_inst_t * inst); + int (*bond) (netif_inst_t * inst, const char *bond_name, + uint8_t slave_num, netif_inst_t * slave[]); + uint32_t (*mtu) (netif_inst_t * inst); + int (*macaddr) (netif_inst_t * inst, void *mac_addr); + int (*capability) (netif_inst_t * inst, hal_netif_capa_t * info); + uint16_t (*recv) (netif_inst_t * inst, uint16_t queue_id, + struct common_mem_mbuf ** rx_pkts, uint16_t nb_pkts); + uint16_t (*send) (netif_inst_t * inst, uint16_t queue_id, + struct common_mem_mbuf ** tx_pkts, uint16_t nb_pkts); + uint32_t (*link_status) (netif_inst_t * inst); + int (*stats) (netif_inst_t * inst, hal_netif_stats_t * stats); + int (*stats_reset) (netif_inst_t * inst); + int (*config) (netif_inst_t * inst, hal_netif_config_t * conf); + int (*mcastaddr) (netif_inst_t * inst, void *mc_addr_set, + void *mc_addr, uint32_t nb_mc_addr); + int (*add_mac) (netif_inst_t * inst, void *mc_addr); + int (*rmv_mac) (netif_inst_t * inst, void *mc_addr); + int (*allmcast) (netif_inst_t * inst, uint8_t enable); +} netif_ops_t; + +extern netif_inst_t netif_tbl[HAL_MAX_NIC_NUM]; + +static inline netif_inst_t * +alloc_netif_inst () +{ + int i; + netif_inst_t *inst; + + for (i = 0; i < HAL_MAX_NIC_NUM; ++i) + { + inst = &netif_tbl[i]; + + if (NETIF_STATE_FREE == inst->state) + { + inst->state = NETIF_STATE_ACTIVE; + + inst->hdl.id = i; + + return inst; + } + } + + return NULL; + +} + +static inline netif_inst_t * +get_netif_inst (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + if (unlikely (!hal_is_valid (hdl))) + { + NSHAL_LOGERR ("inst id is not valid]inst=%i, HAL_MAX_NIC_NUM=%d", + HAL_HDL_TO_ID (hdl), HAL_MAX_NIC_NUM); + + return NULL; + } + + inst = &netif_tbl[HAL_HDL_TO_ID (hdl)]; + + if (unlikely ((NETIF_STATE_ACTIVE != inst->state) || (NULL == inst->ops))) + { + NSHAL_LOGERR ("netif is not active]inst=%i", HAL_HDL_TO_ID (hdl)); + + return NULL; + } + + return inst; +} + +int hal_snprintf (char *buffer, size_t buflen, const char *format, ...); +int hal_is_script_valid (const char *cmd); +int hal_run_script (const char *cmd, char *result_buf, size_t max_result_len); +void hal_io_adpt_register (const netif_ops_t * ops); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif |