*sbp= nil;
}
-#if __minix_vmd
-#define N_FDS 16 /* Minix-vmd can go async on many fds. */
-#else
-#define N_FDS 1 /* Minix doesn't have async I/O. */
-#endif
+#define N_FDS 16 /* Minix can go async on many fds. */
static fd_t fds[N_FDS]; /* List of open descriptors. */
static struct network *fdwaitq; /* Queue of nets waiting for fds. */
return 1;
}
-#if !__minix_vmd /* No fsync() for Minix. */
-#define fsync(fd) sync()
-#endif
-
static void writepool(int fd, pool_t *entry)
{
/* (Over)write a pool table entry. */
static int job_read_udp(void *data, int expired)
/* Read UDP queries and replies. */
{
- size_t ulen, dlen;
+ ssize_t ulen;
+ size_t dlen;
static udp_dns_t udp;
u16_t id, port;
ipaddr_t ip;
+20100515:
+ /usr/src/etc/usr/rc updated: copy it (or merge it) to /usr/etc/rc.
+ /etc/inet.conf is now line-based; if you have hand-edited this file
+ before, then make sure that you do not have configurations in there
+ that span multiple lines.
20100512:
yacc and lex updated
# make includes
{ 0x0000, 0x0000 }
};
-PRIVATE long instance;
+PRIVATE int instance;
/*===========================================================================*
* atl2_read_vpd *
/* Send a task reply to Inet.
*/
message m;
- int r, stat;
+ int r, flags;
- stat = 0;
+ flags = DL_NOFLAGS;
if (state.flags & ATL2_FLAG_PACK_SENT)
- stat |= DL_PACK_SEND;
+ flags |= DL_PACK_SEND;
if (state.flags & ATL2_FLAG_PACK_RCVD)
- stat |= DL_PACK_RECV;
+ flags |= DL_PACK_RECV;
m.m_type = DL_TASK_REPLY;
- m.DL_PORT = 0;
- m.DL_PROC = state.task_endpt;
- m.DL_STAT = stat;
+ m.DL_FLAGS = flags;
m.DL_COUNT = state.recv_count;
- ATL2_DEBUG(("ATL2: sending reply stat %x count %d\n", stat,
+ ATL2_DEBUG(("ATL2: sending reply, flags %x count %d\n", flags,
m.DL_COUNT));
if ((r = send(state.task_endpt, &m)) != OK)
u8_t *pos;
int i, j, r, batch;
- if (m->DL_PORT != 0) {
- printf("ATL2: read from invalid port\n");
-
- return;
- }
-
/* We can deal with only one read request from Inet at a time. */
assert(from_int || !(state.flags & ATL2_FLAG_READ_PEND));
- /* The exact semantics of DL_PROC are not clear. This driver takes it
- * to be only the grant owner; other drivers treat it as the reply
- * destination as well.
- */
- assert(m->m_source == m->DL_PROC);
state.task_endpt = m->m_source;
/* Are there any packets available at all? */
/* Copy in the next batch. */
batch = MIN(m->DL_COUNT - i, NR_IOREQS);
- r = sys_safecopyfrom(m->DL_PROC, m->DL_GRANT, off,
+ r = sys_safecopyfrom(m->DL_ENDPT, m->DL_GRANT, off,
(vir_bytes) iovec, batch * sizeof(iovec[0]), D);
if (r != OK)
panic("vector copy failed: %d", r);
for (j = 0, iovp = iovec; j < batch && left > 0; j++, iovp++) {
size = MIN(iovp->iov_size, left);
- r = sys_safecopyto(m->DL_PROC, iovp->iov_grant, 0,
+ r = sys_safecopyto(m->DL_ENDPT, iovp->iov_grant, 0,
(vir_bytes) pos, size, D);
if (r != OK)
panic("safe copy failed: %d", r);
u8_t *sizep;
int i, j, r, batch, maxnum;
- if (m->DL_PORT != 0) {
- printf("ATL2: write to invalid port\n");
-
- return;
- }
-
/* We can deal with only one write request from Inet at a time. */
assert(from_int || !(state.flags & ATL2_FLAG_WRITE_PEND));
- assert(m->m_source == m->DL_PROC);
state.task_endpt = m->m_source;
/* If we are already certain that the packet won't fit, bail out.
/* Copy in the next batch. */
batch = MIN(m->DL_COUNT - i, NR_IOREQS);
- r = sys_safecopyfrom(m->DL_PROC, m->DL_GRANT, off,
+ r = sys_safecopyfrom(m->DL_ENDPT, m->DL_GRANT, off,
(vir_bytes) iovec, batch * sizeof(iovec[0]), D);
if (r != OK)
panic("vector copy failed: %d", r);
skip = 0;
if (size > ATL2_TXD_BUFSIZE - pos) {
skip = ATL2_TXD_BUFSIZE - pos;
- r = sys_safecopyfrom(m->DL_PROC,
+ r = sys_safecopyfrom(m->DL_ENDPT,
iovp->iov_grant, 0,
(vir_bytes) (state.txd_base + pos),
skip, D);
pos = 0;
}
- r = sys_safecopyfrom(m->DL_PROC, iovp->iov_grant, skip,
- (vir_bytes) (state.txd_base + pos),
+ r = sys_safecopyfrom(m->DL_ENDPT, iovp->iov_grant,
+ skip, (vir_bytes) (state.txd_base + pos),
size - skip, D);
if (r != OK)
panic("safe copy failed: %d", r);
ether_addr_t *addr;
int r;
- if (m->DL_PORT != 0) {
- m->m3_i1 = ENXIO;
- }
- else {
- state.mode = m->DL_MODE;
-
- atl2_set_mode();
+ state.mode = m->DL_MODE;
- addr = (ether_addr_t *) m->m3_ca1;
+ atl2_set_mode();
- addr->ea_addr[0] = state.hwaddr[1] >> 8;
- addr->ea_addr[1] = state.hwaddr[1] & 0xff;
- addr->ea_addr[2] = state.hwaddr[0] >> 24;
- addr->ea_addr[3] = (state.hwaddr[0] >> 16) & 0xff;
- addr->ea_addr[4] = (state.hwaddr[0] >> 8) & 0xff;
- addr->ea_addr[5] = state.hwaddr[0] & 0xff;
+ addr = (ether_addr_t *) m->DL_HWADDR;
- m->m3_i1 = OK;
- }
+ addr->ea_addr[0] = state.hwaddr[1] >> 8;
+ addr->ea_addr[1] = state.hwaddr[1] & 0xff;
+ addr->ea_addr[2] = state.hwaddr[0] >> 24;
+ addr->ea_addr[3] = (state.hwaddr[0] >> 16) & 0xff;
+ addr->ea_addr[4] = (state.hwaddr[0] >> 8) & 0xff;
+ addr->ea_addr[5] = state.hwaddr[0] & 0xff;
m->m_type = DL_CONF_REPLY;
+ m->DL_STAT = OK;
if ((r = send(m->m_source, m)) != OK)
printf("ATL2: unable to send reply (%d)\n", r);
*/
int r;
- if (m->DL_PORT != 0) {
- r = ENXIO;
- }
- else {
- r = sys_safecopyto(m->DL_PROC, m->DL_GRANT, 0,
- (vir_bytes) &state.stat, sizeof(state.stat), D);
- }
+ sys_safecopyto(m->DL_ENDPT, m->DL_GRANT, 0,
+ (vir_bytes) &state.stat, sizeof(state.stat), D);
m->m_type = DL_STAT_REPLY;
- /* keep m->DL_PORT */
- m->DL_STAT = r;
-
- if ((r = send(m->m_source, m)) != OK)
- printf("ATL2: unable to send reply (%d)\n", r);
-}
-
-/*===========================================================================*
- * atl2_getname *
- *===========================================================================*/
-PRIVATE void atl2_getname(message *m, int instance)
-{
- /* Tell Inet the name of this driver.
- */
- int r;
-
- /* Each instance must have a unique name. */
- m->m_type = DL_NAME_REPLY;
- if (instance > 0)
- snprintf(m->DL_NAME, sizeof(m->DL_NAME), "atl2:%u",
- instance - 1);
- else
- strcpy(m->DL_NAME, "atl2");
if ((r = send(m->m_source, m)) != OK)
printf("ATL2: unable to send reply (%d)\n", r);
/* Initialize the atl2 driver.
*/
int r, devind;
+ long v;
#if ATL2_FKEY
int fkeys, sfkeys;
#endif
/* How many matching devices should we skip? */
- instance = 0;
- env_parse("atl2_instance", "d", 0, &instance, 0, 32);
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ instance = (int) v;
/* Try to find a recognized device. */
devind = atl2_probe(instance);
/* Process requests from Inet. */
switch (m.m_type) {
- case DL_GETNAME: atl2_getname(&m, instance); break;
case DL_CONF: atl2_conf(&m); break;
case DL_GETSTAT_S: atl2_getstat(&m); break;
case DL_WRITEV_S: atl2_writev(&m, FALSE); break;
_PROTOTYPE( PRIVATE u32_t io_inl, (u16_t); );
_PROTOTYPE( PRIVATE void io_outl, (u16_t, u32_t); );
_PROTOTYPE( PRIVATE void do_conf, (const message *); );
-_PROTOTYPE( PRIVATE void do_get_name, (message *); );
_PROTOTYPE( PRIVATE void do_get_stat_s, (message *); );
_PROTOTYPE( PRIVATE void do_interrupt, (const dpeth_t *); );
-_PROTOTYPE( PRIVATE void do_reply, (dpeth_t *, int, int); );
+_PROTOTYPE( PRIVATE void do_reply, (dpeth_t *); );
_PROTOTYPE( PRIVATE void do_vread_s, (const message *, int); );
_PROTOTYPE( PRIVATE void do_watchdog, (void *); );
/* Error messages */
static char str_CopyErrMsg[] = "unable to read/write user data";
-static char str_PortErrMsg[] = "illegal port";
static char str_SendErrMsg[] = "send failed";
static char str_SizeErrMsg[] = "illegal packet size";
static char str_UmapErrMsg[] = "Unable to sys_umap";
static char str_AlignErrMsg[] = "Bad align of buffer/descriptor";
static char str_DevName[] = "dec21140A:eth#?";
-PRIVATE dpeth_t de_table[DE_PORT_NR];
-PRIVATE const char *progname;
+PRIVATE dpeth_t de_state;
+PRIVATE int de_instance;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
break;
case HARDWARE:
- for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) {
- if (dep->de_mode == DEM_ENABLED) {
- do_interrupt(dep);
- if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
- do_reply(dep, OK, TRUE);
- sys_irqenable(&dep->de_hook);
- }
+ dep = &de_state;
+ if (dep->de_mode == DEM_ENABLED) {
+ do_interrupt(dep);
+ if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
+ do_reply(dep);
+ sys_irqenable(&dep->de_hook);
}
break;
default:
case DL_READV_S: do_vread_s(&m, FALSE); break;
case DL_CONF: do_conf(&m); break;
case DL_GETSTAT_S: do_get_stat_s(&m); break;
- case DL_GETNAME: do_get_name(&m); break;
- case DL_STOP: /* nothing */ break;
default:
printf("message 0x%lx; %d from %d\n",
{
/* Initialize the DEC 21140A driver. */
int fkeys, sfkeys;
+ long v;
- (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ de_instance = (int) v;
/* Request function key for debug dumps */
fkeys = sfkeys = 0;
PRIVATE void do_get_stat_s(message * mp)
{
- int port, rc;
+ int rc;
dpeth_t *dep;
- port = mp->DL_PORT;
- if (port < 0 || port >= DE_PORT_NR)
- panic(str_PortErrMsg, port);
-
- dep = &de_table[port];
- dep->de_client = mp->DL_PROC;
+ dep = &de_state;
- if ((rc = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0UL,
+ if ((rc = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0UL,
(vir_bytes)&dep->de_stat,
sizeof(dep->de_stat), 0)) != OK)
panic(str_CopyErrMsg, rc);
mp->m_type = DL_STAT_REPLY;
- mp->DL_PORT = port;
- mp->DL_STAT = OK;
rc = send(mp->m_source, mp);
if( rc != OK )
panic(str_StatErrMsg, rc);
PRIVATE void do_conf(const message * mp)
{
- int port = mp->DL_PORT;
+ int r;
dpeth_t *dep;
message reply_mess;
- if (port >= 0 && port < DE_PORT_NR) {
+ dep = &de_state;
- dep = &de_table[port];
- strncpy(dep->de_name, str_DevName, strlen(str_DevName));
- dep->de_name[strlen(dep->de_name)-1] = '0' + port;
+ strncpy(dep->de_name, str_DevName, strlen(str_DevName));
+ dep->de_name[strlen(dep->de_name)-1] = '0' + de_instance;
- if (dep->de_mode == DEM_DISABLED) {
- de_update_conf(dep);
- pci_init();
- if (dep->de_mode == DEM_ENABLED && !de_probe(dep, port)) {
+ if (dep->de_mode == DEM_DISABLED) {
+ de_update_conf(dep);
+ pci_init();
+ if (dep->de_mode == DEM_ENABLED && !de_probe(dep, de_instance)) {
printf("%s: warning no ethernet card found at 0x%04X\n",
dep->de_name, dep->de_base_port);
dep->de_mode = DEM_DISABLED;
- }
}
+ }
- /* 'de_mode' may change if probe routines fail, test again */
- switch (dep->de_mode) {
+ r = OK;
- case DEM_DISABLED:
- port = ENXIO; /* Device is OFF or hardware probe failed */
- break;
+ /* 'de_mode' may change if probe routines fail, test again */
+ switch (dep->de_mode) {
- case DEM_ENABLED:
- if (dep->de_flags == DEF_EMPTY) {
+ case DEM_DISABLED:
+ r = ENXIO; /* Device is OFF or hardware probe failed */
+ break;
+
+ case DEM_ENABLED:
+ if (dep->de_flags == DEF_EMPTY) {
de_first_init(dep);
dep->de_flags |= DEF_ENABLED;
de_reset(dep);
de_hw_conf(dep);
de_setup_frame(dep);
de_start(dep);
- }
+ }
- /* TODO CHECK PROMISC AND MULTI */
- dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
- if (mp->DL_MODE & DL_PROMISC_REQ)
+ /* TODO CHECK PROMISC AND MULTI */
+ dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
+ if (mp->DL_MODE & DL_PROMISC_REQ)
dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
- if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI;
- if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD;
- dep->de_client = mp->m_source;
- break;
-
- case DEM_SINK:
- DEBUG(printf("%s running in sink mode\n", str_DevName));
- memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t));
- de_conf_addr(dep);
- break;
-
- default: break;
- }
- } else { /* Port number is out of range */
- port = ENXIO;
- dep = NULL;
+ if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI;
+ if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD;
+ break;
+
+ case DEM_SINK:
+ DEBUG(printf("%s running in sink mode\n", str_DevName));
+ memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t));
+ de_conf_addr(dep);
+ break;
+
+ default: break;
}
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = port;
- reply_mess.m3_i2 = DE_PORT_NR;
- if(dep != NULL){
- *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
+ reply_mess.DL_STAT = r;
+ if(r == OK){
+ *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
}
if (send(mp->m_source, &reply_mess) != OK)
return;
}
-
-PRIVATE void do_get_name(message *mp)
-{
- int r;
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
- mp->m_type= DL_NAME_REPLY;
- r = send(mp->m_source, mp);
- if (r!= OK)
- panic("do_getname: send failed: %d", r);
-}
-
-PRIVATE void do_reply(dpeth_t * dep, int err, int may_block)
+PRIVATE void do_reply(dpeth_t * dep)
{
message reply;
- int status = 0;
+ int r, flags = DL_NOFLAGS;
- if (dep->de_flags & DEF_ACK_SEND) status |= DL_PACK_SEND;
- if (dep->de_flags & DEF_ACK_RECV) status |= DL_PACK_RECV;
+ if (dep->de_flags & DEF_ACK_SEND) flags |= DL_PACK_SEND;
+ if (dep->de_flags & DEF_ACK_RECV) flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY;
- reply.DL_PORT = dep - de_table;
- reply.DL_PROC = dep->de_client;
- reply.DL_STAT = status | ((u32_t) err << 16);
+ reply.DL_STAT = flags;
reply.DL_COUNT = dep->de_read_s;
- reply.DL_CLCK = 0;
- status = send(dep->de_client, &reply);
+ r = send(dep->de_client, &reply);
- if(status == ELOCKED && may_block){
- /*printf("Warning: Dec21041 send lock prevented\n\n");*/
- return;
- }
-
- if(status < 0)
- panic(str_SendErrMsg, status);
+ if(r < 0)
+ panic(str_SendErrMsg, r);
dep->de_read_s = 0;
dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
static void de_update_conf(dpeth_t * dep)
{
static char dpc_fmt[] = "x:d:x";
+ char ec_key[16];
long val;
+ strcpy(ec_key, "DEETH0");
+ ec_key[5] += de_instance;
+
dep->de_mode = DEM_ENABLED;
- switch (env_parse("DEETH0", dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
+ switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
case EP_OFF: dep->de_mode = DEM_DISABLED; break;
case EP_ON: dep->de_mode = DEM_SINK; break;
}
de_loc_descr_t *descr = NULL;
iovec_dat_s_t *iovp = NULL;
- if (mp->DL_PORT < 0 || mp->DL_PORT >= DE_PORT_NR)
- panic(str_PortErrMsg, mp->DL_PORT);
+ dep = &de_state;
- dep = &de_table[mp->DL_PORT];
- dep->de_client = mp->DL_PROC;
+ dep->de_client = mp->m_source;
if (dep->de_mode == DEM_ENABLED) {
/* Setup the iovec entry to allow copying into
client layer
*/
- dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
- de_get_userdata_s(mp->DL_PROC, (cp_grant_id_t) mp->DL_GRANT, 0,
+ dep->de_read_iovec.iod_proc_nr = mp->DL_ENDPT;
+ de_get_userdata_s(mp->DL_ENDPT, (cp_grant_id_t) mp->DL_GRANT, 0,
mp->DL_COUNT, dep->de_read_iovec.iod_iovec);
dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT;
dep->de_read_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT;
}
if(!from_int){
- do_reply(dep, OK, FALSE);
+ do_reply(dep);
}
return;
assert(!(dep->de_flags & DEF_READING));
dep->rx_return_msg = *mp;
dep->de_flags |= DEF_READING;
- do_reply(dep, OK, FALSE);
+ do_reply(dep);
return;
}
int ix;
long val;
- /* TODO: should be configurable... */
- strcpy(ea_key, "DEETH0");
- strcat(ea_key, "_EA");
+ strcpy(ea_key, "DEETH0_EA");
+ ea_key[5] += de_instance;
for (ix = 0; ix < SA_ADDR_LEN; ix++) {
val = dep->de_address.ea_addr[ix];
de_loc_descr_t *descr = NULL;
char *buffer = NULL;
- if( mp->DL_PORT < 0 || mp->DL_PORT >= DE_PORT_NR)
- panic(str_PortErrMsg, mp->DL_PORT);
+ dep = &de_state;
- dep = &de_table[mp->DL_PORT];
- dep->de_client = mp->DL_PROC;
+ dep->de_client = mp->m_source;
if (dep->de_mode == DEM_ENABLED) {
buffer = descr->buf1;
iovp = &dep->de_write_iovec;
- iovp->iod_proc_nr = mp->DL_PROC;
- de_get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
+ iovp->iod_proc_nr = mp->DL_ENDPT;
+ de_get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0,
mp->DL_COUNT, iovp->iod_iovec);
iovp->iod_iovec_s = mp->DL_COUNT;
iovp->iod_grant = (cp_grant_id_t) mp->DL_GRANT;
dep->de_flags &= NOT(DEF_SENDING);
return;
}
- do_reply(dep, OK, FALSE);
+ do_reply(dep);
return;
suspend:
dep->de_flags |= DEF_SENDING;
dep->de_stat.ets_transDef++;
dep->tx_return_msg = *mp;
- do_reply(dep, OK, FALSE);
+ do_reply(dep);
}
PRIVATE void warning(const char *type, int err){
*/
-#define DE_PORT_NR 1
-
#define DE_FKEY 8 /* Shitf+ this value will dump info on console */
#undef NULL
* This file contains a ethernet device driver for NS dp8390 based ethernet
* cards.
*
- * The valid messages and their parameters are:
- *
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
- * |------------+----------+---------+----------+---------+---------+---------|
- * | HARDINT | | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITE | port nr | proc nr | count | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV | port nr | proc nr | count | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READ | port nr | proc nr | count | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV | port nr | proc nr | count | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV_S | port nr | proc nr | count | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_CONF | port nr | proc nr | | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_GETSTAT | port nr | proc nr | | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_STOP | port_nr | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
- *
- * The messages sent are:
- *
- * m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
- * |-------------+----------+---------+----------+---------+---------|
- * |DL_TASK_REPLY| port nr | proc nr | rd-count | err|stat| clock |
- * |-------------+----------+---------+----------+---------+---------|
- *
- * m_type m3_i1 m3_i2 m3_ca1
- * |-------------+---------+-----------+---------------|
- * |DL_CONF_REPLY| port nr | last port | ethernet addr |
- * |-------------+---------+-----------+---------------|
- *
* Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
*
* Modified Mar 10 1994 by Philip Homburg
#include "local.h"
#include "dp8390.h"
-#define DE_PORT_NR 3
-
-static dpeth_t de_table[DE_PORT_NR];
-static u16_t eth_ign_proto;
-static const char *progname;
+static dpeth_t de_state;
+static int de_instance;
u32_t system_hz;
port_t dpc_port;
int dpc_irq;
phys_bytes dpc_mem;
- char *dpc_envvar;
} dp_conf_t;
-PRIVATE dp_conf_t dp_conf[]= /* Card addresses */
+#define DP_CONF_NR 4
+PRIVATE dp_conf_t dp_conf[DP_CONF_NR]= /* Card addresses */
{
- /* I/O port, IRQ, Buffer address, Env. var. */
- { 0x280, 3, 0xD0000, "DPETH0" },
- { 0x300, 5, 0xC8000, "DPETH1" },
- { 0x380, 10, 0xD8000, "DPETH2" },
+ /* I/O port, IRQ, Buffer address. */
+ { 0x280, 3, 0xD0000, },
+ { 0x300, 5, 0xC8000, },
+ { 0x380, 10, 0xD8000, },
+ { 0x000, 0, 0x00000, },
};
-/* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see
- * the error: "array size is negative".
- */
-extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
-
/* Card inits configured out? */
#if !ENABLE_WDETH
#define wdeth_probe(dep) (0)
#if ENABLE_PCI
_PROTOTYPE( static void pci_conf, (void) );
#endif
-_PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
- int vectored) );
_PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int) );
-_PROTOTYPE( static void do_vread, (message *mp, int vectored) );
_PROTOTYPE( static void do_vread_s, (message *mp) );
_PROTOTYPE( static void do_init, (message *mp) );
_PROTOTYPE( static void do_int, (dpeth_t *dep) );
-_PROTOTYPE( static void do_getstat, (message *mp) );
_PROTOTYPE( static void do_getstat_s, (message *mp) );
-_PROTOTYPE( static void do_getname, (message *mp) );
-_PROTOTYPE( static void do_stop, (message *mp) );
+_PROTOTYPE( static void dp_stop, (dpeth_t *dep) );
_PROTOTYPE( static void dp_init, (dpeth_t *dep) );
_PROTOTYPE( static void dp_confaddr, (dpeth_t *dep) );
_PROTOTYPE( static void dp_reinit, (dpeth_t *dep) );
size_t offset, size_t size, void *dst) );
_PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
size_t offset, size_t size, void *dst) );
-_PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
- vir_bytes length) );
_PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
vir_bytes length) );
-_PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
- vir_bytes offset, int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
vir_bytes offset, int nic_addr, vir_bytes count) );
-_PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
- iovec_dat_t *iovp, vir_bytes offset,
- int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
iovec_dat_s_t *iovp, vir_bytes offset,
int nic_addr, vir_bytes count) );
-_PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
- iovec_dat_t *iovp, vir_bytes offset,
- int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
iovec_dat_s_t *iovp, vir_bytes offset,
int nic_addr, vir_bytes count) );
-_PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
- iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
_PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
-_PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
- iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
_PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
-_PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
- iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
_PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
-_PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) );
_PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp) );
_PROTOTYPE( static void conf_hw, (dpeth_t *dep) );
_PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) );
_PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep) );
-_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
_PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp) );
-_PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block) );
+_PROTOTYPE( static void reply, (dpeth_t *dep) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
-_PROTOTYPE( static void get_userdata, (int user_proc,
- vir_bytes user_addr, vir_bytes count, void *loc_addr) );
_PROTOTYPE( static void get_userdata_s, (int user_proc,
cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
void *loc_addr) );
-_PROTOTYPE( static void put_userdata, (int user_proc,
- vir_bytes user_addr, vir_bytes count, void *loc_addr) );
_PROTOTYPE( static void put_userdata_s, (int user_proc,
cp_grant_id_t grant, size_t count, void *loc_addr) );
_PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) );
EXTERN int env_argc;
EXTERN char **env_argv;
-PRIVATE int handle_hw_intr(void)
+PRIVATE void handle_hw_intr(void)
{
- int i, r, irq;
+ int r, irq;
dpeth_t *dep;
- for (i= 0, dep= &de_table[0]; i<DE_PORT_NR; i++, dep++)
- {
- if (dep->de_mode != DEM_ENABLED)
- continue;
- assert(dep->de_flags & DEF_ENABLED);
- irq= dep->de_irq;
- assert(irq >= 0 && irq < NR_IRQ_VECTORS);
- if (dep->de_int_pending || 1)
- {
- dep->de_int_pending= 0;
- dp_check_ints(dep);
- do_int(dep);
- r= sys_irqenable(&dep->de_hook);
- if (r != OK) {
- panic("unable enable interrupts: %d", r);
- }
+ dep = &de_state;
+
+ if (dep->de_mode != DEM_ENABLED)
+ return;
+ assert(dep->de_flags & DEF_ENABLED);
+ irq= dep->de_irq;
+ assert(irq >= 0 && irq < NR_IRQ_VECTORS);
+ if (dep->de_int_pending || 1)
+ {
+ dep->de_int_pending= 0;
+ dp_check_ints(dep);
+ do_int(dep);
+ r= sys_irqenable(&dep->de_hook);
+ if (r != OK) {
+ panic("unable enable interrupts: %d", r);
}
}
-
- return r;
}
/*===========================================================================*
if (is_ipc_notify(ipc_status)) {
switch (_ENDPOINT_P(m.m_source)) {
case HARDWARE:
- r = handle_hw_intr();
+ handle_hw_intr();
break;
case CLOCK:
printf("dp8390: notify from CLOCK\n");
switch (m.m_type)
{
- case DL_WRITE: do_vwrite(&m, FALSE, FALSE); break;
- case DL_WRITEV: do_vwrite(&m, FALSE, TRUE); break;
case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break;
- case DL_READ: do_vread(&m, FALSE); break;
- case DL_READV: do_vread(&m, TRUE); break;
case DL_READV_S: do_vread_s(&m); break;
case DL_CONF: do_init(&m); break;
- case DL_GETSTAT: do_getstat(&m); break;
case DL_GETSTAT_S: do_getstat_s(&m); break;
- case DL_GETNAME: do_getname(&m); break;
- case DL_STOP: do_stop(&m); break;
default:
panic("dp8390: illegal message: %d", m.m_type);
}
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the dp8390 driver. */
- int i;
dpeth_t *dep;
long v;
if (env_argc < 1) {
panic("A head which at this time has no name");
}
- (progname=strrchr(env_argv[0],'/')) ? progname++
- : (progname=env_argv[0]);
- for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
- {
- strcpy(dep->de_name, "dp8390#0");
- dep->de_name[7] += i;
- }
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ de_instance = (int) v;
- v= 0;
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- eth_ign_proto= htons((u16_t) v);
+ dep = &de_state;
+
+ strcpy(dep->de_name, "dp8390#0");
+ dep->de_name[7] += de_instance;
/* Announce we are up! */
netdriver_announce();
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
- message mess;
- int i;
-
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
- for (i= 0; i<DE_PORT_NR; i++)
- {
- if (de_table[i].de_mode != DEM_ENABLED)
- continue;
- mess.m_type= DL_STOP;
- mess.DL_PORT= i;
- do_stop(&mess);
- }
+ if (de_state.de_mode == DEM_ENABLED)
+ dp_stop(&de_state);
}
#if 0
void dp8390_dump()
{
dpeth_t *dep;
- int i, isr;
+ int isr;
+
+ dep = &de_state;
printf("\n");
- for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
- {
#if XXX
- if (dep->de_mode == DEM_DISABLED)
- printf("dp8390 port %d is disabled\n", i);
- else if (dep->de_mode == DEM_SINK)
- printf("dp8390 port %d is in sink mode\n", i);
+ if (dep->de_mode == DEM_DISABLED)
+ printf("dp8390 instance %d is disabled\n", de_instance);
+ else if (dep->de_mode == DEM_SINK)
+ printf("dp8390 instance %d is in sink mode\n", de_instance);
#endif
- if (dep->de_mode != DEM_ENABLED)
- continue;
+ if (dep->de_mode != DEM_ENABLED)
+ return;
- printf("dp8390 statistics of port %d:\n", i);
+ printf("dp8390 statistics of instance %d:\n", de_instance);
- printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
- printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
- printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
+ printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
+ printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
+ printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
- printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
- printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
- printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
+ printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
+ printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
+ printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
- printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
- printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
- printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
+ printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
+ printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
+ printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
- printf("collision :%8ld\t", dep->de_stat.ets_collision);
- printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
- printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
+ printf("collision :%8ld\t", dep->de_stat.ets_collision);
+ printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
+ printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
- printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
- printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
- printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
+ printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
+ printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
+ printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
- printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
+ printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
- isr= inb_reg0(dep, DP_ISR);
- printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
- inb_reg0(dep, DP_ISR), dep->de_flags);
- }
+ isr= inb_reg0(dep, DP_ISR);
+ printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
+ inb_reg0(dep, DP_ISR), dep->de_flags);
}
#endif
*===========================================================================*/
static void pci_conf()
{
- int i, h;
- char *envvar;
+ int confnr;
+ char envvar[16];
struct dpeth *dep;
static char envfmt[] = "*:d.d.d";
long v;
return;
first_time= 0;
- for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
- {
- envvar= dp_conf[i].dpc_envvar;
- if (!(dep->de_pci= env_prefix(envvar, "pci")))
- continue; /* no PCI config */
- v= 0;
- (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
- dep->de_pcibus= v;
- v= 0;
- (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
- dep->de_pcidev= v;
- v= 0;
- (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
- dep->de_pcifunc= v;
- }
-
- for (h= 1; h >= 0; h--) {
- for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
- {
- if (!dep->de_pci)
- {
- printf("pci: no pci for port %d\n", i);
- continue;
- }
- if (((dep->de_pcibus | dep->de_pcidev |
- dep->de_pcifunc) != 0) != h)
- {
- continue;
- }
- if (!rtl_probe(dep, i))
- dep->de_pci= -1;
- }
- }
-}
-#endif /* ENABLE_PCI */
-
-/*===========================================================================*
- * do_vwrite *
- *===========================================================================*/
-static void do_vwrite(mp, from_int, vectored)
-message *mp;
-int from_int;
-int vectored;
-{
- int port, count, size;
- int sendq_head;
- dpeth_t *dep;
+ dep= &de_state;
- port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (port < 0 || port >= DE_PORT_NR)
- panic("dp8390: illegal port: %d", port);
- dep= &de_table[port];
- dep->de_client= mp->DL_PROC;
+ /* Pick a default configuration for this instance. */
+ confnr= MIN(de_instance, DP_CONF_NR-1);
- if (dep->de_mode == DEM_SINK)
- {
- assert(!from_int);
- dep->de_flags |= DEF_PACK_SEND;
- reply(dep, OK, FALSE);
- return;
- }
- assert(dep->de_mode == DEM_ENABLED);
- assert(dep->de_flags & DEF_ENABLED);
- if (dep->de_flags & DEF_SEND_AVAIL)
- panic("dp8390: send already in progress");
+ strcpy(envvar, "DPETH0");
+ envvar[5] += de_instance;
+ if (!(dep->de_pci= env_prefix(envvar, "pci")))
+ return; /* no PCI config */
+ v= 0;
+ (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
+ dep->de_pcibus= v;
+ v= 0;
+ (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
+ dep->de_pcidev= v;
+ v= 0;
+ (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
+ dep->de_pcifunc= v;
- sendq_head= dep->de_sendq_head;
- if (dep->de_sendq[sendq_head].sq_filled)
- {
- if (from_int)
- panic("dp8390: should not be sending");
- dep->de_sendmsg= *mp;
- dep->de_flags |= DEF_SEND_AVAIL;
- reply(dep, OK, FALSE);
+ if (!dep->de_pci) {
+ printf("%s: no pci for instance %d\n", dep->de_name,
+ de_instance);
return;
}
- assert(!(dep->de_flags & DEF_PACK_SEND));
-
- if (vectored)
- {
- get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (count > IOVEC_NR ? IOVEC_NR : count) *
- sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
- dep->de_write_iovec.iod_iovec_s = count;
- dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
- dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
-
- dep->de_tmp_iovec = dep->de_write_iovec;
- size = calc_iovec_size(&dep->de_tmp_iovec);
- }
- else
- {
- dep->de_write_iovec.iod_iovec[0].iov_addr =
- (vir_bytes) mp->DL_ADDR;
- dep->de_write_iovec.iod_iovec[0].iov_size =
- mp->DL_COUNT;
- dep->de_write_iovec.iod_iovec_s = 1;
- dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
- dep->de_write_iovec.iod_iovec_addr = 0;
- size= mp->DL_COUNT;
- }
- if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
- {
- panic("dp8390: invalid packet size: %d", size);
- }
- (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
- dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
- size);
- dep->de_sendq[sendq_head].sq_filled= TRUE;
- if (dep->de_sendq_tail == sendq_head)
- {
- outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
- outb_reg0(dep, DP_TBCR1, size >> 8);
- outb_reg0(dep, DP_TBCR0, size & 0xff);
- outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
- }
- else
- dep->de_sendq[sendq_head].sq_size= size;
-
- if (++sendq_head == dep->de_sendq_nr)
- sendq_head= 0;
- assert(sendq_head < SENDQ_NR);
- dep->de_sendq_head= sendq_head;
-
- dep->de_flags |= DEF_PACK_SEND;
-
- /* If the interrupt handler called, don't send a reply. The reply
- * will be sent after all interrupts are handled.
- */
- if (from_int)
- return;
- reply(dep, OK, FALSE);
- assert(dep->de_mode == DEM_ENABLED);
- assert(dep->de_flags & DEF_ENABLED);
+ if (!rtl_probe(dep, de_instance))
+ dep->de_pci= -1;
}
+#endif /* ENABLE_PCI */
/*===========================================================================*
* do_vwrite_s *
message *mp;
int from_int;
{
- int port, count, size;
+ int count, size;
int sendq_head;
dpeth_t *dep;
- port = mp->DL_PORT;
+ dep= &de_state;
+
count = mp->DL_COUNT;
- if (port < 0 || port >= DE_PORT_NR)
- panic("dp8390: illegal port: %d", port);
- dep= &de_table[port];
- dep->de_client= mp->DL_PROC;
+ dep->de_client= mp->m_source;
if (dep->de_mode == DEM_SINK)
{
assert(!from_int);
dep->de_flags |= DEF_PACK_SEND;
- reply(dep, OK, FALSE);
+ reply(dep);
return;
}
assert(dep->de_mode == DEM_ENABLED);
panic("dp8390: should not be sending");
dep->de_sendmsg= *mp;
dep->de_flags |= DEF_SEND_AVAIL;
- reply(dep, OK, FALSE);
+ reply(dep);
return;
}
assert(!(dep->de_flags & DEF_PACK_SEND));
- get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
+ get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0,
(count > IOVEC_NR ? IOVEC_NR : count) *
sizeof(dep->de_write_iovec_s.iod_iovec[0]),
dep->de_write_iovec_s.iod_iovec);
dep->de_write_iovec_s.iod_iovec_s = count;
- dep->de_write_iovec_s.iod_proc_nr = mp->DL_PROC;
+ dep->de_write_iovec_s.iod_proc_nr = mp->DL_ENDPT;
dep->de_write_iovec_s.iod_grant = mp->DL_GRANT;
dep->de_write_iovec_s.iod_iovec_offset = 0;
*/
if (from_int)
return;
- reply(dep, OK, FALSE);
-
- assert(dep->de_mode == DEM_ENABLED);
- assert(dep->de_flags & DEF_ENABLED);
-}
-
-/*===========================================================================*
- * do_vread *
- *===========================================================================*/
-static void do_vread(mp, vectored)
-message *mp;
-int vectored;
-{
- int port, count;
- int size;
- dpeth_t *dep;
+ reply(dep);
- port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (port < 0 || port >= DE_PORT_NR)
- panic("dp8390: illegal port: %d", port);
- dep= &de_table[port];
- dep->de_client= mp->DL_PROC;
- if (dep->de_mode == DEM_SINK)
- {
- reply(dep, OK, FALSE);
- return;
- }
assert(dep->de_mode == DEM_ENABLED);
assert(dep->de_flags & DEF_ENABLED);
-
- if(dep->de_flags & DEF_READING)
- panic("dp8390: read already in progress");
-
- dep->de_safecopy_read= 0;
-
- if (vectored)
- {
- get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (count > IOVEC_NR ? IOVEC_NR : count) *
- sizeof(iovec_t), dep->de_read_iovec.iod_iovec);
- dep->de_read_iovec.iod_iovec_s = count;
- dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
- dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
-
- dep->de_tmp_iovec = dep->de_read_iovec;
- size= calc_iovec_size(&dep->de_tmp_iovec);
- }
- else
- {
- dep->de_read_iovec.iod_iovec[0].iov_addr =
- (vir_bytes) mp->DL_ADDR;
- dep->de_read_iovec.iod_iovec[0].iov_size =
- mp->DL_COUNT;
- dep->de_read_iovec.iod_iovec_s = 1;
- dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
- dep->de_read_iovec.iod_iovec_addr = 0;
- size= count;
- }
- if (size < ETH_MAX_PACK_SIZE_TAGGED)
- panic("dp8390: wrong packet size: %d", size);
- dep->de_flags |= DEF_READING;
-
- dp_recv(dep);
-
- if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
- (DEF_READING|DEF_STOPPED))
- {
- /* The chip is stopped, and all arrived packets are
- * delivered.
- */
- dp_reset(dep);
- }
- reply(dep, OK, FALSE);
}
/*===========================================================================*
static void do_vread_s(mp)
message *mp;
{
- int port, count;
+ int count;
int size;
dpeth_t *dep;
- port = mp->DL_PORT;
+ dep= &de_state;
+
count = mp->DL_COUNT;
- if (port < 0 || port >= DE_PORT_NR)
- panic("dp8390: illegal port: %d", port);
- dep= &de_table[port];
- dep->de_client= mp->DL_PROC;
+ dep->de_client= mp->m_source;
if (dep->de_mode == DEM_SINK)
{
- reply(dep, OK, FALSE);
+ reply(dep);
return;
}
assert(dep->de_mode == DEM_ENABLED);
assert(dep->de_flags & DEF_ENABLED);
- dep->de_safecopy_read= 1;
-
if(dep->de_flags & DEF_READING)
panic("dp8390: read already in progress");
- get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
+ get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0,
(count > IOVEC_NR ? IOVEC_NR : count) *
sizeof(dep->de_read_iovec_s.iod_iovec[0]),
dep->de_read_iovec_s.iod_iovec);
dep->de_read_iovec_s.iod_iovec_s = count;
- dep->de_read_iovec_s.iod_proc_nr = mp->DL_PROC;
+ dep->de_read_iovec_s.iod_proc_nr = mp->DL_ENDPT;
dep->de_read_iovec_s.iod_grant = mp->DL_GRANT;
dep->de_read_iovec_s.iod_iovec_offset = 0;
*/
dp_reset(dep);
}
- reply(dep, OK, FALSE);
+ reply(dep);
}
/*===========================================================================*
*===========================================================================*/
static void do_init(message *mp)
{
- int port;
dpeth_t *dep;
message reply_mess;
pci_conf(); /* Configure PCI devices. */
#endif
- port = mp->DL_PORT;
- if (port < 0 || port >= DE_PORT_NR)
- {
- reply_mess.m_type= DL_CONF_REPLY;
- reply_mess.m3_i1= ENXIO;
- mess_reply(mp, &reply_mess);
- return;
- }
- dep= &de_table[port];
+ dep= &de_state;
+
if (dep->de_mode == DEM_DISABLED)
{
/* This is the default, try to (re)locate the device. */
{
/* Probe failed, or the device is configured off. */
reply_mess.m_type= DL_CONF_REPLY;
- reply_mess.m3_i1= ENXIO;
+ reply_mess.DL_STAT= ENXIO;
mess_reply(mp, &reply_mess);
return;
}
if (dep->de_mode == DEM_SINK)
{
strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
- dep->de_address.ea_addr[5] = port;
+ dep->de_address.ea_addr[5] = de_instance;
dp_confaddr(dep);
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = mp->DL_PORT;
- reply_mess.m3_i2 = DE_PORT_NR;
- *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
+ reply_mess.DL_STAT = OK;
+ *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
mess_reply(mp, &reply_mess);
return;
}
if (mp->DL_MODE & DL_BROAD_REQ)
dep->de_flags |= DEF_BROAD;
- dep->de_client = mp->m_source;
dp_reinit(dep);
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = mp->DL_PORT;
- reply_mess.m3_i2 = DE_PORT_NR;
- *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
+ reply_mess.DL_STAT = OK;
+ *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
mess_reply(mp, &reply_mess);
}
dpeth_t *dep;
{
if (dep->de_flags & (DEF_PACK_SEND | DEF_PACK_RECV))
- reply(dep, OK, TRUE);
-}
-
-/*===========================================================================*
- * do_getstat *
- *===========================================================================*/
-static void do_getstat(message *mp)
-{
- int port, r;
- dpeth_t *dep;
-
- port = mp->DL_PORT;
- if (port < 0 || port >= DE_PORT_NR)
- panic("dp8390: illegal port: %d", port);
- dep= &de_table[port];
- dep->de_client= mp->DL_PROC;
- if (dep->de_mode == DEM_SINK)
- {
- put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
-
- mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= port;
- mp->DL_STAT= OK;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("do_getstat: send failed: %d", r);
- return;
- }
- assert(dep->de_mode == DEM_ENABLED);
- assert(dep->de_flags & DEF_ENABLED);
-
- dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
- dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
- dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
-
- put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
-
- mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= port;
- mp->DL_STAT= OK;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("do_getstat: send failed: %d", r);
+ reply(dep);
}
/*===========================================================================*
static void do_getstat_s(mp)
message *mp;
{
- int port, r;
+ int r;
dpeth_t *dep;
- port = mp->DL_PORT;
- if (port < 0 || port >= DE_PORT_NR)
- panic("dp8390: illegal port: %d", port);
- dep= &de_table[port];
- dep->de_client= mp->DL_PROC;
+ dep= &de_state;
+
if (dep->de_mode == DEM_SINK)
{
- put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
+ put_userdata_s(mp->DL_ENDPT, (vir_bytes) mp->DL_GRANT,
(vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= port;
- mp->DL_STAT= OK;
r= send(mp->m_source, mp);
if (r != OK)
panic("do_getstat: send failed: %d", r);
dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
- put_userdata_s(mp->DL_PROC, mp->DL_GRANT,
+ put_userdata_s(mp->DL_ENDPT, mp->DL_GRANT,
sizeof(dep->de_stat), &dep->de_stat);
mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= port;
- mp->DL_STAT= OK;
r= send(mp->m_source, mp);
if (r != OK)
panic("do_getstat: send failed: %d", r);
}
/*===========================================================================*
- * do_getname *
- *===========================================================================*/
-static void do_getname(mp)
-message *mp;
-{
- int r;
-
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
- mp->m_type= DL_NAME_REPLY;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("do_getname: send failed: %d", r);
-}
-
-/*===========================================================================*
- * do_stop *
+ * dp_stop *
*===========================================================================*/
-static void do_stop(mp)
-message *mp;
+static void dp_stop(dep)
+dpeth_t *dep;
{
- int port;
- dpeth_t *dep;
- port = mp->DL_PORT;
-
- if (port < 0 || port >= DE_PORT_NR)
- panic("dp8390: illegal port: %d", port);
- dep= &de_table[port];
if (dep->de_mode == DEM_SINK)
return;
assert(dep->de_mode == DEM_ENABLED);
dep->de_sendq_tail= 0;
if (!dep->de_prog_IO)
{
- dep->de_user2nicf= dp_user2nic;
dep->de_user2nicf_s= dp_user2nic_s;
- dep->de_nic2userf= dp_nic2user;
dep->de_nic2userf_s= dp_nic2user_s;
dep->de_getblockf= dp_getblock;
}
else if (dep->de_16bit)
{
- dep->de_user2nicf= dp_pio16_user2nic;
dep->de_user2nicf_s= dp_pio16_user2nic_s;
- dep->de_nic2userf= dp_pio16_nic2user;
dep->de_nic2userf_s= dp_pio16_nic2user_s;
dep->de_getblockf= dp_pio16_getblock;
}
else
{
- dep->de_user2nicf= dp_pio8_user2nic;
dep->de_user2nicf_s= dp_pio8_user2nic_s;
- dep->de_nic2userf= dp_pio8_nic2user;
dep->de_nic2userf_s= dp_pio8_nic2user_s;
dep->de_getblockf= dp_pio8_getblock;
}
long v;
/* User defined ethernet address? */
- strcpy(eakey, dp_conf[dep-de_table].dpc_envvar);
- strcat(eakey, "_EA");
+ strcpy(eakey, "DPETH0_EA");
+ eakey[5] += de_instance;
for (i= 0; i < 6; i++)
{
printf("%s: strange next page\n", dep->de_name);
next= curr;
}
- else if (eth_type == eth_ign_proto)
- {
- /* Hack: ignore packets of a given protocol, useful
- * if you share a net with 80 computers sending
- * Amoeba FLIP broadcasts. (Protocol 0x8146.)
- */
- static int first= 1;
- if (first)
- {
- first= 0;
- printf("%s: dropping proto 0x%04x packets\n",
- dep->de_name,
- ntohs(eth_ign_proto));
- }
- dep->de_stat.ets_packetR++;
- }
else if (header.dr_status & RSR_FO)
{
/* This is very serious, so we issue a warning and
else if ((header.dr_status & RSR_PRX) &&
(dep->de_flags & DEF_ENABLED))
{
- if (dep->de_safecopy_read)
- r = dp_pkt2user_s(dep, pageno, length);
- else
- r = dp_pkt2user(dep, pageno, length);
+ r = dp_pkt2user_s(dep, pageno, length);
if (r != OK)
return;
return;
dep->de_flags &= ~DEF_SEND_AVAIL;
- switch(dep->de_sendmsg.m_type)
- {
- case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break;
- case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break;
- case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE); break;
- default:
- panic("dp8390: wrong type: %d", dep->de_sendmsg.m_type);
- break;
- }
+ do_vwrite_s(&dep->de_sendmsg, TRUE);
}
/*===========================================================================*
insw(dep->de_data_port, dst, size);
}
-/*===========================================================================*
- * dp_pkt2user *
- *===========================================================================*/
-static int dp_pkt2user(dpeth_t *dep, int page, vir_bytes length)
-{
- int last, count;
-
- if (!(dep->de_flags & DEF_READING))
- return EGENERIC;
-
- last = page + (length - 1) / DP_PAGESIZE;
- if (last >= dep->de_stoppage)
- {
- count = (dep->de_stoppage - page) * DP_PAGESIZE -
- sizeof(dp_rcvhdr_t);
-
- /* Save read_iovec since we need it twice. */
- dep->de_tmp_iovec = dep->de_read_iovec;
- (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
- sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
- (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
- &dep->de_read_iovec, count, length - count);
- }
- else
- {
- (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
- sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
- }
-
- dep->de_read_s = length;
- dep->de_flags |= DEF_PACK_RECV;
- dep->de_flags &= ~DEF_READING;
-
- return OK;
-}
-
/*===========================================================================*
* dp_pkt2user_s *
*===========================================================================*/
}
/*===========================================================================*
- * dp_user2nic *
+ * dp_user2nic_s *
*===========================================================================*/
-static void dp_user2nic(dep, iovp, offset, nic_addr, count)
+static void dp_user2nic_s(dep, iovp, offset, nic_addr, count)
dpeth_t *dep;
-iovec_dat_t *iovp;
-vir_bytes offset;
-int nic_addr;
-vir_bytes count;
-{
- vir_bytes vir_hw;
- int i, r;
- vir_bytes bytes;
-
- vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
-
- i= 0;
- while (count > 0)
- {
- if (i >= IOVEC_NR)
- {
- dp_next_iovec(iovp);
- i= 0;
- continue;
- }
- assert(i < iovp->iod_iovec_s);
- if (offset >= iovp->iod_iovec[i].iov_size)
- {
- offset -= iovp->iod_iovec[i].iov_size;
- i++;
- continue;
- }
- bytes = iovp->iod_iovec[i].iov_size - offset;
- if (bytes > count)
- bytes = count;
-
- r= sys_vircopy(iovp->iod_proc_nr, D,
- iovp->iod_iovec[i].iov_addr + offset,
- SELF, D, vir_hw, bytes);
- if (r != OK)
- panic("dp_user2nic: sys_vircopy failed: %d", r);
-
- count -= bytes;
- vir_hw += bytes;
- offset += bytes;
- }
- assert(count == 0);
-}
-
-/*===========================================================================*
- * dp_user2nic_s *
- *===========================================================================*/
-static void dp_user2nic_s(dep, iovp, offset, nic_addr, count)
-dpeth_t *dep;
-iovec_dat_s_t *iovp;
+iovec_dat_s_t *iovp;
vir_bytes offset;
int nic_addr;
vir_bytes count;
assert(count == 0);
}
-/*===========================================================================*
- * dp_pio8_user2nic *
- *===========================================================================*/
-static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
-dpeth_t *dep;
-iovec_dat_t *iovp;
-vir_bytes offset;
-int nic_addr;
-vir_bytes count;
-{
- int bytes, i;
-
- outb_reg0(dep, DP_ISR, ISR_RDC);
-
- outb_reg0(dep, DP_RBCR0, count & 0xFF);
- outb_reg0(dep, DP_RBCR1, count >> 8);
- outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
- outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
- outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
-
- i= 0;
- while (count > 0)
- {
- if (i >= IOVEC_NR)
- {
- dp_next_iovec(iovp);
- i= 0;
- continue;
- }
- assert(i < iovp->iod_iovec_s);
- if (offset >= iovp->iod_iovec[i].iov_size)
- {
- offset -= iovp->iod_iovec[i].iov_size;
- i++;
- continue;
- }
- bytes = iovp->iod_iovec[i].iov_size - offset;
- if (bytes > count)
- bytes = count;
-
- do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
- iovp->iod_iovec[i].iov_addr + offset, bytes);
- count -= bytes;
- offset += bytes;
- }
- assert(count == 0);
-
- for (i= 0; i<100; i++)
- {
- if (inb_reg0(dep, DP_ISR) & ISR_RDC)
- break;
- }
- if (i == 100)
- {
- panic("dp8390: remote dma failed to complete");
- }
-}
-
/*===========================================================================*
* dp_pio8_user2nic_s *
*===========================================================================*/
}
}
-/*===========================================================================*
- * dp_pio16_user2nic *
- *===========================================================================*/
-static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
-dpeth_t *dep;
-iovec_dat_t *iovp;
-vir_bytes offset;
-int nic_addr;
-vir_bytes count;
-{
- vir_bytes vir_user;
- vir_bytes ecount;
- int i, r, bytes, user_proc;
- u8_t two_bytes[2];
- int odd_byte;
-
- ecount= (count+1) & ~1;
- odd_byte= 0;
-
- outb_reg0(dep, DP_ISR, ISR_RDC);
- outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
- outb_reg0(dep, DP_RBCR1, ecount >> 8);
- outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
- outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
- outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
-
- i= 0;
- while (count > 0)
- {
- if (i >= IOVEC_NR)
- {
- dp_next_iovec(iovp);
- i= 0;
- continue;
- }
- assert(i < iovp->iod_iovec_s);
- if (offset >= iovp->iod_iovec[i].iov_size)
- {
- offset -= iovp->iod_iovec[i].iov_size;
- i++;
- continue;
- }
- bytes = iovp->iod_iovec[i].iov_size - offset;
- if (bytes > count)
- bytes = count;
-
- user_proc= iovp->iod_proc_nr;
- vir_user= iovp->iod_iovec[i].iov_addr + offset;
- if (odd_byte)
- {
- r= sys_vircopy(user_proc, D, vir_user,
- SELF, D, (vir_bytes)&two_bytes[1], 1);
- if (r != OK) {
- panic("dp_pio16_user2nic: sys_vircopy failed: %d",
- r);
- }
- outw(dep->de_data_port, *(u16_t *)two_bytes);
- count--;
- offset++;
- bytes--;
- vir_user++;
- odd_byte= 0;
- if (!bytes)
- continue;
- }
- ecount= bytes & ~1;
- if (ecount != 0)
- {
- do_vir_outsw(dep->de_data_port, user_proc, vir_user,
- ecount);
- count -= ecount;
- offset += ecount;
- bytes -= ecount;
- vir_user += ecount;
- }
- if (bytes)
- {
- assert(bytes == 1);
- r= sys_vircopy(user_proc, D, vir_user,
- SELF, D, (vir_bytes)&two_bytes[0], 1);
- if (r != OK) {
- panic("dp_pio16_user2nic: sys_vircopy failed: %d",
- r);
- }
- count--;
- offset++;
- bytes--;
- vir_user++;
- odd_byte= 1;
- }
- }
- assert(count == 0);
-
- if (odd_byte)
- outw(dep->de_data_port, *(u16_t *)two_bytes);
-
- for (i= 0; i<100; i++)
- {
- if (inb_reg0(dep, DP_ISR) & ISR_RDC)
- break;
- }
- if (i == 100)
- {
- panic("dp8390: remote dma failed to complete");
- }
-}
-
/*===========================================================================*
* dp_pio16_user2nic_s *
*===========================================================================*/
}
}
-/*===========================================================================*
- * dp_nic2user *
- *===========================================================================*/
-static void dp_nic2user(dep, nic_addr, iovp, offset, count)
-dpeth_t *dep;
-int nic_addr;
-iovec_dat_t *iovp;
-vir_bytes offset;
-vir_bytes count;
-{
- int bytes, i, r;
-
- vir_bytes vir_hw = (vir_bytes) (dep->de_locmem + nic_addr);
-
- i= 0;
- while (count > 0)
- {
- if (i >= IOVEC_NR)
- {
- dp_next_iovec(iovp);
- i= 0;
- continue;
- }
- assert(i < iovp->iod_iovec_s);
- if (offset >= iovp->iod_iovec[i].iov_size)
- {
- offset -= iovp->iod_iovec[i].iov_size;
- i++;
- continue;
- }
- bytes = iovp->iod_iovec[i].iov_size - offset;
- if (bytes > count)
- bytes = count;
-
- r= sys_vircopy(SELF, D, vir_hw,
- iovp->iod_proc_nr, D,
- iovp->iod_iovec[i].iov_addr + offset, bytes);
- if (r != OK)
- panic("dp_nic2user: sys_vircopy failed: %d", r);
-
- count -= bytes;
- vir_hw += bytes;
- offset += bytes;
- }
- assert(count == 0);
-}
-
/*===========================================================================*
* dp_nic2user_s *
*===========================================================================*/
assert(count == 0);
}
-/*===========================================================================*
- * dp_pio8_nic2user *
- *===========================================================================*/
-static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
-dpeth_t *dep;
-int nic_addr;
-iovec_dat_t *iovp;
-vir_bytes offset;
-vir_bytes count;
-{
- int bytes, i;
-
- outb_reg0(dep, DP_RBCR0, count & 0xFF);
- outb_reg0(dep, DP_RBCR1, count >> 8);
- outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
- outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
- outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
-
- i= 0;
- while (count > 0)
- {
- if (i >= IOVEC_NR)
- {
- dp_next_iovec(iovp);
- i= 0;
- continue;
- }
- assert(i < iovp->iod_iovec_s);
- if (offset >= iovp->iod_iovec[i].iov_size)
- {
- offset -= iovp->iod_iovec[i].iov_size;
- i++;
- continue;
- }
- bytes = iovp->iod_iovec[i].iov_size - offset;
- if (bytes > count)
- bytes = count;
-
- do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
- iovp->iod_iovec[i].iov_addr + offset, bytes);
- count -= bytes;
- offset += bytes;
- }
- assert(count == 0);
-}
-
/*===========================================================================*
* dp_pio8_nic2user_s *
*===========================================================================*/
assert(count == 0);
}
-/*===========================================================================*
- * dp_pio16_nic2user *
- *===========================================================================*/
-static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
-dpeth_t *dep;
-int nic_addr;
-iovec_dat_t *iovp;
-vir_bytes offset;
-vir_bytes count;
-{
- vir_bytes vir_user;
- vir_bytes ecount;
- int i, r, bytes, user_proc;
- u8_t two_bytes[2];
- int odd_byte;
-
- ecount= (count+1) & ~1;
- odd_byte= 0;
-
- outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
- outb_reg0(dep, DP_RBCR1, ecount >> 8);
- outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
- outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
- outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
-
- i= 0;
- while (count > 0)
- {
- if (i >= IOVEC_NR)
- {
- dp_next_iovec(iovp);
- i= 0;
- continue;
- }
- assert(i < iovp->iod_iovec_s);
- if (offset >= iovp->iod_iovec[i].iov_size)
- {
- offset -= iovp->iod_iovec[i].iov_size;
- i++;
- continue;
- }
- bytes = iovp->iod_iovec[i].iov_size - offset;
- if (bytes > count)
- bytes = count;
-
- user_proc= iovp->iod_proc_nr;
- vir_user= iovp->iod_iovec[i].iov_addr + offset;
- if (odd_byte)
- {
- r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
- user_proc, D, vir_user, 1);
- if (r != OK) {
- panic("dp_pio16_nic2user: sys_vircopy failed: %d",
- r);
- }
- count--;
- offset++;
- bytes--;
- vir_user++;
- odd_byte= 0;
- if (!bytes)
- continue;
- }
- ecount= bytes & ~1;
- if (ecount != 0)
- {
- do_vir_insw(dep->de_data_port, user_proc, vir_user,
- ecount);
- count -= ecount;
- offset += ecount;
- bytes -= ecount;
- vir_user += ecount;
- }
- if (bytes)
- {
- assert(bytes == 1);
- *(u16_t *)two_bytes= inw(dep->de_data_port);
- r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
- user_proc, D, vir_user, 1);
- if (r != OK) {
- panic("dp_pio16_nic2user: sys_vircopy failed: %d", r);
- }
- count--;
- offset++;
- bytes--;
- vir_user++;
- odd_byte= 1;
- }
- }
- assert(count == 0);
-}
-
/*===========================================================================*
* dp_pio16_nic2user_s *
*===========================================================================*/
assert(count == 0);
}
-/*===========================================================================*
- * dp_next_iovec *
- *===========================================================================*/
-static void dp_next_iovec(iovp)
-iovec_dat_t *iovp;
-{
- assert(iovp->iod_iovec_s > IOVEC_NR);
-
- iovp->iod_iovec_s -= IOVEC_NR;
-
- iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
-
- get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
- (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
- sizeof(iovec_t), iovp->iod_iovec);
-}
-
/*===========================================================================*
* dp_next_iovec_s *
*===========================================================================*/
{
static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
- int ifnr;
+ int confnr;
dp_conf_t *dcp;
dep->de_mode= DEM_DISABLED; /* Superfluous */
- ifnr= dep-de_table;
- dcp= &dp_conf[ifnr];
+ /* Pick a default configuration for this instance. */
+ confnr= MIN(de_instance, DP_CONF_NR-1);
+
+ dcp= &dp_conf[confnr];
update_conf(dep, dcp);
if (dep->de_mode != DEM_ENABLED)
return;
{
long v;
static char dpc_fmt[] = "x:d:x:x";
+ char eckey[16];
#if ENABLE_PCI
if (dep->de_pci)
}
#endif
+ strcpy(eckey, "DPETH0");
+ eckey[5] += de_instance;
+
/* Get the default settings and modify them from the environment. */
dep->de_mode= DEM_SINK;
v= dcp->dpc_port;
- switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL)) {
+ switch (env_parse(eckey, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL)) {
case EP_OFF:
dep->de_mode= DEM_DISABLED;
break;
dep->de_base_port= v;
v= dcp->dpc_irq | DEI_DEFAULT;
- (void) env_parse(dcp->dpc_envvar, dpc_fmt, 1, &v, 0L,
- (long) NR_IRQ_VECTORS - 1);
+ (void) env_parse(eckey, dpc_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1);
dep->de_irq= v;
v= dcp->dpc_mem;
- (void) env_parse(dcp->dpc_envvar, dpc_fmt, 2, &v, 0L, 0xFFFFFL);
+ (void) env_parse(eckey, dpc_fmt, 2, &v, 0L, 0xFFFFFL);
dep->de_linmem= v;
v= 0;
- (void) env_parse(dcp->dpc_envvar, dpc_fmt, 3, &v, 0x2000L, 0x8000L);
+ (void) env_parse(eckey, dpc_fmt, 3, &v, 0x2000L, 0x8000L);
dep->de_ramsize= v;
}
panic("map_hw_buffer: cannot malloc size: %d", size);
o= I386_PAGE_SIZE - ((vir_bytes)buf % I386_PAGE_SIZE);
abuf= buf + o;
- printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
+ printf("buf at %p, abuf at %p\n", buf, abuf);
#if 0
r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
dep->de_locmem = abuf;
}
-/*===========================================================================*
- * calc_iovec_size *
- *===========================================================================*/
-static int calc_iovec_size(iovp)
-iovec_dat_t *iovp;
-{
- /* Calculate the size of a request. Note that the iovec_dat
- * structure will be unusable after calc_iovec_size.
- */
- int size;
- int i;
-
- size= 0;
- i= 0;
- while (i < iovp->iod_iovec_s)
- {
- if (i >= IOVEC_NR)
- {
- dp_next_iovec(iovp);
- i= 0;
- continue;
- }
- size += iovp->iod_iovec[i].iov_size;
- i++;
- }
- return size;
-}
-
/*===========================================================================*
* calc_iovec_size_s *
*===========================================================================*/
/*===========================================================================*
* reply *
*===========================================================================*/
-static void reply(dep, err, may_block)
+static void reply(dep)
dpeth_t *dep;
-int err;
-int may_block;
{
message reply;
- int status;
+ int flags;
int r;
- status = 0;
+ flags = DL_NOFLAGS;
if (dep->de_flags & DEF_PACK_SEND)
- status |= DL_PACK_SEND;
+ flags |= DL_PACK_SEND;
if (dep->de_flags & DEF_PACK_RECV)
- status |= DL_PACK_RECV;
+ flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY;
- reply.DL_PORT = dep - de_table;
- reply.DL_PROC = dep->de_client;
- reply.DL_STAT = status | ((u32_t) err << 16);
+ reply.DL_FLAGS = flags;
reply.DL_COUNT = dep->de_read_s;
- reply.DL_CLCK = 0; /* Don't know */
r= send(dep->de_client, &reply);
- if (r == ELOCKED && may_block)
- {
-#if 0
- printf("send locked\n");
-#endif
- return;
- }
-
if (r < 0)
panic("dp8390: send failed: %d", r);
panic("dp8390: unable to mess_reply");
}
-/*===========================================================================*
- * get_userdata *
- *===========================================================================*/
-static void get_userdata(user_proc, user_addr, count, loc_addr)
-int user_proc;
-vir_bytes user_addr;
-vir_bytes count;
-void *loc_addr;
-{
- int r;
-
- r= sys_vircopy(user_proc, D, user_addr,
- SELF, D, (vir_bytes)loc_addr, count);
- if (r != OK)
- panic("get_userdata: sys_vircopy failed: %d", r);
-}
-
/*===========================================================================*
* get_userdata_s *
*===========================================================================*/
panic("get_userdata: sys_safecopyfrom failed: %d", r);
}
-/*===========================================================================*
- * put_userdata *
- *===========================================================================*/
-static void put_userdata(user_proc, user_addr, count, loc_addr)
-int user_proc;
-vir_bytes user_addr;
-vir_bytes count;
-void *loc_addr;
-{
- int r;
-
- r= sys_vircopy(SELF, D, (vir_bytes)loc_addr,
- user_proc, D, user_addr, count);
- if (r != OK)
- panic("put_userdata: sys_vircopy failed: %d", r);
-}
-
/*===========================================================================*
* put_userdata_s *
*===========================================================================*/
int de_flags;
int de_mode;
eth_stat_t de_stat;
- iovec_dat_t de_read_iovec;
iovec_dat_s_t de_read_iovec_s;
- int de_safecopy_read;
- iovec_dat_t de_write_iovec;
iovec_dat_s_t de_write_iovec_s;
- iovec_dat_t de_tmp_iovec;
iovec_dat_s_t de_tmp_iovec_s;
vir_bytes de_read_s;
endpoint_t de_client;
message de_sendmsg;
- dp_user2nicf_t de_user2nicf;
dp_user2nicf_s_t de_user2nicf_s;
- dp_nic2userf_t de_nic2userf;
dp_nic2userf_s_t de_nic2userf_s;
dp_getblock_t de_getblockf;
} dpeth_t;
-#include <assert.h>
/*
** File: dp.c Version 1.01, Oct. 17, 2007
** Original: eth.c Version 1.00, Jan. 14, 1997
** to remove bord specific code. It should operate (I hope)
** with any board driver.
**
-** The valid messages and their parameters are:
-**
-** m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR
-** +------------+---------+---------+--------+-------+---------+
-** | NOTIFY from HARDWARE, CLOCK, TTY, RS, PM, SYSTEM |
-** +------------+---------+---------+--------+-------+---------+
-** | HARD_STOP | | | | | |
-** +------------+---------+---------+--------+-------+---------+
-** | DL_WRITE | port nr | proc nr | count | mode | address | (3)
-** +------------+---------+---------+--------+-------+---------+
-** | DL_WRITEV | port nr | proc nr | count | mode | address | (4)
-** +------------+---------+---------+--------+-------+---------+
-** | DL_READ | port nr | proc nr | count | | address | (5)
-** +------------+---------+---------+--------+-------+---------+
-** | DL_READV | port nr | proc nr | count | | address | (6)
-** +------------+---------+---------+--------+-------+---------+
-** | DL_CONF | port nr | proc nr | | mode | address | (7)
-** +------------+---------+---------+--------+-------+---------+
-** | DL_STOP | port_nr | | | | | (8)
-** +------------+---------+---------+--------+-------+---------+
-** | DL_GETSTAT | port nr | proc nr | | | address | (9)
-** +------------+---------+---------+--------+-------+---------+
-**
-** The messages sent are:
-**
-** m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
-** +------------+---------+---------+--------+---------+---------+
-** |DL_TASK_REPL| port nr | proc nr |rd-count| err|stat| clock | (21)
-** +------------+---------+---------+--------+---------+---------+
-**
-** m_type m3_i1 m3_i2 m3_ca1
-** +------------+---------+---------+---------------+
-** |DL_CONF_REPL| port nr |last port| ethernet addr | (20)
-** +------------+---------+---------+---------------+
-**
** $Id$
-**
-** 2007-10-17: modified by jfdsmit@gmail.com
-** added a third argument to the reply() function because not
-** every reply should be of DL_TASK_REPLY (one should be
-** DL_STAT_REPLY)
*/
#include <minix/drivers.h>
/*
** Local data
*/
-extern int errno;
-static dpeth_t de_table[DE_PORT_NR];
-static const char *progname;
+static dpeth_t de_state;
+static int de_instance;
typedef struct dp_conf { /* Configuration description structure */
port_t dpc_port;
int dpc_irq;
phys_bytes dpc_mem;
- char *dpc_envvar;
} dp_conf_t;
/* Device default configuration */
-static dp_conf_t dp_conf[DE_PORT_NR] = {
- /* I/O port, IRQ, Buff addr, Env. var, Buf. selector */
- { 0x300, 5, 0xC8000, "DPETH0", },
- { 0x280, 10, 0xCC000, "DPETH1", },
+#define DP_CONF_NR 3
+static dp_conf_t dp_conf[DP_CONF_NR] = {
+ /* I/O port, IRQ, Buff addr, Env. var */
+ { 0x300, 5, 0xC8000, },
+ { 0x280, 10, 0xCC000, },
+ { 0x000, 0, 0x00000, },
};
static char CopyErrMsg[] = "unable to read/write user data";
-static char PortErrMsg[] = "illegal port";
static char RecvErrMsg[] = "netdriver_receive failed";
static char SendErrMsg[] = "send failed";
static char SizeErrMsg[] = "illegal packet size";
static char TypeErrMsg[] = "illegal message type";
static char DevName[] = "eth#?";
-static void do_getname(message *mp);
-
/*
** Name: void reply(dpeth_t *dep, int err, int m_type)
** Function: Fills a reply message and sends it.
*/
-static void reply(dpeth_t * dep, int err, int m_type)
+static void reply(dpeth_t * dep)
{
message reply;
- int status = FALSE;
+ int r, flags;
- if (dep->de_flags & DEF_ACK_SEND) status |= DL_PACK_SEND;
- if (dep->de_flags & DEF_ACK_RECV) status |= DL_PACK_RECV;
+ flags = DL_NOFLAGS;
+ if (dep->de_flags & DEF_ACK_SEND) flags |= DL_PACK_SEND;
+ if (dep->de_flags & DEF_ACK_RECV) flags |= DL_PACK_RECV;
- reply.m_type = m_type;
- reply.DL_PORT = dep - de_table;
- reply.DL_PROC = dep->de_client;
- reply.DL_STAT = status /* | ((u32_t) err << 16) */;
+ reply.m_type = DL_TASK_REPLY;
+ reply.DL_FLAGS = flags;
reply.DL_COUNT = dep->de_read_s;
- getuptime(&reply.DL_CLCK);
- DEBUG(printf("\t reply %d (%ld)\n", reply.m_type, reply.DL_STAT));
+ DEBUG(printf("\t reply %d (%lx)\n", reply.m_type, reply.DL_FLAGS));
- if ((status = send(dep->de_client, &reply)) == OK) {
- dep->de_read_s = 0;
- dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
+ if ((r = send(dep->de_client, &reply)) != OK)
+ panic(SendErrMsg, r);
- } else if (status != ELOCKED || err == OK)
- panic(SendErrMsg, status);
+ dep->de_read_s = 0;
+ dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
return;
}
int ix;
long val;
- strcpy(ea_key, dp_conf[dep - de_table].dpc_envvar);
- strcat(ea_key, "_EA");
+ strcpy(ea_key, "DPETH0_EA");
+ ea_key[5] += de_instance;
for (ix = 0; ix < SA_ADDR_LEN; ix++) {
val = dep->de_address.ea_addr[ix];
static void update_conf(dpeth_t * dep, const dp_conf_t * dcp)
{
static char dpc_fmt[] = "x:d:x";
+ char ec_key[16];
long val;
+ strcpy(ec_key, "DPETH0");
+ ec_key[5] += de_instance;
+
dep->de_mode = DEM_SINK;
val = dcp->dpc_port; /* Get I/O port address */
- switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
+ switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
case EP_OFF: dep->de_mode = DEM_DISABLED; break;
case EP_ON:
case EP_SET: dep->de_mode = DEM_ENABLED; break;
dep->de_base_port = val;
val = dcp->dpc_irq | DEI_DEFAULT; /* Get Interrupt line (IRQ) */
- env_parse(dcp->dpc_envvar, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1);
+ env_parse(ec_key, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1);
dep->de_irq = val;
val = dcp->dpc_mem; /* Get shared memory address */
- env_parse(dcp->dpc_envvar, dpc_fmt, 2, &val, 0L, LONG_MAX);
+ env_parse(ec_key, dpc_fmt, 2, &val, 0L, LONG_MAX);
dep->de_linmem = val;
return;
static void do_dump(const message *mp)
{
dpeth_t *dep;
- int port;
+
+ dep = &de_state;
printf("\n\n");
- for (port = 0, dep = de_table; port < DE_PORT_NR; port += 1, dep += 1) {
- if (dep->de_mode == DEM_DISABLED) continue;
+ if (dep->de_mode == DEM_DISABLED) return;
- printf("%s statistics:\t\t", dep->de_name);
+ printf("%s statistics:\t\t", dep->de_name);
- /* Network interface status */
- printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending);
+ /* Network interface status */
+ printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending);
- (*dep->de_dumpstatsf) (dep);
+ (*dep->de_dumpstatsf) (dep);
- /* Transmitted/received bytes */
- printf("Tx bytes:%10ld\t", dep->bytes_Tx);
- printf("Rx bytes:%10ld\n", dep->bytes_Rx);
+ /* Transmitted/received bytes */
+ printf("Tx bytes:%10ld\t", dep->bytes_Tx);
+ printf("Rx bytes:%10ld\n", dep->bytes_Rx);
- /* Transmitted/received packets */
- printf("Tx OK: %8ld\t", dep->de_stat.ets_packetT);
- printf("Rx OK: %8ld\n", dep->de_stat.ets_packetR);
+ /* Transmitted/received packets */
+ printf("Tx OK: %8ld\t", dep->de_stat.ets_packetT);
+ printf("Rx OK: %8ld\n", dep->de_stat.ets_packetR);
- /* Transmit/receive errors */
- printf("Tx Err: %8ld\t", dep->de_stat.ets_sendErr);
- printf("Rx Err: %8ld\n", dep->de_stat.ets_recvErr);
+ /* Transmit/receive errors */
+ printf("Tx Err: %8ld\t", dep->de_stat.ets_sendErr);
+ printf("Rx Err: %8ld\n", dep->de_stat.ets_recvErr);
- /* Transmit unnerruns/receive overrruns */
- printf("Tx Und: %8ld\t", dep->de_stat.ets_fifoUnder);
- printf("Rx Ovr: %8ld\n", dep->de_stat.ets_fifoOver);
+ /* Transmit unnerruns/receive overrruns */
+ printf("Tx Und: %8ld\t", dep->de_stat.ets_fifoUnder);
+ printf("Rx Ovr: %8ld\n", dep->de_stat.ets_fifoOver);
+
+ /* Transmit collisions/receive CRC errors */
+ printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision);
+ printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr);
- /* Transmit collisions/receive CRC errors */
- printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision);
- printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr);
- }
return;
}
*/
static void do_init(const message * mp)
{
- int port;
dpeth_t *dep;
dp_conf_t *dcp;
message reply_mess;
+ int r, confnr;
- port = mp->DL_PORT;
- if (port >= 0 && port < DE_PORT_NR) {
-
- dep = &de_table[port];
- dcp = &dp_conf[port];
- strcpy(dep->de_name, DevName);
- dep->de_name[4] = '0' + port;
-
- if (dep->de_mode == DEM_DISABLED) {
-
- update_conf(dep, dcp); /* First time thru */
- if (dep->de_mode == DEM_ENABLED &&
- !el1_probe(dep) && /* Probe for 3c501 */
- !wdeth_probe(dep) && /* Probe for WD80x3 */
- !ne_probe(dep) && /* Probe for NEx000 */
- !el2_probe(dep) && /* Probe for 3c503 */
- !el3_probe(dep)) { /* Probe for 3c509 */
- printf("%s: warning no ethernet card found at 0x%04X\n",
- dep->de_name, dep->de_base_port);
- dep->de_mode = DEM_DISABLED;
- }
- }
+ dep = &de_state;
- /* 'de_mode' may change if probe routines fail, test again */
- switch (dep->de_mode) {
+ /* Pick a default configuration for this instance. */
+ confnr = MIN(de_instance, DP_CONF_NR-1);
- case DEM_DISABLED:
- /* Device is configured OFF or hardware probe failed */
- port = ENXIO;
- break;
+ dcp = &dp_conf[confnr];
+ strcpy(dep->de_name, DevName);
+ dep->de_name[4] = '0' + de_instance;
- case DEM_ENABLED:
- /* Device is present and probed */
- if (dep->de_flags == DEF_EMPTY) {
- /* These actions only the first time */
- do_first_init(dep, dcp);
- dep->de_flags |= DEF_ENABLED;
- }
- dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
- if (mp->DL_MODE & DL_PROMISC_REQ)
- dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
- if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI;
- if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD;
- (*dep->de_flagsf) (dep);
- dep->de_client = mp->m_source;
- break;
+ if (dep->de_mode == DEM_DISABLED) {
- case DEM_SINK:
- /* Device not present (sink mode) */
- memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t));
- dp_confaddr(dep); /* Station address from env. */
- break;
-
- default: break;
+ update_conf(dep, dcp); /* First time thru */
+ if (dep->de_mode == DEM_ENABLED &&
+ !el1_probe(dep) && /* Probe for 3c501 */
+ !wdeth_probe(dep) && /* Probe for WD80x3 */
+ !ne_probe(dep) && /* Probe for NEx000 */
+ !el2_probe(dep) && /* Probe for 3c503 */
+ !el3_probe(dep)) { /* Probe for 3c509 */
+ printf("%s: warning no ethernet card found at 0x%04X\n",
+ dep->de_name, dep->de_base_port);
+ dep->de_mode = DEM_DISABLED;
}
- *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
+ }
+
+ r = OK;
+
+ /* 'de_mode' may change if probe routines fail, test again */
+ switch (dep->de_mode) {
+
+ case DEM_DISABLED:
+ /* Device is configured OFF or hardware probe failed */
+ r = ENXIO;
+ break;
- } else { /* Port number is out of range */
- port = ENXIO;
+ case DEM_ENABLED:
+ /* Device is present and probed */
+ if (dep->de_flags == DEF_EMPTY) {
+ /* These actions only the first time */
+ do_first_init(dep, dcp);
+ dep->de_flags |= DEF_ENABLED;
+ }
+ dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
+ if (mp->DL_MODE & DL_PROMISC_REQ)
+ dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
+ if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI;
+ if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD;
+ (*dep->de_flagsf) (dep);
+ break;
+
+ case DEM_SINK:
+ /* Device not present (sink mode) */
+ memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t));
+ dp_confaddr(dep); /* Station address from env. */
+ break;
+
+ default: break;
}
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = port;
- reply_mess.m3_i2 = DE_PORT_NR;
+ reply_mess.DL_STAT = r;
+ if (r == OK)
+ *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
DEBUG(printf("\t reply %d\n", reply_mess.m_type));
if (send(mp->m_source, &reply_mess) != OK) /* Can't send */
panic(SendErrMsg, mp->m_source);
*/
static void do_vwrite_s(const message * mp)
{
- int port, size;
+ int size;
dpeth_t *dep;
- port = mp->DL_PORT;
- if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */
- panic(PortErrMsg, EINVAL);
+ dep = &de_state;
- dep = &de_table[port];
- dep->de_client = mp->DL_PROC;
+ dep->de_client = mp->m_source;
if (dep->de_mode == DEM_ENABLED) {
if (dep->de_flags & DEF_SENDING) /* Is sending in progress? */
panic("send already in progress ");
- dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
- get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
+ dep->de_write_iovec.iod_proc_nr = mp->DL_ENDPT;
+ get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0,
mp->DL_COUNT, dep->de_write_iovec.iod_iovec);
dep->de_write_iovec.iod_iovec_s = mp->DL_COUNT;
dep->de_write_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT;
} else if (dep->de_mode == DEM_SINK)
dep->de_flags |= DEF_ACK_SEND;
- reply(dep, OK, DL_TASK_REPLY);
+ reply(dep);
return;
}
*/
static void do_vread_s(const message * mp)
{
- int port, size;
+ int size;
dpeth_t *dep;
- port = mp->DL_PORT;
- if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */
- panic(PortErrMsg, EINVAL);
+ dep = &de_state;
- dep = &de_table[port];
- dep->de_client = mp->DL_PROC;
+ dep->de_client = mp->m_source;
if (dep->de_mode == DEM_ENABLED) {
if (dep->de_flags & DEF_READING) /* Reading in progress */
panic("read already in progress");
- dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
- get_userdata_s(mp->DL_PROC, (cp_grant_id_t) mp->DL_GRANT, 0,
+ dep->de_read_iovec.iod_proc_nr = mp->DL_ENDPT;
+ get_userdata_s(mp->DL_ENDPT, (cp_grant_id_t) mp->DL_GRANT, 0,
mp->DL_COUNT, dep->de_read_iovec.iod_iovec);
dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT;
dep->de_read_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT;
dep->de_flags &= NOT(DEF_STOPPED);
#endif
}
- reply(dep, OK, DL_TASK_REPLY);
+ reply(dep);
return;
}
*/
static void do_getstat_s(const message * mp)
{
- int port, rc;
+ int rc;
dpeth_t *dep;
+ message reply_mess;
- port = mp->DL_PORT;
- if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */
- panic(PortErrMsg, EINVAL);
-
- dep = &de_table[port];
- dep->de_client = mp->DL_PROC;
+ dep = &de_state;
if (dep->de_mode == DEM_ENABLED) (*dep->de_getstatsf) (dep);
- if ((rc = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0,
+ if ((rc = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0,
(vir_bytes)&dep->de_stat,
(vir_bytes) sizeof(dep->de_stat), 0)) != OK)
panic(CopyErrMsg, rc);
- reply(dep, OK, DL_STAT_REPLY);
- return;
-}
-static void do_getname(mp)
-message *mp;
-{
- int r;
-
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
- mp->m_type= DL_NAME_REPLY;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("do_getname: send failed: %d", r);
+ reply_mess.m_type = DL_STAT_REPLY;
+ rc= send(mp->m_source, &reply_mess);
+ if (rc != OK)
+ panic("do_getname: send failed: %d", rc);
+ return;
}
/*
-** Name: void do_stop(message *mp)
+** Name: void dp_stop(dpeth_t *dep)
** Function: Stops network interface.
*/
-static void do_stop(const message * mp)
+static void dp_stop(dpeth_t * dep)
{
- int port;
- dpeth_t *dep;
- port = mp->DL_PORT;
- if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */
- panic(PortErrMsg, EINVAL);
-
- dep = &de_table[port];
if (dep->de_mode == DEM_ENABLED && (dep->de_flags & DEF_ENABLED)) {
/* Stop device */
{
dpeth_t *dep;
- for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) {
- /* If device is enabled and interrupt pending */
- if (dep->de_mode == DEM_ENABLED) {
- dep->de_int_pending = TRUE;
- (*dep->de_interruptf) (dep);
- if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
- reply(dep, !OK, DL_TASK_REPLY);
- dep->de_int_pending = FALSE;
- sys_irqenable(&dep->de_hook);
- }
+ dep = &de_state;
+
+ /* If device is enabled and interrupt pending */
+ if (dep->de_mode == DEM_ENABLED) {
+ dep->de_int_pending = TRUE;
+ (*dep->de_interruptf) (dep);
+ if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
+ reply(dep);
+ dep->de_int_pending = FALSE;
+ sys_irqenable(&dep->de_hook);
}
}
case DL_GETSTAT_S: /* Get device statistics */
do_getstat_s(&m);
break;
- case DL_GETNAME:
- do_getname(&m);
- break;
- case DL_STOP: /* Stop device */
- do_stop(&m);
- break;
default: /* Invalid message type */
panic(TypeErrMsg, m.m_type);
break;
{
/* Initialize the dpeth driver. */
int fkeys, sfkeys;
-
- (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
+ long v;
/* Request function key for debug dumps */
fkeys = sfkeys = 0; bit_set(sfkeys, 8);
if ((fkey_map(&fkeys, &sfkeys)) != OK)
printf("%s: couldn't program Shift+F8 key (%d)\n", DevName, errno);
-#ifdef ETH_IGN_PROTO
- {
- static u16_t eth_ign_proto = 0;
- long val;
- val = 0xFFFF;
- env_parse("ETH_IGN_PROTO", "x", 0, &val, 0x0000L, 0xFFFFL);
- eth_ign_proto = htons((u16_t) val);
- }
-#endif
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ de_instance = (int) v;
/* Announce we are up! */
netdriver_announce();
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
- int port;
- message m;
-
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
- for (port = 0; port < DE_PORT_NR; port += 1) {
- if (de_table[port].de_mode == DEM_ENABLED) {
- m.m_type = DL_STOP;
- m.DL_PORT = port;
- do_stop(&m);
- }
- }
+ if (de_state.de_mode == DEM_ENABLED)
+ dp_stop(&de_state);
+
+ exit(0);
}
/** dp.c **/
typedef void (*dp_getblock_t) (struct dpeth *, u16_t, int, void *);
#endif
-#define DE_PORT_NR 2 /* Number of devices supported */
#define SENDQ_NR 2 /* Size of the send queue */
#define IOVEC_NR 16 /* Number of IOVEC entries at a time */
0,
};
-PRIVATE const char *progname;
-PRIVATE e1000_t e1000_table[E1000_PORT_NR];
+PRIVATE int e1000_instance;
+PRIVATE e1000_t e1000_state;
_PROTOTYPE( PRIVATE void e1000_init, (message *mp) );
_PROTOTYPE( PRIVATE void e1000_init_pci, (void) );
_PROTOTYPE( PRIVATE void e1000_writev_s, (message *mp, int from_int) );
_PROTOTYPE( PRIVATE void e1000_readv_s, (message *mp, int from_int) );
_PROTOTYPE( PRIVATE void e1000_getstat_s, (message *mp) );
-_PROTOTYPE( PRIVATE void e1000_getname, (message *mp) );
_PROTOTYPE( PRIVATE void e1000_interrupt, (message *mp) );
_PROTOTYPE( PRIVATE int e1000_link_changed, (e1000_t *e) );
_PROTOTYPE( PRIVATE void e1000_stop, (void) );
-_PROTOTYPE( PRIVATE e1000_t * e1000_port, (int port) );
_PROTOTYPE( PRIVATE uint32_t e1000_reg_read, (e1000_t *e, uint32_t reg) );
_PROTOTYPE( PRIVATE void e1000_reg_write, (e1000_t *e, uint32_t reg,
uint32_t value) );
_PROTOTYPE( PRIVATE u16_t eeprom_ich, (void *e, int reg) );
_PROTOTYPE( PRIVATE int eeprom_ich_init, (e1000_t *e) );
_PROTOTYPE( PRIVATE int eeprom_ich_cycle, (const e1000_t *e, u32_t timeout) );
-_PROTOTYPE( PRIVATE void reply, (e1000_t *e, int err, int may_block) );
+_PROTOTYPE( PRIVATE void reply, (e1000_t *e) );
_PROTOTYPE( PRIVATE void mess_reply, (message *req, message *reply) );
/* SEF functions and variables. */
case DL_WRITEV_S: e1000_writev_s(&m, FALSE); break;
case DL_READV_S: e1000_readv_s(&m, FALSE); break;
case DL_CONF: e1000_init(&m); break;
- case DL_STOP: e1000_stop(); break;
case DL_GETSTAT_S: e1000_getstat_s(&m); break;
- case DL_GETNAME: e1000_getname(&m); break;
default:
panic("illegal message: %d", m.m_type);
}
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
{
/* Initialize the e1000 driver. */
+ long v;
int r;
- /* Verify command-line arguments. */
- if (env_argc < 1)
- {
- panic("no program name given in argc/argv");
- }
- else
- (progname = strrchr(env_argv[0],'/')) ? progname++
- : (progname = env_argv[0]);
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ e1000_instance = (int) v;
/* Clear state. */
- memset(e1000_table, 0, sizeof(e1000_table));
+ memset(&e1000_state, 0, sizeof(e1000_state));
/* Perform calibration. */
if((r = tsc_calibrate()) != OK)
first_time = 0;
e1000_init_pci();
}
- /* Retrieve e1000 pointer. */
- e = e1000_port(mp->DL_PORT);
- e->client = mp->DL_PROC;
+ e = &e1000_state;
/* Initialize hardware, if needed. */
if (!(e->status & E1000_ENABLED) && !(e1000_init_hw(e)))
{
- reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = ENXIO;
+ reply_mess.m_type = DL_CONF_REPLY;
+ reply_mess.DL_STAT = ENXIO;
mess_reply(mp, &reply_mess);
return;
}
/* Reply back to INET. */
- reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = mp->DL_PORT;
- reply_mess.m3_i2 = E1000_PORT_NR;
- *(ether_addr_t *) reply_mess.m3_ca1 = e->address;
+ reply_mess.m_type = DL_CONF_REPLY;
+ reply_mess.DL_STAT = OK;
+ *(ether_addr_t *) reply_mess.DL_HWADDR = e->address;
mess_reply(mp, &reply_mess);
}
PRIVATE void e1000_init_pci()
{
e1000_t *e;
- int i;
/* Initialize the PCI bus. */
pci_init();
/* Try to detect e1000's. */
- for (i = 0, e = &e1000_table[i]; i < E1000_PORT_NR; i++, e++)
- {
- strcpy(e->name, "e1000#0");
- e->name[6] += i;
- e1000_probe(e, i);
- }
+ e = &e1000_state;
+ strcpy(e->name, "e1000#0");
+ e->name[6] += e1000_instance;
+ e1000_probe(e, e1000_instance);
}
/*===========================================================================*
* Output debug information.
*/
status[0] = e1000_reg_read(e, E1000_REG_STATUS);
- E1000_DEBUG(3, ("%s: MEM at 0x%lx, IRQ %d\n",
+ E1000_DEBUG(3, ("%s: MEM at %p, IRQ %d\n",
e->name, e->regs, e->irq));
E1000_DEBUG(3, ("%s: link %s, %s duplex\n",
e->name, status[0] & 3 ? "up" : "down",
/*
* Do we have a user defined ethernet address?
*/
- eakey[sizeof(E1000_ENVVAR)-1] = '0' + (e-e1000_table);
+ eakey[sizeof(E1000_ENVVAR)-1] = '0' + e1000_instance;
for (i= 0; i < 6; i++)
{
/*
* If that fails, read Ethernet Address from EEPROM.
*/
- if ((i != 0 && i != 6) || i == 0)
+ if (i != 6)
{
for (i = 0; i < 3; i++)
{
message *mp;
int from_int;
{
- e1000_t *e = e1000_port(mp->DL_PORT);
+ e1000_t *e = &e1000_state;
e1000_tx_desc_t *desc;
iovec_s_t iovec[E1000_IOVEC_NR];
int r, head, tail, i, bytes = 0, size;
- E1000_DEBUG(3, ("e1000: writev_s(%x,%d)\n", mp, from_int));
+ E1000_DEBUG(3, ("e1000: writev_s(%p,%d)\n", mp, from_int));
/* Are we called from the interrupt handler? */
if (!from_int)
/* Copy write message. */
e->tx_message = *mp;
+ e->client = mp->m_source;
e->status |= E1000_WRITING;
/* Must be a sane vector count. */
/*
* Copy the I/O vector table.
*/
- if ((r = sys_safecopyfrom(e->client, e->tx_message.DL_GRANT, 0,
+ if ((r = sys_safecopyfrom(e->tx_message.DL_ENDPT,
+ e->tx_message.DL_GRANT, 0,
(vir_bytes) iovec, e->tx_message.DL_COUNT *
sizeof(iovec_s_t), D)) != OK)
{
E1000_DEBUG(4, ("iovec[%d] = %d\n", i, size));
/* Copy bytes to TX queue buffers. */
- if ((r = sys_safecopyfrom(e->client, iovec[i].iov_grant, 0,
+ if ((r = sys_safecopyfrom(e->tx_message.DL_ENDPT,
+ iovec[i].iov_grant, 0,
(vir_bytes) e->tx_buffer +
(tail * E1000_IOBUF_SIZE),
size, D)) != OK)
{
e->status |= E1000_TRANSMIT;
}
- reply(e, OK, FALSE);
+ reply(e);
}
/*===========================================================================*
message *mp;
int from_int;
{
- e1000_t *e = e1000_port(mp->DL_PORT);
+ e1000_t *e = &e1000_state;
e1000_rx_desc_t *desc;
iovec_s_t iovec[E1000_IOVEC_NR];
int i, r, head, tail, cur, bytes = 0, size;
- E1000_DEBUG(3, ("e1000: readv_s(%x,%d)\n", mp, from_int));
+ E1000_DEBUG(3, ("e1000: readv_s(%p,%d)\n", mp, from_int));
/* Are we called from the interrupt handler? */
if (!from_int)
{
e->rx_message = *mp;
+ e->client = mp->m_source;
e->status |= E1000_READING;
e->rx_size = 0;
/*
* Copy the I/O vector table first.
*/
- if ((r = sys_safecopyfrom(e->client, e->rx_message.DL_GRANT, 0,
+ if ((r = sys_safecopyfrom(e->rx_message.DL_ENDPT,
+ e->rx_message.DL_GRANT, 0,
(vir_bytes) iovec, e->rx_message.DL_COUNT *
sizeof(iovec_s_t), D)) != OK)
{
*/
if (!(desc->status & E1000_RX_STATUS_EOP))
{
- reply(e, OK, FALSE);
+ reply(e);
return;
}
E1000_DEBUG(4, ("%s: head=%x, tail=%d\n",
size = iovec[i].iov_size < (desc->length - bytes) ?
iovec[i].iov_size : (desc->length - bytes);
- E1000_DEBUG(4, ("iovec[%d] = %d[%d]\n",
+ E1000_DEBUG(4, ("iovec[%d] = %lu[%d]\n",
i, iovec[i].iov_size, size));
- if ((r = sys_safecopyto(e->client, iovec[i].iov_grant, 0,
- (vir_bytes) e->rx_buffer + bytes +
+ if ((r = sys_safecopyto(e->rx_message.DL_ENDPT, iovec[i].iov_grant,
+ 0, (vir_bytes) e->rx_buffer + bytes +
(cur * E1000_IOBUF_SIZE),
size, D)) != OK)
{
/* Increment tail. */
e1000_reg_write(e, E1000_REG_RDT, (tail + 1) % e->rx_desc_count);
}
- reply(e, OK, FALSE);
+ reply(e);
}
/*===========================================================================*
{
int r;
eth_stat_t stats;
- e1000_t *e = e1000_port(mp->DL_PORT);
+ e1000_t *e = &e1000_state;
E1000_DEBUG(3, ("e1000: getstat_s()\n"));
stats.ets_CDheartbeat = 0;
stats.ets_OWC = 0;
- sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, (vir_bytes)&stats,
+ sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes)&stats,
sizeof(stats), D);
mp->m_type = DL_STAT_REPLY;
- mp->DL_PORT = mp->DL_PORT;
- mp->DL_STAT = OK;
if((r=send(mp->m_source, mp)) != OK)
panic("e1000_getstat: send() failed: %d", r);
}
-/*===========================================================================*
- * e1000_getname *
- *===========================================================================*/
-PRIVATE void e1000_getname(mp)
-message *mp;
-{
- int r;
-
- E1000_DEBUG(3, ("e1000: getname()\n"));
-
- /* Copy our program name. */
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[ sizeof(mp->DL_NAME) - 1 ] = 0;
-
- /* Acknowledge the name request. */
- mp->m_type = DL_NAME_REPLY;
- if ((r = send(mp->m_source, mp)) != OK)
- {
- panic("e1000_getname: send() failed: %d", r);
- }
-}
-
/*===========================================================================*
* e1000_interrupt *
*===========================================================================*/
{
e1000_t *e;
u32_t cause;
- unsigned int i;
E1000_DEBUG(3, ("e1000: interrupt\n"));
/*
- * Loop all cards. Check for interrupt reason(s).
+ * Check the card for interrupt reason(s).
*/
- for (i = 0; i < E1000_PORT_NR; i++)
- {
- e = e1000_port(i);
+ e = &e1000_state;
- /* Re-enable interrupts. */
- if (sys_irqenable(&e->irq_hook) != OK)
- {
- panic("failed to re-enable IRQ");
- }
+ /* Re-enable interrupts. */
+ if (sys_irqenable(&e->irq_hook) != OK)
+ {
+ panic("failed to re-enable IRQ");
+ }
- /* Read the Interrupt Cause Read register. */
- if ((cause = e1000_reg_read(e, E1000_REG_ICR)))
- {
- if (cause & E1000_REG_ICR_LSC)
- e1000_link_changed(e);
+ /* Read the Interrupt Cause Read register. */
+ if ((cause = e1000_reg_read(e, E1000_REG_ICR)))
+ {
+ if (cause & E1000_REG_ICR_LSC)
+ e1000_link_changed(e);
- if (cause & (E1000_REG_ICR_RXO | E1000_REG_ICR_RXT))
- e1000_readv_s(&e->rx_message, TRUE);
+ if (cause & (E1000_REG_ICR_RXO | E1000_REG_ICR_RXT))
+ e1000_readv_s(&e->rx_message, TRUE);
- if ((cause & E1000_REG_ICR_TXQE) ||
- (cause & E1000_REG_ICR_TXDW))
- e1000_writev_s(&e->tx_message, TRUE);
-
- }
+ if ((cause & E1000_REG_ICR_TXQE) ||
+ (cause & E1000_REG_ICR_TXDW))
+ e1000_writev_s(&e->tx_message, TRUE);
}
}
exit(EXIT_SUCCESS);
}
-/*===========================================================================*
- * e1000_port *
- *===========================================================================*/
-PRIVATE e1000_t * e1000_port(num)
-int num;
-{
- /*
- * Is the given port number within the allowed range?
- */
- if (num < 0 || num >= E1000_PORT_NR)
- {
- panic("invalid port number given: %d", num);
- }
-
- /*
- * The card must be active.
- */
- if (!(e1000_table[num].status & E1000_DETECTED))
- {
- panic("inactive port number given: %d", num);
- }
- return &e1000_table[num];
-}
-
-
/*===========================================================================*
* e1000_reg_read *
*===========================================================================*/
int ret_val = -1;
u8_t count = 0;
e1000_t *e = (e1000_t *) v;
- u16_t data;
+ u16_t data = 0;
E1000_DEBUG(3, ("e1000_read_flash_data_ich8lan"));
/*===========================================================================*
* reply *
*===========================================================================*/
-PRIVATE void reply(e, err, may_block)
+PRIVATE void reply(e)
e1000_t *e;
-int err;
-int may_block;
{
message msg;
int r;
}
/* Construct reply message. */
msg.m_type = DL_TASK_REPLY;
- msg.DL_PORT = e - e1000_table;
- msg.DL_PROC = e->client;
+ msg.DL_FLAGS = DL_NOFLAGS;
msg.DL_COUNT = 0;
- msg.DL_STAT = 0;
- msg.DL_CLCK = 0;
/* Did we successfully receive packet(s)? */
if (e->status & E1000_READING &&
e->status & E1000_RECEIVED)
{
- msg.DL_STAT = DL_PACK_RECV;
+ msg.DL_FLAGS |= DL_PACK_RECV;
msg.DL_COUNT = e->rx_size >= ETH_MIN_PACK_SIZE ?
e->rx_size : ETH_MIN_PACK_SIZE;
if (e->status & E1000_TRANSMIT &&
e->status & E1000_WRITING)
{
- msg.DL_STAT = DL_PACK_SEND;
- msg.DL_COUNT = 0;
+ msg.DL_FLAGS |= DL_PACK_SEND;
/* Clear flags. */
e->status &= ~(E1000_WRITING | E1000_TRANSMIT);
* @{
*/
-/** Maximum number of cards supported. */
-#define E1000_PORT_NR 1
-
/** Number of receive descriptors per card. */
#define E1000_RXDESC_NR 256
* This file contains an ethernet device driver for Intel 82557, 82558,
* 82559, 82550, and 82562 fast ethernet controllers.
*
- * The valid messages and their parameters are:
- *
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
- * |------------+----------+---------+----------+---------+---------+---------|
- * | HARDINT | | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITE | port nr | proc nr | count | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV | port nr | proc nr | count | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READ | port nr | proc nr | count | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV | port nr | proc nr | count | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV_S | port nr | proc nr | count | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_CONF | port nr | proc nr | | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_GETSTAT | port nr | proc nr | | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_STOP | port_nr | | | | | |
- * |------------+----------+---------+----------+---------+---------+---------|
- *
- * The messages sent are:
- *
- * m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
- * |-------------+----------+---------+----------+---------+---------|
- * |DL_TASK_REPLY| port nr | proc nr | rd-count | err|stat| clock |
- * |-------------+----------+---------+----------+---------+---------|
- *
- * m_type m3_i1 m3_i2 m3_ca1
- * |-------------+---------+-----------+---------------|
- * |DL_CONF_REPLY| port nr | last port | ethernet addr |
- * |-------------+---------+-----------+---------------|
- *
- * m_type DL_PORT DL_STAT
- * |------------|---------|-----------|
- * |DL_STAT_REPL| port nr | err |
- * |------------|---------|-----------|
- *
- *
* Created: Nov 2004 by Philip Homburg <philip@f-mnx.phicoh.com>
*/
{ 0x0000, 0x0000, 0 }
};
-#define FXP_PORT_NR 1 /* Minix */
-
typedef int irq_hook_t;
static timer_t *fxp_timers= NULL;
#define FT_82559 0x4
#define FT_82801 0x8
-PRIVATE fxp_t *fxp_table;
-PRIVATE phys_bytes fxp_table_phys;
+PRIVATE int fxp_instance;
+
+PRIVATE fxp_t *fxp_state;
-PRIVATE u16_t eth_ign_proto;
PRIVATE tmra_ut fxp_watchdog;
-PRIVATE const char *progname;
PRIVATE u32_t system_hz;
_PROTOTYPE( static void fxp_reset_hw, (fxp_t *fp) );
_PROTOTYPE( static void fxp_confaddr, (fxp_t *fp) );
_PROTOTYPE( static void fxp_rec_mode, (fxp_t *fp) );
-_PROTOTYPE( static void fxp_writev, (message *mp, int from_int,
- int vectored) );
_PROTOTYPE( static void fxp_writev_s, (const message *mp, int from_int) );
-_PROTOTYPE( static void fxp_readv, (message *mp, int from_int,
- int vectored) );
_PROTOTYPE( static void fxp_readv_s, (message *mp, int from_int) );
_PROTOTYPE( static void fxp_do_conf, (fxp_t *fp) );
_PROTOTYPE( static void fxp_cu_ptr_cmd, (fxp_t *fp, int cmd,
_PROTOTYPE( static void fxp_ru_ptr_cmd, (fxp_t *fp, int cmd,
phys_bytes bus_addr, int check_idle) );
_PROTOTYPE( static void fxp_restart_ru, (fxp_t *fp) );
-_PROTOTYPE( static void fxp_getstat, (message *mp) );
_PROTOTYPE( static void fxp_getstat_s, (message *mp) );
-_PROTOTYPE( static void fxp_getname, (message *mp) );
_PROTOTYPE( static void fxp_handler, (fxp_t *fp) );
_PROTOTYPE( static void fxp_check_ints, (fxp_t *fp) );
_PROTOTYPE( static void fxp_watchdog_f, (timer_t *tp) );
_PROTOTYPE( static int fxp_link_changed, (fxp_t *fp) );
_PROTOTYPE( static void fxp_report_link, (fxp_t *fp) );
-_PROTOTYPE( static void reply, (fxp_t *fp, int err, int may_block) );
+_PROTOTYPE( static void reply, (fxp_t *fp) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
_PROTOTYPE( static u16_t eeprom_read, (fxp_t *fp, int reg) );
_PROTOTYPE( static void eeprom_addrsize, (fxp_t *fp) );
PRIVATE void handle_hw_intr(void)
{
- int i, r;
+ int r;
fxp_t *fp;
- for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++) {
- if (fp->fxp_mode != FM_ENABLED)
- return;
- fxp_handler(fp);
+ fp= fxp_state;
- r= sys_irqenable(&fp->fxp_hook);
- if (r != OK) {
- panic("unable enable interrupts: %d", r);
- }
+ if (fp->fxp_mode != FM_ENABLED)
+ return;
+ fxp_handler(fp);
- if (!fp->fxp_got_int)
- return;
- fp->fxp_got_int= 0;
- assert(fp->fxp_flags & FF_ENABLED);
- fxp_check_ints(fp);
+ r= sys_irqenable(&fp->fxp_hook);
+ if (r != OK) {
+ panic("unable enable interrupts: %d", r);
}
+
+ if (!fp->fxp_got_int)
+ return;
+ fp->fxp_got_int= 0;
+ assert(fp->fxp_flags & FF_ENABLED);
+ fxp_check_ints(fp);
}
/* SEF functions and variables. */
switch (m.m_type)
{
- case DL_WRITEV: fxp_writev(&m, FALSE, TRUE); break;
- case DL_WRITE: fxp_writev(&m, FALSE, FALSE); break;
case DL_WRITEV_S: fxp_writev_s(&m, FALSE); break;
- case DL_READ: fxp_readv(&m, FALSE, FALSE); break;
- case DL_READV: fxp_readv(&m, FALSE, TRUE); break;
case DL_READV_S: fxp_readv_s(&m, FALSE); break;
case DL_CONF: fxp_init(&m); break;
- case DL_GETSTAT: fxp_getstat(&m); break;
case DL_GETSTAT_S: fxp_getstat_s(&m); break;
- case DL_GETNAME: fxp_getname(&m); break;
default:
panic(" illegal message: %d", m.m_type);
}
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
{
/* Initialize the fxp driver. */
- int r;
long v;
+ int r;
vir_bytes ft;
- ft = sizeof(*fxp_table)*FXP_PORT_NR;
system_hz = sys_hz();
- if (env_argc < 1)
- panic("A head which at this time has no name");
- (progname=strrchr(env_argv[0],'/')) ? progname++
- : (progname=env_argv[0]);
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ fxp_instance = (int) v;
- v= 0;
-#if 0
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
-#endif
- eth_ign_proto= htons((u16_t) v);
+ ft = sizeof(*fxp_state);
- if(!(fxp_table = alloc_contig(ft, 0, &fxp_table_phys)))
+ if(!(fxp_state = alloc_contig(ft, 0, NULL)))
panic("couldn't allocate table: %d", ENOMEM);
- memset(fxp_table, 0, ft);
+ memset(fxp_state, 0, ft);
if((r=tsc_calibrate()) != OK)
panic("tsc_calibrate failed: %d", r);
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
- int i;
port_t port;
fxp_t *fp;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
- for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)
- {
- if (fp->fxp_mode != FM_ENABLED)
- continue;
- if (!(fp->fxp_flags & FF_ENABLED))
- continue;
+ fp= fxp_state;
+
+ if (fp->fxp_mode == FM_ENABLED && (fp->fxp_flags & FF_ENABLED)) {
port= fp->fxp_base_port;
/* Reset device */
printf("%s: resetting device\n", fp->fxp_name);
fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);
}
+
exit(0);
}
{
static int first_time= 1;
- int port;
fxp_t *fp;
message reply_mess;
fxp_set_timer(&fxp_watchdog, system_hz, fxp_watchdog_f);
}
- port = mp->DL_PORT;
- if (port < 0 || port >= FXP_PORT_NR)
- {
- reply_mess.m_type= DL_CONF_REPLY;
- reply_mess.m3_i1= ENXIO;
- mess_reply(mp, &reply_mess);
- return;
- }
- fp= &fxp_table[port];
+ fp= fxp_state;
if (fp->fxp_mode == FM_DISABLED)
{
/* This is the default, try to (re)locate the device. */
{
/* Probe failed, or the device is configured off. */
reply_mess.m_type= DL_CONF_REPLY;
- reply_mess.m3_i1= ENXIO;
+ reply_mess.DL_STAT= ENXIO;
mess_reply(mp, &reply_mess);
return;
}
if (mp->DL_MODE & DL_BROAD_REQ)
fp->fxp_flags |= FF_BROAD;
- fp->fxp_client = mp->m_source;
fxp_rec_mode(fp);
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = mp->DL_PORT;
- reply_mess.m3_i2 = FXP_PORT_NR;
- *(ether_addr_t *) reply_mess.m3_ca1 = fp->fxp_address;
+ reply_mess.DL_STAT = OK;
+ *(ether_addr_t *) reply_mess.DL_HWADDR = fp->fxp_address;
mess_reply(mp, &reply_mess);
}
static char envvar[] = FXP_ENVVAR "#";
static char envfmt[] = "*:d.d.d";
- int i, h;
fxp_t *fp;
long v;
- for (i= 0, fp= fxp_table; i<FXP_PORT_NR; i++, fp++)
- {
- strcpy(fp->fxp_name, "fxp#0");
- fp->fxp_name[4] += i;
- fp->fxp_seen= FALSE;
- fp->fxp_features= FFE_NONE;
- envvar[sizeof(FXP_ENVVAR)-1]= '0'+i;
+ fp= fxp_state;
+
+ strcpy(fp->fxp_name, "fxp#0");
+ fp->fxp_name[4] += fxp_instance;
+ fp->fxp_seen= FALSE;
+ fp->fxp_features= FFE_NONE;
+ envvar[sizeof(FXP_ENVVAR)-1]= '0'+fxp_instance;
#if 0
- if (getenv(envvar) != NULL)
+ if (getenv(envvar) != NULL)
+ {
+ if (strcmp(getenv(envvar), "off") == 0)
{
- if (strcmp(getenv(envvar), "off") == 0)
- {
- fp->fxp_pcibus= 255;
- continue;
- }
- if (!env_prefix(envvar, "pci"))
- env_panic(envvar);
+ fp->fxp_pcibus= 255;
}
+ if (!env_prefix(envvar, "pci"))
+ env_panic(envvar);
+ }
#endif
- v= 0;
+ pci_init();
+
+ if (fp->fxp_pcibus == 255)
+ return;
+
+ v= 0;
#if 0
- (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
+ (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
#endif
- fp->fxp_pcibus= v;
- v= 0;
+ fp->fxp_pcibus= v;
+ v= 0;
#if 0
- (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
+ (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
#endif
- fp->fxp_pcidev= v;
- v= 0;
+ fp->fxp_pcidev= v;
+ v= 0;
#if 0
- (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
+ (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
#endif
- fp->fxp_pcifunc= v;
- }
-
- pci_init();
+ fp->fxp_pcifunc= v;
- for (h= 1; h >= 0; h--) {
- for (i= 0, fp= fxp_table; i<FXP_PORT_NR; i++, fp++)
- {
- if (fp->fxp_pcibus == 255)
- continue;
- if (((fp->fxp_pcibus | fp->fxp_pcidev |
- fp->fxp_pcifunc) != 0) != h)
- {
- continue;
- }
- if (fxp_probe(fp, i))
- fp->fxp_seen= TRUE;
- }
- }
+ if (fxp_probe(fp, fxp_instance))
+ fp->fxp_seen= TRUE;
}
/*===========================================================================*
long v;
/* User defined ethernet address? */
- eakey[sizeof(FXP_ENVVAR)-1]= '0' + (fp-fxp_table);
+ eakey[sizeof(FXP_ENVVAR)-1]= '0' + fxp_instance;
for (i= 0; i < 6; i++)
{
}
}
-/*===========================================================================*
- * fxp_writev *
- *===========================================================================*/
-static void fxp_writev(mp, from_int, vectored)
-message *mp;
-int from_int;
-int vectored;
-{
- vir_bytes iov_src;
- int i, j, n, o, r, s, dl_port, count, size, prev_head;
- int fxp_client, fxp_tx_nbuf, fxp_tx_head;
- u16_t tx_command;
- fxp_t *fp;
- iovec_t *iovp;
- struct tx *txp, *prev_txp;
-
- dl_port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= FXP_PORT_NR)
- panic("fxp_writev: illegal port: %d", dl_port);
- fp= &fxp_table[dl_port];
- fxp_client= mp->DL_PROC;
- fp->fxp_client= fxp_client;
-
- assert(fp->fxp_mode == FM_ENABLED);
- assert(fp->fxp_flags & FF_ENABLED);
-
- if (from_int)
- {
- assert(fp->fxp_flags & FF_SEND_AVAIL);
- fp->fxp_flags &= ~FF_SEND_AVAIL;
- fp->fxp_tx_alive= TRUE;
- }
-
- if (fp->fxp_tx_idle)
- {
- txp= fp->fxp_tx_buf;
- fxp_tx_head= 0; /* lint */
- prev_txp= NULL; /* lint */
- }
- else
- {
- fxp_tx_nbuf= fp->fxp_tx_nbuf;
- prev_head= fp->fxp_tx_head;
- fxp_tx_head= prev_head+1;
- if (fxp_tx_head == fxp_tx_nbuf)
- fxp_tx_head= 0;
- assert(fxp_tx_head < fxp_tx_nbuf);
-
- if (fxp_tx_head == fp->fxp_tx_tail)
- {
- /* Send queue is full */
- assert(!(fp->fxp_flags & FF_SEND_AVAIL));
- fp->fxp_flags |= FF_SEND_AVAIL;
- goto suspend;
- }
-
- prev_txp= &fp->fxp_tx_buf[prev_head];
- txp= &fp->fxp_tx_buf[fxp_tx_head];
- }
-
- assert(!(fp->fxp_flags & FF_SEND_AVAIL));
- assert(!(fp->fxp_flags & FF_PACK_SENT));
-
- if (vectored)
- {
-
- iov_src = (vir_bytes)mp->DL_ADDR;
-
- size= 0;
- o= 0;
- for (i= 0; i<count; i += IOVEC_NR,
- iov_src += IOVEC_NR * sizeof(fp->fxp_iovec[0]))
- {
- n= IOVEC_NR;
- if (i+n > count)
- n= count-i;
- r= sys_vircopy(fxp_client, D, iov_src,
- SELF, D, (vir_bytes)fp->fxp_iovec,
- n * sizeof(fp->fxp_iovec[0]));
- if (r != OK)
- panic("fxp_writev: sys_vircopy failed: %d", r);
-
- for (j= 0, iovp= fp->fxp_iovec; j<n; j++, iovp++)
- {
- s= iovp->iov_size;
- if (size + s > ETH_MAX_PACK_SIZE_TAGGED) {
- panic("fxp_writev: invalid packet size");
- }
-
- r= sys_vircopy(fxp_client, D, iovp->iov_addr,
- SELF, D, (vir_bytes)(txp->tx_buf+o),
- s);
- if (r != OK) {
- panic("fxp_writev: sys_vircopy failed: %d", r);
- }
- size += s;
- o += s;
- }
- }
- if (size < ETH_MIN_PACK_SIZE)
- panic("fxp_writev: invalid packet size: %d", size);
- }
- else
- {
- size= mp->DL_COUNT;
- if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
- panic("fxp_writev: invalid packet size: %d", size);
-
- r= sys_vircopy(fxp_client, D, (vir_bytes)mp->DL_ADDR,
- SELF, D, (vir_bytes)txp->tx_buf, size);
- if (r != OK)
- panic("fxp_writev: sys_vircopy failed: %d", r);
- }
-
- txp->tx_status= 0;
- txp->tx_command= TXC_EL | CBL_XMIT;
- txp->tx_tbda= TX_TBDA_NIL;
- txp->tx_size= TXSZ_EOF | size;
- txp->tx_tthresh= fp->fxp_tx_threshold;
- txp->tx_ntbd= 0;
- if (fp->fxp_tx_idle)
- {
- fp->fxp_tx_idle= 0;
- fp->fxp_tx_head= fp->fxp_tx_tail= 0;
-
- fxp_cu_ptr_cmd(fp, SC_CU_START, fp->fxp_tx_busaddr,
- TRUE /* check idle */);
- }
- else
- {
- /* Link new request in transmit list */
- tx_command= prev_txp->tx_command;
- assert(tx_command == (TXC_EL | CBL_XMIT));
- prev_txp->tx_command= CBL_XMIT;
- fp->fxp_tx_head= fxp_tx_head;
- }
-
- fp->fxp_flags |= FF_PACK_SENT;
-
- /* If the interrupt handler called, don't send a reply. The reply
- * will be sent after all interrupts are handled.
- */
- if (from_int)
- return;
- reply(fp, OK, FALSE);
- return;
-
-suspend:
- if (from_int)
- panic("fxp: should not be sending");
-
- fp->fxp_tx_mess= *mp;
- reply(fp, OK, FALSE);
-}
-
/*===========================================================================*
* fxp_writev_s *
*===========================================================================*/
static void fxp_writev_s(const message *mp, int from_int)
{
+ endpoint_t iov_endpt;
cp_grant_id_t iov_grant;
vir_bytes iov_offset;
- int i, j, n, o, r, s, dl_port, count, size, prev_head;
- int fxp_client, fxp_tx_nbuf, fxp_tx_head;
+ int i, j, n, o, r, s, count, size, prev_head;
+ int fxp_tx_nbuf, fxp_tx_head;
u16_t tx_command;
fxp_t *fp;
iovec_s_t *iovp;
struct tx *txp, *prev_txp;
- dl_port = mp->DL_PORT;
+ fp= fxp_state;
+
count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= FXP_PORT_NR)
- panic("fxp_writev: illegal port: %d", dl_port);
- fp= &fxp_table[dl_port];
- fxp_client= mp->DL_PROC;
- fp->fxp_client= fxp_client;
+ fp->fxp_client= mp->m_source;
assert(fp->fxp_mode == FM_ENABLED);
assert(fp->fxp_flags & FF_ENABLED);
assert(!(fp->fxp_flags & FF_SEND_AVAIL));
assert(!(fp->fxp_flags & FF_PACK_SENT));
+ iov_endpt= mp->DL_ENDPT;
iov_grant= mp->DL_GRANT;
size= 0;
n= IOVEC_NR;
if (i+n > count)
n= count-i;
- r= sys_safecopyfrom(fxp_client, iov_grant, iov_offset,
+ r= sys_safecopyfrom(iov_endpt, iov_grant, iov_offset,
(vir_bytes)fp->fxp_iovec_s,
n * sizeof(fp->fxp_iovec_s[0]), D);
if (r != OK)
panic("fxp_writev: invalid packet size: %d", size + s);
}
- r= sys_safecopyfrom(fxp_client, iovp->iov_grant,
+ r= sys_safecopyfrom(iov_endpt, iovp->iov_grant,
0, (vir_bytes)(txp->tx_buf+o), s, D);
if (r != OK) {
panic("fxp_writev_s: sys_safecopyfrom failed: %d", r);
*/
if (from_int)
return;
- reply(fp, OK, FALSE);
+ reply(fp);
return;
suspend:
panic("fxp: should not be sending");
fp->fxp_tx_mess= *mp;
- reply(fp, OK, FALSE);
-}
-
-/*===========================================================================*
- * fxp_readv *
- *===========================================================================*/
-static void fxp_readv(mp, from_int, vectored)
-message *mp;
-int from_int;
-int vectored;
-{
- int i, j, n, o, r, s, dl_port, fxp_client, count, size,
- fxp_rx_head, fxp_rx_nbuf;
- port_t port;
- unsigned packlen;
- vir_bytes iov_src;
- u16_t rfd_status;
- u16_t rfd_res;
- u8_t scb_status;
- fxp_t *fp;
- iovec_t *iovp;
- struct rfd *rfdp, *prev_rfdp;
-
- dl_port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= FXP_PORT_NR)
- panic("fxp_readv: illegal port: %d", dl_port);
- fp= &fxp_table[dl_port];
- fxp_client= mp->DL_PROC;
- fp->fxp_client= fxp_client;
-
- assert(fp->fxp_mode == FM_ENABLED);
- assert(fp->fxp_flags & FF_ENABLED);
-
- port= fp->fxp_base_port;
-
- fxp_rx_head= fp->fxp_rx_head;
- rfdp= &fp->fxp_rx_buf[fxp_rx_head];
-
- rfd_status= rfdp->rfd_status;
- if (!(rfd_status & RFDS_C))
- {
- /* Receive buffer is empty, suspend */
- goto suspend;
- }
-
- if (!(rfd_status & RFDS_OK))
- {
- /* Not OK? What happened? */
- assert(0);
- }
- else
- {
- assert(!(rfd_status & (RFDS_CRCERR | RFDS_ALIGNERR |
- RFDS_OUTOFBUF | RFDS_DMAOVR | RFDS_TOOSHORT |
- RFDS_RXERR)));
- }
- rfd_res= rfdp->rfd_res;
- assert(rfd_res & RFDR_EOF);
- assert(rfd_res & RFDR_F);
-
- packlen= rfd_res & RFDSZ_SIZE;
-
- if (vectored)
- {
- iov_src = (vir_bytes)mp->DL_ADDR;
-
- size= 0;
- o= 0;
- for (i= 0; i<count; i += IOVEC_NR,
- iov_src += IOVEC_NR * sizeof(fp->fxp_iovec[0]))
- {
- n= IOVEC_NR;
- if (i+n > count)
- n= count-i;
- r= sys_vircopy(fxp_client, D, iov_src,
- SELF, D, (vir_bytes)fp->fxp_iovec,
- n * sizeof(fp->fxp_iovec[0]));
- if (r != OK)
- panic("fxp_readv: sys_vircopy failed: %d", r);
-
- for (j= 0, iovp= fp->fxp_iovec; j<n; j++, iovp++)
- {
- s= iovp->iov_size;
- if (size + s > packlen)
- {
- assert(packlen > size);
- s= packlen-size;
- }
-
- r= sys_vircopy(SELF, D,
- (vir_bytes)(rfdp->rfd_buf+o),
- fxp_client, D, iovp->iov_addr, s);
- if (r != OK) {
- panic("fxp_readv: sys_vircopy failed: %d", r);
- }
-
- size += s;
- if (size == packlen)
- break;
- o += s;
- }
- if (size == packlen)
- break;
- }
- if (size < packlen)
- {
- assert(0);
- }
- }
- else
- {
- assert(0);
- }
-
- fp->fxp_read_s= packlen;
- fp->fxp_flags= (fp->fxp_flags & ~FF_READING) | FF_PACK_RECV;
-
- /* Re-init the current buffer */
- rfdp->rfd_status= 0;
- rfdp->rfd_command= RFDC_EL;
- rfdp->rfd_reserved= 0;
- rfdp->rfd_res= 0;
- rfdp->rfd_size= sizeof(rfdp->rfd_buf);
-
- fxp_rx_nbuf= fp->fxp_rx_nbuf;
- if (fxp_rx_head == 0)
- {
- prev_rfdp= &fp->fxp_rx_buf[fxp_rx_nbuf-1];
- }
- else
- prev_rfdp= &rfdp[-1];
-
- assert(prev_rfdp->rfd_command & RFDC_EL);
- prev_rfdp->rfd_command &= ~RFDC_EL;
-
- fxp_rx_head++;
- if (fxp_rx_head == fxp_rx_nbuf)
- fxp_rx_head= 0;
- assert(fxp_rx_head < fxp_rx_nbuf);
- fp->fxp_rx_head= fxp_rx_head;
-
- if (!from_int)
- reply(fp, OK, FALSE);
-
- return;
-
-suspend:
- if (fp->fxp_rx_need_restart)
- {
- fp->fxp_rx_need_restart= 0;
-
- /* Check the status of the RU */
- scb_status= fxp_inb(port, SCB_STATUS);
- if ((scb_status & SS_RUS_MASK) != SS_RU_NORES)
- {
- /* Race condition? */
- printf("fxp_readv: restart race: 0x%x\n",
- scb_status);
- assert((scb_status & SS_RUS_MASK) == SS_RU_READY);
- }
- else
- {
- fxp_restart_ru(fp);
- }
- }
- if (from_int)
- {
- assert(fp->fxp_flags & FF_READING);
-
- /* No need to store any state */
- return;
- }
-
- fp->fxp_rx_mess= *mp;
- assert(!(fp->fxp_flags & FF_READING));
- fp->fxp_flags |= FF_READING;
-
- reply(fp, OK, FALSE);
+ reply(fp);
}
/*===========================================================================*
message *mp;
int from_int;
{
- int i, j, n, o, r, s, dl_port, fxp_client, count, size,
- fxp_rx_head, fxp_rx_nbuf;
+ int i, j, n, o, r, s, count, size, fxp_rx_head, fxp_rx_nbuf;
+ endpoint_t iov_endpt;
cp_grant_id_t iov_grant;
port_t port;
unsigned packlen;
iovec_s_t *iovp;
struct rfd *rfdp, *prev_rfdp;
- dl_port = mp->DL_PORT;
+ fp= fxp_state;
+
count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= FXP_PORT_NR)
- panic("fxp_readv: illegal port: %d", dl_port);
- fp= &fxp_table[dl_port];
- fxp_client= mp->DL_PROC;
- fp->fxp_client= fxp_client;
+ fp->fxp_client= mp->m_source;
assert(fp->fxp_mode == FM_ENABLED);
assert(fp->fxp_flags & FF_ENABLED);
packlen= rfd_res & RFDSZ_SIZE;
+ iov_endpt = mp->DL_ENDPT;
iov_grant = mp->DL_GRANT;
size= 0;
n= IOVEC_NR;
if (i+n > count)
n= count-i;
- r= sys_safecopyfrom(fxp_client, iov_grant, iov_offset,
+ r= sys_safecopyfrom(iov_endpt, iov_grant, iov_offset,
(vir_bytes)fp->fxp_iovec_s,
n * sizeof(fp->fxp_iovec_s[0]), D);
if (r != OK)
s= packlen-size;
}
- r= sys_safecopyto(fxp_client, iovp->iov_grant,
+ r= sys_safecopyto(iov_endpt, iovp->iov_grant,
0, (vir_bytes)(rfdp->rfd_buf+o), s, D);
if (r != OK)
{
fp->fxp_rx_head= fxp_rx_head;
if (!from_int)
- reply(fp, OK, FALSE);
+ reply(fp);
return;
assert(!(fp->fxp_flags & FF_READING));
fp->fxp_flags |= FF_READING;
- reply(fp, OK, FALSE);
+ reply(fp);
}
/*===========================================================================*
FALSE /* do not check idle */);
}
-/*===========================================================================*
- * fxp_getstat *
- *===========================================================================*/
-static void fxp_getstat(mp)
-message *mp;
-{
- clock_t t0,t1;
- int r, dl_port;
- fxp_t *fp;
- u32_t *p;
- eth_stat_t stats;
-
- dl_port = mp->DL_PORT;
- if (dl_port < 0 || dl_port >= FXP_PORT_NR)
- panic("fxp_getstat: illegal port: %d", dl_port);
- fp= &fxp_table[dl_port];
- fp->fxp_client= mp->DL_PROC;
-
- assert(fp->fxp_mode == FM_ENABLED);
- assert(fp->fxp_flags & FF_ENABLED);
-
- p= &fp->fxp_stat.sc_tx_fcp;
- *p= 0;
-
- /* The dump commmand doesn't take a pointer. Setting a pointer
- * doesn't hard though.
- */
- fxp_cu_ptr_cmd(fp, SC_CU_DUMP_SC, 0, FALSE /* do not check idle */);
-
- getuptime(&t0);
- do {
- /* Wait for CU command to complete */
- if (*p != 0)
- break;
- } while (getuptime(&t1)==OK && (t1-t0) < micros_to_ticks(1000));
-
- if (*p == 0)
- panic("fxp_getstat: CU command failed to complete");
- if (*p != SCM_DSC)
- panic("fxp_getstat: bad magic");
-
- stats.ets_recvErr=
- fp->fxp_stat.sc_rx_crc +
- fp->fxp_stat.sc_rx_align +
- fp->fxp_stat.sc_rx_resource +
- fp->fxp_stat.sc_rx_overrun +
- fp->fxp_stat.sc_rx_cd +
- fp->fxp_stat.sc_rx_short;
- stats.ets_sendErr=
- fp->fxp_stat.sc_tx_maxcol +
- fp->fxp_stat.sc_tx_latecol +
- fp->fxp_stat.sc_tx_crs;
- stats.ets_OVW= fp->fxp_stat.sc_rx_overrun;
- stats.ets_CRCerr= fp->fxp_stat.sc_rx_crc;
- stats.ets_frameAll= fp->fxp_stat.sc_rx_align;
- stats.ets_missedP= fp->fxp_stat.sc_rx_resource;
- stats.ets_packetR= fp->fxp_stat.sc_rx_good;
- stats.ets_packetT= fp->fxp_stat.sc_tx_good;
- stats.ets_transDef= fp->fxp_stat.sc_tx_defered;
- stats.ets_collision= fp->fxp_stat.sc_tx_totcol;
- stats.ets_transAb= fp->fxp_stat.sc_tx_maxcol;
- stats.ets_carrSense= fp->fxp_stat.sc_tx_crs;
- stats.ets_fifoUnder= fp->fxp_stat.sc_tx_underrun;
- stats.ets_fifoOver= fp->fxp_stat.sc_rx_overrun;
- stats.ets_CDheartbeat= 0;
- stats.ets_OWC= fp->fxp_stat.sc_tx_latecol;
-
- r= sys_vircopy(SELF, D, (vir_bytes)&stats,
- mp->DL_PROC, D, (vir_bytes) mp->DL_ADDR, sizeof(stats));
- if (r != OK)
- panic("fxp_getstat: sys_vircopy failed: %d", r);
-
- mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= dl_port;
- mp->DL_STAT= OK;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("fxp_getstat: send failed: %d", r);
-}
-
-
/*===========================================================================*
* fxp_getstat_s *
*===========================================================================*/
static void fxp_getstat_s(message *mp)
{
clock_t t0,t1;
- int r, dl_port;
+ int r;
fxp_t *fp;
u32_t *p;
eth_stat_t stats;
- dl_port = mp->DL_PORT;
- if (dl_port < 0 || dl_port >= FXP_PORT_NR)
- panic("fxp_getstat: illegal port: %d", dl_port);
- fp= &fxp_table[dl_port];
- fp->fxp_client= mp->DL_PROC;
+ fp= fxp_state;
assert(fp->fxp_mode == FM_ENABLED);
assert(fp->fxp_flags & FF_ENABLED);
stats.ets_CDheartbeat= 0;
stats.ets_OWC= fp->fxp_stat.sc_tx_latecol;
- r= sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, (vir_bytes)&stats,
+ r= sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes)&stats,
sizeof(stats), D);
if (r != OK)
panic("fxp_getstat_s: sys_safecopyto failed: %d", r);
mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= dl_port;
- mp->DL_STAT= OK;
r= send(mp->m_source, mp);
if (r != OK)
panic("fxp_getstat_s: send failed: %d", r);
}
-
-/*===========================================================================*
- * fxp_getname *
- *===========================================================================*/
-static void fxp_getname(message *mp)
-{
- int r;
-
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
- mp->m_type= DL_NAME_REPLY;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("fxp_getname: send failed: %d", r);
-}
-
/*===========================================================================*
* fxp_handler *
*===========================================================================*/
{
if (!(fp->fxp_rx_buf[fp->fxp_rx_head].rfd_status & RFDS_C))
; /* Nothing */
- else if (fp->fxp_rx_mess.m_type == DL_READV)
- {
- fxp_readv(&fp->fxp_rx_mess, TRUE /* from int */,
- TRUE /* vectored */);
- }
- else if (fp->fxp_rx_mess.m_type == DL_READV_S)
- {
- fxp_readv_s(&fp->fxp_rx_mess, TRUE /* from int */);
-
- }
else
{
- assert(fp->fxp_rx_mess.m_type == DL_READ);
- fxp_readv(&fp->fxp_rx_mess, TRUE /* from int */,
- FALSE /* !vectored */);
+ fxp_readv_s(&fp->fxp_rx_mess, TRUE /* from int */);
}
}
if (fp->fxp_tx_idle)
if (fp->fxp_flags & FF_SEND_AVAIL)
{
- if (fp->fxp_tx_mess.m_type == DL_WRITEV)
- {
- fxp_writev(&fp->fxp_tx_mess,
- TRUE /* from int */,
- TRUE /* vectored */);
- }
- else if (fp->fxp_tx_mess.m_type == DL_WRITEV_S)
- {
- fxp_writev_s(&fp->fxp_tx_mess,
- TRUE /* from int */);
- }
- else
- {
- assert(fp->fxp_tx_mess.m_type ==
- DL_WRITE);
- fxp_writev(&fp->fxp_tx_mess,
- TRUE /* from int */,
- FALSE /* !vectored */);
- }
+ fxp_writev_s(&fp->fxp_tx_mess,
+ TRUE /* from int */);
}
}
fxp_report_link(fp);
if (fp->fxp_flags & (FF_PACK_SENT | FF_PACK_RECV))
- reply(fp, OK, TRUE);
+ reply(fp);
}
/*===========================================================================*
static void fxp_watchdog_f(tp)
timer_t *tp;
{
- int i;
fxp_t *fp;
tmr_arg(&fxp_watchdog)->ta_int= 0;
fxp_set_timer(&fxp_watchdog, system_hz, fxp_watchdog_f);
- for (i= 0, fp = &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)
- {
- if (fp->fxp_mode != FM_ENABLED)
- continue;
+ fp= fxp_state;
+ if (fp->fxp_mode != FM_ENABLED)
+ return;
- /* Handle race condition, MII interface mgith be busy */
- if(!fp->fxp_mii_busy)
+ /* Handle race condition, MII interface might be busy */
+ if(!fp->fxp_mii_busy)
+ {
+ /* Check the link status. */
+ if (fxp_link_changed(fp))
{
- /* Check the link status. */
- if (fxp_link_changed(fp))
- {
#if VERBOSE
- printf("fxp_watchdog_f: link changed\n");
+ printf("fxp_watchdog_f: link changed\n");
#endif
- fp->fxp_report_link= TRUE;
- fp->fxp_got_int= TRUE;
- interrupt(fxp_tasknr);
- }
+ fp->fxp_report_link= TRUE;
+ fp->fxp_got_int= TRUE;
+ interrupt(fxp_tasknr);
}
+ }
- if (!(fp->fxp_flags & FF_SEND_AVAIL))
- {
- /* Assume that an idle system is alive */
- fp->fxp_tx_alive= TRUE;
- continue;
- }
- if (fp->fxp_tx_alive)
- {
- fp->fxp_tx_alive= FALSE;
- continue;
- }
-
- fp->fxp_need_reset= TRUE;
- fp->fxp_got_int= TRUE;
- interrupt(fxp_tasknr);
+ if (!(fp->fxp_flags & FF_SEND_AVAIL))
+ {
+ /* Assume that an idle system is alive */
+ fp->fxp_tx_alive= TRUE;
+ return;
+ }
+ if (fp->fxp_tx_alive)
+ {
+ fp->fxp_tx_alive= FALSE;
+ return;
}
+
+ fp->fxp_need_reset= TRUE;
+ fp->fxp_got_int= TRUE;
+ interrupt(fxp_tasknr);
}
/*===========================================================================*
fp->fxp_mii_scr= scr;
mii_ctrl= mii_read(fp, MII_CTRL);
- mii_read(fp, MII_STATUS); /* Read the status register twice, why? */
+ mii_read(fp, MII_STATUS); /* The status reg is latched, read twice */
mii_status= mii_read(fp, MII_STATUS);
mii_id1= mii_read(fp, MII_PHYID_H);
mii_id2= mii_read(fp, MII_PHYID_L);
/*===========================================================================*
* reply *
*===========================================================================*/
-static void reply(fp, err, may_block)
+static void reply(fp)
fxp_t *fp;
-int err;
-int may_block;
{
message reply;
- int status;
+ int flags;
int r;
- status = 0;
+ flags = DL_NOFLAGS;
if (fp->fxp_flags & FF_PACK_SENT)
- status |= DL_PACK_SEND;
+ flags |= DL_PACK_SEND;
if (fp->fxp_flags & FF_PACK_RECV)
- status |= DL_PACK_RECV;
+ flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY;
- reply.DL_PORT = fp - fxp_table;
- reply.DL_PROC = fp->fxp_client;
- reply.DL_STAT = status | ((u32_t) err << 16);
+ reply.DL_FLAGS = flags;
reply.DL_COUNT = fp->fxp_read_s;
-#if 0
- reply.DL_CLCK = get_uptime();
-#else
- reply.DL_CLCK = 0;
-#endif
r= send(fp->fxp_client, &reply);
- if (r == ELOCKED && may_block)
- {
-#if 0
- printW(); printf("send locked\n");
-#endif
- return;
- }
-
if (r < 0)
panic("fxp: send failed: %d", r);
*
* The valid messages and their parameters are:
*
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
- * |------------+----------+---------+----------+---------+---------+---------|
- * | HARDINT | | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV_S | port nr | proc nr | count | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_CONF | port nr | proc nr | | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_STOP | port_nr | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
+ * m_type DL_ENDPT DL_COUNT DL_MODE DL_GRANT
+ * |--------------+---------+----------+---------+---------|
+ * | DL_WRITEV_S | endpt | count | | grant |
+ * |--------------|---------|----------|---------|---------|
+ * | DL_READV_S | endpt | count | | grant |
+ * |--------------|---------|----------|---------|---------|
+ * | DL_CONF | | | mode | |
+ * |--------------|---------|----------|---------|---------|
+ * | DL_GETSTAT_S | endpt | | | grant |
+ * |--------------|---------|----------|---------|---------|
+ * | hardware int | | | | |
+ * |--------------|---------|----------|---------|---------|
*
* The messages sent are:
*
- * m-type DL_POR T DL_PROC DL_COUNT DL_STAT DL_CLCK
- * |------------|----------|---------|----------|---------|---------|
- * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock |
- * |------------|----------|---------|----------|---------|---------|
+ * m_type DL_COUNT DL_FLAGS
+ * |---------------+----------+---------|
+ * | DL_TASK_REPLY | rd-count | flags |
+ * |---------------|----------|---------|
*
- * m_type m3_i1 m3_i2 m3_ca1
- * |------------+---------+-----------+---------------|
- * |DL_CONF_REPL| port nr | last port | ethernet addr |
- * |------------|---------|-----------|---------------|
+ * m_type
+ * |---------------|
+ * | DL_STAT_REPLY |
+ * |---------------|
+ *
+ * m_type DL_STAT DL_ADDR
+ * |---------------+---------+---------------|
+ * | DL_CONF_REPLY | code | ethernet addr |
+ * |---------------|---------|---------------|
*
* Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp>
* Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl>
#include "lance.h"
-static ether_card_t ec_table[EC_PORT_NR_MAX];
-static int eth_tasknr= ANY;
-static u16_t eth_ign_proto;
+static ether_card_t ec_state;
+static int ec_instance;
/* Configuration */
typedef struct ec_conf
port_t ec_port;
int ec_irq;
phys_bytes ec_mem;
- char *ec_envvar;
} ec_conf_t;
/* We hardly use these. Just "LANCE0=on/off" "LANCE1=on/off" mean. */
-ec_conf_t ec_conf[]= /* Card addresses */
+#define EC_CONF_NR 3
+ec_conf_t ec_conf[EC_CONF_NR]= /* Card addresses */
{
- /* I/O port, IRQ, Buffer address, Env. var, Buf selector. */
- { 0x1000, 9, 0x00000, "LANCE0" },
- { 0xD000, 15, 0x00000, "LANCE1" },
+ /* I/O port, IRQ, Buffer address. */
+ { 0x1000, 9, 0x00000, },
+ { 0xD000, 15, 0x00000, },
+ { 0x0000, 0, 0x00000, },
};
/* Actually, we use PCI-BIOS info. */
_PROTOTYPE( static void update_conf, (ether_card_t *ec, ec_conf_t *ecp) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
_PROTOTYPE( static void do_int, (ether_card_t *ec) );
-_PROTOTYPE( static void reply,
- (ether_card_t *ec, int err, int may_block) );
+_PROTOTYPE( static void reply, (ether_card_t *ec) );
_PROTOTYPE( static void ec_reset, (ether_card_t *ec) );
_PROTOTYPE( static void ec_send, (ether_card_t *ec) );
_PROTOTYPE( static void ec_recv, (ether_card_t *ec) );
-_PROTOTYPE( static void do_vwrite_s,
- (message *mp, int from_int) );
-_PROTOTYPE( static void do_vread_s, (const message *mp) );
+_PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int) );
+_PROTOTYPE( static void do_vread_s, (const message *mp) );
_PROTOTYPE( static void ec_user2nic,
(ether_card_t *dep, iovec_dat_t *iovp,
vir_bytes offset, int nic_addr,
_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
_PROTOTYPE( static void ec_next_iovec, (iovec_dat_t *iovp) );
_PROTOTYPE( static void do_getstat_s, (message *mp) );
-_PROTOTYPE( static void do_stop, (message *mp) );
-_PROTOTYPE( static void do_getname, (message *mp) );
+_PROTOTYPE( static void lance_stop, (ether_card_t *ec) );
-_PROTOTYPE( static void lance_dump, (void) );
+_PROTOTYPE( static void lance_dump, (void) );
_PROTOTYPE( static void getAddressing, (int devind, ether_card_t *ec) );
/* probe+init LANCE cards */
/* --- LANCE --- */
/* General */
-#define Address unsigned long
+typedef unsigned long Address;
#define virt_to_bus(x) (vir2phys((unsigned long)x))
unsigned long vir2phys( unsigned long x )
};
/* =============== global variables =============== */
+/* AKA the stuff that really should have been in ether_card_t */
static struct lance_interface *lp;
#define LANCE_BUF_SIZE (sizeof(struct lance_interface))
static char *lance_buf = NULL;
static int tx_slot_nr = 0; /* Tx-slot number */
static int cur_tx_slot_nr = 0; /* Tx-slot number */
static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */
-static const char *progname;
phys_bytes lance_buf_phys;
/*===========================================================================*
* main *
*===========================================================================*/
-void main( int argc, char **argv )
+int main( int argc, char **argv )
{
message m;
int ipc_status;
- int i,r;
+ int r;
ether_card_t *ec;
/* SEF local startup. */
env_setargs(argc, argv);
sef_local_startup();
+ ec= &ec_state;
+
while (TRUE)
{
- for (i=0;i<EC_PORT_NR_MAX;++i)
- {
- ec= &ec_table[i];
- if (ec->ec_irq != 0)
- sys_irqenable(&ec->ec_hook);
- }
+ if (ec->ec_irq != 0)
+ sys_irqenable(&ec->ec_hook);
if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
panic("netdriver_receive failed: %d", r);
- for (i=0;i<EC_PORT_NR_MAX;++i)
- {
- ec= &ec_table[i];
- if (ec->ec_irq != 0)
- sys_irqdisable(&ec->ec_hook);
- }
+ if (ec->ec_irq != 0)
+ sys_irqdisable(&ec->ec_hook);
if (is_ipc_notify(ipc_status)) {
switch(_ENDPOINT_P(m.m_source)) {
lance_dump();
break;
case HARDWARE:
- for (i=0;i<EC_PORT_NR_MAX;++i)
+ if (ec->mode == EC_ENABLED)
{
- ec= &ec_table[i];
- if (ec->mode != EC_ENABLED)
- continue;
-
- {
- ec->ec_int_pending = 0;
- ec_check_ints(ec);
- do_int(ec);
- }
+ ec->ec_int_pending = 0;
+ ec_check_ints(ec);
+ do_int(ec);
}
break;
default:
case DL_GETSTAT_S:
do_getstat_s(&m);
break;
- case DL_STOP:
- do_stop(&m);
- break;
- case DL_GETNAME:
- do_getname(&m);
- break;
default:
panic("illegal message: %d", m.m_type);
}
}
+
+ return 0;
}
/*===========================================================================*
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the lance driver. */
- int r;
long v;
#if LANCE_FKEY
- int fkeys, sfkeys;
+ int r, fkeys, sfkeys;
#endif
- (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
-
#if LANCE_FKEY
fkeys = sfkeys = 0;
bit_set( sfkeys, 7 );
printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r);
#endif
- v= 0;
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- eth_ign_proto= htons((u16_t) v);
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ ec_instance = (int) v;
- /* Announce we are up! */
- netdriver_announce();
+ /* Announce we are up! */
+ netdriver_announce();
return OK;
}
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
- message mess;
- int i;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
- for (i= 0; i<EC_PORT_NR_MAX; i++)
- {
- if (ec_table[i].mode != EC_ENABLED)
- continue;
- mess.m_type= DL_STOP;
- mess.DL_PORT= i;
- do_stop(&mess);
- }
+ if (ec_state.mode == EC_ENABLED)
+ lance_stop(&ec_state);
#if VERBOSE
printf("LANCE driver stopped.\n");
static void lance_dump()
{
ether_card_t *ec;
- int i, isr, csr;
+ int isr, csr;
unsigned short ioaddr;
printf("\n");
- for (i= 0, ec = &ec_table[0]; i<EC_PORT_NR_MAX; i++, ec++)
- {
- if (ec->mode == EC_DISABLED)
- printf("lance port %d is disabled\n", i);
- else if (ec->mode == EC_SINK)
- printf("lance port %d is in sink mode\n", i);
-
- if (ec->mode != EC_ENABLED)
- continue;
+ ec = &ec_state;
+ if (ec->mode == EC_DISABLED)
+ printf("lance instance %d is disabled\n", ec_instance);
+ else if (ec->mode == EC_SINK)
+ printf("lance instance %d is in sink mode\n", ec_instance);
+
+ if (ec->mode != EC_ENABLED)
+ return;
- printf("lance statistics of port %d:\n", i);
+ printf("lance statistics of instance %d:\n", ec_instance);
- printf("recvErr :%8ld\t", ec->eth_stat.ets_recvErr);
- printf("sendErr :%8ld\t", ec->eth_stat.ets_sendErr);
- printf("OVW :%8ld\n", ec->eth_stat.ets_OVW);
+ printf("recvErr :%8ld\t", ec->eth_stat.ets_recvErr);
+ printf("sendErr :%8ld\t", ec->eth_stat.ets_sendErr);
+ printf("OVW :%8ld\n", ec->eth_stat.ets_OVW);
- printf("CRCerr :%8ld\t", ec->eth_stat.ets_CRCerr);
- printf("frameAll :%8ld\t", ec->eth_stat.ets_frameAll);
- printf("missedP :%8ld\n", ec->eth_stat.ets_missedP);
+ printf("CRCerr :%8ld\t", ec->eth_stat.ets_CRCerr);
+ printf("frameAll :%8ld\t", ec->eth_stat.ets_frameAll);
+ printf("missedP :%8ld\n", ec->eth_stat.ets_missedP);
- printf("packetR :%8ld\t", ec->eth_stat.ets_packetR);
- printf("packetT :%8ld\t", ec->eth_stat.ets_packetT);
- printf("transDef :%8ld\n", ec->eth_stat.ets_transDef);
+ printf("packetR :%8ld\t", ec->eth_stat.ets_packetR);
+ printf("packetT :%8ld\t", ec->eth_stat.ets_packetT);
+ printf("transDef :%8ld\n", ec->eth_stat.ets_transDef);
- printf("collision :%8ld\t", ec->eth_stat.ets_collision);
- printf("transAb :%8ld\t", ec->eth_stat.ets_transAb);
- printf("carrSense :%8ld\n", ec->eth_stat.ets_carrSense);
+ printf("collision :%8ld\t", ec->eth_stat.ets_collision);
+ printf("transAb :%8ld\t", ec->eth_stat.ets_transAb);
+ printf("carrSense :%8ld\n", ec->eth_stat.ets_carrSense);
- printf("fifoUnder :%8ld\t", ec->eth_stat.ets_fifoUnder);
- printf("fifoOver :%8ld\t", ec->eth_stat.ets_fifoOver);
- printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat);
+ printf("fifoUnder :%8ld\t", ec->eth_stat.ets_fifoUnder);
+ printf("fifoOver :%8ld\t", ec->eth_stat.ets_fifoOver);
+ printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat);
- printf("OWC :%8ld\t", ec->eth_stat.ets_OWC);
+ printf("OWC :%8ld\t", ec->eth_stat.ets_OWC);
- ioaddr = ec->ec_port;
- isr = read_csr(ioaddr, LANCE_CSR0);
- printf("isr = 0x%x, flags = 0x%x\n", isr,
+ ioaddr = ec->ec_port;
+ isr = read_csr(ioaddr, LANCE_CSR0);
+ printf("isr = 0x%x, flags = 0x%x\n", isr,
ec->flags);
- printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port);
-
- csr = read_csr(ioaddr, LANCE_CSR0);
- printf("CSR0: 0x%x\n", csr);
- csr = read_csr(ioaddr, LANCE_CSR3);
- printf("CSR3: 0x%x\n", csr);
- csr = read_csr(ioaddr, LANCE_CSR4);
- printf("CSR4: 0x%x\n", csr);
- csr = read_csr(ioaddr, LANCE_CSR5);
- printf("CSR5: 0x%x\n", csr);
- csr = read_csr(ioaddr, LANCE_CSR15);
- printf("CSR15: 0x%x\n", csr);
-
- }
+ printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port);
+
+ csr = read_csr(ioaddr, LANCE_CSR0);
+ printf("CSR0: 0x%x\n", csr);
+ csr = read_csr(ioaddr, LANCE_CSR3);
+ printf("CSR3: 0x%x\n", csr);
+ csr = read_csr(ioaddr, LANCE_CSR4);
+ printf("CSR4: 0x%x\n", csr);
+ csr = read_csr(ioaddr, LANCE_CSR5);
+ printf("CSR5: 0x%x\n", csr);
+ csr = read_csr(ioaddr, LANCE_CSR15);
+ printf("CSR15: 0x%x\n", csr);
}
/*===========================================================================*
static void do_init(mp)
message *mp;
{
- int port;
ether_card_t *ec;
message reply_mess;
panic("alloc_contig failed: %d", LANCE_BUF_SIZE);
}
- port = mp->DL_PORT;
- if (port < 0 || port >= EC_PORT_NR_MAX)
- {
- reply_mess.m_type= DL_CONF_REPLY;
- reply_mess.m3_i1= ENXIO;
- mess_reply(mp, &reply_mess);
- return;
- }
-
- ec= &ec_table[port];
- strcpy(ec->port_name, "eth_card#0");
- ec->port_name[9] += port;
+ ec= &ec_state;
+ strcpy(ec->port_name, "lance#0");
+ ec->port_name[6] += ec_instance;
if (ec->mode == EC_DISABLED)
{
{
/* Probe failed, or the device is configured off. */
reply_mess.m_type= DL_CONF_REPLY;
- reply_mess.m3_i1= ENXIO;
+ reply_mess.DL_STAT = ENXIO;
mess_reply(mp, &reply_mess);
return;
}
ec->mac_address.ea_addr[5] = 0;
ec_confaddr(ec);
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = mp->DL_PORT;
- reply_mess.m3_i2 = EC_PORT_NR_MAX;
- *(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address;
+ reply_mess.DL_STAT = OK;
+ *(ether_addr_t *) reply_mess.DL_HWADDR = ec->mac_address;
mess_reply(mp, &reply_mess);
return;
}
if (mp->DL_MODE & DL_BROAD_REQ)
ec->flags |= ECF_BROAD;
- ec->client = mp->m_source;
-
ec_reinit(ec);
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = mp->DL_PORT;
- reply_mess.m3_i2 = EC_PORT_NR_MAX;
- *(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address;
+ reply_mess.DL_STAT = OK;
+ *(ether_addr_t *) reply_mess.DL_HWADDR = ec->mac_address;
mess_reply(mp, &reply_mess);
}
ether_card_t *ec;
{
if (ec->flags & (ECF_PACK_SEND | ECF_PACK_RECV))
- reply(ec, OK, TRUE);
+ reply(ec);
}
{
static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
- int ifnr;
+ int confnr;
ec_conf_t *ecp;
ec->mode= EC_DISABLED; /* Superfluous */
- ifnr= ec-ec_table;
- ecp= &ec_conf[ifnr];
+ /* Pick a default configuration. This hardly matters anymore. */
+ confnr= MIN(ec_instance, EC_CONF_NR-1);
+
+ ecp= &ec_conf[confnr];
update_conf(ec, ecp);
if (ec->mode != EC_ENABLED)
return;
- if (!lance_probe(ec, ifnr))
+ if (!lance_probe(ec, ec_instance))
{
printf("%s: No ethernet card found on PCI-BIOS info.\n",
ec->port_name);
ec_conf_t *ecp;
{
long v;
+ char eckey[16];
static char ec_fmt[] = "x:d:x:x";
/* Get the default settings and modify them from the environment. */
+ strcpy(eckey, "LANCE0");
+ eckey[5] += ec_instance;
ec->mode= EC_SINK;
v= ecp->ec_port;
- switch (env_parse(ecp->ec_envvar, ec_fmt, 0, &v, 0x0000L, 0xFFFFL))
+ switch (env_parse(eckey, ec_fmt, 0, &v, 0x0000L, 0xFFFFL))
{
case EP_OFF:
ec->mode= EC_DISABLED;
ec->ec_port= v;
v= ecp->ec_irq | DEI_DEFAULT;
- (void) env_parse(ecp->ec_envvar, ec_fmt, 1, &v, 0L,
- (long) NR_IRQ_VECTORS - 1);
+ (void) env_parse(eckey, ec_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1);
ec->ec_irq= v;
v= ecp->ec_mem;
- (void) env_parse(ecp->ec_envvar, ec_fmt, 2, &v, 0L, 0xFFFFFL);
+ (void) env_parse(eckey, ec_fmt, 2, &v, 0L, 0xFFFFFL);
ec->ec_linmem= v;
v= 0;
- (void) env_parse(ecp->ec_envvar, ec_fmt, 3, &v, 0x2000L, 0x8000L);
+ (void) env_parse(eckey, ec_fmt, 3, &v, 0x2000L, 0x8000L);
ec->ec_ramsize= v;
}
/*===========================================================================*
* reply *
*===========================================================================*/
-static void reply(ec, err, may_block)
+static void reply(ec)
ether_card_t *ec;
-int err;
-int may_block;
{
message reply;
- int status,r;
- clock_t now;
+ int flags,r;
- status = 0;
+ flags = DL_NOFLAGS;
if (ec->flags & ECF_PACK_SEND)
- status |= DL_PACK_SEND;
+ flags |= DL_PACK_SEND;
if (ec->flags & ECF_PACK_RECV)
- status |= DL_PACK_RECV;
+ flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY;
- reply.DL_PORT = ec - ec_table;
- reply.DL_PROC = ec->client;
- reply.DL_STAT = status | ((u32_t) err << 16);
+ reply.DL_FLAGS = flags;
reply.DL_COUNT = ec->read_s;
- if ((r=getuptime(&now)) != OK)
- panic("getuptime() failed: %d", r);
- reply.DL_CLCK = now;
-
r = send(ec->client, &reply);
- if (r == ELOCKED && may_block)
- {
- return;
- }
if (r < 0)
panic("send failed: %d", r);
long v;
/* User defined ethernet address? */
- strcpy(eakey, ec_conf[ec-ec_table].ec_envvar);
- strcat(eakey, "_EA");
+ strcpy(eakey, "LANCE0_EA");
+ eakey[5] += ec_instance;
for (i = 0; i < 6; i++)
{
*===========================================================================*/
static void do_vread_s(const message *mp)
{
- int port, count, r;
+ int count, r;
ether_card_t *ec;
- port = mp->DL_PORT;
+ ec= &ec_state;
+
+ ec->client= mp->m_source;
count = mp->DL_COUNT;
- ec= &ec_table[port];
- ec->client= mp->DL_PROC;
- r = sys_safecopyfrom(mp->DL_PROC, mp->DL_GRANT, 0,
+ r = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, 0,
(vir_bytes)ec->read_iovec.iod_iovec,
(count > IOVEC_NR ? IOVEC_NR : count) *
sizeof(iovec_s_t), D);
if (r != OK)
panic("do_vread_s: sys_safecopyfrom failed: %d", r);
ec->read_iovec.iod_iovec_s = count;
- ec->read_iovec.iod_proc_nr = mp->DL_PROC;
+ ec->read_iovec.iod_proc_nr = mp->DL_ENDPT;
ec->read_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT;
ec->read_iovec.iod_iovec_offset = 0;
if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
ec_reset(ec);
- reply(ec, OK, FALSE);
+ reply(ec);
}
/*===========================================================================*
message *mp;
int from_int;
{
- int port, count, check, r;
+ int count, check, r;
ether_card_t *ec;
unsigned short ioaddr;
- port = mp->DL_PORT;
+ ec = &ec_state;
+
+ ec->client= mp->m_source;
count = mp->DL_COUNT;
- ec = &ec_table[port];
- ec->client= mp->DL_PROC;
if (isstored[tx_slot_nr]==1)
{
/* all slots are used, so this message is buffered */
ec->sendmsg= *mp;
ec->flags |= ECF_SEND_AVAIL;
- reply(ec, OK, FALSE);
+ reply(ec);
return;
}
/* convert the message to write_iovec */
- r = sys_safecopyfrom(mp->DL_PROC, mp->DL_GRANT, 0,
+ r = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, 0,
(vir_bytes)ec->write_iovec.iod_iovec,
(count > IOVEC_NR ? IOVEC_NR : count) *
sizeof(iovec_s_t), D);
if (r != OK)
panic("do_vwrite_s: sys_safecopyfrom failed: %d", r);
ec->write_iovec.iod_iovec_s = count;
- ec->write_iovec.iod_proc_nr = mp->DL_PROC;
+ ec->write_iovec.iod_proc_nr = mp->DL_ENDPT;
ec->write_iovec.iod_grant = mp->DL_GRANT;
ec->write_iovec.iod_iovec_offset = 0;
/* reply by calling do_int() if this function is called from interrupt. */
if (from_int)
return;
- reply(ec, OK, FALSE);
+ reply(ec);
}
static void do_getstat_s(mp)
message *mp;
{
- int r, port;
+ int r;
ether_card_t *ec;
- port = mp->DL_PORT;
- if (port < 0 || port >= EC_PORT_NR_MAX)
- panic("illegal port: %d", port);
-
- ec= &ec_table[port];
- ec->client= mp->DL_PROC;
+ ec= &ec_state;
- r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0,
+ r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0,
(vir_bytes)&ec->eth_stat, sizeof(ec->eth_stat), D);
if (r != OK)
panic("do_getstat_s: sys_safecopyto failed: %d", r);
mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= port;
- mp->DL_STAT= OK;
r= send(mp->m_source, mp);
if (r != OK)
panic("do_getstat_s: send failed: %d", r);
}
/*===========================================================================*
- * do_stop *
+ * lance_stop *
*===========================================================================*/
-static void do_stop(mp)
-message *mp;
+static void lance_stop(ec)
+ether_card_t *ec;
{
- int port;
- ether_card_t *ec;
unsigned short ioaddr;
- port = mp->DL_PORT;
- if (port < 0 || port >= EC_PORT_NR_MAX)
- panic("illegal port: %d", port);
- ec = &ec_table[port];
-
if (!(ec->flags & ECF_ENABLED))
return;
return lance_version;
}
-/*===========================================================================*
- * do_getname *
- *===========================================================================*/
-static void do_getname(mp)
-message *mp;
-{
- int r;
-
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
- mp->m_type= DL_NAME_REPLY;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("do_getname: send failed: %d", r);
-}
-
/*===========================================================================*
* lance_init_card *
*===========================================================================*/
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
-/* supported max number of ether cards */
-#define EC_PORT_NR_MAX 2
-
/* macros for 'mode' */
#define EC_DISABLED 0x0
#define EC_SINK 0x1
vir_bytes iod_iovec_offset;
} iovec_dat_t;
-#define ETH0_SELECTOR 0x61
-#define ETH1_SELECTOR 0x69
-
/* ====== ethernet card info. ====== */
typedef struct ether_card
{
/* ####### MINIX style ####### */
- char port_name[sizeof("eth_card#n")];
+ char port_name[sizeof("lance#n")];
int flags;
int mode;
int transfer_mode;
}
if (!(reg & HERMES_EV_CMD)) {
- printf("hermes @ %x: Timeout waiting for card to reset\n",
+ printf("hermes @ %lx: Timeout waiting for card to reset\n",
hw->iobase);
return -ETIMEDOUT;
}
/* Was the status, the result of the issued command, ok? */
/* The expression below should be zero. Non-zero means an error */
if (status & HERMES_STATUS_RESULT) {
- printf("Hermes:Result of INIT_CMD wrong.error value: 0x%x\n",
+ printf("Hermes:Result of INIT_CMD wrong.error value: 0x%lx\n",
(status & HERMES_STATUS_RESULT) >> 8);
err = -EIO;
}
err = hermes_issue_cmd (hw, cmd, parm0);
if (err) {
- printf("hermes @ %x: Error %d issuing command.\n",
+ printf("hermes @ %lx: Error %d issuing command.\n",
hw->iobase, err);
return err;
}
/* check for a timeout: has the command still not completed? */
if (!(reg & HERMES_EV_CMD)) {
- printf("hermes @ %x: Timeout waiting for command \
+ printf("hermes @ %lx: Timeout waiting for command \
completion.\n", hw->iobase);
err = -ETIMEDOUT;
return err;
/* tired of waiting to complete. Abort. */
if (!(reg & HERMES_EV_ALLOC)) {
- printf("hermes @ %x:Timeout waiting for frame allocation\n",
+ printf("hermes @ %lx:Timeout waiting for frame allocation\n",
hw->iobase);
return -ETIMEDOUT;
}
* Created by Stevens Le Blond <slblond@few.vu.nl>
* and Michael Valkering <mjvalker@cs.vu.nl>
*
- * * The valid messages and their parameters are:
- *
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
- * |------------+----------+---------+----------+---------+---------+---------|
- * | HARDINT | | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITE | port nr | proc nr | count | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV | port nr | proc nr | count | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READ | port nr | proc nr | count | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV | port nr | proc nr | count | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV_S | port nr | proc nr | count | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_CONF | port nr | proc nr | | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_GETSTAT | port nr | proc nr | | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_STOP | port_nr | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
- *
- * The messages sent are:
- *
- * m_type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
- * |------------|----------|---------|----------|---------|---------|
- * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock |
- * |------------|----------|---------|----------|---------|---------|
- *
- * m_type m3_i1 m3_i2 m3_ca1
- * |------------|---------|-----------|---------------|
- * |DL_CONF_REPL| port nr | last port | ethernet addr |
- * |------------|---------|-----------|---------------|
- *
- * m_type DL_PORT DL_STAT
- * |------------|---------|-----------|
- * |DL_STAT_REPL| port nr | err |
- * |------------|---------|-----------|
- *
*/
#include <minix/drivers.h>
#define IRQ_BAP 1
#define ETH_HLEN 14
-PRIVATE t_or or_table[OR_PORT_NR];
+PRIVATE t_or or_state;
+PRIVATE int or_instance;
struct ethhdr {
u8_t h_dest[ETH_ALEN];
#define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0]))
-_PROTOTYPE (static void or_writev, (message * mp, int from_int, int vectored));
-_PROTOTYPE (static void or_readv, (message * mp, int from_int, int vectored));
_PROTOTYPE (static void or_writev_s, (message * mp, int from_int));
_PROTOTYPE (static void or_readv_s, (message * mp, int from_int));
-_PROTOTYPE (static void reply, (t_or * orp, int err, int may_block));
+_PROTOTYPE (static void reply, (t_or * orp));
_PROTOTYPE (static int or_probe, (t_or *, int skip));
_PROTOTYPE (static void or_ev_info, (t_or *));
_PROTOTYPE (static void or_init, (message *));
_PROTOTYPE (static void or_rec_mode, (t_or *));
_PROTOTYPE (static void mess_reply, (message *, message *));
_PROTOTYPE (static u32_t or_get_bar, (int devind, t_or * orp));
-_PROTOTYPE (static void or_getstat, (message * mp));
_PROTOTYPE (static void or_getstat_s, (message * mp));
_PROTOTYPE (static void print_linkstatus, (t_or * orp, u16_t status));
_PROTOTYPE (static int or_get_recvd_packet, (t_or *orp, u16_t rxfid,
_PROTOTYPE (static void or_reset, (void));
_PROTOTYPE (static void or_watchdog_f, (timer_t *tp) );
_PROTOTYPE (static void setup_wepkey, (t_or *orp, char *wepkey0) );
-_PROTOTYPE (static void or_getstat, (message *m));
_PROTOTYPE (static void do_hard_int, (void));
_PROTOTYPE (static void check_int_events, (void));
-_PROTOTYPE (static void or_getname, (message *m));
_PROTOTYPE (static void or_handler, (t_or *orp));
_PROTOTYPE (static void or_dump, (message *m));
PRIVATE u32_t system_hz;
-PRIVATE const char *progname;
-
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
}
switch (m.m_type) {
- case DL_WRITEV:
- or_writev (&m, FALSE, TRUE);
- break;
case DL_WRITEV_S:
or_writev_s (&m, FALSE);
break;
- case DL_WRITE:
- or_writev (&m, FALSE, FALSE);
- break;
- case DL_READ:
- or_readv (&m, FALSE, FALSE);
- break;
- case DL_READV:
- or_readv (&m, FALSE, TRUE);
- break;
case DL_READV_S:
or_readv_s (&m, FALSE);
break;
case DL_CONF:
or_init (&m);
break;
- case DL_GETSTAT:
- or_getstat (&m);
- break;
case DL_GETSTAT_S:
or_getstat_s (&m);
break;
- case DL_GETNAME:
- or_getname(&m);
- break;
default:
panic("orinoco: illegal message: %d", m.m_type);
}
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the orinoco driver. */
+ long v;
int fkeys, sfkeys, r;
system_hz = sys_hz();
- (progname=strrchr(env_argv[0],'/')) ? progname++
- : (progname=env_argv[0]);
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ or_instance = (int) v;
/* Observe some function key for debug dumps. */
fkeys = sfkeys = 0; bit_set(sfkeys, 11);
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
- int i;
t_or *orp;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
- for (i= 0, orp= &or_table[0]; i<OR_PORT_NR; i++, orp++) {
- if (orp->or_mode != OR_M_ENABLED)
- continue;
+ orp = &or_state;
+
+ if (orp->or_mode == OR_M_ENABLED) {
/* TODO: send a signal to the card to shut it down */
}
exit(0);
/* the interrupt message doesn't contain information about the port, try
* to find it */
- for (orp = or_table;
- orp < or_table + OR_PORT_NR; orp++) {
- if (orp->or_mode != OR_M_ENABLED)
- continue;
- if (!orp->or_got_int)
- continue;
- orp->or_got_int = 0;
- assert (orp->or_flags & OR_F_ENABLED);
- or_check_ints (orp);
- }
+ orp = &or_state;
-}
-
-/****************************************************************************
- * or_getname *
- * *
- * Gets the drivers name, orinoco *
- ****************************************************************************/
-static void or_getname(message *mp) {
- int r;
-
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[sizeof(mp->DL_NAME) - 1] = '\0';
- mp->m_type = DL_NAME_REPLY;
+ if (orp->or_mode != OR_M_ENABLED)
+ return;
+ if (!orp->or_got_int)
+ return;
+ orp->or_got_int = 0;
+ assert (orp->or_flags & OR_F_ENABLED);
+ or_check_ints (orp);
- r = send(mp->m_source, mp);
- if(r != OK) {
- panic("or_getname: send failed: %d", r);
- }
}
/*****************************************************************************
*****************************************************************************/
static void do_hard_int(void)
{
- int i,s;
+ int s;
- for (i=0; i < OR_PORT_NR; i ++) {
- /* Run interrupt handler at driver level. */
- or_handler( &or_table[i]);
+ /* Run interrupt handler at driver level. */
+ or_handler(&or_state);
- /* Reenable interrupts for this hook. */
- if ((s=sys_irqenable(&or_table[i].or_hook_id)) != OK) {
- printf("orinoco: error, couldn't enable");
- printf(" interrupts: %d\n", s);
- }
+ /* Reenable interrupts for this hook. */
+ if ((s=sys_irqenable(&or_state.or_hook_id)) != OK) {
+ printf("orinoco: error, couldn't enable");
+ printf(" interrupts: %d\n", s);
}
}
static void or_reset() {
static clock_t last_reset, now;
t_or *orp;
- int i, j, r;
+ int i, r;
if (OK != (r = getuptime(&now)))
panic("orinoco: getuptime() failed: %d", r);
printf("Resetting card too often. Going to reset driver\n");
exit(1);
}
+
+ last_reset = now;
- for (i = 0, orp = or_table; orp < or_table + OR_PORT_NR; i++, orp++) {
- if(orp->or_mode == OR_M_DISABLED)
- printf("orinoco port %d is disabled\n", i);
-
- if(orp->or_mode != OR_M_ENABLED) {
- continue;
- }
+ orp = &or_state;
- orp->or_need_reset = 0;
- or_init_hw(orp);
+ if(orp->or_mode == OR_M_DISABLED)
+ printf("orinoco instance %d is disabled\n", or_instance);
+
+ if(orp->or_mode != OR_M_ENABLED) {
+ return;
+ }
- orp->rx_last = orp->rx_first = 0;
- for(j = 0; j < NR_RX_BUFS; j++) {
- orp->rx_length[0] = 0;
- }
+ orp->or_need_reset = 0;
+ or_init_hw(orp);
- if(orp->or_flags & OR_F_SEND_AVAIL) {
- orp->or_tx.ret_busy = FALSE;
- orp->or_send_int = TRUE;
- }
+ orp->rx_last = orp->rx_first = 0;
+ for(i = 0; i < NR_RX_BUFS; i++) {
+ orp->rx_length[0] = 0;
}
- last_reset = now;
-
+ if(orp->or_flags & OR_F_SEND_AVAIL) {
+ orp->or_tx.ret_busy = FALSE;
+ orp->or_send_int = TRUE;
+ }
}
/*****************************************************************************
static void or_dump (message *m)
{
t_or *orp;
+
+ orp = &or_state;
- for (orp = or_table; orp < or_table + OR_PORT_NR; orp++) {
- if(orp->or_mode == OR_M_DISABLED) {
- printf("%s is disabled\n", orp->or_name);
- }
+ if(orp->or_mode == OR_M_DISABLED) {
+ printf("%s is disabled\n", orp->or_name);
+ }
- if(orp->or_mode != OR_M_ENABLED)
- continue;
+ if(orp->or_mode != OR_M_ENABLED)
+ return;
- m->m_type = FKEY_CONTROL;
- m->FKEY_REQUEST = FKEY_EVENTS;
- if(OK!=(sendrec(TTY_PROC_NR,m)) )
- printf("Contacting the TTY failed\n");
+ m->m_type = FKEY_CONTROL;
+ m->FKEY_REQUEST = FKEY_EVENTS;
+ if(OK!=(sendrec(TTY_PROC_NR,m)) )
+ printf("Contacting the TTY failed\n");
- if(bit_isset(m->FKEY_SFKEYS, 11)) {
- print_linkstatus(orp, orp->last_linkstatus);
- }
+ if(bit_isset(m->FKEY_SFKEYS, 11)) {
+ print_linkstatus(orp, orp->last_linkstatus);
}
}
* The main initialization function, called when a DL_INIT message comes in. *
*****************************************************************************/
static void or_init (message * mp) {
- int port;
t_or *orp;
message reply;
static int first_time = 1;
sys_setalarm(system_hz, 0);
}
- port = mp->DL_PORT;
- if (port < 0 || port >= OR_PORT_NR) {
- /* illegal port in message */
- reply.m_type = DL_CONF_REPLY;
- reply.m3_i1 = ENXIO;
- mess_reply (mp, &reply);
- return;
- }
-
- /* the port resolves to the main orinoco structure */
- orp = &or_table[port];
- /* resolving to the main hardware structure */
+ orp = &or_state;
if (orp->or_mode == OR_M_DISABLED) {
/* Initialize the orp structure */
or_init_struct (orp);
if (orp->or_mode == OR_M_DISABLED) {
reply.m_type = DL_CONF_REPLY;
- reply.m3_i1 = ENXIO;
+ reply.DL_STAT = ENXIO;
mess_reply (mp, &reply);
return;
}
if (mp->DL_MODE & DL_BROAD_REQ)
orp->or_flags |= OR_F_BROAD;
- orp->or_client = mp->m_source;
or_rec_mode (orp);
/* reply the caller that the configuration succeeded */
reply.m_type = DL_CONF_REPLY;
- reply.m3_i1 = mp->DL_PORT;
- reply.m3_i2 = OR_PORT_NR;
- *(ether_addr_t *) reply.m3_ca1 = orp->or_address;
+ reply.DL_STAT = OK;
+ *(ether_addr_t *) reply.DL_HWADDR = orp->or_address;
mess_reply (mp, &reply);
}
static void or_pci_conf () {
long v;
t_or *orp;
- int i, h;
static char envfmt[] = "*:d.d.d";
static char envvar[] = OR_ENVVAR "#";
static char val[128];
/* extract information from the boot monitor about the pci
* configuration if provided */
- for (i = 0, orp = or_table; i < OR_PORT_NR; i++, orp++) {
- strncpy (orp->or_name, OR_NAME, sizeof(OR_NAME));
- orp->or_name[sizeof(OR_NAME) - 2] = i + '0';
- orp->or_seen = FALSE;
- /* whats this envvar; whats the definition;*/
- /* i guess this whole loop could be removed*/
- envvar[sizeof (OR_ENVVAR) - 1] = '0' + i;
- if (0 == env_get_param(envvar, val, sizeof(val)) &&
- ! env_prefix(envvar, "pci")) {
- env_panic(envvar);
- }
- v = 0;
- (void) env_parse (envvar, envfmt, 1, &v, 0, 255);
- orp->or_pci_bus = v;
- v = 0;
- (void) env_parse (envvar, envfmt, 2, &v, 0, 255);
- orp->or_pci_dev = v;
- v = 0;
- (void) env_parse (envvar, envfmt, 3, &v, 0, 255);
- orp->or_pci_func = v;
- }
+ orp = &or_state;
+
+ strncpy (orp->or_name, OR_NAME, sizeof(OR_NAME));
+ orp->or_name[sizeof(OR_NAME) - 2] = or_instance + '0';
+ orp->or_seen = FALSE;
+ /* whats this envvar; whats the definition;*/
+ /* i guess this whole loop could be removed*/
+ envvar[sizeof (OR_ENVVAR) - 1] = '0' + or_instance;
+ if (0 == env_get_param(envvar, val, sizeof(val)) &&
+ ! env_prefix(envvar, "pci")) {
+ env_panic(envvar);
+ }
+ v = 0;
+ (void) env_parse (envvar, envfmt, 1, &v, 0, 255);
+ orp->or_pci_bus = v;
+ v = 0;
+ (void) env_parse (envvar, envfmt, 2, &v, 0, 255);
+ orp->or_pci_dev = v;
+ v = 0;
+ (void) env_parse (envvar, envfmt, 3, &v, 0, 255);
+ orp->or_pci_func = v;
/* Initialize the pci bus, bridges and cards, if not yet done */
pci_init ();
- /* Try to find out where the card(s) are in the pci bus */
- for (h = 1; h >= 0; h--)
- for (i = 0, orp = or_table; i < OR_PORT_NR; i++, orp++) {
- if (((orp->or_pci_bus | orp->or_pci_dev |
- orp->or_pci_func) != 0) != h) {
- continue;
- }
- if (or_probe (orp, i))
- orp->or_seen = TRUE;
- }
+ /* Try to find out where the card is in the pci bus */
+ if (or_probe (orp, or_instance))
+ orp->or_seen = TRUE;
}
/*****************************************************************************
orp->or_name, bar, orp->or_irq);
}
- panic("Not implemente yet");
+ panic("Not implemented yet");
/* Although we are able to find the desired bar and irq for an
* I/O spaced card, we haven't implemented the right register
* accessing functions. This wouldn't be difficult, but we were
}
/* here begins the real things, yeah! ;) */
- if (err = hermes_init (hw)) {
+ if ((err = hermes_init (hw)) != 0) {
printf ("error value of hermes_init(): %d\n", err);
}
*****************************************************************************/
static void or_watchdog_f(timer_t *tp)
{
- int i;
t_or *orp;
/* Use a synchronous alarm instead of a watchdog timer. */
sys_setalarm(system_hz, 0);
- for (i= 0, orp = &or_table[0]; i<OR_PORT_NR; i++, orp++) {
- if (orp->or_mode != OR_M_ENABLED)
- continue;
+ orp = &or_state;
- if (!(orp->or_flags & OR_F_SEND_AVAIL)) {
- /* Assume that an idle system is alive */
- orp->or_tx_alive= TRUE;
- continue;
- }
+ if (orp->or_mode != OR_M_ENABLED)
+ return;
- if (orp->connected == 0) {
- orp->or_tx_alive= TRUE;
- continue;
- }
- if (orp->or_tx_alive) {
- orp->or_tx_alive= FALSE;
- continue;
- }
-
- printf("or_watchdog_f: resetting port %d\n", i);
-
- orp->or_need_reset= TRUE;
- orp->or_got_int= TRUE;
- check_int_events();
+ if (!(orp->or_flags & OR_F_SEND_AVAIL)) {
+ /* Assume that an idle system is alive */
+ orp->or_tx_alive= TRUE;
+ return;
}
+
+ if (orp->connected == 0) {
+ orp->or_tx_alive= TRUE;
+ return;
+ }
+ if (orp->or_tx_alive) {
+ orp->or_tx_alive= FALSE;
+ return;
+ }
+
+ printf("or_watchdog_f: resetting instance %d\n", or_instance);
+
+ orp->or_need_reset= TRUE;
+ orp->or_got_int= TRUE;
+ check_int_events();
}
/*****************************************************************************
* mess_reply *
*****************************************************************************/
-
static void mess_reply (message * req, message * reply_mess)
{
if (send (req->m_source, reply_mess) != 0)
}
-/*****************************************************************************
- * or_writev *
- * *
- * As far as we can see, this function is never called from 3.1.3. However, *
- * it is still in rtl8139, so we'll keep it here as well. It's almost a copy *
- * of or_writev_s. We left out the comments. For an explanation, see *
- * or_writev_s *
-******************************************************************************/
-static void or_writev (message * mp, int from_int, int vectored)
-{
- int port, or_client, count, size, err, data_len, data_off;
- int o, j, n, i, s, p, cps;
- struct ethhdr *eh;
- t_or *orp;
- hermes_t *hw;
- struct hermes_tx_descriptor desc;
- struct header_struct hdr;
-
- iovec_t *iovp;
- u16_t txfid;
- static u8_t databuf[IEEE802_11_DATA_LEN + ETH_HLEN + 2 + 1];
- memset (databuf, 0, IEEE802_11_DATA_LEN + ETH_HLEN + 3);
-
- port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (port < 0 || port >= OR_PORT_NR)
- panic("orinoco: illegal port");
-
- or_client = mp->DL_PROC;
- orp = &or_table[port];
- orp->or_client = or_client;
- hw = &(orp->hw);
-
- if (from_int) {
- assert (orp->or_flags & OR_F_SEND_AVAIL);
- orp->or_flags &= ~OR_F_SEND_AVAIL;
- orp->or_send_int = FALSE;
- orp->or_tx_alive = TRUE;
- }
-
- if (orp->or_tx.ret_busy) {
- assert(!(orp->or_flags & OR_F_SEND_AVAIL));
- orp->or_flags |= OR_F_SEND_AVAIL;
- goto suspend_write;
- }
-
- assert (orp->or_mode == OR_M_ENABLED);
- assert (orp->or_flags & OR_F_ENABLED);
-
- /* CvR: copied from or_writev_s(), since txfid was not initialized. */
- txfid = orp->or_tx.or_txfid;
-
- if (vectored) {
-
- int iov_offset = 0;
- size = 0;
- o = 0;
-
- for (i = 0; i < count; i += IOVEC_NR,
- iov_offset += IOVEC_NR * sizeof (orp->or_iovec[0])) {
-
- n = IOVEC_NR;
- if (i + n > count)
- n = count - i;
- cps = sys_vircopy(or_client, D,
- ((vir_bytes) mp->DL_ADDR) + iov_offset,
- SELF, D, (vir_bytes) orp->or_iovec,
- n * sizeof(orp->or_iovec[0]));
- if (cps != OK) printf("sys_vircopy failed: %d\n", cps);
-
- for (j = 0, iovp = orp->or_iovec; j < n; j++, iovp++) {
- s = iovp->iov_size;
- if (size + s > ETH_MAX_PACK_SIZE_TAGGED) {
- printf("invalid packet size\n");
- }
- cps = sys_vircopy(or_client, D, iovp->iov_addr,
- SELF, D, (vir_bytes) databuf + o, s);
- if (cps != OK)
- printf("sys_vircopy failed: %d\n",cps);
-
- size += s;
- o += s;
- }
- }
- if (size < ETH_MIN_PACK_SIZE)
- printf("invalid packet size %d\n", size);
- } else {
- size = mp->DL_COUNT;
- if (size < ETH_MIN_PACK_SIZE
- || size > ETH_MAX_PACK_SIZE_TAGGED)
- printf("invalid packet size %d\n", size);
-
- cps = sys_vircopy(or_client, D, (vir_bytes)mp->DL_ADDR,
- SELF, D, (vir_bytes) databuf, size);
- if (cps != OK) printf("sys_abscopy failed: %d\n", cps);
- }
-
- memset (&desc, 0, sizeof (desc));
- desc.tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
-
- err = hermes_bap_pwrite (hw, USER_BAP, &desc, sizeof (desc), txfid,
- 0);
- if (err) {
- or_reset();
- goto fail;
- }
-
- eh = (struct ethhdr *) databuf;
- if (ntohs (eh->h_proto) > 1500) {
-
- data_len = size - ETH_HLEN;
- data_off = HERMES_802_3_OFFSET + sizeof (hdr);
-
- memcpy (hdr.dest, eh->h_dest, ETH_ALEN);
- memcpy (hdr.src, eh->h_src, ETH_ALEN);
- hdr.len = htons (data_len + ENCAPS_OVERHEAD);
-
- memcpy (&hdr.dsap, &encaps_hdr, sizeof (encaps_hdr));
- hdr.ethertype = eh->h_proto;
-
- err = hermes_bap_pwrite (hw, USER_BAP, &hdr, sizeof (hdr),
- txfid, HERMES_802_3_OFFSET);
- if (err) {
- printf ("%s: Error %d writing packet header to BAP\n",
- orp->or_name, err);
- goto fail;
- }
-
- p = ETH_HLEN;
- } else {
- data_len = size + ETH_HLEN;
- data_off = HERMES_802_3_OFFSET;
- p = 0;
- }
-
- err = hermes_bap_pwrite (hw, USER_BAP,
- (void *) &(databuf[p]), RUP_EVEN (data_len),
- txfid, data_off);
- if (err) {
- printf ("hermes_bap_pwrite(data): error %d\n", err);
- goto fail;
- }
-
- orp->or_tx.ret_busy = TRUE;
-
- err = hermes_docmd_wait (hw, HERMES_CMD_TX | HERMES_CMD_RECL,
- txfid, NULL);
- if (err) {
- orp->or_tx.ret_busy = FALSE;
- printf ("hermes_docmd_wait(TX|RECL): error %d\n", err);
- goto fail;
- }
-
-fail:
- orp->or_flags |= OR_F_PACK_SENT;
-
- if (from_int) {
- return;
- }
-
- reply (orp, OK, FALSE);
- return;
-
-suspend_write:
- orp->or_tx_mess = *mp;
- reply (orp, OK, FALSE);
- return;
-}
-
-
-
/*****************************************************************************
* or_writev_s *
* *
* Write data which is denoted by the message to the card and send it. *
*****************************************************************************/
static void or_writev_s (message * mp, int from_int) {
- int port, or_client, count, size, err, data_len, data_off;
+ int count, size, err, data_len, data_off;
int o, j, n, i, s, p, cps ;
struct ethhdr *eh;
t_or *orp;
static u8_t databuf[IEEE802_11_DATA_LEN + ETH_HLEN + 2 + 1];
memset (databuf, 0, IEEE802_11_DATA_LEN + ETH_HLEN + 3);
- port = mp->DL_PORT;
+ orp = &or_state;
+
count = mp->DL_COUNT;
- if (port < 0 || port >= OR_PORT_NR)
- panic("orinoco: illegal port");
- or_client = mp->DL_PROC;
- orp = &or_table[port];
- orp->or_client = or_client;
+ orp->or_client = mp->m_source;
hw = &(orp->hw);
/* Switch off interrupts. The card is accessable via 2 BAPs, one for
if (i + n > count)
n = count - i;
- cps = sys_safecopyfrom(or_client, mp->DL_GRANT, iov_offset,
+ cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset,
(vir_bytes) orp->or_iovec_s,
n * sizeof(orp->or_iovec_s[0]), D);
if (cps != OK)
printf("Orinoco: invalid pkt size\n");
}
- cps = sys_safecopyfrom(or_client, iovp->iov_grant, 0,
- (vir_bytes) databuf + o, s, D);
+ cps = sys_safecopyfrom(mp->DL_ENDPT, iovp->iov_grant,
+ 0, (vir_bytes) databuf + o, s, D);
if (cps != OK)
printf("orinoco: sys_safecopyfrom failed:%d\n",
cps);
return;
}
- reply (orp, OK, FALSE);
+ reply (orp);
return;
suspend_write_s:
orp->or_tx_mess = *mp;
- reply (orp, OK, FALSE);
+ reply (orp);
return;
}
* Send a message back to the caller, informing it about the data received *
* or sent *
*****************************************************************************/
-static void reply (t_or * orp, int err, int may_block) {
+static void reply (t_or * orp) {
message reply;
- int status = 0, r;
- clock_t now;
+ int flags = DL_NOFLAGS, r;
if (orp->or_flags & OR_F_PACK_SENT)
- status |= DL_PACK_SEND;
+ flags |= DL_PACK_SEND;
if (orp->or_flags & OR_F_PACK_RECV)
- status |= DL_PACK_RECV;
+ flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY;
- reply.DL_PORT = orp - or_table;
- assert(reply.DL_PORT == 0);
- reply.DL_PROC = orp->or_client;
- reply.DL_STAT = status | ((u32_t) err << 16);
+ reply.DL_FLAGS = flags;
reply.DL_COUNT = orp->or_read_s;
- if (OK != (r = getuptime(&now)))
- panic("orinoco: getuptime() failed: %d", r);
-
- reply.DL_CLCK = now;
r = send (orp->or_client, &reply);
- if (r == ELOCKED && may_block) {
- return;
- }
-
if (r < 0)
panic("orinoco: send failed: %d", r);
}
-
/*****************************************************************************
* or_ev_info *
* *
printf ("%s: Error %d \n", orp->or_name, err);
return;
}
- printf("channel: %d, freq: %d MHz ",
+ printf("channel: %d, freq: %ld MHz ",
d, (channel_frequency[d-1]));
}
or_reset();
if ((orp->rx_first!=orp->rx_last) && (orp->or_flags & OR_F_READING)) {
orp->or_ev_rx = 0;
- if (orp->or_rx_mess.m_type == DL_READV) {
- or_readv (&orp->or_rx_mess, TRUE, TRUE);
- } else if(orp->or_rx_mess.m_type == DL_READV_S) {
- or_readv_s (&orp->or_rx_mess, TRUE);
- } else {
- assert(orp->or_rx_mess.m_type == DL_READ);
- or_readv (&orp->or_rx_mess, TRUE, FALSE);
- }
+ or_readv_s (&orp->or_rx_mess, TRUE);
}
if (orp->or_send_int) {
- if (orp->or_tx_mess.m_type == DL_WRITEV) {
- or_writev (&orp->or_tx_mess, TRUE, TRUE);
- }
- else if(orp->or_tx_mess.m_type == DL_WRITEV_S) {
- or_writev_s (&orp->or_tx_mess, TRUE);
- } else {
- assert(orp->or_tx_mess.m_type == DL_WRITE);
- or_writev (&orp->or_tx_mess, TRUE, FALSE);
- }
+ or_writev_s (&orp->or_tx_mess, TRUE);
}
if (orp->or_flags & (OR_F_PACK_SENT | OR_F_PACK_RECV)) {
- reply (orp, OK, TRUE);
+ reply (orp);
}
}
&& ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) );
}
-/*****************************************************************************
- * or_readv *
- * *
- * As far as we can see, this function is never called from 3.1.3. However, *
- * it is still in rtl8139, so we'll keep it here as well. It's almost a copy *
- * of or_readv_s. We left out the comments. For an explanation, see *
- * or_readv_s *
- *****************************************************************************/
-static void or_readv (message * mp, int from_int, int vectored) {
- int i, j, n, o, s, dl_port;
- int or_client, count;
- int size, cps;
- int length;
- t_or *orp;
- iovec_t *iovp;
- u8_t *databuf;
-
- dl_port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= OR_PORT_NR)
- panic("orinoco: illegal port: %d", dl_port);
-
- orp = &or_table[dl_port];
- or_client = mp->DL_PROC;
- orp->or_client = or_client;
-
- assert (orp->or_mode == OR_M_ENABLED);
- assert (orp->or_flags & OR_F_ENABLED);
-
- if (!from_int && (orp->rx_first==orp->rx_last)) {
- goto suspend_readv;
- }
-
- databuf = &(orp->rx_buf[orp->rx_first][0]);
- length = orp->rx_length[orp->rx_first];
-
- orp->rxfid[orp->rx_first] = NO_FID;
- orp->rx_length[orp->rx_first] = 0;
-
- orp->rx_first++;
- orp->rx_first %= NR_RX_BUFS;
-
- o = 0;
-
- if (vectored) {
- int iov_offset = 0;
- size = 0;
-
- for (i = 0; i < count; i += IOVEC_NR,
- iov_offset += IOVEC_NR * sizeof(orp->or_iovec[0])) {
-
- n = IOVEC_NR;
- if (i + n > count)
- n = count - i;
-
- cps = sys_vircopy(or_client, D,
- (vir_bytes) mp->DL_ADDR + iov_offset,
- SELF, D, (vir_bytes) orp->or_iovec,
- n * sizeof(orp->or_iovec[0]));
- if (cps != OK) printf("sys_vircopy failed: %d (%d)\n",
- cps, __LINE__);
-
- for (j = 0, iovp = orp->or_iovec; j < n; j++, iovp++) {
- s = iovp->iov_size;
- if (size + s > length) {
- assert (length > size);
- s = length - size;
- }
-
- cps = sys_vircopy(SELF, D,
- (vir_bytes) databuf + o,
- or_client, D,
- iovp->iov_addr, s);
- if (cps != OK)
- printf("sys_vircopy failed:%d (%d)\n",
- cps, __LINE__);
-
- size += s;
- if (size == length)
- break;
- o += s;
- }
- if (size == length)
- break;
- }
- assert (size >= length);
- }
-
- orp->or_stat.ets_packetR++;
- orp->or_read_s = length;
- orp->or_flags &= ~OR_F_READING;
- orp->or_flags |= OR_F_PACK_RECV;
-
- if (!from_int)
- reply (orp, OK, FALSE);
-
- return;
-
-suspend_readv :
- if (from_int) {
- assert (orp->or_flags & OR_F_READING);
- return;
- }
-
- orp->or_rx_mess = *mp;
- assert (!(orp->or_flags & OR_F_READING));
- orp->or_flags |= OR_F_READING;
-
- reply (orp, OK, FALSE);
-}
-
-
/*****************************************************************************
* or_readv_s *
* *
*****************************************************************************/
static void or_readv_s (message * mp, int from_int)
{
- int i, j, n, o, s, dl_port, or_client, count, size, cps;
+ int i, j, n, o, s, count, size, cps;
int iov_offset = 0, length;
t_or *orp;
iovec_s_t *iovp;
u8_t *databuf;
- dl_port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= OR_PORT_NR)
- panic("orinoco: illegal port: %d", dl_port);
+ orp = &or_state;
- orp = &or_table[dl_port];
- or_client = mp->DL_PROC;
- orp->or_client = or_client;
+ orp->or_client = mp->m_source;
+ count = mp->DL_COUNT;
assert (orp->or_mode == OR_M_ENABLED);
assert (orp->or_flags & OR_F_ENABLED);
if (i + n > count)
n = count - i;
- cps = sys_safecopyfrom(or_client, mp->DL_GRANT, iov_offset,
+ cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset,
(vir_bytes)orp->or_iovec_s,
n * sizeof(orp->or_iovec_s[0]), D);
if (cps != OK)
assert (length > size);
s = length - size;
}
- cps = sys_safecopyto(or_client, iovp->iov_grant, 0,
+ cps = sys_safecopyto(mp->DL_ENDPT, iovp->iov_grant, 0,
(vir_bytes) databuf + o, s, D);
if (cps != OK)
panic("orinoco: warning: sys_safecopy failed: %d", cps);
assert(size >= length);
orp->or_stat.ets_packetR++;
-drop:
orp->or_read_s = length;
orp->or_flags &= ~OR_F_READING;
orp->or_flags |= OR_F_PACK_RECV;
if (!from_int) {
/* There was data in the orp->rx_buf[x] which is now copied to
* the inet sever. Tell the inet server */
- reply (orp, OK, FALSE);
+ reply (orp);
}
return;
assert (!(orp->or_flags & OR_F_READING));
orp->or_flags |= OR_F_READING;
- reply (orp, OK, FALSE);
+ reply (orp);
}
return length;
}
-/*****************************************************************************
- * or_getstat *
- * *
- * Return the statistics structure. The statistics aren't updated until now, *
- * so this won't return much interesting yet. *
- *****************************************************************************/
-static void or_getstat (message * mp)
-{
- int r, port;
- eth_stat_t stats;
- t_or *orp;
-
- port = mp->DL_PORT;
- if (port < 0 || port >= OR_PORT_NR)
- panic("orinoco: illegal port: %d", port);
- orp = &or_table[port];
- orp->or_client = mp->DL_PROC;
-
- assert (orp->or_mode == OR_M_ENABLED);
- assert (orp->or_flags & OR_F_ENABLED);
-
- stats = orp->or_stat;
-
- r = sys_datacopy(SELF, (vir_bytes)&stats, mp->DL_PROC,
- (vir_bytes) mp->DL_ADDR, sizeof(stats));
- if(r != OK) {
- panic("or_getstat: send failed: %d", r);
- }
-
- mp->m_type = DL_STAT_REPLY;
- mp->DL_PORT = port;
- mp->DL_STAT = OK;
-
- r = send(mp->m_source, mp);
- if(r != OK)
- panic("orinoco: getstat failed: %d", r);
-
- /*reply (orp, OK, FALSE);*/
-
-}
-
/*****************************************************************************
* or_getstat_s *
* *
* so this won't return much interesting yet. *
*****************************************************************************/
static void or_getstat_s (message * mp) {
- int r, port;
+ int r;
eth_stat_t stats;
t_or *orp;
- port = mp->DL_PORT;
- if (port < 0 || port >= OR_PORT_NR)
- panic("orinoco: illegal port: %d", port);
- assert(port==0);
- orp = &or_table[port];
- orp->or_client = mp->DL_PROC;
+ orp = &or_state;
assert (orp->or_mode == OR_M_ENABLED);
assert (orp->or_flags & OR_F_ENABLED);
stats = orp->or_stat;
- r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0,
+ r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0,
(vir_bytes) &stats, sizeof(stats), D);
if(r != OK) {
panic("or_getstat_s: sys_safecopyto failed: %d", r);
}
mp->m_type = DL_STAT_REPLY;
- mp->DL_PORT = port;
- mp->DL_STAT = OK;
r = send(mp->m_source, mp);
if(r != OK)
#define LARGE_KEY_LENGTH 13
#define IW_ESSID_MAX_SIZE 32
-#define OR_PORT_NR 1
#define IOVEC_NR 16
#define OR_ENVVAR "ORETH"
#define OR_NAME "orinoco#n"
#include "rtl8139.h"
/* State management variables. */
-EXTERN re_t re_table[RE_PORT_NR];
+EXTERN re_t re_state;
/* Custom states definition. */
#define RL_STATE_READ_PROTOCOL_FREE (SEF_LU_STATE_CUSTOM_BASE + 0)
/* State management helpers. */
PRIVATE int is_reading;
PRIVATE int is_writing;
+
PRIVATE void load_state_info(void)
{
- int i, found_processing;
re_t *rep;
/* Check if we are reading or writing. */
- is_reading = FALSE;
- is_writing = FALSE;
- found_processing = FALSE;
- for (i= 0; i<RE_PORT_NR && !found_processing; i++) {
- rep = &re_table[i];
-
- if (rep->re_flags & REF_READING) {
- is_reading = TRUE;
- }
+ rep = &re_state;
- if (rep->re_flags & REF_SEND_AVAIL) {
- is_writing = TRUE;
- }
-
- found_processing = (is_reading && is_writing);
- }
+ is_reading = !!(rep->re_flags & REF_READING);
+ is_writing = !!(rep->re_flags & REF_SEND_AVAIL);
}
/*===========================================================================*
* This file contains a ethernet device driver for Realtek rtl8139 based
* ethernet cards.
*
- * The valid messages and their parameters are:
- *
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
- * |------------+----------+---------+----------+---------+---------+---------|
- * | HARDINT | | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITE | port nr | proc nr | count | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV | port nr | proc nr | count | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READ | port nr | proc nr | count | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV | port nr | proc nr | count | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_READV_S | port nr | proc nr | count | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_CONF | port nr | proc nr | | mode | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_GETSTAT | port nr | proc nr | | | address | |
- * |------------|----------|---------|----------|---------|---------|---------|
- * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
- * |------------|----------|---------|----------|---------|---------|---------|
- * | DL_STOP | port_nr | | | | | |
- * |------------|----------|---------|----------|---------|---------|---------|
- *
- * The messages sent are:
- *
- * m_type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
- * |------------|----------|---------|----------|---------|---------|
- * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock |
- * |------------|----------|---------|----------|---------|---------|
- *
- * m_type m3_i1 m3_i2 m3_ca1
- * |------------|---------|-----------|---------------|
- * |DL_CONF_REPL| port nr | last port | ethernet addr |
- * |------------|---------|-----------|---------------|
- *
- * m_type DL_PORT DL_STAT
- * |------------|---------|-----------|
- * |DL_STAT_REPL| port nr | err |
- * |------------|---------|-----------|
- *
* Created: Aug 2003 by Philip Homburg <philip@cs.vu.nl>
* Changes:
* Aug 15, 2004 sync alarms replace watchdogs timers (Jorrit N. Herder)
*
*/
+#define VERBOSE 0 /* Verbose debugging output */
#define RTL8139_FKEY 0 /* Use function key to dump RTL8139 status */
#include "rtl8139.h"
{ 0x0000, 0x0000, 0 }
};
-PUBLIC re_t re_table[RE_PORT_NR];
+PUBLIC re_t re_state;
+
+static int re_instance;
-static u16_t eth_ign_proto;
static tmra_ut rl_watchdog;
static unsigned my_inb(u16_t port) {
_PROTOTYPE( static void rl_pci_conf, (void) );
_PROTOTYPE( static int rl_probe, (re_t *rep, int skip) );
_PROTOTYPE( static void rl_conf_hw, (re_t *rep) );
-_PROTOTYPE( static void rl_init_buf, (re_t *rep) );
+_PROTOTYPE( static void rl_init_buf, (re_t *rep) );
_PROTOTYPE( static void rl_init_hw, (re_t *rep) );
_PROTOTYPE( static void rl_reset_hw, (re_t *rep) );
_PROTOTYPE( static void rl_confaddr, (re_t *rep) );
_PROTOTYPE( static void rl_rec_mode, (re_t *rep) );
-_PROTOTYPE( static void rl_readv, (const message *mp, int from_int,
- int vectored) );
_PROTOTYPE( static void rl_readv_s, (const message *mp, int from_int) );
-_PROTOTYPE( static void rl_writev, (const message *mp, int from_int,
- int vectored) );
_PROTOTYPE( static void rl_writev_s, (const message *mp, int from_int) );
_PROTOTYPE( static void rl_check_ints, (re_t *rep) );
_PROTOTYPE( static void rl_report_link, (re_t *rep) );
u16_t extstat) );
_PROTOTYPE( static void rl_clear_rx, (re_t *rep) );
_PROTOTYPE( static void rl_do_reset, (re_t *rep) );
-_PROTOTYPE( static void rl_getstat, (message *mp) );
_PROTOTYPE( static void rl_getstat_s, (message *mp) );
-_PROTOTYPE( static void rl_getname, (message *mp) );
-_PROTOTYPE( static void reply, (re_t *rep, int err, int may_block) );
+_PROTOTYPE( static void reply, (re_t *rep) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
-_PROTOTYPE( static void check_int_events, (void) );
+_PROTOTYPE( static void check_int_events, (void) );
_PROTOTYPE( static void do_hard_int, (void) );
-_PROTOTYPE( static void rtl8139_dump, (message *m) );
+_PROTOTYPE( static void rtl8139_dump, (message *m) );
#if 0
_PROTOTYPE( static void dump_phy, (re_t *rep) );
#endif
-_PROTOTYPE( static int rl_handler, (re_t *rep) );
+_PROTOTYPE( static int rl_handler, (re_t *rep) );
_PROTOTYPE( static void rl_watchdog_f, (timer_t *tp) );
_PROTOTYPE( static void tell_dev, (vir_bytes start, size_t size,
int pci_bus, int pci_dev, int pci_func) );
PRIVATE message m;
PRIVATE int int_event_check; /* set to TRUE if events arrived */
-static const char *progname;
PRIVATE u32_t system_hz;
/* SEF functions and variables. */
switch (m.m_type)
{
- case DL_WRITE: rl_writev(&m, FALSE, FALSE); break;
- case DL_WRITEV: rl_writev(&m, FALSE, TRUE); break;
case DL_WRITEV_S: rl_writev_s(&m, FALSE); break;
- case DL_READ: rl_readv(&m, FALSE, FALSE); break;
- case DL_READV: rl_readv(&m, FALSE, TRUE); break;
case DL_READV_S: rl_readv_s(&m, FALSE); break;
case DL_CONF: rl_init(&m); break;
- case DL_GETSTAT: rl_getstat(&m); break;
case DL_GETSTAT_S: rl_getstat_s(&m); break;
- case DL_GETNAME: rl_getname(&m); break;
-#if 0
- case DL_STOP: do_stop(&m); break;
-#endif
default:
panic("illegal message: %d", m.m_type);
}
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the rtl8139 driver. */
+ long v;
#if RTL8139_FKEY
- int fkeys, sfkeys;
+ int r, fkeys, sfkeys;
#endif
- int r;
- re_t *rep;
- long v;
system_hz = sys_hz();
- (progname=strrchr(env_argv[0],'/')) ? progname++
- : (progname=env_argv[0]);
-
- v= 0;
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- eth_ign_proto= htons((u16_t) v);
+ v = 0;
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ re_instance = (int) v;
#if RTL8139_FKEY
/* Observe some function key for debug dumps. */
printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r);
#endif
- /* Claim buffer memory now under Minix, before MM takes it all. */
- for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++)
- rl_init_buf(rep);
+ /* Claim buffer memory now. */
+ rl_init_buf(&re_state);
/* Announce we are up! */
netdriver_announce();
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
- int i;
re_t *rep;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
- for (i= 0, rep= &re_table[0]; i<RE_PORT_NR; i++, rep++)
- {
- if (rep->re_mode != REM_ENABLED)
- continue;
+ rep = &re_state;
+ if (rep->re_mode == REM_ENABLED)
rl_outb(rep->re_base_port, RL_CR, 0);
- }
+
exit(0);
}
*===========================================================================*/
static void check_int_events(void)
{
- int i;
- re_t *rep;
- for (i= 0, rep= &re_table[0]; i<RE_PORT_NR; i++, rep++)
- {
- if (rep->re_mode != REM_ENABLED)
- continue;
- if (!rep->re_got_int)
- continue;
- rep->re_got_int= 0;
- assert(rep->re_flags & REF_ENABLED);
- rl_check_ints(rep);
- }
+ re_t *rep;
+
+ rep= &re_state;
+
+ if (rep->re_mode != REM_ENABLED)
+ return;
+ if (!rep->re_got_int)
+ return;
+ rep->re_got_int= 0;
+ assert(rep->re_flags & REF_ENABLED);
+ rl_check_ints(rep);
}
/*===========================================================================*
message *m; /* pointer to request message */
{
re_t *rep;
- int i;
+
+ rep= &re_state;
printf("\n");
- for (i= 0, rep = &re_table[0]; i<RE_PORT_NR; i++, rep++)
- {
- if (rep->re_mode == REM_DISABLED)
- printf("Realtek RTL 8139 port %d is disabled\n", i);
+ if (rep->re_mode == REM_DISABLED)
+ printf("Realtek RTL 8139 instance %d is disabled\n",
+ re_instance);
- if (rep->re_mode != REM_ENABLED)
- continue;
+ if (rep->re_mode != REM_ENABLED)
+ return;
- printf("Realtek RTL 8139 statistics of port %d:\n", i);
+ printf("Realtek RTL 8139 statistics of instance %d:\n", re_instance);
- printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr);
- printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr);
- printf("OVW :%8ld\n", rep->re_stat.ets_OVW);
+ printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr);
+ printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr);
+ printf("OVW :%8ld\n", rep->re_stat.ets_OVW);
- printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr);
- printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll);
- printf("missedP :%8ld\n", rep->re_stat.ets_missedP);
+ printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr);
+ printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll);
+ printf("missedP :%8ld\n", rep->re_stat.ets_missedP);
- printf("packetR :%8ld\t", rep->re_stat.ets_packetR);
- printf("packetT :%8ld\t", rep->re_stat.ets_packetT);
- printf("transDef :%8ld\n", rep->re_stat.ets_transDef);
+ printf("packetR :%8ld\t", rep->re_stat.ets_packetR);
+ printf("packetT :%8ld\t", rep->re_stat.ets_packetT);
+ printf("transDef :%8ld\n", rep->re_stat.ets_transDef);
- printf("collision :%8ld\t", rep->re_stat.ets_collision);
- printf("transAb :%8ld\t", rep->re_stat.ets_transAb);
- printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense);
+ printf("collision :%8ld\t", rep->re_stat.ets_collision);
+ printf("transAb :%8ld\t", rep->re_stat.ets_transAb);
+ printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense);
- printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder);
- printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver);
- printf("CDheartbeat:%8ld\n", rep->re_stat.ets_CDheartbeat);
+ printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder);
+ printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver);
+ printf("CDheartbeat:%8ld\n", rep->re_stat.ets_CDheartbeat);
- printf("OWC :%8ld\t", rep->re_stat.ets_OWC);
+ printf("OWC :%8ld\t", rep->re_stat.ets_OWC);
- printf("re_flags = 0x%x\n", rep->re_flags);
+ printf("re_flags = 0x%x\n", rep->re_flags);
- printf(
- "TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
- rl_inw(rep->re_base_port, RL_TSAD),
- rl_inl(rep->re_base_port, RL_TSD0+0*4),
- rl_inl(rep->re_base_port, RL_TSD0+1*4),
- rl_inl(rep->re_base_port, RL_TSD0+2*4),
- rl_inl(rep->re_base_port, RL_TSD0+3*4));
- printf("tx_head %d, tx_tail %d, busy: %d %d %d %d\n",
- rep->re_tx_head, rep->re_tx_tail,
- rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,
- rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy);
- }
+ printf("TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ rl_inw(rep->re_base_port, RL_TSAD),
+ rl_inl(rep->re_base_port, RL_TSD0+0*4),
+ rl_inl(rep->re_base_port, RL_TSD0+1*4),
+ rl_inl(rep->re_base_port, RL_TSD0+2*4),
+ rl_inl(rep->re_base_port, RL_TSD0+3*4));
+ printf("tx_head %d, tx_tail %d, busy: %d %d %d %d\n",
+ rep->re_tx_head, rep->re_tx_tail,
+ rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,
+ rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy);
}
/*===========================================================================*
- * do_init *
+ * rl_init *
*===========================================================================*/
static void rl_init(mp)
message *mp;
{
static int first_time= 1;
- int port;
re_t *rep;
message reply_mess;
sys_setalarm(system_hz, 0);
}
- port = mp->DL_PORT;
- if (port < 0 || port >= RE_PORT_NR)
- {
- reply_mess.m_type= DL_CONF_REPLY;
- reply_mess.m3_i1= ENXIO;
- mess_reply(mp, &reply_mess);
- return;
- }
- rep= &re_table[port];
+ rep= &re_state;
if (rep->re_mode == REM_DISABLED)
{
/* This is the default, try to (re)locate the device. */
{
/* Probe failed, or the device is configured off. */
reply_mess.m_type= DL_CONF_REPLY;
- reply_mess.m3_i1= ENXIO;
+ reply_mess.DL_STAT= ENXIO;
mess_reply(mp, &reply_mess);
return;
}
if (mp->DL_MODE & DL_BROAD_REQ)
rep->re_flags |= REF_BROAD;
- rep->re_client = mp->m_source;
rl_rec_mode(rep);
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = mp->DL_PORT;
- reply_mess.m3_i2 = RE_PORT_NR;
- *(ether_addr_t *) reply_mess.m3_ca1 = rep->re_address;
+ reply_mess.DL_STAT = OK;
+ *(ether_addr_t *) reply_mess.DL_HWADDR = rep->re_address;
mess_reply(mp, &reply_mess);
}
*===========================================================================*/
static void rl_pci_conf()
{
- int i, h;
re_t *rep;
static char envvar[] = RL_ENVVAR "#";
static char envfmt[] = "*:d.d.d";
static char val[128];
long v;
- for (i= 0, rep= re_table; i<RE_PORT_NR; i++, rep++)
- {
- strcpy(rep->re_name, "rtl8139#0");
- rep->re_name[8] += i;
- rep->re_seen= FALSE;
- envvar[sizeof(RL_ENVVAR)-1]= '0'+i;
- if (0 == env_get_param(envvar, val, sizeof(val)) &&
- ! env_prefix(envvar, "pci")) {
- env_panic(envvar);
- }
- v= 0;
- (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
- rep->re_pcibus= v;
- v= 0;
- (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
- rep->re_pcidev= v;
- v= 0;
- (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
- rep->re_pcifunc= v;
+ rep= &re_state;
+
+ strcpy(rep->re_name, "rtl8139#0");
+ rep->re_name[8] += re_instance;
+ rep->re_seen= FALSE;
+ envvar[sizeof(RL_ENVVAR)-1]= '0'+re_instance;
+ if (0 == env_get_param(envvar, val, sizeof(val)) &&
+ ! env_prefix(envvar, "pci")) {
+ env_panic(envvar);
}
+ v= 0;
+ (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
+ rep->re_pcibus= v;
+ v= 0;
+ (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
+ rep->re_pcidev= v;
+ v= 0;
+ (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
+ rep->re_pcifunc= v;
pci_init();
- for (h= 1; h >= 0; h--) {
- for (i= 0, rep= re_table; i<RE_PORT_NR; i++, rep++)
- {
- if (((rep->re_pcibus | rep->re_pcidev |
- rep->re_pcifunc) != 0) != h)
- {
- continue;
- }
- if (rl_probe(rep, i))
- rep->re_seen= TRUE;
- }
- }
+ if (rl_probe(rep, re_instance))
+ rep->re_seen= TRUE;
}
/*===========================================================================*
#endif
/* Reset the device */
+#if VERBOSE
printf("rl_reset_hw: (before reset) port = 0x%x, RL_CR = 0x%x\n",
port, rl_inb(port, RL_CR));
+#endif
rl_outb(port, RL_CR, RL_CR_RST);
getuptime(&t0);
do {
if (!(rl_inb(port, RL_CR) & RL_CR_RST))
break;
} while (getuptime(&t1)==OK && (t1-t0) < system_hz);
+#if VERBOSE
printf("rl_reset_hw: (after reset) port = 0x%x, RL_CR = 0x%x\n",
port, rl_inb(port, RL_CR));
+#endif
if (rl_inb(port, RL_CR) & RL_CR_RST)
printf("rtl8139: reset failed to complete");
long v;
/* User defined ethernet address? */
- eakey[sizeof(RL_ENVVAR)-1]= '0' + (rep-re_table);
+ eakey[sizeof(RL_ENVVAR)-1]= '0' + re_instance;
port= rep->re_base_port;
rl_outl(port, RL_RCR, rcr);
}
-/*===========================================================================*
- * rl_readv *
- *===========================================================================*/
-static void rl_readv(const message *mp, int from_int, int vectored)
-{
- int i, j, n, o, s, s1, dl_port, re_client, count, size;
- port_t port;
- unsigned amount, totlen, packlen;
- u16_t d_start, d_end;
- u32_t l, rxstat = 0x12345678;
- re_t *rep;
- iovec_t *iovp;
- int cps;
-
- dl_port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= RE_PORT_NR)
- panic(" illegal port: %d", dl_port);
- rep= &re_table[dl_port];
- re_client= mp->DL_PROC;
- rep->re_client= re_client;
-
- if (rep->re_clear_rx)
- goto suspend; /* Buffer overflow */
-
- assert(rep->re_mode == REM_ENABLED);
- assert(rep->re_flags & REF_ENABLED);
-
- port= rep->re_base_port;
-
- /* Assume that the RL_CR_BUFE check was been done by rl_checks_ints
- */
- if (!from_int && (rl_inb(port, RL_CR) & RL_CR_BUFE))
- {
- /* Receive buffer is empty, suspend */
- goto suspend;
- }
-
- d_start= rl_inw(port, RL_CAPR) + RL_CAPR_DATA_OFF;
- d_end= rl_inw(port, RL_CBR) % RX_BUFSIZE;
-
- if (d_start >= RX_BUFSIZE)
- {
- printf("rl_readv: strange value in RL_CAPR: 0x%x\n",
- rl_inw(port, RL_CAPR));
- d_start %= RX_BUFSIZE;
- }
-
- if (d_end > d_start)
- amount= d_end-d_start;
- else
- amount= d_end+RX_BUFSIZE - d_start;
-
- rxstat = *(u32_t *) (rep->v_re_rx_buf + d_start);
-
- if (rep->re_clear_rx)
- {
-#if 0
- printf("rl_readv: late buffer overflow\n");
-#endif
- goto suspend; /* Buffer overflow */
- }
-
- /* Should convert from little endian to host byte order */
-
- if (!(rxstat & RL_RXS_ROK))
- {
- printf("rxstat = 0x%08lx\n", rxstat);
- printf("d_start: 0x%x, d_end: 0x%x, rxstat: 0x%lx\n",
- d_start, d_end, rxstat);
- panic("received packet not OK");
- }
- totlen= (rxstat >> RL_RXS_LEN_S);
- if (totlen < 8 || totlen > 2*ETH_MAX_PACK_SIZE)
- {
- /* Someting went wrong */
- printf(
- "rl_readv: bad length (%u) in status 0x%08lx at offset 0x%x\n",
- totlen, rxstat, d_start);
- printf(
- "d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%lx\n",
- d_start, d_end, totlen, rxstat);
- panic(NULL);
- }
-
-#if 0
- printf("d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%x\n",
- d_start, d_end, totlen, rxstat);
-#endif
-
- if (totlen+4 > amount)
- {
- printf("rl_readv: packet not yet ready\n");
- goto suspend;
- }
-
- /* Should subtract the CRC */
- packlen= totlen - ETH_CRC_SIZE;
-
- if (vectored)
- {
- int iov_offset = 0;
-
- size= 0;
- o= d_start+4;
- for (i= 0; i<count; i += IOVEC_NR,
- iov_offset += IOVEC_NR * sizeof(rep->re_iovec[0]))
- {
- n= IOVEC_NR;
- if (i+n > count)
- n= count-i;
-
- cps = sys_vircopy(re_client, D,
- (vir_bytes) mp->DL_ADDR + iov_offset,
- SELF, D, (vir_bytes) rep->re_iovec,
- n * sizeof(rep->re_iovec[0]));
- if (cps != OK)
- printf(
- "RTL8139: warning, sys_vircopy failed: %d (%d)\n",
- cps, __LINE__);
-
- for (j= 0, iovp= rep->re_iovec; j<n; j++, iovp++)
- {
- s= iovp->iov_size;
- if (size + s > packlen)
- {
- assert(packlen > size);
- s= packlen-size;
- }
-
- if (o >= RX_BUFSIZE)
- {
- o -= RX_BUFSIZE;
- assert(o < RX_BUFSIZE);
- }
-
- if (o+s > RX_BUFSIZE)
- {
- assert(o<RX_BUFSIZE);
- s1= RX_BUFSIZE-o;
-
- cps = sys_vircopy(SELF, D,
- (vir_bytes) rep->v_re_rx_buf+o,
- re_client, D, iovp->iov_addr,
- s1);
- if (cps != OK)
- printf(
- "RTL8139: warning, sys_vircopy failed: %d (%d)\n",
- cps, __LINE__);
- cps = sys_vircopy(SELF, D,
- (vir_bytes) rep->v_re_rx_buf,
- re_client, D,
- iovp->iov_addr+s1, s-s1);
- if (cps != OK)
- printf(
- "RTL8139: warning, sys_vircopy failed: %d (%d)\n",
- cps, __LINE__);
- }
- else
- {
- cps = sys_vircopy(SELF, D,
- (vir_bytes) rep->v_re_rx_buf+o,
- re_client, D, iovp->iov_addr,
- s);
- if (cps != OK)
- printf(
- "RTL8139: warning, sys_vircopy failed: %d (%d)\n",
- cps, __LINE__);
- }
-
- size += s;
- if (size == packlen)
- break;
- o += s;
- }
- if (size == packlen)
- break;
- }
- if (size < packlen)
- {
- assert(0);
- }
- }
- else
- {
- assert(0);
-#if 0
- size= mp->DL_COUNT;
- if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
- panic("invalid packet size: %d", size);
- if (OK != sys_umap(re_client, D, (vir_bytes)mp->DL_ADDR, size, &phys_user))
- panic("umap_local failed");
-
- p= rep->re_tx[tx_head].ret_buf;
- cps = sys_abscopy(phys_user, p, size);
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
-#endif
- }
-
- if (rep->re_clear_rx)
- {
- /* For some reason the receiver FIFO is not stopped when
- * the buffer is full.
- */
-#if 0
- printf("rl_readv: later buffer overflow\n");
-#endif
- goto suspend; /* Buffer overflow */
- }
-
- rep->re_stat.ets_packetR++;
- rep->re_read_s= packlen;
- rep->re_flags= (rep->re_flags & ~REF_READING) | REF_PACK_RECV;
-
- /* Avoid overflow in 16-bit computations */
- l= d_start;
- l += totlen+4;
- l= (l+3) & ~3; /* align */
- if (l >= RX_BUFSIZE)
- {
- l -= RX_BUFSIZE;
- assert(l < RX_BUFSIZE);
- }
- rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF);
-
- if (!from_int)
- reply(rep, OK, FALSE);
-
- return;
-
-suspend:
- if (from_int)
- {
- assert(rep->re_flags & REF_READING);
-
- /* No need to store any state */
- return;
- }
-
- rep->re_rx_mess= *mp;
- assert(!(rep->re_flags & REF_READING));
- rep->re_flags |= REF_READING;
-
- reply(rep, OK, FALSE);
-}
-
/*===========================================================================*
* rl_readv_s *
*===========================================================================*/
static void rl_readv_s(const message *mp, int from_int)
{
- int i, j, n, o, s, s1, dl_port, re_client, count, size;
+ int i, j, n, o, s, s1, count, size;
port_t port;
unsigned amount, totlen, packlen;
phys_bytes dst_phys;
int cps;
int iov_offset = 0;
- dl_port = mp->DL_PORT;
+ rep= &re_state;
+
+ rep->re_client= mp->m_source;
count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= RE_PORT_NR)
- panic(" illegal port: %d", dl_port);
- rep= &re_table[dl_port];
- re_client= mp->DL_PROC;
- rep->re_client= re_client;
if (rep->re_clear_rx)
goto suspend; /* Buffer overflow */
if (i+n > count)
n= count-i;
- cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset,
+ cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset,
(vir_bytes) rep->re_iovec_s,
n * sizeof(rep->re_iovec_s[0]), D);
if (cps != OK) {
}
#if 0
- if (sys_umap(re_client, D, iovp->iov_addr, s, &dst_phys) != OK)
+ if (sys_umap(mp->DL_ENDPT, D, iovp->iov_addr, s, &dst_phys) != OK)
panic("umap_local failed");
#endif
assert(o<RX_BUFSIZE);
s1= RX_BUFSIZE-o;
- cps = sys_safecopyto(re_client,
+ cps = sys_safecopyto(mp->DL_ENDPT,
iovp->iov_grant, 0,
(vir_bytes) rep->v_re_rx_buf+o, s1, D);
if (cps != OK) {
panic("rl_readv_s: sys_safecopyto failed: %d",
cps);
}
- cps = sys_safecopyto(re_client,
+ cps = sys_safecopyto(mp->DL_ENDPT,
iovp->iov_grant, s1,
(vir_bytes) rep->v_re_rx_buf, s-s1, S);
if (cps != OK) {
}
else
{
- cps = sys_safecopyto(re_client,
+ cps = sys_safecopyto(mp->DL_ENDPT,
iovp->iov_grant, 0,
(vir_bytes) rep->v_re_rx_buf+o, s, D);
if (cps != OK)
rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF);
if (!from_int)
- reply(rep, OK, FALSE);
+ reply(rep);
return;
assert(!(rep->re_flags & REF_READING));
rep->re_flags |= REF_READING;
- reply(rep, OK, FALSE);
-}
-
-/*===========================================================================*
- * rl_writev *
- *===========================================================================*/
-static void rl_writev(const message *mp, int from_int, int vectored)
-{
- phys_bytes phys_user;
- int i, j, n, s, port, count, size;
- int tx_head, re_client;
- re_t *rep;
- iovec_t *iovp;
- char *ret;
- int cps;
-
- port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (port < 0 || port >= RE_PORT_NR)
- panic("illegal port: %d", port);
- rep= &re_table[port];
- re_client= mp->DL_PROC;
- rep->re_client= re_client;
-
- assert(rep->re_mode == REM_ENABLED);
- assert(rep->re_flags & REF_ENABLED);
-
- if (from_int)
- {
- assert(rep->re_flags & REF_SEND_AVAIL);
- rep->re_flags &= ~REF_SEND_AVAIL;
- rep->re_send_int= FALSE;
- rep->re_tx_alive= TRUE;
- }
-
- tx_head= rep->re_tx_head;
- if (rep->re_tx[tx_head].ret_busy)
- {
- assert(!(rep->re_flags & REF_SEND_AVAIL));
- rep->re_flags |= REF_SEND_AVAIL;
- if (rep->re_tx[tx_head].ret_busy)
- goto suspend;
-
- /* Race condition, the interrupt handler may clear re_busy
- * before we got a chance to set REF_SEND_AVAIL. Checking
- * ret_busy twice should be sufficient.
- */
-#if 0
- printf("rl_writev: race detected\n");
-#endif
- rep->re_flags &= ~REF_SEND_AVAIL;
- rep->re_send_int= FALSE;
- }
-
- assert(!(rep->re_flags & REF_SEND_AVAIL));
- assert(!(rep->re_flags & REF_PACK_SENT));
-
- if (vectored)
- {
- int iov_offset = 0;
-
- size= 0;
- ret = rep->re_tx[tx_head].v_ret_buf;
- for (i= 0; i<count; i += IOVEC_NR,
- iov_offset += IOVEC_NR * sizeof(rep->re_iovec[0]))
- {
- n= IOVEC_NR;
- if (i+n > count)
- n= count-i;
- cps = sys_vircopy(re_client, D, ((vir_bytes) mp->DL_ADDR) + iov_offset,
- SELF, D, (vir_bytes) rep->re_iovec,
- n * sizeof(rep->re_iovec[0]));
-if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps);
-
- for (j= 0, iovp= rep->re_iovec; j<n; j++, iovp++)
- {
- s= iovp->iov_size;
- if (size + s > ETH_MAX_PACK_SIZE_TAGGED) {
- panic("invalid packet size");
- }
-
- if (OK != sys_umap(re_client, D, iovp->iov_addr, s, &phys_user))
- panic("umap_local failed");
-
- cps = sys_vircopy(re_client, D, iovp->iov_addr,
- SELF, D, (vir_bytes) ret, s);
- if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps);
- size += s;
- ret += s;
- }
- }
- if (size < ETH_MIN_PACK_SIZE)
- panic("invalid packet size: %d", size);
- }
- else
- {
- size= mp->DL_COUNT;
- if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
- panic("invalid packet size: %d", size);
- ret = rep->re_tx[tx_head].v_ret_buf;
- cps = sys_vircopy(re_client, D, (vir_bytes)mp->DL_ADDR,
- SELF, D, (vir_bytes) ret, size);
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
- }
-
- rl_outl(rep->re_base_port, RL_TSD0+tx_head*4,
- rep->re_ertxth | size);
- rep->re_tx[tx_head].ret_busy= TRUE;
-
- if (++tx_head == N_TX_BUF)
- tx_head= 0;
- assert(tx_head < RL_N_TX);
- rep->re_tx_head= tx_head;
-
- rep->re_flags |= REF_PACK_SENT;
-
- /* If the interrupt handler called, don't send a reply. The reply
- * will be sent after all interrupts are handled.
- */
- if (from_int)
- return;
- reply(rep, OK, FALSE);
- return;
-
-suspend:
-#if 0
- printf("rl_writev: head %d, tail %d, busy: %d %d %d %d\n",
- tx_head, rep->re_tx_tail,
- rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,
- rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy);
- printf("rl_writev: TSD: 0x%x, 0x%x, 0x%x, 0x%x\n",
- rl_inl(rep->re_base_port, RL_TSD0+0*4),
- rl_inl(rep->re_base_port, RL_TSD0+1*4),
- rl_inl(rep->re_base_port, RL_TSD0+2*4),
- rl_inl(rep->re_base_port, RL_TSD0+3*4));
-#endif
-
- if (from_int)
- panic("should not be sending");
-
- rep->re_tx_mess= *mp;
- reply(rep, OK, FALSE);
+ reply(rep);
}
/*===========================================================================*
*===========================================================================*/
static void rl_writev_s(const message *mp, int from_int)
{
- int i, j, n, s, port, count, size;
- int tx_head, re_client;
+ int i, j, n, s, count, size;
+ int tx_head;
re_t *rep;
iovec_s_t *iovp;
char *ret;
int cps;
int iov_offset = 0;
- port = mp->DL_PORT;
+ rep= &re_state;
+
+ rep->re_client= mp->m_source;
count = mp->DL_COUNT;
- if (port < 0 || port >= RE_PORT_NR)
- panic("illegal port: %d", port);
- rep= &re_table[port];
- re_client= mp->DL_PROC;
- rep->re_client= re_client;
assert(rep->re_mode == REM_ENABLED);
assert(rep->re_flags & REF_ENABLED);
{
assert(!(rep->re_flags & REF_SEND_AVAIL));
rep->re_flags |= REF_SEND_AVAIL;
- if (rep->re_tx[tx_head].ret_busy)
- goto suspend;
-
- /* Race condition, the interrupt handler may clear re_busy
- * before we got a chance to set REF_SEND_AVAIL. Checking
- * ret_busy twice should be sufficient.
- */
-#if 0
- printf("rl_writev: race detected\n");
-#endif
- rep->re_flags &= ~REF_SEND_AVAIL;
- rep->re_send_int= FALSE;
+ goto suspend;
}
assert(!(rep->re_flags & REF_SEND_AVAIL));
n= IOVEC_NR;
if (i+n > count)
n= count-i;
- cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset,
+ cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset,
(vir_bytes) rep->re_iovec_s,
n * sizeof(rep->re_iovec_s[0]), D);
if (cps != OK) {
if (size + s > ETH_MAX_PACK_SIZE_TAGGED) {
panic("invalid packet size");
}
- cps = sys_safecopyfrom(re_client, iovp->iov_grant, 0,
- (vir_bytes) ret, s, D);
+ cps = sys_safecopyfrom(mp->DL_ENDPT, iovp->iov_grant,
+ 0, (vir_bytes) ret, s, D);
if (cps != OK) {
panic("rl_writev_s: sys_safecopyfrom failed: %d", cps);
}
*/
if (from_int)
return;
- reply(rep, OK, FALSE);
+ reply(rep);
return;
suspend:
panic("should not be sending");
rep->re_tx_mess= *mp;
- reply(rep, OK, FALSE);
+ reply(rep);
}
/*===========================================================================*
if ((re_flags & REF_READING) &&
!(rl_inb(rep->re_base_port, RL_CR) & RL_CR_BUFE))
{
- if (rep->re_rx_mess.m_type == DL_READV)
- {
- rl_readv(&rep->re_rx_mess, TRUE /* from int */,
- TRUE /* vectored */);
- }
- else if (rep->re_rx_mess.m_type == DL_READV_S)
- {
- rl_readv_s(&rep->re_rx_mess, TRUE /* from int */);
- }
- else
- {
- assert(rep->re_rx_mess.m_type == DL_READ);
- rl_readv(&rep->re_rx_mess, TRUE /* from int */,
- FALSE /* !vectored */);
- }
+ rl_readv_s(&rep->re_rx_mess, TRUE /* from int */);
}
if (rep->re_clear_rx)
rl_clear_rx(rep);
if (rep->re_send_int)
{
- if (rep->re_tx_mess.m_type == DL_WRITEV)
- {
- rl_writev(&rep->re_tx_mess, TRUE /* from int */,
- TRUE /* vectored */);
- }
- else if (rep->re_tx_mess.m_type == DL_WRITEV_S)
- {
- rl_writev_s(&rep->re_tx_mess, TRUE /* from int */);
- }
- else
- {
- assert(rep->re_tx_mess.m_type == DL_WRITE);
- rl_writev(&rep->re_tx_mess, TRUE /* from int */,
- FALSE /* !vectored */);
- }
+ rl_writev_s(&rep->re_tx_mess, TRUE /* from int */);
}
if (rep->re_report_link)
rl_report_link(rep);
if (rep->re_flags & (REF_PACK_SENT | REF_PACK_RECV))
- reply(rep, OK, TRUE);
+ reply(rep);
}
/*===========================================================================*
}
}
-/*===========================================================================*
- * rl_getstat *
- *===========================================================================*/
-static void rl_getstat(mp)
-message *mp;
-{
- int r, port;
- eth_stat_t stats;
- re_t *rep;
-
- port = mp->DL_PORT;
- if (port < 0 || port >= RE_PORT_NR)
- panic("illegal port: %d", port);
- rep= &re_table[port];
- rep->re_client= mp->DL_PROC;
-
- assert(rep->re_mode == REM_ENABLED);
- assert(rep->re_flags & REF_ENABLED);
-
- stats= rep->re_stat;
-
- r = sys_datacopy(SELF, (vir_bytes) &stats, mp->DL_PROC,
- (vir_bytes) mp->DL_ADDR, sizeof(stats));
- if (r != OK)
- panic("rl_getstat: sys_datacopy failed: %d", r);
-
- mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= port;
- mp->DL_STAT= OK;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("rl_getstat: send failed: %d", r);
-}
-
/*===========================================================================*
* rl_getstat_s *
*===========================================================================*/
static void rl_getstat_s(mp)
message *mp;
{
- int r, port;
+ int r;
eth_stat_t stats;
re_t *rep;
- port = mp->DL_PORT;
- if (port < 0 || port >= RE_PORT_NR)
- panic("illegal port: %d", port);
- rep= &re_table[port];
- rep->re_client= mp->DL_PROC;
+ rep= &re_state;
assert(rep->re_mode == REM_ENABLED);
assert(rep->re_flags & REF_ENABLED);
stats= rep->re_stat;
- r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0,
+ r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0,
(vir_bytes) &stats, sizeof(stats), D);
if (r != OK)
panic("rl_getstat_s: sys_safecopyto failed: %d", r);
mp->m_type= DL_STAT_REPLY;
- mp->DL_PORT= port;
- mp->DL_STAT= OK;
r= send(mp->m_source, mp);
if (r != OK)
panic("rl_getstat_s: send failed: %d", r);
}
-
-/*===========================================================================*
- * rl_getname *
- *===========================================================================*/
-static void rl_getname(mp)
-message *mp;
-{
- int r;
-
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
- mp->m_type= DL_NAME_REPLY;
- r= send(mp->m_source, mp);
- if (r != OK)
- panic("rl_getname: send failed: %d", r);
-}
-
-
/*===========================================================================*
* reply *
*===========================================================================*/
-static void reply(rep, err, may_block)
+static void reply(rep)
re_t *rep;
-int err;
-int may_block;
{
message reply;
- int status;
+ int flags;
int r;
- clock_t now;
- status = 0;
+ flags = DL_NOFLAGS;
if (rep->re_flags & REF_PACK_SENT)
- status |= DL_PACK_SEND;
+ flags |= DL_PACK_SEND;
if (rep->re_flags & REF_PACK_RECV)
- status |= DL_PACK_RECV;
+ flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY;
- reply.DL_PORT = rep - re_table;
- reply.DL_PROC = rep->re_client;
- reply.DL_STAT = status | ((u32_t) err << 16);
+ reply.DL_FLAGS = flags;
reply.DL_COUNT = rep->re_read_s;
- if (OK != (r = getuptime(&now)))
- panic("getuptime() failed: %d", r);
- reply.DL_CLCK = now;
r= send(rep->re_client, &reply);
- if (r == ELOCKED && may_block)
- {
-#if 0
- printW(); printf("send locked\n");
-#endif
- return;
- }
-
if (r < 0) {
- printf("RTL8139 tried sending to %d, type %d\n", rep->re_client, reply.m_type);
+ printf("RTL8139 tried sending to %d, type %d\n",
+ rep->re_client, reply.m_type);
panic("send failed: %d", r);
}
}
#if 0
+/*===========================================================================*
+ * dump_phy *
+ *===========================================================================*/
static void dump_phy(rep)
re_t *rep;
{
}
#endif
+/*===========================================================================*
+ * do_hard_int *
+ *===========================================================================*/
static void do_hard_int(void)
{
- int i,s;
-
- for (i=0; i < RE_PORT_NR; i ++) {
+ int s;
- /* Run interrupt handler at driver level. */
- rl_handler( &re_table[i]);
+ /* Run interrupt handler at driver level. */
+ rl_handler(&re_state);
- /* Reenable interrupts for this hook. */
- if ((s=sys_irqenable(&re_table[i].re_hook_id)) != OK)
+ /* Reenable interrupts for this hook. */
+ if ((s=sys_irqenable(&re_state.re_hook_id)) != OK)
printf("RTL8139: error, couldn't enable interrupts: %d\n", s);
- }
}
/*===========================================================================*
static void rl_watchdog_f(tp)
timer_t *tp;
{
- int i;
re_t *rep;
/* Use a synchronous alarm instead of a watchdog timer. */
sys_setalarm(system_hz, 0);
- for (i= 0, rep = &re_table[0]; i<RE_PORT_NR; i++, rep++)
+ rep= &re_state;
+
+ if (rep->re_mode != REM_ENABLED)
+ return;
+ if (!(rep->re_flags & REF_SEND_AVAIL))
{
- if (rep->re_mode != REM_ENABLED)
- continue;
- if (!(rep->re_flags & REF_SEND_AVAIL))
- {
- /* Assume that an idle system is alive */
- rep->re_tx_alive= TRUE;
- continue;
- }
- if (rep->re_tx_alive)
- {
- rep->re_tx_alive= FALSE;
- continue;
- }
- printf("rl_watchdog_f: resetting port %d\n", i);
- printf(
- "TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
- rl_inw(rep->re_base_port, RL_TSAD),
- rl_inl(rep->re_base_port, RL_TSD0+0*4),
- rl_inl(rep->re_base_port, RL_TSD0+1*4),
- rl_inl(rep->re_base_port, RL_TSD0+2*4),
- rl_inl(rep->re_base_port, RL_TSD0+3*4));
- printf("tx_head %d, tx_tail %d, busy: %d %d %d %d\n",
- rep->re_tx_head, rep->re_tx_tail,
- rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,
- rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy);
- rep->re_need_reset= TRUE;
- rep->re_got_int= TRUE;
-
- check_int_events();
+ /* Assume that an idle system is alive */
+ rep->re_tx_alive= TRUE;
+ return;
+ }
+ if (rep->re_tx_alive)
+ {
+ rep->re_tx_alive= FALSE;
+ return;
}
+ printf("rl_watchdog_f: resetting instance %d\n", re_instance);
+ printf("TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ rl_inw(rep->re_base_port, RL_TSAD),
+ rl_inl(rep->re_base_port, RL_TSD0+0*4),
+ rl_inl(rep->re_base_port, RL_TSD0+1*4),
+ rl_inl(rep->re_base_port, RL_TSD0+2*4),
+ rl_inl(rep->re_base_port, RL_TSD0+3*4));
+ printf("tx_head %d, tx_tail %d, busy: %d %d %d %d\n",
+ rep->re_tx_head, rep->re_tx_tail,
+ rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,
+ rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy);
+ rep->re_need_reset= TRUE;
+ rep->re_got_int= TRUE;
+
+ check_int_events();
}
#if 0
#define printW() ((void)0)
#define vm_1phys2bus(p) (p)
-#define VERBOSE 1 /* display message during init */
-
#define RX_BUFSIZE RL_RCR_RBLEN_64K_SIZE
#define RX_BUFBITS RL_RCR_RBLEN_64K
#define N_TX_BUF RL_N_TX
-#define RE_PORT_NR 1 /* Minix */
-
/* I/O vectors are handled IOVEC_NR entries at a time. */
#define IOVEC_NR 16
#include "rtl8169.h"
-#define RE_PORT_NR 1 /* Minix */
-
#define IOVEC_NR 16 /* I/O vectors are handled IOVEC_NR entries at a time. */
#define RE_DTCC_VALUE 600 /* DTCC Update after every 10 minutes */
#define REF_BROAD 0x100
#define REF_ENABLED 0x200
-static re_t re_table[RE_PORT_NR];
+static re_t re_state;
+
+static int re_instance;
-static u16_t eth_ign_proto;
static timer_t rl_watchdog;
static unsigned my_inb(u16_t port)
_PROTOTYPE( static void rl_check_ints, (re_t *rep) );
_PROTOTYPE( static void rl_report_link, (re_t *rep) );
_PROTOTYPE( static void rl_do_reset, (re_t *rep) );
-_PROTOTYPE( static void rl_getstat, (message *mp) );
_PROTOTYPE( static void rl_getstat_s, (message *mp) );
-_PROTOTYPE( static void rl_getname, (message *mp) );
-_PROTOTYPE( static void reply, (re_t *rep, int err, int may_block) );
+_PROTOTYPE( static void reply, (re_t *rep) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
_PROTOTYPE( static void check_int_events, (void) );
_PROTOTYPE( static void do_hard_int, (void) );
PRIVATE message m;
PRIVATE int int_event_check; /* set to TRUE if events arrived */
-static char *progname;
u32_t system_hz;
/* SEF functions and variables. */
case DL_WRITEV_S: rl_writev_s(&m, FALSE); break;
case DL_READV_S: rl_readv_s(&m, FALSE); break;
case DL_CONF: rl_init(&m); break;
- case DL_GETSTAT: rl_getstat(&m); break;
case DL_GETSTAT_S: rl_getstat_s(&m); break;
- case DL_GETNAME: rl_getname(&m); break;
default:
panic("illegal message: %d", m.m_type);
}
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the rtl8169 driver. */
- re_t *rep;
long v;
system_hz = sys_hz();
- (progname = strrchr(env_argv[0], '/')) ? progname++
- : (progname = env_argv[0]);
-
v = 0;
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- eth_ign_proto = htons((u16_t) v);
+ (void) env_parse("instance", "d", 0, &v, 0, 255);
+ re_instance = (int) v;
- /* Claim buffer memory now under Minix, before MM takes it all. */
- for (rep = &re_table[0]; rep < re_table + RE_PORT_NR; rep++)
- rl_init_buf(rep);
+ /* Claim buffer memory now. */
+ rl_init_buf(&re_state);
/* Announce we are up! */
netdriver_announce();
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
- int i;
re_t *rep;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
- for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) {
- if (rep->re_mode != REM_ENABLED)
- continue;
+ rep = &re_state;
+ if (rep->re_mode == REM_ENABLED)
rl_outb(rep->re_base_port, RL_CR, 0);
- }
exit(0);
}
*===========================================================================*/
static void check_int_events(void)
{
- int i;
re_t *rep;
- for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) {
- if (rep->re_mode != REM_ENABLED)
- continue;
- if (!rep->re_got_int)
- continue;
- rep->re_got_int = 0;
- assert(rep->re_flags & REF_ENABLED);
- rl_check_ints(rep);
- }
+ rep = &re_state;
+
+ if (rep->re_mode != REM_ENABLED)
+ return;
+ if (!rep->re_got_int)
+ return;
+ rep->re_got_int = 0;
+ assert(rep->re_flags & REF_ENABLED);
+ rl_check_ints(rep);
}
static void rtl8169_update_stat(re_t *rep)
{
re_dtcc *dtcc;
re_t *rep;
- int i;
+
+ rep = &re_state;
printf("\n");
- for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) {
- if (rep->re_mode == REM_DISABLED)
- printf("Realtek RTL 8169 port %d is disabled\n", i);
+ if (rep->re_mode == REM_DISABLED)
+ printf("Realtek RTL 8169 instance %d is disabled\n",
+ re_instance);
- if (rep->re_mode != REM_ENABLED)
- continue;
+ if (rep->re_mode != REM_ENABLED)
+ return;
- rtl8169_update_stat(rep);
+ rtl8169_update_stat(rep);
- printf("Realtek RTL 8169 statistics of port %d:\n", i);
+ printf("Realtek RTL 8169 statistics of instance %d:\n", re_instance);
- printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr);
- printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr);
- printf("OVW :%8ld\n", rep->re_stat.ets_OVW);
+ printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr);
+ printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr);
+ printf("OVW :%8ld\n", rep->re_stat.ets_OVW);
- printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr);
- printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll);
- printf("missedP :%8ld\n", rep->re_stat.ets_missedP);
+ printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr);
+ printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll);
+ printf("missedP :%8ld\n", rep->re_stat.ets_missedP);
- printf("packetR :%8ld\t", rep->re_stat.ets_packetR);
- printf("packetT :%8ld\t", rep->re_stat.ets_packetT);
- printf("transDef :%8ld\n", rep->re_stat.ets_transDef);
+ printf("packetR :%8ld\t", rep->re_stat.ets_packetR);
+ printf("packetT :%8ld\t", rep->re_stat.ets_packetT);
+ printf("transDef :%8ld\n", rep->re_stat.ets_transDef);
- printf("collision :%8ld\t", rep->re_stat.ets_collision);
- printf("transAb :%8ld\t", rep->re_stat.ets_transAb);
- printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense);
+ printf("collision :%8ld\t", rep->re_stat.ets_collision);
+ printf("transAb :%8ld\t", rep->re_stat.ets_transAb);
+ printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense);
- printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder);
- printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver);
- printf("OWC :%8ld\n", rep->re_stat.ets_OWC);
- printf("interrupts :%8lu\n", rep->interrupts);
+ printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder);
+ printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver);
+ printf("OWC :%8ld\n", rep->re_stat.ets_OWC);
+ printf("interrupts :%8lu\n", rep->interrupts);
- printf("\nRealtek RTL 8169 Tally Counters:\n");
+ printf("\nRealtek RTL 8169 Tally Counters:\n");
- dtcc = rep->v_dtcc_buf;
+ dtcc = rep->v_dtcc_buf;
- if (dtcc->TxOk_high)
- printf("TxOk :%8ld%08ld\t", dtcc->TxOk_high, dtcc->TxOk_low);
- else
- printf("TxOk :%16lu\t", dtcc->TxOk_low);
+ if (dtcc->TxOk_high)
+ printf("TxOk :%8ld%08ld\t", dtcc->TxOk_high, dtcc->TxOk_low);
+ else
+ printf("TxOk :%16lu\t", dtcc->TxOk_low);
- if (dtcc->RxOk_high)
- printf("RxOk :%8ld%08ld\n", dtcc->RxOk_high, dtcc->RxOk_low);
- else
- printf("RxOk :%16lu\n", dtcc->RxOk_low);
+ if (dtcc->RxOk_high)
+ printf("RxOk :%8ld%08ld\n", dtcc->RxOk_high, dtcc->RxOk_low);
+ else
+ printf("RxOk :%16lu\n", dtcc->RxOk_low);
- if (dtcc->TxEr_high)
- printf("TxEr :%8ld%08ld\t", dtcc->TxEr_high, dtcc->TxEr_low);
- else
- printf("TxEr :%16ld\t", dtcc->TxEr_low);
+ if (dtcc->TxEr_high)
+ printf("TxEr :%8ld%08ld\t", dtcc->TxEr_high, dtcc->TxEr_low);
+ else
+ printf("TxEr :%16ld\t", dtcc->TxEr_low);
- printf("RxEr :%16ld\n", dtcc->RxEr);
+ printf("RxEr :%16ld\n", dtcc->RxEr);
- printf("Tx1Col :%16ld\t", dtcc->Tx1Col);
- printf("TxMCol :%16ld\n", dtcc->TxMCol);
+ printf("Tx1Col :%16ld\t", dtcc->Tx1Col);
+ printf("TxMCol :%16ld\n", dtcc->TxMCol);
- if (dtcc->RxOkPhy_high)
- printf("RxOkPhy :%8ld%08ld\t", dtcc->RxOkPhy_high, dtcc->RxOkPhy_low);
- else
- printf("RxOkPhy :%16ld\t", dtcc->RxOkPhy_low);
+ if (dtcc->RxOkPhy_high)
+ printf("RxOkPhy :%8ld%08ld\t", dtcc->RxOkPhy_high, dtcc->RxOkPhy_low);
+ else
+ printf("RxOkPhy :%16ld\t", dtcc->RxOkPhy_low);
- if (dtcc->RxOkBrd_high)
- printf("RxOkBrd :%8ld%08ld\n", dtcc->RxOkBrd_high, dtcc->RxOkBrd_low);
- else
- printf("RxOkBrd :%16ld\n", dtcc->RxOkBrd_low);
+ if (dtcc->RxOkBrd_high)
+ printf("RxOkBrd :%8ld%08ld\n", dtcc->RxOkBrd_high, dtcc->RxOkBrd_low);
+ else
+ printf("RxOkBrd :%16ld\n", dtcc->RxOkBrd_low);
- printf("RxOkMul :%16ld\t", dtcc->RxOkMul);
- printf("MissPkt :%16d\n", dtcc->MissPkt);
+ printf("RxOkMul :%16ld\t", dtcc->RxOkMul);
+ printf("MissPkt :%16d\n", dtcc->MissPkt);
- printf("\nRealtek RTL 8169 Miscellaneous Info:\n");
+ printf("\nRealtek RTL 8169 Miscellaneous Info:\n");
- printf("re_flags : 0x%08x\n", rep->re_flags);
- printf("tx_head :%8d busy %d\t",
- rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy);
- }
+ printf("re_flags : 0x%08x\n", rep->re_flags);
+ printf("tx_head :%8d busy %d\t",
+ rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy);
}
/*===========================================================================*
{
static int first_time = 1;
- int port;
re_t *rep;
message reply_mess;
sys_setalarm(system_hz, 0);
}
- port = mp->DL_PORT;
- if (port < 0 || port >= RE_PORT_NR) {
- reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = ENXIO;
- mess_reply(mp, &reply_mess);
- return;
- }
- rep = &re_table[port];
+ rep = &re_state;
if (rep->re_mode == REM_DISABLED) {
/* This is the default, try to (re)locate the device. */
rl_conf_hw(rep);
if (rep->re_mode == REM_DISABLED) {
/* Probe failed, or the device is configured off. */
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = ENXIO;
+ reply_mess.DL_STAT = ENXIO;
mess_reply(mp, &reply_mess);
return;
}
if (mp->DL_MODE & DL_BROAD_REQ)
rep->re_flags |= REF_BROAD;
- rep->re_client = mp->m_source;
rl_rec_mode(rep);
reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m3_i1 = mp->DL_PORT;
- reply_mess.m3_i2 = RE_PORT_NR;
- *(ether_addr_t *) reply_mess.m3_ca1 = rep->re_address;
+ reply_mess.DL_STAT = OK;
+ *(ether_addr_t *) reply_mess.DL_HWADDR = rep->re_address;
mess_reply(mp, &reply_mess);
}
*===========================================================================*/
static void rl_pci_conf()
{
- int i, h;
re_t *rep;
static char envvar[] = RL_ENVVAR "#";
static char envfmt[] = "*:d.d.d";
static char val[128];
long v;
- for (i = 0, rep = re_table; i < RE_PORT_NR; i++, rep++) {
- strcpy(rep->re_name, "rtl8169#0");
- rep->re_name[8] += i;
- rep->re_seen = FALSE;
- envvar[sizeof(RL_ENVVAR)-1] = '0' + i;
- if (0 == env_get_param(envvar, val, sizeof(val)) &&
- !env_prefix(envvar, "pci"))
- {
- env_panic(envvar);
- }
- v = 0;
- (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
- rep->re_pcibus = v;
- v = 0;
- (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
- rep->re_pcidev = v;
- v = 0;
- (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
- rep->re_pcifunc = v;
+ rep = &re_state;
+
+ strcpy(rep->re_name, "rtl8169#0");
+ rep->re_name[8] += re_instance;
+ rep->re_seen = FALSE;
+ envvar[sizeof(RL_ENVVAR)-1] = '0' + re_instance;
+ if (0 == env_get_param(envvar, val, sizeof(val)) &&
+ !env_prefix(envvar, "pci"))
+ {
+ env_panic(envvar);
}
+ v = 0;
+ (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
+ rep->re_pcibus = v;
+ v = 0;
+ (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
+ rep->re_pcidev = v;
+ v = 0;
+ (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
+ rep->re_pcifunc = v;
pci_init();
- for (h = 1; h >= 0; h--) {
- for (i = 0, rep = re_table; i < RE_PORT_NR; i++, rep++) {
- if (((rep->re_pcibus | rep->re_pcidev |
- rep->re_pcifunc) != 0) != h) {
- continue;
- }
- if (rl_probe(rep, i))
- rep->re_seen = TRUE;
- }
- }
+ if (rl_probe(rep, re_instance))
+ rep->re_seen = TRUE;
}
/*===========================================================================*
long v;
/* User defined ethernet address? */
- eakey[sizeof(RL_ENVVAR)-1] = '0' + (rep-re_table);
+ eakey[sizeof(RL_ENVVAR)-1] = '0' + re_instance;
port = rep->re_base_port;
*===========================================================================*/
static void rl_readv_s(const message *mp, int from_int)
{
- int i, j, n, s, dl_port, re_client, count, size, index;
+ int i, j, n, s, count, size, index;
port_t port;
unsigned totlen, packlen;
re_desc *desc;
int cps;
int iov_offset = 0;
- dl_port = mp->DL_PORT;
+ rep = &re_state;
+
+ rep->re_client = mp->m_source;
count = mp->DL_COUNT;
- if (dl_port < 0 || dl_port >= RE_PORT_NR)
- panic(" illegal port: %d", dl_port);
- rep = &re_table[dl_port];
- re_client = mp->DL_PROC;
- rep->re_client = re_client;
assert(rep->re_mode == REM_ENABLED);
assert(rep->re_flags & REF_ENABLED);
goto suspend; /* Receive buffer is empty, suspend */
index = rep->re_rx_head;
-readvs_test_loop:
desc = rep->re_rx_desc;
desc += index;
readvs_loop:
n = IOVEC_NR;
if (i + n > count)
n = count-i;
- cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset,
+ cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset,
(vir_bytes) rep->re_iovec_s,
n * sizeof(rep->re_iovec_s[0]), D);
if (cps != OK) {
s = packlen-size;
}
- cps = sys_safecopyto(re_client, iovp->iov_grant, 0,
+ cps = sys_safecopyto(mp->DL_ENDPT, iovp->iov_grant, 0,
(vir_bytes) rep->re_rx[index].v_ret_buf + size, s, D);
if (cps != OK)
panic("rl_readv_s: sys_safecopyto failed: %d", cps);
rep->re_flags = (rep->re_flags & ~REF_READING) | REF_PACK_RECV;
if (!from_int)
- reply(rep, OK, FALSE);
+ reply(rep);
return;
assert(!(rep->re_flags & REF_READING));
rep->re_flags |= REF_READING;
- reply(rep, OK, FALSE);
+ reply(rep);
}
/*===========================================================================*
*===========================================================================*/
static void rl_writev_s(const message *mp, int from_int)
{
- int i, j, n, s, port, count, size;
- int tx_head, re_client;
+ int i, j, n, s, count, size;
+ int tx_head;
re_t *rep;
iovec_s_t *iovp;
re_desc *desc;
int cps;
int iov_offset = 0;
- port = mp->DL_PORT;
+ rep = &re_state;
+
+ rep->re_client = mp->m_source;
count = mp->DL_COUNT;
- if (port < 0 || port >= RE_PORT_NR)
- panic("illegal port: %d", port);
- rep = &re_table[port];
- assert(mp);
- assert(port >= 0 && port < RE_PORT_NR);
assert(rep->setup);
- re_client = mp->DL_PROC;
- rep->re_client = re_client;
assert(rep->re_mode == REM_ENABLED);
assert(rep->re_flags & REF_ENABLED);
desc += tx_head;
if(!desc || !rep->re_tx_desc) {
- printf("desc 0x%lx, re_tx_desc 0x%lx, tx_head %d, setup %d\n",
+ printf("desc %p, re_tx_desc %p, tx_head %d, setup %d\n",
desc, rep->re_tx_desc, tx_head, rep->setup);
}
assert(desc);
-
if (rep->re_tx[tx_head].ret_busy) {
assert(!(rep->re_flags & REF_SEND_AVAIL));
rep->re_flags |= REF_SEND_AVAIL;
n = IOVEC_NR;
if (i + n > count)
n = count - i;
- cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset,
+ cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset,
(vir_bytes) rep->re_iovec_s,
n * sizeof(rep->re_iovec_s[0]), D);
if (cps != OK) {
if (size + s > ETH_MAX_PACK_SIZE_TAGGED)
panic("invalid packet size");
- cps = sys_safecopyfrom(re_client, iovp->iov_grant, 0,
- (vir_bytes) ret, s, D);
+ cps = sys_safecopyfrom(mp->DL_ENDPT, iovp->iov_grant,
+ 0, (vir_bytes) ret, s, D);
if (cps != OK) {
panic("rl_writev_s: sys_safecopyfrom failed: %d", cps);
}
*/
if (from_int)
return;
- reply(rep, OK, FALSE);
+ reply(rep);
return;
suspend:
panic("should not be sending");
rep->re_tx_mess = *mp;
- reply(rep, OK, FALSE);
+ reply(rep);
}
/*===========================================================================*
rl_report_link(rep);
if (rep->re_flags & (REF_PACK_SENT | REF_PACK_RECV))
- reply(rep, OK, TRUE);
+ reply(rep);
}
/*===========================================================================*
}
}
-/*===========================================================================*
- * rl_getstat *
- *===========================================================================*/
-static void rl_getstat(mp)
-message *mp;
-{
- int r, port;
- eth_stat_t stats;
- re_t *rep;
-
- port = mp->DL_PORT;
- if (port < 0 || port >= RE_PORT_NR)
- panic("illegal port: %d", port);
- rep = &re_table[port];
- rep->re_client = mp->DL_PROC;
-
- assert(rep->re_mode == REM_ENABLED);
- assert(rep->re_flags & REF_ENABLED);
-
- stats = rep->re_stat;
-
- r = sys_datacopy(SELF, (vir_bytes) &stats, mp->DL_PROC,
- (vir_bytes) mp->DL_ADDR, sizeof(stats));
- if (r != OK)
- panic("rl_getstat: sys_datacopy failed: %d", r);
-
- mp->m_type = DL_STAT_REPLY;
- mp->DL_PORT = port;
- mp->DL_STAT = OK;
- r = send(mp->m_source, mp);
- if (r != OK)
- panic("rl_getstat: send failed: %d", r);
-}
-
/*===========================================================================*
* rl_getstat_s *
*===========================================================================*/
static void rl_getstat_s(mp)
message *mp;
{
- int r, port;
+ int r;
eth_stat_t stats;
re_t *rep;
- port = mp->DL_PORT;
- if (port < 0 || port >= RE_PORT_NR)
- panic("illegal port: %d", port);
- rep = &re_table[port];
- rep->re_client = mp->DL_PROC;
+ rep = &re_state;
assert(rep->re_mode == REM_ENABLED);
assert(rep->re_flags & REF_ENABLED);
stats = rep->re_stat;
- r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0,
+ r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0,
(vir_bytes) &stats, sizeof(stats), D);
if (r != OK)
panic("rl_getstat_s: sys_safecopyto failed: %d", r);
mp->m_type = DL_STAT_REPLY;
- mp->DL_PORT = port;
- mp->DL_STAT = OK;
r = send(mp->m_source, mp);
if (r != OK)
panic("rl_getstat_s: send failed: %d", r);
}
-
-/*===========================================================================*
- * rl_getname *
- *===========================================================================*/
-static void rl_getname(mp)
-message *mp;
-{
- int r;
-
- strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
- mp->DL_NAME[sizeof(mp->DL_NAME)-1] = '\0';
- mp->m_type = DL_NAME_REPLY;
- r = send(mp->m_source, mp);
- if (r != OK)
- panic("rl_getname: send failed: %d", r);
-}
-
-
/*===========================================================================*
* reply *
*===========================================================================*/
-static void reply(rep, err, may_block)
+static void reply(rep)
re_t *rep;
-int err;
-int may_block;
{
message reply;
- int status;
+ int flags;
int r;
- clock_t now;
- status = 0;
+ flags = DL_NOFLAGS;
if (rep->re_flags & REF_PACK_SENT)
- status |= DL_PACK_SEND;
+ flags |= DL_PACK_SEND;
if (rep->re_flags & REF_PACK_RECV)
- status |= DL_PACK_RECV;
+ flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY;
- reply.DL_PORT = rep - re_table;
- reply.DL_PROC = rep->re_client;
- reply.DL_STAT = status | ((u32_t) err << 16);
+ reply.DL_FLAGS = flags;
reply.DL_COUNT = rep->re_read_s;
- if (OK != (r = getuptime(&now)))
- panic("getuptime() failed: %d", r);
- reply.DL_CLCK = now;
r = send(rep->re_client, &reply);
- if (r == ELOCKED && may_block) {
- printW(); printf("send locked\n");
- return;
- }
-
if (r < 0) {
printf("RTL8169 tried sending to %d, type %d\n",
rep->re_client, reply.m_type);
static void do_hard_int(void)
{
- int i, s;
-
- for (i = 0; i < RE_PORT_NR; i++) {
+ int s;
- /* Run interrupt handler at driver level. */
- rl_handler(&re_table[i]);
+ /* Run interrupt handler at driver level. */
+ rl_handler(&re_state);
- /* Reenable interrupts for this hook. */
- if ((s = sys_irqenable(&re_table[i].re_hook_id)) != OK)
- printf("RTL8169: error, couldn't enable interrupts: %d\n", s);
- }
+ /* Reenable interrupts for this hook. */
+ if ((s = sys_irqenable(&re_state.re_hook_id)) != OK)
+ printf("RTL8169: error, couldn't enable interrupts: %d\n", s);
}
/*===========================================================================*
static void rl_watchdog_f(tp)
timer_t *tp;
{
- int i;
re_t *rep;
/* Use a synchronous alarm instead of a watchdog timer. */
sys_setalarm(system_hz, 0);
- for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) {
- if (rep->re_mode != REM_ENABLED)
- continue;
+ rep = &re_state;
- /* Should collect statistics */
- if (!(++rep->dtcc_counter % RE_DTCC_VALUE))
- rtl8169_update_stat(rep);
+ if (rep->re_mode != REM_ENABLED)
+ return;
- if (!(rep->re_flags & REF_SEND_AVAIL)) {
- /* Assume that an idle system is alive */
- rep->re_tx_alive = TRUE;
- continue;
- }
- if (rep->re_tx_alive) {
- rep->re_tx_alive = FALSE;
- continue;
- }
- printf("rl_watchdog_f: resetting port %d mode 0x%x flags 0x%x\n",
- i, rep->re_mode, rep->re_flags);
- printf("tx_head :%8d busy %d\t",
- rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy);
- rep->re_need_reset = TRUE;
- rep->re_got_int = TRUE;
-
- check_int_events();
+ /* Should collect statistics */
+ if (!(++rep->dtcc_counter % RE_DTCC_VALUE))
+ rtl8169_update_stat(rep);
+
+ if (!(rep->re_flags & REF_SEND_AVAIL)) {
+ /* Assume that an idle system is alive */
+ rep->re_tx_alive = TRUE;
+ return;
+ }
+ if (rep->re_tx_alive) {
+ rep->re_tx_alive = FALSE;
+ return;
}
+ printf("rl_watchdog_f: resetting instance %d mode 0x%x flags 0x%x\n",
+ re_instance, rep->re_mode, rep->re_flags);
+ printf("tx_head :%8d busy %d\t",
+ rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy);
+ rep->re_need_reset = TRUE;
+ rep->re_got_int = TRUE;
+
+ check_int_events();
}
service $opt up /usr/sbin/$service "$@"
}
+get_eth_labels() {
+ # Filter out the non-vlan ethernet entries from inet.conf.
+ # Produce as output a list of "drivername_instancenr"-formatted labels.
+ # The first sed is taken from /bin as older GNU sed versions don't know '\t'.
+ /bin/sed 's/\t/ /g' /etc/inet.conf | \
+ sed -n 's/^ *eth[0-9][0-9]* *\([^ ][^ ]*\) *\([0-9][0-9]*\).*$/\1_\2/p' | \
+ grep -v '^vlan_'
+}
DAEMONS=/etc/rc.daemons
dd if=/dev/random of=$RANDOM_FILE bs=1024 count=1 2> /dev/null
fi
- # start only network drivers that are in use
- for driver in lance rtl8139 rtl8169 fxp e1000 dpeth dp8390 orinoco atl2 dec21140A
- do
- if grep " $driver " /etc/inet.conf > /dev/null 2>&1
- then
- eval arg=\$${driver}_arg
- if [ ! -z "$arg" ]; then arg="-args \"$arg\""; fi
- eval up $driver $arg -period 5HZ
- fi
+ # start network driver instances for all configured ethernet devices
+ for label in $(get_eth_labels); do
+ driver=$(echo $label | sed 's/\(.*\)_.*/\1/')
+ instance=$(echo $label | sed 's/.*_//')
+ eval arg=\$${label}_arg
+ if [ ! -z "$arg" ]; then arg=" $arg"; fi
+ arg="-args \"instance=$instance$arg\""
+ eval up $driver -label $label $arg -period 5HZ
done
up inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
upopt -n printer -dev /dev/lp -period 10HZ
#define DL_RS_BASE 0x280
/* Message types for data link layer requests. */
-#define DL_WRITE (DL_RQ_BASE + 3)
-#define DL_WRITEV (DL_RQ_BASE + 4)
-#define DL_READ (DL_RQ_BASE + 5)
-#define DL_READV (DL_RQ_BASE + 6)
-#define DL_CONF (DL_RQ_BASE + 7)
-#define DL_STOP (DL_RQ_BASE + 8)
-#define DL_GETSTAT (DL_RQ_BASE + 9)
-#define DL_GETNAME (DL_RQ_BASE +10)
-#define DL_WRITEV_S (DL_RQ_BASE +11)
-#define DL_READV_S (DL_RQ_BASE +12)
-#define DL_GETSTAT_S (DL_RQ_BASE +13)
+#define DL_CONF (DL_RQ_BASE + 0)
+#define DL_GETSTAT_S (DL_RQ_BASE + 1)
+#define DL_WRITEV_S (DL_RQ_BASE + 2)
+#define DL_READV_S (DL_RQ_BASE + 3)
/* Message type for data link layer replies. */
-#define DL_CONF_REPLY (DL_RS_BASE + 20)
-#define DL_TASK_REPLY (DL_RS_BASE + 21)
-#define DL_NAME_REPLY (DL_RS_BASE + 22)
-#define DL_STAT_REPLY (DL_RS_BASE + 23)
+#define DL_CONF_REPLY (DL_RS_BASE + 0)
+#define DL_STAT_REPLY (DL_RS_BASE + 1)
+#define DL_TASK_REPLY (DL_RS_BASE + 2)
/* Field names for data link layer messages. */
-#define DL_PORT m2_i1
-#define DL_PROC m2_i2 /* endpoint */
+#define DL_ENDPT m2_i2
#define DL_COUNT m2_i3
#define DL_MODE m2_l1
-#define DL_CLCK m2_l2
-#define DL_ADDR m2_p1
-#define DL_STAT m2_l1
+#define DL_FLAGS m2_l1
#define DL_GRANT m2_l2
-#define DL_NAME m3_ca1
+#define DL_STAT m3_i1
+#define DL_HWADDR m3_ca1
-/* Bits in 'DL_STAT' field of DL replies. */
+/* Bits in 'DL_FLAGS' field of DL replies. */
+# define DL_NOFLAGS 0x00
# define DL_PACK_SEND 0x01
# define DL_PACK_RECV 0x02
-# define DL_READ_IP 0x04
/* Bits in 'DL_MODE' field of DL requests. */
# define DL_NOMODE 0x0
-# define DL_PROMISC_REQ 0x2
-# define DL_MULTI_REQ 0x4
-# define DL_BROAD_REQ 0x8
+# define DL_PROMISC_REQ 0x1
+# define DL_MULTI_REQ 0x2
+# define DL_BROAD_REQ 0x4
/*===========================================================================*
* SYSTASK request types and field names *
/* asynchio.h - Asynchronous I/O Author: Kees J. Bot
- * 26 Jan 1995
- * This is just a fake async I/O library to be used for programs
- * written for Minix-vmd that must also run under standard Minix.
- * This limits the number of ugly #ifdefs somewhat. The programs must
- * be restricted to performing just one service, of course.
+ * 7 Jul 1997
+ * Minix-vmd compatible asynchio(3) using BSD select(2).
*/
#ifndef _SYS__ASYNCHIO_H
#define _SYS__ASYNCHIO_H
-#ifndef _ANSI_H
-#include <ansi.h>
-#endif
+#include <sys/select.h> /* for FD_SETSIZE */
-#include <sys/time.h>
+#define SEL_READ 0 /* Code for a read. */
+#define SEL_WRITE 1 /* Code for a write. */
+#define SEL_EXCEPT 2 /* Code for some exception. */
+#define SEL_NR 3 /* Number of codes. */
+
+struct _asynfd {
+ int afd_seen; /* Set if we manage this descriptor. */
+ int afd_flags; /* File flags by fcntl(fd, F_GETFL). */
+ int afd_state[SEL_NR]; /* Operation state. */
+};
typedef struct {
- char state;
- char op;
- char fd;
- char req;
- void *data;
- ssize_t count;
- int errno;
+ int asyn_more; /* Set if more to do before blocking. */
+ struct _asynfd asyn_afd[FD_SETSIZE];
+ fd_set asyn_fdset[SEL_NR]; /* Select() fd sets. */
} asynchio_t;
-#define ASYN_NONBLOCK 0x01
+#define ASYN_INPROGRESS EAGAIN /* Errno code telling "nothing yet." */
+#define ASYN_NONBLOCK 0x01 /* If asyn_wait() mustn't block. */
-#define ASYN_INPROGRESS EINPROGRESS
+struct timeval;
void asyn_init(asynchio_t *_asyn);
ssize_t asyn_read(asynchio_t *_asyn, int _fd, void *_buf, size_t _len);
ssize_t asyn_write(asynchio_t *_asyn, int _fd, const void *_buf, size_t _len);
-int asyn_ioctl(asynchio_t *_asyn, int _fd, unsigned long _request, void *_data);
+int asyn_special(asynchio_t *_asyn, int _fd, int _op);
+int asyn_result(asynchio_t *_asyn, int _fd, int _op, int _result);
int asyn_wait(asynchio_t *_asyn, int _flags, struct timeval *to);
+int asyn_cancel(asynchio_t *_asyn, int _fd, int _op);
+int asyn_pending(asynchio_t *_asyn, int _fd, int _op);
int asyn_synch(asynchio_t *_asyn, int _fd);
int asyn_close(asynchio_t *_asyn, int _fd);
CPPFLAGS+=-O -D_MINIX -D_POSIX_SOURCE
.include "${.CURDIR}/ansi/Makefile.inc"
-.include "${.CURDIR}/wchar/Makefile.inc"
+.include "${.CURDIR}/asyn/Makefile.inc"
.include "${.CURDIR}/ip/Makefile.inc"
.include "${.CURDIR}/math/Makefile.inc"
.include "${.CURDIR}/other/Makefile.inc"
.include "${.CURDIR}/stdtime/Makefile.inc"
.include "${.CURDIR}/syscall/Makefile.inc"
.include "${.CURDIR}/sysvipc/Makefile.inc"
+.include "${.CURDIR}/wchar/Makefile.inc"
.include "${.CURDIR}/arch/${ARCH}/int64/Makefile.inc"
.include "${.CURDIR}/arch/${ARCH}/misc/Makefile.inc"
--- /dev/null
+# ansi sources
+.PATH: ${.CURDIR}/asyn
+
+SRCS+= \
+ asyn_cancel.c \
+ asyn_close.c \
+ asyn_init.c \
+ asyn_pending.c \
+ asyn_read.c \
+ asyn_synch.c \
+ asyn_wait.c \
+ asyn_write.c
--- /dev/null
+/* asyn.h - async I/O
+ * Author: Kees J. Bot
+ * 7 Jul 1997
+ * Minix-vmd compatible asynchio(3) using BSD select(2).
+ */
+#define nil 0
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/asynchio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+typedef struct _asynfd asynfd_t;
+
+typedef enum state { IDLE, WAITING, PENDING } state_t;
--- /dev/null
+/* asyn_cancel() - cancel an asynch operation Author: Kees J. Bot
+ * 7 Jul 1997
+ */
+#include "asyn.h"
+
+int asyn_cancel(asynchio_t *asyn, int fd, int op)
+/* Cancel an asynchronous operation if one is in progress. (This is easy with
+ * select(2), because no operation is actually happening.)
+ */
+{
+ asynfd_t *afd;
+
+ if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; }
+ afd= &asyn->asyn_afd[fd];
+
+ if (afd->afd_state[op] == WAITING) {
+ afd->afd_state[op]= IDLE;
+ FD_CLR(fd, &asyn->asyn_fdset[SEL_READ]);
+ }
+ return 0;
+}
--- /dev/null
+/* asyn_close() - forcefully forget about a file descriptor
+ * Author: Kees J. Bot
+ * 7 Jul 1997
+ */
+#include "asyn.h"
+
+int asyn_close(asynchio_t *asyn, int fd)
+/* Stop caring about any async operations on this file descriptor. */
+{
+ asynfd_t *afd;
+ int op;
+
+ if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; }
+
+ afd= &asyn->asyn_afd[fd];
+
+ for (op= 0; op < SEL_NR; op++) {
+ afd->afd_state[op]= IDLE;
+ FD_CLR(fd, &asyn->asyn_fdset[op]);
+ }
+ afd->afd_seen= 0;
+ asyn->asyn_more++;
+ return 0;
+}
--- /dev/null
+/* asyn_init() Author: Kees J. Bot
+ * 7 Jul 1997
+ */
+#include "asyn.h"
+
+void asyn_init(asynchio_t *asyn)
+{
+ memset(asyn, 0, sizeof(*asyn));
+}
--- /dev/null
+/* asyn_pending() - any results pending? Author: Kees J. Bot
+ * 7 Jul 1997
+ */
+#include "asyn.h"
+
+int asyn_pending(asynchio_t *asyn, int fd, int op)
+/* Check if a result of an operation is pending. (This is easy with
+ * select(2), because no operation is actually happening.)
+ */
+{
+ if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; }
+
+ return 0;
+}
--- /dev/null
+/* asyn_read() Author: Kees J. Bot
+ * 7 Jul 1997
+ */
+#include "asyn.h"
+#include <signal.h>
+
+ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len)
+/* Asynchronous read(). Try if a read can be done, if not then set a flag
+ * indicating that select(2) should look out for it. Returns like a normal
+ * read or returns -1 with errno set to EAGAIN.
+ */
+{
+ asynfd_t *afd;
+
+ /* Asyn_wait() may block if this counter equals zero indicating that
+ * all of the asyn_* functions are "in progress".
+ */
+ asyn->asyn_more++;
+
+ if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; }
+ afd= &asyn->asyn_afd[fd];
+
+ /* If this is the first async call on this filedescriptor then
+ * remember its file flags.
+ */
+ if (!afd->afd_seen) {
+ if ((afd->afd_flags= fcntl(fd, F_GETFL)) < 0) return -1;
+ afd->afd_seen= 1;
+ }
+
+ /* Try to read if I/O is pending. */
+ if (afd->afd_state[SEL_READ] == PENDING) {
+ sigset_t mask;
+ ssize_t result;
+ int err;
+
+ sigemptyset(&mask);
+ if (sigprocmask(SIG_SETMASK, &mask, &mask) < 0) return -1;
+ (void) fcntl(fd, F_SETFL, afd->afd_flags | O_NONBLOCK);
+
+ /* Try the actual read. */
+ result= read(fd, buf, len);
+ err= errno;
+
+ (void) fcntl(fd, F_SETFL, afd->afd_flags);
+ (void) sigprocmask(SIG_SETMASK, &mask, nil);
+
+ errno= err;
+ if (result != -1 || errno != EAGAIN) {
+ afd->afd_state[SEL_READ]= IDLE;
+ return result;
+ }
+ }
+
+ /* Record this read as "waiting". */
+ afd->afd_state[SEL_READ]= WAITING;
+ FD_SET(fd, &asyn->asyn_fdset[SEL_READ]);
+ errno= EAGAIN;
+ asyn->asyn_more--;
+ return -1;
+}
--- /dev/null
+/* asyn_special(), asyn_result() Author: Kees J. Bot
+ * 8 Jul 1997
+ */
+#include "asyn.h"
+#include <signal.h>
+
+/* Saved signal mask between asyn_special() and asyn_result(). */
+static sigset_t mask;
+
+int asyn_special(asynchio_t *asyn, int fd, int op)
+/* Wait for an operation. This is an odd one out compared to asyn_read()
+ * and asyn_write(). It does not do an operation itself, but together with
+ * asyn_result() it is a set of brackets around a system call xxx that has
+ * no asyn_xxx() for itself. It can be used to build an asyn_accept() or
+ * asyn_connect() for instance. (Minix-vmd has asyn_ioctl() instead,
+ * which is used for any other event like TCP/IP listen/connect. BSD has
+ * a myriad of calls that can't be given an asyn_xxx() counterpart each.)
+ * Asyn_special() returns -1 for "forget it", 0 for "try it", and 1 for
+ * "very first call, maybe you should try it once, maybe not". Errno is
+ * set to EAGAIN if the result is -1 or 1. After trying the system call
+ * make sure errno equals EAGAIN if the call is still in progress and call
+ * asyn_result with the result of the system call. Asyn_result() must be
+ * called if asyn_special() returns 0 or 1.
+ *
+ * Example use:
+ *
+ * int asyn_accept(asynchio_t *asyn, int s, struct sockaddr *addr, int *addrlen)
+ * {
+ * int r;
+ * if ((r= asyn_special(asyn, fd, SEL_READ)) < 0) return -1;
+ * r= r == 0 ? accept(fd, addr, addrlen) : -1;
+ * return asyn_result(asyn, fd, SEL_READ, r);
+ * }
+ *
+ * int asyn_connect(asynchio_t *asyn, int s, struct sockaddr *name, int namelen)
+ * {
+ * int r;
+ * if ((r= asyn_special(asyn, fd, SEL_WRITE)) < 0) return -1;
+ * if (r == 1 && (r= connect(fd, name, namelen)) < 0) {
+ * if (errno == EINPROGRESS) errno= EAGAIN;
+ * }
+ * return asyn_result(asyn, fd, SEL_WRITE, r);
+ * }
+ */
+{
+ asynfd_t *afd;
+ int seen;
+
+ asyn->asyn_more++;
+
+ if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; }
+ afd= &asyn->asyn_afd[fd];
+
+ /* If this is the first async call on this filedescriptor then
+ * remember its file flags.
+ */
+ if (!(seen= afd->afd_seen)) {
+ if ((afd->afd_flags= fcntl(fd, F_GETFL)) < 0) return -1;
+ afd->afd_seen= 1;
+ }
+
+ /* Try to read if I/O is pending. */
+ if (!seen || afd->afd_state[op] == PENDING) {
+ sigemptyset(&mask);
+ if (sigprocmask(SIG_SETMASK, &mask, &mask) < 0) return -1;
+ (void) fcntl(fd, F_SETFL, afd->afd_flags | O_NONBLOCK);
+
+ /* Let the caller try the system call. */
+ errno= EAGAIN;
+ return seen ? 0 : 1;
+ }
+
+ /* Record this read as "waiting". */
+ afd->afd_state[op]= WAITING;
+ FD_SET(fd, &asyn->asyn_fdset[op]);
+ errno= EAGAIN;
+ asyn->asyn_more--;
+ return -1;
+}
+
+int asyn_result(asynchio_t *asyn, int fd, int op, int result)
+/* The caller has tried the system call with the given result. Finish up. */
+{
+ int err;
+ asynfd_t *afd= &asyn->asyn_afd[fd];
+
+ err= errno;
+
+ (void) fcntl(fd, F_SETFL, afd->afd_flags);
+ (void) sigprocmask(SIG_SETMASK, &mask, nil);
+
+ errno= err;
+ if (result != -1 || errno != EAGAIN) {
+ afd->afd_state[op]= IDLE;
+ return result;
+ }
+
+ /* Record this operation as "waiting". */
+ afd->afd_state[op]= WAITING;
+ FD_SET(fd, &asyn->asyn_fdset[op]);
+ errno= EAGAIN;
+ asyn->asyn_more--;
+ return -1;
+}
--- /dev/null
+/* asyn_synch() - step back to synch Author: Kees J. Bot
+ * 7 Jul 1997
+ */
+#include "asyn.h"
+
+int asyn_synch(asynchio_t *asyn, int fd)
+/* No more asynchronous operations on this file descriptor. */
+{
+ asynfd_t *afd;
+ int flags;
+ int op;
+
+ if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; }
+ afd= &asyn->asyn_afd[fd];
+
+ for (op= 0; op < SEL_NR; op++) {
+ if (afd->afd_state[op] != IDLE) {
+ errno= EAGAIN;
+ return -1;
+ }
+ }
+
+ /* Make sure the file flags are as they once were. */
+ if (afd->afd_seen && fcntl(fd, F_SETFL, afd->afd_flags) < 0) return -1;
+ afd->afd_seen= 0;
+ return 0;
+}
--- /dev/null
+/* asyn_wait() - wait for asynch operations Author: Kees J. Bot
+ * 7 Jul 1997
+ */
+#define DEBUG 0
+
+#include "asyn.h"
+#include <time.h>
+#if DEBUG
+#include <stdio.h>
+#endif
+
+#define TBOUND_MIN 1
+#define TBOUND_MAX 16
+
+int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
+/* Wait for one or more nonblocking operations to return a result. */
+{
+ int r;
+ static struct timeval zero_time;
+ struct timeval t;
+ static time_t tbound= TBOUND_MIN;
+
+ /* Are there more things to do before we can block? */
+ if (asyn->asyn_more > 0) { asyn->asyn_more= 0; return 0; }
+
+ if (flags & ASYN_NONBLOCK) {
+ /* Don't block by using a zero second timeout. */
+ to= &zero_time;
+ } else
+ if (to != nil) {
+ /* asyn_wait() uses an absolute time. */
+ if (to->tv_usec >= 1000000L) {
+ to->tv_sec+= to->tv_usec / 1000000L;
+ to->tv_usec%= 1000000L;
+ }
+ (void) gettimeofday(&t, nil);
+ if (t.tv_sec > to->tv_sec || (t.tv_sec == to->tv_sec
+ && t.tv_usec >= to->tv_usec)) {
+ to= &zero_time;
+ } else {
+ t.tv_sec= to->tv_sec - t.tv_sec;
+ t.tv_usec= to->tv_usec - t.tv_usec;
+ if (t.tv_usec < 0) {
+ t.tv_sec--;
+ t.tv_usec+= 1000000L;
+ }
+ to= &t;
+ }
+
+ /* Don't sleep too long, we don't trust select(). */
+ if (to->tv_sec > tbound) goto bound;
+ } else {
+ bound:
+ /* No timeout? Don't hang in (buggy?) select() forever. */
+ to= &t;
+ t.tv_sec= tbound;
+ t.tv_usec= 0;
+ }
+
+#if DEBUG
+ {
+ int op;
+
+ fprintf(stderr, "select: ");
+ for (op= 0; op < SEL_NR; op++) {
+ fd_set *fdsetp= &asyn->asyn_fdset[op];
+ int fd;
+
+ for (fd= 0; fd < FD_SETSIZE; fd++) {
+ if (FD_ISSET(fd, fdsetp)) {
+ asyn->asyn_afd[fd].afd_state[op]=
+ PENDING;
+ fprintf(stderr, "%d%c", fd, "rwx"[op]);
+ }
+ }
+ }
+ fflush(stderr);
+ }
+#endif
+ r= select(FD_SETSIZE, &asyn->asyn_fdset[SEL_READ],
+ &asyn->asyn_fdset[SEL_WRITE],
+ &asyn->asyn_fdset[SEL_EXCEPT], to);
+#if DEBUG
+ fprintf(stderr, " (%d) ", r);
+#endif
+ if (r > 0) {
+ /* An event occurred on one or more file descriptors. */
+ int op;
+
+ for (op= 0; op < SEL_NR; op++) {
+ fd_set *fdsetp= &asyn->asyn_fdset[op];
+ int fd;
+
+ for (fd= 0; fd < FD_SETSIZE; fd++) {
+ if (FD_ISSET(fd, fdsetp)) {
+ asyn->asyn_afd[fd].afd_state[op]=
+ PENDING;
+#if DEBUG
+ fprintf(stderr, "%d%c", fd, "rwx"[op]);
+#endif
+ }
+ }
+ }
+ tbound= TBOUND_MIN;
+ } else
+ if (r == 0) {
+ /* If nothing happened then let the time boundary slip a bit. */
+ if (tbound < TBOUND_MAX) tbound <<= 1;
+ }
+#if DEBUG
+ fputc('\n', stderr);
+#endif
+
+ FD_ZERO(&asyn->asyn_fdset[SEL_READ]);
+ FD_ZERO(&asyn->asyn_fdset[SEL_WRITE]);
+ FD_ZERO(&asyn->asyn_fdset[SEL_EXCEPT]);
+
+ return r == 0 ? (errno= EINTR, -1) : r;
+}
--- /dev/null
+/* asyn_write() Author: Kees J. Bot
+ * 7 Jul 1997
+ */
+#include "asyn.h"
+#include <signal.h>
+
+ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len)
+/* Nonblocking write(). (See asyn_read()). */
+{
+ asynfd_t *afd;
+ ssize_t result;
+
+ asyn->asyn_more++;
+
+ if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; }
+ afd= &asyn->asyn_afd[fd];
+
+ if (!afd->afd_seen) {
+ if ((afd->afd_flags= fcntl(fd, F_GETFL)) < 0) return -1;
+ afd->afd_seen= 1;
+ }
+
+ if (afd->afd_state[SEL_WRITE] == PENDING) {
+ sigset_t mask;
+ ssize_t result;
+ int err;
+
+ sigemptyset(&mask);
+ if (sigprocmask(SIG_SETMASK, &mask, &mask) < 0) return -1;
+ (void) fcntl(fd, F_SETFL, afd->afd_flags | O_NONBLOCK);
+
+ result= write(fd, buf, len);
+ err= errno;
+
+ (void) fcntl(fd, F_SETFL, afd->afd_flags);
+ (void) sigprocmask(SIG_SETMASK, &mask, nil);
+
+ errno= err;
+ if (result != -1 || errno != EAGAIN) {
+ afd->afd_state[SEL_WRITE]= IDLE;
+ return result;
+ }
+ }
+
+ afd->afd_state[SEL_WRITE]= WAITING;
+ FD_SET(fd, &asyn->asyn_fdset[SEL_WRITE]);
+ errno= EAGAIN;
+ asyn->asyn_more--;
+ return -1;
+}
_vm_set_priv.c \
_vm_update.c \
_vm_query_exit.c \
- asynchio.c \
basename.c \
bcmp.c \
bcopy.c \
+++ /dev/null
-/* asyn_init(), asyn_read(), asyn_write(), asyn_ioctl(),
- * asyn_wait(), asyn_synch(), asyn_close()
- * Author: Kees J. Bot
- * 26 Jan 1995
- * Thise are just stub routines that are call compatible with
- * the asynchio(3) library of Minix-vmd. See asynchio.h.
- */
-#define alarm _alarm
-#define ioctl _ioctl
-#define read _read
-#define sigaction _sigaction
-#define sigfillset _sigfillset
-#define time _time
-#define write _write
-#include <lib.h>
-#include <time.h>
-#include <sys/ioctl.h>
-#include <sys/asynchio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-
-#define IO_IDLE 0
-#define IO_INPROGRESS 1
-#define IO_RESULT 2
-
-#define OP_NOOP 0
-#define OP_READ 1
-#define OP_WRITE 2
-#define OP_IOCTL 3
-
-static asynchio_t *asyn_current;
-
-void asyn_init(asynchio_t *asyn)
-{
- asyn->state= IO_IDLE;
- asyn->op= OP_NOOP;
-}
-
-static ssize_t operation(int op, asynchio_t *asyn, int fd, int req,
- void *data, ssize_t count)
-{
- switch (asyn->state) {
- case IO_INPROGRESS:
- if (asyn_current != asyn && asyn->op != op) abort();
- /*FALL THROUGH*/
- case IO_IDLE:
- asyn_current= asyn;
- asyn->op= op;
- asyn->fd= fd;
- asyn->req= req;
- asyn->data= data;
- asyn->count= count;
- asyn->state= IO_INPROGRESS;
- errno= EINPROGRESS;
- return -1;
- case IO_RESULT:
- if (asyn_current != asyn && asyn->op != op) abort();
- errno= asyn->errno;
- return asyn->count;
- }
-}
-
-ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len)
-{
- return operation(OP_READ, asyn, fd, 0, buf, len);
-}
-
-ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len)
-{
- return operation(OP_WRITE, asyn, fd, 0, (void *) buf, len);
-}
-
-int asyn_ioctl(asynchio_t *asyn, int fd, unsigned long request, void *data)
-{
- return operation(OP_IOCTL, asyn, fd, request, data, 0);
-}
-
-static void time_out(int sig)
-{
- alarm(1);
-}
-
-int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
-{
- time_t now;
- unsigned old_timer, new_timer;
- struct sigaction old_sa, new_sa;
-
- if (asyn_current != asyn) abort();
- if (flags & ASYN_NONBLOCK) abort();
-
- if (asyn->state == IO_RESULT) {
- asyn->state= IO_IDLE;
- asyn->op= OP_NOOP;
- return 0;
- }
-
- if (to != NULL) {
- now= time(NULL);
- if (to->tv_sec <= now) { errno= EINTR; return -1; }
- old_timer= alarm(0);
- new_sa.sa_handler= time_out;
- sigfillset(&new_sa.sa_mask);
- new_sa.sa_flags= 0;
- sigaction(SIGALRM, &new_sa, &old_sa);
- new_timer= to->tv_sec - now;
- if (new_timer < old_timer) {
- new_timer= old_timer;
- }
- alarm(new_timer);
- }
- switch (asyn->op) {
- case OP_NOOP:
- asyn->count= pause();
- asyn->errno= errno;
- case OP_READ:
- asyn->count= read(asyn->fd, asyn->data, asyn->count);
- asyn->errno= errno;
- break;
- case OP_WRITE:
- asyn->count= write(asyn->fd, asyn->data, asyn->count);
- asyn->errno= errno;
- break;
- case OP_IOCTL:
- asyn->count= ioctl(asyn->fd, asyn->req, asyn->data);
- asyn->errno= errno;
- break;
- }
- if (to != NULL) {
- alarm(0);
- sigaction(SIGALRM, &old_sa, (struct sigaction *)0);
- alarm(old_timer);
- }
-
- if (asyn->count == -1 && asyn->errno == EINTR) {
- errno= EINTR;
- return -1;
- } else {
- asyn->state= IO_RESULT;
- return 0;
- }
-}
-
-int asyn_synch(asynchio_t *asyn, int fd)
-{
-}
-
-int asyn_close(asynchio_t *asyn, int fd)
-{
- asyn_init(asyn);
-}
if(m_ptr->m_type == DL_CONF) {
conf_expected = FALSE;
}
- else if(m_ptr->m_type != DL_GETNAME) {
+ else {
continue;
}
}
and
.BR udp0 )
uses the ethernet device driver handled
-by task "DP8390" at port 0. This network is marked as the default
+by driver "DP8390" instance 0. This network is marked as the default
network, so most programs use it through the unnumbered devices like
.B /dev/tcp
or
Network 1 is a Pseudo IP network that can be used for
a serial IP over a modem for instance.
.PP
-The configuration file may look like a common configuration file as
-described by
-.BR configfile (5),
-but it is currently just a simple subset allowing only what you see here.
+The configuration file uses a simple line-based format.
+Each network definition has to be fully on its own line.
+Empty lines and lines that start with a `#' symbol are ignored.
The following network definitions are possible:
.PP
.BI eth N
-.I task port
+.I driver instance
.RI { options };
.RS
This sets up an ethernet with device name
.BI /dev/eth N\fR,
-built on the given ethernet device driver at the given port at that driver.
-(If a network driver manages two network
-cards then they are at port 0 and 1.)
+built on the given ethernet device driver with the given instance number.
+(If there are two network cards of the same type
+then they will be managed by instance 0 and 1 of the corresponding driver.)
.br
.RE
.PP
int fd;
unsigned operations;
{
- printf("ip_select: not implemented\n");
- return 0;
+ unsigned resops;
+ ip_fd_t *ip_fd;
+
+ ip_fd= &ip_fd_table[fd];
+ assert (ip_fd->if_flags & IFF_INUSE);
+
+ resops= 0;
+
+ if (operations & SR_SELECT_READ)
+ {
+ if (ip_sel_read(ip_fd))
+ resops |= SR_SELECT_READ;
+ else if (!(operations & SR_SELECT_POLL))
+ ip_fd->if_flags |= IFF_SEL_READ;
+ }
+ if (operations & SR_SELECT_WRITE)
+ {
+ /* Should handle special case when the interface is down */
+ resops |= SR_SELECT_WRITE;
+ }
+ if (operations & SR_SELECT_EXCEPTION)
+ {
+ printf("ip_select: not implemented for exceptions\n");
+ }
+ return resops;
}
PUBLIC int ip_open (port, srfd, get_userdata, put_userdata, put_pkt,
ip_fd->if_get_userdata= get_userdata;
ip_fd->if_put_userdata= put_userdata;
ip_fd->if_put_pkt= put_pkt;
+ ip_fd->if_select_res= select_res;
return i;
}
get_userdata_t if_get_userdata;
put_userdata_t if_put_userdata;
put_pkt_t if_put_pkt;
+ select_res_t if_select_res;
time_t if_exp_time;
size_t if_rd_count;
ioreq_t if_ioctl;
#define IFF_EMPTY 0x00
#define IFF_INUSE 0x01
#define IFF_OPTSET 0x02
-#define IFF_BUSY 0x1C
+#define IFF_BUSY 0x0C
# define IFF_READ_IP 0x04
# define IFF_IOCTL_IP 0x08
+#define IFF_SEL_READ 0x10
typedef enum nettype
{
void ip_arrived ARGS(( ip_port_t *port, acc_t *pack ));
void ip_arrived_broadcast ARGS(( ip_port_t *port, acc_t *pack ));
void ip_process_loopb ARGS(( event_t *ev, ev_arg_t arg ));
+int ip_sel_read ARGS(( ip_fd_t *ip_fd ));
void ip_packet2user ARGS(( ip_fd_t *ip_fd, acc_t *pack, time_t exp_time,
size_t data_len ));
#include "ip.h"
#include "ip_int.h"
#include "ipr.h"
+#include "sr.h"
THIS_FILE
return TRUE;
}
+PUBLIC int ip_sel_read (ip_fd_t *ip_fd)
+{
+ acc_t *pack;
+
+ if (!(ip_fd->if_flags & IFF_OPTSET))
+ return 1; /* Read will not block */
+
+ if (ip_fd->if_rdbuf_head)
+ {
+ if (get_time() <= ip_fd->if_exp_time)
+ return 1;
+
+ while (ip_fd->if_rdbuf_head)
+ {
+ pack= ip_fd->if_rdbuf_head;
+ ip_fd->if_rdbuf_head= pack->acc_ext_link;
+ bf_afree(pack);
+ }
+ }
+ return 0;
+}
+
PUBLIC void ip_packet2user (ip_fd, pack, exp_time, data_len)
ip_fd_t *ip_fd;
acc_t *pack;
else
ip_fd->if_rdbuf_tail->acc_ext_link= pack;
ip_fd->if_rdbuf_tail= pack;
+
+ if (ip_fd->if_flags & IFF_SEL_READ)
+ {
+ ip_fd->if_flags & ~IFF_SEL_READ;
+ if (ip_fd->if_select_res)
+ ip_fd->if_select_res(ip_fd->if_srfd,
+ SR_SELECT_READ);
+ else
+ printf("ip_packet2user: no select_res\n");
+ }
return;
}
|_______________|___________|_________|_______|__________|_________|
from DL_ETH:
- _______________________________________________________________________
-| | | | | | |
-| m_type | DL_PORT | DL_PROC | DL_COUNT | DL_STAT | DL_TIME |
-|_______________|___________|_________|__________|____________|_________|
-| | | | | | |
-| DL_CONF_REPLY | minor dev | proc nr | rd_count | 0 | stat | time |
-|_______________|___________|_________|__________|____________|_________|
-| | | | | | |
-| DL_TASK_REPLY | minor dev | proc nr | rd_count | err | stat | time |
-|_______________|___________|_________|__________|____________|_________|
+ (not documented here)
*/
#include "inet.h"
}
}
else if (m_type == DL_CONF_REPLY || m_type == DL_TASK_REPLY ||
- m_type == DL_NAME_REPLY || m_type == DL_STAT_REPLY)
+ m_type == DL_STAT_REPLY)
{
eth_rec(&mq->mq_mess);
mq_free(mq);
{
char key[DS_MAX_KEYLEN];
char *driver_prefix = "drv.net.";
+ char *label;
u32_t value;
int type;
endpoint_t owner_endpoint;
int r;
- /* Get the event and the owner from DS. */
- r = ds_check(key, &type, &owner_endpoint);
- if(r != OK) {
- if(r != ENOENT)
- printf("inet: ds_event: ds_check failed: %d\n", r);
- return;
- }
- r = ds_retrieve_u32(key, &value);
- if(r != OK) {
- printf("inet: ds_event: ds_retrieve_u32 failed\n");
- return;
- }
+ /* We may get one notification for multiple updates from DS. Get events
+ * and owners from DS, until DS tells us that there are no more.
+ */
+ while ((r = ds_check(key, &type, &owner_endpoint)) == OK) {
+ r = ds_retrieve_u32(key, &value);
+ if(r != OK) {
+ printf("inet: ds_event: ds_retrieve_u32 failed\n");
+ return;
+ }
+
+ /* Only check for network driver up events. */
+ if(strncmp(key, driver_prefix, sizeof(driver_prefix))
+ || value != DS_DRIVER_UP) {
+ return;
+ }
+
+ /* The driver label comes after the prefix. */
+ label = key + strlen(driver_prefix);
- /* Only check for network driver up events. */
- if(strncmp(key, driver_prefix, sizeof(driver_prefix))
- || value != DS_DRIVER_UP) {
- return;
+ /* A driver is (re)started. */
+ eth_check_driver(label, owner_endpoint);
}
- /* A driver is (re)started. */
- eth_check_driver(owner_endpoint);
+ if(r != ENOENT)
+ printf("inet: ds_event: ds_check failed: %d\n", r);
}
PUBLIC void panic0(file, line)
static int cfg_fd;
static char word[16];
-static unsigned line;
+static unsigned char line[256], *lineptr;
+static unsigned linenr;
static void error(void)
{
- printf("inet: error on line %u\n", line);
+ printf("inet: error on line %u\n", linenr);
exit(1);
}
+static int nextline(void)
+{
+ /* Read a line from the configuration file, to be used by subsequent
+ * token() calls. Skip empty lines, and lines where the first character
+ * after leading "whitespace" is '#'. The last line of the file need
+ * not be terminated by a newline. Return 1 if a line was read in
+ * successfully, and 0 on EOF or error.
+ */
+ unsigned char *lp, c;
+ int r, skip;
+
+ lineptr = lp = line;
+ linenr++;
+ skip = -1;
+
+ while ((r = read(cfg_fd, &c, 1)) == 1) {
+ if (c == '\n') {
+ if (skip == 0)
+ break;
+
+ linenr++;
+ skip = -1;
+ continue;
+ }
+
+ if (skip == -1 && c > ' ')
+ skip = (c == '#');
+
+ if (skip == 0 && lp < (unsigned char *) line + sizeof(line)-1)
+ *lp++ = c;
+ }
+
+ *lp = 0;
+ return (r == 1 || lp != line);
+}
+
static void token(int need)
{
- /* Read a word from the configuration file. Return a null string on
- * EOF. Return a punctiation as a one character word. If 'need' is
+ /* Read a word from the configuration line. Return a null string on
+ * EOL. Return a punctuation as a one character word. If 'need' is
* true then an actual word is expected at this point, so err out if
* not.
*/
*wp = 0;
while (c <= ' ') {
- if (c == '\n') line++;
- if (read(cfg_fd, &c, 1) != 1) {
+ if (*lineptr == 0) {
if (need) error();
return;
}
+ c = *lineptr++;
}
do {
if (wp < (unsigned char *) word + sizeof(word)-1) *wp++ = c;
- if (read(cfg_fd, &c, 1) != 1) c= ' ';
+ c = (*lineptr != 0) ? *lineptr++ : ' ';
if (word[0] == ';' || word[0] == '{' || word[0] == '}') {
if (need) error();
break;
struct psip_conf *pcp;
struct ip_conf *icp;
struct stat st;
+ char buf[sizeof(word)];
{ static int first= 1;
if (!first) ip_panic(( "read_conf: called a second time" ));
pcp= psip_conf;
icp= ip_conf;
- while (token(0), word[0] != 0) {
+ while (nextline()) {
+ token(1);
if (strncmp(word, "eth", 3) == 0) {
ecp->ec_ifno= ifno= number(word+3, IP_PORT_MAX-1);
type= NETTYPE_ETH;
}
ecp->ec_port= number(word+3, IP_PORT_MAX-1);
} else {
- ecp->ec_task= alloc(strlen(word)+1);
- strcpy(ecp->ec_task, word);
+ /* The process label consists of the driver
+ * name, an underscore, and the instance
+ * number.
+ */
+ strncpy(buf, word, sizeof(buf)-1);
+ buf[sizeof(buf)-1]= 0;
token(1);
- ecp->ec_port= number(word, IP_PORT_MAX-1);
+ ecp->ec_label=
+ alloc(strlen(buf)+1+strlen(word)+1);
+ sprintf(ecp->ec_label, "%s_%s", buf, word);
+ ecp->ec_port= 0;
}
ecp++;
eth_conf_nr++;
struct eth_conf
{
- char *ec_task; /* Kernel ethernet task name if nonnull */
- u8_t ec_port; /* Task port (!vlan) or Ethernet port (vlan) */
+ char *ec_label; /* Process label name if nonnull */
+ u8_t ec_port; /* Ethernet port for VLAN if label == NULL */
u8_t ec_ifno; /* Interface number of /dev/eth* */
- u16_t ec_vlan; /* VLAN number of this net if task == NULL */
+ u16_t ec_vlan; /* VLAN number of this net if label == NULL */
};
-#define eth_is_vlan(ecp) ((ecp)->ec_task == NULL)
+#define eth_is_vlan(ecp) ((ecp)->ec_label == NULL)
struct psip_conf
{
*/
#include "inet.h"
-#include <minix/ds.h>
#include <minix/safecopies.h>
#include "proto.h"
#include "osdep_eth.h"
THIS_FILE
-static int recv_debug= 0;
-
FORWARD _PROTOTYPE( void setup_read, (eth_port_t *eth_port) );
FORWARD _PROTOTYPE( void read_int, (eth_port_t *eth_port, int count) );
FORWARD _PROTOTYPE( void eth_issue_send, (eth_port_t *eth_port) );
FORWARD _PROTOTYPE( void write_int, (eth_port_t *eth_port) );
-FORWARD _PROTOTYPE( void eth_recvev, (event_t *ev, ev_arg_t ev_arg) );
-FORWARD _PROTOTYPE( void eth_sendev, (event_t *ev, ev_arg_t ev_arg) );
-FORWARD _PROTOTYPE( eth_port_t *find_port, (message *m) );
FORWARD _PROTOTYPE( void eth_restart, (eth_port_t *eth_port,
endpoint_t endpoint) );
FORWARD _PROTOTYPE( void send_getstat, (eth_port_t *eth_port) );
PUBLIC void osdep_eth_init()
{
- int i, j, r, rport;
+ int i, j, rport;
struct eth_conf *ecp;
eth_port_t *eth_port, *rep;
cp_grant_id_t gid;
}
eth_port->etp_osdep.etp_rd_vec_grant= gid;
- eth_port->etp_osdep.etp_port= ecp->ec_port;
- eth_port->etp_osdep.etp_task= ANY;
+ eth_port->etp_osdep.etp_task= NONE;
eth_port->etp_osdep.etp_recvconf= 0;
- eth_port->etp_osdep.etp_send_ev= 0;
ev_init(ð_port->etp_osdep.etp_recvev);
sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
if (!eth_is_vlan(ecp))
continue;
- eth_port->etp_osdep.etp_port= ecp->ec_port;
- eth_port->etp_osdep.etp_task= ANY;
+ eth_port->etp_osdep.etp_task= NONE;
ev_init(ð_port->etp_osdep.etp_recvev);
- rport= eth_port->etp_osdep.etp_port;
+ rport= ecp->ec_port;
assert(rport >= 0 && rport < eth_conf_nr);
rep= ð_port_table[rport];
if (!(rep->etp_flags & EPF_ENABLED))
eth_issue_send(eth_port);
}
-#if 0
-PRIVATE int notification_count;
-#endif
-
PUBLIC void eth_rec(message *m)
{
- int i, r, m_type, stat;
+ int i, r, m_type, flags;
eth_port_t *loc_port, *vlan_port;
- char *drivername;
- struct eth_conf *ecp;
m_type= m->m_type;
- if (m_type == DL_NAME_REPLY)
- {
- drivername= m->m3_ca1;
-#if 0
- printf("eth_rec: got name: %s\n", drivername);
-
- notification_count= 0;
-#endif
-
- /* Re-init ethernet interfaces */
- for (i= 0, ecp= eth_conf, loc_port= eth_port_table;
- i<eth_conf_nr; i++, ecp++, loc_port++)
- {
- if (eth_is_vlan(ecp))
- continue;
-
- if (strcmp(ecp->ec_task, drivername) != 0)
- {
- /* Wrong driver */
- continue;
- }
- eth_restart(loc_port, m->m_source);
- }
- return;
- }
assert(m_type == DL_CONF_REPLY || m_type == DL_TASK_REPLY ||
m_type == DL_STAT_REPLY);
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)
+ if (loc_port->etp_osdep.etp_task == m->m_source)
break;
}
if (i >= eth_conf_nr)
{
- printf("eth_rec: bad port %d in message type 0x%x from %d\n",
- m->DL_PORT, m_type, m->m_source);
+ printf("eth_rec: message 0x%x from unknown driver %d\n",
+ m_type, m->m_source);
return;
}
{
if (m_type == DL_TASK_REPLY)
{
- stat= m->DL_STAT & 0xffff;
+ flags= m->DL_FLAGS;
- if (stat & DL_PACK_SEND)
+ if (flags & DL_PACK_SEND)
write_int(loc_port);
- if (stat & DL_PACK_RECV)
+ if (flags & DL_PACK_RECV)
read_int(loc_port, m->DL_COUNT);
return;
}
return;
}
- r= m->m3_i1;
- if (r == ENXIO)
- {
- printf(
- "eth_rec(conf_reply): no ethernet device at task=%d,port=%d\n",
- loc_port->etp_osdep.etp_task,
- loc_port->etp_osdep.etp_port);
- return;
- }
+ r= m->DL_STAT;
if (r < 0)
{
- ip_panic(("eth_rec: DL_INIT returned error %d\n", r));
+ ip_warning(("eth_rec: DL_CONF returned error %d\n",
+ r));
+
+ /* Just leave it in limbo. Nothing more we can do. */
return;
}
loc_port->etp_osdep.etp_state= OEPS_IDLE;
loc_port->etp_flags |= EPF_ENABLED;
- loc_port->etp_ethaddr= *(ether_addr_t *)m->m3_ca1;
+ loc_port->etp_ethaddr= *(ether_addr_t *)m->DL_HWADDR;
if (!(loc_port->etp_flags & EPF_GOT_ADDR))
{
loc_port->etp_flags |= EPF_GOT_ADDR;
return;
}
- r= m->DL_STAT;
- if (r != OK)
- {
- ip_warning(("eth_rec: DL_STAT returned error %d\n",
- r));
- return;
- }
-
loc_port->etp_osdep.etp_state= OEPS_IDLE;
loc_port->etp_osdep.etp_flags &= ~OEPF_NEED_STAT;
(printf("etp_state = %d\n", loc_port->etp_osdep.etp_state), 0));
loc_port->etp_osdep.etp_state= OEPS_IDLE;
-#if 0 /* Ethernet driver is not trusted */
- set_time (m->DL_CLCK);
-#endif
-
- stat= m->DL_STAT & 0xffff;
+ flags= m->DL_FLAGS;
-#if 0
- if (!(stat & (DL_PACK_SEND|DL_PACK_RECV)))
- printf("eth_rec: neither DL_PACK_SEND nor DL_PACK_RECV\n");
-#endif
- if (stat & DL_PACK_SEND)
+ if (flags & DL_PACK_SEND)
write_int(loc_port);
- if (stat & DL_PACK_RECV)
- {
- if (recv_debug)
- {
- printf("eth_rec: eth%d got DL_PACK_RECV\n",
- m->DL_PORT);
- }
+ if (flags & DL_PACK_RECV)
read_int(loc_port, m->DL_COUNT);
- }
if (loc_port->etp_osdep.etp_state == OEPS_IDLE &&
loc_port->etp_osdep.etp_flags & OEPF_NEED_SEND)
}
}
-PUBLIC void eth_check_driver(endpoint_t endpoint)
+PUBLIC void eth_check_driver(char *label, endpoint_t endpoint)
{
- int r;
- message m;
+ int i;
+ eth_port_t *loc_port;
+ struct eth_conf *ecp;
- m.m_type = DL_GETNAME;
- r= asynsend(endpoint, &m);
- if (r != OK)
+ /* Re-init ethernet interface */
+ for (i= 0, ecp= eth_conf, loc_port= eth_port_table;
+ i<eth_conf_nr; i++, ecp++, loc_port++)
{
- printf("eth_check_driver: asynsend to %d failed: %d\n",
- endpoint, r);
- return;
+ if (eth_is_vlan(ecp))
+ continue;
+
+ if (strcmp(ecp->ec_label, label) != 0)
+ {
+ /* Wrong driver */
+ continue;
+ }
+ eth_restart(loc_port, endpoint);
}
}
dl_flags |= DL_PROMISC_REQ;
mess.m_type= DL_CONF;
- mess.DL_PORT= eth_port->etp_osdep.etp_port;
- mess.DL_PROC= this_proc;
mess.DL_MODE= dl_flags;
assert(eth_port->etp_osdep.etp_state == OEPS_IDLE);
"eth_write_port: cpf_setgrant_direct failed: %d\n",
errno));
}
+ m.m_type= DL_WRITEV_S;
+ m.DL_ENDPT= this_proc;
m.DL_COUNT= i;
m.DL_GRANT= eth_port->etp_osdep.etp_wr_vec_grant;
- m.m_type= DL_WRITEV_S;
-
- m.DL_PORT= eth_port->etp_osdep.etp_port;
- m.DL_PROC= this_proc;
- m.DL_MODE= DL_NOMODE;
assert(eth_port->etp_osdep.etp_state == OEPS_IDLE);
r= asynsend(eth_port->etp_osdep.etp_task, &m);
if (pack == NULL)
{
printf("write_int: strange no packet on eth port %d\n",
- eth_port-eth_port_table);
+ (int)(eth_port-eth_port_table));
eth_restart_write(eth_port);
return;
}
eth_port_t *eth_port;
{
acc_t *pack, *pack_ptr;
- message mess1;
+ message mess;
iovec_s_t *iovec;
int i, r;
errno));
}
- mess1.m_type= DL_READV_S;
- mess1.DL_PORT= eth_port->etp_osdep.etp_port;
- mess1.DL_PROC= this_proc;
- mess1.DL_COUNT= i;
- mess1.DL_GRANT= eth_port->etp_osdep.etp_rd_vec_grant;
+ mess.m_type= DL_READV_S;
+ mess.DL_ENDPT= this_proc;
+ mess.DL_COUNT= i;
+ mess.DL_GRANT= eth_port->etp_osdep.etp_rd_vec_grant;
assert(eth_port->etp_osdep.etp_state == OEPS_IDLE);
- r= asynsend(eth_port->etp_osdep.etp_task, &mess1);
+ r= asynsend(eth_port->etp_osdep.etp_task, &mess);
eth_port->etp_osdep.etp_state= OEPS_RECV_SENT;
if (r < 0)
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;
- assert(eth_port->etp_osdep.etp_send_ev);
- eth_port->etp_osdep.etp_send_ev= 0;
-
- /* 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_t *eth_port, endpoint_t endpoint)
{
int r;
if (flags & NWEO_EN_PROMISC)
dl_flags |= DL_PROMISC_REQ;
mess.m_type= DL_CONF;
- mess.DL_PORT= eth_port->etp_osdep.etp_port;
- mess.DL_PROC= this_proc;
mess.DL_MODE= dl_flags;
compare(eth_port->etp_osdep.etp_state, ==, OEPS_IDLE);
message mess;
mess.m_type= DL_GETSTAT_S;
- mess.DL_PORT= eth_port->etp_osdep.etp_port;
- mess.DL_PROC= this_proc;
+ mess.DL_ENDPT= this_proc;
mess.DL_GRANT= eth_port->etp_osdep.etp_stat_gid;
assert(eth_port->etp_osdep.etp_state == OEPS_IDLE);
int etp_state;
int etp_flags;
endpoint_t etp_task;
- int etp_port;
int etp_recvconf;
- int etp_send_ev;
iovec_s_t etp_wr_iovec[IOVEC_NR];
cp_grant_id_t etp_wr_vec_grant;
iovec_s_t etp_rd_iovec[RD_IOVEC];
cp_grant_id_t etp_rd_vec_grant;
event_t etp_recvev;
- message etp_sendrepl;
- message etp_recvrepl;
cp_grant_id_t etp_stat_gid;
eth_stat_t *etp_stat_buf;
} osdep_eth_port_t;
/* mnx_eth.c */
_PROTOTYPE( void eth_rec, (message *m) );
-_PROTOTYPE( void eth_check_driver, (endpoint_t endpoint) );
+_PROTOTYPE( void eth_check_driver, (char *label, endpoint_t endpoint) );
/* sr.c */
FORWARD _PROTOTYPE ( int sr_repl_queue, (int proc, int ref, int operation) );
FORWARD _PROTOTYPE ( int walk_queue, (sr_fd_t *sr_fd, mq_t **q_head_ptr,
mq_t **q_tail_ptr, int type, int proc_nr, int ref, int first_flag) );
-FORWARD _PROTOTYPE ( void process_req_q, (mq_t *mq, mq_t *tail,
- mq_t **tail_ptr) );
FORWARD _PROTOTYPE ( void sr_event, (event_t *evp, ev_arg_t arg) );
FORWARD _PROTOTYPE ( int cp_u2b, (endpoint_t proc, cp_grant_id_t gid,
vir_bytes offset, acc_t **var_acc_ptr, int size) );
notify(sr_fd->srf_select_proc);
}
-PRIVATE void process_req_q(mq, tail, tail_ptr)
-mq_t *mq, *tail, **tail_ptr;
-{
- mq_t *m;
- int result;
-
- for(;mq;)
- {
- m= mq;
- mq= mq->mq_next;
-
- result= sr_rwio(m);
- if (result == SUSPEND)
- {
- if (mq)
- {
- (*tail_ptr)->mq_next= mq;
- *tail_ptr= tail;
- }
- return;
- }
- }
- return;
-}
-
PRIVATE void sr_event(evp, arg)
event_t *evp;
ev_arg_t arg;
#define PORT 6060L
-int listen(long port) {
+int my_listen(long port) {
char *tcp_device;
int netfd;
int ret;
fd_set fds_read;
- if ((fd = listen(PORT)) < 0) {
+ if ((fd = my_listen(PORT)) < 0) {
exit(-1);
}
printf("Waiting for messages on port: %ld\n", PORT);
#define PORT 6060L
-int listen(long port) {
+int my_listen(long port) {
char *tcp_device;
int netfd;
fd_set fds_read;
struct timeval timeout;
- if ((fd = listen(PORT)) < 0) {
+ if ((fd = my_listen(PORT)) < 0) {
exit(-1);
}
printf("Waiting for messages on port: %ld\n", PORT);
#define PORT 6060L
-int listen(long port) {
+int my_listen(long port) {
char *tcp_device;
int netfd;
int ret;
fd_set fds_excep;
- if ((fd = listen(PORT)) < 0) {
+ if ((fd = my_listen(PORT)) < 0) {
exit(-1);
}
printf("Waiting for messages on port: %ld\n", PORT);