1 /*
2 inet/mnx_eth.c
3
4 Created: Jan 2, 1992 by Philip Homburg
5
6 Copyright 1995 Philip Homburg
7 */
8
9 #include "inet.h"
10 #include "proto.h"
11 #include "osdep_eth.h"
12 #include "generic/type.h"
13
14 #include "generic/assert.h"
15 #include "generic/buf.h"
16 #include "generic/clock.h"
17 #include "generic/eth.h"
18 #include "generic/eth_int.h"
19 #include "generic/sr.h"
20
21 THIS_FILE
22
23 static int recv_debug= 0;
24
25 FORWARD _PROTOTYPE( void setup_read, (eth_port_t *eth_port) );
26 FORWARD _PROTOTYPE( void read_int, (eth_port_t *eth_port, int count) );
27 FORWARD _PROTOTYPE( void write_int, (eth_port_t *eth_port) );
28 FORWARD _PROTOTYPE( void eth_recvev, (event_t *ev, ev_arg_t ev_arg) );
29 FORWARD _PROTOTYPE( void eth_sendev, (event_t *ev, ev_arg_t ev_arg) );
30 FORWARD _PROTOTYPE( eth_port_t *find_port, (message *m) );
31 FORWARD _PROTOTYPE( void eth_restart, (eth_port_t *eth_port, int tasknr) );
32
33 PUBLIC void osdep_eth_init()
34 {
35 int i, r, tasknr, rport;
36 struct eth_conf *ecp;
37 eth_port_t *eth_port, *rep;
38 message mess;
39
40 /* First initialize normal ethernet interfaces */
41 for (i= 0, ecp= eth_conf, eth_port= eth_port_table;
42 i<eth_conf_nr; i++, ecp++, eth_port++)
43 {
44 if (eth_is_vlan(ecp))
45 continue;
46 #ifdef __minix_vmd
47 r= sys_findproc(ecp->ec_task, &tasknr, 0);
48 #else /* Minix 3 */
49 r = findproc(ecp->ec_task, &tasknr);
50 #endif
51 if (r != OK)
52 {
53 printf("eth%d: unable to find task %s: %d\n",
54 i, ecp->ec_task, r);
55 continue;
56 }
57
58 eth_port->etp_osdep.etp_port= ecp->ec_port;
59 eth_port->etp_osdep.etp_task= tasknr;
60 ev_init(ð_port->etp_osdep.etp_recvev);
61
62 mess.m_type= DL_INIT;
63 mess.DL_PORT= eth_port->etp_osdep.etp_port;
64 mess.DL_PROC= this_proc;
65 mess.DL_MODE= DL_NOMODE;
66
67 r= send(eth_port->etp_osdep.etp_task, &mess);
68 if (r<0)
69 {
70 printf(
71 "osdep_eth_init: unable to send to ethernet task, error= %d\n",
72 r);
73 continue;
74 }
75
76 r= receive(eth_port->etp_osdep.etp_task, &mess);
77 if (r<0)
78 {
79 printf(
80 "osdep_eth_init: unable to receive from ethernet task, error= %d\n",
81 r);
82 continue;
83 }
84
85 if (mess.m3_i1 == ENXIO)
86 {
87 printf(
88 "osdep_eth_init: no ethernet device at task=%d,port=%d\n",
89 eth_port->etp_osdep.etp_task,
90 eth_port->etp_osdep.etp_port);
91 continue;
92 }
93 if (mess.m3_i1 < 0)
94 ip_panic(("osdep_eth_init: DL_INIT returned error %d\n",
95 mess.m3_i1));
96
97 if (mess.m3_i1 != eth_port->etp_osdep.etp_port)
98 {
99 ip_panic((
100 "osdep_eth_init: got reply for wrong port (got %d, expected %d)\n",
101 mess.m3_i1, eth_port->etp_osdep.etp_port));
102 }
103
104 eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1;
105
106 sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
107 i, eth_open, eth_close, eth_read,
108 eth_write, eth_ioctl, eth_cancel, eth_select);
109
110 eth_port->etp_flags |= EPF_ENABLED;
111 eth_port->etp_vlan= 0;
112 eth_port->etp_vlan_port= NULL;
113 eth_port->etp_wr_pack= 0;
114 eth_port->etp_rd_pack= 0;
115 setup_read (eth_port);
116 }
117
118 /* And now come the VLANs */
119 for (i= 0, ecp= eth_conf, eth_port= eth_port_table;
120 i<eth_conf_nr; i++, ecp++, eth_port++)
121 {
122 if (!eth_is_vlan(ecp))
123 continue;
124
125 eth_port->etp_osdep.etp_port= ecp->ec_port;
126 eth_port->etp_osdep.etp_task= ANY;
127 ev_init(ð_port->etp_osdep.etp_recvev);
128
129 rport= eth_port->etp_osdep.etp_port;
130 assert(rport >= 0 && rport < eth_conf_nr);
131 rep= ð_port_table[rport];
132 if (!(rep->etp_flags & EPF_ENABLED))
133 {
134 printf(
135 "eth%d: underlying ethernet device %d not enabled",
136 i, rport);
137 continue;
138 }
139 if (rep->etp_vlan != 0)
140 {
141 printf(
142 "eth%d: underlying ethernet device %d is a VLAN",
143 i, rport);
144 continue;
145 }
146
147 eth_port->etp_ethaddr= rep->etp_ethaddr;
148
149 sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
150 i, eth_open, eth_close, eth_read,
151 eth_write, eth_ioctl, eth_cancel, eth_select);
152
153 eth_port->etp_flags |= EPF_ENABLED;
154 eth_port->etp_vlan= ecp->ec_vlan;
155 eth_port->etp_vlan_port= rep;
156 assert(eth_port->etp_vlan != 0);
157 eth_port->etp_wr_pack= 0;
158 eth_port->etp_rd_pack= 0;
159 eth_reg_vlan(rep, eth_port);
160 }
161 }
162
163 PUBLIC void eth_write_port(eth_port, pack)
164 eth_port_t *eth_port;
165 acc_t *pack;
166 {
167 eth_port_t *loc_port;
168 message mess1, block_msg;
169 int i, pack_size;
170 acc_t *pack_ptr;
171 iovec_t *iovec;
172 u8_t *eth_dst_ptr;
173 int multicast, r;
174 ev_arg_t ev_arg;
175
176 assert(!no_ethWritePort);
177 assert(!eth_port->etp_vlan);
178
179 assert(eth_port->etp_wr_pack == NULL);
180 eth_port->etp_wr_pack= pack;
181
182 iovec= eth_port->etp_osdep.etp_wr_iovec;
183 pack_size= 0;
184 for (i=0, pack_ptr= pack; i<IOVEC_NR && pack_ptr; i++,
185 pack_ptr= pack_ptr->acc_next)
186 {
187 iovec[i].iov_addr= (vir_bytes)ptr2acc_data(pack_ptr);
188 pack_size += iovec[i].iov_size= pack_ptr->acc_length;
189 }
190 if (i>= IOVEC_NR)
191 {
192 pack= bf_pack(pack); /* packet is too fragmented */
193 eth_port->etp_wr_pack= pack;
194 pack_size= 0;
195 for (i=0, pack_ptr= pack; i<IOVEC_NR && pack_ptr;
196 i++, pack_ptr= pack_ptr->acc_next)
197 {
198 iovec[i].iov_addr= (vir_bytes)ptr2acc_data(pack_ptr);
199 pack_size += iovec[i].iov_size= pack_ptr->acc_length;
200 }
201 }
202 assert (i< IOVEC_NR);
203 assert (pack_size >= ETH_MIN_PACK_SIZE);
204
205 if (i == 1)
206 {
207 /* simple packets can be sent using DL_WRITE instead of
208 * DL_WRITEV.
209 */
210 mess1.DL_COUNT= iovec[0].iov_size;
211 mess1.DL_ADDR= (char *)iovec[0].iov_addr;
212 mess1.m_type= DL_WRITE;
213 }
214 else
215 {
216 mess1.DL_COUNT= i;
217 mess1.DL_ADDR= (char *)iovec;
218 mess1.m_type= DL_WRITEV;
219 }
220 mess1.DL_PORT= eth_port->etp_osdep.etp_port;
221 mess1.DL_PROC= this_proc;
222 mess1.DL_MODE= DL_NOMODE;
223
224 for (;;)
225 {
226 r= sendrec(eth_port->etp_osdep.etp_task, &mess1);
227 if (r != ELOCKED)
228 break;
229
230 /* ethernet task is sending to this task, I hope */
231 r= receive(eth_port->etp_osdep.etp_task, &block_msg);
232 if (r < 0)
233 ip_panic(("unable to receive"));
234
235 loc_port= eth_port;
236 if (loc_port->etp_osdep.etp_port != block_msg.DL_PORT ||
237 loc_port->etp_osdep.etp_task != block_msg.m_source)
238 {
239 loc_port= find_port(&block_msg);
240 }
241 assert(block_msg.DL_STAT & (DL_PACK_SEND|DL_PACK_RECV));
242 if (block_msg.DL_STAT & DL_PACK_SEND)
243 {
244 assert(loc_port != eth_port);
245 loc_port->etp_osdep.etp_sendrepl= block_msg;
246 ev_arg.ev_ptr= loc_port;
247 ev_enqueue(&loc_port->etp_sendev, eth_sendev, ev_arg);
248 }
249 if (block_msg.DL_STAT & DL_PACK_RECV)
250 {
251 if (recv_debug)
252 {
253 printf(
254 "eth_write_port(block_msg): eth%d got DL_PACK_RECV\n",
255 loc_port-eth_port_table);
256 }
257 loc_port->etp_osdep.etp_recvrepl= block_msg;
258 ev_arg.ev_ptr= loc_port;
259 ev_enqueue(&loc_port->etp_osdep.etp_recvev,
260 eth_recvev, ev_arg);
261 }
262 }
263
264 if (r < 0)
265 {
266 printf("eth_write_port: sendrec to %d failed: %d\n",
267 eth_port->etp_osdep.etp_task, r);
268 return;
269 }
270
271 assert(mess1.m_type == DL_TASK_REPLY &&
272 mess1.DL_PORT == eth_port->etp_osdep.etp_port &&
273 mess1.DL_PROC == this_proc);
274 assert((mess1.DL_STAT >> 16) == OK);
275
276 if (mess1.DL_STAT & DL_PACK_RECV)
277 {
278 if (recv_debug)
279 {
280 printf(
281 "eth_write_port(mess1): eth%d got DL_PACK_RECV\n",
282 mess1.DL_PORT);
283 }
284 eth_port->etp_osdep.etp_recvrepl= mess1;
285 ev_arg.ev_ptr= eth_port;
286 ev_enqueue(ð_port->etp_osdep.etp_recvev, eth_recvev,
287 ev_arg);
288 }
289 if (!(mess1.DL_STAT & DL_PACK_SEND))
290 {
291 /* Packet is not yet sent. */
292 return;
293 }
294
295 /* If the port is in promiscuous mode or the packet is
296 * broad- or multicast, enqueue the reply packet.
297 */
298 eth_dst_ptr= (u8_t *)ptr2acc_data(pack);
299 multicast= (*eth_dst_ptr & 1); /* low order bit indicates multicast */
300 if (multicast || (eth_port->etp_osdep.etp_recvconf & NWEO_EN_PROMISC))
301 {
302 eth_port->etp_osdep.etp_sendrepl= mess1;
303 ev_arg.ev_ptr= eth_port;
304 ev_enqueue(ð_port->etp_sendev, eth_sendev, ev_arg);
305
306 /* Pretend that we didn't get a reply. */
307 return;
308 }
309
310 /* packet is sent */
311 bf_afree(eth_port->etp_wr_pack);
312 eth_port->etp_wr_pack= NULL;
313 }
314
315 PUBLIC void eth_rec(m)
316 message *m;
317 {
318 int i;
319 eth_port_t *loc_port;
320 int stat;
321
322 assert(m->m_type == DL_TASK_REPLY);
323
324 set_time (m->DL_CLCK);
325
326 for (i=0, loc_port= eth_port_table; i<eth_conf_nr; i++, loc_port++)
327 {
328 if (loc_port->etp_osdep.etp_port == m->DL_PORT &&
329 loc_port->etp_osdep.etp_task == m->m_source)
330 break;
331 }
332 if (i == eth_conf_nr)
333 {
334 ip_panic(("message from unknown source: %d:%d",
335 m->m_source, m->DL_PORT));
336 }
337
338 stat= m->DL_STAT & 0xffff;
339
340 assert(stat & (DL_PACK_SEND|DL_PACK_RECV));
341 if (stat & DL_PACK_SEND)
342 write_int(loc_port);
343 if (stat & DL_PACK_RECV)
344 {
345 if (recv_debug)
346 {
347 printf("eth_rec: eth%d got DL_PACK_RECV\n",
348 m->DL_PORT);
349 }
350 read_int(loc_port, m->DL_COUNT);
351 }
352 }
353
354 PUBLIC void eth_check_drivers(m)
355 message *m;
356 {
357 int i, r, tasknr;
358 struct eth_conf *ecp;
359 eth_port_t *eth_port;
360 char *drivername;
361
362 tasknr= m->m_source;
363 printf("eth_check_drivers: got a notification from %d\n", tasknr);
364
365 m->m_type= DL_GETNAME;
366 r= sendrec(tasknr, m);
367 if (r != OK)
368 {
369 printf("eth_check_drivers: sendrec to %d failed: %d\n",
370 tasknr, r);
371 return;
372 }
373 if (m->m_type != DL_NAME_REPLY)
374 {
375 printf(
376 "eth_check_drivers: got bad getname reply (%d) from %d\n",
377 m->m_type, tasknr);
378 return;
379 }
380
381 drivername= m->m3_ca1;
382 printf("eth_check_drivers: got name: %s\n", drivername);
383
384 /* Re-init ethernet interfaces */
385 for (i= 0, ecp= eth_conf, eth_port= eth_port_table;
386 i<eth_conf_nr; i++, ecp++, eth_port++)
387 {
388 if (eth_is_vlan(ecp))
389 continue;
390
391 if (strcmp(ecp->ec_task, drivername) != 0)
392 {
393 /* Wrong driver */
394 continue;
395 }
396
397 eth_restart(eth_port, tasknr);
398 }
399 }
400
401 PUBLIC int eth_get_stat(eth_port, eth_stat)
402 eth_port_t *eth_port;
403 eth_stat_t *eth_stat;
404 {
405 int r;
406 message mess, mlocked;
407
408 assert(!eth_port->etp_vlan);
409
410 mess.m_type= DL_GETSTAT;
411 mess.DL_PORT= eth_port->etp_osdep.etp_port;
412 mess.DL_PROC= this_proc;
413 mess.DL_ADDR= (char *)eth_stat;
414
415 for (;;)
416 {
417 r= sendrec(eth_port->etp_osdep.etp_task, &mess);
418 if (r != ELOCKED)
419 break;
420
421 r= receive(eth_port->etp_osdep.etp_task, &mlocked);
422 assert(r == OK);
423
424 compare(mlocked.m_type, ==, DL_TASK_REPLY);
425 eth_rec(&mlocked);
426 }
427
428 if (r != OK)
429 {
430 printf("eth_get_stat: sendrec to %d failed: %d\n",
431 eth_port->etp_osdep.etp_task, r);
432 return EIO;
433 }
434
435 assert(mess.m_type == DL_TASK_REPLY);
436
437 r= mess.DL_STAT >> 16;
438 assert (r == 0);
439
440 if (mess.DL_STAT)
441 {
442 eth_rec(&mess);
443 }
444 return OK;
445 }
446
447 PUBLIC void eth_set_rec_conf (eth_port, flags)
448 eth_port_t *eth_port;
449 u32_t flags;
450 {
451 int r;
452 unsigned dl_flags;
453 message mess, repl_mess;
454
455 assert(!eth_port->etp_vlan);
456
457 eth_port->etp_osdep.etp_recvconf= flags;
458 dl_flags= DL_NOMODE;
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;
465
466 mess.m_type= DL_INIT;
467 mess.DL_PORT= eth_port->etp_osdep.etp_port;
468 mess.DL_PROC= this_proc;
469 mess.DL_MODE= dl_flags;
470
471 do
472 {
473 r= sendrec(eth_port->etp_osdep.etp_task, &mess);
474 if (r == ELOCKED) /* etp_task is sending to this task,
475 I hope */
476 {
477 if (receive (eth_port->etp_osdep.etp_task,
478 &repl_mess)< 0)
479 {
480 ip_panic(("unable to receive"));
481 }
482
483 compare(repl_mess.m_type, ==, DL_TASK_REPLY);
484 eth_rec(&repl_mess);
485 }
486 } while (r == ELOCKED);
487
488 if (r < 0)
489 {
490 printf("eth_set_rec_conf: sendrec to %d failed: %d\n",
491 eth_port->etp_osdep.etp_task, r);
492 return;
493 }
494
495 assert (mess.m_type == DL_INIT_REPLY);
496 if (mess.m3_i1 != eth_port->etp_osdep.etp_port)
497 {
498 ip_panic(("got reply for wrong port"));
499 }
500 }
501
502 PRIVATE void write_int(eth_port)
503 eth_port_t *eth_port;
504 {
505 acc_t *pack;
506 int multicast;
507 u8_t *eth_dst_ptr;
508
509 pack= eth_port->etp_wr_pack;
510 eth_port->etp_wr_pack= NULL;
511
512 eth_dst_ptr= (u8_t *)ptr2acc_data(pack);
513 multicast= (*eth_dst_ptr & 1); /* low order bit indicates multicast */
514 if (multicast || (eth_port->etp_osdep.etp_recvconf & NWEO_EN_PROMISC))
515 {
516 assert(!no_ethWritePort);
517 no_ethWritePort= 1;
518 eth_arrive(eth_port, pack, bf_bufsize(pack));
519 assert(no_ethWritePort);
520 no_ethWritePort= 0;
521 }
522 else
523 bf_afree(pack);
524
525 eth_restart_write(eth_port);
526 }
527
528 PRIVATE void read_int(eth_port, count)
529 eth_port_t *eth_port;
530 int count;
531 {
532 acc_t *pack, *cut_pack;
533
534 pack= eth_port->etp_rd_pack;
535 eth_port->etp_rd_pack= NULL;
536
537 cut_pack= bf_cut(pack, 0, count);
538 bf_afree(pack);
539
540 assert(!no_ethWritePort);
541 no_ethWritePort= 1;
542 eth_arrive(eth_port, cut_pack, count);
543 assert(no_ethWritePort);
544 no_ethWritePort= 0;
545
546 eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP);
547 setup_read(eth_port);
548 }
549
550 PRIVATE void setup_read(eth_port)
551 eth_port_t *eth_port;
552 {
553 eth_port_t *loc_port;
554 acc_t *pack, *pack_ptr;
555 message mess1, block_msg;
556 iovec_t *iovec;
557 ev_arg_t ev_arg;
558 int i, r;
559
560 assert(!eth_port->etp_vlan);
561 assert(!(eth_port->etp_flags & (EPF_READ_IP|EPF_READ_SP)));
562
563 do
564 {
565 assert (!eth_port->etp_rd_pack);
566
567 iovec= eth_port->etp_osdep.etp_rd_iovec;
568 pack= bf_memreq (ETH_MAX_PACK_SIZE_TAGGED);
569
570 for (i=0, pack_ptr= pack; i<RD_IOVEC && pack_ptr;
571 i++, pack_ptr= pack_ptr->acc_next)
572 {
573 iovec[i].iov_addr= (vir_bytes)ptr2acc_data(pack_ptr);
574 iovec[i].iov_size= (vir_bytes)pack_ptr->acc_length;
575 }
576 assert (!pack_ptr);
577
578 mess1.m_type= DL_READV;
579 mess1.DL_PORT= eth_port->etp_osdep.etp_port;
580 mess1.DL_PROC= this_proc;
581 mess1.DL_COUNT= i;
582 mess1.DL_ADDR= (char *)iovec;
583
584 for (;;)
585 {
586 if (recv_debug)
587 {
588 printf("eth%d: sending DL_READV\n",
589 mess1.DL_PORT);
590 }
591 r= sendrec(eth_port->etp_osdep.etp_task, &mess1);
592 if (r != ELOCKED)
593 break;
594
595 /* ethernet task is sending to this task, I hope */
596 r= receive(eth_port->etp_osdep.etp_task, &block_msg);
597 if (r < 0)
598 ip_panic(("unable to receive"));
599
600 loc_port= eth_port;
601 if (loc_port->etp_osdep.etp_port != block_msg.DL_PORT ||
602 loc_port->etp_osdep.etp_task !=
603 block_msg.m_source)
604 {
605 loc_port= find_port(&block_msg);
606 }
607 assert(block_msg.DL_STAT &
608 (DL_PACK_SEND|DL_PACK_RECV));
609 if (block_msg.DL_STAT & DL_PACK_SEND)
610 {
611 loc_port->etp_osdep.etp_sendrepl= block_msg;
612 ev_arg.ev_ptr= loc_port;
613 ev_enqueue(&loc_port->etp_sendev, eth_sendev,
614 ev_arg);
615 }
616 if (block_msg.DL_STAT & DL_PACK_RECV)
617 {
618 if (recv_debug)
619 {
620 printf(
621 "setup_read(block_msg): eth%d got DL_PACK_RECV\n",
622 block_msg.DL_PORT);
623 }
624 assert(loc_port != eth_port);
625 loc_port->etp_osdep.etp_recvrepl= block_msg;
626 ev_arg.ev_ptr= loc_port;
627 ev_enqueue(&loc_port->etp_osdep.etp_recvev,
628 eth_recvev, ev_arg);
629 }
630 }
631
632 if (r < 0)
633 {
634 printf("mnx_eth`setup_read: sendrec to %d failed: %d\n",
635 eth_port->etp_osdep.etp_task, r);
636 eth_port->etp_rd_pack= pack;
637 eth_port->etp_flags |= EPF_READ_IP;
638 continue;
639 }
640
641 assert (mess1.m_type == DL_TASK_REPLY &&
642 mess1.DL_PORT == mess1.DL_PORT &&
643 mess1.DL_PROC == this_proc);
644 compare((mess1.DL_STAT >> 16), ==, OK);
645
646 if (mess1.DL_STAT & DL_PACK_RECV)
647 {
648 if (recv_debug)
649 {
650 printf(
651 "setup_read(mess1): eth%d: got DL_PACK_RECV\n",
652 mess1.DL_PORT);
653 }
654 /* packet received */
655 pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT);
656 bf_afree(pack);
657
658 assert(!no_ethWritePort);
659 no_ethWritePort= 1;
660 eth_arrive(eth_port, pack_ptr, mess1.DL_COUNT);
661 assert(no_ethWritePort);
662 no_ethWritePort= 0;
663 }
664 else
665 {
666 /* no packet received */
667 eth_port->etp_rd_pack= pack;
668 eth_port->etp_flags |= EPF_READ_IP;
669 }
670
671 if (mess1.DL_STAT & DL_PACK_SEND)
672 {
673 eth_port->etp_osdep.etp_sendrepl= mess1;
674 ev_arg.ev_ptr= eth_port;
675 ev_enqueue(ð_port->etp_sendev, eth_sendev, ev_arg);
676 }
677 } while (!(eth_port->etp_flags & EPF_READ_IP));
678 eth_port->etp_flags |= EPF_READ_SP;
679 }
680
681 PRIVATE void eth_recvev(ev, ev_arg)
682 event_t *ev;
683 ev_arg_t ev_arg;
684 {
685 eth_port_t *eth_port;
686 message *m_ptr;
687
688 eth_port= ev_arg.ev_ptr;
689 assert(ev == ð_port->etp_osdep.etp_recvev);
690 m_ptr= ð_port->etp_osdep.etp_recvrepl;
691
692 assert(m_ptr->m_type == DL_TASK_REPLY);
693 assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&
694 eth_port->etp_osdep.etp_task == m_ptr->m_source);
695
696 assert(m_ptr->DL_STAT & DL_PACK_RECV);
697 m_ptr->DL_STAT &= ~DL_PACK_RECV;
698
699 if (recv_debug)
700 {
701 printf("eth_recvev: eth%d got DL_PACK_RECV\n", m_ptr->DL_PORT);
702 }
703
704 read_int(eth_port, m_ptr->DL_COUNT);
705 }
706
707 PRIVATE void eth_sendev(ev, ev_arg)
708 event_t *ev;
709 ev_arg_t ev_arg;
710 {
711 eth_port_t *eth_port;
712 message *m_ptr;
713
714 eth_port= ev_arg.ev_ptr;
715 assert(ev == ð_port->etp_sendev);
716 m_ptr= ð_port->etp_osdep.etp_sendrepl;
717
718 assert (m_ptr->m_type == DL_TASK_REPLY);
719 assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&
720 eth_port->etp_osdep.etp_task == m_ptr->m_source);
721
722 assert(m_ptr->DL_STAT & DL_PACK_SEND);
723 m_ptr->DL_STAT &= ~DL_PACK_SEND;
724
725 /* packet is sent */
726 write_int(eth_port);
727 }
728
729 PRIVATE eth_port_t *find_port(m)
730 message *m;
731 {
732 eth_port_t *loc_port;
733 int i;
734
735 for (i=0, loc_port= eth_port_table; i<eth_conf_nr; i++, loc_port++)
736 {
737 if (loc_port->etp_osdep.etp_port == m->DL_PORT &&
738 loc_port->etp_osdep.etp_task == m->m_source)
739 break;
740 }
741 assert (i<eth_conf_nr);
742 return loc_port;
743 }
744
745 static void eth_restart(eth_port, tasknr)
746 eth_port_t *eth_port;
747 int tasknr;
748 {
749 int r;
750 unsigned flags, dl_flags;
751 message mess;
752 #if 0
753 int i, r, rport;
754 struct eth_conf *ecp;
755 eth_port_t *rep;
756 #endif
757
758 printf("eth_restart: restarting eth%d, task %d, port %d\n",
759 eth_port-eth_port_table, tasknr,
760 eth_port->etp_osdep.etp_port);
761
762 eth_port->etp_osdep.etp_task= tasknr;
763
764 flags= eth_port->etp_osdep.etp_recvconf;
765 dl_flags= DL_NOMODE;
766 if (flags & NWEO_EN_BROAD)
767 dl_flags |= DL_BROAD_REQ;
768 if (flags & NWEO_EN_MULTI)
769 dl_flags |= DL_MULTI_REQ;
770 if (flags & NWEO_EN_PROMISC)
771 dl_flags |= DL_PROMISC_REQ;
772 mess.m_type= DL_INIT;
773 mess.DL_PORT= eth_port->etp_osdep.etp_port;
774 mess.DL_PROC= this_proc;
775 mess.DL_MODE= dl_flags;
776
777 r= sendrec(eth_port->etp_osdep.etp_task, &mess);
778 /* YYY */
779 if (r<0)
780 {
781 printf(
782 "eth_restart: sendrec to ethernet task %d failed: %d\n",
783 eth_port->etp_osdep.etp_task, r);
784 return;
785 }
786
787 if (mess.m3_i1 == ENXIO)
788 {
789 printf(
790 "osdep_eth_init: no ethernet device at task=%d,port=%d\n",
791 eth_port->etp_osdep.etp_task,
792 eth_port->etp_osdep.etp_port);
793 return;
794 }
795 if (mess.m3_i1 < 0)
796 ip_panic(("osdep_eth_init: DL_INIT returned error %d\n",
797 mess.m3_i1));
798
799 if (mess.m3_i1 != eth_port->etp_osdep.etp_port)
800 {
801 ip_panic((
802 "osdep_eth_init: got reply for wrong port (got %d, expected %d)\n",
803 mess.m3_i1, eth_port->etp_osdep.etp_port));
804 }
805
806 eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1;
807
808 eth_port->etp_flags |= EPF_ENABLED;
809 if (eth_port->etp_wr_pack)
810 {
811 bf_afree(eth_port->etp_wr_pack);
812 eth_port->etp_wr_pack= NULL;
813 eth_restart_write(eth_port);
814 }
815 if (eth_port->etp_rd_pack)
816 {
817 bf_afree(eth_port->etp_rd_pack);
818 eth_port->etp_rd_pack= NULL;
819 eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP);
820 }
821 setup_read (eth_port);
822 }
823
824 /*
825 * $PchId: mnx_eth.c,v 1.16 2005/06/28 14:24:37 philip Exp $
826 */
Cache object: 2bad5a9c9779eb14fd2c5c0f05710cf1
|