Warning, cross-references for /kernel/drivers/net/ethernetif.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 #include "lwip/init.h"
0053 #include "lwip/opt.h"
0054 #include "lwip/def.h"
0055 #include "lwip/mem.h"
0056 #include "lwip/pbuf.h"
0057 #include "lwip/sys.h"
0058 #include "lwip/netif.h"
0059 #include "lwip/udp.h"
0060 #include "lwip/tcp.h"
0061 #include "lwip/dhcp.h"
0062 #include <lwip/stats.h>
0063 #include <lwip/snmp.h>
0064 #include "netif/etharp.h"
0065 #include "netif/ppp_oe.h"
0066
0067 #include "types.h"
0068 #include "string.h"
0069 #include "drivers/net/ethernet.h"
0070 #include "util/debug.h"
0071 #include "util/printf.h"
0072 #include "util/circular.h"
0073 #include "sched/sched.h"
0074 #include "module/header.h"
0075 #include "kernel.h"
0076
0077
0078
0079 #ifdef DEBUG_NETIF
0080 #define DLOG(fmt,...) DLOG_PREFIX("netif",fmt,##__VA_ARGS__)
0081 #else
0082 #define DLOG(fmt,...) ;
0083 #endif
0084
0085
0086 #define IFNAME0 'e'
0087 #define IFNAME1 'n'
0088
0089
0090
0091
0092
0093
0094
0095 struct ethernetif {
0096
0097 uint8* cur_buf;
0098 uint cur_len;
0099 ethernet_device *dev;
0100 };
0101
0102
0103 static void ethernetif_input(struct netif *netif);
0104
0105
0106
0107
0108
0109
0110
0111
0112 static void
0113 low_level_init(struct netif *netif)
0114 {
0115 struct ethernetif *ethernetif = netif->state;
0116
0117 netif->hwaddr_len = ETHARP_HWADDR_LEN;
0118
0119 ethernetif->dev->get_hwaddr_func (netif->hwaddr);
0120
0121
0122 netif->mtu = 1500;
0123
0124
0125
0126 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
0127 }
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 static err_t
0146 low_level_output(struct netif *netif, struct pbuf *p)
0147 {
0148 struct ethernetif *ethernetif = netif->state;
0149 struct pbuf *q;
0150 uint8 buffer[MAX_FRAME_SIZE], *ptr;
0151
0152 #if ETH_PAD_SIZE
0153 pbuf_header(p, -ETH_PAD_SIZE);
0154 #endif
0155
0156 ptr = buffer;
0157 for(q = p; q != NULL; q = q->next) {
0158
0159
0160
0161 memcpy(ptr, q->payload, q->len);
0162 ptr += q->len;
0163 }
0164
0165 if (ethernetif->dev->send_func (buffer, p->tot_len) != p->tot_len)
0166 return ERR_BUF;
0167
0168 #if ETH_PAD_SIZE
0169 pbuf_header(p, ETH_PAD_SIZE);
0170 #endif
0171
0172 LINK_STATS_INC(link.xmit);
0173
0174 return ERR_OK;
0175 }
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 static struct pbuf *
0186 low_level_input(struct netif *netif)
0187 {
0188 struct ethernetif *ethernetif = netif->state;
0189 struct pbuf *p, *q;
0190 uint8 *buffer;
0191 uint len, start;
0192
0193 len = ethernetif->cur_len;
0194 buffer = ethernetif->cur_buf;
0195
0196 #if ETH_PAD_SIZE
0197 len += ETH_PAD_SIZE;
0198 #endif
0199
0200
0201 p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
0202
0203 if (p != NULL) {
0204
0205 #if ETH_PAD_SIZE
0206 pbuf_header(p, -ETH_PAD_SIZE);
0207 #endif
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 start=0;
0219 for (q = p; q != NULL; q = q->next) {
0220
0221
0222
0223
0224 memcpy(q->payload, (uint8 *)&buffer[start], q->len);
0225 start += q->len;
0226 len -= q->len;
0227 if (len<=0) {
0228 break;
0229 }
0230
0231 }
0232
0233 #if ETH_PAD_SIZE
0234 pbuf_header(p, ETH_PAD_SIZE);
0235 #endif
0236
0237 LINK_STATS_INC(link.recv);
0238 } else {
0239 LINK_STATS_INC(link.memerr);
0240 LINK_STATS_INC(link.drop);
0241 }
0242
0243 return p;
0244 }
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 static void
0256 ethernetif_input(struct netif *netif)
0257 {
0258
0259 struct eth_hdr *ethhdr;
0260 struct pbuf *p = low_level_input (netif);
0261
0262 if (!p) return;
0263
0264
0265
0266 ethhdr = (struct eth_hdr*) (p->payload);
0267
0268 switch (htons(ethhdr->type)) {
0269
0270 case ETHTYPE_IP:
0271 case ETHTYPE_ARP:
0272
0273 if (netif->input(p, netif)!=ERR_OK) {
0274 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
0275 pbuf_free(p);
0276 p = NULL;
0277 }
0278 break;
0279
0280 default:
0281 logger_printf("ethernetif_input: unknown type %d\n", htons (ethhdr->type));
0282 pbuf_free(p);
0283 p = NULL;
0284 break;
0285 }
0286
0287 }
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 err_t
0302 ethernetif_init(struct netif *netif)
0303 {
0304 struct ethernetif *ethernetif = netif->state;
0305
0306 LWIP_ASSERT("netif != NULL", (netif != NULL));
0307
0308 #if LWIP_NETIF_HOSTNAME
0309
0310 netif->hostname = "lwip";
0311 #endif
0312
0313
0314
0315
0316
0317
0318 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
0319
0320 netif->name[0] = IFNAME0;
0321 netif->name[1] = IFNAME1;
0322 netif->num = ethernetif->dev->num;
0323
0324
0325
0326
0327 netif->output = etharp_output;
0328 netif->linkoutput = low_level_output;
0329
0330
0331
0332
0333 low_level_init(netif);
0334
0335 return ERR_OK;
0336 }
0337
0338 static void
0339 dispatch(ethernet_device *dev, uint8* buf, sint len)
0340 {
0341 struct ethernetif *ethernetif = dev->netif.state;
0342 ethernetif->cur_buf = buf;
0343 ethernetif->cur_len = len;
0344 ethernetif_input (&dev->netif);
0345 }
0346
0347
0348
0349
0350
0351 static void
0352 echo_close (struct tcp_pcb* pcb)
0353 {
0354 tcp_close (pcb);
0355 }
0356
0357 static err_t
0358 echo_sent (void* arg, struct tcp_pcb* pcb, u16_t len)
0359 {
0360 DLOG ("echo_sent (%p, %p, %p)", arg, pcb, len);
0361 return ERR_OK;
0362 }
0363
0364 static err_t
0365 echo_send (struct tcp_pcb* pcb, struct pbuf* p)
0366 {
0367 err_t wr_err = ERR_OK;
0368 struct pbuf* q;
0369 u16_t plen;
0370
0371 while (wr_err == ERR_OK &&
0372 p != NULL &&
0373 p->len <= tcp_sndbuf (pcb)) {
0374 q = p;
0375 wr_err = tcp_write (pcb, p->payload, p->len, 1);
0376 if (wr_err == ERR_OK) {
0377 plen = p->len;
0378 p = p->next;
0379 if (p)
0380 pbuf_ref (p);
0381 while (pbuf_free (q) == 0);
0382 tcp_recved (pcb, plen);
0383 }
0384 }
0385 return ERR_OK;
0386 }
0387
0388 static err_t
0389 echo_recv (void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
0390 {
0391 err_t ret_err = ERR_OK;
0392 DLOG ("echo_recv (%p, %p, %p, %p)", arg, pcb, p, err);
0393 if (p == NULL) {
0394 if (p) pbuf_free (p);
0395 echo_close (pcb);
0396 } else if (err != ERR_OK) {
0397 if (p) pbuf_free (p);
0398 } else {
0399 tcp_sent(pcb, echo_sent);
0400 echo_send(pcb, p);
0401 ret_err = ERR_OK;
0402 }
0403 return ret_err;
0404 }
0405
0406 static err_t
0407 echo_accept (void* arg, struct tcp_pcb* pcb, err_t err)
0408 {
0409 DLOG ("echo_accept (%p, (%p, %d, %d), %p)",
0410 arg, pcb, pcb->local_port, pcb->remote_port, err);
0411 tcp_accepted (pcb);
0412 tcp_recv (pcb, echo_recv);
0413
0414 return ERR_OK;
0415 }
0416
0417 static void
0418 echo_init (void)
0419 {
0420 struct tcp_pcb* echo_pcb = tcp_new ();
0421 tcp_bind (echo_pcb, IP_ADDR_ANY, 7);
0422 echo_pcb = tcp_listen (echo_pcb);
0423 tcp_accept (echo_pcb, echo_accept);
0424 }
0425
0426
0427
0428
0429
0430 #define KHTTPD_CPU 2
0431 #define KHTTPD_BUF_LEN 8
0432 #define KHTTPD_STR_SIZ 256
0433 typedef struct {
0434 struct tcp_pcb *pcb;
0435 u32 len;
0436 s8 str[KHTTPD_STR_SIZ];
0437 } khttpd_msg_t;
0438 khttpd_msg_t khttpd_circ_buf[KHTTPD_BUF_LEN];
0439 circular khttpd_circ;
0440
0441 static void
0442 khttpd_close (struct tcp_pcb* pcb)
0443 {
0444 tcp_close (pcb);
0445 }
0446
0447 static err_t
0448 khttpd_sent (void* arg, struct tcp_pcb* pcb, u16_t len)
0449 {
0450 DLOG ("khttpd_sent (%p, %p, %p)", arg, pcb, len);
0451 tcp_close (pcb);
0452 return ERR_OK;
0453 }
0454
0455 static err_t
0456 khttpd_recv (void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
0457 {
0458 struct pbuf *q;
0459 u16 plen;
0460 err_t ret_err = ERR_OK;
0461 khttpd_msg_t msg;
0462
0463 DLOG ("khttpd_recv (%p, %p, %p, %p)", arg, pcb, p, err);
0464 if (p == NULL) {
0465 if (p) pbuf_free (p);
0466 khttpd_close (pcb);
0467 } else if (err != ERR_OK) {
0468 if (p) pbuf_free (p);
0469 } else {
0470 while (p != NULL) {
0471 s8 *s = p->payload;
0472 q = p;
0473 plen = p->len;
0474
0475 do {
0476 u16 curlen = plen > KHTTPD_STR_SIZ ? KHTTPD_STR_SIZ : plen;
0477 memset (msg.str, 0, KHTTPD_STR_SIZ);
0478 memcpy (msg.str, s, curlen);
0479 msg.pcb = pcb;
0480 msg.len = curlen;
0481 circular_insert (&khttpd_circ, &msg);
0482 plen -= curlen;
0483 s += curlen;
0484 } while (plen > 0);
0485
0486 p = p->next;
0487 if (p)
0488 pbuf_ref (p);
0489 while (pbuf_free (q) == 0);
0490 tcp_recved (pcb, plen);
0491 }
0492 ret_err = ERR_OK;
0493 }
0494 return ret_err;
0495 }
0496
0497 static err_t
0498 khttpd_accept (void* arg, struct tcp_pcb* pcb, err_t err)
0499 {
0500 DLOG ("khttpd_accept (%p, (%p, %d, %d), %p)",
0501 arg, pcb, pcb->local_port, pcb->remote_port, err);
0502 tcp_accepted (pcb);
0503 tcp_recv (pcb, khttpd_recv);
0504
0505 return ERR_OK;
0506 }
0507
0508 static task_id khttpd_id;
0509 static u32 khttpd_stack[1024] ALIGNED (0x1000);
0510 static void
0511 khttpd_thread (void)
0512 {
0513 logger_printf ("khttpd_thread: hello from 0x%x\n", str ());
0514 for (;;) {
0515 khttpd_msg_t msg;
0516 circular_remove (&khttpd_circ, &msg);
0517 tcp_sent(msg.pcb, khttpd_sent);
0518
0519 #define send(s) tcp_write (msg.pcb, s, strlen ((const char *) s), 1)
0520 send ("HTTP/1.0 200 OK\r\n"
0521 "Server: Quest\r\n"
0522 "Content-Type: text/html\r\n"
0523 "\r\n"
0524 "<html><head><title>The Quest OS</title></head>"
0525 "<body><p>Hello World!</p></body></html>\r\n");
0526 #undef send
0527 }
0528 }
0529
0530 static void
0531 khttpd_init (void)
0532 {
0533 circular_init (&khttpd_circ,
0534 (void *) khttpd_circ_buf,
0535 KHTTPD_BUF_LEN,
0536 KHTTPD_STR_SIZ);
0537
0538 khttpd_id =
0539 start_kernel_thread ((u32) khttpd_thread, (u32) &khttpd_stack[1023]);
0540 lookup_TSS (khttpd_id)->cpu = KHTTPD_CPU;
0541 struct tcp_pcb* khttpd_pcb = tcp_new ();
0542 tcp_bind (khttpd_pcb, IP_ADDR_ANY, 80);
0543 khttpd_pcb = tcp_listen (khttpd_pcb);
0544 tcp_accept (khttpd_pcb, khttpd_accept);
0545 }
0546
0547
0548
0549
0550
0551 #ifdef GDBSTUB_TCP
0552 static struct tcp_pcb* debug_client = NULL;
0553 static char debug_buffer[GDBSTUB_BUFFER_SIZE];
0554 static uint debug_ins_pt=0;
0555 static uint debug_buf_cnt=0;
0556 static uint debug_send_cnt=0;
0557 static struct netif* debug_netif = NULL;
0558
0559 bool break_requested = FALSE;
0560
0561
0562 static err_t
0563 debug_recv (void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
0564 {
0565 struct pbuf* q;
0566 int i;
0567
0568 if (p == NULL) {
0569 _printf ("GDBstub disconnected\n");
0570
0571 tcp_close (debug_client);
0572 debug_client = NULL;
0573 debug_ins_pt = debug_buf_cnt = 0;
0574 debug_send_cnt = 0;
0575 return ERR_OK;
0576 }
0577
0578 if (p->payload && *((char *)p->payload) == 3) {
0579
0580 q = p; p = p->next;
0581 if (p) pbuf_ref (p);
0582 while (q->ref > 0) pbuf_free (q);
0583 break_requested = TRUE;
0584 }
0585
0586
0587 while (p != NULL &&
0588 p->payload != NULL &&
0589 debug_buf_cnt < GDBSTUB_BUFFER_SIZE) {
0590 q = p;
0591 for (i=0; i<p->len;
0592 i++, debug_ins_pt=(debug_ins_pt+1)%GDBSTUB_BUFFER_SIZE)
0593 debug_buffer[debug_ins_pt] = ((char *)p->payload)[i];
0594 p = p->next;
0595 if (p) pbuf_ref (p);
0596 while (q->ref > 0) pbuf_free (q);
0597 tcp_recved (pcb, i);
0598 debug_buf_cnt += i;
0599 }
0600
0601 return ERR_OK;
0602 }
0603
0604
0605 static err_t
0606 debug_sent (void* arg, struct tcp_pcb* pcb, u16_t len)
0607 {
0608 if (debug_send_cnt > 0)
0609 debug_send_cnt--;
0610 return ERR_OK;
0611 }
0612
0613 #endif
0614
0615
0616 static err_t
0617 debug_accept (void* arg, struct tcp_pcb* pcb, err_t err)
0618 {
0619 #ifdef GDBSTUB_TCP
0620 void set_debug_traps (void);
0621
0622 tcp_accepted (pcb);
0623 tcp_recv (pcb, debug_recv);
0624 tcp_sent (pcb, debug_sent);
0625 debug_client = pcb;
0626 debug_netif = netif_find (GDBSTUB_ETHDEV);
0627 if (!debug_netif) return ERR_ARG;
0628 _printf ("Accepted GDBstub TCP client\n");
0629 set_debug_traps ();
0630 BREAKPOINT ();
0631 return ERR_OK;
0632 #else
0633 return ERR_ARG;
0634 #endif
0635 }
0636
0637 #ifdef GDBSTUB_TCP
0638
0639
0640 static void
0641 debug_poll (void)
0642 {
0643 struct ethernetif* ethernetif;
0644 ethernetif = debug_netif->state;
0645
0646
0647 ethernetif->dev->poll_func ();
0648
0649 tcp_tmr ();
0650 etharp_tmr ();
0651 }
0652
0653
0654 void
0655 putDebugChar (int c)
0656 {
0657 char buf[2]; buf[0] = c; buf[1] = 0;
0658
0659 if (!debug_netif) return;
0660
0661 if (debug_client) {
0662 while (tcp_write (debug_client, buf, 1, 1) != ERR_OK) {
0663 debug_poll ();
0664 }
0665 debug_send_cnt++;
0666
0667 while (debug_send_cnt > 0) {
0668 debug_poll ();
0669 }
0670 }
0671 }
0672
0673 int
0674 getDebugChar (void)
0675 {
0676 sint i;
0677
0678 if (!debug_netif) return 0;
0679
0680 while (debug_buf_cnt == 0) {
0681 debug_poll ();
0682 }
0683 i = debug_ins_pt - debug_buf_cnt;
0684 i %= GDBSTUB_BUFFER_SIZE;
0685 debug_buf_cnt--;
0686 return debug_buffer[i];
0687 }
0688 #endif
0689
0690
0691
0692
0693
0694 static task_id net_tmr_pid;
0695 static uint32 net_tmr_stack[1024] ALIGNED (0x1000);
0696
0697 #define NET_TMR_THREAD_WAIT_MSEC 50
0698
0699 static void
0700 net_tmr_thread (void)
0701 {
0702 DLOG ("net_tmr_thread id=0x%x", str ());
0703 for (;;) {
0704 void net_tmr_process (void);
0705 net_tmr_process ();
0706 sched_usleep (NET_TMR_THREAD_WAIT_MSEC * 1000);
0707 }
0708 }
0709
0710 bool
0711 net_init(void)
0712 {
0713 lwip_init ();
0714 echo_init ();
0715 khttpd_init ();
0716
0717 net_tmr_pid = start_kernel_thread ((uint) net_tmr_thread,
0718 (uint) &net_tmr_stack[1023]);
0719 uint select_iovcpu (u32);
0720 lookup_TSS (net_tmr_pid)->cpu = select_iovcpu (0);
0721
0722 #ifdef GDBSTUB_TCP
0723 {
0724 struct tcp_pcb* debug_pcb = tcp_new ();
0725 tcp_bind (debug_pcb, IP_ADDR_ANY, GDBSTUB_TCP_PORT);
0726 debug_pcb = tcp_listen (debug_pcb);
0727 tcp_accept (debug_pcb, debug_accept);
0728 }
0729 #endif
0730 return TRUE;
0731 }
0732
0733 static uint ethernet_device_count = 0;
0734
0735 bool
0736 net_register_device (ethernet_device *dev)
0737 {
0738 struct ethernetif *ethernetif;
0739
0740 ethernetif = (struct ethernetif*) mem_malloc (sizeof(struct ethernetif));
0741 if (ethernetif == NULL) {
0742 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
0743 return FALSE;
0744 }
0745
0746 dev->num = ethernet_device_count++;
0747 dev->recv_func = dispatch;
0748
0749 DLOG ("net_register_device num=%d", dev->num);
0750
0751 ethernetif->dev = dev;
0752
0753 if (netif_add (&dev->netif, IP_ADDR_ANY, IP_ADDR_ANY, IP_ADDR_ANY,
0754 (void *)ethernetif, ethernetif_init, ethernet_input) == NULL) {
0755 ethernet_device_count--;
0756 mem_free (ethernetif);
0757 DLOG ("netif_add failed");
0758 return FALSE;
0759 }
0760
0761 return TRUE;
0762 }
0763
0764
0765
0766
0767 bool
0768 net_set_default (char *devname)
0769 {
0770 struct netif *netif = netif_find (devname);
0771 if (netif) {
0772 netif_set_default (netif);
0773 return TRUE;
0774 }
0775 return FALSE;
0776 }
0777
0778
0779 bool
0780 net_dhcp_start (char *devname)
0781 {
0782 struct netif *netif = netif_find (devname);
0783 if (netif) {
0784 dhcp_start (netif);
0785 return TRUE;
0786 }
0787 return FALSE;
0788 }
0789
0790
0791 bool
0792 net_set_up (char *devname)
0793 {
0794 struct netif *netif = netif_find (devname);
0795 if (netif) {
0796 netif_set_up (netif);
0797 return TRUE;
0798 }
0799 return FALSE;
0800 }
0801
0802
0803 bool
0804 net_static_config(char *devname, char *myip_s, char *gwip_s, char *netmask_s)
0805 {
0806 struct in_addr inaddr;
0807 struct ip_addr ipaddr, netmask, gw;
0808
0809 struct netif *netif = netif_find (devname);
0810 if (netif == NULL) return FALSE;
0811
0812 inet_aton (myip_s, &inaddr);
0813 ipaddr.addr = inaddr.s_addr;
0814
0815 inet_aton (gwip_s, &inaddr);
0816 gw.addr = inaddr.s_addr;
0817
0818 inet_aton (netmask_s, &inaddr);
0819 netmask.addr = inaddr.s_addr;
0820
0821 netif_set_ipaddr (netif, &ipaddr);
0822 netif_set_gw (netif, &gw);
0823 netif_set_netmask (netif, &netmask);
0824
0825 return TRUE;
0826 }
0827
0828 void
0829 net_tmr_process(void)
0830 {
0831 extern volatile uint32 tick;
0832 static uint32 next_tcp_time = 0;
0833 static uint32 next_etharp_time = 0;
0834 #if LWIP_DHCP
0835 static uint32 next_dhcp_coarse_time = 0;
0836 static uint32 next_dhcp_fine_time = 0;
0837 #endif
0838
0839 uint32 now = tick;
0840
0841
0842
0843 if (now >= next_tcp_time) {
0844 tcp_tmr ();
0845 next_tcp_time = now + (TCP_TMR_INTERVAL / 10);
0846 }
0847
0848 if (now >= next_etharp_time) {
0849 etharp_tmr ();
0850 next_etharp_time = now + (ARP_TMR_INTERVAL / 10);
0851 }
0852
0853 #if LWIP_DHCP
0854 if (now >= next_dhcp_coarse_time) {
0855 dhcp_coarse_tmr ();
0856 next_dhcp_coarse_time = now + (DHCP_COARSE_TIMER_MSECS / 10);
0857 }
0858
0859 if (now >= next_dhcp_fine_time) {
0860 dhcp_fine_tmr ();
0861 next_dhcp_fine_time = now + (DHCP_FINE_TIMER_MSECS / 10);
0862 }
0863 #endif
0864 }
0865
0866 static const struct module_ops mod_ops = {
0867 .init = net_init
0868 };
0869
0870 DEF_MODULE (net___ethernet, "ethernet driver", &mod_ops, {});
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881