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
;
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(struct sock_req
*req
,
265 unsigned int rem_len
= req
->size
;
266 unsigned int 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(req
->endpt
, p
->payload
, cp_len
,
276 req
->grant
, written
);
284 debug_print("copied %d bytes\n", 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
)
296 debug_print("socket num : %ld", get_sock_num(sock
));
298 if (sock
->flags
& SOCK_FLG_OP_PENDING
) {
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
;
310 /* Do not enqueue more data than allowed */
311 if (sock
->recv_data_size
> RAW_BUF_SIZE
) {
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");
325 if (pbuf_copy(pbuf_new
, pbuf
) != ERR_OK
) {
326 debug_print("LWIP : cannot copy pbuf\n");
331 * If we didn't managed to enqueue the packet we report it as not
334 if (sock_enqueue_data(sock
, pbuf_new
, pbuf_new
->tot_len
) != OK
) {
341 static void nic_pkt_received(struct nic
* nic
, unsigned int size
)
343 assert(nic
->netif
.input
);
346 print_pkt((unsigned char *) nic
->rx_pbuf
->payload
, 64 /*nic->rx_pbuf->len */);
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
);
354 driver_setup_read(nic
);
357 void driver_request(message
* m
)
361 if ((nic
= lookup_nic_by_drv_ep(m
->m_source
)) == NULL
) {
362 printf("LWIP : request from unknown driver %d\n", m
->m_source
);
368 if (m
->DL_STAT
== OK
)
373 if (!(m->DL_FLAGS & DL_PACK_SEND) && !(m->DL_FLAGS & DL_PACK_RECV)) {
374 printf("void reply from driver\n");
378 if (m
->DL_FLAGS
& DL_PACK_SEND
)
380 if (m
->DL_FLAGS
& DL_PACK_RECV
)
381 nic_pkt_received(nic
, m
->DL_COUNT
);
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
)
395 nic
= lookup_nic_by_drv_name(label
);
398 debug_print("LWIP : driver '%s' / %d is up for /dev/%s\n",
399 label
, ep
, nic
->name
);
402 printf("LWIP : WARNING unexpected driver '%s' up event\n",
407 nic
->state
= DRV_IDLE
;
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
);
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
434 pbuf_free(nic
->rx_pbuf
);
438 /* prepare the RX grant once and forever */
439 if (cpf_setgrant_direct(nic
->rx_iogrant
,
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
);
460 if (nic
->raw_socket
== sock
) {
461 nic
->raw_socket
= NULL
;
462 debug_drv_print("no active raw sock at %s", nic
->name
);
468 static int nic_ioctl_set_conf(__unused
struct socket
* sock
,
473 nwio_ipconf_t ipconf
;
476 err
= copy_from_user(endpt
, &ipconf
, sizeof(ipconf
), grant
, 0);
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
;
494 static int nic_ioctl_get_conf(__unused
struct socket
* sock
,
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
,
517 err
= copy_from_user(endpt
, &route
, sizeof(route
), grant
, 0);
521 netif_set_gw(&nic
->netif
, (ip_addr_t
*)&route
.nwr_gateway
);
526 static int nic_ioctl_get_ethstat(__unused
struct socket
* sock
,
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
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");
545 memset(ðstat
, 0, sizeof(ethstat
));
546 memcpy(ðstat
.nwes_addr
, nic
->netif
.hwaddr
, 6);
548 return copy_to_user(endpt
, ðstat
, sizeof(ethstat
), grant
, 0);
551 static int nic_ioctl_set_ethopt(struct socket
* sock
,
557 nwio_ethopt_t ethopt
;
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
569 if (!nic
->netif
.flags
& NETIF_FLAG_UP
||
570 !(nic
->netif
.flags
& (NETIF_FLAG_ETHERNET
|
571 NETIF_FLAG_ETHARP
))) {
575 err
= copy_from_user(endpt
, ðopt
, sizeof(ethopt
), grant
, 0);
579 /* we want to get data from this sock */
580 if (ethopt
.nweo_flags
& NWEO_COPY
) {
584 nic
->raw_socket
= sock
;
585 debug_drv_print("active raw sock %ld at %s",
586 get_sock_num(sock
), nic
->name
);
592 static int nic_do_ioctl(struct socket
* sock
, struct nic
* nic
,
593 struct sock_req
* req
)
597 debug_print("device /dev/%s req %c %ld %ld",
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);
606 r
= nic_ioctl_set_conf(sock
, nic
, req
->endpt
, req
->grant
);
609 r
= nic_ioctl_get_conf(sock
, nic
, req
->endpt
, req
->grant
);
612 r
= nic_ioctl_set_gateway(sock
, nic
, req
->endpt
, req
->grant
);
615 r
= nic_ioctl_get_ethstat(sock
, nic
, req
->endpt
, req
->grant
);
618 r
= nic_ioctl_set_ethopt(sock
, nic
, req
->endpt
, req
->grant
);
627 int nic_default_ioctl(struct sock_req
*req
)
629 struct nic
* nic
= lookup_nic_default();
632 debug_print("No default nic, reporting error");
636 return nic_do_ioctl(NULL
, nic
, req
);
639 static int nic_op_ioctl(struct socket
* sock
, struct sock_req
* req
,
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 */
655 pbuf
= sock
->recv_head
->data
;
657 ret
= raw_receive(req
, pbuf
);
660 sock_dequeue_data(sock
);
661 sock
->recv_data_size
-= pbuf
->tot_len
;
668 /* store the request so we know how to reply */
670 /* operation is being processes */
671 sock
->flags
|= SOCK_FLG_OP_PENDING
;
673 debug_print("no data to read, suspending");
678 static int nic_op_write(struct socket
* sock
, struct sock_req
* req
,
683 struct nic
* nic
= (struct nic
*)sock
->data
;
686 debug_print("device %s data size %u", nic
->name
, req
->size
);
688 pbuf
= pbuf_alloc(PBUF_RAW
, req
->size
, PBUF_RAM
);
692 if ((ret
= copy_from_user(req
->endpt
, pbuf
->payload
, req
->size
,
693 req
->grant
, 0)) != OK
) {
698 if ((ret
= nic
->netif
.linkoutput(&nic
->netif
, pbuf
) != ERR_OK
)) {
699 debug_print("raw linkoutput failed %d", ret
);
709 static struct sock_ops nic_ops
= {
710 .write
= nic_op_write
,
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
)
727 sock
= get_unused_sock();
731 if (sock
->ops
!= NULL
)
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
,
746 struct packet_q
* pkt
;
749 pkt
= (struct packet_q
*) malloc(sizeof(struct packet_q
) + pbuf
->tot_len
);
754 pkt
->buf_len
= pbuf
->tot_len
;
756 for (b
= pkt
->buf
; pbuf
; pbuf
= pbuf
->next
) {
757 memcpy(b
, pbuf
->payload
, pbuf
->len
);
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 */
787 if ((*head
= pkt
->next
) == NULL
)
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
);