更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
driverif.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <lwip/sys.h>
33#include <lwip/netif.h>
34#include <lwip/snmp.h>
35#include <lwip/etharp.h>
36#include <lwip/sockets.h>
37#include <lwip/ethip6.h>
38
39#define LWIP_NETIF_HOSTNAME_DEFAULT "default"
40#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 100000000 // 100Mbps
41
42#define link_rx_drop cachehit
43#define link_rx_overrun cachehit
44
45#define LWIP_STATIC static
46
47#ifndef LWIP_NETIF_IFINDEX_MAX_EX
48#define LWIP_NETIF_IFINDEX_MAX_EX 255
49#endif
50
51LWIP_STATIC void
52driverif_init_ifname(struct netif *netif)
53{
54 struct netif *tmpnetif = NULL;
55 const char *prefix = (netif->link_layer_type == WIFI_DRIVER_IF) ? "wlan" : "eth";
56
57 netif->name[0] = prefix[0];
58 netif->name[1] = prefix[1];
59
60 for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) {
61 if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1,
62 "%s%d", prefix, i) < 0) {
63 break;
64 }
65 NETIF_FOREACH(tmpnetif) {
66 if (strcmp(tmpnetif->full_name, netif->full_name) == 0) {
67 break;
68 }
69 }
70 if (tmpnetif == NULL) {
71 return;
72 }
73 }
74 netif->full_name[0] = '\0';
75}
76
77/*
78 * This function should do the actual transmission of the packet. The packet is
79 * contained in the pbuf that is passed to the function. This pbuf
80 * might be chained.
81 *
82 * @param netif the lwip network interface structure for this driverif
83 * @param p the MAC packet to send (e.g. IP packet including MAC_addresses and type)
84 * @return ERR_OK if the packet could be sent
85 * an err_t value if the packet couldn't be sent
86 *
87 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
88 * strange results. You might consider waiting for space in the DMA queue
89 * to become available since the stack doesn't retry to send a packet
90 * dropped because of memory failure (except for the TCP timers).
91 */
92
93LWIP_STATIC err_t
94driverif_output(struct netif *netif, struct pbuf *p)
95{
96 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_output : going to send packet pbuf 0x%p of length %"U16_F" through netif 0x%p\n", \
97 (void *)p, p->tot_len, (void *)netif));
98
99#if PF_PKT_SUPPORT
100 if (all_pkt_raw_pcbs != NULL) {
101 p->flags = (u16_t)(p->flags & ~(PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST | PBUF_FLAG_HOST));
102 p->flags |= PBUF_FLAG_OUTGOING;
103 (void)raw_pkt_input(p, netif, NULL);
104 }
105#endif
106
107#if ETH_PAD_SIZE
108 (void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
109#endif
110
111 netif->drv_send(netif, p);
112
113#if ETH_PAD_SIZE
114 (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
115#endif
116 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
117 LINK_STATS_INC(link.xmit);
118
119 return ERR_OK;
120}
121
122/*
123 * This function should be called by network driver to pass the input packet to LwIP.
124 * Before calling this API, driver has to keep the packet in pbuf structure. Driver has to
125 * call pbuf_alloc() with type as PBUF_RAM to create pbuf structure. Then driver
126 * has to pass the pbuf structure to this API. This will add the pbuf into the TCPIP thread.
127 * Once this packet is processed by TCPIP thread, pbuf will be freed. Driver is not required to
128 * free the pbuf.
129 *
130 * @param netif the lwip network interface structure for this driverif
131 * @param p packet in pbuf structure format
132 */
133void
134driverif_input(struct netif *netif, struct pbuf *p)
135{
136#if PF_PKT_SUPPORT
137#if (DRIVERIF_DEBUG & LWIP_DBG_OFF)
138 u16_t ethhdr_type;
139 struct eth_hdr* ethhdr = NULL;
140#endif
141#else
142 u16_t ethhdr_type;
143 struct eth_hdr *ethhdr = NULL;
144#endif
145 err_t ret = ERR_VAL;
146
147 LWIP_ERROR("driverif_input : invalid arguments", ((netif != NULL) && (p != NULL)), return);
148
149 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : going to receive input packet. netif 0x%p, pbuf 0x%p, \
150 packet_length %"U16_F"\n", (void *)netif, (void *)p, p->tot_len));
151
152 /* points to packet payload, which starts with an Ethernet header */
153 MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
154 if (p->len < SIZEOF_ETH_HDR) {
155 (void)pbuf_free(p);
156 LINK_STATS_INC(link.drop);
157 LINK_STATS_INC(link.link_rx_drop);
158 return;
159 }
160
161#if PF_PKT_SUPPORT
162#if (DRIVERIF_DEBUG & LWIP_DBG_OFF)
163 ethhdr = (struct eth_hdr *)p->payload;
164 ethhdr_type = ntohs(ethhdr->type);
165 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F" netif->input=%p\n", ethhdr_type, netif->input));
166#endif
167
168 /* full packet send to tcpip_thread to process */
169 if (netif->input) {
170 ret = netif->input(p, netif);
171 }
172 if (ret != ERR_OK) {
173 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
174 (void)pbuf_free(p);
175 LINK_STATS_INC(link.drop);
176 LINK_STATS_INC(link.link_rx_drop);
177 if (ret == ERR_MEM) {
178 LINK_STATS_INC(link.link_rx_overrun);
179 }
180 } else {
181 LINK_STATS_INC(link.recv);
182 }
183
184#else
185 ethhdr = (struct eth_hdr *)p->payload;
186 ethhdr_type = ntohs(ethhdr->type);
187
188 switch (ethhdr_type) {
189 /* IP or ARP packet? */
190 case ETHTYPE_IP:
191 case ETHTYPE_IPV6:
192 case ETHTYPE_ARP:
193#if ETHARP_SUPPORT_VLAN
194 case ETHTYPE_VLAN:
195#endif /* ETHARP_SUPPORT_VLAN */
196 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F"\n", ethhdr_type));
197 /* full packet send to tcpip_thread to process */
198 if (netif->input != NULL) {
199 ret = netif->input(p, netif);
200 }
201
202 if (ret != ERR_OK) {
203 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
204 (void)pbuf_free(p);
205 LINK_STATS_INC(link.drop);
206 LINK_STATS_INC(link.link_rx_drop);
207 if (ret == ERR_MEM) {
208 MIB2_STATS_NETIF_INC(netif, ifinoverruns);
209 LINK_STATS_INC(link.link_rx_overrun);
210 }
211 } else {
212 LINK_STATS_INC(link.recv);
213 }
214 break;
215
216 default:
217 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is of unsupported type %"U16_F"\n", ethhdr_type));
218 (void)pbuf_free(p);
219 LINK_STATS_INC(link.drop);
220 LINK_STATS_INC(link.link_rx_drop);
221 break;
222 }
223#endif
224
225 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is processed\n"));
226}
227
228/*
229 * Should be called at the beginning of the program to set up the
230 * network interface. It calls the function low_level_init() to do the
231 * actual setup of the hardware.
232 *
233 * This function should be passed as a parameter to netif_add().
234 *
235 * @param netif the lwip network interface structure for this driverif
236 * @return ERR_OK if the loopif is initialized
237 * ERR_MEM on Allocation Failure
238 * any other err_t on error
239 */
240err_t
241driverif_init(struct netif *netif)
242{
243 u16_t link_layer_type;
244
245 if (netif == NULL) {
246 return ERR_IF;
247 }
248 link_layer_type = netif->link_layer_type;
249 LWIP_ERROR("driverif_init : invalid link_layer_type in netif", \
250 ((link_layer_type == ETHERNET_DRIVER_IF) || (link_layer_type == WIFI_DRIVER_IF)), \
251 return ERR_IF);
252
253 LWIP_ERROR("driverif_init : netif hardware length is greater than maximum supported", \
254 (netif->hwaddr_len <= NETIF_MAX_HWADDR_LEN), return ERR_IF);
255
256 LWIP_ERROR("driverif_init : drv_send is null", (netif->drv_send != NULL), return ERR_IF);
257
258#if LWIP_NETIF_PROMISC
259 LWIP_ERROR("driverif_init : drv_config is null", (netif->drv_config != NULL), return ERR_IF);
260#endif
261
262#if LWIP_NETIF_HOSTNAME
263 /* Initialize interface hostname */
264 netif->hostname = LWIP_NETIF_HOSTNAME_DEFAULT;
265#endif /* LWIP_NETIF_HOSTNAME */
266
267 /*
268 * Initialize the snmp variables and counters inside the struct netif.
269 * The last argument should be replaced with your link speed, in units
270 * of bits per second.
271 */
272 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
273
274 netif->output = etharp_output;
275 netif->linkoutput = driverif_output;
276
277 /* init the netif's full name */
279
280 /* maximum transfer unit */
281 netif->mtu = IP_FRAG_MAX_MTU;
282
283 /* device capabilities */
284 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
285 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
286 #if DRIVER_STATUS_CHECK
287 NETIF_FLAG_DRIVER_RDY |
288 #endif
289 #if LWIP_IGMP
290 NETIF_FLAG_IGMP |
291 #endif
292
293 /**
294 @page RFC-2710 RFC-2710
295 @par Compliant Sections
296 Section 5. Node State Transition Diagram
297 @par Behavior Description
298 MLD messages are sent for multicast addresses whose scope is 2
299 (link-local), including Solicited-Node multicast addresses.\n
300 Behavior:Stack will send MLD6 report /Done to solicited node multicast address
301 if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled.
302 */
303 /* Enable sending MLD report /done for solicited address during neighbour discovery */
304 #if LWIP_IPV6 && LWIP_IPV6_MLD
305 #if LWIP_MLD6_ENABLE_MLD_ON_DAD
306 NETIF_FLAG_MLD6 |
307 #endif /* LWIP_MLD6_ENABLE_MLD_ON_DAD */
308 #endif
309 NETIF_FLAG_LINK_UP;
310
311#if DRIVER_STATUS_CHECK
312 netif->waketime = -1;
313#endif /* DRIVER_STATUS_CHECK */
314 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif));
315 return ERR_OK;
316}
void driverif_input(struct netif *netif, struct pbuf *p)
Definition: driverif.c:134
LWIP_STATIC err_t driverif_output(struct netif *netif, struct pbuf *p)
Definition: driverif.c:94
LWIP_STATIC void driverif_init_ifname(struct netif *netif)
Definition: driverif.c:52
err_t driverif_init(struct netif *netif)
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void