13d8536b4Sopenharmony_ci/*
23d8536b4Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
33d8536b4Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
43d8536b4Sopenharmony_ci *
53d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
63d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met:
73d8536b4Sopenharmony_ci *
83d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
93d8536b4Sopenharmony_ci *    conditions and the following disclaimer.
103d8536b4Sopenharmony_ci *
113d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
123d8536b4Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
133d8536b4Sopenharmony_ci *    provided with the distribution.
143d8536b4Sopenharmony_ci *
153d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
163d8536b4Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
173d8536b4Sopenharmony_ci *    permission.
183d8536b4Sopenharmony_ci *
193d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
203d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
213d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
233d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
243d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
253d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
263d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
273d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
283d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
293d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
303d8536b4Sopenharmony_ci */
313d8536b4Sopenharmony_ci
323d8536b4Sopenharmony_ci#include <lwip/sys.h>
333d8536b4Sopenharmony_ci#include <lwip/netif.h>
343d8536b4Sopenharmony_ci#include <lwip/snmp.h>
353d8536b4Sopenharmony_ci#include <lwip/etharp.h>
363d8536b4Sopenharmony_ci#include <lwip/sockets.h>
373d8536b4Sopenharmony_ci#include <lwip/ethip6.h>
383d8536b4Sopenharmony_ci
393d8536b4Sopenharmony_ci#define LWIP_NETIF_HOSTNAME_DEFAULT         "default"
403d8536b4Sopenharmony_ci#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS     100000000 // 100Mbps
413d8536b4Sopenharmony_ci
423d8536b4Sopenharmony_ci#define link_rx_drop cachehit
433d8536b4Sopenharmony_ci#define link_rx_overrun cachehit
443d8536b4Sopenharmony_ci
453d8536b4Sopenharmony_ci#define LWIP_STATIC static
463d8536b4Sopenharmony_ci
473d8536b4Sopenharmony_ci#define NETIF_NAME_PREFIX_MAX_LENGTH 10
483d8536b4Sopenharmony_ci#define NETIF_NAME_PREFIX_ETH "eth"
493d8536b4Sopenharmony_ci#define NETIF_NAME_PREFIX_WIFI "wlan"
503d8536b4Sopenharmony_ci#define NETIF_NAME_PREFIX_BT "bt"
513d8536b4Sopenharmony_ci
523d8536b4Sopenharmony_ci#ifndef LWIP_NETIF_IFINDEX_MAX_EX
533d8536b4Sopenharmony_ci#define LWIP_NETIF_IFINDEX_MAX_EX 255
543d8536b4Sopenharmony_ci#endif
553d8536b4Sopenharmony_ci
563d8536b4Sopenharmony_ciLWIP_STATIC void driverif_get_ifname_prefix(struct netif *netif, char *prefix, int prefixLen)
573d8536b4Sopenharmony_ci{
583d8536b4Sopenharmony_ci    if (prefix == NULL || netif == NULL) {
593d8536b4Sopenharmony_ci        LWIP_ASSERT("invalid param", 0);
603d8536b4Sopenharmony_ci        return;
613d8536b4Sopenharmony_ci    }
623d8536b4Sopenharmony_ci    switch (netif->link_layer_type) {
633d8536b4Sopenharmony_ci        case ETHERNET_DRIVER_IF:
643d8536b4Sopenharmony_ci            strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_ETH);
653d8536b4Sopenharmony_ci            break;
663d8536b4Sopenharmony_ci        case WIFI_DRIVER_IF:
673d8536b4Sopenharmony_ci            strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_WIFI);
683d8536b4Sopenharmony_ci            break;
693d8536b4Sopenharmony_ci        case BT_PROXY_IF:
703d8536b4Sopenharmony_ci            strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_BT);
713d8536b4Sopenharmony_ci            break;
723d8536b4Sopenharmony_ci        default:
733d8536b4Sopenharmony_ci            LWIP_ASSERT("invalid link_layer_type", 0);
743d8536b4Sopenharmony_ci            break;
753d8536b4Sopenharmony_ci    }
763d8536b4Sopenharmony_ci}
773d8536b4Sopenharmony_ci
783d8536b4Sopenharmony_ciLWIP_STATIC void driverif_init_ifname(struct netif *netif)
793d8536b4Sopenharmony_ci{
803d8536b4Sopenharmony_ci    struct netif *tmpnetif = NULL;
813d8536b4Sopenharmony_ci    char prefix[NETIF_NAME_PREFIX_MAX_LENGTH] = {0};
823d8536b4Sopenharmony_ci
833d8536b4Sopenharmony_ci    driverif_get_ifname_prefix(netif, prefix, NETIF_NAME_PREFIX_MAX_LENGTH);
843d8536b4Sopenharmony_ci    netif->name[0] = prefix[0];
853d8536b4Sopenharmony_ci    netif->name[1] = prefix[1];
863d8536b4Sopenharmony_ci
873d8536b4Sopenharmony_ci    if (netif->full_name[0] != '\0') {
883d8536b4Sopenharmony_ci        LWIP_DEBUGF(DRIVERIF_DEBUG, ("netif already has fullname %s\n", netif->full_name));
893d8536b4Sopenharmony_ci        return;
903d8536b4Sopenharmony_ci    }
913d8536b4Sopenharmony_ci    for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) {
923d8536b4Sopenharmony_ci        if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1,
933d8536b4Sopenharmony_ci            "%s%d", prefix, i) < 0) {
943d8536b4Sopenharmony_ci            break;
953d8536b4Sopenharmony_ci        }
963d8536b4Sopenharmony_ci        NETIF_FOREACH(tmpnetif) {
973d8536b4Sopenharmony_ci            if (strcmp(tmpnetif->full_name, netif->full_name) == 0) {
983d8536b4Sopenharmony_ci                break;
993d8536b4Sopenharmony_ci            }
1003d8536b4Sopenharmony_ci        }
1013d8536b4Sopenharmony_ci        if (tmpnetif == NULL) {
1023d8536b4Sopenharmony_ci            LWIP_DEBUGF(DRIVERIF_DEBUG, ("set fullname success %s\n", netif->full_name));
1033d8536b4Sopenharmony_ci            return;
1043d8536b4Sopenharmony_ci        }
1053d8536b4Sopenharmony_ci    }
1063d8536b4Sopenharmony_ci    netif->full_name[0] = '\0';
1073d8536b4Sopenharmony_ci}
1083d8536b4Sopenharmony_ci
1093d8536b4Sopenharmony_ci/*
1103d8536b4Sopenharmony_ci * This function should do the actual transmission of the packet. The packet is
1113d8536b4Sopenharmony_ci * contained in the pbuf that is passed to the function. This pbuf
1123d8536b4Sopenharmony_ci * might be chained.
1133d8536b4Sopenharmony_ci *
1143d8536b4Sopenharmony_ci * @param netif the lwip network interface structure for this driverif
1153d8536b4Sopenharmony_ci * @param p the MAC packet to send (e.g. IP packet including MAC_addresses and type)
1163d8536b4Sopenharmony_ci * @return ERR_OK if the packet could be sent
1173d8536b4Sopenharmony_ci *         an err_t value if the packet couldn't be sent
1183d8536b4Sopenharmony_ci *
1193d8536b4Sopenharmony_ci * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
1203d8536b4Sopenharmony_ci *       strange results. You might consider waiting for space in the DMA queue
1213d8536b4Sopenharmony_ci *       to become availale since the stack doesn't retry to send a packet
1223d8536b4Sopenharmony_ci *       dropped because of memory failure (except for the TCP timers).
1233d8536b4Sopenharmony_ci */
1243d8536b4Sopenharmony_ci
1253d8536b4Sopenharmony_ciLWIP_STATIC err_t driverif_output(struct netif *netif, struct pbuf *p)
1263d8536b4Sopenharmony_ci{
1273d8536b4Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_output : send packet pbuf 0x%p of length %"U16_F" through netif 0x%p\n", \
1283d8536b4Sopenharmony_ci        (void *)p, p->tot_len, (void *)netif));
1293d8536b4Sopenharmony_ci
1303d8536b4Sopenharmony_ci#if PF_PKT_SUPPORT
1313d8536b4Sopenharmony_ci    if (all_pkt_raw_pcbs != NULL) {
1323d8536b4Sopenharmony_ci        p->flags = (u16_t)(p->flags & ~(PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST | PBUF_FLAG_HOST));
1333d8536b4Sopenharmony_ci        p->flags |= PBUF_FLAG_OUTGOING;
1343d8536b4Sopenharmony_ci        (void)raw_pkt_input(p, netif, NULL);
1353d8536b4Sopenharmony_ci    }
1363d8536b4Sopenharmony_ci#endif
1373d8536b4Sopenharmony_ci
1383d8536b4Sopenharmony_ci#if ETH_PAD_SIZE
1393d8536b4Sopenharmony_ci    (void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
1403d8536b4Sopenharmony_ci#endif
1413d8536b4Sopenharmony_ci
1423d8536b4Sopenharmony_ci    netif->drv_send(netif, p);
1433d8536b4Sopenharmony_ci
1443d8536b4Sopenharmony_ci#if ETH_PAD_SIZE
1453d8536b4Sopenharmony_ci    (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
1463d8536b4Sopenharmony_ci#endif
1473d8536b4Sopenharmony_ci    MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
1483d8536b4Sopenharmony_ci    LINK_STATS_INC(link.xmit);
1493d8536b4Sopenharmony_ci
1503d8536b4Sopenharmony_ci    return ERR_OK;
1513d8536b4Sopenharmony_ci}
1523d8536b4Sopenharmony_ci
1533d8536b4Sopenharmony_civoid driverif_input_proc(struct netif *netif, struct pbuf *p)
1543d8536b4Sopenharmony_ci{
1553d8536b4Sopenharmony_ci    u16_t ethhdr_type;
1563d8536b4Sopenharmony_ci    struct eth_hdr *ethhdr = NULL;
1573d8536b4Sopenharmony_ci    err_t ret = ERR_VAL;
1583d8536b4Sopenharmony_ci
1593d8536b4Sopenharmony_ci    ethhdr = (struct eth_hdr *)p->payload;
1603d8536b4Sopenharmony_ci    ethhdr_type = ntohs(ethhdr->type);
1613d8536b4Sopenharmony_ci
1623d8536b4Sopenharmony_ci    switch (ethhdr_type) {
1633d8536b4Sopenharmony_ci        /* IP or ARP packet? */
1643d8536b4Sopenharmony_ci        case ETHTYPE_IP:
1653d8536b4Sopenharmony_ci        case ETHTYPE_IPV6:
1663d8536b4Sopenharmony_ci        case ETHTYPE_ARP:
1673d8536b4Sopenharmony_ci#if ETHARP_SUPPORT_VLAN
1683d8536b4Sopenharmony_ci        case ETHTYPE_VLAN:
1693d8536b4Sopenharmony_ci#endif /* ETHARP_SUPPORT_VLAN */
1703d8536b4Sopenharmony_ci            LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F"\n", ethhdr_type));
1713d8536b4Sopenharmony_ci            /* full packet send to tcpip_thread to process */
1723d8536b4Sopenharmony_ci            if (netif->input != NULL) {
1733d8536b4Sopenharmony_ci                ret = netif->input(p, netif);
1743d8536b4Sopenharmony_ci            }
1753d8536b4Sopenharmony_ci
1763d8536b4Sopenharmony_ci            if (ret != ERR_OK) {
1773d8536b4Sopenharmony_ci                LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
1783d8536b4Sopenharmony_ci                (void)pbuf_free(p);
1793d8536b4Sopenharmony_ci                LINK_STATS_INC(link.drop);
1803d8536b4Sopenharmony_ci                LINK_STATS_INC(link.link_rx_drop);
1813d8536b4Sopenharmony_ci                if (ret == ERR_MEM) {
1823d8536b4Sopenharmony_ci                    MIB2_STATS_NETIF_INC(netif, ifinoverruns);
1833d8536b4Sopenharmony_ci                    LINK_STATS_INC(link.link_rx_overrun);
1843d8536b4Sopenharmony_ci                }
1853d8536b4Sopenharmony_ci            } else {
1863d8536b4Sopenharmony_ci                LINK_STATS_INC(link.recv);
1873d8536b4Sopenharmony_ci            }
1883d8536b4Sopenharmony_ci            break;
1893d8536b4Sopenharmony_ci
1903d8536b4Sopenharmony_ci        default:
1913d8536b4Sopenharmony_ci            LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is of unsupported type %"U16_F"\n", \
1923d8536b4Sopenharmony_ci                ethhdr_type));
1933d8536b4Sopenharmony_ci            (void)pbuf_free(p);
1943d8536b4Sopenharmony_ci            LINK_STATS_INC(link.drop);
1953d8536b4Sopenharmony_ci            LINK_STATS_INC(link.link_rx_drop);
1963d8536b4Sopenharmony_ci            break;
1973d8536b4Sopenharmony_ci    }
1983d8536b4Sopenharmony_ci}
1993d8536b4Sopenharmony_ci
2003d8536b4Sopenharmony_ci/*
2013d8536b4Sopenharmony_ci * This function should be called by network driver to pass the input packet to LwIP.
2023d8536b4Sopenharmony_ci * Before calling this API, driver has to keep the packet in pbuf structure. Driver has to
2033d8536b4Sopenharmony_ci * call pbuf_alloc() with type as PBUF_RAM to create pbuf structure. Then driver
2043d8536b4Sopenharmony_ci * has to pass the pbuf structure to this API. This will add the pbuf into the TCPIP thread.
2053d8536b4Sopenharmony_ci * Once this packet is processed by TCPIP thread, pbuf will be freed. Driver is not required to
2063d8536b4Sopenharmony_ci * free the pbuf.
2073d8536b4Sopenharmony_ci *
2083d8536b4Sopenharmony_ci * @param netif the lwip network interface structure for this driverif
2093d8536b4Sopenharmony_ci * @param p packet in pbuf structure format
2103d8536b4Sopenharmony_ci */
2113d8536b4Sopenharmony_civoid driverif_input(struct netif *netif, struct pbuf *p)
2123d8536b4Sopenharmony_ci{
2133d8536b4Sopenharmony_ci#if PF_PKT_SUPPORT
2143d8536b4Sopenharmony_ci#if  (DRIVERIF_DEBUG & LWIP_DBG_OFF)
2153d8536b4Sopenharmony_ci    u16_t ethhdr_type;
2163d8536b4Sopenharmony_ci    struct eth_hdr* ethhdr = NULL;
2173d8536b4Sopenharmony_ci#endif
2183d8536b4Sopenharmony_ci    err_t ret = ERR_VAL;
2193d8536b4Sopenharmony_ci#endif
2203d8536b4Sopenharmony_ci
2213d8536b4Sopenharmony_ci    LWIP_ERROR("driverif_input : invalid arguments", ((netif != NULL) && (p != NULL)), return);
2223d8536b4Sopenharmony_ci
2233d8536b4Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : going to receive input packet. netif 0x%p, pbuf 0x%p, \
2243d8536b4Sopenharmony_ci        packet_length %"U16_F"\n", (void *)netif, (void *)p, p->tot_len));
2253d8536b4Sopenharmony_ci
2263d8536b4Sopenharmony_ci    /* points to packet payload, which starts with an Ethernet header */
2273d8536b4Sopenharmony_ci    MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
2283d8536b4Sopenharmony_ci    if (p->len < SIZEOF_ETH_HDR) {
2293d8536b4Sopenharmony_ci        (void)pbuf_free(p);
2303d8536b4Sopenharmony_ci        LINK_STATS_INC(link.drop);
2313d8536b4Sopenharmony_ci        LINK_STATS_INC(link.link_rx_drop);
2323d8536b4Sopenharmony_ci        return;
2333d8536b4Sopenharmony_ci    }
2343d8536b4Sopenharmony_ci
2353d8536b4Sopenharmony_ci#if PF_PKT_SUPPORT
2363d8536b4Sopenharmony_ci#if  (DRIVERIF_DEBUG & LWIP_DBG_OFF)
2373d8536b4Sopenharmony_ci    ethhdr = (struct eth_hdr *)p->payload;
2383d8536b4Sopenharmony_ci    ethhdr_type = ntohs(ethhdr->type);
2393d8536b4Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F" netif->input=%p\n", \
2403d8536b4Sopenharmony_ci        ethhdr_type, netif->input));
2413d8536b4Sopenharmony_ci#endif
2423d8536b4Sopenharmony_ci
2433d8536b4Sopenharmony_ci    /* full packet send to tcpip_thread to process */
2443d8536b4Sopenharmony_ci    if (netif->input) {
2453d8536b4Sopenharmony_ci        ret = netif->input(p, netif);
2463d8536b4Sopenharmony_ci    }
2473d8536b4Sopenharmony_ci    if (ret != ERR_OK) {
2483d8536b4Sopenharmony_ci        LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
2493d8536b4Sopenharmony_ci        (void)pbuf_free(p);
2503d8536b4Sopenharmony_ci        LINK_STATS_INC(link.drop);
2513d8536b4Sopenharmony_ci        LINK_STATS_INC(link.link_rx_drop);
2523d8536b4Sopenharmony_ci        if (ret == ERR_MEM) {
2533d8536b4Sopenharmony_ci            LINK_STATS_INC(link.link_rx_overrun);
2543d8536b4Sopenharmony_ci        }
2553d8536b4Sopenharmony_ci    } else {
2563d8536b4Sopenharmony_ci        LINK_STATS_INC(link.recv);
2573d8536b4Sopenharmony_ci    }
2583d8536b4Sopenharmony_ci
2593d8536b4Sopenharmony_ci#else
2603d8536b4Sopenharmony_ci    driverif_input_proc(netif, p);
2613d8536b4Sopenharmony_ci#endif
2623d8536b4Sopenharmony_ci
2633d8536b4Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is processed\n"));
2643d8536b4Sopenharmony_ci}
2653d8536b4Sopenharmony_ci
2663d8536b4Sopenharmony_ci/*
2673d8536b4Sopenharmony_ci * Should be called at the beginning of the program to set up the
2683d8536b4Sopenharmony_ci * network interface. It calls the function low_level_init() to do the
2693d8536b4Sopenharmony_ci * actual setup of the hardware.
2703d8536b4Sopenharmony_ci *
2713d8536b4Sopenharmony_ci * This function should be passed as a parameter to netif_add().
2723d8536b4Sopenharmony_ci *
2733d8536b4Sopenharmony_ci * @param netif the lwip network interface structure for this driverif
2743d8536b4Sopenharmony_ci * @return ERR_OK if the loopif is initialized
2753d8536b4Sopenharmony_ci *         ERR_MEM on Allocation Failure
2763d8536b4Sopenharmony_ci *         any other err_t on error
2773d8536b4Sopenharmony_ci */
2783d8536b4Sopenharmony_cierr_t driverif_init(struct netif *netif)
2793d8536b4Sopenharmony_ci{
2803d8536b4Sopenharmony_ci    u16_t link_layer_type;
2813d8536b4Sopenharmony_ci
2823d8536b4Sopenharmony_ci    if (netif == NULL) {
2833d8536b4Sopenharmony_ci        return ERR_IF;
2843d8536b4Sopenharmony_ci    }
2853d8536b4Sopenharmony_ci    link_layer_type = netif->link_layer_type;
2863d8536b4Sopenharmony_ci    LWIP_ERROR("driverif_init : invalid link_layer_type in netif", \
2873d8536b4Sopenharmony_ci        ((link_layer_type == ETHERNET_DRIVER_IF) \
2883d8536b4Sopenharmony_ci        || (link_layer_type == WIFI_DRIVER_IF \
2893d8536b4Sopenharmony_ci        || link_layer_type == BT_PROXY_IF)), \
2903d8536b4Sopenharmony_ci            return ERR_IF);
2913d8536b4Sopenharmony_ci
2923d8536b4Sopenharmony_ci    LWIP_ERROR("driverif_init : netif hardware length is greater than maximum supported", \
2933d8536b4Sopenharmony_ci    (netif->hwaddr_len <= NETIF_MAX_HWADDR_LEN), return ERR_IF);
2943d8536b4Sopenharmony_ci
2953d8536b4Sopenharmony_ci    LWIP_ERROR("driverif_init : drv_send is null", (netif->drv_send != NULL), return ERR_IF);
2963d8536b4Sopenharmony_ci
2973d8536b4Sopenharmony_ci#if LWIP_NETIF_PROMISC
2983d8536b4Sopenharmony_ci    LWIP_ERROR("driverif_init : drv_config is null", (netif->drv_config != NULL), return ERR_IF);
2993d8536b4Sopenharmony_ci#endif
3003d8536b4Sopenharmony_ci
3013d8536b4Sopenharmony_ci#if LWIP_NETIF_HOSTNAME
3023d8536b4Sopenharmony_ci    /* Initialize interface hostname */
3033d8536b4Sopenharmony_ci    netif->hostname = LWIP_NETIF_HOSTNAME_DEFAULT;
3043d8536b4Sopenharmony_ci#endif /* LWIP_NETIF_HOSTNAME */
3053d8536b4Sopenharmony_ci
3063d8536b4Sopenharmony_ci    /*
3073d8536b4Sopenharmony_ci     * Initialize the snmp variables and counters inside the struct netif.
3083d8536b4Sopenharmony_ci     * The last argument should be replaced with your link speed, in units
3093d8536b4Sopenharmony_ci     * of bits per second.
3103d8536b4Sopenharmony_ci     */
3113d8536b4Sopenharmony_ci    NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
3123d8536b4Sopenharmony_ci
3133d8536b4Sopenharmony_ci    netif->output = etharp_output;
3143d8536b4Sopenharmony_ci    netif->linkoutput = driverif_output;
3153d8536b4Sopenharmony_ci
3163d8536b4Sopenharmony_ci    /* init the netif's full name */
3173d8536b4Sopenharmony_ci    driverif_init_ifname(netif);
3183d8536b4Sopenharmony_ci
3193d8536b4Sopenharmony_ci    /* maximum transfer unit */
3203d8536b4Sopenharmony_ci    netif->mtu = IP_FRAG_MAX_MTU;
3213d8536b4Sopenharmony_ci
3223d8536b4Sopenharmony_ci    /* device capabilities */
3233d8536b4Sopenharmony_ci    /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
3243d8536b4Sopenharmony_ci    netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
3253d8536b4Sopenharmony_ci#if DRIVER_STATUS_CHECK
3263d8536b4Sopenharmony_ci        NETIF_FLAG_DRIVER_RDY |
3273d8536b4Sopenharmony_ci#endif
3283d8536b4Sopenharmony_ci#if LWIP_IGMP
3293d8536b4Sopenharmony_ci        NETIF_FLAG_IGMP |
3303d8536b4Sopenharmony_ci#endif
3313d8536b4Sopenharmony_ci
3323d8536b4Sopenharmony_ci        /**
3333d8536b4Sopenharmony_ci        @page RFC-2710 RFC-2710
3343d8536b4Sopenharmony_ci        @par Compliant Sections
3353d8536b4Sopenharmony_ci        Section 5. Node State Transition Diagram
3363d8536b4Sopenharmony_ci        @par Behavior Description
3373d8536b4Sopenharmony_ci        MLD messages are sent for multicast addresses whose scope is 2
3383d8536b4Sopenharmony_ci        (link-local), including Solicited-Node multicast addresses.\n
3393d8536b4Sopenharmony_ci        Behavior:Stack will send MLD6 report /Done to solicited node multicast address
3403d8536b4Sopenharmony_ci        if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled.
3413d8536b4Sopenharmony_ci        */
3423d8536b4Sopenharmony_ci        /* Enable sending MLD report /done for solicited address during neighbour discovery */
3433d8536b4Sopenharmony_ci#if LWIP_IPV6 && LWIP_IPV6_MLD
3443d8536b4Sopenharmony_ci#if LWIP_MLD6_ENABLE_MLD_ON_DAD
3453d8536b4Sopenharmony_ci        NETIF_FLAG_MLD6 |
3463d8536b4Sopenharmony_ci#endif /* LWIP_MLD6_ENABLE_MLD_ON_DAD */
3473d8536b4Sopenharmony_ci#endif
3483d8536b4Sopenharmony_ci        NETIF_FLAG_LINK_UP;
3493d8536b4Sopenharmony_ci
3503d8536b4Sopenharmony_ci#if DRIVER_STATUS_CHECK
3513d8536b4Sopenharmony_ci    netif->waketime = -1;
3523d8536b4Sopenharmony_ci#endif /* DRIVER_STATUS_CHECK */
3533d8536b4Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif));
3543d8536b4Sopenharmony_ci    return ERR_OK;
3553d8536b4Sopenharmony_ci}
356