123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- #include "hal.h"
- #include "evtimer.h"
- #include "lwipthread.h"
- #include <lwip/opt.h>
- #include <lwip/def.h>
- #include <lwip/mem.h>
- #include <lwip/pbuf.h>
- #include <lwip/sys.h>
- #include <lwip/stats.h>
- #include <lwip/snmp.h>
- #include <lwip/tcpip.h>
- #include <netif/etharp.h>
- #include <lwip/netifapi.h>
- #if LWIP_DHCP
- #include <lwip/dhcp.h>
- #endif
- #if LWIP_AUTOIP
- #include <lwip/autoip.h>
- #endif
- #define PERIODIC_TIMER_ID 1
- #define FRAME_RECEIVED_ID 2
- thread_reference_t lwip_trp = NULL;
- static THD_WORKING_AREA(wa_lwip_thread, LWIP_THREAD_STACK_SIZE);
- static void low_level_init(struct netif *netif) {
-
- netif->hwaddr_len = ETHARP_HWADDR_LEN;
-
- netif->mtu = LWIP_NETIF_MTU;
-
-
- netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
-
- }
- static err_t low_level_output(struct netif *netif, struct pbuf *p) {
- struct pbuf *q;
- MACTransmitDescriptor td;
- (void)netif;
- if (macWaitTransmitDescriptor(ÐD1, &td, TIME_MS2I(LWIP_SEND_TIMEOUT)) != MSG_OK)
- return ERR_TIMEOUT;
- #if ETH_PAD_SIZE
- pbuf_header(p, -ETH_PAD_SIZE);
- #endif
-
- for(q = p; q != NULL; q = q->next)
- macWriteTransmitDescriptor(&td, (uint8_t *)q->payload, (size_t)q->len);
- macReleaseTransmitDescriptor(&td);
- MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
- if (((u8_t*)p->payload)[0] & 1) {
-
- MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
- }
- else {
-
- MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
- }
-
- #if ETH_PAD_SIZE
- pbuf_header(p, ETH_PAD_SIZE);
- #endif
- LINK_STATS_INC(link.xmit);
- return ERR_OK;
- }
- static bool low_level_input(struct netif *netif, struct pbuf **pbuf) {
- MACReceiveDescriptor rd;
- struct pbuf *q;
- u16_t len;
- (void)netif;
- osalDbgAssert(pbuf != NULL, "invalid null pointer");
- if (macWaitReceiveDescriptor(ÐD1, &rd, TIME_IMMEDIATE) != MSG_OK)
- return false;
- len = (u16_t)rd.size;
- #if ETH_PAD_SIZE
- len += ETH_PAD_SIZE;
- #endif
-
- *pbuf = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
- if (*pbuf != NULL) {
- #if ETH_PAD_SIZE
- pbuf_header(pbuf, -ETH_PAD_SIZE);
- #endif
-
- for(q = *pbuf; q != NULL; q = q->next)
- macReadReceiveDescriptor(&rd, (uint8_t *)q->payload, (size_t)q->len);
- macReleaseReceiveDescriptor(&rd);
- MIB2_STATS_NETIF_ADD(netif, ifinoctets, *pbuf->tot_len);
- if (*(uint8_t *)((*pbuf)->payload) & 1) {
-
- MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
- }
- else {
-
- MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
- }
- #if ETH_PAD_SIZE
- pbuf_header(pbuf, ETH_PAD_SIZE);
- #endif
- LINK_STATS_INC(link.recv);
- }
- else {
- macReleaseReceiveDescriptor(&rd);
- LINK_STATS_INC(link.memerr);
- LINK_STATS_INC(link.drop);
- MIB2_STATS_NETIF_INC(netif, ifindiscards);
- }
-
- return true;
- }
- static err_t ethernetif_init(struct netif *netif) {
- osalDbgAssert((netif != NULL), "netif != NULL");
-
- MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LWIP_LINK_SPEED);
- netif->state = NULL;
- netif->name[0] = LWIP_IFNAME0;
- netif->name[1] = LWIP_IFNAME1;
-
- netif->output = etharp_output;
- netif->linkoutput = low_level_output;
-
- low_level_init(netif);
- return ERR_OK;
- }
- static THD_FUNCTION(lwip_thread, p) {
- event_timer_t evt;
- event_listener_t el0, el1;
- ip_addr_t ip, gateway, netmask;
- static struct netif thisif = { 0 };
- static const MACConfig mac_config = {thisif.hwaddr};
- net_addr_mode_t addressMode;
- err_t result;
- chRegSetThreadName(LWIP_THREAD_NAME);
-
- tcpip_init(NULL, NULL);
-
- if (p) {
- struct lwipthread_opts *opts = p;
- unsigned i;
- for (i = 0; i < 6; i++)
- thisif.hwaddr[i] = opts->macaddress[i];
- ip.addr = opts->address;
- gateway.addr = opts->gateway;
- netmask.addr = opts->netmask;
- addressMode = opts->addrMode;
- #if LWIP_NETIF_HOSTNAME
- thisif.hostname = opts->ourHostName;
- #endif
- }
- else {
- thisif.hwaddr[0] = LWIP_ETHADDR_0;
- thisif.hwaddr[1] = LWIP_ETHADDR_1;
- thisif.hwaddr[2] = LWIP_ETHADDR_2;
- thisif.hwaddr[3] = LWIP_ETHADDR_3;
- thisif.hwaddr[4] = LWIP_ETHADDR_4;
- thisif.hwaddr[5] = LWIP_ETHADDR_5;
- LWIP_IPADDR(&ip);
- LWIP_GATEWAY(&gateway);
- LWIP_NETMASK(&netmask);
- addressMode = NET_ADDRESS_STATIC;
- #if LWIP_NETIF_HOSTNAME
- thisif.hostname = NULL;
- #endif
- }
- #if LWIP_NETIF_HOSTNAME
- if (thisif.hostname == NULL)
- thisif.hostname = LWIP_NETIF_HOSTNAME_STRING;
- #endif
- macStart(ÐD1, &mac_config);
-
- result = netifapi_netif_add(&thisif, &ip, &netmask, &gateway, NULL, ethernetif_init, tcpip_input);
- if (result != ERR_OK)
- {
- chThdSleepMilliseconds(1000);
- osalSysHalt("netif_add error");
- };
- netif_set_default(&thisif);
- switch (addressMode)
- {
- #if LWIP_AUTOIP
- case NET_ADDRESS_AUTO:
- autoip_start(&thisif);
- break;
- #endif
- default:
- netif_set_up(&thisif);
- break;
- }
-
- evtObjectInit(&evt, LWIP_LINK_POLL_INTERVAL);
- evtStart(&evt);
- chEvtRegisterMask(&evt.et_es, &el0, PERIODIC_TIMER_ID);
- chEvtRegisterMask(macGetReceiveEventSource(ÐD1), &el1, FRAME_RECEIVED_ID);
- chEvtAddEvents(PERIODIC_TIMER_ID | FRAME_RECEIVED_ID);
-
- chThdResume(&lwip_trp, MSG_OK);
- chThdSetPriority(LWIP_THREAD_PRIORITY);
- while (true) {
- eventmask_t mask = chEvtWaitAny(ALL_EVENTS);
- if (mask & PERIODIC_TIMER_ID) {
- bool current_link_status = macPollLinkStatus(ÐD1);
- if (current_link_status != netif_is_link_up(&thisif)) {
- if (current_link_status) {
- tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up,
- &thisif, 0);
- #if LWIP_DHCP
- if (addressMode == NET_ADDRESS_DHCP)
- dhcp_start(&thisif);
- #endif
- }
- else {
- tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down,
- &thisif, 0);
- #if LWIP_DHCP
- if (addressMode == NET_ADDRESS_DHCP)
- dhcp_stop(&thisif);
- #endif
- }
- }
- }
-
- if (mask & FRAME_RECEIVED_ID) {
- struct pbuf *p;
- while (low_level_input(&thisif, &p)) {
- if (p != NULL) {
- struct eth_hdr *ethhdr = p->payload;
- switch (htons(ethhdr->type)) {
-
- case ETHTYPE_IP:
- case ETHTYPE_ARP:
-
- if (thisif.input(p, &thisif) == ERR_OK)
- break;
- LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
-
- default:
- pbuf_free(p);
- }
- }
- }
- }
- }
- }
- void lwipInit(const lwipthread_opts_t *opts) {
-
- chThdCreateStatic(wa_lwip_thread, sizeof (wa_lwip_thread),
- chThdGetPriorityX() - 1, lwip_thread, (void *)opts);
-
- chSysLock();
- chThdSuspendS(&lwip_trp);
- chSysUnlock();
- }
|