<sys/poll.h>
[minix3.git] / servers / lwip / driver.c
blobb0761ee66c263a25831913a6abe5dd4991eac936
1 /*
2 * This file implements handling of meesagges send by drivers
3 */
5 #include <stdio.h>
6 #include <stdlib.h>
8 #include <minix/ipc.h>
9 #include <minix/com.h>
10 #include <minix/sysutil.h>
11 #include <minix/safecopies.h>
12 #include <minix/netsock.h>
14 #include <sys/ioc_net.h>
15 #include <net/gen/in.h>
16 #include <net/gen/ip_io.h>
17 #include <net/gen/route.h>
18 #include <net/gen/ether.h>
19 #include <net/gen/eth_io.h>
21 #include <lwip/pbuf.h>
22 #include <lwip/netif.h>
23 #include <netif/etharp.h>
25 #include "proto.h"
26 #include "driver.h"
28 #if 0
29 #define debug_drv_print(str, ...) printf("LWIP %s:%d : " str "\n", \
30 __func__, __LINE__, ##__VA_ARGS__)
31 #else
32 #define debug_drv_print(...) debug_print(__VA_ARGS__)
33 #endif
35 #define RAW_BUF_SIZE (32 << 10)
37 static struct nic devices[MAX_DEVS];
39 static ip_addr_t ip_addr_none = { IPADDR_NONE };
40 extern endpoint_t lwip_ep;
42 void nic_assign_driver(const char * dev_type,
43 unsigned int dev_num,
44 const char * driver_name,
45 unsigned int instance,
46 int is_default)
48 struct nic * nic;
50 if (strcmp(dev_type, "eth") != 0) {
51 printf("LWIP : Cannot handle other than ethernet devices, "
52 "ignoring '%s%d'\n", dev_type, dev_num);
53 return;
56 nic = &devices[dev_num];
57 snprintf(nic->name, NIC_NAME_LEN, "%s%d", dev_type, dev_num);
58 nic->name[NIC_NAME_LEN - 1] = '\0';
59 snprintf(nic->drv_name, DRV_NAME_LEN, "%s_%d", driver_name, instance);
60 nic->drv_name[DRV_NAME_LEN - 1] = '\0';
61 nic->is_default = is_default;
62 nic->netif.name[0] = 'e';
63 nic->netif.name[1] = 't';
64 nic->netif.num = dev_num;
66 debug_print("/dev/%s driven by %s default = %d",
67 nic->name, nic->drv_name, is_default);
70 static struct nic * lookup_nic_by_drv_ep(endpoint_t ep)
72 int i;
74 for (i = 0; i < MAX_DEVS; i++) {
75 if (devices[i].drv_ep == ep)
76 return &devices[i];
79 return NULL;
82 static struct nic * lookup_nic_by_drv_name(const char * name)
84 int i;
86 for (i = 0; i < MAX_DEVS; i++) {
87 if (strcmp(devices[i].drv_name, name) == 0)
88 return &devices[i];
91 return NULL;
94 static struct nic * lookup_nic_default(void)
96 int i;
98 for (i = 0; i < MAX_DEVS; i++) {
99 if (devices[i].is_default)
100 return &devices[i];
103 return NULL;
106 void nic_init_all(void)
108 int i;
109 unsigned int g;
111 for (i = 0; i < MAX_DEVS; i++) {
112 devices[i].drv_ep = NONE;
113 devices[i].is_default = 0;
115 if (cpf_getgrants(&devices[i].rx_iogrant, 1) != 1)
116 panic("Cannot initialize grants");
117 if (cpf_getgrants(&devices[i].rx_iovec[0].iov_grant, 1) != 1)
118 panic("Cannot initialize grants");
119 if (cpf_getgrants(&devices[i].tx_iogrant, 1) != 1)
120 panic("Cannot initialize grants");
121 for (g = 0; g < TX_IOVEC_NUM; g++) {
122 cp_grant_id_t * gid = &devices[i].tx_iovec[g].iov_grant;
123 if (cpf_getgrants(gid, 1) != 1)
124 panic("Cannot initialize grants");
126 devices[i].raw_socket = NULL;
130 static void driver_setup_read(struct nic * nic)
132 message m;
134 debug_print("device /dev/%s", nic->name);
135 //assert(nic->rx_pbuf == NULL);
136 if (!(nic->rx_pbuf == NULL)) {
137 panic("device /dev/%s rx_pbuf %p", nic->name, nic->rx_pbuf);
140 if (!(nic->rx_pbuf = pbuf_alloc(PBUF_RAW, ETH_MAX_PACK_SIZE + ETH_CRC_SIZE, PBUF_RAM)))
141 panic("Cannot allocate rx pbuf");
143 if (cpf_setgrant_direct(nic->rx_iovec[0].iov_grant,
144 nic->drv_ep, (vir_bytes) nic->rx_pbuf->payload,
145 nic->rx_pbuf->len, CPF_WRITE) != OK)
146 panic("Failed to set grant");
147 nic->rx_iovec[0].iov_size = nic->rx_pbuf->len;
149 m.m_type = DL_READV_S;
150 m.DL_COUNT = 1;
151 m.DL_GRANT = nic->rx_iogrant;
153 if (asynsend(nic->drv_ep, &m) != OK)
154 panic("asynsend to the driver failed!");
157 static void nic_up(struct nic * nic, message * m)
159 memcpy(nic->netif.hwaddr, m->DL_HWADDR, NETIF_MAX_HWADDR_LEN);
161 debug_print("device %s is up MAC : %02x:%02x:%02x:%02x:%02x:%02x",
162 nic->name,
163 nic->netif.hwaddr[0],
164 nic->netif.hwaddr[1],
165 nic->netif.hwaddr[2],
166 nic->netif.hwaddr[3],
167 nic->netif.hwaddr[4],
168 nic->netif.hwaddr[5]);
170 driver_setup_read(nic);
172 netif_set_link_up(&nic->netif);
173 netif_set_up(&nic->netif);
176 int driver_tx(struct nic * nic)
178 struct packet_q * pkt;
179 unsigned int len;
180 message m;
182 int err;
184 debug_print("device /dev/%s", nic->name);
185 assert(nic->tx_buffer);
187 pkt = driver_tx_head(nic);
188 if (pkt == NULL) {
189 debug_print("no packets enqueued");
190 return 0;
193 assert(pkt->buf_len <= nic->max_pkt_sz);
195 if ((len = pkt->buf_len) < nic->min_pkt_sz)
196 len = nic->min_pkt_sz;
197 err = cpf_setgrant_direct(nic->tx_iovec[0].iov_grant,
198 nic->drv_ep, (vir_bytes) pkt->buf,
199 len, CPF_READ);
200 debug_print("packet len %d", len);
201 if (err != OK)
202 panic("Failed to set grant");
203 nic->tx_iovec[0].iov_size = len;
205 if (cpf_setgrant_direct(nic->tx_iogrant, nic->drv_ep,
206 (vir_bytes) &nic->tx_iovec,
207 sizeof(iovec_s_t), CPF_READ) != OK)
208 panic("Failed to set grant");
210 m.m_type = DL_WRITEV_S;
211 m.DL_COUNT = 1;
212 m.DL_GRANT = nic->tx_iogrant;
214 if (asynsend(nic->drv_ep, &m) != OK)
215 panic("asynsend to the driver failed!");
216 nic->state = DRV_SENDING;
218 debug_print("packet sent to driver");
220 return 1;
223 static void nic_pkt_sent(struct nic * nic)
225 debug_print("device /dev/%s", nic->name);
226 assert(nic->state != DRV_IDLE);
228 /* packet has been sent, we are not intereted anymore */
229 driver_tx_dequeue(nic);
231 * Try to transmit the next packet. Failure means that no packet is
232 * enqueued and thus the device is entering idle state
234 if (!driver_tx(nic))
235 nic->state = DRV_IDLE;
238 __unused static void print_pkt(unsigned char * pkt, int len)
240 int i = 0;
242 printf("--- PKT ---\n");
244 while (i < len) {
245 int x;
247 for (x = 0; x < 8 && i < len; x++, i++)
248 printf("%02x ", pkt[i]);
250 kputc(' ');
252 for (x = 0; x < 8 && i < len; x++, i++)
253 printf("%02x ", pkt[i]);
255 kputc('\n');
258 printf("--- PKT END ---\n");
261 static int raw_receive(struct sock_req *req,
262 struct pbuf *pbuf)
264 struct pbuf * p;
265 unsigned int rem_len = req->size;
266 unsigned int written = 0;
267 int err;
269 debug_print("user buffer size : %d\n", rem_len);
271 for (p = pbuf; p && rem_len; p = p->next) {
272 size_t cp_len;
274 cp_len = (rem_len < p->len) ? rem_len : p->len;
275 err = copy_to_user(req->endpt, p->payload, cp_len,
276 req->grant, written);
277 if (err != OK)
278 return err;
280 written += cp_len;
281 rem_len -= cp_len;
284 debug_print("copied %d bytes\n", written);
285 return written;
288 int raw_socket_input(struct pbuf * pbuf, struct nic * nic)
290 struct socket * sock;
291 struct pbuf * pbuf_new;
293 if ((sock = nic->raw_socket) == NULL)
294 return 0;
296 debug_print("socket num : %ld", get_sock_num(sock));
298 if (sock->flags & SOCK_FLG_OP_PENDING) {
299 int ret;
300 /* we are resuming a suspended operation */
301 ret = raw_receive(&sock->req, pbuf);
303 send_req_reply(&sock->req, ret);
304 sock->flags &= ~SOCK_FLG_OP_PENDING;
306 if (ret > 0)
307 return 0;
310 /* Do not enqueue more data than allowed */
311 if (sock->recv_data_size > RAW_BUF_SIZE) {
312 return 0;
316 * nobody is waiting for the data or an error occured above, we enqueue
317 * the packet. We store a copy of this packet
319 pbuf_new = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM);
320 if (pbuf_new == NULL) {
321 debug_print("LWIP : cannot allocated new pbuf\n");
322 return 0;
325 if (pbuf_copy(pbuf_new, pbuf) != ERR_OK) {
326 debug_print("LWIP : cannot copy pbuf\n");
327 return 0;
331 * If we didn't managed to enqueue the packet we report it as not
332 * consumed
334 if (sock_enqueue_data(sock, pbuf_new, pbuf_new->tot_len) != OK) {
335 pbuf_free(pbuf_new);
338 return 0;
341 static void nic_pkt_received(struct nic * nic, unsigned int size)
343 assert(nic->netif.input);
345 #if 0
346 print_pkt((unsigned char *) nic->rx_pbuf->payload, 64 /*nic->rx_pbuf->len */);
347 #endif
349 assert(nic->rx_pbuf->tot_len == nic->rx_pbuf->len);
350 nic->rx_pbuf->tot_len = nic->rx_pbuf->len = size - ETH_CRC_SIZE;
352 nic->netif.input(nic->rx_pbuf, &nic->netif);
353 nic->rx_pbuf = NULL;
354 driver_setup_read(nic);
357 void driver_request(message * m)
359 struct nic * nic;
361 if ((nic = lookup_nic_by_drv_ep(m->m_source)) == NULL) {
362 printf("LWIP : request from unknown driver %d\n", m->m_source);
363 return;
366 switch (m->m_type) {
367 case DL_CONF_REPLY:
368 if (m->DL_STAT == OK)
369 nic_up(nic, m);
370 break;
371 case DL_TASK_REPLY:
373 if (!(m->DL_FLAGS & DL_PACK_SEND) && !(m->DL_FLAGS & DL_PACK_RECV)) {
374 printf("void reply from driver\n");
375 break;
378 if (m->DL_FLAGS & DL_PACK_SEND)
379 nic_pkt_sent(nic);
380 if (m->DL_FLAGS & DL_PACK_RECV)
381 nic_pkt_received(nic, m->DL_COUNT);
382 break;
383 case DL_STAT_REPLY:
384 break;
385 default:
386 printf("LWIP : unexpected request %d from driver %d\n",
387 m->m_type, m->m_source);
391 void driver_up(const char * label, endpoint_t ep)
393 struct nic * nic;
395 nic = lookup_nic_by_drv_name(label);
397 if (nic) {
398 debug_print("LWIP : driver '%s' / %d is up for /dev/%s\n",
399 label, ep, nic->name);
400 nic->drv_ep = ep;
401 } else {
402 printf("LWIP : WARNING unexpected driver '%s' up event\n",
403 label);
404 return;
407 nic->state = DRV_IDLE;
410 * FIXME
412 * We set the initial ip to 0.0.0.0 to make dhcpd broadcasing work
413 * at the very begining. dhcp should use raw socket but it is a little
414 * tricy in the current dhcp implementation
416 if (!netif_add(&nic->netif, (ip_addr_t *) __UNCONST( &ip_addr_any),
417 &ip_addr_none, &ip_addr_none, nic, ethernetif_init, ethernet_input)) {
418 printf("LWIP : failed to add device /dev/%s\n", nic->name);
419 nic->drv_ep = NONE;
421 if (nic->is_default)
422 netif_set_default(&nic->netif);
424 /* FIXME we support ethernet only, 2048 is safe */
425 nic->tx_buffer = debug_malloc(2048);
426 if (nic->tx_buffer == NULL)
427 panic("Cannot allocate tx_buffer");
428 /* When driver restarts, the rx_pbuf is likely ready to receive data
429 * from its previous instance. We free the buffer here, nobody depends
430 * on it. A new one is allocated when we send a new read request to the
431 * driver.
433 if (nic->rx_pbuf) {
434 pbuf_free(nic->rx_pbuf);
435 nic->rx_pbuf = NULL;
438 /* prepare the RX grant once and forever */
439 if (cpf_setgrant_direct(nic->rx_iogrant,
440 nic->drv_ep,
441 (vir_bytes) &nic->rx_iovec,
442 1 * sizeof(iovec_s_t), CPF_READ) != OK)
443 panic("Failed to set grant");
446 static void raw_recv_free(__unused void * data)
448 pbuf_free((struct pbuf *) data);
451 static int nic_op_close(struct socket * sock)
453 struct nic * nic = (struct nic *)sock->data;
455 debug_drv_print("socket %ld", get_sock_num(sock));
457 sock_dequeue_data_all(sock, raw_recv_free);
458 sock->ops = NULL;
460 if (nic->raw_socket == sock) {
461 nic->raw_socket = NULL;
462 debug_drv_print("no active raw sock at %s", nic->name);
465 return OK;
468 static int nic_ioctl_set_conf(__unused struct socket * sock,
469 struct nic * nic,
470 endpoint_t endpt,
471 cp_grant_id_t grant)
473 nwio_ipconf_t ipconf;
474 int err;
476 err = copy_from_user(endpt, &ipconf, sizeof(ipconf), grant, 0);
477 if (err != OK)
478 return err;
480 if (ipconf.nwic_flags & NWIC_IPADDR_SET)
481 netif_set_ipaddr(&nic->netif,
482 (ip_addr_t *)&ipconf.nwic_ipaddr);
483 if (ipconf.nwic_flags & NWIC_NETMASK_SET)
484 netif_set_netmask(&nic->netif,
485 (ip_addr_t *)&ipconf.nwic_netmask);
486 nic->flags = ipconf.nwic_flags;
487 if (nic->flags & NWEO_EN_BROAD)
488 nic->netif.flags |= NETIF_FLAG_BROADCAST;
491 return OK;
494 static int nic_ioctl_get_conf(__unused struct socket * sock,
495 struct nic * nic,
496 endpoint_t endpt,
497 cp_grant_id_t grant)
499 nwio_ipconf_t ipconf;
501 ipconf.nwic_flags = nic->flags;
502 ipconf.nwic_ipaddr = nic->netif.ip_addr.addr;
503 ipconf.nwic_netmask = nic->netif.netmask.addr;
504 ipconf.nwic_mtu = nic->netif.mtu;
506 return copy_to_user(endpt, &ipconf, sizeof(ipconf), grant, 0);
509 static int nic_ioctl_set_gateway(__unused struct socket * sock,
510 struct nic * nic,
511 endpoint_t endpt,
512 cp_grant_id_t grant)
514 nwio_route_t route;
515 int err;
517 err = copy_from_user(endpt, &route, sizeof(route), grant, 0);
518 if (err != OK)
519 return err;
521 netif_set_gw(&nic->netif, (ip_addr_t *)&route.nwr_gateway);
523 return OK;
526 static int nic_ioctl_get_ethstat(__unused struct socket * sock,
527 struct nic * nic,
528 endpoint_t endpt,
529 cp_grant_id_t grant)
531 nwio_ethstat_t ethstat;
533 debug_drv_print("device /dev/%s", nic->name);
535 * The device is not up yet, there is nothing to report or it is not
536 * an ethernet device
538 if (!nic->netif.flags & NETIF_FLAG_UP ||
539 !(nic->netif.flags & (NETIF_FLAG_ETHERNET |
540 NETIF_FLAG_ETHARP))) {
541 printf("LWIP no such device FUCK\n");
542 return ENODEV;
545 memset(&ethstat, 0, sizeof(ethstat));
546 memcpy(&ethstat.nwes_addr, nic->netif.hwaddr, 6);
548 return copy_to_user(endpt, &ethstat, sizeof(ethstat), grant, 0);
551 static int nic_ioctl_set_ethopt(struct socket * sock,
552 struct nic * nic,
553 endpoint_t endpt,
554 cp_grant_id_t grant)
556 int err;
557 nwio_ethopt_t ethopt;
559 assert(nic);
561 if (!sock)
562 return EINVAL;
564 debug_drv_print("device /dev/%s", nic->name);
566 * The device is not up yet, there is nothing to report or it is not
567 * an ethernet device
569 if (!nic->netif.flags & NETIF_FLAG_UP ||
570 !(nic->netif.flags & (NETIF_FLAG_ETHERNET |
571 NETIF_FLAG_ETHARP))) {
572 return ENODEV;
575 err = copy_from_user(endpt, &ethopt, sizeof(ethopt), grant, 0);
576 if (err != OK)
577 return err;
579 /* we want to get data from this sock */
580 if (ethopt.nweo_flags & NWEO_COPY) {
581 if (nic->raw_socket)
582 return EBUSY;
584 nic->raw_socket = sock;
585 debug_drv_print("active raw sock %ld at %s",
586 get_sock_num(sock), nic->name);
589 return OK;
592 static int nic_do_ioctl(struct socket * sock, struct nic * nic,
593 struct sock_req * req)
595 int r;
597 debug_print("device /dev/%s req %c %ld %ld",
598 nic->name,
599 (unsigned char) (req->req >> 8),
600 req->req & 0xff, _MINIX_IOCTL_SIZE(req->req));
602 debug_drv_print("socket %ld", sock ? get_sock_num(sock) : -1);
604 switch (req->req) {
605 case NWIOSIPCONF:
606 r = nic_ioctl_set_conf(sock, nic, req->endpt, req->grant);
607 break;
608 case NWIOGIPCONF:
609 r = nic_ioctl_get_conf(sock, nic, req->endpt, req->grant);
610 break;
611 case NWIOSIPOROUTE:
612 r = nic_ioctl_set_gateway(sock, nic, req->endpt, req->grant);
613 break;
614 case NWIOGETHSTAT:
615 r = nic_ioctl_get_ethstat(sock, nic, req->endpt, req->grant);
616 break;
617 case NWIOSETHOPT:
618 r = nic_ioctl_set_ethopt(sock, nic, req->endpt, req->grant);
619 break;
620 default:
621 r = ENOTTY;
624 return r;
627 int nic_default_ioctl(struct sock_req *req)
629 struct nic * nic = lookup_nic_default();
631 if (nic == NULL) {
632 debug_print("No default nic, reporting error");
633 return ENOTTY;
636 return nic_do_ioctl(NULL, nic, req);
639 static int nic_op_ioctl(struct socket * sock, struct sock_req * req,
640 __unused int blk)
642 return nic_do_ioctl(sock, (struct nic *)sock->data, req);
645 static int nic_op_read(struct socket * sock, struct sock_req * req, int blk)
647 debug_drv_print("sock num %ld", get_sock_num(sock));
649 if (sock->recv_head) {
650 /* data available receive immeditely */
652 struct pbuf * pbuf;
653 int ret;
655 pbuf = sock->recv_head->data;
657 ret = raw_receive(req, pbuf);
659 if (ret > 0) {
660 sock_dequeue_data(sock);
661 sock->recv_data_size -= pbuf->tot_len;
662 pbuf_free(pbuf);
664 return ret;
665 } else if (!blk)
666 return EAGAIN;
667 else {
668 /* store the request so we know how to reply */
669 sock->req = *req;
670 /* operation is being processes */
671 sock->flags |= SOCK_FLG_OP_PENDING;
673 debug_print("no data to read, suspending");
674 return EDONTREPLY;
678 static int nic_op_write(struct socket * sock, struct sock_req * req,
679 __unused int blk)
681 int ret;
682 struct pbuf * pbuf;
683 struct nic * nic = (struct nic *)sock->data;
685 assert(nic);
686 debug_print("device %s data size %u", nic->name, req->size);
688 pbuf = pbuf_alloc(PBUF_RAW, req->size, PBUF_RAM);
689 if (!pbuf)
690 return ENOMEM;
692 if ((ret = copy_from_user(req->endpt, pbuf->payload, req->size,
693 req->grant, 0)) != OK) {
694 pbuf_free(pbuf);
695 return ret;
698 if ((ret = nic->netif.linkoutput(&nic->netif, pbuf) != ERR_OK)) {
699 debug_print("raw linkoutput failed %d", ret);
700 ret = EIO;
701 } else
702 ret = req->size;
704 pbuf_free(pbuf);
706 return ret;
709 static struct sock_ops nic_ops = {
710 .write = nic_op_write,
711 .read = nic_op_read,
712 .close = nic_op_close,
713 .ioctl = nic_op_ioctl,
714 .select = generic_op_select,
715 .select_reply = generic_op_select_reply
718 int nic_open(devminor_t minor)
720 struct socket * sock;
722 debug_print("device %d", minor);
724 if (minor > MAX_DEVS || devices[minor].drv_ep == NONE)
725 return ENODEV;
727 sock = get_unused_sock();
729 if (sock == NULL)
730 return ENODEV;
731 if (sock->ops != NULL)
732 return EBUSY;
734 sock->ops = &nic_ops;
735 sock->select_ep = NONE;
736 sock->recv_data_size = 0;
737 sock->data = &devices[minor];
739 return get_sock_num(sock);
742 static int driver_pkt_enqueue(struct packet_q ** head,
743 struct packet_q ** tail,
744 struct pbuf * pbuf)
746 struct packet_q * pkt;
747 char * b;
749 pkt = (struct packet_q *) malloc(sizeof(struct packet_q) + pbuf->tot_len);
750 if (!pkt)
751 return ENOMEM;
753 pkt->next = NULL;
754 pkt->buf_len = pbuf->tot_len;
756 for (b = pkt->buf; pbuf; pbuf = pbuf->next) {
757 memcpy(b, pbuf->payload, pbuf->len);
758 b += pbuf->len;
761 if (*head == NULL)
762 *head = *tail = pkt;
763 else {
764 (*tail)->next = pkt;
765 *tail = pkt;
768 return OK;
771 int driver_tx_enqueue(struct nic * nic, struct pbuf * pbuf)
773 debug_print("device /dev/%s", nic->name);
774 return driver_pkt_enqueue(&nic->tx_head, &nic->tx_tail, pbuf);
777 static void driver_pkt_dequeue(struct packet_q ** head,
778 struct packet_q ** tail)
780 struct packet_q * pkt;
782 /* we always dequeue only if there is something to dequeue */
783 assert(*head);
785 pkt = *head;
787 if ((*head = pkt->next) == NULL)
788 *tail = NULL;
790 debug_free(pkt);
793 void driver_tx_dequeue(struct nic * nic)
795 debug_print("device /dev/%s", nic->name);
796 driver_pkt_dequeue(&nic->tx_head, &nic->tx_tail);
799 struct packet_q * driver_tx_head(struct nic * nic)
801 debug_print("device /dev/%s", nic->name);
803 if (!nic->tx_head)
804 return NULL;
805 return nic->tx_head;