2 * This file implements handling of meesagges send by drivers
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>
29 #define debug_drv_print(str, ...) printf("LWIP %s:%d : " str "\n", \
30 __func__, __LINE__, ##__VA_ARGS__)
32 #define debug_drv_print(...) debug_print(__VA_ARGS__)
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
,
44 const char * driver_name
,
45 unsigned int instance
,
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
);
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
)
74 for (i
= 0; i
< MAX_DEVS
; i
++) {
75 if (devices
[i
].drv_ep
== ep
)
82 static struct nic
* lookup_nic_by_drv_name(const char * name
)
86 for (i
= 0; i
< MAX_DEVS
; i
++) {
87 if (strcmp(devices
[i
].drv_name
, name
) == 0)
94 static struct nic
* lookup_nic_default(void)
98 for (i
= 0; i
< MAX_DEVS
; i
++) {
99 if (devices
[i
].is_default
)
106 void nic_init_all(void)
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
)
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
.m_net_netdrv_dl_readv_s
.count
= 1;
151 m
.m_net_netdrv_dl_readv_s
.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
->m_netdrv_net_dl_conf
.hw_addr
,
160 sizeof(nic
->netif
.hwaddr
));
162 debug_print("device %s is up MAC : %02x:%02x:%02x:%02x:%02x:%02x",
164 nic
->netif
.hwaddr
[0],
165 nic
->netif
.hwaddr
[1],
166 nic
->netif
.hwaddr
[2],
167 nic
->netif
.hwaddr
[3],
168 nic
->netif
.hwaddr
[4],
169 nic
->netif
.hwaddr
[5]);
171 driver_setup_read(nic
);
173 netif_set_link_up(&nic
->netif
);
174 netif_set_up(&nic
->netif
);
177 int driver_tx(struct nic
* nic
)
179 struct packet_q
* pkt
;
185 debug_print("device /dev/%s", nic
->name
);
186 assert(nic
->tx_buffer
);
188 pkt
= driver_tx_head(nic
);
190 debug_print("no packets enqueued");
194 assert(pkt
->buf_len
<= nic
->max_pkt_sz
);
196 if ((len
= pkt
->buf_len
) < nic
->min_pkt_sz
)
197 len
= nic
->min_pkt_sz
;
198 err
= cpf_setgrant_direct(nic
->tx_iovec
[0].iov_grant
,
199 nic
->drv_ep
, (vir_bytes
) pkt
->buf
,
201 debug_print("packet len %d", len
);
203 panic("Failed to set grant");
204 nic
->tx_iovec
[0].iov_size
= len
;
206 if (cpf_setgrant_direct(nic
->tx_iogrant
, nic
->drv_ep
,
207 (vir_bytes
) &nic
->tx_iovec
,
208 sizeof(iovec_s_t
), CPF_READ
) != OK
)
209 panic("Failed to set grant");
211 m
.m_type
= DL_WRITEV_S
;
212 m
.m_net_netdrv_dl_writev_s
.count
= 1;
213 m
.m_net_netdrv_dl_writev_s
.grant
= nic
->tx_iogrant
;
215 if (asynsend(nic
->drv_ep
, &m
) != OK
)
216 panic("asynsend to the driver failed!");
217 nic
->state
= DRV_SENDING
;
219 debug_print("packet sent to driver");
224 static void nic_pkt_sent(struct nic
* nic
)
226 debug_print("device /dev/%s", nic
->name
);
227 assert(nic
->state
!= DRV_IDLE
);
229 /* packet has been sent, we are not intereted anymore */
230 driver_tx_dequeue(nic
);
232 * Try to transmit the next packet. Failure means that no packet is
233 * enqueued and thus the device is entering idle state
236 nic
->state
= DRV_IDLE
;
239 __unused
static void print_pkt(unsigned char * pkt
, int len
)
243 printf("--- PKT ---\n");
248 for (x
= 0; x
< 8 && i
< len
; x
++, i
++)
249 printf("%02x ", pkt
[i
]);
253 for (x
= 0; x
< 8 && i
< len
; x
++, i
++)
254 printf("%02x ", pkt
[i
]);
259 printf("--- PKT END ---\n");
262 static int raw_receive(struct sock_req
*req
,
266 unsigned int rem_len
= req
->size
;
267 unsigned int written
= 0;
270 debug_print("user buffer size : %d\n", rem_len
);
272 for (p
= pbuf
; p
&& rem_len
; p
= p
->next
) {
275 cp_len
= (rem_len
< p
->len
) ? rem_len
: p
->len
;
276 err
= copy_to_user(req
->endpt
, p
->payload
, cp_len
,
277 req
->grant
, written
);
285 debug_print("copied %d bytes\n", written
);
289 int raw_socket_input(struct pbuf
* pbuf
, struct nic
* nic
)
291 struct socket
* sock
;
292 struct pbuf
* pbuf_new
;
294 if ((sock
= nic
->raw_socket
) == NULL
)
297 debug_print("socket num : %ld", get_sock_num(sock
));
299 if (sock
->flags
& SOCK_FLG_OP_PENDING
) {
301 /* we are resuming a suspended operation */
302 ret
= raw_receive(&sock
->req
, pbuf
);
304 send_req_reply(&sock
->req
, ret
);
305 sock
->flags
&= ~SOCK_FLG_OP_PENDING
;
311 /* Do not enqueue more data than allowed */
312 if (sock
->recv_data_size
> RAW_BUF_SIZE
) {
317 * nobody is waiting for the data or an error occured above, we enqueue
318 * the packet. We store a copy of this packet
320 pbuf_new
= pbuf_alloc(PBUF_RAW
, pbuf
->tot_len
, PBUF_RAM
);
321 if (pbuf_new
== NULL
) {
322 debug_print("LWIP : cannot allocated new pbuf\n");
326 if (pbuf_copy(pbuf_new
, pbuf
) != ERR_OK
) {
327 debug_print("LWIP : cannot copy pbuf\n");
332 * If we didn't managed to enqueue the packet we report it as not
335 if (sock_enqueue_data(sock
, pbuf_new
, pbuf_new
->tot_len
) != OK
) {
342 static void nic_pkt_received(struct nic
* nic
, unsigned int size
)
344 assert(nic
->netif
.input
);
347 print_pkt((unsigned char *) nic
->rx_pbuf
->payload
, 64 /*nic->rx_pbuf->len */);
350 assert(nic
->rx_pbuf
->tot_len
== nic
->rx_pbuf
->len
);
351 nic
->rx_pbuf
->tot_len
= nic
->rx_pbuf
->len
= size
- ETH_CRC_SIZE
;
353 nic
->netif
.input(nic
->rx_pbuf
, &nic
->netif
);
355 driver_setup_read(nic
);
358 void driver_request(message
* m
)
362 if ((nic
= lookup_nic_by_drv_ep(m
->m_source
)) == NULL
) {
363 printf("LWIP : request from unknown driver %d\n", m
->m_source
);
369 if (m
->m_netdrv_net_dl_conf
.stat
== OK
)
374 if (!(m->m_netdrv_net_dl_task.flags & DL_PACK_SEND) &&
375 !(m->m_netdrv_net_dl_task.flags & DL_PACK_RECV)) {
376 printf("void reply from driver\n");
380 if (m
->m_netdrv_net_dl_task
.flags
& DL_PACK_SEND
)
382 if (m
->m_netdrv_net_dl_task
.flags
& DL_PACK_RECV
)
383 nic_pkt_received(nic
, m
->m_netdrv_net_dl_task
.count
);
388 printf("LWIP : unexpected request %d from driver %d\n",
389 m
->m_type
, m
->m_source
);
393 void driver_up(const char * label
, endpoint_t ep
)
397 nic
= lookup_nic_by_drv_name(label
);
400 debug_print("LWIP : driver '%s' / %d is up for /dev/%s\n",
401 label
, ep
, nic
->name
);
404 printf("LWIP : WARNING unexpected driver '%s' up event\n",
409 nic
->state
= DRV_IDLE
;
414 * We set the initial ip to 0.0.0.0 to make dhcpd broadcasing work
415 * at the very begining. dhcp should use raw socket but it is a little
416 * tricy in the current dhcp implementation
418 if (!netif_add(&nic
->netif
, (ip_addr_t
*) __UNCONST( &ip_addr_any
),
419 &ip_addr_none
, &ip_addr_none
, nic
, ethernetif_init
, ethernet_input
)) {
420 printf("LWIP : failed to add device /dev/%s\n", nic
->name
);
424 netif_set_default(&nic
->netif
);
426 /* FIXME we support ethernet only, 2048 is safe */
427 nic
->tx_buffer
= debug_malloc(2048);
428 if (nic
->tx_buffer
== NULL
)
429 panic("Cannot allocate tx_buffer");
430 /* When driver restarts, the rx_pbuf is likely ready to receive data
431 * from its previous instance. We free the buffer here, nobody depends
432 * on it. A new one is allocated when we send a new read request to the
436 pbuf_free(nic
->rx_pbuf
);
440 /* prepare the RX grant once and forever */
441 if (cpf_setgrant_direct(nic
->rx_iogrant
,
443 (vir_bytes
) &nic
->rx_iovec
,
444 1 * sizeof(iovec_s_t
), CPF_READ
) != OK
)
445 panic("Failed to set grant");
448 static void raw_recv_free(__unused
void * data
)
450 pbuf_free((struct pbuf
*) data
);
453 static int nic_op_close(struct socket
* sock
)
455 struct nic
* nic
= (struct nic
*)sock
->data
;
457 debug_drv_print("socket %ld", get_sock_num(sock
));
459 sock_dequeue_data_all(sock
, raw_recv_free
);
462 if (nic
->raw_socket
== sock
) {
463 nic
->raw_socket
= NULL
;
464 debug_drv_print("no active raw sock at %s", nic
->name
);
470 static int nic_ioctl_set_conf(__unused
struct socket
* sock
,
475 nwio_ipconf_t ipconf
;
478 err
= copy_from_user(endpt
, &ipconf
, sizeof(ipconf
), grant
, 0);
482 if (ipconf
.nwic_flags
& NWIC_IPADDR_SET
)
483 netif_set_ipaddr(&nic
->netif
,
484 (ip_addr_t
*)&ipconf
.nwic_ipaddr
);
485 if (ipconf
.nwic_flags
& NWIC_NETMASK_SET
)
486 netif_set_netmask(&nic
->netif
,
487 (ip_addr_t
*)&ipconf
.nwic_netmask
);
488 nic
->flags
= ipconf
.nwic_flags
;
489 if (nic
->flags
& NWEO_EN_BROAD
)
490 nic
->netif
.flags
|= NETIF_FLAG_BROADCAST
;
496 static int nic_ioctl_get_conf(__unused
struct socket
* sock
,
501 nwio_ipconf_t ipconf
;
503 ipconf
.nwic_flags
= nic
->flags
;
504 ipconf
.nwic_ipaddr
= nic
->netif
.ip_addr
.addr
;
505 ipconf
.nwic_netmask
= nic
->netif
.netmask
.addr
;
506 ipconf
.nwic_mtu
= nic
->netif
.mtu
;
508 return copy_to_user(endpt
, &ipconf
, sizeof(ipconf
), grant
, 0);
511 static int nic_ioctl_set_gateway(__unused
struct socket
* sock
,
519 err
= copy_from_user(endpt
, &route
, sizeof(route
), grant
, 0);
523 netif_set_gw(&nic
->netif
, (ip_addr_t
*)&route
.nwr_gateway
);
528 static int nic_ioctl_get_ethstat(__unused
struct socket
* sock
,
533 nwio_ethstat_t ethstat
;
535 debug_drv_print("device /dev/%s", nic
->name
);
537 * The device is not up yet, there is nothing to report or it is not
540 if (!nic
->netif
.flags
& NETIF_FLAG_UP
||
541 !(nic
->netif
.flags
& (NETIF_FLAG_ETHERNET
|
542 NETIF_FLAG_ETHARP
))) {
543 printf("LWIP no such device FUCK\n");
547 memset(ðstat
, 0, sizeof(ethstat
));
548 memcpy(ðstat
.nwes_addr
, nic
->netif
.hwaddr
, 6);
550 return copy_to_user(endpt
, ðstat
, sizeof(ethstat
), grant
, 0);
553 static int nic_ioctl_set_ethopt(struct socket
* sock
,
559 nwio_ethopt_t ethopt
;
566 debug_drv_print("device /dev/%s", nic
->name
);
568 * The device is not up yet, there is nothing to report or it is not
571 if (!nic
->netif
.flags
& NETIF_FLAG_UP
||
572 !(nic
->netif
.flags
& (NETIF_FLAG_ETHERNET
|
573 NETIF_FLAG_ETHARP
))) {
577 err
= copy_from_user(endpt
, ðopt
, sizeof(ethopt
), grant
, 0);
581 /* we want to get data from this sock */
582 if (ethopt
.nweo_flags
& NWEO_COPY
) {
586 nic
->raw_socket
= sock
;
587 debug_drv_print("active raw sock %ld at %s",
588 get_sock_num(sock
), nic
->name
);
594 static int nic_do_ioctl(struct socket
* sock
, struct nic
* nic
,
595 struct sock_req
* req
)
599 debug_print("device /dev/%s req %c %ld %ld",
601 (unsigned char) (req
->req
>> 8),
602 req
->req
& 0xff, _MINIX_IOCTL_SIZE(req
->req
));
604 debug_drv_print("socket %ld", sock
? get_sock_num(sock
) : -1);
608 r
= nic_ioctl_set_conf(sock
, nic
, req
->endpt
, req
->grant
);
611 r
= nic_ioctl_get_conf(sock
, nic
, req
->endpt
, req
->grant
);
614 r
= nic_ioctl_set_gateway(sock
, nic
, req
->endpt
, req
->grant
);
617 r
= nic_ioctl_get_ethstat(sock
, nic
, req
->endpt
, req
->grant
);
620 r
= nic_ioctl_set_ethopt(sock
, nic
, req
->endpt
, req
->grant
);
629 int nic_default_ioctl(struct sock_req
*req
)
631 struct nic
* nic
= lookup_nic_default();
634 debug_print("No default nic, reporting error");
638 return nic_do_ioctl(NULL
, nic
, req
);
641 static int nic_op_ioctl(struct socket
* sock
, struct sock_req
* req
,
644 return nic_do_ioctl(sock
, (struct nic
*)sock
->data
, req
);
647 static int nic_op_read(struct socket
* sock
, struct sock_req
* req
, int blk
)
649 debug_drv_print("sock num %ld", get_sock_num(sock
));
651 if (sock
->recv_head
) {
652 /* data available receive immeditely */
657 pbuf
= sock
->recv_head
->data
;
659 ret
= raw_receive(req
, pbuf
);
662 sock_dequeue_data(sock
);
663 sock
->recv_data_size
-= pbuf
->tot_len
;
670 /* store the request so we know how to reply */
672 /* operation is being processes */
673 sock
->flags
|= SOCK_FLG_OP_PENDING
;
675 debug_print("no data to read, suspending");
680 static int nic_op_write(struct socket
* sock
, struct sock_req
* req
,
685 struct nic
* nic
= (struct nic
*)sock
->data
;
688 debug_print("device %s data size %u", nic
->name
, req
->size
);
690 pbuf
= pbuf_alloc(PBUF_RAW
, req
->size
, PBUF_RAM
);
694 if ((ret
= copy_from_user(req
->endpt
, pbuf
->payload
, req
->size
,
695 req
->grant
, 0)) != OK
) {
700 if ((ret
= nic
->netif
.linkoutput(&nic
->netif
, pbuf
) != ERR_OK
)) {
701 debug_print("raw linkoutput failed %d", ret
);
711 static struct sock_ops nic_ops
= {
712 .write
= nic_op_write
,
714 .close
= nic_op_close
,
715 .ioctl
= nic_op_ioctl
,
716 .select
= generic_op_select
,
717 .select_reply
= generic_op_select_reply
720 int nic_open(devminor_t minor
)
722 struct socket
* sock
;
724 debug_print("device %d", minor
);
726 if (minor
> MAX_DEVS
|| devices
[minor
].drv_ep
== NONE
)
729 sock
= get_unused_sock();
733 if (sock
->ops
!= NULL
)
736 sock
->ops
= &nic_ops
;
737 sock
->select_ep
= NONE
;
738 sock
->recv_data_size
= 0;
739 sock
->data
= &devices
[minor
];
741 return get_sock_num(sock
);
744 static int driver_pkt_enqueue(struct packet_q
** head
,
745 struct packet_q
** tail
,
748 struct packet_q
* pkt
;
751 pkt
= (struct packet_q
*) malloc(sizeof(struct packet_q
) + pbuf
->tot_len
);
756 pkt
->buf_len
= pbuf
->tot_len
;
758 for (b
= pkt
->buf
; pbuf
; pbuf
= pbuf
->next
) {
759 memcpy(b
, pbuf
->payload
, pbuf
->len
);
773 int driver_tx_enqueue(struct nic
* nic
, struct pbuf
* pbuf
)
775 debug_print("device /dev/%s", nic
->name
);
776 return driver_pkt_enqueue(&nic
->tx_head
, &nic
->tx_tail
, pbuf
);
779 static void driver_pkt_dequeue(struct packet_q
** head
,
780 struct packet_q
** tail
)
782 struct packet_q
* pkt
;
784 /* we always dequeue only if there is something to dequeue */
789 if ((*head
= pkt
->next
) == NULL
)
795 void driver_tx_dequeue(struct nic
* nic
)
797 debug_print("device /dev/%s", nic
->name
);
798 driver_pkt_dequeue(&nic
->tx_head
, &nic
->tx_tail
);
801 struct packet_q
* driver_tx_head(struct nic
* nic
)
803 debug_print("device /dev/%s", nic
->name
);