4 Created: Jan 2, 1992 by Philip Homburg
6 Copyright 1995 Philip Homburg
10 #include <minix/safecopies.h>
12 #include "osdep_eth.h"
13 #include "generic/type.h"
15 #include "generic/assert.h"
16 #include "generic/buf.h"
17 #include "generic/clock.h"
18 #include "generic/eth.h"
19 #include "generic/eth_int.h"
20 #include "generic/sr.h"
24 static void setup_read(eth_port_t
*eth_port
);
25 static void read_int(eth_port_t
*eth_port
, int count
);
26 static void eth_issue_send(eth_port_t
*eth_port
);
27 static void write_int(eth_port_t
*eth_port
);
28 static void eth_restart(eth_port_t
*eth_port
, endpoint_t endpoint
);
29 static void send_getstat(eth_port_t
*eth_port
);
35 eth_port_t
*eth_port
, *rep
;
38 /* First initialize normal ethernet interfaces */
39 for (i
= 0, ecp
= eth_conf
, eth_port
= eth_port_table
;
40 i
<eth_conf_nr
; i
++, ecp
++, eth_port
++)
42 /* Set all grants to invalid */
43 for (j
= 0; j
<IOVEC_NR
; j
++)
44 eth_port
->etp_osdep
.etp_wr_iovec
[j
].iov_grant
= -1;
45 eth_port
->etp_osdep
.etp_wr_vec_grant
= -1;
46 for (j
= 0; j
<RD_IOVEC
; j
++)
47 eth_port
->etp_osdep
.etp_rd_iovec
[j
].iov_grant
= -1;
48 eth_port
->etp_osdep
.etp_rd_vec_grant
= -1;
50 eth_port
->etp_osdep
.etp_state
= OEPS_INIT
;
51 eth_port
->etp_osdep
.etp_flags
= OEPF_EMPTY
;
52 eth_port
->etp_osdep
.etp_stat_gid
= -1;
53 eth_port
->etp_osdep
.etp_stat_buf
= NULL
;
59 for (j
= 0; j
<IOVEC_NR
; j
++)
61 if (cpf_getgrants(&gid
, 1) != 1)
64 "osdep_eth_init: cpf_getgrants failed: %d\n",
67 eth_port
->etp_osdep
.etp_wr_iovec
[j
].iov_grant
= gid
;
69 if (cpf_getgrants(&gid
, 1) != 1)
72 "osdep_eth_init: cpf_getgrants failed: %d\n",
75 eth_port
->etp_osdep
.etp_wr_vec_grant
= gid
;
76 for (j
= 0; j
<RD_IOVEC
; j
++)
78 if (cpf_getgrants(&gid
, 1) != 1)
81 "osdep_eth_init: cpf_getgrants failed: %d\n",
84 eth_port
->etp_osdep
.etp_rd_iovec
[j
].iov_grant
= gid
;
86 if (cpf_getgrants(&gid
, 1) != 1)
89 "osdep_eth_init: cpf_getgrants failed: %d\n",
92 eth_port
->etp_osdep
.etp_rd_vec_grant
= gid
;
94 eth_port
->etp_osdep
.etp_task
= NONE
;
95 eth_port
->etp_osdep
.etp_recvconf
= 0;
96 ev_init(ð_port
->etp_osdep
.etp_recvev
);
98 sr_add_minor(if2minor(ecp
->ec_ifno
, ETH_DEV_OFF
),
99 i
, eth_open
, eth_close
, eth_read
,
100 eth_write
, eth_ioctl
, eth_cancel
, eth_select
);
102 eth_port
->etp_flags
|= EPF_ENABLED
;
103 eth_port
->etp_vlan
= 0;
104 eth_port
->etp_vlan_port
= NULL
;
105 eth_port
->etp_wr_pack
= 0;
106 eth_port
->etp_rd_pack
= 0;
109 /* And now come the VLANs */
110 for (i
= 0, ecp
= eth_conf
, eth_port
= eth_port_table
;
111 i
<eth_conf_nr
; i
++, ecp
++, eth_port
++)
113 if (!eth_is_vlan(ecp
))
116 eth_port
->etp_osdep
.etp_task
= NONE
;
117 ev_init(ð_port
->etp_osdep
.etp_recvev
);
120 assert(rport
>= 0 && rport
< eth_conf_nr
);
121 rep
= ð_port_table
[rport
];
122 if (!(rep
->etp_flags
& EPF_ENABLED
))
125 "eth%d: underlying ethernet device %d not enabled",
129 if (rep
->etp_vlan
!= 0)
132 "eth%d: underlying ethernet device %d is a VLAN",
137 if (rep
->etp_flags
& EPF_GOT_ADDR
)
139 eth_port
->etp_ethaddr
= rep
->etp_ethaddr
;
140 printf("osdep_eth_init: setting EPF_GOT_ADDR\n");
141 eth_port
->etp_flags
|= EPF_GOT_ADDR
;
144 sr_add_minor(if2minor(ecp
->ec_ifno
, ETH_DEV_OFF
),
145 i
, eth_open
, eth_close
, eth_read
,
146 eth_write
, eth_ioctl
, eth_cancel
, eth_select
);
148 eth_port
->etp_flags
|= EPF_ENABLED
;
149 eth_port
->etp_vlan
= ecp
->ec_vlan
;
150 eth_port
->etp_vlan_port
= rep
;
151 assert(eth_port
->etp_vlan
!= 0);
152 eth_port
->etp_wr_pack
= 0;
153 eth_port
->etp_rd_pack
= 0;
154 eth_reg_vlan(rep
, eth_port
);
158 void eth_write_port(eth_port
, pack
)
159 eth_port_t
*eth_port
;
162 assert(!no_ethWritePort
);
163 assert(!eth_port
->etp_vlan
);
165 assert(eth_port
->etp_wr_pack
== NULL
);
166 eth_port
->etp_wr_pack
= pack
;
168 if (eth_port
->etp_osdep
.etp_state
!= OEPS_IDLE
)
170 eth_port
->etp_osdep
.etp_flags
|= OEPF_NEED_SEND
;
175 eth_issue_send(eth_port
);
178 void eth_rec(message
*m
)
180 int i
, r
, m_type
, flags
;
181 eth_port_t
*loc_port
, *vlan_port
;
185 assert(m_type
== DL_CONF_REPLY
|| m_type
== DL_TASK_REPLY
||
186 m_type
== DL_STAT_REPLY
);
188 for (i
=0, loc_port
= eth_port_table
; i
<eth_conf_nr
; i
++, loc_port
++)
190 if (loc_port
->etp_osdep
.etp_task
== m
->m_source
)
193 if (i
>= eth_conf_nr
)
195 printf("eth_rec: message 0x%x from unknown driver %d\n",
196 m_type
, m
->m_source
);
200 if (loc_port
->etp_osdep
.etp_state
== OEPS_CONF_SENT
)
202 if (m_type
== DL_TASK_REPLY
)
206 if (flags
& DL_PACK_SEND
)
208 if (flags
& DL_PACK_RECV
)
209 read_int(loc_port
, m
->DL_COUNT
);
213 if (m_type
!= DL_CONF_REPLY
)
216 "eth_rec: got bad message type 0x%x from %d in CONF state\n",
217 m_type
, m
->m_source
);
224 ip_warning(("eth_rec: DL_CONF returned error %d\n",
227 /* Just leave it in limbo. Nothing more we can do. */
231 loc_port
->etp_osdep
.etp_flags
&= ~OEPF_NEED_CONF
;
232 loc_port
->etp_osdep
.etp_state
= OEPS_IDLE
;
233 loc_port
->etp_flags
|= EPF_ENABLED
;
235 loc_port
->etp_ethaddr
= *(ether_addr_t
*)m
->DL_HWADDR
;
236 if (!(loc_port
->etp_flags
& EPF_GOT_ADDR
))
238 loc_port
->etp_flags
|= EPF_GOT_ADDR
;
240 printf("eth_rec: calling eth_restart_ioctl\n");
242 eth_restart_ioctl(loc_port
);
244 /* Also update any VLANs on this device */
245 for (i
=0, vlan_port
= eth_port_table
; i
<eth_conf_nr
;
248 if (!(vlan_port
->etp_flags
& EPF_ENABLED
))
250 if (vlan_port
->etp_vlan_port
!= loc_port
)
253 vlan_port
->etp_ethaddr
= loc_port
->etp_ethaddr
;
254 vlan_port
->etp_flags
|= EPF_GOT_ADDR
;
255 eth_restart_ioctl(vlan_port
);
258 if (!(loc_port
->etp_flags
& EPF_READ_IP
))
259 setup_read (loc_port
);
262 if (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_SEND
)
264 printf("eth_rec(conf): OEPF_NEED_SEND is set\n");
266 if (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_RECV
)
268 printf("eth_rec(conf): OEPF_NEED_RECV is set\n");
270 if (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_STAT
)
272 printf("eth_rec(conf): OEPF_NEED_STAT is set\n");
278 if (loc_port
->etp_osdep
.etp_state
== OEPS_GETSTAT_SENT
)
280 if (m_type
!= DL_STAT_REPLY
)
283 "eth_rec: got bad message type 0x%x from %d in GETSTAT state\n",
284 m_type
, m
->m_source
);
288 loc_port
->etp_osdep
.etp_state
= OEPS_IDLE
;
289 loc_port
->etp_osdep
.etp_flags
&= ~OEPF_NEED_STAT
;
291 assert(loc_port
->etp_osdep
.etp_stat_gid
!= -1);
292 cpf_revoke(loc_port
->etp_osdep
.etp_stat_gid
);
293 loc_port
->etp_osdep
.etp_stat_gid
= -1;
294 loc_port
->etp_osdep
.etp_stat_buf
= NULL
;
297 assert(loc_port
->etp_flags
& EPF_GOT_ADDR
);
298 eth_restart_ioctl(loc_port
);
301 if (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_SEND
)
303 printf("eth_rec(stat): OEPF_NEED_SEND is set\n");
305 if (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_RECV
)
307 printf("eth_rec(stat): OEPF_NEED_RECV is set\n");
309 if (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_CONF
)
311 printf("eth_rec(stat): OEPF_NEED_CONF is set\n");
316 if (loc_port
->etp_osdep
.etp_state
== OEPS_IDLE
&&
317 (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_CONF
))
319 eth_set_rec_conf(loc_port
,
320 loc_port
->etp_osdep
.etp_recvconf
);
325 assert(loc_port
->etp_osdep
.etp_state
== OEPS_IDLE
||
326 loc_port
->etp_osdep
.etp_state
== OEPS_RECV_SENT
||
327 loc_port
->etp_osdep
.etp_state
== OEPS_SEND_SENT
||
328 (printf("etp_state = %d\n", loc_port
->etp_osdep
.etp_state
), 0));
329 loc_port
->etp_osdep
.etp_state
= OEPS_IDLE
;
333 if (flags
& DL_PACK_SEND
)
335 if (flags
& DL_PACK_RECV
)
336 read_int(loc_port
, m
->DL_COUNT
);
338 if (loc_port
->etp_osdep
.etp_state
== OEPS_IDLE
&&
339 loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_SEND
)
341 loc_port
->etp_osdep
.etp_flags
&= ~OEPF_NEED_SEND
;
342 if (loc_port
->etp_wr_pack
)
343 eth_issue_send(loc_port
);
345 if (loc_port
->etp_osdep
.etp_state
== OEPS_IDLE
&&
346 (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_RECV
))
348 loc_port
->etp_osdep
.etp_flags
&= ~OEPF_NEED_RECV
;
349 if (!(loc_port
->etp_flags
& EPF_READ_IP
))
350 setup_read (loc_port
);
352 if (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_CONF
)
355 printf("eth_rec: OEPF_NEED_CONF is set\n");
358 if (loc_port
->etp_osdep
.etp_state
== OEPS_IDLE
&&
359 (loc_port
->etp_osdep
.etp_flags
& OEPF_NEED_STAT
))
361 send_getstat(loc_port
);
365 void eth_check_driver(char *label
, endpoint_t endpoint
)
368 eth_port_t
*loc_port
;
369 struct eth_conf
*ecp
;
371 /* Re-init ethernet interface */
372 for (i
= 0, ecp
= eth_conf
, loc_port
= eth_port_table
;
373 i
<eth_conf_nr
; i
++, ecp
++, loc_port
++)
375 if (eth_is_vlan(ecp
))
378 if (strcmp(ecp
->ec_label
, label
) != 0)
383 eth_restart(loc_port
, endpoint
);
387 int eth_get_stat(eth_port
, eth_stat
)
388 eth_port_t
*eth_port
;
389 eth_stat_t
*eth_stat
;
393 assert(!eth_port
->etp_vlan
);
395 if (eth_port
->etp_osdep
.etp_flags
& OEPF_NEED_STAT
)
396 ip_panic(( "eth_get_stat: getstat already in progress" ));
398 gid
= cpf_grant_direct(eth_port
->etp_osdep
.etp_task
,
399 (vir_bytes
)eth_stat
, sizeof(*eth_stat
), CPF_WRITE
);
402 ip_panic(( "eth_get_stat: cpf_grant_direct failed: %d\n",
405 assert(eth_port
->etp_osdep
.etp_stat_gid
== -1);
406 eth_port
->etp_osdep
.etp_stat_gid
= gid
;
407 eth_port
->etp_osdep
.etp_stat_buf
= eth_stat
;
409 if (eth_port
->etp_osdep
.etp_state
!= OEPS_IDLE
)
411 eth_port
->etp_osdep
.etp_flags
|= OEPF_NEED_STAT
;
415 send_getstat(eth_port
);
420 void eth_set_rec_conf (eth_port
, flags
)
421 eth_port_t
*eth_port
;
425 unsigned dl_flags
, mask
;
428 assert(!eth_port
->etp_vlan
);
430 if (!(eth_port
->etp_flags
& EPF_GOT_ADDR
))
432 /* We have never seen the device. */
434 printf("eth_set_rec_conf: waiting for device to appear\n");
439 if (eth_port
->etp_osdep
.etp_state
!= OEPS_IDLE
)
443 "eth_set_rec_conf: setting OEPF_NEED_CONF, state = %d\n",
444 eth_port
->etp_osdep
.etp_state
);
446 eth_port
->etp_osdep
.etp_flags
|= OEPF_NEED_CONF
;
450 mask
= NWEO_EN_BROAD
| NWEO_EN_MULTI
| NWEO_EN_PROMISC
;
451 if ((eth_port
->etp_osdep
.etp_recvconf
& mask
) == (flags
& mask
))
453 /* No change for the driver, so don't send an update */
457 eth_port
->etp_osdep
.etp_recvconf
= flags
;
459 if (flags
& NWEO_EN_BROAD
)
460 dl_flags
|= DL_BROAD_REQ
;
461 if (flags
& NWEO_EN_MULTI
)
462 dl_flags
|= DL_MULTI_REQ
;
463 if (flags
& NWEO_EN_PROMISC
)
464 dl_flags
|= DL_PROMISC_REQ
;
466 mess
.m_type
= DL_CONF
;
467 mess
.DL_MODE
= dl_flags
;
469 assert(eth_port
->etp_osdep
.etp_state
== OEPS_IDLE
);
470 r
= asynsend(eth_port
->etp_osdep
.etp_task
, &mess
);
471 eth_port
->etp_osdep
.etp_state
= OEPS_CONF_SENT
;
475 printf("eth_set_rec_conf: asynsend to %d failed: %d\n",
476 eth_port
->etp_osdep
.etp_task
, r
);
481 static void eth_issue_send(eth_port
)
482 eth_port_t
*eth_port
;
485 acc_t
*pack
, *pack_ptr
;
489 iovec
= eth_port
->etp_osdep
.etp_wr_iovec
;
490 pack
= eth_port
->etp_wr_pack
;
492 for (i
=0, pack_ptr
= pack
; i
<IOVEC_NR
&& pack_ptr
; i
++,
493 pack_ptr
= pack_ptr
->acc_next
)
495 r
= cpf_setgrant_direct(iovec
[i
].iov_grant
,
496 eth_port
->etp_osdep
.etp_task
,
497 (vir_bytes
)ptr2acc_data(pack_ptr
),
498 (vir_bytes
)pack_ptr
->acc_length
,
503 "eth_write_port: cpf_setgrant_direct failed: %d\n",
506 pack_size
+= iovec
[i
].iov_size
= pack_ptr
->acc_length
;
510 pack
= bf_pack(pack
); /* packet is too fragmented */
511 eth_port
->etp_wr_pack
= pack
;
513 for (i
=0, pack_ptr
= pack
; i
<IOVEC_NR
&& pack_ptr
;
514 i
++, pack_ptr
= pack_ptr
->acc_next
)
516 r
= cpf_setgrant_direct(iovec
[i
].iov_grant
,
517 eth_port
->etp_osdep
.etp_task
,
518 (vir_bytes
)ptr2acc_data(pack_ptr
),
519 (vir_bytes
)pack_ptr
->acc_length
,
524 "eth_write_port: cpf_setgrant_direct failed: %d\n",
527 pack_size
+= iovec
[i
].iov_size
= pack_ptr
->acc_length
;
530 assert (i
< IOVEC_NR
);
531 assert (pack_size
>= ETH_MIN_PACK_SIZE
);
533 r
= cpf_setgrant_direct(eth_port
->etp_osdep
.etp_wr_vec_grant
,
534 eth_port
->etp_osdep
.etp_task
,
536 (vir_bytes
)(i
* sizeof(iovec
[0])),
541 "eth_write_port: cpf_setgrant_direct failed: %d\n",
544 m
.m_type
= DL_WRITEV_S
;
546 m
.DL_GRANT
= eth_port
->etp_osdep
.etp_wr_vec_grant
;
548 assert(eth_port
->etp_osdep
.etp_state
== OEPS_IDLE
);
549 r
= asynsend(eth_port
->etp_osdep
.etp_task
, &m
);
553 printf("eth_issue_send: send to %d failed: %d\n",
554 eth_port
->etp_osdep
.etp_task
, r
);
557 eth_port
->etp_osdep
.etp_state
= OEPS_SEND_SENT
;
560 static void write_int(eth_port_t
*eth_port
)
566 pack
= eth_port
->etp_wr_pack
;
569 printf("write_int: strange no packet on eth port %d\n",
570 (int)(eth_port
-eth_port_table
));
571 eth_restart_write(eth_port
);
575 eth_port
->etp_wr_pack
= NULL
;
577 eth_dst_ptr
= (u8_t
*)ptr2acc_data(pack
);
578 multicast
= (*eth_dst_ptr
& 1); /* low order bit indicates multicast */
579 if (multicast
|| (eth_port
->etp_osdep
.etp_recvconf
& NWEO_EN_PROMISC
))
581 assert(!no_ethWritePort
);
583 eth_arrive(eth_port
, pack
, bf_bufsize(pack
));
584 assert(no_ethWritePort
);
590 eth_restart_write(eth_port
);
593 static void read_int(eth_port
, count
)
594 eth_port_t
*eth_port
;
597 acc_t
*pack
, *pack_ptr
, *cut_pack
;
601 /* A buggy driver might try to feed us a reply for a request we never
602 * sent. Don't let this cause a crash further up.
604 if (!(eth_port
->etp_flags
& EPF_READ_IP
))
606 printf("mnx_eth`read_int: read reply with no read going on\n");
610 pack
= eth_port
->etp_rd_pack
;
611 eth_port
->etp_rd_pack
= NULL
;
613 /* Invalidate the grants first, so that the ethernet driver can no
614 * longer modify the contents of the packet.
616 iovec
= eth_port
->etp_osdep
.etp_rd_iovec
;
617 for (i
=0, pack_ptr
= pack
; i
<RD_IOVEC
&& pack_ptr
;
618 i
++, pack_ptr
= pack_ptr
->acc_next
)
620 r
= cpf_setgrant_disable(iovec
[i
].iov_grant
);
624 "mnx_eth`read_int: cpf_setgrant_disable failed: %d\n",
629 if (count
< ETH_MIN_PACK_SIZE
)
631 printf("mnx_eth`read_int: packet size too small (%d)\n",
635 else if (count
> ETH_MAX_PACK_SIZE_TAGGED
)
637 printf("mnx_eth`read_int: packet size too big (%d)\n",
643 cut_pack
= bf_cut(pack
, 0, count
);
646 assert(!no_ethWritePort
);
648 eth_arrive(eth_port
, cut_pack
, count
);
649 assert(no_ethWritePort
);
653 eth_port
->etp_flags
&= ~(EPF_READ_IP
|EPF_READ_SP
);
654 setup_read(eth_port
);
657 static void setup_read(eth_port
)
658 eth_port_t
*eth_port
;
660 acc_t
*pack
, *pack_ptr
;
665 assert(!eth_port
->etp_vlan
);
666 assert(!(eth_port
->etp_flags
& (EPF_READ_IP
|EPF_READ_SP
)));
668 if (eth_port
->etp_osdep
.etp_state
!= OEPS_IDLE
)
670 eth_port
->etp_osdep
.etp_flags
|= OEPF_NEED_RECV
;
675 assert (!eth_port
->etp_rd_pack
);
677 iovec
= eth_port
->etp_osdep
.etp_rd_iovec
;
678 pack
= bf_memreq (ETH_MAX_PACK_SIZE_TAGGED
);
680 for (i
=0, pack_ptr
= pack
; i
<RD_IOVEC
&& pack_ptr
;
681 i
++, pack_ptr
= pack_ptr
->acc_next
)
683 r
= cpf_setgrant_direct(iovec
[i
].iov_grant
,
684 eth_port
->etp_osdep
.etp_task
,
685 (vir_bytes
)ptr2acc_data(pack_ptr
),
686 (vir_bytes
)pack_ptr
->acc_length
,
691 "mnx_eth`setup_read: cpf_setgrant_direct failed: %d\n",
694 iovec
[i
].iov_size
= (vir_bytes
)pack_ptr
->acc_length
;
698 r
= cpf_setgrant_direct(eth_port
->etp_osdep
.etp_rd_vec_grant
,
699 eth_port
->etp_osdep
.etp_task
,
701 (vir_bytes
)(i
* sizeof(iovec
[0])),
706 "mnx_eth`setup_read: cpf_setgrant_direct failed: %d\n",
710 mess
.m_type
= DL_READV_S
;
712 mess
.DL_GRANT
= eth_port
->etp_osdep
.etp_rd_vec_grant
;
714 assert(eth_port
->etp_osdep
.etp_state
== OEPS_IDLE
);
716 r
= asynsend(eth_port
->etp_osdep
.etp_task
, &mess
);
717 eth_port
->etp_osdep
.etp_state
= OEPS_RECV_SENT
;
722 "mnx_eth`setup_read: asynsend to %d failed: %d\n",
723 eth_port
->etp_osdep
.etp_task
, r
);
725 eth_port
->etp_rd_pack
= pack
;
726 eth_port
->etp_flags
|= EPF_READ_IP
;
727 eth_port
->etp_flags
|= EPF_READ_SP
;
730 static void eth_restart(eth_port_t
*eth_port
, endpoint_t endpoint
)
733 unsigned flags
, dl_flags
;
737 eth_port
->etp_osdep
.etp_task
= endpoint
;
739 switch(eth_port
->etp_osdep
.etp_state
)
745 /* We can safely ignore the pending CONF, RECV, and SEND
746 * requests. If this is the first time that we see this
747 * driver at all, that's fine too.
749 eth_port
->etp_osdep
.etp_state
= OEPS_IDLE
;
751 case OEPS_GETSTAT_SENT
:
752 /* Set the OEPF_NEED_STAT to trigger a new request */
753 eth_port
->etp_osdep
.etp_flags
|= OEPF_NEED_STAT
;
754 eth_port
->etp_osdep
.etp_state
= OEPS_IDLE
;
758 /* If there is a pending GETSTAT request then we have to create a
761 if (eth_port
->etp_osdep
.etp_flags
& OEPF_NEED_STAT
)
763 assert(eth_port
->etp_osdep
.etp_stat_gid
!= -1);
764 cpf_revoke(eth_port
->etp_osdep
.etp_stat_gid
);
766 gid
= cpf_grant_direct(eth_port
->etp_osdep
.etp_task
,
767 (vir_bytes
)eth_port
->etp_osdep
.etp_stat_buf
,
768 sizeof(*eth_port
->etp_osdep
.etp_stat_buf
), CPF_WRITE
);
772 "eth_restart: cpf_grant_direct failed: %d\n",
775 eth_port
->etp_osdep
.etp_stat_gid
= gid
;
778 flags
= eth_port
->etp_osdep
.etp_recvconf
;
780 if (flags
& NWEO_EN_BROAD
)
781 dl_flags
|= DL_BROAD_REQ
;
782 if (flags
& NWEO_EN_MULTI
)
783 dl_flags
|= DL_MULTI_REQ
;
784 if (flags
& NWEO_EN_PROMISC
)
785 dl_flags
|= DL_PROMISC_REQ
;
786 mess
.m_type
= DL_CONF
;
787 mess
.DL_MODE
= dl_flags
;
789 compare(eth_port
->etp_osdep
.etp_state
, ==, OEPS_IDLE
);
790 r
= asynsend(eth_port
->etp_osdep
.etp_task
, &mess
);
794 "eth_restart: send to ethernet task %d failed: %d\n",
795 eth_port
->etp_osdep
.etp_task
, r
);
798 eth_port
->etp_osdep
.etp_state
= OEPS_CONF_SENT
;
800 if (eth_port
->etp_wr_pack
)
802 bf_afree(eth_port
->etp_wr_pack
);
803 eth_port
->etp_wr_pack
= NULL
;
804 eth_restart_write(eth_port
);
806 if (eth_port
->etp_rd_pack
)
808 bf_afree(eth_port
->etp_rd_pack
);
809 eth_port
->etp_rd_pack
= NULL
;
810 eth_port
->etp_flags
&= ~(EPF_READ_IP
|EPF_READ_SP
);
815 static void send_getstat(eth_port
)
816 eth_port_t
*eth_port
;
821 mess
.m_type
= DL_GETSTAT_S
;
822 mess
.DL_GRANT
= eth_port
->etp_osdep
.etp_stat_gid
;
824 assert(eth_port
->etp_osdep
.etp_state
== OEPS_IDLE
);
826 r
= asynsend(eth_port
->etp_osdep
.etp_task
, &mess
);
827 eth_port
->etp_osdep
.etp_state
= OEPS_GETSTAT_SENT
;
830 ip_panic(( "eth_get_stat: asynsend failed: %d", r
));
834 * $PchId: mnx_eth.c,v 1.16 2005/06/28 14:24:37 philip Exp $