blob: 05aa63a499d707bdc82ce686a995b5bbe01c7b64 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001#include <dev/class/netif.h>
2#include <kernel/event.h>
3#include <arch/ops.h>
4#include <netif/etharp.h>
5#include <lwip/netif.h>
6#include <lwip/dhcp.h>
7#include <debug.h>
8#include <trace.h>
9#include <assert.h>
10#include <list.h>
11#include <err.h>
12
13#define LOCAL_TRACE 0
14
15struct local_netif {
16 struct netif netif;
17 struct device *dev;
18};
19
20static event_t netif_up_event = EVENT_INITIAL_VALUE(netif_up_event, false, 0);
21static volatile int netif_up_count = 0;
22
23static err_t local_linkoutput(struct netif *netif, struct pbuf *p)
24{
25 LTRACE_ENTRY;
26
27 struct local_netif *nif = containerof(netif, struct local_netif, netif);
28 DEBUG_ASSERT(nif);
29
30 status_t res = class_netif_output(nif->dev, p);
31
32 LTRACE_EXIT;
33
34 switch (res) {
35 case NO_ERROR: return ERR_OK;
36 case ERR_NO_MEMORY: return ERR_MEM;
37 case ERR_TIMED_OUT: return ERR_TIMEOUT;
38 default: return ERR_IF;
39 }
40}
41
42static void local_netif_status(struct netif *netif)
43{
44 struct local_netif *nif = containerof(netif, struct local_netif, netif);
45 DEBUG_ASSERT(nif);
46
47 if (netif->flags & NETIF_FLAG_UP) {
48 TRACEF("netif %c%c ip %u.%u.%u.%u netmask %u.%u.%u.%u gw %u.%u.%u.%u\n",
49 netif->name[0], netif->name[1],
50 ip4_addr1_16(&netif->ip_addr),
51 ip4_addr2_16(&netif->ip_addr),
52 ip4_addr3_16(&netif->ip_addr),
53 ip4_addr4_16(&netif->ip_addr),
54 ip4_addr1_16(&netif->netmask),
55 ip4_addr2_16(&netif->netmask),
56 ip4_addr3_16(&netif->netmask),
57 ip4_addr4_16(&netif->netmask),
58 ip4_addr1_16(&netif->gw),
59 ip4_addr2_16(&netif->gw),
60 ip4_addr3_16(&netif->gw),
61 ip4_addr4_16(&netif->gw));
62
63 if (atomic_add(&netif_up_count, 1) >= 0)
64 event_signal(&netif_up_event, true);
65 } else {
66 if (atomic_add(&netif_up_count, -1) == 1)
67 event_unsignal(&netif_up_event);
68 }
69}
70
71static err_t local_netif_init(struct netif *netif)
72{
73 LTRACE_ENTRY;
74
75 struct local_netif *nif = containerof(netif, struct local_netif, netif);
76 DEBUG_ASSERT(nif);
77
78 netif->linkoutput = local_linkoutput;
79 netif->output = etharp_output;
80
81 netif->hwaddr_len = class_netif_get_hwaddr(nif->dev, netif->hwaddr, sizeof(netif->hwaddr));
82 netif->mtu = class_netif_get_mtu(nif->dev);
83
84 netif->name[0] = 'e';
85 netif->name[1] = 'n';
86 netif->num = 0;
87 netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
88
89 LTRACE_EXIT;
90
91 return ERR_OK;
92}
93
94status_t class_netstack_wait_for_network(lk_time_t timeout)
95{
96 status_t res;
97
98 LTRACE_ENTRY;
99
100 res = event_wait_timeout(&netif_up_event, timeout);
101 LTRACEF("res=%d\n", res);
102
103 LTRACE_EXIT;
104 return res;
105}
106
107status_t class_netif_add(struct device *dev)
108{
109 status_t err;
110 ip_addr_t ipaddr, netmask, gw;
111
112 struct local_netif *nif = malloc(sizeof(struct local_netif));
113 if (!nif)
114 return ERR_NO_MEMORY;
115
116 nif->dev = dev;
117
118 err = class_netif_set_state(dev, (struct netstack_state *) nif);
119 if (err)
120 goto done;
121
122 IP4_ADDR(&gw, 0, 0, 0, 0);
123 IP4_ADDR(&ipaddr, 0, 0, 0, 0);
124 IP4_ADDR(&netmask, 255, 255, 255, 255);
125
126 netif_add(&nif->netif, &ipaddr, &netmask, &gw, nif, local_netif_init, ethernet_input);
127 netif_set_default(&nif->netif);
128 netif_set_status_callback(&nif->netif, local_netif_status);
129 dhcp_start(&nif->netif);
130
131 err = NO_ERROR;
132
133done:
134 return err;
135}
136
137status_t class_netstack_input(struct device *dev, struct netstack_state *state, struct pbuf *p)
138{
139 LTRACE_ENTRY;
140
141 struct local_netif *nif = (struct local_netif *) state;
142 if (!nif)
143 return ERR_INVALID_ARGS;
144
145 if (nif->netif.input(p, &nif->netif) != ERR_OK)
146 pbuf_free(p);
147
148 LTRACE_EXIT;
149
150 return NO_ERROR;
151}
152