1 void eth_mac_irq()
2 {
3   /* Service MAC IRQ here */
4 
5   /* Allocate pbuf from pool (avoid using heap in interrupts) */
6   struct pbuf* p = pbuf_alloc(PBUF_RAW, eth_data_count, PBUF_POOL);
7 
8   if(p != NULL) {
9     /* Copy ethernet frame into pbuf */
10     pbuf_take(p, eth_data, eth_data_count);
11 
12     /* Put in a queue which is processed in main loop */
13     if(!queue_try_put(&queue, p)) {
14       /* queue is full -> packet loss */
15       pbuf_free(p);
16     }
17   }
18 }
19 
20 static err_t netif_output(struct netif *netif, struct pbuf *p)
21 {
22   LINK_STATS_INC(link.xmit);
23 
24   /* Update SNMP stats (only if you use SNMP) */
25   MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
26   int unicast = ((p->payload[0] & 0x01) == 0);
27   if (unicast) {
28     MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
29   } else {
30     MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
31   }
32 
33   lock_interrupts();
34   pbuf_copy_partial(p, mac_send_buffer, p->tot_len, 0);
35   /* Start MAC transmit here */
36   unlock_interrupts();
37 
38   return ERR_OK;
39 }
40 
41 static void netif_status_callback(struct netif *netif)
42 {
43   printf("netif status changed %s\n", ip4addr_ntoa(netif_ip4_addr(netif)));
44 }
45 
46 static err_t netif_init(struct netif *netif)
47 {
48   netif->linkoutput = netif_output;
49   netif->output     = etharp_output;
50   netif->output_ip6 = ethip6_output;
51   netif->mtu        = ETHERNET_MTU;
52   netif->flags      = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
53   MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 100000000);
54 
55   SMEMCPY(netif->hwaddr, your_mac_address_goes_here, sizeof(netif->hwaddr));
56   netif->hwaddr_len = sizeof(netif->hwaddr);
57 
58   return ERR_OK;
59 }
60 
61 void main(void)
62 {
63   struct netif netif;
64 
65   lwip_init();
66 
67   netif_add(&netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY, NULL, netif_init, netif_input);
68   netif.name[0] = 'e';
69   netif.name[1] = '0';
70   netif_create_ip6_linklocal_address(&netif, 1);
71   netif.ip6_autoconfig_enabled = 1;
72   netif_set_status_callback(&netif, netif_status_callback);
73   netif_set_default(&netif);
74   netif_set_up(&netif);
75 
76   /* Start DHCP and HTTPD */
77   dhcp_init();
78   httpd_init();
79 
80   while(1) {
81     /* Check link state, e.g. via MDIO communication with PHY */
82     if(link_state_changed()) {
83       if(link_is_up()) {
84         netif_set_link_up(&netif);
85       } else {
86         netif_set_link_down(&netif);
87       }
88     }
89 
90     /* Check for received frames, feed them to lwIP */
91     lock_interrupts();
92     struct pbuf* p = queue_try_get(&queue);
93     unlock_interrupts();
94 
95     if(p != NULL) {
96       LINK_STATS_INC(link.recv);
97 
98       /* Update SNMP stats (only if you use SNMP) */
99       MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
100       int unicast = ((p->payload[0] & 0x01) == 0);
101       if (unicast) {
102         MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
103       } else {
104         MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
105       }
106 
107       if(netif.input(p, &netif) != ERR_OK) {
108         pbuf_free(p);
109       }
110     }
111 
112     /* Cyclic lwIP timers check */
113     sys_check_timeouts();
114 
115     /* your application goes here */
116   }
117 }
118