#include "rtl8139.h"
-re_t re_state;
+static re_t re_state;
static int re_instance;
#define rl_outw(port, offset, value) (my_outw((port) + (offset), (value)))
#define rl_outl(port, offset, value) (my_outl((port) + (offset), (value)))
-static void rl_init(message *mp);
-static void rl_pci_conf(void);
-static int rl_probe(re_t *rep, int skip);
-static void rl_conf_hw(re_t *rep);
+static int rl_init(unsigned int instance, ether_addr_t *addr);
+static int rl_probe(re_t *rep, unsigned int skip);
static void rl_init_buf(re_t *rep);
-static void rl_init_hw(re_t *rep);
+static void rl_init_hw(re_t *rep, ether_addr_t *addr);
static void rl_reset_hw(re_t *rep);
-static void rl_confaddr(re_t *rep);
+static void rl_confaddr(re_t *rep, ether_addr_t *addr);
+static void rl_stop(void);
static void rl_rec_mode(re_t *rep);
-static void rl_readv_s(const message *mp, int from_int);
-static void rl_writev_s(const message *mp, int from_int);
+static void rl_mode(unsigned int mode);
+static ssize_t rl_recv(struct netdriver_data *data, size_t max);
+static int rl_send(struct netdriver_data *data, size_t size);
+static void rl_intr(unsigned int mask);
static void rl_check_ints(re_t *rep);
static void rl_report_link(re_t *rep);
+#if VERBOSE
static void mii_print_techab(u16_t techab);
static void mii_print_stat_speed(u16_t stat, u16_t extstat);
+#endif
static void rl_clear_rx(re_t *rep);
static void rl_do_reset(re_t *rep);
-static void rl_getstat_s(message *mp);
-static void reply(re_t *rep);
-static void mess_reply(message *req, message *reply);
-static void check_int_events(void);
-static void do_hard_int(void);
-static void rtl8139_dump(message *m);
+static void rl_stat(eth_stat_t *stat);
+static void rl_other(const message *m_ptr, int ipc_status);
+static void rl_dump(void);
#if 0
static void dump_phy(re_t *rep);
#endif
static int rl_handler(re_t *rep);
-static void rl_watchdog_f(minix_timer_t *tp);
-static void tell_dev(vir_bytes start, size_t size, int pci_bus, int
+static void rl_alarm(clock_t stamp);
+static void tell_iommu(vir_bytes start, size_t size, int pci_bus, int
pci_dev, int pci_func);
-/* The message used in the main loop is made global, so that rl_watchdog_f()
- * can change its message type to fake an interrupt message.
- */
-static message m;
-static int int_event_check; /* set to TRUE if events arrived */
-
-static u32_t system_hz;
-
-/* SEF functions and variables. */
-static void sef_local_startup(void);
-static int sef_cb_init_fresh(int type, sef_init_info_t *info);
-static void sef_cb_signal_handler(int signo);
-EXTERN int sef_cb_lu_prepare(int state);
-EXTERN int sef_cb_lu_state_isvalid(int state);
-EXTERN void sef_cb_lu_state_dump(int state);
+static const struct netdriver rl_table = {
+ .ndr_init = rl_init,
+ .ndr_stop = rl_stop,
+ .ndr_mode = rl_mode,
+ .ndr_recv = rl_recv,
+ .ndr_send = rl_send,
+ .ndr_stat = rl_stat,
+ .ndr_intr = rl_intr,
+ .ndr_alarm = rl_alarm,
+ .ndr_other = rl_other,
+};
/*===========================================================================*
* main *
*===========================================================================*/
int main(int argc, char *argv[])
{
- int r;
- int ipc_status;
- /* SEF local startup. */
env_setargs(argc, argv);
- sef_local_startup();
- while (TRUE)
- {
- if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
- panic("netdriver_receive failed: %d", r);
-
- if (is_ipc_notify(ipc_status)) {
- switch (_ENDPOINT_P(m.m_source)) {
- case CLOCK:
- /*
- * Under MINIX, synchronous alarms are
- * used instead of watchdog functions.
- * The approach is very different: MINIX
- * VMD timeouts are handled within the
- * kernel (the watchdog is executed by
- * CLOCK), and notify() the driver in
- * some cases. MINIX timeouts result in
- * a SYN_ALARM message to the driver and
- * thus are handled where they should be
- * handled. Locally, watchdog functions
- * are used again.
- */
- rl_watchdog_f(NULL);
- break;
- case HARDWARE:
- do_hard_int();
- if (int_event_check)
- check_int_events();
- break ;
- case TTY_PROC_NR:
- rtl8139_dump(&m);
- break;
- default:
- panic("illegal notify from: %d",
- m.m_source);
- }
+ netdriver_task(&rl_table);
- /* done, get nwe message */
- continue;
- }
-
- switch (m.m_type)
- {
- 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_S: rl_getstat_s(&m); break;
- default:
- panic("illegal message: %d", m.m_type);
- }
- }
+ return 0;
}
/*===========================================================================*
- * sef_local_startup *
+ * rl_intr *
*===========================================================================*/
-static void sef_local_startup()
+static void rl_intr(unsigned int __unused mask)
{
- /* Register init callbacks. */
- sef_setcb_init_fresh(sef_cb_init_fresh);
- sef_setcb_init_lu(sef_cb_init_fresh);
- sef_setcb_init_restart(sef_cb_init_fresh);
+ re_t *rep;
+ int s;
+
+ rep = &re_state;
- /* Register live update callbacks. */
- sef_setcb_lu_prepare(sef_cb_lu_prepare);
- sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
- sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+ /* Run interrupt handler at driver level. */
+ rl_handler(rep);
- /* Register signal callbacks. */
- sef_setcb_signal_handler(sef_cb_signal_handler);
+ /* Reenable interrupts for this hook. */
+ if ((s = sys_irqenable(&rep->re_hook_id)) != OK)
+ printf("RTL8139: error, couldn't enable interrupts: %d\n", s);
- /* Let SEF perform startup. */
- sef_startup();
+ /* Perform tasks based on the flagged conditions. */
+ rl_check_ints(rep);
}
/*===========================================================================*
- * sef_cb_init_fresh *
+ * rl_other *
*===========================================================================*/
-static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
+static void rl_other(const message *m_ptr, int ipc_status)
{
-/* Initialize the rtl8139 driver. */
- long v;
-#if RTL8139_FKEY
- int r, fkeys, sfkeys;
-#endif
-
- system_hz = sys_hz();
-
- 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. */
- fkeys = sfkeys = 0; bit_set(sfkeys, 9);
- if ((r=fkey_map(&fkeys, &sfkeys)) != OK)
- printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r);
-#endif
-
- /* Claim buffer memory now. */
- rl_init_buf(&re_state);
-
- /* Announce we are up! */
- netdriver_announce();
-
- return(OK);
+ if (is_ipc_notify(ipc_status) && m_ptr->m_source == TTY_PROC_NR)
+ rl_dump();
}
/*===========================================================================*
- * sef_cb_signal_handler *
+ * rl_stop *
*===========================================================================*/
-static void sef_cb_signal_handler(int signo)
+static void rl_stop(void)
{
re_t *rep;
- /* Only check for termination signal, ignore anything else. */
- if (signo != SIGTERM) return;
-
rep = &re_state;
- if (rep->re_mode == REM_ENABLED)
- rl_outb(rep->re_base_port, RL_CR, 0);
- exit(0);
+ rl_outb(rep->re_base_port, RL_CR, 0);
}
/*===========================================================================*
- * check_int_events *
+ * rl_dump *
*===========================================================================*/
-static void check_int_events(void)
-{
- 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);
-}
-
-/*===========================================================================*
- * rtl8139_dump *
- *===========================================================================*/
-static void rtl8139_dump(m)
-message *m; /* pointer to request message */
+static void rl_dump(void)
{
re_t *rep;
rep= &re_state;
printf("\n");
- if (rep->re_mode == REM_DISABLED)
- printf("Realtek RTL 8139 instance %d is disabled\n",
- re_instance);
-
- if (rep->re_mode != REM_ENABLED)
- return;
-
printf("Realtek RTL 8139 statistics of instance %d:\n", re_instance);
printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr);
printf("OWC :%8ld\t", rep->re_stat.ets_OWC);
- 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_init *
+ * rl_mode *
*===========================================================================*/
-static void rl_init(mp)
-message *mp;
+static void rl_mode(unsigned int mode)
{
- static int first_time= 1;
-
re_t *rep;
- message reply_mess;
-
- if (first_time)
- {
- first_time= 0;
- rl_pci_conf(); /* Configure PCI devices. */
-
- /* Use a synchronous alarm instead of a watchdog timer. */
- sys_setalarm(system_hz, 0);
- }
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.m_netdrv_net_dl_conf.stat= ENXIO;
- mess_reply(mp, &reply_mess);
- return;
- }
- if (rep->re_mode == REM_ENABLED)
- rl_init_hw(rep);
-#if VERBOSE /* load silently ... can always check status later */
- rl_report_link(rep);
-#endif
- }
-
- assert(rep->re_mode == REM_ENABLED);
- assert(rep->re_flags & REF_ENABLED);
- rep->re_flags &= ~(REF_PROMISC | REF_MULTI | REF_BROAD);
-
- if (mp->m_net_netdrv_dl_conf.mode & DL_PROMISC_REQ)
- rep->re_flags |= REF_PROMISC;
- if (mp->m_net_netdrv_dl_conf.mode & DL_MULTI_REQ)
- rep->re_flags |= REF_MULTI;
- if (mp->m_net_netdrv_dl_conf.mode & DL_BROAD_REQ)
- rep->re_flags |= REF_BROAD;
+ rep->re_mode = mode;
rl_rec_mode(rep);
-
- reply_mess.m_type = DL_CONF_REPLY;
- reply_mess.m_netdrv_net_dl_conf.stat = OK;
- memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr,
- rep->re_address.ea_addr,
- sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr));
-
- mess_reply(mp, &reply_mess);
}
/*===========================================================================*
- * rl_pci_conf *
+ * rl_init *
*===========================================================================*/
-static void rl_pci_conf()
+static int rl_init(unsigned int instance, ether_addr_t *addr)
{
+/* Initialize the rtl8139 driver. */
re_t *rep;
+#if RTL8139_FKEY
+ int r, fkeys, sfkeys;
+#endif
+ /* Initialize driver state. */
rep= &re_state;
+ memset(rep, 0, sizeof(*rep));
+ rep->re_link_up= -1; /* Unknown */
+ rep->re_ertxth= RL_TSD_ERTXTH_8;
strlcpy(rep->re_name, "rtl8139#0", sizeof(rep->re_name));
- rep->re_name[8] += re_instance;
- rep->re_seen= FALSE;
+ rep->re_name[8] += instance;
- pci_init();
+ re_instance = instance;
+
+ /* Try to find a matching device. */
+ if (!rl_probe(rep, instance))
+ return ENXIO;
- if (rl_probe(rep, re_instance))
- rep->re_seen= TRUE;
+ /* Claim buffer memory. */
+ rl_init_buf(rep);
+
+ /* Initialize the device we found. */
+ rl_init_hw(rep, addr);
+
+#if VERBOSE
+ /* Report initial link status. */
+ rl_report_link(rep);
+#endif
+
+ /* Use a synchronous alarm instead of a watchdog timer. */
+ sys_setalarm(sys_hz(), 0);
+
+#if RTL8139_FKEY
+ /* Observe some function key for debug dumps. */
+ fkeys = sfkeys = 0; bit_set(sfkeys, 9);
+ if ((r = fkey_map(&fkeys, &sfkeys)) != OK)
+ printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r);
+#endif
+
+ return OK;
}
/*===========================================================================*
* rl_probe *
*===========================================================================*/
-static int rl_probe(rep, skip)
-re_t *rep;
-int skip;
+static int rl_probe(re_t *rep, unsigned int skip)
{
int r, devind;
u16_t cr, vid, did;
char *dname;
#endif
+ pci_init();
+
r= pci_first_dev(&devind, &vid, &did);
if (r == 0)
return 0;
ilr= pci_attr_r8(devind, PCI_ILR);
rep->re_irq= ilr;
- if (debug)
- {
- printf("%s: using I/O address 0x%lx, IRQ %d\n",
- rep->re_name, (unsigned long)bar, ilr);
- }
+#if VERBOSE
+ printf("%s: using I/O address 0x%lx, IRQ %d\n",
+ rep->re_name, (unsigned long)bar, ilr);
+#endif
return TRUE;
}
-/*===========================================================================*
- * rl_conf_hw *
- *===========================================================================*/
-static void rl_conf_hw(rep)
-re_t *rep;
-{
- static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
-
- rep->re_mode= REM_DISABLED; /* Superfluous */
-
- if (rep->re_seen)
- {
- /* PCI device is present */
- rep->re_mode= REM_ENABLED;
- }
- if (rep->re_mode != REM_ENABLED)
- return;
-
- rep->re_flags= REF_EMPTY;
- rep->re_link_up= -1; /* Unknown */
- rep->re_got_int= 0;
- rep->re_send_int= 0;
- rep->re_report_link= 0;
- rep->re_clear_rx= 0;
- rep->re_need_reset= 0;
- rep->re_tx_alive= 0;
- rep->re_read_s= 0;
- rep->re_tx_head= 0;
- rep->re_tx_tail= 0;
- rep->re_ertxth= RL_TSD_ERTXTH_8;
- rep->re_stat= empty_stat;
-}
-
/*===========================================================================*
* rl_init_buf *
*===========================================================================*/
-static void rl_init_buf(rep)
-re_t *rep;
+static void rl_init_buf(re_t *rep)
{
size_t rx_bufsize, tx_bufsize, tot_bufsize;
phys_bytes buf;
#define BUF_ALIGNMENT (64*1024)
- if(!(mallocbuf = alloc_contig(BUF_ALIGNMENT + tot_bufsize, 0, &buf))) {
- panic("Couldn't allocate kernel buffer");
- }
+ if (!(mallocbuf = alloc_contig(BUF_ALIGNMENT + tot_bufsize, 0, &buf)))
+ panic("Couldn't allocate kernel buffer");
/* click-align mallocced buffer. this is what we used to get
* from kmalloc() too.
buf += BUF_ALIGNMENT - off;
}
- tell_dev((vir_bytes)mallocbuf, tot_bufsize, 0, 0, 0);
+ tell_iommu((vir_bytes)mallocbuf, tot_bufsize, 0, 0, 0);
for (i= 0; i<N_TX_BUF; i++)
{
/*===========================================================================*
* rl_init_hw *
*===========================================================================*/
-static void rl_init_hw(rep)
-re_t *rep;
+static void rl_init_hw(re_t *rep, ether_addr_t *addr)
{
- int s, i;
-
- rep->re_flags = REF_EMPTY;
- rep->re_flags |= REF_ENABLED;
+#if VERBOSE
+ int i;
+#endif
+ int s;
- /* Set the interrupt handler. The policy is to only send HARD_INT
+ /* Set the interrupt handler. The policy is to only send HARD_INT
* notifications. Don't reenable interrupts automatically. The id
* that is passed back is the interrupt line number.
*/
- rep->re_hook_id = rep->re_irq;
+ rep->re_hook_id = rep->re_irq;
if ((s=sys_irqsetpolicy(rep->re_irq, 0, &rep->re_hook_id)) != OK)
printf("RTL8139: error, couldn't set IRQ policy: %d\n", s);
}
#endif
- rl_confaddr(rep);
- if (debug)
- {
- printf("%s: Ethernet address ", rep->re_name);
- for (i= 0; i < 6; i++)
- {
- printf("%x%c", rep->re_address.ea_addr[i],
- i < 5 ? ':' : '\n');
- }
- }
+ rl_confaddr(rep, addr);
+
+#if VERBOSE
+ printf("%s: Ethernet address ", rep->re_name);
+ for (i= 0; i < 6; i++)
+ printf("%x%c", addr->ea_addr[i], i < 5 ? ':' : '\n');
+#endif
}
/*===========================================================================*
* rl_reset_hw *
*===========================================================================*/
-static void rl_reset_hw(rep)
-re_t *rep;
+static void rl_reset_hw(re_t *rep)
{
port_t port;
u32_t t;
bus_buf= vm_1phys2bus(rep->re_rx_buf);
rl_outl(port, RL_RBSTART, bus_buf);
- /* Initialize Tx */
+ /* Initialize Tx */
for (i= 0; i<N_TX_BUF; i++)
{
rep->re_tx[i].ret_busy= FALSE;
assert(t & RL_TSD_OWN);
}
+ rep->re_tx_busy = 0;
+
#if 0
dump_phy(rep);
#endif
/*===========================================================================*
* rl_confaddr *
*===========================================================================*/
-static void rl_confaddr(rep)
-re_t *rep;
+static void rl_confaddr(re_t *rep, ether_addr_t *addr)
{
static char eakey[]= RL_ENVVAR "#_EA";
static char eafmt[]= "x:x:x:x:x:x";
{
if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
break;
- rep->re_address.ea_addr[i]= v;
+ addr->ea_addr[i]= v;
}
if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */
rl_outb(port, RL_9346CR, RL_9346CR_EEM_CONFIG);
w= 0;
for (i= 0; i<4; i++)
- w |= (rep->re_address.ea_addr[i] << (i*8));
+ w |= (addr->ea_addr[i] << (i*8));
rl_outl(port, RL_IDR, w);
w= 0;
for (i= 4; i<6; i++)
- w |= (rep->re_address.ea_addr[i] << ((i-4)*8));
+ w |= (addr->ea_addr[i] << ((i-4)*8));
rl_outl(port, RL_IDR+4, w);
rl_outb(port, RL_9346CR, RL_9346CR_EEM_NORMAL);
}
/* Get ethernet address */
for (i= 0; i<6; i++)
- rep->re_address.ea_addr[i]= rl_inb(port, RL_IDR+i);
+ addr->ea_addr[i]= rl_inb(port, RL_IDR+i);
}
/*===========================================================================*
* rl_rec_mode *
*===========================================================================*/
-static void rl_rec_mode(rep)
-re_t *rep;
+static void rl_rec_mode(re_t *rep)
{
port_t port;
u32_t rcr;
port= rep->re_base_port;
rcr= rl_inl(port, RL_RCR);
rcr &= ~(RL_RCR_AB|RL_RCR_AM|RL_RCR_APM|RL_RCR_AAP);
- if (rep->re_flags & REF_PROMISC)
+ if (rep->re_mode & NDEV_PROMISC)
rcr |= RL_RCR_AB | RL_RCR_AM | RL_RCR_AAP;
- if (rep->re_flags & REF_BROAD)
+ if (rep->re_mode & NDEV_BROAD)
rcr |= RL_RCR_AB;
- if (rep->re_flags & REF_MULTI)
+ if (rep->re_mode & NDEV_MULTI)
rcr |= RL_RCR_AM;
rcr |= RL_RCR_APM;
}
/*===========================================================================*
- * rl_readv_s *
+ * rl_recv *
*===========================================================================*/
-static void rl_readv_s(const message *mp, int from_int)
+static ssize_t rl_recv(struct netdriver_data *data, size_t max)
{
- int i, j, n, o, s, s1, count, size;
+ int o, s;
port_t port;
unsigned amount, totlen, packlen;
u16_t d_start, d_end;
- u32_t l, rxstat = 0x12345678;
+ u32_t l, rxstat;
re_t *rep;
- iovec_s_t *iovp;
- int cps;
- int iov_offset = 0;
rep= &re_state;
- rep->re_client= mp->m_source;
- count = mp->m_net_netdrv_dl_readv_s.count;
-
if (rep->re_clear_rx)
- goto suspend; /* Buffer overflow */
-
- assert(rep->re_mode == REM_ENABLED);
- assert(rep->re_flags & REF_ENABLED);
+ return SUSPEND; /* Buffer overflow */
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))
+ if (rl_inb(port, RL_CR) & RL_CR_BUFE)
{
/* Receive buffer is empty, suspend */
- goto suspend;
+ return SUSPEND;
}
d_start= rl_inw(port, RL_CAPR) + RL_CAPR_DATA_OFF;
#if RX_BUFSIZE <= USHRT_MAX
if (d_start >= RX_BUFSIZE)
{
- printf("rl_readv: strange value in RL_CAPR: 0x%x\n",
+ printf("rl_recv: strange value in RL_CAPR: 0x%x\n",
rl_inw(port, RL_CAPR));
d_start %= RX_BUFSIZE;
}
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))
{
/* Someting went wrong */
printf(
- "rl_readv: bad length (%u) in status 0x%08x at offset 0x%x\n",
+ "rl_recv: bad length (%u) in status 0x%08x at offset 0x%x\n",
totlen, rxstat, d_start);
printf(
"d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%x\n",
if (totlen+4 > amount)
{
- printf("rl_readv: packet not yet ready\n");
- goto suspend;
+ printf("rl_recv: packet not yet ready\n");
+ return SUSPEND;
}
/* Should subtract the CRC */
- packlen= totlen - ETH_CRC_SIZE;
+ packlen = MIN(totlen - ETH_CRC_SIZE, max);
- size= 0;
- o= d_start+4;
- for (i= 0; i<count; i += IOVEC_NR,
- iov_offset += IOVEC_NR * sizeof(rep->re_iovec_s[0]))
- {
- n= IOVEC_NR;
- if (i+n > count)
- n= count-i;
-
- cps = sys_safecopyfrom(mp->m_source,
- mp->m_net_netdrv_dl_readv_s.grant, iov_offset,
- (vir_bytes) rep->re_iovec_s,
- n * sizeof(rep->re_iovec_s[0]));
- if (cps != OK) {
- panic("rl_readv_s: sys_safecopyfrom failed: %d",
- cps);
- }
+ /* Copy out the data. The packet may wrap in the receive buffer. */
+ o = (d_start+4) % RX_BUFSIZE;
+ s = MIN(RX_BUFSIZE - o, packlen);
- for (j= 0, iovp= rep->re_iovec_s; j<n; j++, iovp++)
- {
- s= iovp->iov_size;
- if (size + s > packlen)
- {
- assert(packlen > size);
- s= packlen-size;
- }
-
-#if 0
- if (sys_umap(mp->m_source, D, iovp->iov_addr, s, &dst_phys) != OK)
- panic("umap_local failed");
-#endif
-
- 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_safecopyto(mp->m_source,
- iovp->iov_grant, 0,
- (vir_bytes) rep->v_re_rx_buf+o, s1);
- if (cps != OK) {
- panic("rl_readv_s: sys_safecopyto failed: %d",
- cps);
- }
- cps = sys_safecopyto(mp->m_source,
- iovp->iov_grant, s1,
- (vir_bytes) rep->v_re_rx_buf, s-s1);
- if (cps != OK) {
- panic("rl_readv_s: sys_safecopyto failed: %d", cps);
- }
- }
- else
- {
- cps = sys_safecopyto(mp->m_source,
- iovp->iov_grant, 0,
- (vir_bytes) rep->v_re_rx_buf+o, s);
- if (cps != OK)
- panic("rl_readv_s: sys_safecopyto failed: %d", cps);
- }
-
- size += s;
- if (size == packlen)
- break;
- o += s;
- }
- if (size == packlen)
- break;
- }
- if (size < packlen)
- {
- assert(0);
- }
-
- 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 */
- }
+ netdriver_copyout(data, 0, rep->v_re_rx_buf + o, s);
+ if (s < packlen)
+ netdriver_copyout(data, s, rep->v_re_rx_buf, packlen - s);
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;
}
rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF);
- if (!from_int)
- reply(rep);
-
- 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);
+ return packlen;
}
/*===========================================================================*
- * rl_writev_s *
+ * rl_send *
*===========================================================================*/
-static void rl_writev_s(const message *mp, int from_int)
+static int rl_send(struct netdriver_data *data, size_t size)
{
- 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;
rep= &re_state;
- rep->re_client= mp->m_source;
- count = mp->m_net_netdrv_dl_writev_s.count;
-
- 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;
- goto suspend;
- }
-
- assert(!(rep->re_flags & REF_SEND_AVAIL));
- assert(!(rep->re_flags & REF_PACK_SENT));
+ return SUSPEND;
- 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_s[0]))
- {
- n= IOVEC_NR;
- if (i+n > count)
- n= count-i;
- cps = sys_safecopyfrom(mp->m_source,
- mp->m_net_netdrv_dl_writev_s.grant, iov_offset,
- (vir_bytes) rep->re_iovec_s,
- n * sizeof(rep->re_iovec_s[0]));
- if (cps != OK) {
- panic("rl_writev_s: sys_safecopyfrom failed: %d", cps);
- }
+ netdriver_copyin(data, 0, rep->re_tx[tx_head].v_ret_buf, size);
- for (j= 0, iovp= rep->re_iovec_s; j<n; j++, iovp++)
- {
- s= iovp->iov_size;
- if (size + s > ETH_MAX_PACK_SIZE_TAGGED) {
- panic("invalid packet size");
- }
- cps = sys_safecopyfrom(mp->m_source, iovp->iov_grant,
- 0, (vir_bytes) ret, s);
- if (cps != OK) {
- panic("rl_writev_s: sys_safecopyfrom failed: %d", cps);
- }
- size += s;
- ret += s;
- }
- }
- if (size < ETH_MIN_PACK_SIZE)
- panic("invalid packet size: %d", size);
-
- rl_outl(rep->re_base_port, RL_TSD0+tx_head*4,
- rep->re_ertxth | size);
+ rl_outl(rep->re_base_port, RL_TSD0+tx_head*4, rep->re_ertxth | size);
rep->re_tx[tx_head].ret_busy= TRUE;
+ rep->re_tx_busy++;
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);
- 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);
+ return OK;
}
/*===========================================================================*
* rl_check_ints *
*===========================================================================*/
-static void rl_check_ints(rep)
-re_t *rep;
+static void rl_check_ints(re_t *rep)
{
#if 0
10-1f R/W TSD[0-3] Transmit Status of Descriptor [0-3]
15-0 R RXERCNT Received packet counter
#endif
- int re_flags;
+ if (!rep->re_got_int)
+ return;
+ rep->re_got_int = FALSE;
- re_flags= rep->re_flags;
+ netdriver_recv();
- if ((re_flags & REF_READING) &&
- !(rl_inb(rep->re_base_port, RL_CR) & RL_CR_BUFE))
- {
- rl_readv_s(&rep->re_rx_mess, TRUE /* from int */);
- }
if (rep->re_clear_rx)
rl_clear_rx(rep);
if (rep->re_need_reset)
rl_do_reset(rep);
- if (rep->re_send_int)
- {
- rl_writev_s(&rep->re_tx_mess, TRUE /* from int */);
+ if (rep->re_send_int) {
+ rep->re_send_int = FALSE;
+
+ netdriver_send();
}
- if (rep->re_report_link)
- rl_report_link(rep);
+ if (rep->re_report_link) {
+ rep->re_report_link = FALSE;
- if (rep->re_flags & (REF_PACK_SENT | REF_PACK_RECV))
- reply(rep);
+ rl_report_link(rep);
+ }
}
/*===========================================================================*
* rl_report_link *
*===========================================================================*/
-static void rl_report_link(rep)
-re_t *rep;
+static void rl_report_link(re_t *rep)
{
port_t port;
u16_t mii_ctrl, mii_status, mii_ana, mii_anlpa, mii_ane, mii_extstat;
u8_t msr;
int f, link_up;
- rep->re_report_link= FALSE;
port= rep->re_base_port;
msr= rl_inb(port, RL_MSR);
link_up= !(msr & RL_MSR_LINKB);
return;
}
- if (!debug) goto resspeed;
-
+#if VERBOSE
printf("%s: ", rep->re_name);
mii_print_stat_speed(mii_status, mii_extstat);
printf("\n");
printf("%s: remote cap.: ", rep->re_name);
mii_print_techab(mii_anlpa);
printf("\n");
-
resspeed:
+#endif
+
printf("%s: ", rep->re_name);
printf("link up at %d Mbps, ", (msr & RL_MSR_SPEED_10) ? 10 : 100);
printf("%s duplex\n", ((mii_ctrl & MII_CTRL_DM) ? "full" : "half"));
}
+#if VERBOSE
static void mii_print_techab(u16_t techab)
{
int fs, ft;
}
}
}
+#endif /* VERBOSE */
/*===========================================================================*
* rl_clear_rx *
/*===========================================================================*
* rl_do_reset *
*===========================================================================*/
-static void rl_do_reset(rep)
-re_t *rep;
+static void rl_do_reset(re_t *rep)
{
rep->re_need_reset= FALSE;
rl_reset_hw(rep);
rl_rec_mode(rep);
rep->re_tx_head= 0;
- if (rep->re_flags & REF_SEND_AVAIL)
- {
- rep->re_tx[rep->re_tx_head].ret_busy= FALSE;
- rep->re_send_int= TRUE;
- }
+ if (rep->re_tx[rep->re_tx_head].ret_busy)
+ rep->re_tx_busy--;
+ rep->re_tx[rep->re_tx_head].ret_busy= FALSE;
+ rep->re_send_int= TRUE;
}
/*===========================================================================*
- * rl_getstat_s *
+ * rl_stat *
*===========================================================================*/
-static void rl_getstat_s(mp)
-message *mp;
+static void rl_stat(eth_stat_t *stat)
{
- int r;
- eth_stat_t stats;
- re_t *rep;
-
- rep= &re_state;
-
- assert(rep->re_mode == REM_ENABLED);
- assert(rep->re_flags & REF_ENABLED);
-
- stats= rep->re_stat;
-
- r = sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant,
- 0, (vir_bytes) &stats, sizeof(stats));
- if (r != OK)
- panic("rl_getstat_s: sys_safecopyto failed: %d", r);
-
- mp->m_type= DL_STAT_REPLY;
- r= ipc_send(mp->m_source, mp);
- if (r != OK)
- panic("rl_getstat_s: ipc_send failed: %d", r);
-}
-
-/*===========================================================================*
- * reply *
- *===========================================================================*/
-static void reply(rep)
-re_t *rep;
-{
- message reply;
- int flags;
- int r;
-
- flags = DL_NOFLAGS;
- if (rep->re_flags & REF_PACK_SENT)
- flags |= DL_PACK_SEND;
- if (rep->re_flags & REF_PACK_RECV)
- flags |= DL_PACK_RECV;
-
- reply.m_type = DL_TASK_REPLY;
- reply.m_netdrv_net_dl_task.flags = flags;
- reply.m_netdrv_net_dl_task.count = rep->re_read_s;
-
- r= ipc_send(rep->re_client, &reply);
-
- if (r < 0) {
- printf("RTL8139 tried sending to %d, type %d\n",
- rep->re_client, reply.m_type);
- panic("ipc_send failed: %d", r);
- }
-
- rep->re_read_s = 0;
- rep->re_flags &= ~(REF_PACK_SENT | REF_PACK_RECV);
-}
-
-/*===========================================================================*
- * mess_reply *
- *===========================================================================*/
-static void mess_reply(req, reply_mess)
-message *req;
-message *reply_mess;
-{
- if (ipc_send(req->m_source, reply_mess) != OK)
- panic("unable to mess_reply");
+ memcpy(stat, &re_state.re_stat, sizeof(*stat));
}
#if 0
/*===========================================================================*
* dump_phy *
*===========================================================================*/
-static void dump_phy(rep)
-re_t *rep;
+static void dump_phy(re_t *rep)
{
port_t port;
u32_t t;
}
#endif
-/*===========================================================================*
- * do_hard_int *
- *===========================================================================*/
-static void do_hard_int(void)
-{
- int s;
-
- /* Run interrupt handler at driver level. */
- rl_handler(&re_state);
-
- /* 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);
-}
-
/*===========================================================================*
* rl_handler *
*===========================================================================*/
int i, port, tx_head, tx_tail, link_up;
u16_t isr, tsad;
u32_t tsd, tcr, ertxth;
-#if 0
- u8_t cr;
-#endif
- int_event_check = FALSE; /* disable check by default */
port= rep->re_base_port;
{
rep->re_report_link= TRUE;
rep->re_got_int= TRUE;
- int_event_check = TRUE;
}
}
if (isr & RL_IMR_RXOVW)
/* Clear the receive buffer */
rep->re_clear_rx= TRUE;
rep->re_got_int= TRUE;
- int_event_check = TRUE;
}
if (isr & (RL_ISR_RER | RL_ISR_ROK))
{
isr &= ~(RL_ISR_RER | RL_ISR_ROK);
- if (!rep->re_got_int && (rep->re_flags & REF_READING))
- {
- rep->re_got_int= TRUE;
- int_event_check = TRUE;
- }
- }
-#if 0
- if ((isr & (RL_ISR_TER | RL_ISR_TOK)) &&
- (rep->re_flags & REF_SEND_AVAIL) &&
- (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_handler, SEND_AVAIL: 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(
- "rl_handler: TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
- rl_inw(port, RL_TSAD),
- rl_inl(port, RL_TSD0+0*4),
- rl_inl(port, RL_TSD0+1*4),
- rl_inl(port, RL_TSD0+2*4),
- rl_inl(port, RL_TSD0+3*4));
+ rep->re_got_int= TRUE;
}
-#endif
if ((isr & (RL_ISR_TER | RL_ISR_TOK)) || 1)
{
isr &= ~(RL_ISR_TER | RL_ISR_TOK);
if (tsad & (RL_TSAD_TABT0|RL_TSAD_TABT1|
RL_TSAD_TABT2|RL_TSAD_TABT3))
{
-#if 0
- /* Do we need a watch dog? */
- /* Just reset the whole chip */
- rep->re_need_reset= TRUE;
- rep->re_got_int= TRUE;
- int_event_check = TRUE;
-#elif 0
- /* Reset transmitter */
- rep->re_stat.ets_transAb++;
-
- cr= rl_inb(port, RL_CR);
- cr &= ~RL_CR_TE;
- rl_outb(port, RL_CR, cr);
- SPIN_UNTIL(!(rl_inb(port, RL_CR) & RL_CR_TE), 1000000);
- if (rl_inb(port, RL_CR) & RL_CR_TE) {
- panic("cannot disable transmitter");
- }
- rl_outb(port, RL_CR, cr | RL_CR_TE);
-
- tcr= rl_inl(port, RL_TCR);
- rl_outl(port, RL_TCR, tcr | RL_TCR_IFG_STD);
-
- printf("rl_handler: reset after abort\n");
-
- if (rep->re_flags & REF_SEND_AVAIL)
- {
- printf("rl_handler: REF_SEND_AVAIL\n");
- rep->re_send_int= TRUE;
- rep->re_got_int= TRUE;
- int_event_check = TRUE;
- }
- for (i= 0; i< N_TX_BUF; i++)
- rep->re_tx[i].ret_busy= FALSE;
- rep->re_tx_head= 0;
-#else
printf("rl_handler, TABT, tasd = 0x%04x\n",
tsad);
rep->re_stat.ets_transAb++;
tcr= rl_inl(port, RL_TCR);
rl_outl(port, RL_TCR, tcr | RL_TCR_CLRABT);
-#endif
}
/* Transmit completed */
/* Increase ERTXTH */
ertxth= tsd + (1 << RL_TSD_ERTXTH_S);
ertxth &= RL_TSD_ERTXTH_M;
- if (debug && ertxth > rep->re_ertxth)
+#if VERBOSE
+ if (ertxth > rep->re_ertxth)
{
printf("%s: new ertxth: %d bytes\n",
rep->re_name,
32);
rep->re_ertxth= ertxth;
}
+#endif
}
rep->re_tx[tx_tail].ret_busy= FALSE;
+ rep->re_tx_busy--;
#if 0
- if (rep->re_flags & REF_SEND_AVAIL)
- {
printf("TSD%d: %08lx\n", tx_tail, tsd);
printf(
- "rl_handler: head %d, tail %d, busy: %d %d %d %d\n",
+ "rl_handler: head %d, tail %d, busy: %d %d %d %d\n",
tx_head, tx_tail,
- rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,
+ rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,
rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy);
- }
#endif
if (++tx_tail >= N_TX_BUF)
assert(tx_tail < RL_N_TX);
rep->re_tx_tail= tx_tail;
- if (rep->re_flags & REF_SEND_AVAIL)
- {
-#if 0
- printf("rl_handler: REF_SEND_AVAIL\n");
-#endif
- rep->re_send_int= TRUE;
- if (!rep->re_got_int)
- {
- rep->re_got_int= TRUE;
- int_event_check = TRUE;
- }
- }
+ rep->re_send_int= TRUE;
+ rep->re_got_int= TRUE;
+ rep->re_tx_alive= TRUE;
}
assert(i < 2*N_TX_BUF);
}
}
/*===========================================================================*
- * rl_watchdog_f *
+ * rl_alarm *
*===========================================================================*/
-static void rl_watchdog_f(tp)
-minix_timer_t *tp;
+static void rl_alarm(clock_t __unused stamp)
{
re_t *rep;
+
/* Use a synchronous alarm instead of a watchdog timer. */
- sys_setalarm(system_hz, 0);
+ sys_setalarm(sys_hz(), 0);
rep= &re_state;
- if (rep->re_mode != REM_ENABLED)
- return;
- if (!(rep->re_flags & REF_SEND_AVAIL))
+ assert(rep->re_tx_busy >= 0 && rep->re_tx_busy <= N_TX_BUF);
+ if (rep->re_tx_busy == 0)
{
/* Assume that an idle system is alive */
rep->re_tx_alive= TRUE;
rep->re_tx_alive= FALSE;
return;
}
- printf("rl_watchdog_f: resetting instance %d\n", re_instance);
+ printf("rl_alarm: 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),
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
-
-static void rtl_init(struct dpeth *dep);
-static u16_t get_ee_word(dpeth_t *dep, int a);
-static void ee_wen(dpeth_t *dep);
-static void set_ee_word(dpeth_t *dep, int a, u16_t w);
-static void ee_wds(dpeth_t *dep);
-
-static void rtl_init(dep)
-dpeth_t *dep;
-{
- u8_t reg_a, reg_b, cr, config0, config2, config3;
- int i;
- char val[128];
-
- printf("rtl_init called\n");
- ne_init(dep);
-
- /* ID */
- outb_reg0(dep, DP_CR, CR_PS_P0);
- reg_a = inb_reg0(dep, DP_DUM1);
- reg_b = inb_reg0(dep, DP_DUM2);
-
- printf("rtl_init: '%c', '%c'\n", reg_a, reg_b);
-
- outb_reg0(dep, DP_CR, CR_PS_P3);
- config0 = inb_reg3(dep, 3);
- config2 = inb_reg3(dep, 5);
- config3 = inb_reg3(dep, 6);
- outb_reg0(dep, DP_CR, CR_PS_P0);
-
- printf("rtl_init: config 0/2/3 = %x/%x/%x\n",
- config0, config2, config3);
-
- if (0 == sys_getkenv("RTL8029FD",9+1, val, sizeof(val)))
- {
- printf("rtl_init: setting full-duplex mode\n");
- outb_reg0(dep, DP_CR, CR_PS_P3);
-
- cr= inb_reg3(dep, 1);
- outb_reg3(dep, 1, cr | 0xc0);
-
- outb_reg3(dep, 6, config3 | 0x40);
- config3 = inb_reg3(dep, 6);
-
- config2= inb_reg3(dep, 5);
- outb_reg3(dep, 5, config2 | 0x20);
- config2= inb_reg3(dep, 5);
-
- outb_reg3(dep, 1, cr);
-
- outb_reg0(dep, DP_CR, CR_PS_P0);
-
- printf("rtl_init: config 2 = %x\n", config2);
- printf("rtl_init: config 3 = %x\n", config3);
- }
-
- for (i= 0; i<64; i++)
- printf("%x ", get_ee_word(dep, i));
- printf("\n");
-
- if (0 == sys_getkenv("RTL8029MN",9+1, val, sizeof(val)))
- {
- ee_wen(dep);
-
- set_ee_word(dep, 0x78/2, 0x10ec);
- set_ee_word(dep, 0x7A/2, 0x8029);
- set_ee_word(dep, 0x7C/2, 0x10ec);
- set_ee_word(dep, 0x7E/2, 0x8029);
-
- ee_wds(dep);
-
- assert(get_ee_word(dep, 0x78/2) == 0x10ec);
- assert(get_ee_word(dep, 0x7A/2) == 0x8029);
- assert(get_ee_word(dep, 0x7C/2) == 0x10ec);
- assert(get_ee_word(dep, 0x7E/2) == 0x8029);
- }
-
- if (0 == sys_getkenv("RTL8029XXX",10+1, val, sizeof(val)))
- {
- ee_wen(dep);
-
- set_ee_word(dep, 0x76/2, 0x8029);
-
- ee_wds(dep);
-
- assert(get_ee_word(dep, 0x76/2) == 0x8029);
- }
-}
-
-static u16_t get_ee_word(dep, a)
-dpeth_t *dep;
-int a;
-{
- int b, i, cmd;
- u16_t w;
-
- outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
-
- /* Switch to 9346 mode and enable CS */
- outb_reg3(dep, 1, 0x80 | 0x8);
-
- cmd= 0x180 | (a & 0x3f); /* 1 1 0 a5 a4 a3 a2 a1 a0 */
- for (i= 8; i >= 0; i--)
- {
- b= (cmd & (1 << i));
- b= (b ? 2 : 0);
-
- /* Cmd goes out on the rising edge of the clock */
- outb_reg3(dep, 1, 0x80 | 0x8 | b);
- outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
- }
- outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
-
- w= 0;
- for (i= 0; i<16; i++)
- {
- w <<= 1;
-
- /* Data is shifted out on the rising edge. Read at the
- * falling edge.
- */
- outb_reg3(dep, 1, 0x80 | 0x8 | 0x4);
- outb_reg3(dep, 1, 0x80 | 0x8 | b);
- b= inb_reg3(dep, 1);
- w |= (b & 1);
- }
-
- outb_reg3(dep, 1, 0x80); /* drop CS */
- outb_reg3(dep, 1, 0x00); /* back to normal */
- outb_reg0(dep, DP_CR, CR_PS_P0); /* back to bank 0 */
-
- return w;
-}
-
-static void ee_wen(dep)
-dpeth_t *dep;
-{
- int b, i, cmd;
- u16_t w;
-
- outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
-
- /* Switch to 9346 mode and enable CS */
- outb_reg3(dep, 1, 0x80 | 0x8);
- cmd= 0x130; /* 1 0 0 1 1 x x x x */
- for (i= 8; i >= 0; i--)
- {
- b= (cmd & (1 << i));
- b= (b ? 2 : 0);
-
- /* Cmd goes out on the rising edge of the clock */
- outb_reg3(dep, 1, 0x80 | 0x8 | b);
- outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
- }
- outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
- outb_reg3(dep, 1, 0x80); /* Drop CS */
- /* micro_delay(1); */ /* Is this required? */
-}
-
-static void set_ee_word(dpeth_t *dep, int a, u16_t w)
-dpeth_t *dep;
-int a;
-u16_t w;
-{
- int b, i, cmd;
-
- outb_reg3(dep, 1, 0x80 | 0x8); /* Set CS */
-
- cmd= 0x140 | (a & 0x3f); /* 1 0 1 a5 a4 a3 a2 a1 a0 */
- for (i= 8; i >= 0; i--)
- {
- b= (cmd & (1 << i));
- b= (b ? 2 : 0);
-
- /* Cmd goes out on the rising edge of the clock */
- outb_reg3(dep, 1, 0x80 | 0x8 | b);
- outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
- }
- for (i= 15; i >= 0; i--)
- {
- b= (w & (1 << i));
- b= (b ? 2 : 0);
-
- /* Cmd goes out on the rising edge of the clock */
- outb_reg3(dep, 1, 0x80 | 0x8 | b);
- outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
- }
- outb_reg3(dep, 1, 0x80 | 0x8); /* End of data */
- outb_reg3(dep, 1, 0x80); /* Drop CS */
- /* micro_delay(1); */ /* Is this required? */
- outb_reg3(dep, 1, 0x80 | 0x8); /* Set CS */
- SPIN_UNTIL(inb_reg3(dep, 1) & 1, 10000);
- if (!(inb_reg3(dep, 1) & 1))
- panic("device remains busy");
-}
-
-static void ee_wds(dep)
-dpeth_t *dep;
-{
- int b, i, cmd;
- u16_t w;
-
- outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
-
- /* Switch to 9346 mode and enable CS */
- outb_reg3(dep, 1, 0x80 | 0x8);
-
- cmd= 0x100; /* 1 0 0 0 0 x x x x */
- for (i= 8; i >= 0; i--)
- {
- b= (cmd & (1 << i));
- b= (b ? 2 : 0);
-
- /* Cmd goes out on the rising edge of the clock */
- outb_reg3(dep, 1, 0x80 | 0x8 | b);
- outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
- }
- outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
- outb_reg3(dep, 1, 0x80); /* Drop CS */
- outb_reg3(dep, 1, 0x00); /* back to normal */
- outb_reg0(dep, DP_CR, CR_PS_P0); /* back to bank 0 */
+ rl_check_ints(rep);
}
-#endif
-static void tell_dev(buf, size, pci_bus, pci_dev, pci_func)
-vir_bytes buf;
-size_t size;
-int pci_bus;
-int pci_dev;
-int pci_func;
+/* TODO: obviously this needs a lot of work. */
+static void tell_iommu(vir_bytes buf, size_t size, int pci_bus, int pci_dev,
+ int pci_func)
{
int r;
endpoint_t dev_e;
if (r != OK)
{
#if 0
- printf(
- "rtl8139`tell_dev: ds_retrieve_label_endpt failed for 'amddev': %d\n",
- r);
+ printf("rtl8139`tell_dev: ds_retrieve_label_endpt failed "
+ "for 'amddev': %d\n", r);
#endif
return;
}