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
,
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
;
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",
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
;
184 debug_print("device /dev/%s", nic
->name
);
185 assert(nic
->tx_buffer
);
187 pkt
= driver_tx_head(nic
);
189 debug_print("no packets enqueued");
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
,
200 debug_print("packet len %d", len
);
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
;
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");
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
235 nic
->state
= DRV_IDLE
;
238 __unused
static void print_pkt(unsigned char * pkt
, int len
)
242 printf("--- PKT ---\n");
247 for (x
= 0; x
< 8 && i
< len
; x
++, i
++)
248 printf("%02x ", pkt
[i
]);
252 for (x
= 0; x
< 8 && i
< len
; x
++, i
++)
253 printf("%02x ", pkt
[i
]);
258 printf("--- PKT END ---\n");
261 static int raw_receive(message
* m
,
265 unsigned rem_len
= m
->COUNT
;
266 unsigned written
= 0;
269 debug_print("user buffer size : %d\n", rem_len
);
271 for (p
= pbuf
; p
&& rem_len
; p
= p
->next
) {
274 cp_len
= (rem_len
< p
->len
) ? rem_len
: p
->len
;
275 err
= copy_to_user(m
->m_source
, p
->payload
, cp_len
,
276 (cp_grant_id_t
) m
->IO_GRANT
,
286 debug_print("copied %d bytes\n", written
);
290 int raw_socket_input(struct pbuf
* pbuf
, struct nic
* nic
)
292 struct socket
* sock
;
293 struct pbuf
* pbuf_new
;
295 if ((sock
= nic
->raw_socket
) == NULL
)
298 debug_print("socket num : %ld", get_sock_num(sock
));
300 if (sock
->flags
& SOCK_FLG_OP_PENDING
) {
302 /* we are resuming a suspended operation */
303 ret
= raw_receive(&sock
->mess
, pbuf
);
306 sock_reply(sock
, ret
);
307 sock
->flags
&= ~SOCK_FLG_OP_PENDING
;
310 sock_reply(sock
, ret
);
311 sock
->flags
&= ~SOCK_FLG_OP_PENDING
;
315 /* Do not enqueue more data than allowed */
316 if (sock
->recv_data_size
> RAW_BUF_SIZE
) {
321 * nobody is waiting for the data or an error occured above, we enqueue
322 * the packet. We store a copy of this packet
324 pbuf_new
= pbuf_alloc(PBUF_RAW
, pbuf
->tot_len
, PBUF_RAM
);
325 if (pbuf_new
== NULL
) {
326 debug_print("LWIP : cannot allocated new pbuf\n");
330 if (pbuf_copy(pbuf_new
, pbuf
) != ERR_OK
) {
331 debug_print("LWIP : cannot copy pbuf\n");
336 * If we didn't managed to enqueue the packet we report it as not
339 if (sock_enqueue_data(sock
, pbuf_new
, pbuf_new
->tot_len
) != OK
) {
346 static void nic_pkt_received(struct nic
* nic
, unsigned size
)
348 assert(nic
->netif
.input
);
351 print_pkt((unsigned char *) nic
->rx_pbuf
->payload
, 64 /*nic->rx_pbuf->len */);
354 assert(nic
->rx_pbuf
->tot_len
== nic
->rx_pbuf
->len
);
355 nic
->rx_pbuf
->tot_len
= nic
->rx_pbuf
->len
= size
- ETH_CRC_SIZE
;
357 nic
->netif
.input(nic
->rx_pbuf
, &nic
->netif
);
359 driver_setup_read(nic
);
362 void driver_request(message
* m
)
366 if ((nic
= lookup_nic_by_drv_ep(m
->m_source
)) == NULL
) {
367 printf("LWIP : request from unknown driver %d\n", m
->m_source
);
373 if (m
->DL_STAT
== OK
)
378 if (!(m->DL_FLAGS & DL_PACK_SEND) && !(m->DL_FLAGS & DL_PACK_RECV)) {
379 printf("void reply from driver\n");
383 if (m
->DL_FLAGS
& DL_PACK_SEND
)
385 if (m
->DL_FLAGS
& DL_PACK_RECV
)
386 nic_pkt_received(nic
, m
->DL_COUNT
);
391 printf("LWIP : unexpected request %d from driver %d\n",
392 m
->m_type
, m
->m_source
);
396 void driver_up(const char * label
, endpoint_t ep
)
400 nic
= lookup_nic_by_drv_name(label
);
403 debug_print("LWIP : driver '%s' / %d is up for /dev/%s\n",
404 label
, ep
, nic
->name
);
407 printf("LWIP : WARNING unexpected driver '%s' up event\n",
410 nic
->state
= DRV_IDLE
;
415 * We set the initial ip to 0.0.0.0 to make dhcpd broadcasing work
416 * at the very begining. dhcp should use raw socket but it is a little
417 * tricy in the current dhcp implementation
419 if (!netif_add(&nic
->netif
, (ip_addr_t
*) &ip_addr_any
, &ip_addr_none
,
420 &ip_addr_none
, nic
, ethernetif_init
, ethernet_input
)) {
421 printf("LWIP : failed to add device /dev/%s\n", nic
->name
);
425 netif_set_default(&nic
->netif
);
427 /* FIXME we support ethernet only, 2048 is safe */
428 nic
->tx_buffer
= debug_malloc(2048);
429 if (nic
->tx_buffer
== NULL
)
430 panic("Cannot allocate tx_buffer");
432 /* prepare the RX grant once and forever */
433 if (cpf_setgrant_direct(nic
->rx_iogrant
,
435 (vir_bytes
) &nic
->rx_iovec
,
436 1 * sizeof(iovec_s_t
), CPF_READ
) != OK
)
437 panic("Failed to set grant");
440 static void raw_recv_free(__unused
void * data
)
442 pbuf_free((struct pbuf
*) data
);
445 static void nic_op_close(struct socket
* sock
, __unused message
* m
)
447 struct nic
* nic
= (struct nic
*)sock
->data
;
449 debug_drv_print("socket %d", get_sock_num(sock
));
451 sock_dequeue_data_all(sock
, raw_recv_free
);
454 if (nic
->raw_socket
== sock
) {
455 nic
->raw_socket
= NULL
;
456 debug_drv_print("no active raw sock at %s", nic
->name
);
459 sock_reply_close(sock
, OK
);
462 static void nic_ioctl_set_conf(__unused
struct socket
* sock
,
466 nwio_ipconf_t ipconf
;
469 err
= copy_from_user(m
->m_source
, &ipconf
, sizeof(ipconf
),
470 (cp_grant_id_t
) m
->IO_GRANT
, 0);
474 if (ipconf
.nwic_flags
& NWIC_IPADDR_SET
)
475 netif_set_ipaddr(&nic
->netif
,
476 (ip_addr_t
*)&ipconf
.nwic_ipaddr
);
477 if (ipconf
.nwic_flags
& NWIC_NETMASK_SET
)
478 netif_set_netmask(&nic
->netif
,
479 (ip_addr_t
*)&ipconf
.nwic_netmask
);
480 nic
->flags
= ipconf
.nwic_flags
;
481 if (nic
->flags
& NWEO_EN_BROAD
)
482 nic
->netif
.flags
|= NETIF_FLAG_BROADCAST
;
487 static void nic_ioctl_get_conf(__unused
struct socket
* sock
,
491 nwio_ipconf_t ipconf
;
494 ipconf
.nwic_flags
= nic
->flags
;
495 ipconf
.nwic_ipaddr
= nic
->netif
.ip_addr
.addr
;
496 ipconf
.nwic_netmask
= nic
->netif
.netmask
.addr
;
497 ipconf
.nwic_mtu
= nic
->netif
.mtu
;
499 err
= copy_to_user(m
->m_source
, &ipconf
, sizeof(ipconf
),
500 (cp_grant_id_t
) m
->IO_GRANT
, 0);
507 static void nic_ioctl_set_gateway(__unused
struct socket
* sock
,
514 err
= copy_from_user(m
->m_source
, &route
, sizeof(route
),
515 (cp_grant_id_t
) m
->IO_GRANT
, 0);
519 netif_set_gw(&nic
->netif
, (ip_addr_t
*)&route
.nwr_gateway
);
524 static void nic_ioctl_get_ethstat(__unused
struct socket
* sock
,
529 nwio_ethstat_t ethstat
;
531 debug_drv_print("device /dev/%s", nic
->name
);
533 * The device is not up yet, there is nothing to report or it is not
536 if (!nic
->netif
.flags
& NETIF_FLAG_UP
||
537 !(nic
->netif
.flags
& (NETIF_FLAG_ETHERNET
|
538 NETIF_FLAG_ETHARP
))) {
539 printf("LWIP no such device FUCK\n");
540 send_reply(m
, ENODEV
);
544 memset(ðstat
, 0, sizeof(ethstat
));
545 memcpy(ðstat
.nwes_addr
, nic
->netif
.hwaddr
, 6);
547 err
= copy_to_user(m
->m_source
, ðstat
, sizeof(ethstat
),
548 (cp_grant_id_t
) m
->IO_GRANT
, 0);
555 static void nic_ioctl_set_ethopt(struct socket
* sock
,
560 nwio_ethopt_t ethopt
;
565 send_reply(m
, EINVAL
);
569 debug_drv_print("device /dev/%s", nic
->name
);
571 * The device is not up yet, there is nothing to report or it is not
574 if (!nic
->netif
.flags
& NETIF_FLAG_UP
||
575 !(nic
->netif
.flags
& (NETIF_FLAG_ETHERNET
|
576 NETIF_FLAG_ETHARP
))) {
577 send_reply(m
, ENODEV
);
581 err
= copy_from_user(m
->m_source
, ðopt
, sizeof(ethopt
),
582 (cp_grant_id_t
) m
->IO_GRANT
, 0);
586 /* we want to get data from this sock */
587 if (ethopt
.nweo_flags
& NWEO_COPY
) {
588 if (nic
->raw_socket
) {
589 send_reply(m
, EBUSY
);
593 nic
->raw_socket
= sock
;
594 debug_drv_print("active raw sock %d at %s",
595 get_sock_num(sock
), nic
->name
);
601 static void nic_do_ioctl(struct socket
* sock
, struct nic
* nic
, message
* m
)
603 debug_print("device /dev/%s req %c %d %d",
605 (m
->REQUEST
>> 8) & 0xff,
607 (m
->REQUEST
>> 16) & _IOCPARM_MASK
);
609 debug_drv_print("socket %d", sock
? get_sock_num(sock
) : -1);
611 switch (m
->REQUEST
) {
613 nic_ioctl_set_conf(sock
, nic
, m
);
616 nic_ioctl_get_conf(sock
, nic
, m
);
619 nic_ioctl_set_gateway(sock
, nic
, m
);
622 nic_ioctl_get_ethstat(sock
, nic
, m
);
625 nic_ioctl_set_ethopt(sock
, nic
, m
);
628 send_reply(m
, EBADIOCTL
);
633 void nic_default_ioctl(message
*m
)
635 struct nic
* nic
= lookup_nic_default();
638 debug_print("No default nic, reporting error");
639 send_reply(m
, EBADIOCTL
);
643 nic_do_ioctl(NULL
, nic
, m
);
646 static void nic_op_ioctl(struct socket
* sock
, message
* m
, __unused
int blk
)
648 nic_do_ioctl(sock
, (struct nic
*)sock
->data
, m
);
651 static void nic_op_read(struct socket
* sock
, message
* m
, int blk
)
653 debug_drv_print("sock num %d", get_sock_num(sock
));
655 if (sock
->recv_head
) {
656 /* data available receive immeditely */
661 pbuf
= sock
->recv_head
->data
;
663 ret
= raw_receive(m
, pbuf
);
666 sock_dequeue_data(sock
);
667 sock
->recv_data_size
-= pbuf
->tot_len
;
670 sock_reply(sock
, ret
);
672 send_reply(m
, EAGAIN
);
674 /* store the message so we know how to reply */
676 /* operation is being processes */
677 sock
->flags
|= SOCK_FLG_OP_PENDING
;
679 debug_print("no data to read, suspending");
683 static void nic_op_write(struct socket
* sock
, message
* m
, __unused
int blk
)
687 struct nic
* nic
= (struct nic
*)sock
->data
;
690 debug_print("device %s data size %d", nic
->name
,
691 get_sock_num(sock
), m
->COUNT
);
693 pbuf
= pbuf_alloc(PBUF_RAW
, m
->COUNT
, PBUF_RAM
);
699 if ((ret
= copy_from_user(m
->m_source
, pbuf
->payload
, m
->COUNT
,
700 (cp_grant_id_t
) m
->IO_GRANT
, 0)) != OK
) {
705 if ((ret
= nic
->netif
.linkoutput(&nic
->netif
, pbuf
) != ERR_OK
)) {
706 debug_print("raw linkoutput failed %d", ret
);
715 sock_reply(sock
, ret
);
718 static struct sock_ops nic_ops
= {
719 .write
= nic_op_write
,
721 .close
= nic_op_close
,
722 .ioctl
= nic_op_ioctl
,
723 .select
= generic_op_select
,
724 .select_reply
= generic_op_select_reply
727 void nic_open(message
*m
)
729 struct socket
* sock
;
731 debug_print("device %d", m
->DEVICE
);
733 if (m
->DEVICE
> MAX_DEVS
|| devices
[m
->DEVICE
].drv_ep
== NONE
) {
734 send_reply_open(m
, ENODEV
);
738 sock
= get_unused_sock();
741 send_reply(m
, ENODEV
);
744 if (sock
->ops
!= NULL
) {
745 send_reply(m
, EBUSY
);
749 sock
->ops
= &nic_ops
;
750 sock
->select_ep
= NONE
;
751 sock
->recv_data_size
= 0;
752 sock
->data
= &devices
[m
->DEVICE
];
754 send_reply_open(m
, get_sock_num(sock
));
757 static int driver_pkt_enqueue(struct packet_q
** head
,
758 struct packet_q
** tail
,
761 struct packet_q
* pkt
;
764 pkt
= (struct packet_q
*) malloc(sizeof(struct packet_q
) + pbuf
->tot_len
);
769 pkt
->buf_len
= pbuf
->tot_len
;
771 for (b
= pkt
->buf
; pbuf
; pbuf
= pbuf
->next
) {
772 memcpy(b
, pbuf
->payload
, pbuf
->len
);
786 int driver_tx_enqueue(struct nic
* nic
, struct pbuf
* pbuf
)
788 debug_print("device /dev/%s", nic
->name
);
789 return driver_pkt_enqueue(&nic
->tx_head
, &nic
->tx_tail
, pbuf
);
792 static void driver_pkt_dequeue(struct packet_q
** head
,
793 struct packet_q
** tail
)
795 struct packet_q
* pkt
;
797 /* we always dequeue only if there is something to dequeue */
802 if ((*head
= pkt
->next
) == NULL
)
808 void driver_tx_dequeue(struct nic
* nic
)
810 debug_print("device /dev/%s", nic
->name
);
811 driver_pkt_dequeue(&nic
->tx_head
, &nic
->tx_tail
);
814 struct packet_q
* driver_tx_head(struct nic
* nic
)
816 debug_print("device /dev/%s", nic
->name
);