User | Revision | Line number | New contents of line |
mbed714 |
0:d616ece2d859
|
1
|
|
mbed714 |
0:d616ece2d859
|
2
|
/*
|
mbed714 |
0:d616ece2d859
|
3
|
Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
|
mbed714 |
0:d616ece2d859
|
4
|
|
mbed714 |
0:d616ece2d859
|
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
mbed714 |
0:d616ece2d859
|
6
|
of this software and associated documentation files (the "Software"), to deal
|
mbed714 |
0:d616ece2d859
|
7
|
in the Software without restriction, including without limitation the rights
|
mbed714 |
0:d616ece2d859
|
8
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
mbed714 |
0:d616ece2d859
|
9
|
copies of the Software, and to permit persons to whom the Software is
|
mbed714 |
0:d616ece2d859
|
10
|
furnished to do so, subject to the following conditions:
|
mbed714 |
0:d616ece2d859
|
11
|
|
mbed714 |
0:d616ece2d859
|
12
|
The above copyright notice and this permission notice shall be included in
|
mbed714 |
0:d616ece2d859
|
13
|
all copies or substantial portions of the Software.
|
mbed714 |
0:d616ece2d859
|
14
|
|
mbed714 |
0:d616ece2d859
|
15
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
mbed714 |
0:d616ece2d859
|
16
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
mbed714 |
0:d616ece2d859
|
17
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
mbed714 |
0:d616ece2d859
|
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
mbed714 |
0:d616ece2d859
|
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
mbed714 |
0:d616ece2d859
|
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
mbed714 |
0:d616ece2d859
|
21
|
THE SOFTWARE.
|
mbed714 |
0:d616ece2d859
|
22
|
*/
|
mbed714 |
0:d616ece2d859
|
23
|
|
mbed714 |
0:d616ece2d859
|
24
|
#include "netCfg.h"
|
mbed714 |
0:d616ece2d859
|
25
|
#if NET_ETH
|
mbed714 |
0:d616ece2d859
|
26
|
|
mbed714 |
0:d616ece2d859
|
27
|
#include "mbed.h"
|
mbed714 |
0:d616ece2d859
|
28
|
|
mbed714 |
0:d616ece2d859
|
29
|
Ethernet *pEth = NULL;
|
mbed714 |
0:d616ece2d859
|
30
|
#ifdef __cplusplus
|
mbed714 |
0:d616ece2d859
|
31
|
extern "C" {
|
mbed714 |
0:d616ece2d859
|
32
|
#endif
|
mbed714 |
0:d616ece2d859
|
33
|
|
mbed714 |
0:d616ece2d859
|
34
|
#include "lwip/opt.h"
|
mbed714 |
0:d616ece2d859
|
35
|
|
mbed714 |
0:d616ece2d859
|
36
|
#include "lwip/def.h"
|
mbed714 |
0:d616ece2d859
|
37
|
#include "lwip/pbuf.h"
|
mbed714 |
0:d616ece2d859
|
38
|
#include "lwip/sys.h"
|
mbed714 |
0:d616ece2d859
|
39
|
#include "lwip/stats.h"
|
mbed714 |
0:d616ece2d859
|
40
|
#include "netif/etharp.h"
|
mbed714 |
0:d616ece2d859
|
41
|
#include "string.h"
|
mbed714 |
0:d616ece2d859
|
42
|
|
mbed714 |
0:d616ece2d859
|
43
|
//#include "eth_drv.h"
|
mbed714 |
0:d616ece2d859
|
44
|
|
mbed714 |
0:d616ece2d859
|
45
|
#define IFNAME0 'E'
|
mbed714 |
0:d616ece2d859
|
46
|
#define IFNAME1 'X'
|
mbed714 |
0:d616ece2d859
|
47
|
|
mbed714 |
0:d616ece2d859
|
48
|
#define min(x,y) (((x)<(y))?(x):(y))
|
mbed714 |
0:d616ece2d859
|
49
|
|
mbed714 |
0:d616ece2d859
|
50
|
struct netif* eth_netif;
|
mbed714 |
0:d616ece2d859
|
51
|
|
mbed714 |
0:d616ece2d859
|
52
|
static err_t eth_output(struct netif *netif, struct pbuf *p) {
|
mbed714 |
0:d616ece2d859
|
53
|
#if ETH_PAD_SIZE
|
mbed714 |
0:d616ece2d859
|
54
|
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
mbed714 |
0:d616ece2d859
|
55
|
#endif
|
mbed714 |
0:d616ece2d859
|
56
|
|
mbed714 |
0:d616ece2d859
|
57
|
do {
|
mbed714 |
0:d616ece2d859
|
58
|
pEth->write((const char *)p->payload, p->len);
|
mbed714 |
0:d616ece2d859
|
59
|
} while((p = p->next)!=NULL);
|
mbed714 |
0:d616ece2d859
|
60
|
|
mbed714 |
0:d616ece2d859
|
61
|
pEth->send();
|
mbed714 |
0:d616ece2d859
|
62
|
|
mbed714 |
0:d616ece2d859
|
63
|
#if ETH_PAD_SIZE
|
mbed714 |
0:d616ece2d859
|
64
|
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
mbed714 |
0:d616ece2d859
|
65
|
#endif
|
mbed714 |
0:d616ece2d859
|
66
|
|
mbed714 |
0:d616ece2d859
|
67
|
LINK_STATS_INC(link.xmit);
|
mbed714 |
0:d616ece2d859
|
68
|
return ERR_OK;
|
mbed714 |
0:d616ece2d859
|
69
|
}
|
mbed714 |
0:d616ece2d859
|
70
|
|
mbed714 |
0:d616ece2d859
|
71
|
/*
|
mbed714 |
0:d616ece2d859
|
72
|
void show(char *buf, int size) {
|
mbed714 |
0:d616ece2d859
|
73
|
printf("Destination: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
|
mbed714 |
0:d616ece2d859
|
74
|
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
|
mbed714 |
0:d616ece2d859
|
75
|
printf("Source: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
|
mbed714 |
0:d616ece2d859
|
76
|
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
|
mbed714 |
0:d616ece2d859
|
77
|
|
mbed714 |
0:d616ece2d859
|
78
|
printf("Type %hd\n", htons((short)buf[12]));
|
mbed714 |
0:d616ece2d859
|
79
|
|
mbed714 |
0:d616ece2d859
|
80
|
// hexview(buf, size);
|
mbed714 |
0:d616ece2d859
|
81
|
}
|
mbed714 |
0:d616ece2d859
|
82
|
*/
|
mbed714 |
0:d616ece2d859
|
83
|
|
mbed714 |
0:d616ece2d859
|
84
|
void eth_poll() {
|
mbed714 |
0:d616ece2d859
|
85
|
struct eth_hdr *ethhdr;
|
mbed714 |
0:d616ece2d859
|
86
|
struct pbuf *frame, *p;
|
mbed714 |
0:d616ece2d859
|
87
|
int len, read;
|
mbed714 |
0:d616ece2d859
|
88
|
|
mbed714 |
0:d616ece2d859
|
89
|
while((len = pEth->receive()) != 0) {
|
mbed714 |
0:d616ece2d859
|
90
|
frame = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
mbed714 |
0:d616ece2d859
|
91
|
if(frame == NULL) {
|
mbed714 |
0:d616ece2d859
|
92
|
return;
|
mbed714 |
0:d616ece2d859
|
93
|
}
|
mbed714 |
0:d616ece2d859
|
94
|
p = frame;
|
mbed714 |
0:d616ece2d859
|
95
|
/* no packet could be read, silently ignore this */
|
mbed714 |
0:d616ece2d859
|
96
|
if (p == NULL) return;
|
mbed714 |
0:d616ece2d859
|
97
|
do {
|
mbed714 |
0:d616ece2d859
|
98
|
read = pEth->read((char *)p->payload, p->len);
|
mbed714 |
0:d616ece2d859
|
99
|
p = p->next;
|
mbed714 |
0:d616ece2d859
|
100
|
} while(p != NULL && read != 0);
|
mbed714 |
0:d616ece2d859
|
101
|
|
mbed714 |
0:d616ece2d859
|
102
|
#if ETH_PAD_SIZE
|
mbed714 |
0:d616ece2d859
|
103
|
pbuf_header(p, ETH_PAD_SIZE);
|
mbed714 |
0:d616ece2d859
|
104
|
#endif
|
mbed714 |
0:d616ece2d859
|
105
|
|
mbed714 |
0:d616ece2d859
|
106
|
ethhdr = (struct eth_hdr *)(frame->payload);
|
mbed714 |
0:d616ece2d859
|
107
|
|
mbed714 |
0:d616ece2d859
|
108
|
// show((char*)ethhdr, 13);
|
mbed714 |
0:d616ece2d859
|
109
|
|
mbed714 |
0:d616ece2d859
|
110
|
/*
|
mbed714 |
0:d616ece2d859
|
111
|
switch(htons(ethhdr->type)) {
|
mbed714 |
0:d616ece2d859
|
112
|
|
mbed714 |
0:d616ece2d859
|
113
|
case ETHTYPE_IP:
|
mbed714 |
0:d616ece2d859
|
114
|
etharp_ip_input(gnetif, frame);
|
mbed714 |
0:d616ece2d859
|
115
|
pbuf_header(frame, -((s16_t) sizeof(struct eth_hdr)));
|
mbed714 |
0:d616ece2d859
|
116
|
gnetif->input(frame, gnetif);
|
mbed714 |
0:d616ece2d859
|
117
|
break;
|
mbed714 |
0:d616ece2d859
|
118
|
|
mbed714 |
0:d616ece2d859
|
119
|
case ETHTYPE_ARP:
|
mbed714 |
0:d616ece2d859
|
120
|
etharp_arp_input(gnetif, (struct eth_addr *)(gnetif->hwaddr), frame);
|
mbed714 |
0:d616ece2d859
|
121
|
break;
|
mbed714 |
0:d616ece2d859
|
122
|
|
mbed714 |
0:d616ece2d859
|
123
|
default:
|
mbed714 |
0:d616ece2d859
|
124
|
break;
|
mbed714 |
0:d616ece2d859
|
125
|
}*/
|
mbed714 |
0:d616ece2d859
|
126
|
|
mbed714 |
0:d616ece2d859
|
127
|
|
mbed714 |
0:d616ece2d859
|
128
|
|
mbed714 |
0:d616ece2d859
|
129
|
//ethernet_input(frame, gnetif);
|
mbed714 |
0:d616ece2d859
|
130
|
|
mbed714 |
0:d616ece2d859
|
131
|
switch (htons(ethhdr->type)) {
|
mbed714 |
0:d616ece2d859
|
132
|
/* IP or ARP packet? */
|
mbed714 |
0:d616ece2d859
|
133
|
case ETHTYPE_IP:
|
mbed714 |
0:d616ece2d859
|
134
|
case ETHTYPE_ARP:
|
mbed714 |
0:d616ece2d859
|
135
|
#if PPPOE_SUPPORT
|
mbed714 |
0:d616ece2d859
|
136
|
/* PPPoE packet? */
|
mbed714 |
0:d616ece2d859
|
137
|
case ETHTYPE_PPPOEDISC:
|
mbed714 |
0:d616ece2d859
|
138
|
case ETHTYPE_PPPOE:
|
mbed714 |
0:d616ece2d859
|
139
|
#endif /* PPPOE_SUPPORT */
|
mbed714 |
0:d616ece2d859
|
140
|
/* full packet send to tcpip_thread to process */
|
mbed714 |
0:d616ece2d859
|
141
|
//if (netif->input(p, gnetif)!=ERR_OK)
|
mbed714 |
0:d616ece2d859
|
142
|
if (ethernet_input(frame, eth_netif)!=ERR_OK)
|
mbed714 |
0:d616ece2d859
|
143
|
{ LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
mbed714 |
0:d616ece2d859
|
144
|
pbuf_free(frame);
|
mbed714 |
0:d616ece2d859
|
145
|
frame = NULL;
|
mbed714 |
0:d616ece2d859
|
146
|
}
|
mbed714 |
0:d616ece2d859
|
147
|
break;
|
mbed714 |
0:d616ece2d859
|
148
|
|
mbed714 |
0:d616ece2d859
|
149
|
default:
|
mbed714 |
0:d616ece2d859
|
150
|
pbuf_free(frame);
|
mbed714 |
0:d616ece2d859
|
151
|
frame = NULL;
|
mbed714 |
0:d616ece2d859
|
152
|
break;
|
mbed714 |
0:d616ece2d859
|
153
|
}
|
mbed714 |
0:d616ece2d859
|
154
|
|
mbed714 |
0:d616ece2d859
|
155
|
/* pbuf_free(frame); */
|
mbed714 |
0:d616ece2d859
|
156
|
}
|
mbed714 |
0:d616ece2d859
|
157
|
|
mbed714 |
0:d616ece2d859
|
158
|
|
mbed714 |
0:d616ece2d859
|
159
|
|
mbed714 |
0:d616ece2d859
|
160
|
|
mbed714 |
0:d616ece2d859
|
161
|
}
|
mbed714 |
0:d616ece2d859
|
162
|
|
mbed714 |
0:d616ece2d859
|
163
|
err_t eth_init(struct netif *netif) {
|
mbed714 |
0:d616ece2d859
|
164
|
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
mbed714 |
0:d616ece2d859
|
165
|
|
mbed714 |
0:d616ece2d859
|
166
|
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 0x2EA);
|
mbed714 |
0:d616ece2d859
|
167
|
|
mbed714 |
0:d616ece2d859
|
168
|
/* maximum transfer unit */
|
mbed714 |
0:d616ece2d859
|
169
|
netif->mtu = 0x2EA;
|
mbed714 |
0:d616ece2d859
|
170
|
|
mbed714 |
0:d616ece2d859
|
171
|
/* device capabilities */
|
mbed714 |
0:d616ece2d859
|
172
|
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
mbed714 |
0:d616ece2d859
|
173
|
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;
|
mbed714 |
0:d616ece2d859
|
174
|
|
mbed714 |
0:d616ece2d859
|
175
|
netif->state = NULL;
|
mbed714 |
0:d616ece2d859
|
176
|
eth_netif = netif;
|
mbed714 |
0:d616ece2d859
|
177
|
|
mbed714 |
0:d616ece2d859
|
178
|
netif->name[0] = IFNAME0;
|
mbed714 |
0:d616ece2d859
|
179
|
netif->name[1] = IFNAME1;
|
mbed714 |
0:d616ece2d859
|
180
|
|
mbed714 |
0:d616ece2d859
|
181
|
/* We directly use etharp_output() here to save a function call.
|
mbed714 |
0:d616ece2d859
|
182
|
* You can instead declare your own function an call etharp_output()
|
mbed714 |
0:d616ece2d859
|
183
|
* from it if you have to do some checks before sending (e.g. if link
|
mbed714 |
0:d616ece2d859
|
184
|
* is available...) */
|
mbed714 |
0:d616ece2d859
|
185
|
netif->output = etharp_output;
|
mbed714 |
0:d616ece2d859
|
186
|
netif->linkoutput = eth_output;
|
mbed714 |
0:d616ece2d859
|
187
|
|
mbed714 |
0:d616ece2d859
|
188
|
pEth = new Ethernet();
|
mbed714 |
0:d616ece2d859
|
189
|
|
mbed714 |
0:d616ece2d859
|
190
|
return ERR_OK;
|
mbed714 |
0:d616ece2d859
|
191
|
}
|
mbed714 |
0:d616ece2d859
|
192
|
|
mbed714 |
0:d616ece2d859
|
193
|
void eth_free()
|
mbed714 |
0:d616ece2d859
|
194
|
{
|
mbed714 |
0:d616ece2d859
|
195
|
if(pEth)
|
mbed714 |
0:d616ece2d859
|
196
|
delete pEth;
|
mbed714 |
0:d616ece2d859
|
197
|
pEth = NULL;
|
mbed714 |
0:d616ece2d859
|
198
|
}
|
mbed714 |
0:d616ece2d859
|
199
|
|
mbed714 |
0:d616ece2d859
|
200
|
void eth_address(char* mac) {
|
mbed714 |
0:d616ece2d859
|
201
|
pEth->address(mac);
|
mbed714 |
0:d616ece2d859
|
202
|
}
|
mbed714 |
0:d616ece2d859
|
203
|
|
mbed714 |
0:d616ece2d859
|
204
|
#ifdef __cplusplus
|
mbed714 |
0:d616ece2d859
|
205
|
};
|
mbed714 |
0:d616ece2d859
|
206
|
#endif
|
mbed714 |
0:d616ece2d859
|
207
|
|
mbed714 |
0:d616ece2d859
|
208
|
#endif
|