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;
|
put_pkt_t ef_put_pkt;
|
||||||
time_t ef_exp_time;
|
time_t ef_exp_time;
|
||||||
size_t ef_write_count;
|
size_t ef_write_count;
|
||||||
|
ioreq_t ef_ioctl_req;
|
||||||
} eth_fd_t;
|
} eth_fd_t;
|
||||||
|
|
||||||
#define EFF_FLAGS 0xf
|
#define EFF_FLAGS 0xf
|
||||||
# define EFF_EMPTY 0x0
|
# define EFF_EMPTY 0x0
|
||||||
# define EFF_INUSE 0x1
|
# define EFF_INUSE 0x1
|
||||||
# define EFF_BUSY 0x6
|
# define EFF_BUSY 0xE
|
||||||
# define EFF_READ_IP 0x2
|
# define EFF_READ_IP 0x2
|
||||||
# define EFF_WRITE_IP 0x4
|
# 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
|
/* Note that the vh_type field is normally considered part of the ethernet
|
||||||
* header.
|
* header.
|
||||||
|
@ -335,6 +337,17 @@ ioreq_t req;
|
||||||
acc= bf_memreq(sizeof(nwio_ethstat_t));
|
acc= bf_memreq(sizeof(nwio_ethstat_t));
|
||||||
compare (bf_bufsize(acc), ==, sizeof(*ethstat));
|
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= (nwio_ethstat_t *)ptr2acc_data(acc);
|
||||||
ethstat->nwes_addr= eth_port->etp_ethaddr;
|
ethstat->nwes_addr= eth_port->etp_ethaddr;
|
||||||
|
|
||||||
|
@ -481,6 +494,13 @@ size_t data_len;
|
||||||
if (nweo_flags & NWEO_REMSPEC)
|
if (nweo_flags & NWEO_REMSPEC)
|
||||||
eth_hdr->eh_dst= eth_fd->ef_ethopt.nweo_rem;
|
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))
|
if (!(nweo_flags & NWEO_EN_PROMISC))
|
||||||
eth_hdr->eh_src= eth_port->etp_ethaddr;
|
eth_hdr->eh_src= eth_port->etp_ethaddr;
|
||||||
|
|
||||||
|
@ -569,6 +589,11 @@ int which_operation;
|
||||||
eth_fd->ef_flags &= ~EFF_WRITE_IP;
|
eth_fd->ef_flags &= ~EFF_WRITE_IP;
|
||||||
reply_thr_get(eth_fd, EINTR, FALSE);
|
reply_thr_get(eth_fd, EINTR, FALSE);
|
||||||
break;
|
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:
|
default:
|
||||||
ip_panic(( "got unknown cancel request" ));
|
ip_panic(( "got unknown cancel request" ));
|
||||||
}
|
}
|
||||||
|
@ -784,6 +809,7 @@ size_t pack_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
assert(eth_port->etp_flags & EPF_GOT_ADDR);
|
||||||
if (eth_addrcmp (*dst_addr, eth_port->etp_ethaddr) == 0)
|
if (eth_addrcmp (*dst_addr, eth_port->etp_ethaddr) == 0)
|
||||||
pack_stat= NWEO_EN_LOC;
|
pack_stat= NWEO_EN_LOC;
|
||||||
else
|
else
|
||||||
|
@ -942,6 +968,28 @@ eth_port_t *vlan_port;
|
||||||
eth_port->etp_vlan_tab[h]= 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)
|
PRIVATE void packet2user (eth_fd, pack, exp_time)
|
||||||
eth_fd_t *eth_fd;
|
eth_fd_t *eth_fd;
|
||||||
acc_t *pack;
|
acc_t *pack;
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef struct eth_port
|
||||||
|
|
||||||
#define EPF_EMPTY 0x0
|
#define EPF_EMPTY 0x0
|
||||||
#define EPF_ENABLED 0x1
|
#define EPF_ENABLED 0x1
|
||||||
|
#define EPF_GOT_ADDR 0x2 /* Got ethernet address from device */
|
||||||
#define EPF_READ_IP 0x20
|
#define EPF_READ_IP 0x20
|
||||||
#define EPF_READ_SP 0x40
|
#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_restart_write ARGS(( eth_port_t *eth_port ));
|
||||||
void eth_loop_ev ARGS(( event_t *ev, ev_arg_t ev_arg ));
|
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_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 */
|
#endif /* ETH_INT_H */
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,13 @@ PUBLIC void osdep_eth_init()
|
||||||
#endif
|
#endif
|
||||||
if (r != OK)
|
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",
|
printf("eth%d: unable to find task %s: %d\n",
|
||||||
i, ecp->ec_task, r);
|
i, ecp->ec_task, r);
|
||||||
continue;
|
tasknr= ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
eth_port->etp_osdep.etp_port= ecp->ec_port;
|
eth_port->etp_osdep.etp_port= ecp->ec_port;
|
||||||
|
@ -64,44 +68,54 @@ PUBLIC void osdep_eth_init()
|
||||||
mess.DL_PROC= this_proc;
|
mess.DL_PROC= this_proc;
|
||||||
mess.DL_MODE= DL_NOMODE;
|
mess.DL_MODE= DL_NOMODE;
|
||||||
|
|
||||||
|
if (tasknr == ANY)
|
||||||
|
r= ENXIO;
|
||||||
|
else
|
||||||
|
{
|
||||||
r= send(eth_port->etp_osdep.etp_task, &mess);
|
r= send(eth_port->etp_osdep.etp_task, &mess);
|
||||||
if (r<0)
|
if (r<0)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"osdep_eth_init: unable to send to ethernet task, error= %d\n",
|
"osdep_eth_init: unable to send to ethernet task, error= %d\n",
|
||||||
r);
|
r);
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r == OK)
|
||||||
|
{
|
||||||
r= receive(eth_port->etp_osdep.etp_task, &mess);
|
r= receive(eth_port->etp_osdep.etp_task, &mess);
|
||||||
if (r<0)
|
if (r<0)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"osdep_eth_init: unable to receive from ethernet task, error= %d\n",
|
"osdep_eth_init: unable to receive from ethernet task, error= %d\n",
|
||||||
r);
|
r);
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mess.m3_i1 == ENXIO)
|
if (r == OK)
|
||||||
|
{
|
||||||
|
r= mess.m3_i1;
|
||||||
|
if (r == ENXIO)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"osdep_eth_init: no ethernet device at task=%d,port=%d\n",
|
"osdep_eth_init: no ethernet device at task=%d,port=%d\n",
|
||||||
eth_port->etp_osdep.etp_task,
|
eth_port->etp_osdep.etp_task,
|
||||||
eth_port->etp_osdep.etp_port);
|
eth_port->etp_osdep.etp_port);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (mess.m3_i1 < 0)
|
else if (r < 0)
|
||||||
ip_panic(("osdep_eth_init: DL_INIT returned error %d\n",
|
{
|
||||||
mess.m3_i1));
|
ip_panic((
|
||||||
|
"osdep_eth_init: DL_INIT returned error %d\n",
|
||||||
if (mess.m3_i1 != eth_port->etp_osdep.etp_port)
|
r));
|
||||||
|
}
|
||||||
|
else if (mess.m3_i1 != eth_port->etp_osdep.etp_port)
|
||||||
{
|
{
|
||||||
ip_panic((
|
ip_panic((
|
||||||
"osdep_eth_init: got reply for wrong port (got %d, expected %d)\n",
|
"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),
|
sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
|
||||||
i, eth_open, eth_close, eth_read,
|
i, eth_open, eth_close, eth_read,
|
||||||
|
@ -112,8 +126,13 @@ PUBLIC void osdep_eth_init()
|
||||||
eth_port->etp_vlan_port= NULL;
|
eth_port->etp_vlan_port= NULL;
|
||||||
eth_port->etp_wr_pack= 0;
|
eth_port->etp_wr_pack= 0;
|
||||||
eth_port->etp_rd_pack= 0;
|
eth_port->etp_rd_pack= 0;
|
||||||
|
if (r == OK)
|
||||||
|
{
|
||||||
|
eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1;
|
||||||
|
eth_port->etp_flags |= EPF_GOT_ADDR;
|
||||||
setup_read (eth_port);
|
setup_read (eth_port);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* And now come the VLANs */
|
/* And now come the VLANs */
|
||||||
for (i= 0, ecp= eth_conf, eth_port= eth_port_table;
|
for (i= 0, ecp= eth_conf, eth_port= eth_port_table;
|
||||||
|
@ -144,7 +163,11 @@ PUBLIC void osdep_eth_init()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rep->etp_flags & EPF_GOT_ADDR)
|
||||||
|
{
|
||||||
eth_port->etp_ethaddr= rep->etp_ethaddr;
|
eth_port->etp_ethaddr= rep->etp_ethaddr;
|
||||||
|
eth_port->etp_flags |= EPF_GOT_ADDR;
|
||||||
|
}
|
||||||
|
|
||||||
sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
|
sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
|
||||||
i, eth_open, eth_close, eth_read,
|
i, eth_open, eth_close, eth_read,
|
||||||
|
@ -454,6 +477,13 @@ u32_t flags;
|
||||||
|
|
||||||
assert(!eth_port->etp_vlan);
|
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;
|
eth_port->etp_osdep.etp_recvconf= flags;
|
||||||
dl_flags= DL_NOMODE;
|
dl_flags= DL_NOMODE;
|
||||||
if (flags & NWEO_EN_BROAD)
|
if (flags & NWEO_EN_BROAD)
|
||||||
|
@ -746,14 +776,10 @@ static void eth_restart(eth_port, tasknr)
|
||||||
eth_port_t *eth_port;
|
eth_port_t *eth_port;
|
||||||
int tasknr;
|
int tasknr;
|
||||||
{
|
{
|
||||||
int r;
|
int i, r;
|
||||||
unsigned flags, dl_flags;
|
unsigned flags, dl_flags;
|
||||||
message mess;
|
message mess;
|
||||||
#if 0
|
eth_port_t *loc_port;
|
||||||
int i, r, rport;
|
|
||||||
struct eth_conf *ecp;
|
|
||||||
eth_port_t *rep;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
printf("eth_restart: restarting eth%d, task %d, port %d\n",
|
printf("eth_restart: restarting eth%d, task %d, port %d\n",
|
||||||
eth_port-eth_port_table, tasknr,
|
eth_port-eth_port_table, tasknr,
|
||||||
|
@ -803,9 +829,29 @@ int tasknr;
|
||||||
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;
|
|
||||||
|
|
||||||
eth_port->etp_flags |= EPF_ENABLED;
|
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)
|
if (eth_port->etp_wr_pack)
|
||||||
{
|
{
|
||||||
bf_afree(eth_port->etp_wr_pack);
|
bf_afree(eth_port->etp_wr_pack);
|
||||||
|
|
Loading…
Reference in a new issue