Support for starting ethernet driver after inet has been started
This commit is contained in:
parent
e0634c0b47
commit
9d8b27a2b1
3 changed files with 136 additions and 40 deletions
|
@ -38,15 +38,17 @@ typedef struct eth_fd
|
|||
put_pkt_t ef_put_pkt;
|
||||
time_t ef_exp_time;
|
||||
size_t ef_write_count;
|
||||
ioreq_t ef_ioctl_req;
|
||||
} eth_fd_t;
|
||||
|
||||
#define EFF_FLAGS 0xf
|
||||
# define EFF_EMPTY 0x0
|
||||
# define EFF_INUSE 0x1
|
||||
# define EFF_BUSY 0x6
|
||||
# define EFF_BUSY 0xE
|
||||
# define EFF_READ_IP 0x2
|
||||
# define EFF_WRITE_IP 0x4
|
||||
# define EFF_OPTSET 0x8
|
||||
# define EFF_IOCTL_IP 0x8
|
||||
# define EFF_OPTSET 0x10
|
||||
|
||||
/* Note that the vh_type field is normally considered part of the ethernet
|
||||
* header.
|
||||
|
@ -335,6 +337,17 @@ ioreq_t req;
|
|||
acc= bf_memreq(sizeof(nwio_ethstat_t));
|
||||
compare (bf_bufsize(acc), ==, sizeof(*ethstat));
|
||||
|
||||
if (!(eth_port->etp_flags & EPF_GOT_ADDR))
|
||||
{
|
||||
printf(
|
||||
"eth_ioctl: suspending NWIOGETHSTAT ioctl\n");
|
||||
|
||||
eth_fd->ef_ioctl_req= req;
|
||||
assert(!(eth_fd->ef_flags & EFF_IOCTL_IP));
|
||||
eth_fd->ef_flags |= EFF_IOCTL_IP;
|
||||
return NW_SUSPEND;
|
||||
}
|
||||
|
||||
ethstat= (nwio_ethstat_t *)ptr2acc_data(acc);
|
||||
ethstat->nwes_addr= eth_port->etp_ethaddr;
|
||||
|
||||
|
@ -481,6 +494,13 @@ size_t data_len;
|
|||
if (nweo_flags & NWEO_REMSPEC)
|
||||
eth_hdr->eh_dst= eth_fd->ef_ethopt.nweo_rem;
|
||||
|
||||
if (!(eth_port->etp_flags & EPF_GOT_ADDR))
|
||||
{
|
||||
/* No device, discard packet */
|
||||
bf_afree(eth_pack);
|
||||
return NW_OK;
|
||||
}
|
||||
|
||||
if (!(nweo_flags & NWEO_EN_PROMISC))
|
||||
eth_hdr->eh_src= eth_port->etp_ethaddr;
|
||||
|
||||
|
@ -569,6 +589,11 @@ int which_operation;
|
|||
eth_fd->ef_flags &= ~EFF_WRITE_IP;
|
||||
reply_thr_get(eth_fd, EINTR, FALSE);
|
||||
break;
|
||||
case SR_CANCEL_IOCTL:
|
||||
assert (eth_fd->ef_flags & EFF_IOCTL_IP);
|
||||
eth_fd->ef_flags &= ~EFF_IOCTL_IP;
|
||||
reply_thr_get(eth_fd, EINTR, TRUE);
|
||||
break;
|
||||
default:
|
||||
ip_panic(( "got unknown cancel request" ));
|
||||
}
|
||||
|
@ -784,6 +809,7 @@ size_t pack_size;
|
|||
}
|
||||
else
|
||||
{
|
||||
assert(eth_port->etp_flags & EPF_GOT_ADDR);
|
||||
if (eth_addrcmp (*dst_addr, eth_port->etp_ethaddr) == 0)
|
||||
pack_stat= NWEO_EN_LOC;
|
||||
else
|
||||
|
@ -942,6 +968,28 @@ eth_port_t *vlan_port;
|
|||
eth_port->etp_vlan_tab[h]= vlan_port;
|
||||
}
|
||||
|
||||
PUBLIC void eth_restart_ioctl(eth_port)
|
||||
eth_port_t *eth_port;
|
||||
{
|
||||
int i;
|
||||
eth_fd_t *eth_fd;
|
||||
|
||||
for (i= 0, eth_fd= eth_fd_table; i<ETH_FD_NR; i++, eth_fd++)
|
||||
{
|
||||
if (!(eth_fd->ef_flags & EFF_INUSE))
|
||||
continue;
|
||||
if (eth_fd->ef_port != eth_port)
|
||||
continue;
|
||||
if (!(eth_fd->ef_flags & EFF_IOCTL_IP))
|
||||
continue;
|
||||
if (eth_fd->ef_ioctl_req != NWIOGETHSTAT)
|
||||
continue;
|
||||
|
||||
eth_fd->ef_flags &= ~EFF_IOCTL_IP;
|
||||
eth_ioctl(i, eth_fd->ef_ioctl_req);
|
||||
}
|
||||
}
|
||||
|
||||
PRIVATE void packet2user (eth_fd, pack, exp_time)
|
||||
eth_fd_t *eth_fd;
|
||||
acc_t *pack;
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef struct eth_port
|
|||
|
||||
#define EPF_EMPTY 0x0
|
||||
#define EPF_ENABLED 0x1
|
||||
#define EPF_GOT_ADDR 0x2 /* Got ethernet address from device */
|
||||
#define EPF_READ_IP 0x20
|
||||
#define EPF_READ_SP 0x40
|
||||
|
||||
|
@ -53,6 +54,7 @@ void eth_set_rec_conf ARGS(( eth_port_t *eth_port, u32_t flags ));
|
|||
void eth_restart_write ARGS(( eth_port_t *eth_port ));
|
||||
void eth_loop_ev ARGS(( event_t *ev, ev_arg_t ev_arg ));
|
||||
void eth_reg_vlan ARGS(( eth_port_t *eth_port, eth_port_t *vlan_port ));
|
||||
void eth_restart_ioctl ARGS(( eth_port_t *eth_port ));
|
||||
|
||||
#endif /* ETH_INT_H */
|
||||
|
||||
|
|
|
@ -50,9 +50,13 @@ PUBLIC void osdep_eth_init()
|
|||
#endif
|
||||
if (r != OK)
|
||||
{
|
||||
/* Eventually, we expect ethernet drivers to be
|
||||
* started after INET. So we always end up here. And
|
||||
* the findproc can be removed.
|
||||
*/
|
||||
printf("eth%d: unable to find task %s: %d\n",
|
||||
i, ecp->ec_task, r);
|
||||
continue;
|
||||
tasknr= ANY;
|
||||
}
|
||||
|
||||
eth_port->etp_osdep.etp_port= ecp->ec_port;
|
||||
|
@ -64,45 +68,55 @@ PUBLIC void osdep_eth_init()
|
|||
mess.DL_PROC= this_proc;
|
||||
mess.DL_MODE= DL_NOMODE;
|
||||
|
||||
r= send(eth_port->etp_osdep.etp_task, &mess);
|
||||
if (r<0)
|
||||
if (tasknr == ANY)
|
||||
r= ENXIO;
|
||||
else
|
||||
{
|
||||
printf(
|
||||
r= send(eth_port->etp_osdep.etp_task, &mess);
|
||||
if (r<0)
|
||||
{
|
||||
printf(
|
||||
"osdep_eth_init: unable to send to ethernet task, error= %d\n",
|
||||
r);
|
||||
continue;
|
||||
r);
|
||||
}
|
||||
}
|
||||
|
||||
r= receive(eth_port->etp_osdep.etp_task, &mess);
|
||||
if (r<0)
|
||||
if (r == OK)
|
||||
{
|
||||
printf(
|
||||
r= receive(eth_port->etp_osdep.etp_task, &mess);
|
||||
if (r<0)
|
||||
{
|
||||
printf(
|
||||
"osdep_eth_init: unable to receive from ethernet task, error= %d\n",
|
||||
r);
|
||||
continue;
|
||||
r);
|
||||
}
|
||||
}
|
||||
|
||||
if (mess.m3_i1 == ENXIO)
|
||||
if (r == OK)
|
||||
{
|
||||
printf(
|
||||
r= mess.m3_i1;
|
||||
if (r == 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);
|
||||
continue;
|
||||
}
|
||||
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((
|
||||
eth_port->etp_osdep.etp_task,
|
||||
eth_port->etp_osdep.etp_port);
|
||||
}
|
||||
else if (r < 0)
|
||||
{
|
||||
ip_panic((
|
||||
"osdep_eth_init: DL_INIT returned error %d\n",
|
||||
r));
|
||||
}
|
||||
else 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));
|
||||
mess.m3_i1,
|
||||
eth_port->etp_osdep.etp_port));
|
||||
}
|
||||
}
|
||||
|
||||
eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1;
|
||||
|
||||
|
||||
sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
|
||||
i, eth_open, eth_close, eth_read,
|
||||
eth_write, eth_ioctl, eth_cancel, eth_select);
|
||||
|
@ -112,7 +126,12 @@ PUBLIC void osdep_eth_init()
|
|||
eth_port->etp_vlan_port= NULL;
|
||||
eth_port->etp_wr_pack= 0;
|
||||
eth_port->etp_rd_pack= 0;
|
||||
setup_read (eth_port);
|
||||
if (r == OK)
|
||||
{
|
||||
eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1;
|
||||
eth_port->etp_flags |= EPF_GOT_ADDR;
|
||||
setup_read (eth_port);
|
||||
}
|
||||
}
|
||||
|
||||
/* And now come the VLANs */
|
||||
|
@ -144,7 +163,11 @@ PUBLIC void osdep_eth_init()
|
|||
continue;
|
||||
}
|
||||
|
||||
eth_port->etp_ethaddr= rep->etp_ethaddr;
|
||||
if (rep->etp_flags & EPF_GOT_ADDR)
|
||||
{
|
||||
eth_port->etp_ethaddr= rep->etp_ethaddr;
|
||||
eth_port->etp_flags |= EPF_GOT_ADDR;
|
||||
}
|
||||
|
||||
sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
|
||||
i, eth_open, eth_close, eth_read,
|
||||
|
@ -454,6 +477,13 @@ u32_t flags;
|
|||
|
||||
assert(!eth_port->etp_vlan);
|
||||
|
||||
if (!(eth_port->etp_flags & EPF_GOT_ADDR))
|
||||
{
|
||||
/* We have never seen the device. */
|
||||
printf("eth_set_rec_conf: waiting for device to appear\n");
|
||||
return;
|
||||
}
|
||||
|
||||
eth_port->etp_osdep.etp_recvconf= flags;
|
||||
dl_flags= DL_NOMODE;
|
||||
if (flags & NWEO_EN_BROAD)
|
||||
|
@ -746,14 +776,10 @@ static void eth_restart(eth_port, tasknr)
|
|||
eth_port_t *eth_port;
|
||||
int tasknr;
|
||||
{
|
||||
int r;
|
||||
int i, r;
|
||||
unsigned flags, dl_flags;
|
||||
message mess;
|
||||
#if 0
|
||||
int i, r, rport;
|
||||
struct eth_conf *ecp;
|
||||
eth_port_t *rep;
|
||||
#endif
|
||||
eth_port_t *loc_port;
|
||||
|
||||
printf("eth_restart: restarting eth%d, task %d, port %d\n",
|
||||
eth_port-eth_port_table, tasknr,
|
||||
|
@ -803,9 +829,29 @@ int tasknr;
|
|||
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;
|
||||
|
||||
eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1;
|
||||
if (!(eth_port->etp_flags & EPF_GOT_ADDR))
|
||||
{
|
||||
eth_port->etp_flags |= EPF_GOT_ADDR;
|
||||
eth_restart_ioctl(eth_port);
|
||||
|
||||
/* Also update any VLANs on this device */
|
||||
for (i=0, loc_port= eth_port_table; i<eth_conf_nr;
|
||||
i++, loc_port++)
|
||||
{
|
||||
if (!(loc_port->etp_flags & EPF_ENABLED))
|
||||
continue;
|
||||
if (loc_port->etp_vlan_port != eth_port)
|
||||
continue;
|
||||
|
||||
loc_port->etp_ethaddr= eth_port->etp_ethaddr;
|
||||
loc_port->etp_flags |= EPF_GOT_ADDR;
|
||||
eth_restart_ioctl(loc_port);
|
||||
}
|
||||
}
|
||||
|
||||
if (eth_port->etp_wr_pack)
|
||||
{
|
||||
bf_afree(eth_port->etp_wr_pack);
|
||||
|
|
Loading…
Reference in a new issue