📄 mnx_eth.c
字号:
for (;;) { r= sendrec(eth_port->etp_osdep.etp_task, &mess); if (r != ELOCKED) break; r= receive(eth_port->etp_osdep.etp_task, &mlocked); assert(r == OK); compare(mlocked.m_type, ==, DL_TASK_REPLY); eth_rec(&mlocked); } if (r != OK) { printf("eth_get_stat: sendrec to %d failed: %d\n", eth_port->etp_osdep.etp_task, r); return EIO; } assert(mess.m_type == DL_TASK_REPLY); r= mess.DL_STAT >> 16; assert (r == 0); if (mess.DL_STAT) { eth_rec(&mess); } return OK;}PUBLIC void eth_set_rec_conf (eth_port, flags)eth_port_t *eth_port;u32_t flags;{ int r; unsigned dl_flags; message mess, repl_mess; assert(!eth_port->etp_vlan); eth_port->etp_osdep.etp_recvconf= flags; dl_flags= DL_NOMODE; if (flags & NWEO_EN_BROAD) dl_flags |= DL_BROAD_REQ; if (flags & NWEO_EN_MULTI) dl_flags |= DL_MULTI_REQ; if (flags & NWEO_EN_PROMISC) dl_flags |= DL_PROMISC_REQ; mess.m_type= DL_INIT; mess.DL_PORT= eth_port->etp_osdep.etp_port; mess.DL_PROC= this_proc; mess.DL_MODE= dl_flags; do { r= sendrec(eth_port->etp_osdep.etp_task, &mess); if (r == ELOCKED) /* etp_task is sending to this task, I hope */ { if (receive (eth_port->etp_osdep.etp_task, &repl_mess)< 0) { ip_panic(("unable to receive")); } compare(repl_mess.m_type, ==, DL_TASK_REPLY); eth_rec(&repl_mess); } } while (r == ELOCKED); if (r < 0) { printf("eth_set_rec_conf: sendrec to %d failed: %d\n", eth_port->etp_osdep.etp_task, r); return; } assert (mess.m_type == DL_INIT_REPLY); if (mess.m3_i1 != eth_port->etp_osdep.etp_port) { ip_panic(("got reply for wrong port")); }}PRIVATE void write_int(eth_port)eth_port_t *eth_port;{ acc_t *pack; int multicast; u8_t *eth_dst_ptr; pack= eth_port->etp_wr_pack; eth_port->etp_wr_pack= NULL; eth_dst_ptr= (u8_t *)ptr2acc_data(pack); multicast= (*eth_dst_ptr & 1); /* low order bit indicates multicast */ if (multicast || (eth_port->etp_osdep.etp_recvconf & NWEO_EN_PROMISC)) { assert(!no_ethWritePort); no_ethWritePort= 1; eth_arrive(eth_port, pack, bf_bufsize(pack)); assert(no_ethWritePort); no_ethWritePort= 0; } else bf_afree(pack); eth_restart_write(eth_port);}PRIVATE void read_int(eth_port, count)eth_port_t *eth_port;int count;{ acc_t *pack, *cut_pack; pack= eth_port->etp_rd_pack; eth_port->etp_rd_pack= NULL; cut_pack= bf_cut(pack, 0, count); bf_afree(pack); assert(!no_ethWritePort); no_ethWritePort= 1; eth_arrive(eth_port, cut_pack, count); assert(no_ethWritePort); no_ethWritePort= 0; eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP); setup_read(eth_port);}PRIVATE void setup_read(eth_port)eth_port_t *eth_port;{ eth_port_t *loc_port; acc_t *pack, *pack_ptr; message mess1, block_msg; iovec_t *iovec; ev_arg_t ev_arg; int i, r; assert(!eth_port->etp_vlan); assert(!(eth_port->etp_flags & (EPF_READ_IP|EPF_READ_SP))); do { assert (!eth_port->etp_rd_pack); iovec= eth_port->etp_osdep.etp_rd_iovec; pack= bf_memreq (ETH_MAX_PACK_SIZE_TAGGED); for (i=0, pack_ptr= pack; i<RD_IOVEC && pack_ptr; i++, pack_ptr= pack_ptr->acc_next) { iovec[i].iov_addr= (vir_bytes)ptr2acc_data(pack_ptr); iovec[i].iov_size= (vir_bytes)pack_ptr->acc_length; } assert (!pack_ptr); mess1.m_type= DL_READV; mess1.DL_PORT= eth_port->etp_osdep.etp_port; mess1.DL_PROC= this_proc; mess1.DL_COUNT= i; mess1.DL_ADDR= (char *)iovec; for (;;) { if (recv_debug) { printf("eth%d: sending DL_READV\n", mess1.DL_PORT); } r= sendrec(eth_port->etp_osdep.etp_task, &mess1); if (r != ELOCKED) break; /* ethernet task is sending to this task, I hope */ r= receive(eth_port->etp_osdep.etp_task, &block_msg); if (r < 0) ip_panic(("unable to receive")); loc_port= eth_port; if (loc_port->etp_osdep.etp_port != block_msg.DL_PORT || loc_port->etp_osdep.etp_task != block_msg.m_source) { loc_port= find_port(&block_msg); } assert(block_msg.DL_STAT & (DL_PACK_SEND|DL_PACK_RECV)); if (block_msg.DL_STAT & DL_PACK_SEND) { loc_port->etp_osdep.etp_sendrepl= block_msg; ev_arg.ev_ptr= loc_port; ev_enqueue(&loc_port->etp_sendev, eth_sendev, ev_arg); } if (block_msg.DL_STAT & DL_PACK_RECV) { if (recv_debug) { printf( "setup_read(block_msg): eth%d got DL_PACK_RECV\n", block_msg.DL_PORT); } assert(loc_port != eth_port); loc_port->etp_osdep.etp_recvrepl= block_msg; ev_arg.ev_ptr= loc_port; ev_enqueue(&loc_port->etp_osdep.etp_recvev, eth_recvev, ev_arg); } } if (r < 0) { printf("mnx_eth`setup_read: sendrec to %d failed: %d\n", eth_port->etp_osdep.etp_task, r); eth_port->etp_rd_pack= pack; eth_port->etp_flags |= EPF_READ_IP; continue; } assert (mess1.m_type == DL_TASK_REPLY && mess1.DL_PORT == mess1.DL_PORT && mess1.DL_PROC == this_proc); compare((mess1.DL_STAT >> 16), ==, OK); if (mess1.DL_STAT & DL_PACK_RECV) { if (recv_debug) { printf( "setup_read(mess1): eth%d: got DL_PACK_RECV\n", mess1.DL_PORT); } /* packet received */ pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT); bf_afree(pack); assert(!no_ethWritePort); no_ethWritePort= 1; eth_arrive(eth_port, pack_ptr, mess1.DL_COUNT); assert(no_ethWritePort); no_ethWritePort= 0; } else { /* no packet received */ eth_port->etp_rd_pack= pack; eth_port->etp_flags |= EPF_READ_IP; } if (mess1.DL_STAT & DL_PACK_SEND) { eth_port->etp_osdep.etp_sendrepl= mess1; ev_arg.ev_ptr= eth_port; ev_enqueue(ð_port->etp_sendev, eth_sendev, ev_arg); } } while (!(eth_port->etp_flags & EPF_READ_IP)); eth_port->etp_flags |= EPF_READ_SP;}PRIVATE void eth_recvev(ev, ev_arg)event_t *ev;ev_arg_t ev_arg;{ eth_port_t *eth_port; message *m_ptr; eth_port= ev_arg.ev_ptr; assert(ev == ð_port->etp_osdep.etp_recvev); m_ptr= ð_port->etp_osdep.etp_recvrepl; assert(m_ptr->m_type == DL_TASK_REPLY); assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT && eth_port->etp_osdep.etp_task == m_ptr->m_source); assert(m_ptr->DL_STAT & DL_PACK_RECV); m_ptr->DL_STAT &= ~DL_PACK_RECV; if (recv_debug) { printf("eth_recvev: eth%d got DL_PACK_RECV\n", m_ptr->DL_PORT); } read_int(eth_port, m_ptr->DL_COUNT);}PRIVATE void eth_sendev(ev, ev_arg)event_t *ev;ev_arg_t ev_arg;{ eth_port_t *eth_port; message *m_ptr; eth_port= ev_arg.ev_ptr; assert(ev == ð_port->etp_sendev); m_ptr= ð_port->etp_osdep.etp_sendrepl; assert (m_ptr->m_type == DL_TASK_REPLY); assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT && eth_port->etp_osdep.etp_task == m_ptr->m_source); assert(m_ptr->DL_STAT & DL_PACK_SEND); m_ptr->DL_STAT &= ~DL_PACK_SEND; /* packet is sent */ write_int(eth_port);}PRIVATE eth_port_t *find_port(m)message *m;{ eth_port_t *loc_port; int i; for (i=0, loc_port= eth_port_table; i<eth_conf_nr; i++, loc_port++) { if (loc_port->etp_osdep.etp_port == m->DL_PORT && loc_port->etp_osdep.etp_task == m->m_source) break; } assert (i<eth_conf_nr); return loc_port;}static void eth_restart(eth_port, tasknr)eth_port_t *eth_port;int tasknr;{ int r; unsigned flags, dl_flags; message mess;#if 0 int i, r, rport; struct eth_conf *ecp; eth_port_t *rep;#endif printf("eth_restart: restarting eth%d, task %d, port %d\n", eth_port-eth_port_table, tasknr, eth_port->etp_osdep.etp_port); eth_port->etp_osdep.etp_task= tasknr; flags= eth_port->etp_osdep.etp_recvconf; dl_flags= DL_NOMODE; if (flags & NWEO_EN_BROAD) dl_flags |= DL_BROAD_REQ; if (flags & NWEO_EN_MULTI) dl_flags |= DL_MULTI_REQ; if (flags & NWEO_EN_PROMISC) dl_flags |= DL_PROMISC_REQ; mess.m_type= DL_INIT; mess.DL_PORT= eth_port->etp_osdep.etp_port; mess.DL_PROC= this_proc; mess.DL_MODE= dl_flags; r= sendrec(eth_port->etp_osdep.etp_task, &mess); /* YYY */ if (r<0) { printf( "eth_restart: sendrec to ethernet task %d failed: %d\n", eth_port->etp_osdep.etp_task, r); return; } if (mess.m3_i1 == ENXIO) { printf( "osdep_eth_init: no ethernet device at task=%d,port=%d\n", eth_port->etp_osdep.etp_task, eth_port->etp_osdep.etp_port); return; } if (mess.m3_i1 < 0) ip_panic(("osdep_eth_init: DL_INIT returned error %d\n", mess.m3_i1)); if (mess.m3_i1 != eth_port->etp_osdep.etp_port) { ip_panic(("osdep_eth_init: got reply for wrong port (got %d, expected %d)\n", mess.m3_i1, eth_port->etp_osdep.etp_port)); } eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1; eth_port->etp_flags |= EPF_ENABLED; if (eth_port->etp_wr_pack) { bf_afree(eth_port->etp_wr_pack); eth_port->etp_wr_pack= NULL; eth_restart_write(eth_port); } if (eth_port->etp_rd_pack) { bf_afree(eth_port->etp_rd_pack); eth_port->etp_rd_pack= NULL; eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP); } setup_read (eth_port);}/* * $PchId: mnx_eth.c,v 1.16 2005/06/28 14:24:37 philip Exp $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -