From: David van Moolenbroek Date: Wed, 12 Oct 2016 04:41:08 +0000 (+0000) Subject: libnetdriver: rewrite X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=f7df02e7476731c31f12548e38bcadbaf0233f6a;p=minix.git libnetdriver: rewrite This is a driver-breaking update to the netdriver library, which is used by all network drivers. The aim of this change is to make the library more compatible with NetBSD, and in particular with various features that are expected to be supported by the NetBSD userland. The main changes made by this patch are the following: - each network driver now has a NetBSD-style short device name; - drivers are not expected to receive packets right after startup; - extended support for receipt modes, including multicast lists; - support for multiple parallel send, receive requests; - embedding of I/O vectors in send and receive requests; - support for capabilities, including checksum offloading; - support for reporting link status updates to the TCP/IP stack; - support for setting and retrieving media status; - support for changing the hardware (MAC) address; - support for NetBSD interface flags IFF_DEBUG, IFF_LINK[0-2]; - support for NetBSD error statistics; - support for regular time-based ("tick") callbacks. IMPORTANT: this patch applies a minimal update to the existing drivers in order to make them work at all with the new netdriver library. It however does *not* change all drivers to make use of the new features. In fact, strictly speaking, all drivers are now violating requirements imposed by the new library in one way or another, most notably by enabling packet receipt when starting the driver. Changing all the drivers to be compliant, and to support the newly added options, is left to future patches. The existing drivers should currently *not* be taken as examples of how to implement a new network driver! With that said, a few drivers have already been changed to make use of some of the new features: fxp, e1000, rtl8139, and rtl8169 now report link and media status, and the last three of those now support setting the hardware MAC address on the fly. In addition, dp8390 has been changed to default to PCI autoconfiguration if no configuration is specified through environment variables. Change-Id: I4b3ea9c0b9bc25d5b0609c6ff256fb0db71cdc42 --- diff --git a/minix/drivers/net/3c90x/3c90x.c b/minix/drivers/net/3c90x/3c90x.c index dda936005..8b0304cc1 100644 --- a/minix/drivers/net/3c90x/3c90x.c +++ b/minix/drivers/net/3c90x/3c90x.c @@ -10,7 +10,6 @@ #include "3c90x.h" #define VERBOSE 0 /* verbose debugging output */ -#define XLBC_FKEY 11 /* use Shift+Fn to dump statistics (0=off) */ #if VERBOSE #define XLBC_DEBUG(x) printf x @@ -19,8 +18,6 @@ #endif static struct { - char name[sizeof("3c90x#0")]; /* driver name */ - int hook_id; /* IRQ hook ID */ uint8_t *base; /* base address of memory-mapped registers */ uint32_t size; /* size of memory-mapped register area */ @@ -41,8 +38,6 @@ static struct { size_t txb_tail; /* index of tail TX byte in buffer */ size_t txb_used; /* number of in-use TX buffer bytes */ unsigned int upd_head; /* index of head RX descriptor */ - - eth_stat_t stat; /* statistics */ } state; enum xlbc_link_type { @@ -64,24 +59,25 @@ enum xlbc_link_type { #define XLBC_WRITE_32(off, val) \ (*(volatile uint32_t *)(state.base + (off)) = (val)) -static int xlbc_init(unsigned int instance, ether_addr_t *addr); +static int xlbc_init(unsigned int, netdriver_addr_t *, uint32_t *, + unsigned int *); static void xlbc_stop(void); -static void xlbc_mode(unsigned int mode); -static ssize_t xlbc_recv(struct netdriver_data *data, size_t max); -static int xlbc_send(struct netdriver_data *data, size_t size); -static void xlbc_stat(eth_stat_t *stat); -static void xlbc_intr(unsigned int mask); -static void xlbc_other(const message *m_ptr, int ipc_status); +static void xlbc_set_mode(unsigned int, const netdriver_addr_t *, + unsigned int); +static ssize_t xlbc_recv(struct netdriver_data *, size_t); +static int xlbc_send(struct netdriver_data *, size_t); +static void xlbc_intr(unsigned int); +static void xlbc_tick(void); static const struct netdriver xlbc_table = { + .ndr_name = "xl", .ndr_init = xlbc_init, .ndr_stop = xlbc_stop, - .ndr_mode = xlbc_mode, + .ndr_set_mode = xlbc_set_mode, .ndr_recv = xlbc_recv, .ndr_send = xlbc_send, - .ndr_stat = xlbc_stat, .ndr_intr = xlbc_intr, - .ndr_other = xlbc_other, + .ndr_tick = xlbc_tick }; /* @@ -108,7 +104,7 @@ xlbc_probe(unsigned int skip) #if VERBOSE dname = pci_dev_name(vid, did); - XLBC_DEBUG(("%s: found %s (%04x:%04x) at %s\n", state.name, + XLBC_DEBUG(("%s: found %s (%04x:%04x) at %s\n", netdriver_name(), dname ? dname : "", vid, did, pci_slot_name(devind))); #endif @@ -223,7 +219,7 @@ xlbc_read_eeprom(unsigned int word) * Obtain the preconfigured hardware address of the device. */ static void -xlbc_get_hwaddr(ether_addr_t * addr) +xlbc_get_hwaddr(netdriver_addr_t * addr) { uint16_t word[3]; @@ -233,34 +229,35 @@ xlbc_get_hwaddr(ether_addr_t * addr) word[1] = xlbc_read_eeprom(XLBC_EEPROM_WORD_OEM_ADDR1); word[2] = xlbc_read_eeprom(XLBC_EEPROM_WORD_OEM_ADDR2); - addr->ea_addr[0] = word[0] >> 8; - addr->ea_addr[1] = word[0] & 0xff; - addr->ea_addr[2] = word[1] >> 8; - addr->ea_addr[3] = word[1] & 0xff; - addr->ea_addr[4] = word[2] >> 8; - addr->ea_addr[5] = word[2] & 0xff; + addr->na_addr[0] = word[0] >> 8; + addr->na_addr[1] = word[0] & 0xff; + addr->na_addr[2] = word[1] >> 8; + addr->na_addr[3] = word[1] & 0xff; + addr->na_addr[4] = word[2] >> 8; + addr->na_addr[5] = word[2] & 0xff; XLBC_DEBUG(("%s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", - state.name, addr->ea_addr[0], addr->ea_addr[1], addr->ea_addr[2], - addr->ea_addr[3], addr->ea_addr[4], addr->ea_addr[5])); + netdriver_name(), + addr->na_addr[0], addr->na_addr[1], addr->na_addr[2], + addr->na_addr[3], addr->na_addr[4], addr->na_addr[5])); } /* * Configure the device to use the given hardware address. */ static void -xlbc_set_hwaddr(ether_addr_t * addr) +xlbc_set_hwaddr(netdriver_addr_t * addr) { xlbc_select_window(XLBC_STATION_WINDOW); /* Set station address. */ XLBC_WRITE_16(XLBC_STATION_ADDR0_REG, - addr->ea_addr[0] | (addr->ea_addr[1] << 8)); + addr->na_addr[0] | (addr->na_addr[1] << 8)); XLBC_WRITE_16(XLBC_STATION_ADDR1_REG, - addr->ea_addr[2] | (addr->ea_addr[3] << 8)); + addr->na_addr[2] | (addr->na_addr[3] << 8)); XLBC_WRITE_16(XLBC_STATION_ADDR2_REG, - addr->ea_addr[4] | (addr->ea_addr[5] << 8)); + addr->na_addr[4] | (addr->na_addr[5] << 8)); /* Set station mask. */ XLBC_WRITE_16(XLBC_STATION_MASK0_REG, 0); @@ -527,7 +524,7 @@ xlbc_mii_write(uint16_t phy, uint16_t reg, uint16_t data) /* * Return a human-readable description for the given link type. */ -#if VERBOSE || XLBC_FKEY +#if VERBOSE static const char * xlbc_get_link_name(enum xlbc_link_type link_type) { @@ -542,7 +539,7 @@ xlbc_get_link_name(enum xlbc_link_type link_type) default: return "(unknown)"; } } -#endif /* VERBOSE || XLBC_FKEY */ +#endif /* VERBOSE */ /* * Determine the current link status, and return the resulting link type. @@ -625,7 +622,7 @@ xlbc_set_duplex(enum xlbc_link_type link) * on a link change, so we're probably not doing much extra damage. * TODO: recovery for packets currently on the transmission queue. */ - XLBC_DEBUG(("%s: %s full-duplex mode\n", state.name, + XLBC_DEBUG(("%s: %s full-duplex mode\n", netdriver_name(), duplex ? "setting" : "clearing")); XLBC_WRITE_16(XLBC_MAC_CTRL_REG, word ^ XLBC_MAC_CTRL_ENA_FD); @@ -654,7 +651,7 @@ xlbc_link_event(void) link_type = xlbc_get_link_type(); #if VERBOSE - XLBC_DEBUG(("%s: link %s\n", state.name, + XLBC_DEBUG(("%s: link %s\n", netdriver_name(), xlbc_get_link_name(link_type))); #endif @@ -665,7 +662,7 @@ xlbc_link_event(void) * Initialize the device. */ static void -xlbc_init_hw(int devind, ether_addr_t * addr) +xlbc_init_hw(int devind, netdriver_addr_t * addr) { uint32_t bar; uint16_t cr; @@ -734,16 +731,12 @@ xlbc_init_hw(int devind, ether_addr_t * addr) * Initialize the 3c90x driver and device. */ static int -xlbc_init(unsigned int instance, ether_addr_t * addr) +xlbc_init(unsigned int instance, netdriver_addr_t * addr, uint32_t * caps, + unsigned int * ticks) { int devind; -#if XLBC_FKEY - int fkeys, sfkeys; -#endif memset(&state, 0, sizeof(state)); - strlcpy(state.name, "3c90x#0", sizeof(state.name)); - state.name[sizeof(state.name) - 2] += instance; /* Try to find a recognized device. */ if ((devind = xlbc_probe(instance)) < 0) @@ -752,13 +745,8 @@ xlbc_init(unsigned int instance, ether_addr_t * addr) /* Initialize the device. */ xlbc_init_hw(devind, addr); -#if XLBC_FKEY - /* Register debug dump function key. */ - fkeys = sfkeys = 0; - bit_set(sfkeys, XLBC_FKEY); - (void)fkey_map(&fkeys, &sfkeys); /* ignore failure */ -#endif - + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; + *ticks = sys_hz() / 10; /* update statistics 10x/sec */ return OK; } @@ -777,16 +765,17 @@ xlbc_stop(void) * Set packet receipt mode. */ static void -xlbc_mode(unsigned int mode) +xlbc_set_mode(unsigned int mode, const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) { state.filter = XLBC_FILTER_STATION; - if (mode & NDEV_MULTI) + if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) state.filter |= XLBC_FILTER_MULTI; - if (mode & NDEV_BROAD) + if (mode & NDEV_MODE_BCAST) state.filter |= XLBC_FILTER_BROAD; - if (mode & NDEV_PROMISC) + if (mode & NDEV_MODE_PROMISC) state.filter |= XLBC_FILTER_PROMISC; xlbc_issue_cmd(XLBC_CMD_SET_FILTER | state.filter); @@ -814,22 +803,16 @@ xlbc_recv(struct netdriver_data * data, size_t max) return SUSPEND; if (flags & XLBC_UP_ERROR) { - XLBC_DEBUG(("%s: received error\n", state.name)); + XLBC_DEBUG(("%s: received error\n", netdriver_name())); - state.stat.ets_recvErr++; - if (flags & XLBC_UP_OVERRUN) - state.stat.ets_fifoOver++; - if (flags & XLBC_UP_ALIGN_ERR) - state.stat.ets_frameAll++; - if (flags & XLBC_UP_CRC_ERR) - state.stat.ets_CRCerr++; + netdriver_stat_ierror(1); len = 0; /* immediately move on to the next descriptor */ } else { len = flags & XLBC_UP_LEN; - XLBC_DEBUG(("%s: received packet (size %zu)\n", state.name, - len)); + XLBC_DEBUG(("%s: received packet (size %zu)\n", + netdriver_name(), len)); /* The device is supposed to not give us runt frames. */ assert(len >= XLBC_MIN_PKT_LEN); @@ -902,7 +885,8 @@ xlbc_send(struct netdriver_data * data, size_t size) if (left < size) return SUSPEND; - XLBC_DEBUG(("%s: transmitting packet (size %zu)\n", state.name, size)); + XLBC_DEBUG(("%s: transmitting packet (size %zu)\n", + netdriver_name(), size)); /* Copy in the packet. */ off = (state.txb_tail + used) % XLBC_TXB_SIZE; @@ -966,7 +950,8 @@ xlbc_advance_tx(void) if (!(flags & XLBC_DN_DN_COMPLETE)) break; - XLBC_DEBUG(("%s: packet copied to transmitter\n", state.name)); + XLBC_DEBUG(("%s: packet copied to transmitter\n", + netdriver_name())); len = state.dpd_base[state.dpd_tail].len & ~XLBC_LEN_LAST; @@ -995,25 +980,20 @@ xlbc_recover_tx(void) while ((status = XLBC_READ_8(XLBC_TX_STATUS_REG)) & XLBC_TX_STATUS_COMPLETE) { - XLBC_DEBUG(("%s: transmission error (0x%04x)\n", state.name, - status)); + XLBC_DEBUG(("%s: transmission error (0x%04x)\n", + netdriver_name(), status)); /* This is an internal (non-packet) error status. */ if (status & XLBC_TX_STATUS_OVERFLOW) enable = TRUE; if (status & XLBC_TX_STATUS_MAX_COLL) { - state.stat.ets_sendErr++; - state.stat.ets_transAb++; + netdriver_stat_coll(1); enable = TRUE; } - if (status & XLBC_TX_STATUS_UNDERRUN) { - state.stat.ets_sendErr++; - state.stat.ets_fifoUnder++; - reset = TRUE; - } - if (status & XLBC_TX_STATUS_JABBER) { - state.stat.ets_sendErr++; + if (status & + (XLBC_TX_STATUS_UNDERRUN | XLBC_TX_STATUS_JABBER)) { + netdriver_stat_oerror(1); reset = TRUE; } @@ -1047,7 +1027,7 @@ xlbc_recover_tx(void) XLBC_WRITE_32(XLBC_DN_LIST_PTR_REG, state.dpd_phys + state.dpd_tail * sizeof(xlbc_pd_t)); - XLBC_DEBUG(("%s: performed recovery\n", state.name)); + XLBC_DEBUG(("%s: performed recovery\n", netdriver_name())); } else if (enable) xlbc_issue_cmd(XLBC_CMD_TX_ENABLE); } @@ -1059,24 +1039,20 @@ xlbc_recover_tx(void) static void xlbc_update_stats(void) { - uint8_t upper, up_rx, up_tx; xlbc_select_window(XLBC_STATS_WINDOW); - state.stat.ets_carrSense += XLBC_READ_8(XLBC_CARRIER_LOST_REG); + (void)XLBC_READ_8(XLBC_CARRIER_LOST_REG); (void)XLBC_READ_8(XLBC_SQE_ERR_REG); - state.stat.ets_collision += XLBC_READ_8(XLBC_MULTI_COLL_REG); - state.stat.ets_collision += XLBC_READ_8(XLBC_SINGLE_COLL_REG); - state.stat.ets_OWC += XLBC_READ_8(XLBC_LATE_COLL_REG); - state.stat.ets_missedP += XLBC_READ_8(XLBC_RX_OVERRUNS_REG); - state.stat.ets_transDef += XLBC_READ_8(XLBC_FRAMES_DEFERRED_REG); + netdriver_stat_coll(XLBC_READ_8(XLBC_MULTI_COLL_REG)); + netdriver_stat_coll(XLBC_READ_8(XLBC_SINGLE_COLL_REG)); + netdriver_stat_coll(XLBC_READ_8(XLBC_LATE_COLL_REG)); + netdriver_stat_ierror(XLBC_READ_8(XLBC_RX_OVERRUNS_REG)); + (void)XLBC_READ_8(XLBC_FRAMES_DEFERRED_REG); - upper = XLBC_READ_8(XLBC_UPPER_FRAMES_REG); - up_tx = ((upper & XLBC_UPPER_TX_MASK) >> XLBC_UPPER_TX_SHIFT) << 8; - up_rx = ((upper & XLBC_UPPER_RX_MASK) >> XLBC_UPPER_RX_SHIFT) << 8; - - state.stat.ets_packetT += XLBC_READ_8(XLBC_FRAMES_XMIT_OK_REG) + up_tx; - state.stat.ets_packetR += XLBC_READ_8(XLBC_FRAMES_RCVD_OK_REG) + up_rx; + (void)XLBC_READ_8(XLBC_UPPER_FRAMES_REG); + (void)XLBC_READ_8(XLBC_FRAMES_XMIT_OK_REG); + (void)XLBC_READ_8(XLBC_FRAMES_RCVD_OK_REG); (void)XLBC_READ_16(XLBC_BYTES_RCVD_OK_REG); (void)XLBC_READ_16(XLBC_BYTES_XMIT_OK_REG); @@ -1086,18 +1062,6 @@ xlbc_update_stats(void) (void)XLBC_READ_8(XLBC_BAD_SSD_REG); } -/* - * Copy out statistics. - */ -static void -xlbc_stat(eth_stat_t * stat) -{ - - xlbc_update_stats(); - - memcpy(stat, &state.stat, sizeof(*stat)); -} - /* * Process an interrupt. */ @@ -1116,7 +1080,7 @@ xlbc_intr(unsigned int __unused mask) */ val = XLBC_READ_16(XLBC_STATUS_AUTO_REG); - XLBC_DEBUG(("%s: interrupt (0x%04x)\n", state.name, val)); + XLBC_DEBUG(("%s: interrupt (0x%04x)\n", netdriver_name(), val)); if (val & XLBC_STATUS_UP_COMPLETE) netdriver_recv(); @@ -1136,7 +1100,8 @@ xlbc_intr(unsigned int __unused mask) * Since this entire condition is effectively untestable, we * do not even try to be smart about it. */ - XLBC_DEBUG(("%s: host error, performing reset\n", state.name)); + XLBC_DEBUG(("%s: host error, performing reset\n", + netdriver_name())); xlbc_reset_tx(); @@ -1166,61 +1131,13 @@ xlbc_intr(unsigned int __unused mask) } /* - * Dump statistics. + * Do regular processing. */ -#if XLBC_FKEY static void -xlbc_dump(void) +xlbc_tick(void) { - enum xlbc_link_type link_type; - - link_type = xlbc_get_link_type(); xlbc_update_stats(); - - printf("\n"); - printf("%s statistics:\n", state.name); - - printf("recvErr: %8ld\t", state.stat.ets_recvErr); - printf("sendErr: %8ld\t", state.stat.ets_sendErr); - printf("OVW: %8ld\n", state.stat.ets_OVW); - - printf("CRCerr: %8ld\t", state.stat.ets_CRCerr); - printf("frameAll: %8ld\t", state.stat.ets_frameAll); - printf("missedP: %8ld\n", state.stat.ets_missedP); - - printf("packetR: %8ld\t", state.stat.ets_packetR); - printf("packetT: %8ld\t", state.stat.ets_packetT); - printf("transDef: %8ld\n", state.stat.ets_transDef); - - printf("collision: %8ld\t", state.stat.ets_collision); - printf("transAb: %8ld\t", state.stat.ets_transAb); - printf("carrSense: %8ld\n", state.stat.ets_carrSense); - - printf("fifoUnder: %8ld\t", state.stat.ets_fifoUnder); - printf("fifoOver: %8ld\t", state.stat.ets_fifoOver); - printf("CDheartbeat: %8ld\n", state.stat.ets_CDheartbeat); - - printf("OWC: %8ld\t", state.stat.ets_OWC); - printf("link: %s\n", xlbc_get_link_name(link_type)); -} -#endif /* XLBC_FKEY */ - -/* - * Process miscellaneous messages. - */ -static void -xlbc_other(const message * m_ptr, int ipc_status) -{ -#if XLBC_FKEY - int sfkeys; - - if (!is_ipc_notify(ipc_status) || m_ptr->m_source != TTY_PROC_NR) - return; - - if (fkey_events(NULL, &sfkeys) == OK && bit_isset(sfkeys, XLBC_FKEY)) - xlbc_dump(); -#endif /* XLBC_FKEY */ } /* diff --git a/minix/drivers/net/3c90x/3c90x.h b/minix/drivers/net/3c90x/3c90x.h index 96ebf44d6..6ce637c0f 100644 --- a/minix/drivers/net/3c90x/3c90x.h +++ b/minix/drivers/net/3c90x/3c90x.h @@ -21,8 +21,8 @@ #define XLBC_TXB_SIZE 48128 /* TX buffer size in bytes */ #define XLBC_UPD_COUNT 32 /* RX descriptor count */ -#define XLBC_MIN_PKT_LEN ETH_MIN_PACK_SIZE -#define XLBC_MAX_PKT_LEN ETH_MAX_PACK_SIZE_TAGGED +#define XLBC_MIN_PKT_LEN NDEV_ETH_PACKET_MIN +#define XLBC_MAX_PKT_LEN NDEV_ETH_PACKET_MAX_TAGGED #define XLBC_MIN_REG_SIZE 128 /* min. register memory size */ diff --git a/minix/drivers/net/3c90x/Makefile b/minix/drivers/net/3c90x/Makefile index 1358767d6..f7a9000fd 100644 --- a/minix/drivers/net/3c90x/Makefile +++ b/minix/drivers/net/3c90x/Makefile @@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d DPADD+= ${LIBNETDRIVER} ${LIBSYS} LDADD+= -lnetdriver -lsys +WARNS?= 5 + .include diff --git a/minix/drivers/net/atl2/Makefile b/minix/drivers/net/atl2/Makefile index 4165db4c3..202ada0ac 100644 --- a/minix/drivers/net/atl2/Makefile +++ b/minix/drivers/net/atl2/Makefile @@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d DPADD+= ${LIBNETDRIVER} ${LIBSYS} LDADD+= -lnetdriver -lsys +WARNS?= 5 + .include diff --git a/minix/drivers/net/atl2/atl2.c b/minix/drivers/net/atl2/atl2.c index e9f332fbd..454515e09 100644 --- a/minix/drivers/net/atl2/atl2.c +++ b/minix/drivers/net/atl2/atl2.c @@ -14,7 +14,6 @@ #include "atl2.h" #define VERBOSE 0 /* Verbose debugging output */ -#define ATL2_FKEY 11 /* Use Shift+Fn to dump statistics (0=off) */ #if VERBOSE #define ATL2_DEBUG(x) printf x @@ -54,8 +53,6 @@ static struct { int rxd_tail; /* tail index into RxD, in elements */ int rx_avail; /* is there a packet available for receipt? */ - - eth_stat_t stat; /* statistics */ } state; #define ATL2_READ_U8(off) (*(volatile uint8_t *)(state.base + (off))) @@ -70,24 +67,23 @@ static struct { #define ATL2_ALIGN_32(n) (((n) + 3) & ~3) -static int atl2_init(unsigned int instance, ether_addr_t *addr); +static int atl2_init(unsigned int, netdriver_addr_t *, uint32_t *, + unsigned int *); static void atl2_stop(void); -static void atl2_mode(unsigned int mode); -static int atl2_send(struct netdriver_data *data, size_t size); -static ssize_t atl2_recv(struct netdriver_data *data, size_t max); -static void atl2_stat(eth_stat_t *stat); +static void atl2_set_mode(unsigned int, const netdriver_addr_t *, + unsigned int); +static int atl2_send(struct netdriver_data *, size_t); +static ssize_t atl2_recv(struct netdriver_data *, size_t); static void atl2_intr(unsigned int mask); -static void atl2_other(const message *m_ptr, int ipc_status); static const struct netdriver atl2_table = { + .ndr_name = "lii", .ndr_init = atl2_init, .ndr_stop = atl2_stop, - .ndr_mode = atl2_mode, + .ndr_set_mode = atl2_set_mode, .ndr_recv = atl2_recv, .ndr_send = atl2_send, - .ndr_stat = atl2_stat, .ndr_intr = atl2_intr, - .ndr_other = atl2_other }; /* @@ -115,7 +111,8 @@ atl2_read_vpd(int index, uint32_t * res) } if (i == ATL2_VPD_NTRIES) { - printf("ATL2: timeout reading EEPROM register %d\n", index); + printf("%s: timeout reading EEPROM register %d\n", + netdriver_name(), index); return FALSE; } @@ -181,27 +178,28 @@ atl2_get_vpd_hwaddr(void) * use whatever the card was already set to. */ static void -atl2_get_hwaddr(ether_addr_t * addr) +atl2_get_hwaddr(netdriver_addr_t * addr) { if (!atl2_get_vpd_hwaddr()) { - printf("ATL2: unable to read from VPD\n"); + printf("%s: unable to read from VPD\n", netdriver_name()); state.hwaddr[0] = ATL2_READ_U32(ATL2_HWADDR0_REG); state.hwaddr[1] = ATL2_READ_U32(ATL2_HWADDR1_REG) & 0xffff; } - ATL2_DEBUG(("ATL2: MAC address %04x%08x\n", - state.hwaddr[1], state.hwaddr[0])); + ATL2_DEBUG(("%s: MAC address %04x%08x\n", + netdriver_name(), state.hwaddr[1], state.hwaddr[0])); - 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->na_addr[0] = state.hwaddr[1] >> 8; + addr->na_addr[1] = state.hwaddr[1] & 0xff; + addr->na_addr[2] = state.hwaddr[0] >> 24; + addr->na_addr[3] = (state.hwaddr[0] >> 16) & 0xff; + addr->na_addr[4] = (state.hwaddr[0] >> 8) & 0xff; + addr->na_addr[5] = state.hwaddr[0] & 0xff; } +#if 0 /* TODO: link status */ /* * Read a MII PHY register using MDIO. */ @@ -231,6 +229,7 @@ atl2_read_mdio(int addr, uint16_t * res) *res = (uint16_t)(rval & ATL2_MDIO_DATA_MASK); return TRUE; } +#endif /* * Allocate DMA ring buffers. @@ -340,18 +339,19 @@ atl2_reset(void) * settings. */ static void -atl2_mode(unsigned int mode) +atl2_set_mode(unsigned int mode, const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) { uint32_t val; val = ATL2_READ_U32(ATL2_MAC_REG); val &= ~(ATL2_MAC_PROMISC_EN | ATL2_MAC_MCAST_EN | ATL2_MAC_BCAST_EN); - if (mode & NDEV_PROMISC) + if (mode & NDEV_MODE_PROMISC) val |= ATL2_MAC_PROMISC_EN; - if (mode & NDEV_MULTI) + if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) val |= ATL2_MAC_MCAST_EN; - if (mode & NDEV_BROAD) + if (mode & NDEV_MODE_BCAST) val |= ATL2_MAC_BCAST_EN; ATL2_WRITE_U32(ATL2_MAC_REG, val); @@ -428,7 +428,7 @@ atl2_setup(void) /* Did everything go alright? */ val = ATL2_READ_U32(ATL2_ISR_REG); if (val & ATL2_ISR_PHY_LINKDOWN) { - printf("ATL2: initialization failed\n"); + printf("%s: initialization failed\n", netdriver_name()); return FALSE; } @@ -442,15 +442,10 @@ atl2_setup(void) /* Configure MAC. */ ATL2_WRITE_U32(ATL2_MAC_REG, ATL2_MAC_DEFAULT); - /* - * Inet does not tell us about the multicast addresses that it is - * interested in, so we have to simply accept all multicast packets. - */ + /* TODO: multicast lists. */ ATL2_WRITE_U32(ATL2_MHT0_REG, 0xffffffff); ATL2_WRITE_U32(ATL2_MHT1_REG, 0xffffffff); - atl2_mode(NDEV_NOMODE); - /* Enable Tx/Rx. */ val = ATL2_READ_U32(ATL2_MAC_REG); ATL2_WRITE_U32(ATL2_MAC_REG, val | ATL2_MAC_TX_EN | ATL2_MAC_RX_EN); @@ -466,7 +461,7 @@ atl2_probe(int skip) { uint16_t vid, did; #if VERBOSE - char *dname; + const char *dname; #endif int r, devind; @@ -484,7 +479,7 @@ atl2_probe(int skip) #if VERBOSE dname = pci_dev_name(vid, did); - ATL2_DEBUG(("ATL2: found %s (%x/%x) at %s\n", + ATL2_DEBUG(("%s: found %s (%x/%x) at %s\n", netdriver_name(), dname ? dname : "", vid, did, pci_slot_name(devind))); #endif @@ -497,7 +492,7 @@ atl2_probe(int skip) * Initialize the device. */ static void -atl2_init_hw(int devind, ether_addr_t * addr) +atl2_init_hw(int devind, netdriver_addr_t * addr) { uint32_t bar; int r, flag; @@ -543,22 +538,12 @@ atl2_tx_stat(uint32_t stat) { if (stat & ATL2_TXS_SUCCESS) - state.stat.ets_packetT++; + return; + + if (stat & (ATL2_TXS_SINGLECOL | ATL2_TXS_MULTICOL | ATL2_TXS_LATECOL)) + netdriver_stat_coll(1); else - state.stat.ets_recvErr++; - - if (stat & ATL2_TXS_DEFER) - state.stat.ets_transDef++; - if (stat & (ATL2_TXS_EXCDEFER | ATL2_TXS_ABORTCOL)) - state.stat.ets_transAb++; - if (stat & ATL2_TXS_SINGLECOL) - state.stat.ets_collision++; - if (stat & ATL2_TXS_MULTICOL) - state.stat.ets_collision++; - if (stat & ATL2_TXS_LATECOL) - state.stat.ets_OWC++; - if (stat & ATL2_TXS_UNDERRUN) - state.stat.ets_fifoUnder++; + netdriver_stat_oerror(1); } /* @@ -568,19 +553,8 @@ static void atl2_rx_stat(uint32_t stat) { - if (stat & ATL2_RXD_SUCCESS) - state.stat.ets_packetR++; - else - state.stat.ets_recvErr++; - - if (stat & ATL2_RXD_CRCERR) - state.stat.ets_CRCerr++; - if (stat & ATL2_RXD_FRAG) - state.stat.ets_collision++; - if (stat & ATL2_RXD_TRUNC) - state.stat.ets_fifoOver++; - if (stat & ATL2_RXD_ALIGN) - state.stat.ets_frameAll++; + if (!(stat & ATL2_RXD_SUCCESS)) + netdriver_stat_ierror(1); } /* @@ -612,8 +586,8 @@ atl2_tx_advance(void) dsize = *(volatile uint32_t *)(state.txd_base + state.txd_tail); if (size != dsize) - printf("ATL2: TxD/TxS size mismatch (%x vs %x)\n", - size, dsize); + printf("%s: TxD/TxS size mismatch (%x vs %x)\n", + netdriver_name(), size, dsize); /* Advance tails accordingly. */ size = sizeof(uint32_t) + ATL2_ALIGN_32(dsize); @@ -625,9 +599,11 @@ atl2_tx_advance(void) state.txs_num--; if (stat & ATL2_TXS_SUCCESS) - ATL2_DEBUG(("ATL2: successfully sent packet\n")); + ATL2_DEBUG(("%s: successfully sent packet\n", + netdriver_name())); else - ATL2_DEBUG(("ATL2: failed to send packet\n")); + ATL2_DEBUG(("%s: failed to send packet\n", + netdriver_name())); /* Update statistics. */ atl2_tx_stat(stat); @@ -657,7 +633,8 @@ atl2_rx_advance(int next) state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT; update_tail = TRUE; - ATL2_DEBUG(("ATL2: successfully received packet\n")); + ATL2_DEBUG(("%s: successfully received packet\n", + netdriver_name())); state.rx_avail = FALSE; } @@ -685,15 +662,15 @@ atl2_rx_advance(int next) size = hdr & ATL2_RXD_SIZE_MASK; if ((hdr & ATL2_RXD_SUCCESS) && - size >= ETH_MIN_PACK_SIZE + ETH_CRC_SIZE) { - ATL2_DEBUG(("ATL2: packet available, size %zu\n", - size)); + size >= NDEV_ETH_PACKET_MIN + NDEV_ETH_PACKET_CRC) { + ATL2_DEBUG(("%s: packet available, size %zu\n", + netdriver_name(), size)); state.rx_avail = TRUE; break; } - ATL2_DEBUG(("ATL2: packet receipt failed\n")); + ATL2_DEBUG(("%s: packet receipt failed\n", netdriver_name())); /* Advance tail. */ state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT; @@ -725,9 +702,10 @@ atl2_recv(struct netdriver_data * data, size_t max) rxd = &state.rxd_base[state.rxd_tail]; size = rxd->hdr & ATL2_RXD_SIZE_MASK; - size -= ETH_CRC_SIZE; + size -= NDEV_ETH_PACKET_CRC; - ATL2_DEBUG(("ATL2: receiving packet with length %zu\n", size)); + ATL2_DEBUG(("%s: receiving packet with length %zu\n", + netdriver_name(), size)); /* Truncate large packets. */ if (size > max) @@ -810,7 +788,7 @@ atl2_intr(unsigned int __unused mask) ATL2_WRITE_U32(ATL2_ISR_REG, val | ATL2_ISR_DISABLE); - ATL2_DEBUG(("ATL2: interrupt (0x%08x)\n", val)); + ATL2_DEBUG(("%s: interrupt (0x%08x)\n", netdriver_name(), val)); /* If an error occurred, reset the card. */ if (val & (ATL2_ISR_DMAR_TIMEOUT | ATL2_ISR_DMAW_TIMEOUT | @@ -847,16 +825,7 @@ atl2_intr(unsigned int __unused mask) netdriver_recv(); } -/* - * Copy out statistics. - */ -static void -atl2_stat(eth_stat_t * stat) -{ - - memcpy(stat, &state.stat, sizeof(*stat)); -} - +#if 0 /* TODO: link status (using part of this code) */ /* * Dump link status. */ @@ -892,76 +861,16 @@ atl2_dump_link(void) printf("%s duplex)", (val & ATL2_MII_PSSR_DUPLEX) ? "full" : "half"); } - -/* - * Dump statistics. - */ -static void -atl2_dump(void) -{ - - printf("\n"); - printf("Attansic L2 statistics:\n"); - - printf("recvErr: %8ld\t", state.stat.ets_recvErr); - printf("sendErr: %8ld\t", state.stat.ets_sendErr); - printf("OVW: %8ld\n", state.stat.ets_OVW); - - printf("CRCerr: %8ld\t", state.stat.ets_CRCerr); - printf("frameAll: %8ld\t", state.stat.ets_frameAll); - printf("missedP: %8ld\n", state.stat.ets_missedP); - - printf("packetR: %8ld\t", state.stat.ets_packetR); - printf("packetT: %8ld\t", state.stat.ets_packetT); - printf("transDef: %8ld\n", state.stat.ets_transDef); - - printf("collision: %8ld\t", state.stat.ets_collision); - printf("transAb: %8ld\t", state.stat.ets_transAb); - printf("carrSense: %8ld\n", state.stat.ets_carrSense); - - printf("fifoUnder: %8ld\t", state.stat.ets_fifoUnder); - printf("fifoOver: %8ld\t", state.stat.ets_fifoOver); - printf("CDheartbeat: %8ld\n", state.stat.ets_CDheartbeat); - - printf("OWC: %8ld\t", state.stat.ets_OWC); - printf("TxD tail: %8d\t", state.txd_tail); - printf("TxD count: %8d\n", state.txd_num); - - printf("RxD tail: %8d\t", state.rxd_tail); - printf("TxS tail: %8d\t", state.txs_tail); - printf("TxS count: %8d\n", state.txs_num); - - atl2_dump_link(); - printf("\n"); -} - -/* - * Process miscellaneous messages. - */ -static void -atl2_other(const message * m_ptr, int ipc_status) -{ -#if ATL2_FKEY - int sfkeys; - - if (!is_ipc_notify(ipc_status) || m_ptr->m_source != TTY_PROC_NR) - return; - - if (fkey_events(NULL, &sfkeys) == OK && bit_isset(sfkeys, ATL2_FKEY)) - atl2_dump(); #endif -} /* * Initialize the atl2 driver. */ static int -atl2_init(unsigned int instance, ether_addr_t * addr) +atl2_init(unsigned int instance, netdriver_addr_t * addr, uint32_t * caps, + unsigned int * ticks __unused) { int devind; -#if ATL2_FKEY - int r, fkeys, sfkeys; -#endif memset(&state, 0, sizeof(state)); @@ -974,15 +883,7 @@ atl2_init(unsigned int instance, ether_addr_t * addr) /* Initialize the device. */ atl2_init_hw(devind, addr); -#if ATL2_FKEY - /* Register debug dump function key. */ - fkeys = sfkeys = 0; - bit_set(sfkeys, ATL2_FKEY); - if ((r = fkey_map(&fkeys, &sfkeys)) != OK) - printf("ATL2: warning, could not map Shift+F%u key (%d)\n", - r, ATL2_FKEY); -#endif - + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; return OK; } diff --git a/minix/drivers/net/atl2/atl2.h b/minix/drivers/net/atl2/atl2.h index 7d53c4741..c7d6cc565 100644 --- a/minix/drivers/net/atl2/atl2.h +++ b/minix/drivers/net/atl2/atl2.h @@ -94,7 +94,7 @@ # define ATL2_ICT_DEFAULT 50000 /* 100 ms */ #define ATL2_MTU_REG 0x149c /* MTU config */ -# define ATL2_MTU_DEFAULT ETH_MAX_PACK_SIZE_TAGGED +# define ATL2_MTU_DEFAULT NDEV_ETH_PACKET_MAX #define ATL2_CUT_THRESH_REG 0x1590 /* cut-through config */ # define ATL2_CUT_THRESH_DEFAULT 0x177 /* (magic) */ diff --git a/minix/drivers/net/dec21140A/Makefile b/minix/drivers/net/dec21140A/Makefile index 6ef33c09a..c388360f0 100644 --- a/minix/drivers/net/dec21140A/Makefile +++ b/minix/drivers/net/dec21140A/Makefile @@ -11,4 +11,6 @@ LDADD+= -lnetdriver -lsys CPPFLAGS+= -Ddebug=0 +WARNS?= 5 + .include diff --git a/minix/drivers/net/dec21140A/README.txt b/minix/drivers/net/dec21140A/README.txt index d62ccb8c7..99eb37455 100644 --- a/minix/drivers/net/dec21140A/README.txt +++ b/minix/drivers/net/dec21140A/README.txt @@ -10,19 +10,4 @@ This driver supports only the Dec21140A as emulated by VPC2007. It is untested in any other environment and will probably panic if you use it outside VPC2007. -The driver supports bridged, nat and local network settings. See the -next section for a remark on seting up a nat environment. - -Only one card can be used at a time, do not activate multiple network -cards in VPC2007, the driver will panic. - -NOTE FOR USERS CONFIGURING VPC2007 TO USE NAT: - -in /usr/etc/rc comment out the following three lines: - -trap '' 2 -intr -t 20 hostaddr -h -trap 2 - -VPC2007 does not play well with hostaddr and it will hang the boot process -until you CTRL-C out of it. +The driver supports bridged, nat and local network settings. diff --git a/minix/drivers/net/dec21140A/dec21140A.c b/minix/drivers/net/dec21140A/dec21140A.c index 5d9eec3b5..50f643c86 100644 --- a/minix/drivers/net/dec21140A/dec21140A.c +++ b/minix/drivers/net/dec21140A/dec21140A.c @@ -20,31 +20,30 @@ static u32_t io_inl(u16_t); static void io_outl(u16_t, u32_t); -static int do_init(unsigned int, ether_addr_t *); +static int do_init(unsigned int, netdriver_addr_t *, uint32_t *, + unsigned int *); static void do_stop(void); static int do_send(struct netdriver_data *, size_t); static ssize_t do_recv(struct netdriver_data *, size_t); -static void do_stat(eth_stat_t *); static void do_intr(unsigned int); static int de_probe(dpeth_t *, unsigned int skip); -static void de_conf_addr(dpeth_t *, ether_addr_t *); +static void de_conf_addr(dpeth_t *, netdriver_addr_t *); static void de_init_buf(dpeth_t *); static void de_reset(const dpeth_t *); static void de_hw_conf(const dpeth_t *); static void de_start(const dpeth_t *); -static void de_setup_frame(const dpeth_t *, const ether_addr_t *); +static void de_setup_frame(const dpeth_t *, const netdriver_addr_t *); static u16_t de_read_rom(const dpeth_t *, u8_t, u8_t); static dpeth_t de_state; -static int de_instance; static const struct netdriver de_table = { + .ndr_name = "dec", .ndr_init = do_init, .ndr_stop = do_stop, .ndr_recv = do_recv, .ndr_send = do_send, - .ndr_stat = do_stat, .ndr_intr = do_intr }; @@ -57,7 +56,7 @@ int main(int argc, char *argv[]) return 0; } -static void de_init_hw(dpeth_t *dep, ether_addr_t *addr) +static void de_init_hw(dpeth_t *dep, netdriver_addr_t *addr) { de_reset(dep); de_conf_addr(dep, addr); @@ -76,7 +75,8 @@ static void de_init_hw(dpeth_t *dep, ether_addr_t *addr) de_start(dep); } -static int do_init(unsigned int instance, ether_addr_t *addr) +static int do_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks) { /* Initialize the DEC 21140A driver. */ dpeth_t *dep; @@ -84,24 +84,15 @@ static int do_init(unsigned int instance, ether_addr_t *addr) dep = &de_state; memset(dep, 0, sizeof(*dep)); - strlcpy(dep->de_name, "dec21140A:?", sizeof(dep->de_name)); - dep->de_name[strlen(dep->de_name)-1] = '0' + instance; - - de_instance = instance; - if (!de_probe(dep, instance)) return ENXIO; de_init_hw(dep, addr); + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; return OK; } -static void do_stat(eth_stat_t *stat) -{ - memcpy(stat, &de_state.de_stat, sizeof(*stat)); -} - static int de_probe(dpeth_t *dep, unsigned int skip) { int r, devind; @@ -131,14 +122,15 @@ static int de_probe(dpeth_t *dep, unsigned int skip) panic("de_probe: base address invalid: %d", dep->de_base_port); DEBUG(printf("%s: using I/O address 0x%lx, IRQ %d\n", - dep->de_name, (unsigned long)dep->de_base_port, + netdriver_name(), (unsigned long)dep->de_base_port, dep->de_irq)); dep->de_type = pci_attr_r8(devind, PCI_REV); /* device validation. We support only the DEC21140A */ if(dep->de_type != DEC_21140A){ - printf("%s: unsupported card type %x\n", dep->de_name, dep->de_type); + printf("%s: unsupported card type %x\n", netdriver_name(), + dep->de_type); return FALSE; } @@ -252,8 +244,6 @@ static ssize_t do_recv(struct netdriver_data *data, size_t max) netdriver_copyout(data, 0, descr->buf1, size); - dep->de_stat.ets_packetR++; - descr->descr->des[DES0]=DES0_OWN; dep->cur_descr[DESCR_RECV]++; if(dep->cur_descr[DESCR_RECV] >= DE_NB_RECV_DESCR) @@ -264,7 +254,7 @@ static ssize_t do_recv(struct netdriver_data *data, size_t max) return size; } -static void de_conf_addr(dpeth_t *dep, ether_addr_t *addr) +static void de_conf_addr(dpeth_t *dep, netdriver_addr_t *addr) { u16_t temp16; int i; @@ -281,8 +271,8 @@ static void de_conf_addr(dpeth_t *dep, ether_addr_t *addr) /* acquire MAC addr */ DEBUG(printf("Using MAC addr= ")); for(i=0;i<6;i++){ - addr->ea_addr[i] = dep->srom[i+DE_SROM_EA_OFFSET]; - DEBUG(printf("%02X%c", addr->ea_addr[i],i!=5?'-':'\n')); + addr->na_addr[i] = dep->srom[i+DE_SROM_EA_OFFSET]; + DEBUG(printf("%02X%c", addr->na_addr[i],i!=5?'-':'\n')); } DEBUG(printf("probe success\n")); } @@ -436,7 +426,7 @@ static void de_start(const dpeth_t *dep) io_outl(CSR_ADDR(dep, CSR6), val); } -static void de_setup_frame(const dpeth_t *dep, const ether_addr_t *addr) +static void de_setup_frame(const dpeth_t *dep, const netdriver_addr_t *addr) { int i; u32_t val; @@ -451,12 +441,12 @@ static void de_setup_frame(const dpeth_t *dep, const ether_addr_t *addr) dep->descr[DESCR_TRAN][0].buf1[9] = 0xFF; for(i=1;i<16;i++){ memset(&(dep->descr[DESCR_TRAN][0].buf1[12*i]), 0, 12); - dep->descr[DESCR_TRAN][0].buf1[12*i+0] = addr->ea_addr[0]; - dep->descr[DESCR_TRAN][0].buf1[12*i+1] = addr->ea_addr[1]; - dep->descr[DESCR_TRAN][0].buf1[12*i+4] = addr->ea_addr[2]; - dep->descr[DESCR_TRAN][0].buf1[12*i+5] = addr->ea_addr[3]; - dep->descr[DESCR_TRAN][0].buf1[12*i+8] = addr->ea_addr[4]; - dep->descr[DESCR_TRAN][0].buf1[12*i+9] = addr->ea_addr[5]; + dep->descr[DESCR_TRAN][0].buf1[12*i+0] = addr->na_addr[0]; + dep->descr[DESCR_TRAN][0].buf1[12*i+1] = addr->na_addr[1]; + dep->descr[DESCR_TRAN][0].buf1[12*i+4] = addr->na_addr[2]; + dep->descr[DESCR_TRAN][0].buf1[12*i+5] = addr->na_addr[3]; + dep->descr[DESCR_TRAN][0].buf1[12*i+8] = addr->na_addr[4]; + dep->descr[DESCR_TRAN][0].buf1[12*i+9] = addr->na_addr[5]; } dep->descr[DESCR_TRAN][0].descr->des[DES0] = DES0_OWN; @@ -499,8 +489,6 @@ static int do_send(struct netdriver_data *data, size_t size) io_outl(CSR_ADDR(dep, CSR1), 0xFFFFFFFF); - dep->de_stat.ets_packetT++; - return OK; } diff --git a/minix/drivers/net/dec21140A/dec21140A.h b/minix/drivers/net/dec21140A/dec21140A.h index 74f8af910..b0a13e91a 100644 --- a/minix/drivers/net/dec21140A/dec21140A.h +++ b/minix/drivers/net/dec21140A/dec21140A.h @@ -18,9 +18,9 @@ Created: 09/01/2009 Nicolas Tittley (first.last @ gmail DOT com) #endif #define DE_NB_SEND_DESCR 32 -#define DE_SEND_BUF_SIZE (ETH_MAX_PACK_SIZE+2) +#define DE_SEND_BUF_SIZE (NDEV_ETH_PACKET_MAX+2) #define DE_NB_RECV_DESCR 32 -#define DE_RECV_BUF_SIZE (ETH_MAX_PACK_SIZE+2) +#define DE_RECV_BUF_SIZE (NDEV_ETH_PACKET_MAX+2) #define DE_MIN_BASE_ADDR 0x0400 #define DE_SROM_EA_OFFSET 20 @@ -37,15 +37,12 @@ typedef struct de_local_descr { } de_loc_descr_t; typedef struct dpeth { - char de_name[32]; /* Name of this interface */ port_t de_base_port; /* Base port, for multiple card instance */ int de_irq; /* IRQ line number */ int de_hook; /* interrupt hook at kernel */ int de_type; /* What kind of hardware */ - eth_stat_t de_stat; /* Stats */ - /* Space reservation. We will allocate all structures later in the code. here we just make sure we have the space we need at compile time */ u8_t sendrecv_descr_buf[(DE_NB_SEND_DESCR+DE_NB_RECV_DESCR)* diff --git a/minix/drivers/net/dp8390/3c503.c b/minix/drivers/net/dp8390/3c503.c index 54702c677..d88505fd9 100644 --- a/minix/drivers/net/dp8390/3c503.c +++ b/minix/drivers/net/dp8390/3c503.c @@ -14,9 +14,6 @@ #include #include -#include -#include - #include "local.h" #include "dp8390.h" #include "3c503.h" @@ -48,7 +45,7 @@ dpeth_t * dep; /* Read station address from PROM */ for (ix = EL2_EA0; ix <= EL2_EA5; ix += 1) - dep->de_address.ea_addr[ix] = inb_el2(dep, ix); + dep->de_address.na_addr[ix] = inb_el2(dep, ix); /* Map the 8390 back to lower I/O address range */ outb_el2(dep, EL2_CNTR, cntr); @@ -108,12 +105,12 @@ dpeth_t * dep; if (!debug) { printf("%s: 3c503 at %X:%d:%lX\n", - dep->de_name, dep->de_base_port, dep->de_irq, + netdriver_name(), dep->de_base_port, dep->de_irq, dep->de_linmem + dep->de_offset_page); } else { printf("%s: 3Com Etherlink II %sat I/O address 0x%X, " "memory address 0x%lX, irq %d\n", - dep->de_name, dep->de_16bit ? "(16-bit) " : "", + netdriver_name(), dep->de_16bit ? "(16-bit) " : "", dep->de_base_port, dep->de_linmem + dep->de_offset_page, dep->de_irq); @@ -129,7 +126,7 @@ dpeth_t * dep; /* Stops board by disabling interrupts. */ #if DEBUG - printf("%s: stopping Etherlink\n", dep->de_name); + printf("%s: stopping Etherlink\n", netdriver_name()); #endif outb_el2(dep, EL2_CFGR, ECFGR_IRQOFF); return; diff --git a/minix/drivers/net/dp8390/Makefile b/minix/drivers/net/dp8390/Makefile index bd3b36632..9189c0583 100644 --- a/minix/drivers/net/dp8390/Makefile +++ b/minix/drivers/net/dp8390/Makefile @@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d DPADD+= ${LIBNETDRIVER} ${LIBSYS} LDADD+= -lnetdriver -lsys +WARNS?= 5 + .include diff --git a/minix/drivers/net/dp8390/dp8390.c b/minix/drivers/net/dp8390/dp8390.c index c68d634cb..99242fd18 100644 --- a/minix/drivers/net/dp8390/dp8390.c +++ b/minix/drivers/net/dp8390/dp8390.c @@ -16,7 +16,6 @@ #include #include -#include #include #include "assert.h" @@ -24,7 +23,6 @@ #include "dp8390.h" static dpeth_t de_state; -static int de_instance; u32_t system_hz; @@ -63,17 +61,19 @@ static dp_conf_t dp_conf[DP_CONF_NR]= /* Card addresses */ */ #define CR_EXTRA CR_STA -static int do_init(unsigned int instance, ether_addr_t *addr); -static void pci_conf(void); +static int do_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks); +static void pci_conf(unsigned int instance); static int do_send(struct netdriver_data *data, size_t size); static ssize_t do_recv(struct netdriver_data *data, size_t max); -static void do_mode(unsigned int mode); -static void do_stat(eth_stat_t *stat); +static void do_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, + unsigned int mcast_count); static void do_stop(void); -static void dp_init(dpeth_t *dep); -static void dp_confaddr(dpeth_t *dep); +static void dp_init(dpeth_t *dep, unsigned int instance); +static void dp_confaddr(dpeth_t *dep, unsigned int instance); static void dp_reset(dpeth_t *dep); static void do_intr(unsigned int mask); +static void do_tick(void); static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst); static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, @@ -94,20 +94,21 @@ static void dp_pio8_nic2user_s(dpeth_t *dep, struct netdriver_data *data, int nic_addr, size_t offset, size_t count); static void dp_pio16_nic2user_s(dpeth_t *dep, struct netdriver_data *data, int nic_addr, size_t offset, size_t count); -static void conf_hw(dpeth_t *dep); -static void update_conf(dpeth_t *dep, dp_conf_t *dcp); +static void conf_hw(dpeth_t *dep, unsigned int instance); +static void update_conf(dpeth_t *dep, dp_conf_t *dcp, unsigned int instance); static void map_hw_buffer(dpeth_t *dep); static void insb(port_t port, void *buf, size_t size); static void insw(port_t port, void *buf, size_t size); static const struct netdriver dp_table = { + .ndr_name = "dp", .ndr_init = do_init, .ndr_stop = do_stop, - .ndr_mode = do_mode, + .ndr_set_mode = do_set_mode, .ndr_recv = do_recv, .ndr_send = do_send, - .ndr_stat = do_stat, - .ndr_intr = do_intr + .ndr_intr = do_intr, + .ndr_tick = do_tick }; /*===========================================================================* @@ -125,30 +126,27 @@ int main(int argc, char *argv[]) /*===========================================================================* * do_init * *===========================================================================*/ -static int do_init(unsigned int instance, ether_addr_t *addr) +static int do_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks) { /* Initialize the dp8390 driver. */ dpeth_t *dep; system_hz = sys_hz(); - de_instance = instance; - dep = &de_state; memset(dep, 0, sizeof(*dep)); - strlcpy(dep->de_name, "dp8390#0", sizeof(dep->de_name)); - dep->de_name[7] += de_instance; - - pci_conf(); /* Configure PCI devices. */ + pci_conf(instance); /* Configure PCI devices. */ /* This is the default, try to (re)locate the device. */ - conf_hw(dep); - - dp_init(dep); + conf_hw(dep, instance); - memcpy(addr, dep->de_address.ea_addr, sizeof(*addr)); + dp_init(dep, instance); + memcpy(addr, dep->de_address.na_addr, sizeof(*addr)); + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; + *ticks = sys_hz(); /* update statistics once a second */ return OK; } @@ -164,29 +162,7 @@ void dp8390_dump(void) dep = &de_state; printf("\n"); - 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("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("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("OWC :%8ld\t", dep->de_stat.ets_OWC); + printf("dp8390 statistics of %s:\n", netdriver_name()); isr= inb_reg0(dep, DP_ISR); printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr, @@ -194,29 +170,45 @@ void dp8390_dump(void) } #endif +/*===========================================================================* + * pci_env * + *===========================================================================*/ +static int pci_env(unsigned int instance) +{ + char envvar[16], value[EP_BUF_SIZE]; + const char punct[] = ":,;."; + + strlcpy(envvar, "DPETH0", sizeof(envvar)); + envvar[5] += instance; + + /* If no setting with this name is present, default to PCI. */ + if (env_get_param(envvar, value, sizeof(value)) != 0) + return TRUE; + + /* Legacy support: check for a "pci" prefix. */ + return (strncmp(value, "pci", 3) == 0 && + strchr(punct, value[3]) != NULL); +} + /*===========================================================================* * pci_conf * *===========================================================================*/ -static void pci_conf(void) +static void pci_conf(unsigned int instance) { - char envvar[16]; struct dpeth *dep; - int i, pci_instance; + unsigned int i, pci_instance; dep= &de_state; - strlcpy(envvar, "DPETH0", sizeof(envvar)); - envvar[5] += de_instance; - if (!(dep->de_pci= env_prefix(envvar, "pci"))) + if (!(dep->de_pci= pci_env(instance))) return; /* no PCI config */ /* Count the number of dp instances before this one that are configured * for PCI, so that we can skip that many when enumerating PCI devices. */ pci_instance= 0; - for (i= 0; i < de_instance; i++) { - envvar[5]= i; - if (env_prefix(envvar, "pci")) + for (i= 0; i < instance; i++) { + if (pci_env(i)) pci_instance++; } @@ -261,9 +253,11 @@ static int do_send(struct netdriver_data *data, size_t size) } /*===========================================================================* - * do_mode * + * do_set_mode * *===========================================================================*/ -static void do_mode(unsigned int mode) +static void do_set_mode(unsigned int mode, + const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) { dpeth_t *dep; int dp_rcr_reg; @@ -273,29 +267,33 @@ static void do_mode(unsigned int mode) outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA); dp_rcr_reg = 0; - if (mode & NDEV_PROMISC) + if (mode & NDEV_MODE_PROMISC) dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM; - if (mode & NDEV_BROAD) + if (mode & NDEV_MODE_BCAST) dp_rcr_reg |= RCR_AB; - if (mode & NDEV_MULTI) + if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) dp_rcr_reg |= RCR_AM; outb_reg0(dep, DP_RCR, dp_rcr_reg); } /*===========================================================================* - * do_stat * + * dp_update_stats * *===========================================================================*/ -static void do_stat(eth_stat_t *stat) +static void dp_update_stats(dpeth_t * dep) { - dpeth_t *dep; - dep= &de_state; + netdriver_stat_ierror(inb_reg0(dep, DP_CNTR0)); + netdriver_stat_ierror(inb_reg0(dep, DP_CNTR1)); + netdriver_stat_ierror(inb_reg0(dep, DP_CNTR2)); +} - 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); +/*===========================================================================* + * do_tick * + *===========================================================================*/ +static void do_tick(void) +{ - memcpy(stat, &dep->de_stat, sizeof(*stat)); + dp_update_stats(&de_state); } /*===========================================================================* @@ -314,7 +312,7 @@ static void do_stop(void) /*===========================================================================* * dp_init * *===========================================================================*/ -static void dp_init(dpeth_t *dep) +static void dp_init(dpeth_t *dep, unsigned int instance) { int i, r; @@ -322,13 +320,13 @@ static void dp_init(dpeth_t *dep) dep->de_flags = DEF_EMPTY; (*dep->de_initf)(dep); - dp_confaddr(dep); + dp_confaddr(dep, instance); if (debug) { - printf("%s: Ethernet address ", dep->de_name); + printf("%s: Ethernet address ", netdriver_name()); for (i= 0; i < 6; i++) - printf("%x%c", dep->de_address.ea_addr[i], + printf("%x%c", dep->de_address.na_addr[i], i < 5 ? ':' : '\n'); } @@ -365,12 +363,12 @@ static void dp_init(dpeth_t *dep) /* Step 9: */ outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP); - outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]); - outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]); - outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]); - outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]); - outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]); - outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]); + outb_reg1(dep, DP_PAR0, dep->de_address.na_addr[0]); + outb_reg1(dep, DP_PAR1, dep->de_address.na_addr[1]); + outb_reg1(dep, DP_PAR2, dep->de_address.na_addr[2]); + outb_reg1(dep, DP_PAR3, dep->de_address.na_addr[3]); + outb_reg1(dep, DP_PAR4, dep->de_address.na_addr[4]); + outb_reg1(dep, DP_PAR5, dep->de_address.na_addr[5]); outb_reg1(dep, DP_MAR0, 0xff); outb_reg1(dep, DP_MAR1, 0xff); @@ -431,7 +429,7 @@ static void dp_init(dpeth_t *dep) /*===========================================================================* * dp_confaddr * *===========================================================================*/ -static void dp_confaddr(dpeth_t *dep) +static void dp_confaddr(dpeth_t *dep, unsigned int instance) { int i; char eakey[16]; @@ -440,16 +438,16 @@ static void dp_confaddr(dpeth_t *dep) /* User defined ethernet address? */ strlcpy(eakey, "DPETH0_EA", sizeof(eakey)); - eakey[5] += de_instance; + eakey[5] += instance; for (i= 0; i < 6; i++) { - v= dep->de_address.ea_addr[i]; + v= dep->de_address.na_addr[i]; if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) { break; } - dep->de_address.ea_addr[i]= v; + dep->de_address.na_addr[i]= v; } if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */ @@ -510,15 +508,18 @@ static void do_intr(unsigned int __unused mask) if (isr & ISR_TXE) { #if DEBUG - { printf("%s: got send Error\n", dep->de_name); } + printf("%s: got send error\n", + netdriver_name()); #endif - dep->de_stat.ets_sendErr++; + netdriver_stat_oerror(1); } else { tsr = inb_reg0(dep, DP_TSR); - if (tsr & TSR_PTX) dep->de_stat.ets_packetT++; + if (tsr & TSR_PTX) { + /* Transmission was successful. */ + } #if 0 /* Reserved in later manuals, should be ignored */ if (!(tsr & TSR_DFR)) { @@ -526,25 +527,9 @@ static void do_intr(unsigned int __unused mask) * the dp8390, this bit is set * when the packet is not deferred */ - dep->de_stat.ets_transDef++; } #endif - if (tsr & TSR_COL) dep->de_stat.ets_collision++; - if (tsr & TSR_ABT) dep->de_stat.ets_transAb++; - if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++; - if (tsr & TSR_FU - && ++dep->de_stat.ets_fifoUnder <= 10) - { - printf("%s: fifo underrun\n", - dep->de_name); - } - if (tsr & TSR_CDH - && ++dep->de_stat.ets_CDheartbeat <= 10) - { - printf("%s: CD heart beat failure\n", - dep->de_name); - } - if (tsr & TSR_OWC) dep->de_stat.ets_OWC++; + if (tsr & TSR_COL) netdriver_stat_coll(1); } sendq_tail= dep->de_sendq_tail; @@ -556,7 +541,7 @@ static void do_intr(unsigned int __unused mask) /* Or hardware bug? */ printf( "%s: transmit interrupt, but not sending\n", - dep->de_name); + netdriver_name()); continue; } dep->de_sendq[sendq_tail].sq_filled= 0; @@ -578,21 +563,10 @@ static void do_intr(unsigned int __unused mask) if (isr & ISR_PRX) netdriver_recv(); - if (isr & ISR_RXE) dep->de_stat.ets_recvErr++; + if (isr & ISR_RXE) + netdriver_stat_ierror(1); if (isr & ISR_CNT) - { - 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); - } - if (isr & ISR_OVW) - { - dep->de_stat.ets_OVW++; -#if 0 - { printW(); printf( - "%s: got overwrite warning\n", dep->de_name); } -#endif - } + dp_update_stats(dep); if (isr & ISR_RDC) { /* Nothing to do */ @@ -606,7 +580,7 @@ static void do_intr(unsigned int __unused mask) */ #if 0 { printW(); printf( - "%s: NIC stopped\n", dep->de_name); } + "%s: NIC stopped\n", netdriver_name()); } #endif dep->de_flags |= DEF_STOPPED; netdriver_recv(); /* see if we can reset right now */ @@ -656,20 +630,21 @@ static ssize_t do_recv(struct netdriver_data *data, size_t max) (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header), &header); (dep->de_getblockf)(dep, pageno, sizeof(header) + - 2*sizeof(ether_addr_t), sizeof(eth_type), ð_type); + 2*sizeof(netdriver_addr_t), sizeof(eth_type), + ð_type); length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t); next = header.dr_next; - if (length < ETH_MIN_PACK_SIZE || length > max) + if (length < NDEV_ETH_PACKET_MIN || length > max) { printf("%s: packet with strange length arrived: %d\n", - dep->de_name, (int) length); + netdriver_name(), (int) length); next= curr; } else if (next < dep->de_startpage || next >= dep->de_stoppage) { - printf("%s: strange next page\n", dep->de_name); + printf("%s: strange next page\n", netdriver_name()); next= curr; } else if (header.dr_status & RSR_FO) @@ -677,8 +652,8 @@ static ssize_t do_recv(struct netdriver_data *data, size_t max) /* This is very serious, so we issue a warning and * reset the buffers */ printf("%s: fifo overrun, resetting receive buffer\n", - dep->de_name); - dep->de_stat.ets_fifoOver++; + netdriver_name()); + netdriver_stat_ierror(1); next = curr; } else if (header.dr_status & RSR_PRX) @@ -686,7 +661,6 @@ static ssize_t do_recv(struct netdriver_data *data, size_t max) dp_pkt2user_s(dep, data, pageno, length); packet_processed = TRUE; - dep->de_stat.ets_packetR++; } if (next == dep->de_startpage) outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1); @@ -749,7 +723,7 @@ static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, static void dp_pkt2user_s(dpeth_t *dep, struct netdriver_data *data, int page, size_t length) { - int last, count; + unsigned int last, count; last = page + (length - 1) / DP_PAGESIZE; if (last >= dep->de_stoppage) @@ -884,16 +858,16 @@ static void dp_pio16_nic2user_s(dpeth_t *dep, struct netdriver_data *data, /*===========================================================================* * conf_hw * *===========================================================================*/ -static void conf_hw(dpeth_t *dep) +static void conf_hw(dpeth_t *dep, unsigned int instance) { int confnr; dp_conf_t *dcp; /* Pick a default configuration for this instance. */ - confnr= MIN(de_instance, DP_CONF_NR-1); + confnr= MIN(instance, DP_CONF_NR-1); dcp= &dp_conf[confnr]; - update_conf(dep, dcp); + update_conf(dep, dcp, instance); if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep)) panic("no ethernet card found at 0x%x\n", dep->de_base_port); @@ -903,7 +877,7 @@ static void conf_hw(dpeth_t *dep) /*===========================================================================* * update_conf * *===========================================================================*/ -static void update_conf(dpeth_t *dep, dp_conf_t *dcp) +static void update_conf(dpeth_t *dep, dp_conf_t *dcp, unsigned int instance) { long v; static char dpc_fmt[] = "x:d:x:x"; @@ -916,7 +890,7 @@ static void update_conf(dpeth_t *dep, dp_conf_t *dcp) } strlcpy(eckey, "DPETH0", sizeof(eckey)); - eckey[5] += de_instance; + eckey[5] += instance; /* Get the default settings and modify them from the environment. */ v= dcp->dpc_port; diff --git a/minix/drivers/net/dp8390/dp8390.h b/minix/drivers/net/dp8390/dp8390.h index ab02f7baf..d55d9c01a 100644 --- a/minix/drivers/net/dp8390/dp8390.h +++ b/minix/drivers/net/dp8390/dp8390.h @@ -208,21 +208,20 @@ typedef struct dpeth dp_initf_t de_initf; dp_stopf_t de_stopf; int de_prog_IO; - char de_name[sizeof("dp8390#n")]; /* The initf function fills the following fields. Only cards that do * programmed I/O fill in the de_pata_port field. * In addition, the init routine has to fill in the sendq data * structures. */ - ether_addr_t de_address; + netdriver_addr_t de_address; port_t de_dp8390_port; port_t de_data_port; int de_16bit; - int de_ramsize; - int de_offset_page; - int de_startpage; - int de_stoppage; + unsigned int de_ramsize; + unsigned int de_offset_page; + unsigned int de_startpage; + unsigned int de_stoppage; /* PCI config */ char de_pci; /* TRUE iff PCI device */ @@ -240,7 +239,6 @@ typedef struct dpeth /* Fields for internal use by the dp8390 driver. */ int de_flags; - eth_stat_t de_stat; dp_user2nicf_s_t de_user2nicf_s; dp_nic2userf_s_t de_nic2userf_s; dp_getblock_t de_getblockf; diff --git a/minix/drivers/net/dp8390/ne2000.c b/minix/drivers/net/dp8390/ne2000.c index de0ee889d..4aa990c5b 100644 --- a/minix/drivers/net/dp8390/ne2000.c +++ b/minix/drivers/net/dp8390/ne2000.c @@ -10,9 +10,6 @@ Created: March 15, 1994 by Philip Homburg #include #include -#include -#include - #include "local.h" #include "dp8390.h" #include "ne2000.h" @@ -142,11 +139,11 @@ dpeth_t *dep; if (dep->de_16bit) { word= inw_ne(dep, NE_DATA); - dep->de_address.ea_addr[i]= word; + dep->de_address.na_addr[i]= word; } else { - dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA); + dep->de_address.na_addr[i] = inb_ne(dep, NE_DATA); } } dep->de_data_port= dep->de_base_port + NE_DATA; @@ -183,14 +180,14 @@ dpeth_t *dep; if (!debug) { printf("%s: NE%d000 at %X:%d\n", - dep->de_name, dep->de_16bit ? 2 : 1, + netdriver_name(), dep->de_16bit ? 2 : 1, dep->de_base_port, dep->de_irq); } else { printf("%s: Novell NE%d000 ethernet card at I/O address " "0x%X, memory size 0x%X, irq %d\n", - dep->de_name, dep->de_16bit ? 2 : 1, + netdriver_name(), dep->de_16bit ? 2 : 1, dep->de_base_port, dep->de_ramsize, dep->de_irq); } } @@ -229,7 +226,7 @@ u8_t *pat; if (debug) { printf("%s: NE1000 remote DMA test failed\n", - dep->de_name); + netdriver_name()); } return 0; } @@ -283,7 +280,7 @@ u8_t *pat; if (debug) { printf("%s: NE2000 remote DMA test failed\n", - dep->de_name); + netdriver_name()); } return 0; } diff --git a/minix/drivers/net/dp8390/rtl8029.c b/minix/drivers/net/dp8390/rtl8029.c index c66f43bae..864e5abe4 100644 --- a/minix/drivers/net/dp8390/rtl8029.c +++ b/minix/drivers/net/dp8390/rtl8029.c @@ -11,8 +11,6 @@ Created: April 2000 by Philip Homburg #include #include -#include -#include #include #include "assert.h" @@ -37,7 +35,7 @@ int skip; u16_t vid, did; u32_t bar; u8_t ilr; - char *dname; + const char *dname; pci_init(); @@ -56,7 +54,7 @@ int skip; if (!dname) dname= "unknown device"; printf("%s: %s (%04X/%04X) at %s\n", - dep->de_name, dname, vid, did, pci_slot_name(devind)); + netdriver_name(), dname, vid, did, pci_slot_name(devind)); if(pci_reserve_ok(devind) != OK) return 0; /* printf("cr = 0x%x\n", pci_attr_r16(devind, PCI_CR)); */ @@ -72,7 +70,7 @@ int skip; if (debug) { printf("%s: using I/O address 0x%lx, IRQ %d\n", - dep->de_name, (unsigned long)bar, ilr); + netdriver_name(), (unsigned long)bar, ilr); } dep->de_initf= rtl_init; diff --git a/minix/drivers/net/dp8390/wdeth.c b/minix/drivers/net/dp8390/wdeth.c index e9feb7991..60299da98 100644 --- a/minix/drivers/net/dp8390/wdeth.c +++ b/minix/drivers/net/dp8390/wdeth.c @@ -7,9 +7,7 @@ Created: March 14, 1994 by Philip Homburg #include #include -#include -#include -#include "assert.h" +#include #include "local.h" #include "dp8390.h" @@ -71,12 +69,12 @@ dpeth_t *dep; int we_type; int sendq_nr; - dep->de_address.ea_addr[0] = inb_we(dep, EPL_EA0); - dep->de_address.ea_addr[1] = inb_we(dep, EPL_EA1); - dep->de_address.ea_addr[2] = inb_we(dep, EPL_EA2); - dep->de_address.ea_addr[3] = inb_we(dep, EPL_EA3); - dep->de_address.ea_addr[4] = inb_we(dep, EPL_EA4); - dep->de_address.ea_addr[5] = inb_we(dep, EPL_EA5); + dep->de_address.na_addr[0] = inb_we(dep, EPL_EA0); + dep->de_address.na_addr[1] = inb_we(dep, EPL_EA1); + dep->de_address.na_addr[2] = inb_we(dep, EPL_EA2); + dep->de_address.na_addr[3] = inb_we(dep, EPL_EA3); + dep->de_address.na_addr[4] = inb_we(dep, EPL_EA4); + dep->de_address.na_addr[5] = inb_we(dep, EPL_EA5); dep->de_dp8390_port= dep->de_base_port + EPL_DP8390; @@ -182,7 +180,7 @@ dpeth_t *dep; ((irr & (E_IRR_IR0|E_IRR_IR1)) >> 5); int_nr= we_int_table[int_indx]; #if DEBUG - { printf("%s: encoded irq= %d\n", dep->de_name, int_nr); } + printf("%s: encoded irq= %d\n", netdriver_name(), int_nr); #endif if (dep->de_irq & DEI_DEFAULT) dep->de_irq= int_nr; @@ -201,7 +199,7 @@ dpeth_t *dep; ((gcr & (E_790_GCR_IR1|E_790_GCR_IR0)) >> 2); int_nr= we_790int_table[int_indx]; #if DEBUG - { printf("%s: encoded irq= %d\n", dep->de_name, int_nr); } + printf("%s: encoded irq= %d\n", netdriver_name(), int_nr); #endif if (dep->de_irq & DEI_DEFAULT) dep->de_irq= int_nr; @@ -215,7 +213,7 @@ dpeth_t *dep; if (!debug) { printf("%s: WD80%d3 at %X:%d:%lX\n", - dep->de_name, we_type & WET_BRD_16BIT ? 1 : 0, + netdriver_name(), we_type & WET_BRD_16BIT ? 1 : 0, dep->de_base_port, dep->de_irq, dep->de_linmem); } else @@ -223,7 +221,7 @@ dpeth_t *dep; printf("%s: Western Digital %s%s card %s%s at I/O " "address 0x%X, memory address 0x%lX, " "memory size 0x%X, irq %d\n", - dep->de_name, + netdriver_name(), we_type & WET_BRD_16BIT ? "16-bit " : "", we_type & WET_ETHERNET ? "Ethernet" : we_type & WET_STARLAN ? "Starlan" : "Network", @@ -320,7 +318,7 @@ dpeth_t *dep; { tlb= inb_we(dep, EPL_TLB); #if DEBUG - printf("%s: tlb= 0x%x\n", dep->de_name, tlb); + printf("%s: tlb= 0x%x\n", netdriver_name(), tlb); #endif return tlb == E_TLB_EB || tlb == E_TLB_E || tlb == E_TLB_SMCE || tlb == E_TLB_SMC8216T || diff --git a/minix/drivers/net/dpeth/3c501.c b/minix/drivers/net/dpeth/3c501.c index 2fd87e5f3..df2d881f1 100644 --- a/minix/drivers/net/dpeth/3c501.c +++ b/minix/drivers/net/dpeth/3c501.c @@ -11,8 +11,6 @@ #include #include -#include -#include #include "dp.h" #if (ENABLE_3C501 == 1) @@ -38,7 +36,7 @@ static void el1_getstats(dpeth_t * dep) */ static void el1_reset(dpeth_t * dep) { - int ix; + unsigned int ix; for (ix = 0; ix < 8; ix += 1) /* Resets the board */ outb_el1(dep, EL1_CSR, ECSR_RESET); @@ -113,7 +111,7 @@ static ssize_t el1_recv(dpeth_t *dep, struct netdriver_data *data, size_t max) dep->de_recvq_head = rxptr->next; /* Copy buffer to user area */ - size = MIN(rxptr->size, max); + size = MIN((size_t)rxptr->size, max); netdriver_copyout(data, 0, rxptr->buffer, size); @@ -137,7 +135,7 @@ static int el1_send(dpeth_t *dep, struct netdriver_data *data, size_t size) if ((now - dep->de_xmit_start) > 4) { /* Transmitter timed out */ DEBUG(printf("3c501: transmitter timed out ... \n")); - dep->de_stat.ets_sendErr += 1; + netdriver_stat_oerror(1); dep->de_flags &= NOT(DEF_XMIT_BUSY); /* Try sending anyway. */ } else @@ -184,7 +182,7 @@ static void el1_stop(dpeth_t * dep) { int ix; - DEBUG(printf("%s: stopping Etherlink ....\n", dep->de_name)); + DEBUG(printf("%s: stopping Etherlink ....\n", netdriver_name())); for (ix = 0; ix < 8; ix += 1) /* Reset board */ outb_el1(dep, EL1_CSR, ECSR_RESET); outb_el1(dep, EL1_CSR, ECSR_SYS); @@ -211,7 +209,7 @@ static void el1_interrupt(dpeth_t * dep) DEBUG(printf("3c501: got xmit interrupt (ASR=0x%02X XSR=0x%02X)\n", csr, isr)); if (isr & EXSR_JAM) { /* Sending, packet got a collision */ - dep->de_stat.ets_collision += 1; + netdriver_stat_coll(1); /* Put pointer back to beginning of packet */ outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_SYS); outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - TxBuff->size)); @@ -220,17 +218,15 @@ static void el1_interrupt(dpeth_t * dep) return; } else if ((isr & EXSR_16JAM) || !(isr & EXSR_IDLE)) { - dep->de_stat.ets_sendErr += 1; - + netdriver_stat_oerror(1); } else if (isr & EXSR_UNDER) { - dep->de_stat.ets_fifoUnder += 1; + netdriver_stat_oerror(1); } DEBUG(printf("3c501: got xmit interrupt (0x%02X)\n", isr)); el1_reset(dep); } else { /** if (inw_el1(dep, EL1_XMITPTR) == EL1_BFRSIZ) **/ /* Packet transmitted successfully */ - dep->de_stat.ets_packetT += 1; dep->bytes_Tx += (long) (TxBuff->size); free_buff(dep, TxBuff); dep->de_flags &= NOT(DEF_XMIT_BUSY); @@ -245,16 +241,19 @@ static void el1_interrupt(dpeth_t * dep) isr = inb_el1(dep, EL1_RECV); pktsize = inw_el1(dep, EL1_RECVPTR); if ((isr & ERSR_RERROR) || (isr & ERSR_STALE)) { - DEBUG(printf("Rx0 (ASR=0x%02X RSR=0x%02X size=%d)\n", csr, isr, pktsize)); - dep->de_stat.ets_recvErr += 1; + DEBUG(printf("Rx0 (ASR=0x%02X RSR=0x%02X size=%d)\n", + csr, isr, pktsize)); + netdriver_stat_ierror(1); - } else if (pktsize < ETH_MIN_PACK_SIZE || pktsize > ETH_MAX_PACK_SIZE) { - DEBUG(printf("Rx1 (ASR=0x%02X RSR=0x%02X size=%d)\n", csr, isr, pktsize)); - dep->de_stat.ets_recvErr += 1; + } else if (pktsize < NDEV_ETH_PACKET_MIN || + pktsize > NDEV_ETH_PACKET_MAX) { + DEBUG(printf("Rx1 (ASR=0x%02X RSR=0x%02X size=%d)\n", + csr, isr, pktsize)); + netdriver_stat_ierror(1); } else if ((rxptr = alloc_buff(dep, pktsize + sizeof(buff_t))) == NULL) { /* Memory not available. Drop packet */ - dep->de_stat.ets_fifoOver += 1; + netdriver_stat_ierror(1); } else if (isr & (ERSR_GOOD | ERSR_ANY)) { /* Got a good packet. Read it from buffer */ @@ -263,7 +262,6 @@ static void el1_interrupt(dpeth_t * dep) insb(dep->de_data_port, rxptr->buffer, pktsize); rxptr->next = NULL; rxptr->size = pktsize; - dep->de_stat.ets_packetR += 1; dep->bytes_Rx += (long) pktsize; /* Queue packet to receive queue */ if (dep->de_recvq_head == NULL) @@ -303,7 +301,7 @@ static void el1_interrupt(dpeth_t * dep) */ static void el1_init(dpeth_t * dep) { - int ix; + unsigned int ix; dep->de_irq &= NOT(DEI_DEFAULT); /* Strip the default flag. */ dep->de_offset_page = 0; @@ -320,9 +318,9 @@ static void el1_init(dpeth_t * dep) el1_mode_init(dep); printf("%s: Etherlink (%s) at %X:%d - ", - dep->de_name, "3c501", dep->de_base_port, dep->de_irq); + netdriver_name(), "3c501", dep->de_base_port, dep->de_irq); for (ix = 0; ix < SA_ADDR_LEN; ix += 1) - printf("%02X%c", (dep->de_address.ea_addr[ix] = StationAddress[ix]), + printf("%02X%c", (dep->de_address.na_addr[ix] = StationAddress[ix]), ix < SA_ADDR_LEN - 1 ? ':' : '\n'); /* Device specific functions */ @@ -341,7 +339,7 @@ static void el1_init(dpeth_t * dep) */ int el1_probe(dpeth_t * dep) { - int ix; + unsigned int ix; for (ix = 0; ix < 8; ix += 1) /* Reset the board */ outb_el1(dep, EL1_CSR, ECSR_RESET); diff --git a/minix/drivers/net/dpeth/3c503.c b/minix/drivers/net/dpeth/3c503.c index 8b3503e1b..5612a81ec 100644 --- a/minix/drivers/net/dpeth/3c503.c +++ b/minix/drivers/net/dpeth/3c503.c @@ -11,8 +11,6 @@ #include #include -#include -#include #include "dp.h" #if (ENABLE_3C503 == 1) @@ -26,8 +24,8 @@ */ static void el2_init(dpeth_t * dep) { - int ix, irq; - int sendq_nr; + unsigned int ix, irq; + unsigned int sendq_nr; int cntr; /* Map the address PROM to lower I/O address range */ @@ -36,7 +34,7 @@ static void el2_init(dpeth_t * dep) /* Read station address from PROM */ for (ix = EL2_EA0; ix <= EL2_EA5; ix += 1) - dep->de_address.ea_addr[ix] = inb_el2(dep, ix); + dep->de_address.na_addr[ix] = inb_el2(dep, ix); /* Map the 8390 back to lower I/O address range */ outb_el2(dep, EL2_CNTR, cntr); @@ -92,11 +90,11 @@ static void el2_init(dpeth_t * dep) ns_init(dep); /* Initialize DP controller */ printf("%s: Etherlink II%s (%s) at %X:%d:%05lX - ", - dep->de_name, dep->de_16bit ? "/16" : "", "3c503", + netdriver_name(), dep->de_16bit ? "/16" : "", "3c503", dep->de_base_port, dep->de_irq, dep->de_linmem + dep->de_offset_page); for (ix = 0; ix < SA_ADDR_LEN; ix += 1) - printf("%02X%c", dep->de_address.ea_addr[ix], + printf("%02X%c", dep->de_address.na_addr[ix], ix < SA_ADDR_LEN - 1 ? ':' : '\n'); } diff --git a/minix/drivers/net/dpeth/3c509.c b/minix/drivers/net/dpeth/3c509.c index debcb2f2c..a089d6cd0 100644 --- a/minix/drivers/net/dpeth/3c509.c +++ b/minix/drivers/net/dpeth/3c509.c @@ -11,8 +11,6 @@ #include #include -#include -#include #include "dp.h" @@ -37,17 +35,12 @@ static void el3_update_stats(dpeth_t * dep) SetWindow(WNO_Statistics); /* Reads everything, adding values to the local counters */ - dep->de_stat.ets_sendErr += inb_el3(dep, REG_TxCarrierLost); /* Reg. 00 */ - dep->de_stat.ets_sendErr += inb_el3(dep, REG_TxNoCD); /* Reg. 01 */ - dep->de_stat.ets_collision += inb_el3(dep, REG_TxMultColl); /* Reg. 02 */ - dep->de_stat.ets_collision += inb_el3(dep, REG_TxSingleColl); /* Reg. 03 */ - dep->de_stat.ets_collision += inb_el3(dep, REG_TxLate); /* Reg. 04 */ - dep->de_stat.ets_recvErr += inb_el3(dep, REG_RxDiscarded); /* Reg. 05 */ - dep->de_stat.ets_packetT += inb_el3(dep, REG_TxFrames); /* Reg. 06 */ - dep->de_stat.ets_packetR += inb_el3(dep, REG_RxFrames); /* Reg. 07 */ - dep->de_stat.ets_transDef += inb_el3(dep, REG_TxDefer); /* Reg. 08 */ - dep->bytes_Rx += (unsigned) inw_el3(dep, REG_RxBytes); /* Reg. 10 */ - dep->bytes_Tx += (unsigned) inw_el3(dep, REG_TxBytes); /* Reg. 12 */ + netdriver_stat_oerror(inb_el3(dep, REG_TxCarrierLost)); /* Reg. 00 */ + netdriver_stat_oerror(inb_el3(dep, REG_TxNoCD)); /* Reg. 01 */ + netdriver_stat_coll(inb_el3(dep, REG_TxMultColl)); /* Reg. 02 */ + netdriver_stat_coll(inb_el3(dep, REG_TxSingleColl)); /* Reg. 03 */ + netdriver_stat_coll(inb_el3(dep, REG_TxLate)); /* Reg. 04 */ + netdriver_stat_ierror(inb_el3(dep, REG_RxDiscarded)); /* Reg. 05 */ /* Goes back to operating window and enables statistics */ SetWindow(WNO_Operating); @@ -120,7 +113,7 @@ static ssize_t el3_recv(dpeth_t *dep, struct netdriver_data *data, size_t max) dep->de_recvq_head = rxptr->next; /* Copy buffer to user area and free it */ - size = MIN(rxptr->size, max); + size = MIN((size_t)rxptr->size, max); netdriver_copyout(data, 0, rxptr->buffer, size); @@ -151,15 +144,16 @@ static void el3_rx_complete(dpeth_t * dep) switch (RxStatus) { /* Bad packet (see error type) */ case RXS_Dribble: case RXS_Oversize: - case RXS_Runt: dep->de_stat.ets_recvErr += 1; break; - case RXS_Overrun: dep->de_stat.ets_OVW += 1; break; - case RXS_Framing: dep->de_stat.ets_frameAll += 1; break; - case RXS_CRC: dep->de_stat.ets_CRCerr += 1; break; + case RXS_Runt: + case RXS_Overrun: + case RXS_Framing: + case RXS_CRC: + netdriver_stat_ierror(1); } } else if ((rxptr = alloc_buff(dep, pktsize + sizeof(buff_t))) == NULL) { /* Memory not available. Drop packet */ - dep->de_stat.ets_fifoOver += 1; + netdriver_stat_ierror(1); } else { /* Good packet. Read it from FIFO */ @@ -199,8 +193,8 @@ static int el3_send(dpeth_t *dep, struct netdriver_data *data, size_t size) (now - dep->de_xmit_start) > 4) { DEBUG(printf("3c509: Transmitter timed out. Resetting ....\n");) - dep->de_stat.ets_sendErr += 1; - /* Resets and restars the transmitter */ + netdriver_stat_oerror(1); + /* Resets and restarts the transmitter */ outw_el3(dep, REG_CmdStatus, CMD_TxReset); outw_el3(dep, REG_CmdStatus, CMD_TxEnable); dep->de_flags &= NOT(DEF_XMIT_BUSY); @@ -219,17 +213,18 @@ static int el3_send(dpeth_t *dep, struct netdriver_data *data, size_t size) dep->de_xmit_start = getticks(); dep->de_flags |= DEF_XMIT_BUSY; - if (inw_el3(dep, REG_TxFree) > ETH_MAX_PACK_SIZE) { + if (inw_el3(dep, REG_TxFree) > NDEV_ETH_PACKET_MAX) { /* Tx has enough room for a packet of maximum size */ dep->de_flags &= NOT(DEF_XMIT_BUSY); } else { /* Interrupt driver when enough room is available */ - outw_el3(dep, REG_CmdStatus, CMD_SetTxAvailable | ETH_MAX_PACK_SIZE); + outw_el3(dep, REG_CmdStatus, CMD_SetTxAvailable | NDEV_ETH_PACKET_MAX); } /* Pops Tx status stack */ for (ix = 4; --ix && (TxStatus = inb_el3(dep, REG_TxStatus)) > 0;) { - if (TxStatus & 0x38) dep->de_stat.ets_sendErr += 1; + if (TxStatus & 0x38) + netdriver_stat_oerror(1); if (TxStatus & 0x30) outw_el3(dep, REG_CmdStatus, CMD_TxReset); if (TxStatus & 0x3C) @@ -262,7 +257,7 @@ static void el3_close(dpeth_t * dep) NOT((MediaLBeatEnable | MediaJabberEnable))); /* micro_delay(5000); */ } - DEBUG(printf("%s: stopping Etherlink ... \n", dep->de_name)); + DEBUG(printf("%s: stopping Etherlink ... \n", netdriver_name())); /* Issues a global reset outw_el3(dep, REG_CmdStatus, CMD_GlobalReset); */ sys_irqdisable(&dep->de_hook); /* Disable interrupt */ @@ -341,8 +336,8 @@ static void el3_read_StationAddress(dpeth_t * dep) /* Accesses with word No. */ rc = el3_read_eeprom(dep->de_id_port, ix / 2); /* Swaps bytes of word */ - dep->de_address.ea_addr[ix++] = (rc >> 8) & 0xFF; - dep->de_address.ea_addr[ix++] = rc & 0xFF; + dep->de_address.na_addr[ix++] = (rc >> 8) & 0xFF; + dep->de_address.na_addr[ix++] = rc & 0xFF; } } @@ -387,7 +382,7 @@ static void el3_open(dpeth_t * dep) /* Set "my own" address */ SetWindow(WNO_StationAddress); for (ix = 0; ix < 6; ix += 1) - outb_el3(dep, REG_SA0_1 + ix, dep->de_address.ea_addr[ix]); + outb_el3(dep, REG_SA0_1 + ix, dep->de_address.na_addr[ix]); /* Start Transceivers as required */ if (dep->de_if_port == BNC_XCVR) { @@ -445,10 +440,10 @@ static void el3_open(dpeth_t * dep) dep->de_interruptf = el3_interrupt; printf("%s: Etherlink III (%s) at %X:%d, %s port - ", - dep->de_name, "3c509", dep->de_base_port, dep->de_irq, + netdriver_name(), "3c509", dep->de_base_port, dep->de_irq, IfNamesMsg[dep->de_if_port >> 14]); for (ix = 0; ix < SA_ADDR_LEN; ix += 1) - printf("%02X%c", dep->de_address.ea_addr[ix], + printf("%02X%c", dep->de_address.na_addr[ix], ix < SA_ADDR_LEN - 1 ? ':' : '\n'); } diff --git a/minix/drivers/net/dpeth/8390.c b/minix/drivers/net/dpeth/8390.c index 8007d0b0b..4405bacb2 100644 --- a/minix/drivers/net/dpeth/8390.c +++ b/minix/drivers/net/dpeth/8390.c @@ -12,8 +12,6 @@ #include #include -#include -#include #include #include "dp.h" @@ -57,7 +55,8 @@ static void ns_start_xmit(const dpeth_t * dep, int size, int pageno) static void mem_getblock(dpeth_t *dep, u16_t offset, int size, void *dst) { - assert(offset + size <= dep->de_ramsize); + assert(size >= 0); + assert(offset + (unsigned int)size <= dep->de_ramsize); memcpy(dst, dep->de_locmem + offset, size); } @@ -179,9 +178,9 @@ static void pio_user2nic(dpeth_t *dep, int pageno, struct netdriver_data *data, static void ns_stats(dpeth_t * dep) { - dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0); - dep->de_stat.ets_recvErr += inb_reg0(dep, DP_CNTR1); - dep->de_stat.ets_fifoOver += inb_reg0(dep, DP_CNTR2); + netdriver_stat_ierror(inb_reg0(dep, DP_CNTR0)); + netdriver_stat_ierror(inb_reg0(dep, DP_CNTR1)); + netdriver_stat_ierror(inb_reg0(dep, DP_CNTR2)); } /* @@ -215,7 +214,7 @@ static void ns_reinit(dpeth_t * dep) */ static int ns_send(dpeth_t *dep, struct netdriver_data *data, size_t size) { - int queue; + unsigned int queue; queue = dep->de_sendq_head; if (dep->de_sendq[queue].sq_filled) @@ -242,7 +241,7 @@ static int ns_send(dpeth_t *dep, struct netdriver_data *data, size_t size) */ static void ns_reset(dpeth_t * dep) { - int ix; + unsigned int ix; /* Stop chip */ outb_reg0(dep, DP_CR, CR_STP | CR_NO_DMA); @@ -298,21 +297,21 @@ static ssize_t ns_recv(dpeth_t *dep, struct netdriver_data *data, size_t max) &header); #ifdef ETH_IGN_PROTO (dep->de_getblockf)(dep, pageno * DP_PAGESIZE + sizeof(header) + - 2 * sizeof(ether_addr_t), sizeof(eth_type), ð_type); + 2 * sizeof(netdriver_addr_t), sizeof(eth_type), ð_type); #endif length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t); next = header.dr_next; - if (length < ETH_MIN_PACK_SIZE || length > max) { + if (length < NDEV_ETH_PACKET_MIN || length > max) { printf("%s: packet with strange length arrived: %zu\n", - dep->de_name, length); - dep->de_stat.ets_recvErr += 1; + netdriver_name(), length); + netdriver_stat_ierror(1); next = curr; } else if (next < dep->de_startpage || next >= dep->de_stoppage) { - printf("%s: strange next page\n", dep->de_name); - dep->de_stat.ets_recvErr += 1; + printf("%s: strange next page\n", netdriver_name()); + netdriver_stat_ierror(1); next = curr; #ifdef ETH_IGN_PROTO } else if (eth_type == eth_ign_proto) { @@ -321,15 +320,15 @@ static ssize_t ns_recv(dpeth_t *dep, struct netdriver_data *data, size_t max) if (first) { first = FALSE; printf("%s: dropping proto %04x packet\n", - dep->de_name, ntohs(eth_ign_proto)); + netdriver_name(), ntohs(eth_ign_proto)); } next = curr; #endif } else if (header.dr_status & RSR_FO) { /* This is very serious, issue a warning and reset buffers */ printf("%s: fifo overrun, resetting receive buffer\n", - dep->de_name); - dep->de_stat.ets_fifoOver += 1; + netdriver_name()); + netdriver_stat_ierror(1); next = curr; } else if (header.dr_status & RSR_PRX) { @@ -337,7 +336,6 @@ static ssize_t ns_recv(dpeth_t *dep, struct netdriver_data *data, size_t max) packet_processed = TRUE; } dep->bytes_Rx += (long) length; - dep->de_stat.ets_packetR += 1; outb_reg0(dep, DP_BNRY, (next == dep->de_startpage ? dep->de_stoppage : next) - 1); pageno = next; @@ -353,7 +351,7 @@ static ssize_t ns_recv(dpeth_t *dep, struct netdriver_data *data, size_t max) static void ns_interrupt(dpeth_t * dep) { int isr, tsr; - int queue; + unsigned int queue; while ((isr = inb_reg0(dep, DP_ISR)) != 0) { @@ -362,22 +360,23 @@ static void ns_interrupt(dpeth_t * dep) tsr = inb_reg0(dep, DP_TSR); if (tsr & TSR_PTX) { - dep->de_stat.ets_packetT++; + /* Packet transmission was successful. */ } - if (tsr & TSR_COL) dep->de_stat.ets_collision++; + if (tsr & TSR_COL) + netdriver_stat_coll(1); if (tsr & (TSR_ABT | TSR_FU)) { - dep->de_stat.ets_fifoUnder++; + netdriver_stat_oerror(1); } if ((isr & ISR_TXE) || (tsr & (TSR_CRS | TSR_CDH | TSR_OWC))) { printf("%s: got send Error (0x%02X)\n", - dep->de_name, tsr); - dep->de_stat.ets_sendErr++; + netdriver_name(), tsr); + netdriver_stat_oerror(1); } queue = dep->de_sendq_tail; if (!(dep->de_sendq[queue].sq_filled)) { /* Hardware bug? */ printf("%s: transmit interrupt, but not sending\n", - dep->de_name); + netdriver_name()); continue; } dep->de_sendq[queue].sq_filled = FALSE; @@ -394,16 +393,14 @@ static void ns_interrupt(dpeth_t * dep) } if (isr & ISR_RXE) { printf("%s: got recv Error (0x%04X)\n", - dep->de_name, inb_reg0(dep, DP_RSR)); - dep->de_stat.ets_recvErr++; + netdriver_name(), inb_reg0(dep, DP_RSR)); + netdriver_stat_ierror(1); } if (isr & ISR_CNT) { - dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0); - dep->de_stat.ets_recvErr += inb_reg0(dep, DP_CNTR1); - dep->de_stat.ets_fifoOver += inb_reg0(dep, DP_CNTR2); + ns_stats(dep); } if (isr & ISR_OVW) { - printf("%s: got overwrite warning\n", dep->de_name); + printf("%s: got overwrite warning\n", netdriver_name()); } if (isr & ISR_RDC) { /* Nothing to do */ @@ -415,7 +412,8 @@ static void ns_interrupt(dpeth_t * dep) * approach of resetting only after all pending packets had * been accepted, but it was broken and this is simpler anyway. */ - printf("%s: network interface stopped\n", dep->de_name); + printf("%s: network interface stopped\n", + netdriver_name()); ns_reset(dep); break; } @@ -428,8 +426,8 @@ static void ns_interrupt(dpeth_t * dep) */ void ns_init(dpeth_t * dep) { - int dp_reg; - int ix; + unsigned int dp_reg; + unsigned int ix; /* NS8390 initialization (as recommended in National Semiconductor specs) */ outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_NO_DMA); /* 0x21 */ @@ -448,7 +446,7 @@ void ns_init(dpeth_t * dep) /* Copies station address in page 1 registers */ outb_reg0(dep, DP_CR, CR_PS_P1 | CR_NO_DMA); /* Selects Page 1 */ for (ix = 0; ix < SA_ADDR_LEN; ix += 1) /* Initializes address */ - outb_reg1(dep, DP_PAR0 + ix, dep->de_address.ea_addr[ix]); + outb_reg1(dep, DP_PAR0 + ix, dep->de_address.na_addr[ix]); for (ix = DP_MAR0; ix <= DP_MAR7; ix += 1) /* Initializes address */ outb_reg1(dep, ix, 0xFF); diff --git a/minix/drivers/net/dpeth/Makefile b/minix/drivers/net/dpeth/Makefile index 1b3843dd9..7416e8998 100644 --- a/minix/drivers/net/dpeth/Makefile +++ b/minix/drivers/net/dpeth/Makefile @@ -11,4 +11,6 @@ LDADD+= -lnetdriver -lsys CPPFLAGS+= -DVERBOSE=0 +WARNS?= 5 + .include diff --git a/minix/drivers/net/dpeth/devio.c b/minix/drivers/net/dpeth/devio.c index 1e388b0f2..14e701723 100644 --- a/minix/drivers/net/dpeth/devio.c +++ b/minix/drivers/net/dpeth/devio.c @@ -9,8 +9,6 @@ #include #include -#include -#include #include "dp.h" #if (USE_IOPL == 0) diff --git a/minix/drivers/net/dpeth/dp.c b/minix/drivers/net/dpeth/dp.c index 0099dcef1..f3d202588 100644 --- a/minix/drivers/net/dpeth/dp.c +++ b/minix/drivers/net/dpeth/dp.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include @@ -41,23 +39,26 @@ static dp_conf_t dp_conf[DP_CONF_NR] = { { 0x000, 0, 0x00000, }, }; -static int do_init(unsigned int instance, ether_addr_t *addr); +static int do_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks); static void do_stop(void); -static void do_mode(unsigned int mode); +static void do_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, + unsigned int mcast_count); static int do_send(struct netdriver_data *data, size_t size); static ssize_t do_recv(struct netdriver_data *data, size_t max); -static void do_stat(eth_stat_t *stat); static void do_intr(unsigned int mask); +static void do_tick(void); static void do_other(const message *m_ptr, int ipc_status); static const struct netdriver dp_table = { + .ndr_name = "dpe", .ndr_init = do_init, .ndr_stop = do_stop, - .ndr_mode = do_mode, + .ndr_set_mode = do_set_mode, .ndr_recv = do_recv, .ndr_send = do_send, - .ndr_stat = do_stat, .ndr_intr = do_intr, + .ndr_tick = do_tick, .ndr_other = do_other }; @@ -101,7 +102,7 @@ static void do_dump(void) printf("\n\n"); - printf("%s statistics:\t\t", dep->de_name); + printf("%s statistics:\t\t", netdriver_name()); /* Network interface status */ printf("Status: 0x%04x\n\n", dep->de_flags); @@ -111,22 +112,6 @@ static void do_dump(void) /* 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); - - /* 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 collisions/receive CRC errors */ - printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision); - printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr); } /* @@ -138,9 +123,6 @@ static void do_first_init(dpeth_t *dep, const dp_conf_t *dcp) dep->de_linmem = 0xFFFF0000; /* FIXME: this overrides update_conf, why? */ - /* Make sure statisics are cleared */ - memset(&dep->de_stat, 0, sizeof(dep->de_stat)); - /* Device specific initialization */ (*dep->de_initf)(dep); @@ -168,7 +150,8 @@ static void do_first_init(dpeth_t *dep, const dp_conf_t *dcp) ** Initialize hardware and data structures. ** Return status and ethernet address. */ -static int do_init(unsigned int instance, ether_addr_t *addr) +static int do_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks) { dpeth_t *dep; dp_conf_t *dcp; @@ -176,9 +159,6 @@ static int do_init(unsigned int instance, ether_addr_t *addr) dep = &de_state; - strlcpy(dep->de_name, "dpeth#?", sizeof(dep->de_name)); - dep->de_name[4] = '0' + instance; - /* Pick a default configuration for this instance. */ confnr = MIN(instance, DP_CONF_NR-1); @@ -192,7 +172,7 @@ static int do_init(unsigned int instance, ether_addr_t *addr) !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); + netdriver_name(), dep->de_base_port); return ENXIO; } @@ -201,28 +181,33 @@ static int do_init(unsigned int instance, ether_addr_t *addr) /* Request function key for debug dumps */ fkeys = sfkeys = 0; bit_set(sfkeys, 7); if (fkey_map(&fkeys, &sfkeys) != OK) - printf("%s: couldn't bind Shift+F7 key (%d)\n", dep->de_name, errno); + printf("%s: couldn't bind Shift+F7 key (%d)\n", + netdriver_name(), errno); - memcpy(addr, dep->de_address.ea_addr, sizeof(*addr)); + memcpy(addr, dep->de_address.na_addr, sizeof(*addr)); + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; /* ..is this even accurate? */ + *ticks = sys_hz(); /* update statistics once a second */ return OK; } /* -** Name: de_mode +** Name: de_set_mode ** Function: Sets packet receipt mode. */ -static void do_mode(unsigned int mode) +static void do_set_mode(unsigned int mode, + const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) { dpeth_t *dep; dep = &de_state; dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD); - if (mode & NDEV_PROMISC) + if (mode & NDEV_MODE_PROMISC) dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD; - if (mode & NDEV_MULTI) + if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) dep->de_flags |= DEF_MULTI; - if (mode & NDEV_BROAD) + if (mode & NDEV_MODE_BCAST) dep->de_flags |= DEF_BROAD; (*dep->de_flagsf)(dep); } @@ -253,16 +238,6 @@ static ssize_t do_recv(struct netdriver_data *data, size_t max) return (*dep->de_recvf)(dep, data, max); } -/* -** Name: do_stat -** Function: Reports device statistics. -*/ -static void do_stat(eth_stat_t *stat) -{ - - memcpy(stat, &de_state.de_stat, sizeof(*stat)); -} - /* ** Name: do_stop ** Function: Stops network interface. @@ -292,6 +267,20 @@ static void do_intr(unsigned int __unused mask) sys_irqenable(&dep->de_hook); } +/* +** Name: do_tick +** Function: perform regular processing. +*/ +static void do_tick(void) +{ + dpeth_t *dep; + + dep = &de_state; + + if (dep->de_getstatsf != NULL) + (*dep->de_getstatsf)(dep); +} + /* ** Name: do_other ** Function: Processes miscellaneous messages. diff --git a/minix/drivers/net/dpeth/dp.h b/minix/drivers/net/dpeth/dp.h index 6a0b56f0e..9923c6340 100644 --- a/minix/drivers/net/dpeth/dp.h +++ b/minix/drivers/net/dpeth/dp.h @@ -101,17 +101,15 @@ typedef struct dpeth { port_t de_base_port; port_t de_data_port; /* For boards using Prog. I/O for xmit/recv */ - int de_irq; + unsigned int de_irq; int de_hook; /* interrupt hook at kernel */ - char de_name[8]; - #define DEI_DEFAULT 0x8000 phys_bytes de_linmem; /* For boards using shared memory */ char *de_locmem; /* Locally mapped (virtual) address */ - int de_ramsize; /* Size of on board memory */ - int de_offset_page; /* Offset of shared memory page */ + unsigned int de_ramsize; /* Size of on board memory */ + unsigned int de_offset_page; /* Offset of shared memory page */ /* Board specific functions */ dp_eth_t de_initf; @@ -124,12 +122,11 @@ typedef struct dpeth { dp_recv_t de_recvf; dp_send_t de_sendf; - ether_addr_t de_address; /* Ethernet Address */ - eth_stat_t de_stat; /* Ethernet Statistics */ + netdriver_addr_t de_address; /* Ethernet Address */ unsigned long bytes_Tx; /* Total bytes sent/received */ unsigned long bytes_Rx; -#define SA_ADDR_LEN sizeof(ether_addr_t) +#define SA_ADDR_LEN sizeof(netdriver_addr_t) int de_flags; /* Send/Receive mode (Configuration) */ @@ -144,8 +141,8 @@ typedef struct dpeth { port_t de_dp8390_port; int de_prog_IO; int de_16bit; - int de_startpage; - int de_stoppage; + unsigned int de_startpage; + unsigned int de_stoppage; /* Do it yourself send queue */ struct sendq { @@ -153,9 +150,9 @@ typedef struct dpeth { int sq_size; /* with this size */ int sq_sendpage; /* starting page of the buffer */ } de_sendq[SENDQ_NR]; - int de_sendq_nr; - int de_sendq_head; /* Enqueue at the head */ - int de_sendq_tail; /* Dequeue at the tail */ + unsigned int de_sendq_nr; + unsigned int de_sendq_head; /* Enqueue at the head */ + unsigned int de_sendq_tail; /* Dequeue at the tail */ dp_user2nicf_t de_user2nicf; dp_nic2userf_t de_nic2userf; diff --git a/minix/drivers/net/dpeth/ne.c b/minix/drivers/net/dpeth/ne.c index 4b8add035..a6ea8d1f8 100644 --- a/minix/drivers/net/dpeth/ne.c +++ b/minix/drivers/net/dpeth/ne.c @@ -14,8 +14,6 @@ #include #include -#include -#include #include "dp.h" #if (ENABLE_NE2000 == 1) @@ -58,7 +56,7 @@ static void ne_close(dpeth_t * dep) */ static void ne_init(dpeth_t * dep) { - int ix; + unsigned int ix; dep->de_data_port = dep->de_base_port + NE_DATA; if (dep->de_16bit) { @@ -85,12 +83,12 @@ static void ne_init(dpeth_t * dep) ns_init(dep); /* Initialize DP controller */ printf("%s: NE%d000 (%dkB RAM) at %X:%d - ", - dep->de_name, + netdriver_name(), dep->de_16bit ? 2 : 1, dep->de_ramsize / 1024, dep->de_base_port, dep->de_irq); for (ix = 0; ix < SA_ADDR_LEN; ix += 1) - printf("%02X%c", dep->de_address.ea_addr[ix], + printf("%02X%c", dep->de_address.na_addr[ix], ix < SA_ADDR_LEN - 1 ? ':' : '\n'); } @@ -103,7 +101,7 @@ static void ne_init(dpeth_t * dep) */ int ne_probe(dpeth_t * dep) { - int ix, wd, loc1, loc2; + unsigned int ix, wd, loc1, loc2; char EPROM[32]; static const struct { unsigned char offset; @@ -176,7 +174,7 @@ int ne_probe(dpeth_t * dep) /* Setup the ethernet address. */ for (ix = 0; ix < SA_ADDR_LEN; ix += 1) { - dep->de_address.ea_addr[ix] = EPROM[ix]; + dep->de_address.na_addr[ix] = EPROM[ix]; } dep->de_16bit = wd; dep->de_linmem = 0; /* Uses Programmed I/O only */ diff --git a/minix/drivers/net/dpeth/netbuff.c b/minix/drivers/net/dpeth/netbuff.c index 955c466e7..7a3877ba2 100644 --- a/minix/drivers/net/dpeth/netbuff.c +++ b/minix/drivers/net/dpeth/netbuff.c @@ -9,8 +9,6 @@ #include #include -#include -#include #include "dp.h" #if (HAVE_BUFFERS == 1) @@ -90,7 +88,8 @@ void init_buff(dpeth_t *dep, buff_t **tx_buff) free_buff(dep, rx + 1); dep->de_recvq_tail = dep->de_recvq_head = NULL; if (tx_buff != NULL) { - *tx_buff = alloc_buff(dep, ETH_MAX_PACK_SIZE + sizeof(buff_t)); + *tx_buff = alloc_buff(dep, + NDEV_ETH_PACKET_MAX + sizeof(buff_t)); (*tx_buff)->size = 0; } } diff --git a/minix/drivers/net/dpeth/wd.c b/minix/drivers/net/dpeth/wd.c index 2e3d5d1df..9a46dce10 100644 --- a/minix/drivers/net/dpeth/wd.c +++ b/minix/drivers/net/dpeth/wd.c @@ -14,8 +14,6 @@ #include #include -#include -#include #include "dp.h" #if (ENABLE_WDETH == 1) @@ -69,14 +67,14 @@ int wdeth_probe(dpeth_t *dep) *===========================================================================*/ static void we_init(dpeth_t *dep) { - int i, int_indx, int_nr; + unsigned int i, int_indx, int_nr; int tlb, rambit, revision; int icr, irr, hwr, b, gcr; int we_type; - int sendq_nr; + unsigned int sendq_nr; for (i = 0; i < 6; i += 1) { - dep->de_address.ea_addr[i] = inb_we(dep, EPL_EA0 + i); + dep->de_address.na_addr[i] = inb_we(dep, EPL_EA0 + i); } dep->de_dp8390_port = dep->de_base_port + EPL_DP8390; @@ -154,7 +152,7 @@ static void we_init(dpeth_t *dep) irr = inb_we(dep, EPL_IRR); int_indx = (icr & E_ICR_IR2) | ((irr & (E_IRR_IR0 | E_IRR_IR1)) >> 5); int_nr = we_int_table[int_indx]; - DEBUG(printf("%s: encoded irq= %d\n", dep->de_name, int_nr)); + DEBUG(printf("%s: encoded irq= %d\n", netdriver_name(), int_nr)); if (dep->de_irq & DEI_DEFAULT) dep->de_irq = int_nr; outb_we(dep, EPL_IRR, irr | E_IRR_IEN); } @@ -169,7 +167,7 @@ static void we_init(dpeth_t *dep) int_indx = ((gcr & E_790_GCR_IR2) >> 4) | ((gcr & (E_790_GCR_IR1 | E_790_GCR_IR0)) >> 2); int_nr = we_790int_table[int_indx]; - DEBUG(printf("%s: encoded irq= %d\n", dep->de_name, int_nr)); + DEBUG(printf("%s: encoded irq= %d\n", netdriver_name(), int_nr)); if (dep->de_irq & DEI_DEFAULT) dep->de_irq = int_nr; icr = inb_we(dep, EPL_790_ICR); outb_we(dep, EPL_790_ICR, icr | E_790_ICR_EIL); @@ -195,14 +193,14 @@ static void we_init(dpeth_t *dep) ns_init(dep); /* Initialize DP controller */ printf("%s: WD80%d3 (%dkB RAM) at %X:%d:%lX - ", - dep->de_name, + netdriver_name(), we_type & WET_BRD_16BIT ? 1 : 0, dep->de_ramsize / 1024, dep->de_base_port, dep->de_irq, dep->de_linmem); for (i = 0; i < SA_ADDR_LEN; i += 1) - printf("%02X%c", dep->de_address.ea_addr[i], + printf("%02X%c", dep->de_address.na_addr[i], i < SA_ADDR_LEN - 1 ? ':' : '\n'); return; @@ -260,7 +258,7 @@ static int we_16bitboard(dpeth_t *dep) * If the 16 bit enable bit is unchangable by software we'll assume an * 8 bit board. */ - int icr; + unsigned int icr; u8_t tlb; icr = inb_we(dep, EPL_ICR); @@ -269,7 +267,7 @@ static int we_16bitboard(dpeth_t *dep) if (inb_we(dep, EPL_ICR) == icr) { tlb = inb_we(dep, EPL_TLB); - DEBUG(printf("%s: tlb= 0x%x\n", dep->de_name, tlb)); + DEBUG(printf("%s: tlb= 0x%x\n", netdriver_name(), tlb)); return tlb == E_TLB_EB || tlb == E_TLB_E || tlb == E_TLB_SMCE || tlb == E_TLB_SMC8216C; diff --git a/minix/drivers/net/e1000/Makefile b/minix/drivers/net/e1000/Makefile index 510936c04..9a6a6675b 100644 --- a/minix/drivers/net/e1000/Makefile +++ b/minix/drivers/net/e1000/Makefile @@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d DPADD+= ${LIBNETDRIVER} ${LIBSYS} LDADD+= -lnetdriver -lsys +WARNS?= 5 + .include diff --git a/minix/drivers/net/e1000/e1000.c b/minix/drivers/net/e1000/e1000.c index 3632c6da0..b8a30691c 100644 --- a/minix/drivers/net/e1000/e1000.c +++ b/minix/drivers/net/e1000/e1000.c @@ -10,14 +10,19 @@ #include "e1000_reg.h" #include "e1000_pci.h" -static int e1000_init(unsigned int instance, ether_addr_t *addr); +static int e1000_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks); static void e1000_stop(void); +static void e1000_set_mode(unsigned int, const netdriver_addr_t *, + unsigned int); +static void e1000_set_hwaddr(const netdriver_addr_t *); static int e1000_send(struct netdriver_data *data, size_t size); static ssize_t e1000_recv(struct netdriver_data *data, size_t max); -static void e1000_stat(eth_stat_t *stat); +static unsigned int e1000_get_link(uint32_t *); static void e1000_intr(unsigned int mask); +static void e1000_tick(void); static int e1000_probe(e1000_t *e, int skip); -static void e1000_init_hw(e1000_t *e, ether_addr_t *addr); +static void e1000_init_hw(e1000_t *e, netdriver_addr_t *addr); static uint32_t e1000_reg_read(e1000_t *e, uint32_t reg); static void e1000_reg_write(e1000_t *e, uint32_t reg, uint32_t value); static void e1000_reg_set(e1000_t *e, uint32_t reg, uint32_t value); @@ -31,12 +36,16 @@ static int e1000_instance; static e1000_t e1000_state; static const struct netdriver e1000_table = { - .ndr_init = e1000_init, - .ndr_stop = e1000_stop, - .ndr_recv = e1000_recv, - .ndr_send = e1000_send, - .ndr_stat = e1000_stat, - .ndr_intr = e1000_intr, + .ndr_name = "em", + .ndr_init = e1000_init, + .ndr_stop = e1000_stop, + .ndr_set_mode = e1000_set_mode, + .ndr_set_hwaddr = e1000_set_hwaddr, + .ndr_recv = e1000_recv, + .ndr_send = e1000_send, + .ndr_get_link = e1000_get_link, + .ndr_intr = e1000_intr, + .ndr_tick = e1000_tick }; /* @@ -58,7 +67,8 @@ main(int argc, char * argv[]) * Initialize the e1000 driver and device. */ static int -e1000_init(unsigned int instance, ether_addr_t * addr) +e1000_init(unsigned int instance, netdriver_addr_t * addr, uint32_t * caps, + unsigned int * ticks) { e1000_t *e; int r; @@ -69,8 +79,6 @@ e1000_init(unsigned int instance, ether_addr_t * addr) memset(&e1000_state, 0, sizeof(e1000_state)); e = &e1000_state; - strlcpy(e->name, "e1000#0", sizeof(e->name)); - e->name[6] += instance; /* Perform calibration. */ if ((r = tsc_calibrate()) != OK) @@ -83,6 +91,8 @@ e1000_init(unsigned int instance, ether_addr_t * addr) /* Initialize the hardware, and return its ethernet address. */ e1000_init_hw(e, addr); + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST | NDEV_CAP_HWADDR; + *ticks = sys_hz() / 10; /* update statistics 10x/sec */ return OK; } @@ -138,9 +148,9 @@ e1000_probe(e1000_t * e, int skip) u16_t vid, did, cr; u32_t status; u32_t base, size; - char *dname; + const char *dname; - E1000_DEBUG(3, ("%s: probe()\n", e->name)); + E1000_DEBUG(3, ("%s: probe()\n", netdriver_name())); /* Initialize communication to the PCI driver. */ pci_init(); @@ -152,7 +162,7 @@ e1000_probe(e1000_t * e, int skip) /* Loop devices on the PCI bus. */ while (skip--) { E1000_DEBUG(3, ("%s: probe() devind %d vid 0x%x did 0x%x\n", - e->name, devind, vid, did)); + netdriver_name(), devind, vid, did)); if (!(r = pci_next_dev(&devind, &vid, &did))) return FALSE; @@ -184,7 +194,7 @@ e1000_probe(e1000_t * e, int skip) if (!(dname = pci_dev_name(vid, did))) dname = "Intel Pro/1000 Gigabit Ethernet Card"; E1000_DEBUG(1, ("%s: %s (%04x/%04x) at %s\n", - e->name, dname, vid, did, pci_slot_name(devind))); + netdriver_name(), dname, vid, did, pci_slot_name(devind))); /* Reserve PCI resources found. */ pci_reserve(devind); @@ -210,8 +220,9 @@ e1000_probe(e1000_t * e, int skip) /* Output debug information. */ status = e1000_reg_read(e, E1000_REG_STATUS); - 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, + E1000_DEBUG(3, ("%s: MEM at %p, IRQ %d\n", netdriver_name(), + e->regs, e->irq)); + E1000_DEBUG(3, ("%s: link %s, %s duplex\n", netdriver_name(), status & 3 ? "up" : "down", status & 1 ? "full" : "half")); return TRUE; @@ -235,7 +246,7 @@ e1000_reset_hw(e1000_t * e) * Initialize and return the card's ethernet address. */ static void -e1000_init_addr(e1000_t * e, ether_addr_t * addr) +e1000_init_addr(e1000_t * e, netdriver_addr_t * addr) { static char eakey[] = E1000_ENVVAR "#_EA"; static char eafmt[] = "x:x:x:x:x:x"; @@ -250,27 +261,25 @@ e1000_init_addr(e1000_t * e, ether_addr_t * addr) if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) break; else - addr->ea_addr[i] = v; + addr->na_addr[i] = v; } /* If that fails, read Ethernet Address from EEPROM. */ if (i != 6) { for (i = 0; i < 3; i++) { word = e->eeprom_read(e, i); - addr->ea_addr[i * 2] = (word & 0x00ff); - addr->ea_addr[i * 2 + 1] = (word & 0xff00) >> 8; + addr->na_addr[i * 2] = (word & 0x00ff); + addr->na_addr[i * 2 + 1] = (word & 0xff00) >> 8; } } /* Set Receive Address. */ - e1000_reg_write(e, E1000_REG_RAL, *(u32_t *)(&addr->ea_addr[0])); - e1000_reg_write(e, E1000_REG_RAH, *(u16_t *)(&addr->ea_addr[4])); - e1000_reg_set(e, E1000_REG_RAH, E1000_REG_RAH_AV); - e1000_reg_set(e, E1000_REG_RCTL, E1000_REG_RCTL_MPE); + e1000_set_hwaddr(addr); - E1000_DEBUG(3, ("%s: Ethernet Address %x:%x:%x:%x:%x:%x\n", e->name, - addr->ea_addr[0], addr->ea_addr[1], addr->ea_addr[2], - addr->ea_addr[3], addr->ea_addr[4], addr->ea_addr[5])); + E1000_DEBUG(3, ("%s: Ethernet Address %x:%x:%x:%x:%x:%x\n", + netdriver_name(), + addr->na_addr[0], addr->na_addr[1], addr->na_addr[2], + addr->na_addr[3], addr->na_addr[4], addr->na_addr[5])); } /* @@ -348,7 +357,7 @@ e1000_init_buf(e1000_t * e) * Initialize the hardware. Return the ethernet address. */ static void -e1000_init_hw(e1000_t * e, ether_addr_t * addr) +e1000_init_hw(e1000_t * e, netdriver_addr_t * addr) { int r, i; @@ -399,6 +408,52 @@ e1000_init_hw(e1000_t * e, ether_addr_t * addr) E1000_REG_IMS_RXT | E1000_REG_IMS_TXQE | E1000_REG_IMS_TXDW); } +/* + * Set receive mode. + */ +static void +e1000_set_mode(unsigned int mode, const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) +{ + e1000_t *e; + uint32_t rctl; + + e = &e1000_state; + + rctl = e1000_reg_read(e, E1000_REG_RCTL); + + rctl &= ~(E1000_REG_RCTL_BAM | E1000_REG_RCTL_MPE | + E1000_REG_RCTL_UPE); + + /* TODO: support for NDEV_MODE_DOWN and multicast lists */ + if (mode & NDEV_MODE_BCAST) + rctl |= E1000_REG_RCTL_BAM; + if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) + rctl |= E1000_REG_RCTL_MPE; + if (mode & NDEV_MODE_PROMISC) + rctl |= E1000_REG_RCTL_BAM | E1000_REG_RCTL_MPE | + E1000_REG_RCTL_UPE; + + e1000_reg_write(e, E1000_REG_RCTL, rctl); +} + +/* + * Set hardware address. + */ +static void +e1000_set_hwaddr(const netdriver_addr_t * hwaddr) +{ + e1000_t *e; + + e = &e1000_state; + + e1000_reg_write(e, E1000_REG_RAL, + *(const u32_t *)(&hwaddr->na_addr[0])); + e1000_reg_write(e, E1000_REG_RAH, + *(const u16_t *)(&hwaddr->na_addr[4])); + e1000_reg_set(e, E1000_REG_RAH, E1000_REG_RAH_AV); +} + /* * Try to send a packet. */ @@ -463,7 +518,8 @@ e1000_recv(struct netdriver_data * data, size_t max) head = e1000_reg_read(e, E1000_REG_RDH); tail = e1000_reg_read(e, E1000_REG_RDT); - E1000_DEBUG(4, ("%s: head=%u, tail=%u\n", e->name, head, tail)); + E1000_DEBUG(4, ("%s: head=%u, tail=%u\n", + netdriver_name(), head, tail)); if (head == tail) return SUSPEND; @@ -506,40 +562,38 @@ e1000_recv(struct netdriver_data * data, size_t max) } /* - * Return statistics. + * Return the link and media status. */ -static void -e1000_stat(eth_stat_t * stat) +static unsigned int +e1000_get_link(uint32_t * media) { - e1000_t *e = &e1000_state; - - E1000_DEBUG(3, ("e1000: stat()\n")); - - stat->ets_recvErr = e1000_reg_read(e, E1000_REG_RXERRC); - stat->ets_sendErr = 0; - stat->ets_OVW = 0; - stat->ets_CRCerr = e1000_reg_read(e, E1000_REG_CRCERRS); - stat->ets_frameAll = 0; - stat->ets_missedP = e1000_reg_read(e, E1000_REG_MPC); - stat->ets_packetR = e1000_reg_read(e, E1000_REG_TPR); - stat->ets_packetT = e1000_reg_read(e, E1000_REG_TPT); - stat->ets_collision = e1000_reg_read(e, E1000_REG_COLC); - stat->ets_transAb = 0; - stat->ets_carrSense = 0; - stat->ets_fifoUnder = 0; - stat->ets_fifoOver = 0; - stat->ets_CDheartbeat = 0; - stat->ets_OWC = 0; -} + uint32_t status, type; -/* - * Link status has changed. Nothing to do for now. - */ -static void -e1000_link_changed(e1000_t * e) -{ + status = e1000_reg_read(&e1000_state, E1000_REG_STATUS); + + if (!(status & E1000_REG_STATUS_LU)) + return NDEV_LINK_DOWN; + + if (status & E1000_REG_STATUS_FD) + type = IFM_ETHER | IFM_FDX; + else + type = IFM_ETHER | IFM_HDX; + + switch (status & E1000_REG_STATUS_SPEED) { + case E1000_REG_STATUS_SPEED_10: + type |= IFM_10_T; + break; + case E1000_REG_STATUS_SPEED_100: + type |= IFM_100_TX; + break; + case E1000_REG_STATUS_SPEED_1000_A: + case E1000_REG_STATUS_SPEED_1000_B: + type |= IFM_1000_T; + break; + } - E1000_DEBUG(4, ("%s: link_changed()\n", e->name)); + *media = type; + return NDEV_LINK_UP; } /* @@ -562,7 +616,7 @@ e1000_intr(unsigned int __unused mask) /* Read the Interrupt Cause Read register. */ if ((cause = e1000_reg_read(e, E1000_REG_ICR)) != 0) { if (cause & E1000_REG_ICR_LSC) - e1000_link_changed(e); + netdriver_link(); if (cause & (E1000_REG_ICR_RXO | E1000_REG_ICR_RXT)) netdriver_recv(); @@ -572,6 +626,23 @@ e1000_intr(unsigned int __unused mask) } } +/* + * Do regular processing. + */ +static void +e1000_tick(void) +{ + e1000_t *e; + + e = &e1000_state; + + /* Update statistics. */ + netdriver_stat_ierror(e1000_reg_read(e, E1000_REG_RXERRC)); + netdriver_stat_ierror(e1000_reg_read(e, E1000_REG_CRCERRS)); + netdriver_stat_ierror(e1000_reg_read(e, E1000_REG_MPC)); + netdriver_stat_coll(e1000_reg_read(e, E1000_REG_COLC)); +} + /* * Stop the card. */ @@ -582,7 +653,7 @@ e1000_stop(void) e = &e1000_state; - E1000_DEBUG(3, ("%s: stop()\n", e->name)); + E1000_DEBUG(3, ("%s: stop()\n", netdriver_name())); e1000_reset_hw(e); } diff --git a/minix/drivers/net/e1000/e1000.h b/minix/drivers/net/e1000/e1000.h index f97b437e7..308b934da 100644 --- a/minix/drivers/net/e1000/e1000.h +++ b/minix/drivers/net/e1000/e1000.h @@ -112,7 +112,6 @@ */ typedef struct e1000 { - char name[8]; /**< String containing the device name. */ int irq; /**< Interrupt Request Vector. */ int irq_hook; /**< Interrupt Request Vector Hook. */ u8_t *regs; /**< Memory mapped hardware registers. */ diff --git a/minix/drivers/net/e1000/e1000_reg.h b/minix/drivers/net/e1000/e1000_reg.h index bcaefd114..5ba7ef8cc 100644 --- a/minix/drivers/net/e1000/e1000_reg.h +++ b/minix/drivers/net/e1000/e1000_reg.h @@ -164,6 +164,11 @@ /** Link Speed Setting. */ #define E1000_REG_STATUS_SPEED ((1 << 6) | (1 << 7)) +#define E1000_REG_STATUS_SPEED_10 (0 << 6) /* 10 Mb/s */ +#define E1000_REG_STATUS_SPEED_100 (1 << 6) /* 100 Mb/s */ +#define E1000_REG_STATUS_SPEED_1000_A (2 << 6) /* 1000 Mb/s */ +#define E1000_REG_STATUS_SPEED_1000_B (3 << 6) /* 1000 Mb/s */ + /** * @} */ @@ -245,7 +250,10 @@ /** Receive Enable. */ #define E1000_REG_RCTL_EN (1 << 1) -/** Multicast Promiscious Enable. */ +/** Unicast Promiscuous Enable. */ +#define E1000_REG_RCTL_UPE (1 << 3) + +/** Multicast Promiscuous Enable. */ #define E1000_REG_RCTL_MPE (1 << 4) /** Broadcast Accept Mode. */ diff --git a/minix/drivers/net/fxp/Makefile b/minix/drivers/net/fxp/Makefile index 3fc4548f3..3d67dda00 100644 --- a/minix/drivers/net/fxp/Makefile +++ b/minix/drivers/net/fxp/Makefile @@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d DPADD+= ${LIBNETDRIVER} ${LIBSYS} LDADD+= -lnetdriver -lsys +WARNS?= 5 + .include diff --git a/minix/drivers/net/fxp/fxp.c b/minix/drivers/net/fxp/fxp.c index 48d4bdcb5..bc70627d9 100644 --- a/minix/drivers/net/fxp/fxp.c +++ b/minix/drivers/net/fxp/fxp.c @@ -76,7 +76,6 @@ typedef struct fxp irq_hook_t fxp_hook; struct sc fxp_stat; u8_t fxp_conf_bytes[CC_BYTES_NR]; - char fxp_name[sizeof("fxp#n")]; } fxp_t; /* fxp_type */ @@ -86,8 +85,6 @@ typedef struct fxp #define FT_82559 0x4 #define FT_82801 0x8 -static int fxp_instance; - static fxp_t *fxp_state; #define fxp_inb(port, offset) (do_inb((port) + (offset))) @@ -95,16 +92,20 @@ static fxp_t *fxp_state; #define fxp_outb(port, offset, value) (do_outb((port) + (offset), (value))) #define fxp_outl(port, offset, value) (do_outl((port) + (offset), (value))) -static int fxp_init(unsigned int instance, ether_addr_t *addr); +static int fxp_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks); static void fxp_intr(unsigned int __unused mask); static void fxp_stop(void); static int fxp_probe(fxp_t *fp, int skip); static void fxp_conf_hw(fxp_t *fp); -static void fxp_init_hw(fxp_t *fp, ether_addr_t *addr); +static void fxp_init_hw(fxp_t *fp, netdriver_addr_t *addr, + unsigned int instance); static void fxp_init_buf(fxp_t *fp); static void fxp_reset_hw(fxp_t *fp); -static void fxp_confaddr(fxp_t *fp, ether_addr_t *addr); -static void fxp_mode(unsigned int mode); +static void fxp_confaddr(fxp_t *fp, netdriver_addr_t *addr, + unsigned int instance); +static void fxp_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, + unsigned int mcast_count); static int fxp_send(struct netdriver_data *data, size_t size); static ssize_t fxp_recv(struct netdriver_data *data, size_t max); static void fxp_do_conf(fxp_t *fp); @@ -113,11 +114,11 @@ static void fxp_cu_ptr_cmd(fxp_t *fp, int cmd, phys_bytes bus_addr, int static void fxp_ru_ptr_cmd(fxp_t *fp, int cmd, phys_bytes bus_addr, int check_idle); static void fxp_restart_ru(fxp_t *fp); -static void fxp_stat(eth_stat_t *stat); static void fxp_handler(fxp_t *fp); static void fxp_check_ints(fxp_t *fp); -static void fxp_alarm(clock_t stamp); +static void fxp_tick(void); static int fxp_link_changed(fxp_t *fp); +static unsigned int fxp_get_link(uint32_t *media); static void fxp_report_link(fxp_t *fp); static u16_t eeprom_read(fxp_t *fp, int reg); static void eeprom_addrsize(fxp_t *fp); @@ -130,14 +131,15 @@ static void tell_iommu(vir_bytes start, size_t size, int pci_bus, int pci_dev, int pci_func); static const struct netdriver fxp_table = { + .ndr_name = "fxp", .ndr_init = fxp_init, .ndr_stop = fxp_stop, - .ndr_mode = fxp_mode, + .ndr_set_mode = fxp_set_mode, .ndr_recv = fxp_recv, .ndr_send = fxp_send, - .ndr_stat = fxp_stat, + .ndr_get_link = fxp_get_link, .ndr_intr = fxp_intr, - .ndr_alarm = fxp_alarm, + .ndr_tick = fxp_tick, }; /*===========================================================================* @@ -187,7 +189,7 @@ static void fxp_stop(void) /* Stop device */ #if VERBOSE - printf("%s: stopping device\n", fp->fxp_name); + printf("%s: stopping device\n", netdriver_name()); #endif fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET); @@ -196,13 +198,12 @@ static void fxp_stop(void) /*===========================================================================* * fxp_init * *===========================================================================*/ -static int fxp_init(unsigned int instance, ether_addr_t *addr) +static int fxp_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks) { fxp_t *fp; int r; - fxp_instance = instance; - if (!(fxp_state = alloc_contig(sizeof(*fxp_state), 0, NULL))) panic("couldn't allocate table"); @@ -210,25 +211,20 @@ static int fxp_init(unsigned int instance, ether_addr_t *addr) memset(fp, 0, sizeof(*fp)); - strlcpy(fp->fxp_name, "fxp#0", sizeof(fp->fxp_name)); - fp->fxp_name[4] += fxp_instance; - if ((r = tsc_calibrate()) != OK) panic("tsc_calibrate failed: %d", r); /* Configure PCI device. */ - if (!fxp_probe(fp, fxp_instance)) + if (!fxp_probe(fp, instance)) return ENXIO; fxp_conf_hw(fp); - fxp_init_hw(fp, addr); + fxp_init_hw(fp, addr, instance); fxp_report_link(fp); - /* Set watchdog timer. */ - if ((r = sys_setalarm(sys_hz(), 0)) != OK) - panic("unable to set watchdog alarm"); - + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; + *ticks = sys_hz(); return OK; } @@ -241,9 +237,9 @@ static int fxp_probe(fxp_t *fp, int skip) u16_t vid, did, cr; u32_t bar; u8_t ilr, rev; - char *str; + const char *str; #if VERBOSE - char *dname; + const char *dname; #endif pci_init(); @@ -264,7 +260,7 @@ static int fxp_probe(fxp_t *fp, int skip) if (!dname) dname= "unknown device"; printf("%s: %s (%04x/%04x) at %s\n", - fp->fxp_name, dname, vid, did, pci_slot_name(devind)); + netdriver_name(), dname, vid, did, pci_slot_name(devind)); #endif pci_reserve(devind); @@ -283,7 +279,7 @@ static int fxp_probe(fxp_t *fp, int skip) fp->fxp_irq= ilr; #if VERBOSE printf("%s: using I/O address 0x%lx, IRQ %d\n", - fp->fxp_name, (unsigned long)bar, ilr); + netdriver_name(), (unsigned long)bar, ilr); #endif rev= pci_attr_r8(devind, PCI_REV); @@ -338,9 +334,10 @@ static int fxp_probe(fxp_t *fp, int skip) #if VERBOSE if (str) - printf("%s: device revision: %s\n", fp->fxp_name, str); + printf("%s: device revision: %s\n", netdriver_name(), str); else - printf("%s: unknown revision: 0x%x\n", fp->fxp_name, rev); + printf("%s: unknown revision: 0x%x\n", netdriver_name(), + rev); #endif if (fp->fxp_type == FT_UNKNOWN) @@ -445,7 +442,8 @@ static void fxp_conf_hw(fxp_t *fp) /*===========================================================================* * fxp_init_hw * *===========================================================================*/ -static void fxp_init_hw(fxp_t *fp, ether_addr_t *addr) +static void fxp_init_hw(fxp_t *fp, netdriver_addr_t *addr, + unsigned int instance) { int r, isr; port_t port; @@ -490,7 +488,7 @@ static void fxp_init_hw(fxp_t *fp, ether_addr_t *addr) fxp_ru_ptr_cmd(fp, SC_RU_START, fp->fxp_rx_busaddr, TRUE /* check idle */); - fxp_confaddr(fp, addr); + fxp_confaddr(fp, addr, instance); } /*===========================================================================* @@ -624,7 +622,8 @@ fxp_t *fp; /*===========================================================================* * fxp_confaddr * *===========================================================================*/ -static void fxp_confaddr(fxp_t *fp, ether_addr_t *addr) +static void fxp_confaddr(fxp_t *fp, netdriver_addr_t *addr, + unsigned int instance) { static char eakey[]= FXP_ENVVAR "#_EA"; static char eafmt[]= "x:x:x:x:x:x"; @@ -633,13 +632,13 @@ static void fxp_confaddr(fxp_t *fp, ether_addr_t *addr) long v; /* User defined ethernet address? */ - eakey[sizeof(FXP_ENVVAR)-1]= '0' + fxp_instance; + eakey[sizeof(FXP_ENVVAR)-1]= '0' + instance; for (i= 0; i < 6; i++) { if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) break; - addr->ea_addr[i]= v; + addr->na_addr[i]= v; } if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */ @@ -650,8 +649,8 @@ static void fxp_confaddr(fxp_t *fp, ether_addr_t *addr) for (i= 0; i<3; i++) { v= eeprom_read(fp, i); - addr->ea_addr[i*2]= (v & 0xff); - addr->ea_addr[i*2+1]= ((v >> 8) & 0xff); + addr->na_addr[i*2]= (v & 0xff); + addr->na_addr[i*2+1]= ((v >> 8) & 0xff); } } @@ -659,7 +658,7 @@ static void fxp_confaddr(fxp_t *fp, ether_addr_t *addr) tmpbufp->ias.ias_status= 0; tmpbufp->ias.ias_command= CBL_C_EL | CBL_AIS; tmpbufp->ias.ias_linkaddr= 0; - memcpy(tmpbufp->ias.ias_ethaddr, addr->ea_addr, + memcpy(tmpbufp->ias.ias_ethaddr, addr->na_addr, sizeof(tmpbufp->ias.ias_ethaddr)); r= sys_umap(SELF, VM_D, (vir_bytes)&tmpbufp->ias, (phys_bytes)sizeof(tmpbufp->ias), &bus_addr); @@ -677,17 +676,19 @@ static void fxp_confaddr(fxp_t *fp, ether_addr_t *addr) panic("fxp_confaddr: CU command failed"); #if VERBOSE - printf("%s: hardware ethernet address: ", fp->fxp_name); + printf("%s: hardware ethernet address: ", netdriver_name()); for (i= 0; i<6; i++) - printf("%02x%s", addr->ea_addr[i], i < 5 ? ":" : ""); + printf("%02x%s", addr->na_addr[i], i < 5 ? ":" : ""); printf("\n"); #endif } /*===========================================================================* - * fxp_mode * + * fxp_set_mode * *===========================================================================*/ -static void fxp_mode(unsigned int mode) +static void fxp_set_mode(unsigned int mode, + const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) { fxp_t *fp; @@ -697,12 +698,13 @@ static void fxp_mode(unsigned int mode) fp->fxp_conf_bytes[15] &= ~(CCB15_BD|CCB15_PM); fp->fxp_conf_bytes[21] &= ~CCB21_MA; - if (mode & NDEV_PROMISC) + if (mode & NDEV_MODE_PROMISC) fp->fxp_conf_bytes[15] |= CCB15_PM; - if (mode & NDEV_MULTI) + if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) fp->fxp_conf_bytes[21] |= CCB21_MA; - if (!(mode & (NDEV_BROAD|NDEV_MULTI|NDEV_PROMISC))) + if (!(mode & (NDEV_MODE_BCAST | NDEV_MODE_MCAST_LIST | + NDEV_MODE_MCAST_ALL | NDEV_MODE_PROMISC))) fp->fxp_conf_bytes[15] |= CCB15_BD; /* Queue request if not idle */ @@ -1034,9 +1036,9 @@ fxp_t *fp; } /*===========================================================================* - * fxp_stat * + * fxp_update_stats * *===========================================================================*/ -static void fxp_stat(eth_stat_t *stat) +static void fxp_update_stats(void) { fxp_t *fp; u32_t *p; @@ -1049,41 +1051,26 @@ static void fxp_stat(eth_stat_t *stat) /* The dump commmand doesn't take a pointer. Setting a pointer * doesn't hurt though. */ - fxp_cu_ptr_cmd(fp, SC_CU_DUMP_SC, 0, FALSE /* do not check idle */); + fxp_cu_ptr_cmd(fp, SC_CU_DUMP_RSET_SC, 0, + FALSE /* do not check idle */); /* Wait for CU command to complete */ - SPIN_UNTIL(*p != 0, 1000); + SPIN_UNTIL(*p != 0, 2500); if (*p == 0) panic("fxp_stat: CU command failed to complete"); - if (*p != SCM_DSC) + if (*p != SCM_DRSC) panic("fxp_stat: bad magic"); - stat->ets_recvErr= - fp->fxp_stat.sc_rx_crc + + netdriver_stat_ierror(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; - stat->ets_sendErr= - fp->fxp_stat.sc_tx_maxcol + - fp->fxp_stat.sc_tx_latecol + - fp->fxp_stat.sc_tx_crs; - stat->ets_OVW= fp->fxp_stat.sc_rx_overrun; - stat->ets_CRCerr= fp->fxp_stat.sc_rx_crc; - stat->ets_frameAll= fp->fxp_stat.sc_rx_align; - stat->ets_missedP= fp->fxp_stat.sc_rx_resource; - stat->ets_packetR= fp->fxp_stat.sc_rx_good; - stat->ets_packetT= fp->fxp_stat.sc_tx_good; - stat->ets_transDef= fp->fxp_stat.sc_tx_defered; - stat->ets_collision= fp->fxp_stat.sc_tx_totcol; - stat->ets_transAb= fp->fxp_stat.sc_tx_maxcol; - stat->ets_carrSense= fp->fxp_stat.sc_tx_crs; - stat->ets_fifoUnder= fp->fxp_stat.sc_tx_underrun; - stat->ets_fifoOver= fp->fxp_stat.sc_rx_overrun; - stat->ets_CDheartbeat= 0; - stat->ets_OWC= fp->fxp_stat.sc_tx_latecol; + fp->fxp_stat.sc_rx_short); + netdriver_stat_coll(fp->fxp_stat.sc_tx_maxcol + + fp->fxp_stat.sc_tx_latecol); + netdriver_stat_oerror(fp->fxp_stat.sc_tx_crs); } /*===========================================================================* @@ -1243,25 +1230,28 @@ static void fxp_check_ints(fxp_t *fp) } } - if (fp->fxp_report_link) + if (fp->fxp_report_link) { + netdriver_link(); + fxp_report_link(fp); + } } /*===========================================================================* - * fxp_alarm * + * fxp_tick * *===========================================================================*/ -static void fxp_alarm(clock_t __unused stamp) +static void fxp_tick(void) { fxp_t *fp; - sys_setalarm(sys_hz(), 0); + fxp_update_stats(); fp= fxp_state; /* Check the link status. */ if (fxp_link_changed(fp)) { #if VERBOSE - printf("fxp_alarm: link changed\n"); + printf("fxp_tick: link changed\n"); #endif fp->fxp_report_link= TRUE; fxp_check_ints(fp); @@ -1297,6 +1287,37 @@ static int fxp_link_changed(fxp_t *fp) return (fp->fxp_mii_scr != scr); } +/*===========================================================================* + * fxp_get_link * + *===========================================================================*/ +static unsigned int fxp_get_link(uint32_t *media) +{ + fxp_t *fp; + u16_t mii_status, scr; + + fp = fxp_state; + + scr= mii_read(fp, MII_SCR); + + mii_read(fp, MII_STATUS); /* The status reg is latched, read twice */ + mii_status= mii_read(fp, MII_STATUS); + + if (!(mii_status & MII_STATUS_LS)) + return NDEV_LINK_DOWN; + + if (scr & MII_SCR_100) + *media = IFM_ETHER | IFM_100_TX; + else + *media = IFM_ETHER | IFM_10_T; + + if (scr & MII_SCR_FD) + *media |= IFM_FDX; + else + *media |= IFM_HDX; + + return NDEV_LINK_UP; +} + /*===========================================================================* * fxp_report_link * *===========================================================================*/ @@ -1345,7 +1366,7 @@ static void fxp_report_link(fxp_t *fp) if (!link_up) { #if VERBOSE - printf("%s: link down\n", fp->fxp_name); + printf("%s: link down\n", netdriver_name()); #endif return; } @@ -1361,8 +1382,9 @@ static void fxp_report_link(fxp_t *fp) if (mii_ctrl & (MII_CTRL_LB|MII_CTRL_PD|MII_CTRL_ISO)) { - printf("%s: PHY: ", fp->fxp_name); f= 1; +#if VERBOSE + printf("%s: PHY: ", netdriver_name()); if (mii_ctrl & MII_CTRL_LB) { printf("loopback mode"); @@ -1381,11 +1403,13 @@ static void fxp_report_link(fxp_t *fp) printf("isolated"); } printf("\n"); +#endif return; } if (!(mii_ctrl & MII_CTRL_ANE)) { - printf("%s: manual config: ", fp->fxp_name); +#if VERBOSE + printf("%s: manual config: ", netdriver_name()); switch(mii_ctrl & (MII_CTRL_SP_LSB|MII_CTRL_SP_MSB)) { case MII_CTRL_SP_10: printf("10 Mbps"); break; @@ -1398,36 +1422,38 @@ static void fxp_report_link(fxp_t *fp) else printf(", half duplex"); printf("\n"); +#endif return; } #if VERBOSE - printf("%s: ", fp->fxp_name); + printf("%s: ", netdriver_name()); mii_print_stat_speed(mii_status, mii_extstat); printf("\n"); if (!(mii_status & MII_STATUS_ANC)) - printf("%s: auto-negotiation not complete\n", fp->fxp_name); + printf("%s: auto-negotiation not complete\n", + netdriver_name()); if (mii_status & MII_STATUS_RF) - printf("%s: remote fault detected\n", fp->fxp_name); + printf("%s: remote fault detected\n", netdriver_name()); if (!(mii_status & MII_STATUS_ANA)) { printf("%s: local PHY has no auto-negotiation ability\n", - fp->fxp_name); + netdriver_name()); } if (!(mii_status & MII_STATUS_LS)) - printf("%s: link down\n", fp->fxp_name); + printf("%s: link down\n", netdriver_name()); if (mii_status & MII_STATUS_JD) - printf("%s: jabber condition detected\n", fp->fxp_name); + printf("%s: jabber condition detected\n", netdriver_name()); if (!(mii_status & MII_STATUS_EC)) { - printf("%s: no extended register set\n", fp->fxp_name); + printf("%s: no extended register set\n", netdriver_name()); goto resspeed; } if (!(mii_status & MII_STATUS_ANC)) goto resspeed; - printf("%s: local cap.: ", fp->fxp_name); + printf("%s: local cap.: ", netdriver_name()); if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD)) { printf("1000 Mbps: T-"); @@ -1444,15 +1470,15 @@ static void fxp_report_link(fxp_t *fp) printf("\n"); if (mii_ane & MII_ANE_PDF) - printf("%s: parallel detection fault\n", fp->fxp_name); + printf("%s: parallel detection fault\n", netdriver_name()); if (!(mii_ane & MII_ANE_LPANA)) { printf("%s: link-partner does not support auto-negotiation\n", - fp->fxp_name); + netdriver_name()); goto resspeed; } - printf("%s: remote cap.: ", fp->fxp_name); + printf("%s: remote cap.: ", netdriver_name()); if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD)) if (mii_ms_status & (MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD)) { @@ -1472,7 +1498,7 @@ static void fxp_report_link(fxp_t *fp) if (fp->fxp_ms_regs) { - printf("%s: ", fp->fxp_name); + printf("%s: ", netdriver_name()); if (mii_ms_ctrl & MII_MSC_MS_MANUAL) { printf("manual %s", @@ -1502,17 +1528,17 @@ static void fxp_report_link(fxp_t *fp) if (!(mii_ms_status & MII_MSS_LOCREC)) { printf("%s: local receiver not OK\n", - fp->fxp_name); + netdriver_name()); } if (!(mii_ms_status & MII_MSS_REMREC)) { printf("%s: remote receiver not OK\n", - fp->fxp_name); + netdriver_name()); } } if (mii_ms_status & (MII_MSS_RES|MII_MSS_IDLE_ERR)) { - printf("%s", fp->fxp_name); + printf("%s", netdriver_name()); if (mii_ms_status & MII_MSS_RES) printf(" reserved<0x%x>", mii_ms_status & MII_MSS_RES); if (mii_ms_status & MII_MSS_IDLE_ERR) @@ -1527,7 +1553,7 @@ resspeed: #if VERBOSE printf("%s: link up, %d Mbps, %s duplex\n", - fp->fxp_name, (scr & MII_SCR_100) ? 100 : 10, + netdriver_name(), (scr & MII_SCR_100) ? 100 : 10, (scr & MII_SCR_FD) ? "full" : "half"); #endif } @@ -1643,7 +1669,7 @@ static void eeprom_addrsize(fxp_t *fp) #if VERBOSE printf("%s EEPROM address length: %d\n", - fp->fxp_name, fp->fxp_ee_addrlen); + netdriver_name(), fp->fxp_ee_addrlen); #endif } diff --git a/minix/drivers/net/fxp/fxp.h b/minix/drivers/net/fxp/fxp.h index 58a7e93bb..5c64f222d 100644 --- a/minix/drivers/net/fxp/fxp.h +++ b/minix/drivers/net/fxp/fxp.h @@ -429,7 +429,7 @@ struct tx u16_t tx_size; u8_t tx_tthresh; u8_t tx_ntbd; - u8_t tx_buf[ETH_MAX_PACK_SIZE_TAGGED]; + u8_t tx_buf[NDEV_ETH_PACKET_MAX_TAGGED]; }; #define TXS_C 0x8000 /* Transmit DMA has completed */ @@ -506,7 +506,7 @@ struct rfd u32_t rfd_reserved; u16_t rfd_res; u16_t rfd_size; - u8_t rfd_buf[ETH_MAX_PACK_SIZE_TAGGED]; + u8_t rfd_buf[NDEV_ETH_PACKET_MAX_TAGGED]; }; #define RFDS_C 0x8000 /* Frame Reception Completed */ diff --git a/minix/drivers/net/ip1000/ip1000.c b/minix/drivers/net/ip1000/ip1000.c index aa3be54dd..919b1eb4f 100644 --- a/minix/drivers/net/ip1000/ip1000.c +++ b/minix/drivers/net/ip1000/ip1000.c @@ -10,20 +10,21 @@ static NDR_driver g_driver; static int g_instance; /* driver interface */ -static int NDR_init(unsigned int instance, ether_addr_t *addr); +static int NDR_init(unsigned int instance, netdriver_addr_t * addr, + uint32_t * caps, unsigned int * ticks); static void NDR_stop(void); -static void NDR_mode(unsigned int mode); +static void NDR_set_mode(unsigned int mode, + const netdriver_addr_t * mcast_list, unsigned int mcast_count); static ssize_t NDR_recv(struct netdriver_data *data, size_t max); static int NDR_send(struct netdriver_data *data, size_t size); static void NDR_intr(unsigned int mask); -static void NDR_stat(eth_stat_t *stat); /* internal function */ static int dev_probe(NDR_driver *pdev, int instance); static int dev_init_buf(NDR_driver *pdev); -static int dev_init_hw(NDR_driver *pdev, ether_addr_t *addr); +static int dev_init_hw(NDR_driver *pdev, netdriver_addr_t *addr); static int dev_reset_hw(NDR_driver *pdev); -static void dev_conf_addr(NDR_driver *pdev, ether_addr_t *addr); +static void dev_conf_addr(NDR_driver *pdev, netdriver_addr_t *addr); static void dev_handler(NDR_driver *pdev); static void dev_check_ints(NDR_driver *pdev); @@ -338,11 +339,11 @@ static void dev_set_rec_mode(u32_t *base, int mode) { u32_t data, base0 = base[0]; data = ndr_in8(base0, REG_RCR); data &= ~(CMD_RCR_UNICAST | CMD_RCR_MULTICAST | CMD_RCR_BROADCAST); - if (mode & NDEV_PROMISC) + if (mode & NDEV_MODE_PROMISC) data |= CMD_RCR_UNICAST | CMD_RCR_MULTICAST | CMD_RCR_MULTICAST; - if (mode & NDEV_BROAD) + if (mode & NDEV_MODE_BCAST) data |= CMD_RCR_BROADCAST; - if (mode & NDEV_MULTI) + if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) data |= CMD_RCR_MULTICAST; data |= CMD_RCR_UNICAST; ndr_out8(base0, REG_RCR, data); @@ -455,13 +456,13 @@ static void dev_set_tx_desc_done(u32_t *base, NDR_desc *desc, int index) { /* Driver interface table */ static const struct netdriver NDR_table = { + .ndr_name = "stge", .ndr_init = NDR_init, .ndr_stop = NDR_stop, - .ndr_mode = NDR_mode, + .ndr_set_mode = NDR_set_mode, .ndr_recv = NDR_recv, .ndr_send = NDR_send, .ndr_intr = NDR_intr, - .ndr_stat = NDR_stat }; int main(int argc, char *argv[]) { @@ -470,15 +471,15 @@ int main(int argc, char *argv[]) { } /* Initialize the driver */ -static int NDR_init(unsigned int instance, ether_addr_t *addr) { +static int +NDR_init(unsigned int instance, netdriver_addr_t * addr, uint32_t * caps, + unsigned int * ticks __unused) +{ int i, ret = 0; /* Intialize driver data structure */ memset(&g_driver, 0, sizeof(g_driver)); g_driver.link = LINK_UNKNOWN; - strcpy(g_driver.name, DRIVER_NAME); - strcat(g_driver.name, "#0"); - g_driver.name[strlen(g_driver.name) - 1] += instance; g_instance = instance; /* Probe the device */ @@ -510,14 +511,12 @@ static int NDR_init(unsigned int instance, ether_addr_t *addr) { /* ### RX_TX_ENABLE_DISABLE ### */ dev_rx_tx_control(g_driver.base, RX_TX_ENABLE); - /* Use a synchronous alarm instead of a watchdog timer */ - sys_setalarm(sys_hz(), 0); - /* Clear send and recv flag */ g_driver.send_flag = FALSE; g_driver.recv_flag = FALSE; - return 0; + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; + return OK; err_init_buf: err_init_hw: @@ -540,7 +539,10 @@ static void NDR_stop(void) { } /* Set driver mode */ -static void NDR_mode(unsigned int mode) { +static void +NDR_set_mode(unsigned int mode, const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) +{ g_driver.mode = mode; /* Set driver receive mode */ /* ### SET_REC_MODE ### */ @@ -570,7 +572,7 @@ static ssize_t NDR_recv(struct netdriver_data *data, size_t max) { /* Get data length */ /* ### Get , int inde, int indexxRx data length ### */ - if (totlen < 8 || totlen > 2 * ETH_MAX_PACK_SIZE) { + if (totlen < 8 || totlen > 2 * NDEV_ETH_PACKET_MAX) { printf("NDR: Bad data length: %d\n", totlen); panic(NULL); } @@ -581,7 +583,6 @@ static ssize_t NDR_recv(struct netdriver_data *data, size_t max) { /* Copy data to user */ netdriver_copyout(data, 0, pdev->rx[index].buf + offset, packlen); - pdev->stat.ets_packetR++; /* Set Rx descriptor after Rx done */ /* ### SET_RX_DESC_DONE ### */ @@ -649,11 +650,6 @@ static void NDR_intr(unsigned int mask) { dev_check_ints(&g_driver); } -/* Get driver status */ -static void NDR_stat(eth_stat_t *stat) { - memcpy(stat, &g_driver.stat, sizeof(*stat)); -} - /* Match the device and get base address */ static int dev_probe(NDR_driver *pdev, int instance) { int devind, ioflag, i; @@ -717,7 +713,7 @@ static int dev_probe(NDR_driver *pdev, int instance) { } /* Intialize hardware */ -static int dev_init_hw(NDR_driver *pdev, ether_addr_t *addr) { +static int dev_init_hw(NDR_driver *pdev, netdriver_addr_t *addr) { int r, ret; /* Set the OS interrupt handler */ @@ -800,22 +796,22 @@ err_real_reset: } /* Configure MAC address */ -static void dev_conf_addr(NDR_driver *pdev, ether_addr_t *addr) { +static void dev_conf_addr(NDR_driver *pdev, netdriver_addr_t *addr) { u8_t pa[6]; /* Get MAC address */ /* ### GET_MAC_ADDR ### */ dev_get_addr(pdev->base, pa); - addr->ea_addr[0] = pa[0]; - addr->ea_addr[1] = pa[1]; - addr->ea_addr[2] = pa[2]; - addr->ea_addr[3] = pa[3]; - addr->ea_addr[4] = pa[4]; - addr->ea_addr[5] = pa[5]; + addr->na_addr[0] = pa[0]; + addr->na_addr[1] = pa[1]; + addr->na_addr[2] = pa[2]; + addr->na_addr[3] = pa[3]; + addr->na_addr[4] = pa[4]; + addr->na_addr[5] = pa[5]; #ifdef MY_DEBUG printf("NDR: Ethernet address is %02x:%02x:%02x:%02x:%02x:%02x\n", - addr->ea_addr[0], addr->ea_addr[1], addr->ea_addr[2], - addr->ea_addr[3], addr->ea_addr[4], addr->ea_addr[5]); + addr->na_addr[0], addr->na_addr[1], addr->na_addr[2], + addr->na_addr[3], addr->na_addr[4], addr->na_addr[5]); #endif } @@ -950,7 +946,6 @@ static void dev_handler(NDR_driver *pdev) { else if (ret == TX_ERROR) printf("NDR: Tx error now\n"); - pdev->stat.ets_packetT++; pdev->tx[tx_tail].busy = FALSE; pdev->tx_busy_num--; diff --git a/minix/drivers/net/ip1000/ip1000.h b/minix/drivers/net/ip1000/ip1000.h index d07f4f431..7ed366505 100644 --- a/minix/drivers/net/ip1000/ip1000.h +++ b/minix/drivers/net/ip1000/ip1000.h @@ -185,8 +185,6 @@ typedef struct NDR_driver { phys_bytes tx_desc_dma; /* Tx descriptor DMA buffer */ int hook; /* IRQ hook id at kernel */ - eth_stat_t stat; /* Ethernet status */ - char name[50]; /* Driver name */ } NDR_driver; #endif diff --git a/minix/drivers/net/lan8710a/Makefile b/minix/drivers/net/lan8710a/Makefile index 9a610343c..1c21460cb 100644 --- a/minix/drivers/net/lan8710a/Makefile +++ b/minix/drivers/net/lan8710a/Makefile @@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d DPADD+= ${LIBNETDRIVER} ${LIBSYS} LDADD+= -lnetdriver -lsys +WARNS?= 5 + .include diff --git a/minix/drivers/net/lan8710a/lan8710a.c b/minix/drivers/net/lan8710a/lan8710a.c index eb5ecbdea..ed34c940c 100644 --- a/minix/drivers/net/lan8710a/lan8710a.c +++ b/minix/drivers/net/lan8710a/lan8710a.c @@ -7,21 +7,22 @@ #include "lan8710a_reg.h" /* Local functions */ -static int lan8710a_init(unsigned int instance, ether_addr_t *addr); +static int lan8710a_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks); static void lan8710a_stop(void); static ssize_t lan8710a_recv(struct netdriver_data *data, size_t max); static int lan8710a_send(struct netdriver_data *data, size_t size); -static void lan8710a_stat(eth_stat_t *stat); static void lan8710a_intr(unsigned int mask); +static void lan8710a_tick(void); static void lan8710a_enable_interrupt(int interrupt); static void lan8710a_map_regs(void); static void lan8710a_dma_config_tx(u8_t desc_idx); static void lan8710a_dma_reset_init(void); -static void lan8710a_init_addr(ether_addr_t *addr); +static void lan8710a_init_addr(netdriver_addr_t *addr, unsigned int instance); static void lan8710a_init_desc(void); static void lan8710a_init_mdio(void); -static int lan8710a_init_hw(ether_addr_t *addr); +static int lan8710a_init_hw(netdriver_addr_t *addr, unsigned int instance); static void lan8710a_reset_hw(void); static void lan8710a_phy_write(u32_t reg, u32_t value); @@ -36,12 +37,13 @@ static void lan8710a_reg_unset(volatile u32_t *reg, u32_t value); static lan8710a_t lan8710a_state; static const struct netdriver lan8710a_table = { + .ndr_name = "cpsw", .ndr_init = lan8710a_init, .ndr_stop = lan8710a_stop, .ndr_recv = lan8710a_recv, .ndr_send = lan8710a_send, - .ndr_stat = lan8710a_stat, - .ndr_intr = lan8710a_intr + .ndr_intr = lan8710a_intr, + .ndr_tick = lan8710a_tick }; /*============================================================================* @@ -65,22 +67,21 @@ main(int argc, char *argv[]) * lan8710a_init * *============================================================================*/ static int -lan8710a_init(unsigned int instance, ether_addr_t * addr) +lan8710a_init(unsigned int instance, netdriver_addr_t * addr, uint32_t * caps, + unsigned int * ticks) { /* Initialize the ethernet driver. */ /* Clear state. */ memset(&lan8710a_state, 0, sizeof(lan8710a_state)); - strlcpy(lan8710a_state.name, "lan8710a#0", LAN8710A_NAME_LEN); - lan8710a_state.name[9] += instance; - lan8710a_state.instance = instance; - /* Initialize driver. */ lan8710a_map_regs(); - lan8710a_init_hw(addr); + lan8710a_init_hw(addr, instance); + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; + *ticks = sys_hz(); /* update statistics once a second */ return OK; } @@ -158,7 +159,7 @@ lan8710a_intr(unsigned int mask) * lan8710a_init_addr * *============================================================================*/ static void -lan8710a_init_addr(ether_addr_t * addr) +lan8710a_init_addr(netdriver_addr_t * addr, unsigned int instance) { static char eakey[]= LAN8710A_ENVVAR "#_EA"; static char eafmt[]= "x:x:x:x:x:x"; @@ -168,13 +169,13 @@ lan8710a_init_addr(ether_addr_t * addr) /* * Do we have a user defined ethernet address? */ - eakey[sizeof(LAN8710A_ENVVAR)-1] = '0' + lan8710a_state.instance; + eakey[sizeof(LAN8710A_ENVVAR)-1] = '0' + instance; for (i= 0; i < 6; i++) { if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) break; else - addr->ea_addr[i] = v; + addr->na_addr[i] = v; } if (i == 6) return; @@ -182,12 +183,12 @@ lan8710a_init_addr(ether_addr_t * addr) /* * No; get the address from the chip itself. */ - addr->ea_addr[0] = lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF; - addr->ea_addr[1] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 8) & 0xFF; - addr->ea_addr[2] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 16) & 0xFF; - addr->ea_addr[3] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 24) & 0xFF; - addr->ea_addr[4] = lan8710a_reg_read(CTRL_MAC_ID0_LO) & 0xFF; - addr->ea_addr[5] = (lan8710a_reg_read(CTRL_MAC_ID0_LO) >> 8) & 0xFF; + addr->na_addr[0] = lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF; + addr->na_addr[1] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 8) & 0xFF; + addr->na_addr[2] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 16) & 0xFF; + addr->na_addr[3] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 24) & 0xFF; + addr->na_addr[4] = lan8710a_reg_read(CTRL_MAC_ID0_LO) & 0xFF; + addr->na_addr[5] = (lan8710a_reg_read(CTRL_MAC_ID0_LO) >> 8) & 0xFF; } /*============================================================================* @@ -287,28 +288,44 @@ lan8710a_map_regs(void) } /*============================================================================* - * lan8710a_stat * + * lan8710a_update_stats * + *============================================================================*/ +static void +lan8710a_update_stats(void) +{ + uint32_t val; + + /* + * AM335x Technical Reference (SPRUH73J) Sec. 14.3.2.20: statistics + * registers are decrement-on-write when any of the statistics port + * enable bits are set. + */ + val = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR); + lan8710a_reg_write(CPSW_STAT_RX_CRC_ERR, val); + netdriver_stat_ierror(val); + + val = lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR); + lan8710a_reg_write(CPSW_STAT_RX_AGNCD_ERR, val); + netdriver_stat_ierror(val); + + val = lan8710a_reg_read(CPSW_STAT_RX_OVERSIZE); + lan8710a_reg_write(CPSW_STAT_RX_OVERSIZE, val); + netdriver_stat_ierror(val); + + val = lan8710a_reg_read(CPSW_STAT_COLLISIONS); + lan8710a_reg_write(CPSW_STAT_COLLISIONS, val); + netdriver_stat_coll(val); +} + +/*============================================================================* + * lan8710a_tick * *============================================================================*/ static void -lan8710a_stat(eth_stat_t * stat) +lan8710a_tick(void) { - stat->ets_recvErr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR) - + lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR) - + lan8710a_reg_read(CPSW_STAT_RX_OVERSIZE); - stat->ets_sendErr = 0; - stat->ets_OVW = 0; - stat->ets_CRCerr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR); - stat->ets_frameAll = lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR); - stat->ets_missedP = 0; - stat->ets_packetR = lan8710a_reg_read(CPSW_STAT_RX_GOOD); - stat->ets_packetT = lan8710a_reg_read(CPSW_STAT_TX_GOOD); - stat->ets_collision = lan8710a_reg_read(CPSW_STAT_COLLISIONS); - stat->ets_transAb = 0; - stat->ets_carrSense = lan8710a_reg_read(CPSW_STAT_CARR_SENS_ERR); - stat->ets_fifoUnder = lan8710a_reg_read(CPSW_STAT_TX_UNDERRUN); - stat->ets_fifoOver = lan8710a_reg_read(CPSW_STAT_RX_OVERRUN); - stat->ets_CDheartbeat = 0; - stat->ets_OWC = 0; + + /* Update statistics. */ + lan8710a_update_stats(); } /*============================================================================* @@ -399,7 +416,6 @@ lan8710a_init_desc(void) lan8710a_desc_t *p_rx_desc; lan8710a_desc_t *p_tx_desc; phys_bytes buf_phys_addr; - u8_t *p_buf; u8_t i; /* Attempt to allocate. */ @@ -408,7 +424,6 @@ lan8710a_init_desc(void) &buf_phys_addr)) == NULL) { panic("failed to allocate RX buffers."); } - p_buf = lan8710a_state.p_rx_buf; for (i = 0; i < LAN8710A_NUM_RX_DESC; i++) { p_rx_desc = &(lan8710a_state.rx_desc[i]); memset(p_rx_desc, 0x0, sizeof(lan8710a_desc_t)); @@ -430,7 +445,6 @@ lan8710a_init_desc(void) &buf_phys_addr)) == NULL) { panic("failed to allocate TX buffers"); } - p_buf = lan8710a_state.p_tx_buf; for (i = 0; i < LAN8710A_NUM_TX_DESC; i++) { p_tx_desc = &(lan8710a_state.tx_desc[i]); memset(p_tx_desc, 0x0, sizeof(lan8710a_desc_t)); @@ -445,7 +459,7 @@ lan8710a_init_desc(void) * lan8710a_init_hw * *============================================================================*/ static int -lan8710a_init_hw(ether_addr_t * addr) +lan8710a_init_hw(netdriver_addr_t * addr, unsigned int instance) { int r, i; @@ -615,7 +629,7 @@ lan8710a_init_hw(ether_addr_t * addr) lan8710a_init_mdio(); /* Getting MAC Address */ - lan8710a_init_addr(addr); + lan8710a_init_addr(addr, instance); /* Initialize descriptors */ lan8710a_init_desc(); @@ -703,7 +717,8 @@ lan8710a_send(struct netdriver_data * data, size_t size) /* Drop packets that exceed the size of our transmission buffer. */ if (size > LAN8710A_IOBUF_SIZE) { - printf("%s: dropping large packet (%zu)\n", e->name, size); + printf("%s: dropping large packet (%zu)\n", + netdriver_name(), size); return OK; } diff --git a/minix/drivers/net/lan8710a/lan8710a.h b/minix/drivers/net/lan8710a/lan8710a.h index 3dca3a787..3bcce840d 100644 --- a/minix/drivers/net/lan8710a/lan8710a.h +++ b/minix/drivers/net/lan8710a/lan8710a.h @@ -1,8 +1,6 @@ #ifndef LAN8710A_H_ #define LAN8710A_H_ -#include - #define LAN8710A_DEBUG (1) #if LAN8710A_DEBUG == 1 @@ -68,10 +66,8 @@ typedef struct lan8710a_t lan8710a_desc_t *tx_desc; phys_bytes rx_desc_phy; phys_bytes tx_desc_phy; - char name[LAN8710A_NAME_LEN]; int irq_rx_hook; /* Rx interrupt Request Vector Hook. */ int irq_tx_hook; /* Tx interrupt Request Vector Hook. */ - int instance; u8_t *regs; u32_t phy_address; u8_t *p_rx_buf; /* pointer to the buffer with receive frames */ diff --git a/minix/drivers/net/lance/Makefile b/minix/drivers/net/lance/Makefile index 5825ff2a1..ee1d645ed 100644 --- a/minix/drivers/net/lance/Makefile +++ b/minix/drivers/net/lance/Makefile @@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d DPADD+= ${LIBNETDRIVER} ${LIBSYS} LDADD+= -lnetdriver -lsys +WARNS?= 5 + .include diff --git a/minix/drivers/net/lance/lance.c b/minix/drivers/net/lance/lance.c index b63d40029..d360047b2 100644 --- a/minix/drivers/net/lance/lance.c +++ b/minix/drivers/net/lance/lance.c @@ -14,9 +14,6 @@ #include #include -#include -#include -#include #include #include @@ -26,21 +23,23 @@ #include "lance.h" -static int do_init(unsigned int instance, ether_addr_t *addr); -static void ec_confaddr(ether_addr_t *addr); +static int do_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks); +static void ec_confaddr(netdriver_addr_t *addr, unsigned int instance); static void ec_reinit(ether_card_t *ec); static void ec_reset(ether_card_t *ec); static void do_intr(unsigned int mask); -static void do_mode(unsigned int mode); +static void do_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, + unsigned int mcast_count); static int do_send(struct netdriver_data *data, size_t size); static ssize_t do_recv(struct netdriver_data *data, size_t max); -static void do_stat(eth_stat_t *stat); static void do_stop(void); static void lance_dump(void); static void do_other(const message *m_ptr, int ipc_status); static void get_addressing(int devind, ether_card_t *ec); static int lance_probe(ether_card_t *ec, unsigned int skip); -static void lance_init_hw(ether_card_t *ec, ether_addr_t *addr); +static void lance_init_hw(ether_card_t *ec, netdriver_addr_t *addr, + unsigned int instance); /* Accesses Lance Control and Status Registers */ static u8_t in_byte(port_t port); @@ -50,7 +49,6 @@ static u16_t read_csr(port_t ioaddr, u16_t csrno); static void write_csr(port_t ioaddr, u16_t csrno, u16_t value); static ether_card_t ec_state; -static int ec_instance; /* --- LANCE --- */ /* General */ @@ -159,14 +157,14 @@ static phys_bytes tx_ring_base[TX_RING_SIZE]; /* Tx-slot physical address */ static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */ static const struct netdriver lance_table = { - .ndr_init = do_init, - .ndr_stop = do_stop, - .ndr_mode = do_mode, - .ndr_recv = do_recv, - .ndr_send = do_send, - .ndr_stat = do_stat, - .ndr_intr = do_intr, - .ndr_other = do_other, + .ndr_name = "le", + .ndr_init = do_init, + .ndr_stop = do_stop, + .ndr_set_mode = do_set_mode, + .ndr_recv = do_recv, + .ndr_send = do_send, + .ndr_intr = do_intr, + .ndr_other = do_other, }; /*===========================================================================* @@ -194,34 +192,11 @@ static void lance_dump() printf("\n"); ec = &ec_state; - 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("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("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("OWC :%8ld\t", ec->eth_stat.ets_OWC); + printf("lance driver %s:\n", netdriver_name()); ioaddr = ec->ec_port; isr = read_csr(ioaddr, LANCE_CSR0); - printf("isr = 0x%x, flags = 0x%x\n", isr, - ec->flags); + printf("isr = 0x%x, mode = 0x%x\n", isr, ec->ec_mode); printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port); @@ -250,7 +225,7 @@ static void do_other(const message *m_ptr, int ipc_status) /*===========================================================================* * ec_confaddr * *===========================================================================*/ -static void ec_confaddr(ether_addr_t *addr) +static void ec_confaddr(netdriver_addr_t *addr, unsigned int instance) { int i; char eakey[16]; @@ -259,14 +234,14 @@ static void ec_confaddr(ether_addr_t *addr) /* User defined ethernet address? */ strlcpy(eakey, "LANCE0_EA", sizeof(eakey)); - eakey[5] += ec_instance; + eakey[5] += instance; for (i = 0; i < 6; i++) { - v= addr->ea_addr[i]; + v= addr->na_addr[i]; if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) break; - addr->ea_addr[i]= v; + addr->na_addr[i]= v; } if (i != 0 && i != 6) @@ -279,15 +254,16 @@ static void ec_confaddr(ether_addr_t *addr) /*===========================================================================* * do_init * *===========================================================================*/ -static int do_init(unsigned int instance, ether_addr_t *addr) +static int do_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks __unused) { /* Initialize the lance driver. */ ether_card_t *ec; #if VERBOSE - int i, r; + int i; #endif #if LANCE_FKEY - int fkeys, sfkeys; + int r, fkeys, sfkeys; #endif #if LANCE_FKEY @@ -297,27 +273,24 @@ static int do_init(unsigned int instance, ether_addr_t *addr) printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r); #endif - ec_instance = instance; - /* Initialize the driver state. */ ec= &ec_state; memset(ec, 0, sizeof(*ec)); - strlcpy(ec->port_name, "lance#0", sizeof(ec->port_name)); - ec->port_name[6] += instance; /* See if there is a matching card. */ if (!lance_probe(ec, instance)) return ENXIO; /* Initialize the hardware. */ - lance_init_hw(ec, addr); + lance_init_hw(ec, addr, instance); #if VERBOSE - printf("%s: Ethernet address ", ec->port_name); + printf("%s: Ethernet address ", netdriver_name()); for (i= 0; i < 6; i++) - printf("%x%c", addr->ea_addr[i], i < 5 ? ':' : '\n'); + printf("%x%c", addr->na_addr[i], i < 5 ? ':' : '\n'); #endif + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; return OK; } @@ -349,13 +322,14 @@ static void ec_reinit(ether_card_t *ec) } /* Set 'Receive Mode' */ - if (ec->flags & ECF_PROMISC) + if (ec->ec_mode & NDEV_MODE_PROMISC) { write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM); } else { - if (ec->flags & (ECF_BROAD | ECF_MULTI)) + if (ec->ec_mode & + (NDEV_MODE_BCAST | NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) { write_csr(ioaddr, LANCE_CSR15, 0x0000); } @@ -373,22 +347,17 @@ static void ec_reinit(ether_card_t *ec) } /*===========================================================================* - * do_mode * + * do_set_mode * *===========================================================================*/ -static void do_mode(unsigned int mode) +static void do_set_mode(unsigned int mode, + const netdriver_addr_t *mcast_list __unused, + unsigned int mcast_count __unused) { ether_card_t *ec; ec = &ec_state; - ec->flags &= ~(ECF_PROMISC | ECF_MULTI | ECF_BROAD); - - if (mode & NDEV_PROMISC) - ec->flags |= ECF_PROMISC | ECF_MULTI | ECF_BROAD; - if (mode & NDEV_MULTI) - ec->flags |= ECF_MULTI; - if (mode & NDEV_BROAD) - ec->flags |= ECF_BROAD; + ec->ec_mode = mode; ec_reinit(ec); } @@ -436,7 +405,7 @@ static void do_intr(unsigned int __unused mask) #if VERBOSE printf("RX Missed Frame\n"); #endif - ec->eth_stat.ets_recvErr++; + netdriver_stat_ierror(1); } if ((isr & LANCE_CSR0_BABL) || (isr & LANCE_CSR0_TINT)) { @@ -445,7 +414,7 @@ static void do_intr(unsigned int __unused mask) #if VERBOSE printf("TX Timeout\n"); #endif - ec->eth_stat.ets_sendErr++; + netdriver_stat_oerror(1); } if (isr & LANCE_CSR0_TINT) { @@ -459,24 +428,16 @@ static void do_intr(unsigned int __unused mask) if (status & 0x40000000) { status = lp->tx_ring[cur_tx_slot_nr].misc; - ec->eth_stat.ets_sendErr++; - if (status & 0x0400) /* RTRY */ - ec->eth_stat.ets_transAb++; - if (status & 0x0800) /* LCAR */ - ec->eth_stat.ets_carrSense++; - if (status & 0x1000) /* LCOL */ - ec->eth_stat.ets_OWC++; + netdriver_stat_oerror(1); if (status & 0x4000) /* UFLO */ { - ec->eth_stat.ets_fifoUnder++; must_restart=1; } } else { if (status & 0x18000000) - ec->eth_stat.ets_collision++; - ec->eth_stat.ets_packetT++; + netdriver_stat_coll(1); } } /* transmit a packet on the next slot if it exists. */ @@ -597,20 +558,11 @@ static ssize_t do_recv(struct netdriver_data *data, size_t max) if (status != 0x03) { if (status & 0x01) - ec->eth_stat.ets_recvErr++; - if (status & 0x04) - ec->eth_stat.ets_fifoOver++; - if (status & 0x08) - ec->eth_stat.ets_CRCerr++; - if (status & 0x10) - ec->eth_stat.ets_OVW++; - if (status & 0x20) - ec->eth_stat.ets_frameAll++; + netdriver_stat_ierror(1); length = 0; } else { - ec->eth_stat.ets_packetR++; length = lp->rx_ring[rx_slot_nr].msg_length; } @@ -677,15 +629,6 @@ static int do_send(struct netdriver_data *data, size_t size) return OK; } -/*===========================================================================* - * do_stat * - *===========================================================================*/ -static void do_stat(eth_stat_t *stat) -{ - - memcpy(stat, &ec_state.eth_stat, sizeof(*stat)); -} - /*===========================================================================* * do_stop * *===========================================================================*/ @@ -799,7 +742,7 @@ static int lance_probe(ether_card_t *ec, unsigned int skip) #if VERBOSE printf("%s: %s at %X:%d\n", - ec->port_name, chip_table[lance_version].name, + netdriver_name(), chip_table[lance_version].name, ec->ec_port, ec->ec_irq); #endif @@ -823,7 +766,8 @@ static phys_bytes virt_to_bus(void *ptr) /*===========================================================================* * lance_init_hw * *===========================================================================*/ -static void lance_init_hw(ether_card_t *ec, ether_addr_t *addr) +static void lance_init_hw(ether_card_t *ec, netdriver_addr_t *addr, + unsigned int instance) { phys_bytes lance_buf_phys; int i, r; @@ -859,10 +803,10 @@ static void lance_init_hw(ether_card_t *ec, ether_addr_t *addr) /* ============= Get MAC address (cf. lance_probe1) ================ */ for (i = 0; i < 6; ++i) - addr->ea_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i); + addr->na_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i); /* Allow the user to override the hardware address. */ - ec_confaddr(addr); + ec_confaddr(addr, instance); /* ============ (re)start init_block(cf. lance_reset) =============== */ /* Reset the LANCE */ @@ -871,7 +815,7 @@ static void lance_init_hw(ether_card_t *ec, ether_addr_t *addr) /* ----- Re-initialize the LANCE ----- */ /* Set station address */ for (i = 0; i < 6; ++i) - lp->init_block.phys_addr[i] = addr->ea_addr[i]; + lp->init_block.phys_addr[i] = addr->na_addr[i]; /* Preset the receive ring headers */ for (i=0; iflags & ECF_PROMISC) + if (ec->ec_mode & NDEV_MODE_PROMISC) { write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM); } else { - if (ec->flags & (ECF_BROAD | ECF_MULTI)) + if (ec->ec_mode & + (NDEV_MODE_BCAST | NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) { write_csr(ioaddr, LANCE_CSR15, 0x0000); } diff --git a/minix/drivers/net/lance/lance.h b/minix/drivers/net/lance/lance.h index 5a1b3e5dc..87227a8b7 100644 --- a/minix/drivers/net/lance/lance.h +++ b/minix/drivers/net/lance/lance.h @@ -1,18 +1,8 @@ -/* macros for 'flags' */ -#define ECF_PROMISC 0x01 -#define ECF_MULTI 0x02 -#define ECF_BROAD 0x04 - /* ====== ethernet card info. ====== */ typedef struct ether_card { - /* ####### MINIX style ####### */ - char port_name[sizeof("lance#n")]; - int flags; - eth_stat_t eth_stat; - - /* ######## device info. ####### */ + unsigned int ec_mode; port_t ec_port; int ec_irq; int ec_hook; diff --git a/minix/drivers/net/rtl8139/Makefile b/minix/drivers/net/rtl8139/Makefile index 0a3b4096b..dfba27e70 100644 --- a/minix/drivers/net/rtl8139/Makefile +++ b/minix/drivers/net/rtl8139/Makefile @@ -11,4 +11,6 @@ LDADD+= -lnetdriver -lsys CPPFLAGS+= -I${NETBSDSRCDIR}/minix +WARNS?= 5 + .include diff --git a/minix/drivers/net/rtl8139/rtl8139.c b/minix/drivers/net/rtl8139/rtl8139.c index 2a259e42a..1aedde499 100644 --- a/minix/drivers/net/rtl8139/rtl8139.c +++ b/minix/drivers/net/rtl8139/rtl8139.c @@ -18,8 +18,6 @@ static re_t re_state; -static int re_instance; - static unsigned my_inb(u16_t port) { u32_t value; int s; @@ -64,46 +62,53 @@ static void my_outl(u16_t port, u32_t value) { #define rl_outw(port, offset, value) (my_outw((port) + (offset), (value))) #define rl_outl(port, offset, value) (my_outl((port) + (offset), (value))) -static int rl_init(unsigned int instance, ether_addr_t *addr); +static int rl_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks); 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, ether_addr_t *addr); +static void rl_init_hw(re_t *rep, netdriver_addr_t *addr, + unsigned int instance); static void rl_reset_hw(re_t *rep); -static void rl_confaddr(re_t *rep, ether_addr_t *addr); +static void rl_set_hwaddr(const netdriver_addr_t *addr); +static void rl_confaddr(re_t *rep, netdriver_addr_t *addr, + unsigned int instance); static void rl_stop(void); static void rl_rec_mode(re_t *rep); -static void rl_mode(unsigned int mode); +static void rl_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, + unsigned int mcast_count); static ssize_t rl_recv(struct netdriver_data *data, size_t max); static int rl_send(struct netdriver_data *data, size_t size); +static unsigned int rl_get_link(uint32_t *media); 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 rl_report_link(re_t *rep); 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_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_alarm(clock_t stamp); +static void rl_tick(void); static void tell_iommu(vir_bytes start, size_t size, int pci_bus, int pci_dev, int pci_func); static const struct netdriver rl_table = { + .ndr_name = "rl", .ndr_init = rl_init, .ndr_stop = rl_stop, - .ndr_mode = rl_mode, + .ndr_set_mode = rl_set_mode, + .ndr_set_hwaddr = rl_set_hwaddr, .ndr_recv = rl_recv, .ndr_send = rl_send, - .ndr_stat = rl_stat, + .ndr_get_link = rl_get_link, .ndr_intr = rl_intr, - .ndr_alarm = rl_alarm, + .ndr_tick = rl_tick, .ndr_other = rl_other, }; @@ -172,29 +177,7 @@ static void rl_dump(void) rep= &re_state; printf("\n"); - 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("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("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("OWC :%8ld\t", rep->re_stat.ets_OWC); + printf("Realtek RTL 8139 device %s:\n", netdriver_name()); printf("TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", rl_inw(rep->re_base_port, RL_TSAD), @@ -209,9 +192,10 @@ static void rl_dump(void) } /*===========================================================================* - * rl_mode * + * rl_set_mode * *===========================================================================*/ -static void rl_mode(unsigned int mode) +static void rl_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, + unsigned int mcast_count) { re_t *rep; @@ -225,7 +209,8 @@ static void rl_mode(unsigned int mode) /*===========================================================================* * rl_init * *===========================================================================*/ -static int rl_init(unsigned int instance, ether_addr_t *addr) +static int rl_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks) { /* Initialize the rtl8139 driver. */ re_t *rep; @@ -239,10 +224,6 @@ static int rl_init(unsigned int instance, ether_addr_t *addr) 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] += instance; - - re_instance = instance; /* Try to find a matching device. */ if (!rl_probe(rep, instance)) @@ -252,16 +233,13 @@ static int rl_init(unsigned int instance, ether_addr_t *addr) rl_init_buf(rep); /* Initialize the device we found. */ - rl_init_hw(rep, addr); + rl_init_hw(rep, addr, instance); #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); @@ -269,6 +247,8 @@ static int rl_init(unsigned int instance, ether_addr_t *addr) printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r); #endif + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST | NDEV_CAP_HWADDR; + *ticks = sys_hz(); return OK; } @@ -282,7 +262,7 @@ static int rl_probe(re_t *rep, unsigned int skip) u32_t bar; u8_t ilr; #if VERBOSE - char *dname; + const char *dname; #endif pci_init(); @@ -302,7 +282,7 @@ static int rl_probe(re_t *rep, unsigned int skip) dname= pci_dev_name(vid, did); if (!dname) dname= "unknown device"; - printf("%s: ", rep->re_name); + printf("%s: ", netdriver_name()); printf("%s (%x/%x) at %s\n", dname, vid, did, pci_slot_name(devind)); #endif pci_reserve(devind); @@ -323,7 +303,7 @@ static int rl_probe(re_t *rep, unsigned int skip) rep->re_irq= ilr; #if VERBOSE printf("%s: using I/O address 0x%lx, IRQ %d\n", - rep->re_name, (unsigned long)bar, ilr); + netdriver_name(), (unsigned long)bar, ilr); #endif return TRUE; @@ -340,7 +320,7 @@ static void rl_init_buf(re_t *rep) int i, off; /* Allocate receive and transmit buffers */ - tx_bufsize= ETH_MAX_PACK_SIZE_TAGGED; + tx_bufsize= NDEV_ETH_PACKET_MAX_TAGGED; if (tx_bufsize % 4) tx_bufsize += 4-(tx_bufsize % 4); /* Align */ rx_bufsize= RX_BUFSIZE; @@ -378,7 +358,8 @@ static void rl_init_buf(re_t *rep) /*===========================================================================* * rl_init_hw * *===========================================================================*/ -static void rl_init_hw(re_t *rep, ether_addr_t *addr) +static void rl_init_hw(re_t *rep, netdriver_addr_t *addr, + unsigned int instance) { #if VERBOSE int i; @@ -400,22 +381,22 @@ static void rl_init_hw(re_t *rep, ether_addr_t *addr) #if VERBOSE /* stay silent during startup, can always get status later */ if (rep->re_model) { - printf("%s: model %s\n", rep->re_name, rep->re_model); + printf("%s: model %s\n", netdriver_name(), rep->re_model); } else { printf("%s: unknown model 0x%08x\n", - rep->re_name, + netdriver_name(), rl_inl(rep->re_base_port, RL_TCR) & (RL_TCR_HWVER_AM | RL_TCR_HWVER_BM)); } #endif - rl_confaddr(rep, addr); + rl_confaddr(rep, addr, instance); #if VERBOSE - printf("%s: Ethernet address ", rep->re_name); + printf("%s: Ethernet address ", netdriver_name()); for (i= 0; i < 6; i++) - printf("%x%c", addr->ea_addr[i], i < 5 ? ':' : '\n'); + printf("%x%c", addr->na_addr[i], i < 5 ? ':' : '\n'); #endif } @@ -527,52 +508,64 @@ static void rl_reset_hw(re_t *rep) rl_outl(port, RL_TCR, t | RL_TCR_IFG_STD); } +/*===========================================================================* + * rl_set_hwaddr * + *===========================================================================*/ +static void rl_set_hwaddr(const netdriver_addr_t *addr) +{ + re_t *rep; + port_t port; + u32_t w; + int i; + + rep = &re_state; + + port= rep->re_base_port; + rl_outb(port, RL_9346CR, RL_9346CR_EEM_CONFIG); + w= 0; + for (i= 0; i<4; i++) + w |= (addr->na_addr[i] << (i*8)); + rl_outl(port, RL_IDR, w); + w= 0; + for (i= 4; i<6; i++) + w |= (addr->na_addr[i] << ((i-4)*8)); + rl_outl(port, RL_IDR+4, w); + rl_outb(port, RL_9346CR, RL_9346CR_EEM_NORMAL); +} + /*===========================================================================* * rl_confaddr * *===========================================================================*/ -static void rl_confaddr(re_t *rep, ether_addr_t *addr) +static void rl_confaddr(re_t *rep, netdriver_addr_t *addr, + unsigned int instance) { static char eakey[]= RL_ENVVAR "#_EA"; static char eafmt[]= "x:x:x:x:x:x"; - - int i; port_t port; - u32_t w; + int i; long v; /* User defined ethernet address? */ - eakey[sizeof(RL_ENVVAR)-1]= '0' + re_instance; - - port= rep->re_base_port; + eakey[sizeof(RL_ENVVAR)-1]= '0' + instance; for (i= 0; i < 6; i++) { if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) break; - addr->ea_addr[i]= v; + addr->na_addr[i]= v; } if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */ /* Should update ethernet address in hardware */ if (i == 6) - { - port= rep->re_base_port; - rl_outb(port, RL_9346CR, RL_9346CR_EEM_CONFIG); - w= 0; - for (i= 0; i<4; i++) - w |= (addr->ea_addr[i] << (i*8)); - rl_outl(port, RL_IDR, w); - w= 0; - for (i= 4; i<6; i++) - w |= (addr->ea_addr[i] << ((i-4)*8)); - rl_outl(port, RL_IDR+4, w); - rl_outb(port, RL_9346CR, RL_9346CR_EEM_NORMAL); - } + rl_set_hwaddr(addr); /* Get ethernet address */ + port= rep->re_base_port; + for (i= 0; i<6; i++) - addr->ea_addr[i]= rl_inb(port, RL_IDR+i); + addr->na_addr[i]= rl_inb(port, RL_IDR+i); } /*===========================================================================* @@ -586,11 +579,11 @@ static void rl_rec_mode(re_t *rep) 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_mode & NDEV_PROMISC) + if (rep->re_mode & NDEV_MODE_PROMISC) rcr |= RL_RCR_AB | RL_RCR_AM | RL_RCR_AAP; - if (rep->re_mode & NDEV_BROAD) + if (rep->re_mode & NDEV_MODE_BCAST) rcr |= RL_RCR_AB; - if (rep->re_mode & NDEV_MULTI) + if (rep->re_mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) rcr |= RL_RCR_AM; rcr |= RL_RCR_APM; @@ -651,7 +644,7 @@ static ssize_t rl_recv(struct netdriver_data *data, size_t max) panic("received packet not OK"); } totlen= (rxstat >> RL_RXS_LEN_S); - if (totlen < 8 || totlen > 2*ETH_MAX_PACK_SIZE) + if (totlen < 8 || totlen > 2*NDEV_ETH_PACKET_MAX) { /* Someting went wrong */ printf( @@ -675,18 +668,16 @@ static ssize_t rl_recv(struct netdriver_data *data, size_t max) } /* Should subtract the CRC */ - packlen = MIN(totlen - ETH_CRC_SIZE, max); + packlen = MIN(totlen - NDEV_ETH_PACKET_CRC, max); /* Copy out the data. The packet may wrap in the receive buffer. */ o = (d_start+4) % RX_BUFSIZE; - s = MIN(RX_BUFSIZE - o, packlen); + s = MIN(RX_BUFSIZE - o, (int)packlen); netdriver_copyout(data, 0, rep->v_re_rx_buf + o, s); - if (s < packlen) + if (s < (int)packlen) netdriver_copyout(data, s, rep->v_re_rx_buf, packlen - s); - rep->re_stat.ets_packetR++; - /* Avoid overflow in 16-bit computations */ l= d_start; l += totlen+4; @@ -794,10 +785,46 @@ static void rl_check_ints(re_t *rep) if (rep->re_report_link) { rep->re_report_link = FALSE; + netdriver_link(); +#if VERBOSE rl_report_link(rep); +#endif } } +/*===========================================================================* + * rl_get_link * + *===========================================================================*/ +static unsigned int rl_get_link(uint32_t *media) +{ + port_t port; + u8_t msr; + u16_t mii_ctrl; + re_t *rep; + + rep = &re_state; + + port= rep->re_base_port; + msr= rl_inb(port, RL_MSR); + + if (msr & RL_MSR_LINKB) + return NDEV_LINK_DOWN; + + if (msr & RL_MSR_SPEED_10) + *media = IFM_ETHER | IFM_10_T; + else + *media = IFM_ETHER | IFM_100_TX; + + mii_ctrl= rl_inw(port, RL_BMCR); + if (mii_ctrl & MII_CTRL_DM) + *media |= IFM_FDX; + else + *media |= IFM_HDX; + + return NDEV_LINK_UP; +} + +#if VERBOSE /*===========================================================================* * rl_report_link * *===========================================================================*/ @@ -814,7 +841,7 @@ static void rl_report_link(re_t *rep) rep->re_link_up= link_up; if (!link_up) { - printf("%s: link down\n", rep->re_name); + printf("%s: link down\n", netdriver_name()); return; } @@ -827,7 +854,7 @@ static void rl_report_link(re_t *rep) if (mii_ctrl & (MII_CTRL_LB|MII_CTRL_PD|MII_CTRL_ISO)) { - printf("%s: PHY: ", rep->re_name); + printf("%s: PHY: ", netdriver_name()); f= 1; if (mii_ctrl & MII_CTRL_LB) { @@ -851,7 +878,7 @@ static void rl_report_link(re_t *rep) } if (!(mii_ctrl & MII_CTRL_ANE)) { - printf("%s: manual config: ", rep->re_name); + printf("%s: manual config: ", netdriver_name()); switch(mii_ctrl & (MII_CTRL_SP_LSB|MII_CTRL_SP_MSB)) { case MII_CTRL_SP_10: printf("10 Mbps"); break; @@ -868,57 +895,58 @@ static void rl_report_link(re_t *rep) } #if VERBOSE - printf("%s: ", rep->re_name); + printf("%s: ", netdriver_name()); mii_print_stat_speed(mii_status, mii_extstat); printf("\n"); if (!(mii_status & MII_STATUS_ANC)) - printf("%s: auto-negotiation not complete\n", rep->re_name); + printf("%s: auto-negotiation not complete\n", + netdriver_name()); if (mii_status & MII_STATUS_RF) - printf("%s: remote fault detected\n", rep->re_name); + printf("%s: remote fault detected\n", netdriver_name()); if (!(mii_status & MII_STATUS_ANA)) { printf("%s: local PHY has no auto-negotiation ability\n", - rep->re_name); + netdriver_name()); } if (!(mii_status & MII_STATUS_LS)) - printf("%s: link down\n", rep->re_name); + printf("%s: link down\n", netdriver_name()); if (mii_status & MII_STATUS_JD) - printf("%s: jabber condition detected\n", rep->re_name); + printf("%s: jabber condition detected\n", + netdriver_name()); if (!(mii_status & MII_STATUS_EC)) { - printf("%s: no extended register set\n", rep->re_name); + printf("%s: no extended register set\n", netdriver_name()); goto resspeed; } if (!(mii_status & MII_STATUS_ANC)) goto resspeed; - printf("%s: local cap.: ", rep->re_name); + printf("%s: local cap.: ", netdriver_name()); mii_print_techab(mii_ana); printf("\n"); if (mii_ane & MII_ANE_PDF) - printf("%s: parallel detection fault\n", rep->re_name); + printf("%s: parallel detection fault\n", netdriver_name()); if (!(mii_ane & MII_ANE_LPANA)) { printf("%s: link-partner does not support auto-negotiation\n", - rep->re_name); + netdriver_name()); goto resspeed; } - printf("%s: remote cap.: ", rep->re_name); + printf("%s: remote cap.: ", netdriver_name()); mii_print_techab(mii_anlpa); printf("\n"); resspeed: #endif - printf("%s: ", rep->re_name); + printf("%s: ", netdriver_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; @@ -1121,7 +1149,7 @@ static void rl_clear_rx(re_t *rep) rl_rec_mode(rep); - rep->re_stat.ets_missedP++; + netdriver_stat_ierror(1); } /*===========================================================================* @@ -1140,14 +1168,6 @@ static void rl_do_reset(re_t *rep) rep->re_send_int= TRUE; } -/*===========================================================================* - * rl_stat * - *===========================================================================*/ -static void rl_stat(eth_stat_t *stat) -{ - memcpy(stat, &re_state.re_stat, sizeof(*stat)); -} - #if 0 /*===========================================================================* * dump_phy * @@ -1265,8 +1285,6 @@ static int rl_handler(re_t *rep) { isr &= ~RL_IMR_FOVW; /* Should do anything? */ - - rep->re_stat.ets_fifoOver++; } if (isr & RL_IMR_PUN) { @@ -1331,7 +1349,8 @@ static int rl_handler(re_t *rep) /* Aborted transmission, just kick the device * and be done with it. */ - rep->re_stat.ets_transAb++; + netdriver_stat_oerror(1); + tcr= rl_inl(port, RL_TCR); rl_outl(port, RL_TCR, tcr | RL_TCR_CLRABT); } @@ -1341,6 +1360,8 @@ static int rl_handler(re_t *rep) tx_tail= rep->re_tx_tail; for (i= 0; i< 2*N_TX_BUF; i++) { + if (rep->re_tx_busy == 0) + break; if (!rep->re_tx[tx_tail].ret_busy) { /* Strange, this buffer is not in-use. @@ -1357,40 +1378,29 @@ static int rl_handler(re_t *rep) continue; } tsd= rl_inl(port, RL_TSD0+tx_tail*4); - if (!(tsd & RL_TSD_OWN)) + if (!(tsd & (RL_TSD_TABT | RL_TSD_TOK | RL_TSD_TUN))) { /* Buffer is not yet ready */ break; } /* Should collect statistics */ - if (tsd & RL_TSD_CRS) - rep->re_stat.ets_carrSense++; if (tsd & RL_TSD_TABT) { printf("rl_handler, TABT, TSD%d = 0x%04x\n", tx_tail, tsd); - assert(0); /* CLRABT is not all that - * effective, why not? - */ - rep->re_stat.ets_transAb++; + panic("TX abort"); /* CLRABT is not all that + * that effective, why not? + */ tcr= rl_inl(port, RL_TCR); rl_outl(port, RL_TCR, tcr | RL_TCR_CLRABT); } - if (tsd & RL_TSD_OWC) - rep->re_stat.ets_OWC++; - if (tsd & RL_TSD_CDH) - rep->re_stat.ets_CDheartbeat++; /* What about collisions? */ - if (tsd & RL_TSD_TOK) - rep->re_stat.ets_packetT++; - else - rep->re_stat.ets_sendErr++; + if (!(tsd & RL_TSD_TOK)) + netdriver_stat_oerror(1); if (tsd & RL_TSD_TUN) { - rep->re_stat.ets_fifoUnder++; - /* Increase ERTXTH */ ertxth= tsd + (1 << RL_TSD_ERTXTH_S); ertxth &= RL_TSD_ERTXTH_M; @@ -1398,7 +1408,7 @@ static int rl_handler(re_t *rep) if (ertxth > rep->re_ertxth) { printf("%s: new ertxth: %d bytes\n", - rep->re_name, + netdriver_name(), (ertxth >> RL_TSD_ERTXTH_S) * 32); rep->re_ertxth= ertxth; @@ -1438,15 +1448,12 @@ static int rl_handler(re_t *rep) } /*===========================================================================* - * rl_alarm * + * rl_tick * *===========================================================================*/ -static void rl_alarm(clock_t __unused stamp) +static void rl_tick(void) { re_t *rep; - /* Use a synchronous alarm instead of a watchdog timer. */ - sys_setalarm(sys_hz(), 0); - rep= &re_state; assert(rep->re_tx_busy >= 0 && rep->re_tx_busy <= N_TX_BUF); @@ -1461,7 +1468,7 @@ static void rl_alarm(clock_t __unused stamp) rep->re_tx_alive= FALSE; return; } - printf("rl_alarm: resetting instance %d\n", re_instance); + printf("%s: TX timeout, resetting\n", netdriver_name()); 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), diff --git a/minix/drivers/net/rtl8139/rtl8139.h b/minix/drivers/net/rtl8139/rtl8139.h index 19b995287..0f6372e94 100644 --- a/minix/drivers/net/rtl8139/rtl8139.h +++ b/minix/drivers/net/rtl8139/rtl8139.h @@ -470,8 +470,6 @@ typedef struct re u32_t re_ertxth; /* Early Tx Threshold */ int re_hook_id; /* IRQ hook id at kernel */ - eth_stat_t re_stat; - char re_name[sizeof("rtl8139#n")]; } re_t; /* diff --git a/minix/drivers/net/rtl8169/Makefile b/minix/drivers/net/rtl8169/Makefile index 9650f69aa..d4861ac10 100644 --- a/minix/drivers/net/rtl8169/Makefile +++ b/minix/drivers/net/rtl8169/Makefile @@ -11,4 +11,6 @@ LDADD+= -lnetdriver -lsys CPPFLAGS+= -I${NETBSDSRCDIR}/minix +WARNS?= 5 + .include diff --git a/minix/drivers/net/rtl8169/rtl8169.c b/minix/drivers/net/rtl8169/rtl8169.c index 47c7bcab9..e59e2155b 100644 --- a/minix/drivers/net/rtl8169/rtl8169.c +++ b/minix/drivers/net/rtl8169/rtl8169.c @@ -90,18 +90,14 @@ typedef struct re { int re_tx_busy; /* how many Tx descriptors are busy? */ int re_hook_id; /* IRQ hook id at kernel */ - eth_stat_t re_stat; phys_bytes dtcc_buf; /* Dump Tally Counter buffer physical */ re_dtcc *v_dtcc_buf; /* Dump Tally Counter buffer */ u32_t dtcc_counter; /* DTCC update counter */ - char re_name[sizeof("rtl8169#n")]; u32_t interrupts; } re_t; static re_t re_state; -static int re_instance; - static unsigned my_inb(u16_t port) { u32_t value; @@ -155,37 +151,44 @@ static void my_outl(u16_t port, u32_t value) #define rl_outw(port, offset, value) (my_outw((port) + (offset), (value))) #define rl_outl(port, offset, value) (my_outl((port) + (offset), (value))) -static int rl_init(unsigned int instance, ether_addr_t *addr); +static int rl_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks); 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, ether_addr_t *addr); +static void rl_init_hw(re_t *rep, netdriver_addr_t *addr, + unsigned int instance); static void rl_reset_hw(re_t *rep); -static void rl_confaddr(re_t *rep, ether_addr_t *addr); +static void rl_confaddr(re_t *rep, netdriver_addr_t *addr, + unsigned int instance); +static void rl_set_hwaddr(const netdriver_addr_t *addr); static void rl_stop(void); static void rl_rec_mode(re_t *rep); -static void rl_mode(unsigned int mode); +static void rl_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, + unsigned int mcast_count); static ssize_t rl_recv(struct netdriver_data *data, size_t max); static int rl_send(struct netdriver_data *data, size_t size); +static unsigned int rl_get_link(uint32_t *media); static void rl_intr(unsigned int mask); static void rl_check_ints(re_t *rep); static void rl_do_reset(re_t *rep); -static void rl_stat(eth_stat_t *stat); #if VERBOSE static void rl_report_link(re_t *rep); static void dump_phy(const re_t *rep); #endif static void rl_handler(re_t *rep); -static void rl_alarm(clock_t stamp); +static void rl_tick(void); static const struct netdriver rl_table = { + .ndr_name = "re", .ndr_init = rl_init, .ndr_stop = rl_stop, - .ndr_mode = rl_mode, + .ndr_set_mode = rl_set_mode, + .ndr_set_hwaddr = rl_set_hwaddr, .ndr_recv = rl_recv, .ndr_send = rl_send, - .ndr_stat = rl_stat, + .ndr_get_link = rl_get_link, .ndr_intr = rl_intr, - .ndr_alarm = rl_alarm + .ndr_tick = rl_tick }; /*===========================================================================* @@ -203,7 +206,8 @@ int main(int argc, char *argv[]) /*===========================================================================* * rl_init * *===========================================================================*/ -static int rl_init(unsigned int instance, ether_addr_t *addr) +static int rl_init(unsigned int instance, netdriver_addr_t *addr, + uint32_t *caps, unsigned int *ticks) { /* Initialize the rtl8169 driver. */ re_t *rep; @@ -212,11 +216,6 @@ static int rl_init(unsigned int instance, ether_addr_t *addr) rep = &re_state; memset(rep, 0, sizeof(*rep)); - strlcpy(rep->re_name, "rtl8169#0", sizeof(rep->re_name)); - rep->re_name[8] += re_instance; - - re_instance = instance; - /* Try to find a matching device. */ if (!rl_probe(rep, instance)) return ENXIO; @@ -225,11 +224,10 @@ static int rl_init(unsigned int instance, ether_addr_t *addr) rl_init_buf(&re_state); /* Initialize the device we found. */ - rl_init_hw(rep, addr); - - /* Use a synchronous alarm instead of a watchdog timer. */ - sys_setalarm(sys_hz(), 0); + rl_init_hw(rep, addr, instance); + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST | NDEV_CAP_HWADDR; + *ticks = sys_hz(); return OK; } @@ -286,15 +284,13 @@ static int mdio_read(u16_t port, int regaddr) static void rtl8169_update_stat(re_t *rep) { + static u64_t last_miss = 0, last_coll = 0; + u64_t miss, coll; port_t port; int i; port = rep->re_base_port; - /* Fetch Missed Packets */ - rep->re_stat.ets_missedP += rl_inw(port, RL_MPC); - rl_outw(port, RL_MPC, 0x00); - /* Dump Tally Counter Command */ rl_outl(port, RL_DTCCR_HI, 0); /* 64 bits */ rl_outl(port, RL_DTCCR_LO, rep->dtcc_buf | RL_DTCCR_CMD); @@ -305,11 +301,13 @@ static void rtl8169_update_stat(re_t *rep) } /* Update counters */ - rep->re_stat.ets_frameAll = rep->v_dtcc_buf->FAE; - rep->re_stat.ets_transDef = rep->v_dtcc_buf->TxUndrn; - rep->re_stat.ets_transAb = rep->v_dtcc_buf->TxAbt; - rep->re_stat.ets_collision = - rep->v_dtcc_buf->Tx1Col + rep->v_dtcc_buf->TxMCol; + miss = rep->v_dtcc_buf->MissPkt; + netdriver_stat_ierror(miss - last_miss); + last_miss = miss; + + coll = rep->v_dtcc_buf->Tx1Col + rep->v_dtcc_buf->TxMCol; + netdriver_stat_coll(coll - last_coll); + last_coll = coll; } #if 0 @@ -327,27 +325,8 @@ static void rtl8169_dump(void) rtl8169_update_stat(rep); - printf("Realtek RTL 8169 statistics of instance %d:\n", re_instance); + printf("Realtek RTL 8169 driver %s:\n", netdriver_name()); - 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("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("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 :%8u\n", rep->interrupts); printf("\nRealtek RTL 8169 Tally Counters:\n"); @@ -400,9 +379,11 @@ static void rtl8169_dump(void) #endif /*===========================================================================* - * rl_mode * + * rl_set_mode * *===========================================================================*/ -static void rl_mode(unsigned int mode) +static void rl_set_mode(unsigned int mode, + const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) { re_t *rep; @@ -423,7 +404,7 @@ static int rl_probe(re_t *rep, unsigned int skip) u32_t bar; u8_t ilr; #if VERBOSE - char *dname; + const char *dname; #endif pci_init(); @@ -442,7 +423,7 @@ static int rl_probe(re_t *rep, unsigned int skip) dname = pci_dev_name(vid, did); if (!dname) dname = "unknown device"; - printf("%s: ", rep->re_name); + printf("%s: ", netdriver_name()); printf("%s (%x/%x) at %s\n", dname, vid, did, pci_slot_name(devind)); #endif @@ -457,7 +438,7 @@ static int rl_probe(re_t *rep, unsigned int skip) rep->re_irq = ilr; #if VERBOSE printf("%s: using I/O address 0x%lx, IRQ %d\n", - rep->re_name, (unsigned long)bar, ilr); + netdriver_name(), (unsigned long)bar, ilr); #endif return TRUE; @@ -479,7 +460,7 @@ static void rl_init_buf(re_t *rep) tx_descsize = (N_TX_DESC * sizeof(struct re_desc)); /* Allocate receive and transmit buffers */ - tx_bufsize = ETH_MAX_PACK_SIZE_TAGGED; + tx_bufsize = NDEV_ETH_PACKET_MAX_TAGGED; if (tx_bufsize % 4) tx_bufsize += 4-(tx_bufsize % 4); /* Align */ rx_bufsize = RX_BUFSIZE; @@ -548,7 +529,8 @@ static void rl_init_buf(re_t *rep) /*===========================================================================* * rl_init_hw * *===========================================================================*/ -static void rl_init_hw(re_t *rep, ether_addr_t *addr) +static void rl_init_hw(re_t *rep, netdriver_addr_t *addr, + unsigned int instance) { int s; #if VERBOSE @@ -571,15 +553,15 @@ static void rl_init_hw(re_t *rep, ether_addr_t *addr) #if VERBOSE printf("%s: model: %s mac: 0x%08x\n", - rep->re_name, rep->re_model, rep->re_mac); + netdriver_name(), rep->re_model, rep->re_mac); #endif - rl_confaddr(rep, addr); + rl_confaddr(rep, addr, instance); #if VERBOSE - printf("%s: Ethernet address ", rep->re_name); + printf("%s: Ethernet address ", netdriver_name()); for (i = 0; i < 6; i++) { - printf("%x%c", addr->ea_addr[i], + printf("%x%c", addr->na_addr[i], i < 5 ? ':' : '\n'); } #endif @@ -828,47 +810,61 @@ static void rl_reset_hw(re_t *rep) /*===========================================================================* * rl_confaddr * *===========================================================================*/ -static void rl_confaddr(re_t *rep, ether_addr_t *addr) +static void rl_confaddr(re_t *rep, netdriver_addr_t *addr, + unsigned int instance) { static char eakey[] = RL_ENVVAR "#_EA"; static char eafmt[] = "x:x:x:x:x:x"; int i; port_t port; - u32_t w; long v; /* User defined ethernet address? */ - eakey[sizeof(RL_ENVVAR)-1] = '0' + re_instance; + eakey[sizeof(RL_ENVVAR)-1] = '0' + instance; port = rep->re_base_port; for (i = 0; i < 6; i++) { if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) break; - addr->ea_addr[i] = v; + addr->na_addr[i] = v; } if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */ /* Should update ethernet address in hardware */ - if (i == 6) { - port = rep->re_base_port; - rl_outb(port, RL_9346CR, RL_9346CR_EEM_CONFIG); - w = 0; - for (i = 0; i < 4; i++) - w |= (addr->ea_addr[i] << (i * 8)); - rl_outl(port, RL_IDR, w); - w = 0; - for (i = 4; i < 6; i++) - w |= (addr->ea_addr[i] << ((i-4) * 8)); - rl_outl(port, RL_IDR + 4, w); - rl_outb(port, RL_9346CR, RL_9346CR_EEM_NORMAL); - } + if (i == 6) + rl_set_hwaddr(addr); /* Get ethernet address */ for (i = 0; i < 6; i++) - addr->ea_addr[i] = rl_inb(port, RL_IDR+i); + addr->na_addr[i] = rl_inb(port, RL_IDR+i); +} + +/*===========================================================================* + * rl_set_hwaddr * + *===========================================================================*/ +static void rl_set_hwaddr(const netdriver_addr_t *addr) +{ + re_t *rep; + port_t port; + u32_t w; + int i; + + rep = &re_state; + + port = rep->re_base_port; + rl_outb(port, RL_9346CR, RL_9346CR_EEM_CONFIG); + w = 0; + for (i = 0; i < 4; i++) + w |= (addr->na_addr[i] << (i * 8)); + rl_outl(port, RL_IDR, w); + w = 0; + for (i = 4; i < 6; i++) + w |= (addr->na_addr[i] << ((i-4) * 8)); + rl_outl(port, RL_IDR + 4, w); + rl_outb(port, RL_9346CR, RL_9346CR_EEM_NORMAL); } /*===========================================================================* @@ -888,11 +884,11 @@ static void rl_rec_mode(re_t *rep) rcr = rl_inl(port, RL_RCR); rcr &= ~(RL_RCR_AB | RL_RCR_AM | RL_RCR_APM | RL_RCR_AAP); - if (rep->re_mode & NDEV_PROMISC) + if (rep->re_mode & NDEV_MODE_PROMISC) rcr |= RL_RCR_AB | RL_RCR_AM | RL_RCR_AAP; - if (rep->re_mode & NDEV_BROAD) + if (rep->re_mode & NDEV_MODE_BCAST) rcr |= RL_RCR_AB; - if (rep->re_mode & NDEV_MULTI) + if (rep->re_mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) rcr |= RL_RCR_AM; rcr |= RL_RCR_APM; rl_outl(port, RL_RCR, RL_RCR_RXFTH_UNLIM | RL_RCR_MXDMA_1024 | rcr); @@ -928,7 +924,7 @@ static ssize_t rl_recv(struct netdriver_data *data, size_t max) return SUSPEND; if (rxstat & DESC_RX_CRC) - rep->re_stat.ets_CRCerr++; + netdriver_stat_ierror(1); if ((rxstat & (DESC_FS | DESC_LS)) == (DESC_FS | DESC_LS)) break; @@ -952,7 +948,7 @@ static ssize_t rl_recv(struct netdriver_data *data, size_t max) } totlen = rxstat & DESC_RX_LENMASK; - if (totlen < 8 || totlen > 2 * ETH_MAX_PACK_SIZE) { + if (totlen < 8 || totlen > 2 * NDEV_ETH_PACKET_MAX) { /* Someting went wrong */ printf("rl_recv: bad length (%u) in status 0x%08x\n", totlen, rxstat); @@ -960,14 +956,12 @@ static ssize_t rl_recv(struct netdriver_data *data, size_t max) } /* Should subtract the CRC */ - packlen = totlen - ETH_CRC_SIZE; + packlen = totlen - NDEV_ETH_PACKET_CRC; if (packlen > max) packlen = max; netdriver_copyout(data, 0, rep->re_rx[index].v_ret_buf, packlen); - rep->re_stat.ets_packetR++; - if (index == N_RX_DESC - 1) { desc->status = DESC_EOR | DESC_OWN | (RX_BUFSIZE & DESC_RX_LENMASK); @@ -1049,12 +1043,44 @@ static void rl_check_ints(re_t *rep) if (rep->re_report_link) { rep->re_report_link = FALSE; + netdriver_link(); + #if VERBOSE rl_report_link(rep); #endif } } +/*===========================================================================* + * rl_get_link * + *===========================================================================*/ +static unsigned int rl_get_link(uint32_t *media) +{ + re_t *rep; + u8_t mii_status; + + rep = &re_state; + + mii_status = rl_inb(rep->re_base_port, RL_PHYSTAT); + + if (!(mii_status & RL_STAT_LINK)) + return NDEV_LINK_DOWN; + + if (mii_status & RL_STAT_1000) + *media = IFM_ETHER | IFM_1000_T; + else if (mii_status & RL_STAT_100) + *media = IFM_ETHER | IFM_100_TX; + else if (mii_status & RL_STAT_10) + *media = IFM_ETHER | IFM_10_T; + + if (mii_status & RL_STAT_FULLDUP) + *media |= IFM_FDX; + else + *media |= IFM_HDX; + + return NDEV_LINK_UP; +} + /*===========================================================================* * rl_report_link * *===========================================================================*/ @@ -1070,10 +1096,10 @@ static void rl_report_link(re_t *rep) if (mii_status & RL_STAT_LINK) { rep->re_link_up = 1; - printf("%s: link up at ", rep->re_name); + printf("%s: link up at ", netdriver_name()); } else { rep->re_link_up = 0; - printf("%s: link down\n", rep->re_name); + printf("%s: link down\n", netdriver_name()); return; } @@ -1110,14 +1136,6 @@ static void rl_do_reset(re_t *rep) rep->re_send_int = TRUE; } -/*===========================================================================* - * rl_stat * - *===========================================================================*/ -static void rl_stat(eth_stat_t *stat) -{ - memcpy(stat, &re_state.re_stat, sizeof(*stat)); -} - #if VERBOSE static void dump_phy(const re_t *rep) { @@ -1341,8 +1359,6 @@ static void rl_handler(re_t *rep) if (isr & RL_IMR_FOVW) { isr &= ~RL_IMR_FOVW; /* Should do anything? */ - - rep->re_stat.ets_fifoOver++; } if (isr & RL_IMR_PUN) { isr &= ~RL_IMR_PUN; @@ -1360,7 +1376,7 @@ static void rl_handler(re_t *rep) if (isr & (RL_ISR_RDU | RL_ISR_RER | RL_ISR_ROK)) { if (isr & RL_ISR_RER) - rep->re_stat.ets_recvErr++; + netdriver_stat_ierror(1); isr &= ~(RL_ISR_RDU | RL_ISR_RER | RL_ISR_ROK); rep->re_got_int = TRUE; @@ -1368,7 +1384,7 @@ static void rl_handler(re_t *rep) if ((isr & (RL_ISR_TDU | RL_ISR_TER | RL_ISR_TOK)) || 1) { if (isr & RL_ISR_TER) - rep->re_stat.ets_sendErr++; + netdriver_stat_oerror(1); isr &= ~(RL_ISR_TDU | RL_ISR_TER | RL_ISR_TOK); /* Transmit completed */ @@ -1397,7 +1413,6 @@ static void rl_handler(re_t *rep) break; } - rep->re_stat.ets_packetT++; rep->re_tx[tx_tail].ret_busy = FALSE; rep->re_tx_busy--; @@ -1421,15 +1436,12 @@ static void rl_handler(re_t *rep) } /*===========================================================================* - * rl_alarm * + * rl_tick * *===========================================================================*/ -static void rl_alarm(clock_t __unused stamp) +static void rl_tick(void) { re_t *rep; - /* Use a synchronous alarm instead of a watchdog timer. */ - sys_setalarm(sys_hz(), 0); - rep = &re_state; /* Should collect statistics */ @@ -1446,7 +1458,7 @@ static void rl_alarm(clock_t __unused stamp) rep->re_tx_alive = FALSE; return; } - printf("rl_alarm: resetting instance %d\n", re_instance); + printf("%s: TX timeout, resetting\n", netdriver_name()); 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; diff --git a/minix/drivers/net/virtio_net/Makefile b/minix/drivers/net/virtio_net/Makefile index 990112540..b718ac40d 100644 --- a/minix/drivers/net/virtio_net/Makefile +++ b/minix/drivers/net/virtio_net/Makefile @@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBVIRTIO} LDADD+= -lnetdriver -lsys -lvirtio +WARNS?= 5 + .include diff --git a/minix/drivers/net/virtio_net/virtio_net.c b/minix/drivers/net/virtio_net/virtio_net.c index 9ba7313a4..5f2dd679e 100644 --- a/minix/drivers/net/virtio_net/virtio_net.c +++ b/minix/drivers/net/virtio_net/virtio_net.c @@ -10,12 +10,8 @@ #include #include -#include -#include - #include #include -#include #include #include @@ -27,7 +23,7 @@ #if VERBOSE #define dput(s) do { dprintf(s); printf("\n"); } while (0) #define dprintf(s) do { \ - printf("%s: ", name); \ + printf("%s: ", netdriver_name()); \ printf s; \ } while (0) #else @@ -37,8 +33,6 @@ static struct virtio_device *net_dev; -static const char *const name = "virtio-net"; - enum queue {RX_Q, TX_Q, CTRL_Q}; /* Number of packets to work with */ @@ -47,7 +41,7 @@ enum queue {RX_Q, TX_Q, CTRL_Q}; */ #define BUF_PACKETS 64 /* Maximum size of a packet */ -#define MAX_PACK_SIZE ETH_MAX_PACK_SIZE +#define MAX_PACK_SIZE NDEV_ETH_PACKET_MAX /* Buffer size needed for the payload of BUF_PACKETS */ #define PACKET_BUF_SZ (BUF_PACKETS * MAX_PACK_SIZE) @@ -76,12 +70,11 @@ static STAILQ_HEAD(free_list, packet) free_list; static STAILQ_HEAD(recv_list, packet) recv_list; /* Various state data */ -static eth_stat_t virtio_net_stats; static int spurious_interrupt; /* Prototypes */ static int virtio_net_probe(unsigned int skip); -static void virtio_net_config(ether_addr_t *addr); +static void virtio_net_config(netdriver_addr_t *addr); static int virtio_net_alloc_bufs(void); static void virtio_net_init_queues(void); @@ -89,19 +82,19 @@ static void virtio_net_refill_rx_queue(void); static void virtio_net_check_queues(void); static void virtio_net_check_pending(void); -static int virtio_net_init(unsigned int instance, ether_addr_t *addr); +static int virtio_net_init(unsigned int instance, netdriver_addr_t * addr, + uint32_t * caps, unsigned int * ticks); static void virtio_net_stop(void); static int virtio_net_send(struct netdriver_data *data, size_t len); static ssize_t virtio_net_recv(struct netdriver_data *data, size_t max); -static void virtio_net_stat(eth_stat_t *stat); static void virtio_net_intr(unsigned int mask); static const struct netdriver virtio_net_table = { + .ndr_name = "vio", .ndr_init = virtio_net_init, .ndr_stop = virtio_net_stop, .ndr_recv = virtio_net_recv, .ndr_send = virtio_net_send, - .ndr_stat = virtio_net_stat, .ndr_intr = virtio_net_intr, }; @@ -119,7 +112,7 @@ virtio_net_probe(unsigned int skip) { /* virtio-net has at least 2 queues */ int queues = 2; - net_dev= virtio_setup_device(0x00001, name, netf, + net_dev= virtio_setup_device(0x00001, netdriver_name(), netf, sizeof(netf) / sizeof(netf[0]), 1 /* threads */, skip); if (net_dev == NULL) @@ -138,7 +131,7 @@ virtio_net_probe(unsigned int skip) } static void -virtio_net_config(ether_addr_t * addr) +virtio_net_config(netdriver_addr_t * addr) { u32_t mac14; u32_t mac56; @@ -148,11 +141,11 @@ virtio_net_config(ether_addr_t * addr) dprintf(("Mac set by host: ")); mac14 = virtio_sread32(net_dev, 0); mac56 = virtio_sread32(net_dev, 4); - memcpy(&addr->ea_addr[0], &mac14, 4); - memcpy(&addr->ea_addr[4], &mac56, 2); + memcpy(&addr->na_addr[0], &mac14, 4); + memcpy(&addr->na_addr[4], &mac56, 2); for (i = 0; i < 6; i++) - dprintf(("%02x%s", addr->ea_addr[i], + dprintf(("%02x%s", addr->na_addr[i], i == 5 ? "\n" : ":")); } else { dput(("No mac")); @@ -247,10 +240,8 @@ virtio_net_refill_rx_queue(void) in_rx++; } - if (in_rx == 0 && STAILQ_EMPTY(&free_list)) { + if (in_rx == 0 && STAILQ_EMPTY(&free_list)) dput(("warning: rx queue underflow!")); - virtio_net_stats.ets_fifoUnder++; - } } static void @@ -264,7 +255,6 @@ virtio_net_check_queues(void) p->len = len; STAILQ_INSERT_TAIL(&recv_list, p, next); in_rx--; - virtio_net_stats.ets_packetR++; } /* @@ -275,7 +265,6 @@ virtio_net_check_queues(void) memset(p->vhdr, 0, sizeof(*p->vhdr)); memset(p->vdata, 0, MAX_PACK_SIZE); STAILQ_INSERT_HEAD(&free_list, p, next); - virtio_net_stats.ets_packetT++; } } @@ -330,7 +319,8 @@ virtio_net_send(struct netdriver_data * data, size_t len) STAILQ_REMOVE_HEAD(&free_list, next); if (len > MAX_PACK_SIZE) - panic("%s: packet too large to send: %zu", name, len); + panic("%s: packet too large to send: %zu", + netdriver_name(), len); netdriver_copyin(data, 0, p->vdata, len); @@ -363,18 +353,21 @@ virtio_net_recv(struct netdriver_data * data, size_t max) STAILQ_REMOVE_HEAD(&recv_list, next); /* Copy out the packet contents. */ + if (p->len < sizeof(struct virtio_net_hdr)) + panic("received packet does not have virtio header"); len = p->len - sizeof(struct virtio_net_hdr); - if (len > max) - len = max; + if ((size_t)len > max) + len = (ssize_t)max; /* * HACK: due to lack of padding, received packets may in fact be - * smaller than the minimum ethernet packet size. Inet will accept the - * packets just fine if we increase the length to its minimum. We - * already zeroed out the rest of the packet data, so this is safe. + * smaller than the minimum ethernet packet size. The TCP/IP service + * will accept the packets just fine if we increase the length to its + * minimum. We already zeroed out the rest of the packet data, so this + * is safe. */ - if (len < ETH_MIN_PACK_SIZE) - len = ETH_MIN_PACK_SIZE; + if (len < NDEV_ETH_PACKET_MIN) + len = NDEV_ETH_PACKET_MIN; netdriver_copyout(data, 0, p->vdata, len); @@ -389,21 +382,12 @@ virtio_net_recv(struct netdriver_data * data, size_t max) return len; } -/* - * Return statistics. - */ -static void -virtio_net_stat(eth_stat_t *stat) -{ - - memcpy(stat, &virtio_net_stats, sizeof(*stat)); -} - /* * Initialize the driver and the virtual hardware. */ static int -virtio_net_init(unsigned int instance, ether_addr_t *addr) +virtio_net_init(unsigned int instance, netdriver_addr_t * addr, + uint32_t * caps, unsigned int * ticks __unused) { int r; @@ -413,7 +397,7 @@ virtio_net_init(unsigned int instance, ether_addr_t *addr) virtio_net_config(addr); if (virtio_net_alloc_bufs() != OK) - panic("%s: Buffer allocation failed", name); + panic("%s: Buffer allocation failed", netdriver_name()); virtio_net_init_queues(); @@ -424,7 +408,8 @@ virtio_net_init(unsigned int instance, ether_addr_t *addr) virtio_irq_enable(net_dev); - return(OK); + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; + return OK; } /* diff --git a/minix/drivers/net/vt6105/vt6105.c b/minix/drivers/net/vt6105/vt6105.c index 92b89d0cf..58e97c279 100644 --- a/minix/drivers/net/vt6105/vt6105.c +++ b/minix/drivers/net/vt6105/vt6105.c @@ -10,20 +10,21 @@ static NDR_driver g_driver; static int g_instance; /* driver interface */ -static int NDR_init(unsigned int instance, ether_addr_t *addr); +static int NDR_init(unsigned int instance, netdriver_addr_t * addr, + uint32_t * caps, unsigned int * ticks); static void NDR_stop(void); -static void NDR_mode(unsigned int mode); +static void NDR_set_mode(unsigned int mode, + const netdriver_addr_t * mcast_list, unsigned int mcast_count); static ssize_t NDR_recv(struct netdriver_data *data, size_t max); static int NDR_send(struct netdriver_data *data, size_t size); static void NDR_intr(unsigned int mask); -static void NDR_stat(eth_stat_t *stat); /* internal function */ static int dev_probe(NDR_driver *pdev, int instance); static int dev_init_buf(NDR_driver *pdev); -static int dev_init_hw(NDR_driver *pdev, ether_addr_t *addr); +static int dev_init_hw(NDR_driver *pdev, netdriver_addr_t *addr); static int dev_reset_hw(NDR_driver *pdev); -static void dev_conf_addr(NDR_driver *pdev, ether_addr_t *addr); +static void dev_conf_addr(NDR_driver *pdev, netdriver_addr_t *addr); static void dev_handler(NDR_driver *pdev); static void dev_check_ints(NDR_driver *pdev); @@ -150,11 +151,11 @@ static void dev_set_rec_mode(u32_t *base, int mode) { u32_t data, base0 = base[0]; data = ndr_in8(base0, REG_RCR); data &= ~(CMD_RCR_UNICAST | CMD_RCR_MULTICAST | CMD_RCR_BROADCAST); - if (mode & NDEV_PROMISC) + if (mode & NDEV_MODE_PROMISC) data |= CMD_RCR_UNICAST | CMD_RCR_BROADCAST | CMD_RCR_MULTICAST; - if (mode & NDEV_BROAD) + if (mode & NDEV_MODE_BCAST) data |= CMD_RCR_BROADCAST; - if (mode & NDEV_MULTI) + if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) data |= CMD_RCR_MULTICAST; data |= CMD_RCR_UNICAST; ndr_out8(base0, REG_RCR, data); @@ -226,8 +227,7 @@ static int dev_rx_ok_desc(u32_t *base, NDR_desc *desc, int index) { * -- Current buffer number is index * -- Return the length */ static int dev_rx_len_desc(u32_t *base, NDR_desc *desc, int index) { - int len = ((desc->status & DESC_RX_LENMASK) >> 16) - ETH_CRC_SIZE; - return len; + return ((desc->status & DESC_RX_LENMASK) >> 16) - NDEV_ETH_PACKET_CRC; } /* Set Rx descriptor after Rx done (### SET_RX_DESC_DONE ###) @@ -264,13 +264,13 @@ static void dev_set_tx_desc_done(u32_t *base, NDR_desc *desc, int index) { /* Driver interface table */ static const struct netdriver NDR_table = { + .ndr_name = "vr", .ndr_init = NDR_init, .ndr_stop = NDR_stop, - .ndr_mode = NDR_mode, + .ndr_set_mode = NDR_set_mode, .ndr_recv = NDR_recv, .ndr_send = NDR_send, .ndr_intr = NDR_intr, - .ndr_stat = NDR_stat }; int main(int argc, char *argv[]) { @@ -279,15 +279,15 @@ int main(int argc, char *argv[]) { } /* Initialize the driver */ -static int NDR_init(unsigned int instance, ether_addr_t *addr) { +static int +NDR_init(unsigned int instance, netdriver_addr_t * addr, uint32_t * caps, + unsigned int * ticks __unused) +{ int i, ret = 0; /* Intialize driver data structure */ memset(&g_driver, 0, sizeof(g_driver)); g_driver.link = LINK_UNKNOWN; - strcpy(g_driver.name, DRIVER_NAME); - strcat(g_driver.name, "#0"); - g_driver.name[strlen(g_driver.name) - 1] += instance; g_instance = instance; /* Probe the device */ @@ -319,14 +319,12 @@ static int NDR_init(unsigned int instance, ether_addr_t *addr) { /* ### RX_TX_ENABLE_DISABLE ### */ dev_rx_tx_control(g_driver.base, RX_TX_ENABLE); - /* Use a synchronous alarm instead of a watchdog timer */ - sys_setalarm(sys_hz(), 0); - /* Clear send and recv flag */ g_driver.send_flag = FALSE; g_driver.recv_flag = FALSE; - return 0; + *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; + return OK; err_init_buf: err_init_hw: @@ -349,7 +347,10 @@ static void NDR_stop(void) { } /* Set driver mode */ -static void NDR_mode(unsigned int mode) { +static void +NDR_set_mode(unsigned int mode, const netdriver_addr_t * mcast_list __unused, + unsigned int mcast_count __unused) +{ g_driver.mode = mode; /* Set driver receive mode */ /* ### SET_REC_MODE ### */ @@ -379,7 +380,7 @@ static ssize_t NDR_recv(struct netdriver_data *data, size_t max) { /* Get data length */ /* ### Get , int inde, int indexxRx data length ### */ - if (totlen < 8 || totlen > 2 * ETH_MAX_PACK_SIZE) { + if (totlen < 8 || totlen > 2 * NDEV_ETH_PACKET_MAX) { printf("NDR: Bad data length: %d\n", totlen); panic(NULL); } @@ -390,7 +391,6 @@ static ssize_t NDR_recv(struct netdriver_data *data, size_t max) { /* Copy data to user */ netdriver_copyout(data, 0, pdev->rx[index].buf + offset, packlen); - pdev->stat.ets_packetR++; /* Set Rx descriptor after Rx done */ /* ### SET_RX_DESC_DONE ### */ @@ -458,11 +458,6 @@ static void NDR_intr(unsigned int mask) { dev_check_ints(&g_driver); } -/* Get driver status */ -static void NDR_stat(eth_stat_t *stat) { - memcpy(stat, &g_driver.stat, sizeof(*stat)); -} - /* Match the device and get base address */ static int dev_probe(NDR_driver *pdev, int instance) { int devind, ioflag, i; @@ -526,7 +521,7 @@ static int dev_probe(NDR_driver *pdev, int instance) { } /* Intialize hardware */ -static int dev_init_hw(NDR_driver *pdev, ether_addr_t *addr) { +static int dev_init_hw(NDR_driver *pdev, netdriver_addr_t *addr) { int r, ret; /* Set the OS interrupt handler */ @@ -609,22 +604,22 @@ err_real_reset: } /* Configure MAC address */ -static void dev_conf_addr(NDR_driver *pdev, ether_addr_t *addr) { +static void dev_conf_addr(NDR_driver *pdev, netdriver_addr_t *addr) { u8_t pa[6]; /* Get MAC address */ /* ### GET_MAC_ADDR ### */ dev_get_addr(pdev->base, pa); - addr->ea_addr[0] = pa[0]; - addr->ea_addr[1] = pa[1]; - addr->ea_addr[2] = pa[2]; - addr->ea_addr[3] = pa[3]; - addr->ea_addr[4] = pa[4]; - addr->ea_addr[5] = pa[5]; + addr->na_addr[0] = pa[0]; + addr->na_addr[1] = pa[1]; + addr->na_addr[2] = pa[2]; + addr->na_addr[3] = pa[3]; + addr->na_addr[4] = pa[4]; + addr->na_addr[5] = pa[5]; #ifdef MY_DEBUG printf("NDR: Ethernet address is %02x:%02x:%02x:%02x:%02x:%02x\n", - addr->ea_addr[0], addr->ea_addr[1], addr->ea_addr[2], - addr->ea_addr[3], addr->ea_addr[4], addr->ea_addr[5]); + addr->na_addr[0], addr->na_addr[1], addr->na_addr[2], + addr->na_addr[3], addr->na_addr[4], addr->na_addr[5]); #endif } @@ -759,7 +754,6 @@ static void dev_handler(NDR_driver *pdev) { else if (ret == TX_ERROR) printf("NDR: Tx error now\n"); - pdev->stat.ets_packetT++; pdev->tx[tx_tail].busy = FALSE; pdev->tx_busy_num--; diff --git a/minix/drivers/net/vt6105/vt6105.h b/minix/drivers/net/vt6105/vt6105.h index c804c4a88..286acdd50 100644 --- a/minix/drivers/net/vt6105/vt6105.h +++ b/minix/drivers/net/vt6105/vt6105.h @@ -133,8 +133,6 @@ typedef struct NDR_driver { phys_bytes tx_desc_dma; /* Tx descriptor DMA buffer */ int hook; /* IRQ hook id at kernel */ - eth_stat_t stat; /* Ethernet status */ - char name[50]; /* Driver name */ } NDR_driver; #endif diff --git a/minix/include/minix/com.h b/minix/include/minix/com.h index f43d01856..0cef8fdef 100644 --- a/minix/include/minix/com.h +++ b/minix/include/minix/com.h @@ -31,6 +31,7 @@ * 0x1700 - 0x17FF PTYFS requests * 0x1800 - 0x18FF Management Information Base (MIB) requests * 0x1900 - 0x19FF Socket device requests and responses + * 0x1A00 - 0x1AFF Network device requests and responses * * Zero and negative values are widely used for OK and error responses. */ @@ -1076,6 +1077,73 @@ # define SDEV_OP_ERR 0x04 /* selected for error operation */ # define SDEV_NOTIFY 0x08 /* notification requested */ +/*===========================================================================* + * Messages for network devices * + *===========================================================================*/ + +/* Base type for network device requests and responses. */ +#define NDEV_RQ_BASE 0x1A00 /* ndev -> netdriver */ +#define NDEV_RS_BASE 0x1A80 /* netdriver -> ndev */ + +#define IS_NDEV_RQ(type) (((type) & ~0x7f) == NDEV_RQ_BASE) +#define IS_NDEV_RS(type) (((type) & ~0x7f) == NDEV_RS_BASE) + +/* + * Status requests and responses travel in the opposite direction, so we group + * them with their sending party, so that the IS_NDEV_R[QS] macros can be used + * by either side to see whether the message is indeed for them. + */ +#define NDEV_INIT (NDEV_RQ_BASE + 0) /* initialize driver */ +#define NDEV_CONF (NDEV_RQ_BASE + 1) /* configure driver */ +#define NDEV_SEND (NDEV_RQ_BASE + 2) /* send a packet */ +#define NDEV_RECV (NDEV_RQ_BASE + 3) /* receive a packet */ +#define NDEV_IOCTL (NDEV_RQ_BASE + 4) /* (reserved) */ +#define NDEV_STATUS_REPLY (NDEV_RQ_BASE + 5) /* status reply */ + +#define NDEV_INIT_REPLY (NDEV_RS_BASE + 0) /* initialize reply */ +#define NDEV_CONF_REPLY (NDEV_RS_BASE + 1) /* configure reply */ +#define NDEV_SEND_REPLY (NDEV_RS_BASE + 2) /* send reply */ +#define NDEV_RECV_REPLY (NDEV_RS_BASE + 3) /* receive reply */ +#define NDEV_IOCTL_REPLY (NDEV_RS_BASE + 4) /* (reserved) */ +#define NDEV_STATUS (NDEV_RS_BASE + 5) /* status report */ + +/* Bits in the 'set' field of configuration requests. */ +# define NDEV_SET_MODE 0x01 /* set I/O mode and multicast list */ +# define NDEV_SET_CAPS 0x02 /* enable or disable capabilities */ +# define NDEV_SET_FLAGS 0x04 /* set driver-specific flags */ +# define NDEV_SET_MEDIA 0x08 /* set media type */ +# define NDEV_SET_HWADDR 0x10 /* change the hardware address */ + +/* Bits in the 'mode' field of configuration requests. */ +# define NDEV_MODE_DOWN 0x00 /* transmission and receipt disabled */ +# define NDEV_MODE_UP 0x01 /* receive unicast packets for me */ +# define NDEV_MODE_BCAST 0x02 /* receive broadcast packets */ +# define NDEV_MODE_MCAST_LIST 0x04 /* receive certain multicast packets */ +# define NDEV_MODE_MCAST_ALL 0x08 /* receive all multicast packets */ +# define NDEV_MODE_PROMISC 0x10 /* receive all packets */ + +/* Bits in the 'caps' field of initialization and configuration requests. */ +# define NDEV_CAP_CS_IP4_TX 0x01 /* IPv4 header checksum generation */ +# define NDEV_CAP_CS_IP4_RX 0x02 /* IPv4 header checksum verification */ +# define NDEV_CAP_CS_UDP_TX 0x04 /* UDP header checksum generation */ +# define NDEV_CAP_CS_UDP_RX 0x08 /* UDP header checksum verification */ +# define NDEV_CAP_CS_TCP_TX 0x10 /* TCP header checksum generation */ +# define NDEV_CAP_CS_TCP_RX 0x20 /* TCP header checksum verification */ +# define NDEV_CAP_MCAST 0x20000000 /* init only: mcast capable */ +# define NDEV_CAP_BCAST 0x40000000 /* init only: bcast capable */ +# define NDEV_CAP_HWADDR 0x80000000 /* init only: can set hwaddr */ + +/* Values for the 'flags' field of configuration requests. */ +# define NDEV_FLAG_DEBUG 0x01 /* enable driver-specific debug mode */ +# define NDEV_FLAG_LINK0 0x02 /* enable driver-specific LINK0 flag */ +# define NDEV_FLAG_LINK1 0x04 /* enable driver-specific LINK1 flag */ +# define NDEV_FLAG_LINK2 0x08 /* enable driver-specific LINK2 flag */ + +/* Values for the 'link' field of initialization and status replies. */ +# define NDEV_LINK_UNKNOWN 0 /* link status is unknown, assume up */ +# define NDEV_LINK_UP 1 /* link is up */ +# define NDEV_LINK_DOWN 2 /* link is down */ + /*===========================================================================* * Internal codes used by several services * *===========================================================================*/ diff --git a/minix/include/minix/config.h b/minix/include/minix/config.h index e8c944b6b..74e118543 100644 --- a/minix/include/minix/config.h +++ b/minix/include/minix/config.h @@ -98,4 +98,9 @@ #define NR_PCIBUS 40 #define NR_PCIDEV 50 +/* Network device driver protocol parameters. */ +#define NDEV_NAME_MAX 16 /* max network driver name length (incl nul) */ +#define NDEV_HWADDR_MAX 6 /* max network hardware address length */ +#define NDEV_IOV_MAX 8 /* max number of elements in I/O vector */ + #endif /* _CONFIG_H */ diff --git a/minix/include/minix/const.h b/minix/include/minix/const.h index 43b3fbc13..2ab957fcd 100644 --- a/minix/include/minix/const.h +++ b/minix/include/minix/const.h @@ -175,4 +175,11 @@ */ #define MINIX_CPUSTATES 5 +/* Network device driver constants. TODO: move to a better location. */ +#define NDEV_ETH_PACKET_MIN 60 /* min network packet size, in bytes */ +#define NDEV_ETH_PACKET_MAX 1514 /* max network packet size, in bytes */ +#define NDEV_ETH_PACKET_TAG 4 /* ethernet VLAN tag size, in bytes */ +#define NDEV_ETH_PACKET_CRC 4 /* ethernet CRC size, in bytes */ +#define NDEV_ETH_PACKET_MAX_TAGGED (NDEV_ETH_PACKET_MAX + NDEV_ETH_PACKET_TAG) + #endif /* _MINIX_CONST_H */ diff --git a/minix/include/minix/ipc.h b/minix/include/minix/ipc.h index 6ca59a3f5..fab92f976 100644 --- a/minix/include/minix/ipc.h +++ b/minix/include/minix/ipc.h @@ -1592,6 +1592,79 @@ typedef struct { } mess_mmap; _ASSERT_MSG_SIZE(mess_mmap); +typedef struct { + uint32_t id; + + uint8_t padding[52]; +} mess_ndev_netdriver_init; +_ASSERT_MSG_SIZE(mess_ndev_netdriver_init); + +typedef struct { + uint32_t id; + uint32_t set; + uint32_t mode; + cp_grant_id_t mcast_grant; + unsigned int mcast_count; + uint32_t caps; + uint32_t flags; + uint32_t media; + uint8_t hwaddr[NDEV_HWADDR_MAX]; + + uint8_t padding[18]; +} mess_ndev_netdriver_conf; +_ASSERT_MSG_SIZE(mess_ndev_netdriver_conf); + +typedef struct { + uint32_t id; + uint32_t count; + cp_grant_id_t grant[NDEV_IOV_MAX]; + uint16_t len[NDEV_IOV_MAX]; +} mess_ndev_netdriver_transfer; +_ASSERT_MSG_SIZE(mess_ndev_netdriver_transfer); + +typedef struct { + uint32_t id; + + uint8_t padding[52]; +} mess_ndev_netdriver_status_reply; +_ASSERT_MSG_SIZE(mess_ndev_netdriver_status_reply); + +typedef struct { + uint32_t id; + uint32_t link; + uint32_t media; + uint32_t caps; + char name[NDEV_NAME_MAX]; + uint8_t hwaddr[NDEV_HWADDR_MAX]; + uint8_t hwaddr_len; + uint8_t max_send; + uint8_t max_recv; + + uint8_t padding[15]; +} mess_netdriver_ndev_init_reply; +_ASSERT_MSG_SIZE(mess_netdriver_ndev_init_reply); + +typedef struct { + uint32_t id; + int32_t result; + + uint8_t padding[48]; +} mess_netdriver_ndev_reply; +_ASSERT_MSG_SIZE(mess_netdriver_ndev_reply); + +typedef struct { + uint32_t id; + uint32_t link; + uint32_t media; + uint32_t oerror; + uint32_t coll; + uint32_t ierror; + uint32_t iqdrop; + + uint8_t padding[28]; +} mess_netdriver_ndev_status; +_ASSERT_MSG_SIZE(mess_netdriver_ndev_status); + typedef struct { int mode; @@ -2509,6 +2582,13 @@ typedef struct noxfer_message { mess_mib_lsys_call m_mib_lsys_call; mess_mib_lsys_info m_mib_lsys_info; mess_mmap m_mmap; + mess_ndev_netdriver_init m_ndev_netdriver_init; + mess_ndev_netdriver_conf m_ndev_netdriver_conf; + mess_ndev_netdriver_transfer m_ndev_netdriver_transfer; + mess_ndev_netdriver_status_reply m_ndev_netdriver_status_reply; + mess_netdriver_ndev_init_reply m_netdriver_ndev_init_reply; + mess_netdriver_ndev_reply m_netdriver_ndev_reply; + mess_netdriver_ndev_status m_netdriver_ndev_status; mess_net_netdrv_dl_conf m_net_netdrv_dl_conf; mess_net_netdrv_dl_getstat_s m_net_netdrv_dl_getstat_s; mess_net_netdrv_dl_readv_s m_net_netdrv_dl_readv_s; diff --git a/minix/include/minix/netdriver.h b/minix/include/minix/netdriver.h index 693855838..a4cee50ad 100644 --- a/minix/include/minix/netdriver.h +++ b/minix/include/minix/netdriver.h @@ -1,67 +1,75 @@ -/* Prototypes and definitions for network drivers. */ - #ifndef _MINIX_NETDRIVER_H #define _MINIX_NETDRIVER_H +/* + * Prototypes and definitions for network drivers. + */ +#include #include #include #include -/* The flags that make up the requested receive mode. */ -#define NDEV_NOMODE DL_NOMODE /* targeted packets only */ -#define NDEV_PROMISC DL_PROMISC_REQ /* promiscuous mode */ -#define NDEV_MULTI DL_MULTI_REQ /* receive multicast packets */ -#define NDEV_BROAD DL_BROAD_REQ /* receive broadcast packets */ - -/* - * For now, only ethernet-type network drivers are supported, and thus, we use - * some ethernet-specific data structures. - */ -#include -#include +#include /* Opaque data structure for copying in and out actual packet data. */ struct netdriver_data; -/* Function call table for network drivers. */ +/* Network (ethernet) address structure. */ +typedef struct { + uint8_t na_addr[NDEV_HWADDR_MAX]; +} netdriver_addr_t; + +/* Information and function call table for network drivers. */ struct netdriver { - int (*ndr_init)(unsigned int instance, ether_addr_t *addr); - void (*ndr_stop)(void); - void (*ndr_mode)(unsigned int mode); - ssize_t (*ndr_recv)(struct netdriver_data *data, size_t max); - int (*ndr_send)(struct netdriver_data *data, size_t size); - void (*ndr_stat)(eth_stat_t *stat); - void (*ndr_intr)(unsigned int mask); - void (*ndr_alarm)(clock_t stamp); - void (*ndr_other)(const message *m_ptr, int ipc_status); + const char *ndr_name; + int (* ndr_init)(unsigned int instance, netdriver_addr_t * hwaddr, + uint32_t * caps, unsigned int * ticks); + void (* ndr_stop)(void); + void (* ndr_set_mode)(unsigned int mode, + const netdriver_addr_t * mcast_list, unsigned int mcast_count); + void (* ndr_set_caps)(uint32_t caps); + void (* ndr_set_flags)(uint32_t flags); + void (* ndr_set_media)(uint32_t media); + void (* ndr_set_hwaddr)(const netdriver_addr_t * hwaddr); + ssize_t (* ndr_recv)(struct netdriver_data * data, size_t max); + int (* ndr_send)(struct netdriver_data * data, size_t size); + unsigned int (* ndr_get_link)(uint32_t * media); + void (* ndr_intr)(unsigned int mask); + void (* ndr_tick)(void); + void (* ndr_other)(const message * m_ptr, int ipc_status); }; /* Functions defined by libnetdriver. */ -void netdriver_task(const struct netdriver *ndp); +void netdriver_task(const struct netdriver * ndp); -void netdriver_announce(void); /* legacy; deprecated */ -int netdriver_init(const struct netdriver *ndp); +int netdriver_init(const struct netdriver * ndp); void netdriver_process(const struct netdriver * __restrict ndp, const message * __restrict m_ptr, int ipc_status); void netdriver_terminate(void); +const char *netdriver_name(void); + void netdriver_recv(void); void netdriver_send(void); +void netdriver_link(void); + +void netdriver_stat_oerror(uint32_t count); +void netdriver_stat_coll(uint32_t count); +void netdriver_stat_ierror(uint32_t count); +void netdriver_stat_iqdrop(uint32_t count); void netdriver_copyin(struct netdriver_data * __restrict data, size_t off, void * __restrict ptr, size_t size); void netdriver_copyout(struct netdriver_data * __restrict data, size_t off, const void * __restrict ptr, size_t size); -void netdriver_portinb(struct netdriver_data *data, size_t off, long port, +void netdriver_portinb(struct netdriver_data * data, size_t off, long port, size_t size); -void netdriver_portoutb(struct netdriver_data *data, size_t off, long port, +void netdriver_portoutb(struct netdriver_data * data, size_t off, long port, size_t size); -void netdriver_portinw(struct netdriver_data *data, size_t off, long port, +void netdriver_portinw(struct netdriver_data * data, size_t off, long port, size_t size); -void netdriver_portoutw(struct netdriver_data *data, size_t off, long port, +void netdriver_portoutw(struct netdriver_data * data, size_t off, long port, size_t size); -#define netdriver_receive sef_receive_status /* legacy; deprecated */ - #endif /* _MINIX_NETDRIVER_H */ diff --git a/minix/include/minix/sysutil.h b/minix/include/minix/sysutil.h index bd976f809..dc259949d 100644 --- a/minix/include/minix/sysutil.h +++ b/minix/include/minix/sysutil.h @@ -13,7 +13,7 @@ * May 31, 2005: added printf, kputc (relocated from syslib) * May 31, 2005: added getuptime * Mar 18, 2005: added tickdelay - * Oct 01, 2004: added env_parse, env_prefix, env_panic + * Oct 01, 2004: added env_parse, env_panic * Jul 13, 2004: added fkey_ctl * Apr 28, 2004: added report, panic * Mar 31, 2004: setup like other libraries, such as syslib @@ -36,7 +36,6 @@ extern char **env_argv; void env_setargs(int argc, char *argv[]); int env_get_param(const char *key, char *value, int max_size); -int env_prefix(const char *env, const char *prefix); void __dead env_panic(const char *key); int env_parse(const char *env, const char *fmt, int field, long *param, long min, long max); diff --git a/minix/lib/libnetdriver/Makefile b/minix/lib/libnetdriver/Makefile index 1549d44cc..a3c9584d1 100644 --- a/minix/lib/libnetdriver/Makefile +++ b/minix/lib/libnetdriver/Makefile @@ -6,4 +6,6 @@ LIB= netdriver SRCS= netdriver.c portio.c +WARNS?= 5 + .include diff --git a/minix/lib/libnetdriver/netdriver.c b/minix/lib/libnetdriver/netdriver.c index 9cf12e006..a42db2edf 100644 --- a/minix/lib/libnetdriver/netdriver.c +++ b/minix/lib/libnetdriver/netdriver.c @@ -1,32 +1,60 @@ /* The device-independent network driver framework. */ #include -#include #include #include #include #include "netdriver.h" +/* + * These maximum values should be at least somewhat synchronized with the + * values in the LWIP service's ndev module. + */ +#define NETDRIVER_SENDQ_MAX 8 +#define NETDRIVER_RECVQ_MAX 2 + +/* + * Maximum number of multicast addresses that can be copied in from the TCP/IP + * service and passed to the driver. If the actual number from the service + * exceeds this maximum, the driver will be told to receive all multicast + * packets instead. + */ +#define NETDRIVER_MCAST_MAX 16 + static const struct netdriver *netdriver_table = NULL; static int running; -static int conf_expected; +static int init_expected; + +static int up; + +static unsigned int ticks; -static endpoint_t pending_endpt; -static struct netdriver_data pending_recv, pending_send; +static struct netdriver_data pending_sendq[NETDRIVER_SENDQ_MAX]; +static unsigned int pending_sends, pending_sendtail; -static int defer_reply; -static unsigned int pending_flags; -static size_t pending_size; +static struct netdriver_data pending_recvq[NETDRIVER_RECVQ_MAX]; +static unsigned int pending_recvs, pending_recvtail; -static ether_addr_t hw_addr; +static int pending_status; +static endpoint_t status_endpt; + +static int pending_link, pending_stat; +static uint32_t stat_oerror, stat_coll, stat_ierror, stat_iqdrop; + +static char device_name[NDEV_NAME_MAX]; +static netdriver_addr_t device_hwaddr; +static uint32_t device_caps; + +static unsigned int device_link; +static uint32_t device_media; /* * Announce we are up after a fresh start or restart. */ -void +static void netdriver_announce(void) { const char *driver_prefix = "drv.net."; @@ -183,240 +211,549 @@ send_reply(endpoint_t endpt, message * m_ptr) { int r; - if ((r = ipc_send(endpt, m_ptr)) != OK) + if ((r = asynsend(endpt, m_ptr)) != OK) panic("netdriver: unable to send to %d: %d", endpt, r); } /* - * Defer sending any replies to task requests until the next call to - * check_replies(). The purpose of this is aggregation of task replies to both - * send and receive requests into a single reply message, which saves on - * messages, in particular when processing interrupts. + * A packet receive request has finished. Send a reply and clean up. */ static void -defer_replies(void) +finish_recv(int32_t result) { + struct netdriver_data *data; + message m; - assert(netdriver_table != NULL); - assert(defer_reply == FALSE); - - defer_reply = TRUE; -} - -/* - * Check if we have to reply to earlier task (I/O) requests, and if so, send - * the reply. If deferred is FALSE and the call to this function was preceded - * by a call to defer_replies(), do not send a reply yet. If always_send is - * TRUE, send a reply even if no tasks have completed yet. - */ -static void -check_replies(int deferred, int always_send) -{ - message m_reply; - - if (defer_reply && !deferred) - return; - - defer_reply = FALSE; + assert(pending_recvs > 0); - if (pending_flags == 0 && !always_send) - return; + data = &pending_recvq[pending_recvtail]; - assert(pending_endpt != NONE); + memset(&m, 0, sizeof(m)); + m.m_type = NDEV_RECV_REPLY; + m.m_netdriver_ndev_reply.id = data->id; + m.m_netdriver_ndev_reply.result = result; - memset(&m_reply, 0, sizeof(m_reply)); - m_reply.m_type = DL_TASK_REPLY; - m_reply.m_netdrv_net_dl_task.flags = pending_flags; - m_reply.m_netdrv_net_dl_task.count = pending_size; + send_reply(data->endpt, &m); - send_reply(pending_endpt, &m_reply); - - pending_flags = 0; - pending_size = 0; + pending_recvtail = (pending_recvtail + 1) % + __arraycount(pending_recvq); + pending_recvs--; } /* * Resume receiving packets. In particular, if a receive request was pending, - * call the driver's receive function. If the call is successful, schedule - * sending a reply to the requesting party. + * call the driver's receive function. If the call is successful, send a reply + * to the requesting party. */ void netdriver_recv(void) { + struct netdriver_data *data; ssize_t r; - if (pending_recv.size == 0) - return; - assert(netdriver_table != NULL); - /* - * For convenience of driver writers: if the receive function returns - * zero, simply call it again, to simplify discarding invalid packets. - */ - do { - r = netdriver_table->ndr_recv(&pending_recv, - pending_recv.size); + while (pending_recvs > 0) { + data = &pending_recvq[pending_recvtail]; /* - * The default policy is: drop undersized packets, panic on - * oversized packets. The driver may implement any other - * policy (e.g., pad small packets, drop or truncate large - * packets), but it should at least test against the given - * 'max' value. The reason that truncation should be - * implemented in the driver rather than here, is explained in - * an earlier comment about truncating copy operations. + * For convenience of driver writers: if the receive function + * returns zero, simply call it again, to simplify discarding + * invalid packets. */ - if (r >= 0 && r < ETH_MIN_PACK_SIZE) - r = 0; - else if (r > (ssize_t)pending_recv.size) - panic("netdriver: oversized packet returned: %zd", r); - } while (r == 0); + do { + r = netdriver_table->ndr_recv(data, data->size); + + /* + * The default policy is: drop undersized packets, + * panic on oversized packets. The driver may + * implement any other policy (e.g., pad small packets, + * drop or truncate large packets), but it should at + * least test against the given 'max' value. The + * reason that truncation should be implemented in the + * driver rather than here, is explained in an earlier + * comment about truncating copy operations. + */ + if (r >= 0 && r < NDEV_ETH_PACKET_MIN) + r = 0; + else if (r > (ssize_t)data->size) + panic("netdriver: oversized packet returned: " + "%zd", r); + } while (r == 0); + + if (r == SUSPEND) + break; - if (r == SUSPEND) - return; - if (r < 0) - panic("netdriver: driver reported receive failure: %d", r); + if (r < 0) + panic("netdriver: driver reported receive failure: %d", + r); + + assert(r >= NDEV_ETH_PACKET_MIN && (size_t)r <= data->size); + + finish_recv(r); + } +} + +/* + * A packet send request has finished. Send a reply and clean up. + */ +static void +finish_send(int32_t result) +{ + struct netdriver_data *data; + message m; + + assert(pending_sends > 0); - assert(r >= ETH_MIN_PACK_SIZE && (size_t)r <= pending_recv.size); + data = &pending_sendq[pending_sendtail]; - pending_flags |= DL_PACK_RECV; - pending_size = r; + memset(&m, 0, sizeof(m)); + m.m_type = NDEV_SEND_REPLY; + m.m_netdriver_ndev_reply.id = data->id; + m.m_netdriver_ndev_reply.result = result; - pending_recv.size = 0; + send_reply(data->endpt, &m); - check_replies(FALSE /*deferred*/, FALSE /*always_send*/); + pending_sendtail = (pending_sendtail + 1) % + __arraycount(pending_sendq); + pending_sends--; } /* - * Resume sending packets. In particular, if a send request was pending, call - * the driver's send function. If the call is successful, schedule sending a - * reply to the requesting party. This function relies on being called - * between init_pending() and check_pending(). + * Resume sending packets. In particular, if any send requests were pending, + * call the driver's send function for each of them, until the driver can take + * no more. For each successful request is successful, send a reply to the + * requesting party. */ void netdriver_send(void) { + struct netdriver_data *data; int r; - if (pending_send.size == 0) - return; - assert(netdriver_table != NULL); - r = netdriver_table->ndr_send(&pending_send, pending_send.size); + while (pending_sends > 0) { + data = &pending_sendq[pending_sendtail]; - if (r == SUSPEND) - return; - if (r < 0) - panic("netdriver: driver reported send failure: %d", r); + r = netdriver_table->ndr_send(data, data->size); - pending_flags |= DL_PACK_SEND; + if (r == SUSPEND) + break; - pending_send.size = 0; + if (r < 0) + panic("netdriver: driver reported send failure: %d", + r); - check_replies(FALSE /*deferred*/, FALSE /*always_send*/); + finish_send(r); + } } /* - * Process a request to receive or send a packet. + * Process a request to send or receive a packet. */ static void -do_readwrite(const struct netdriver * __restrict ndp, endpoint_t endpt, - cp_grant_id_t grant, unsigned int count, int do_write) +do_transfer(const struct netdriver * __restrict ndp, const message * m_ptr, + int do_write) { struct netdriver_data *data; + cp_grant_id_t grant; + size_t size; unsigned int i; - int r; - /* Copy in the I/O vector. */ - data = (do_write) ? &pending_send : &pending_recv; + /* Prepare the local data structure. */ + if (do_write) { + if (pending_sends == __arraycount(pending_sendq)) + panic("netdriver: too many concurrent send requests"); - if (data->size != 0) - panic("netdriver: multiple concurrent requests"); + data = &pending_sendq[(pending_sendtail + pending_sends) % + __arraycount(pending_sendq)]; + } else { + if (pending_recvs == __arraycount(pending_recvq)) + panic("netdriver: too many concurrent receive " + "requests"); + + data = &pending_recvq[(pending_recvtail + pending_recvs) % + __arraycount(pending_recvq)]; + } - if (count == 0 || count > NR_IOREQS) - panic("netdriver: bad I/O vector count: %u", count); + data->endpt = m_ptr->m_source; + data->id = m_ptr->m_ndev_netdriver_transfer.id; + data->count = m_ptr->m_ndev_netdriver_transfer.count; - data->endpt = endpt; - data->count = count; + if (data->count == 0 || data->count > NDEV_IOV_MAX) + panic("netdriver: bad I/O vector count: %u", data->count); + + data->size = 0; + + for (i = 0; i < data->count; i++) { + grant = m_ptr->m_ndev_netdriver_transfer.grant[i]; + size = (size_t)m_ptr->m_ndev_netdriver_transfer.len[i]; - if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)data->iovec, - sizeof(data->iovec[0]) * count)) != OK) - panic("netdriver: unable to copy in I/O vector: %d", r); + assert(size > 0); - for (i = 0; i < count; i++) - data->size += data->iovec[i].iov_size; + data->iovec[i].iov_grant = grant; + data->iovec[i].iov_size = size; + data->size += size; + } - if (data->size < ETH_MIN_PACK_SIZE || - (!do_write && data->size < ETH_MAX_PACK_SIZE_TAGGED)) + if (data->size < NDEV_ETH_PACKET_MIN || + (!do_write && data->size < NDEV_ETH_PACKET_MAX_TAGGED)) panic("netdriver: invalid I/O vector size: %zu\n", data->size); - /* Save the endpoint to which we should reply. */ - if (pending_endpt != NONE && pending_endpt != endpt) - panic("netdriver: multiple request sources"); - pending_endpt = endpt; + if (do_write) + pending_sends++; + else + pending_recvs++; - /* Resume sending or receiving. */ - defer_replies(); + /* + * If the driver is down, immediately abort the request again. This + * is not a common case but does occur as part of queue draining by the + * TCP/IP stack, and is way easier to handle here than up there.. + */ + if (!up) { + if (do_write) + finish_send(EINTR); + else + finish_recv(EINTR); + return; + } + + /* Otherwise, resume sending or receiving. */ if (do_write) netdriver_send(); else netdriver_recv(); - - /* Always send a reply in this case, even if no flags are set. */ - check_replies(TRUE /*deferred*/, TRUE /*always_send*/); } /* - * Process a request to configure the driver, by setting its mode and obtaining - * its ethernet hardware address. We already have the latter as a result of - * calling the ndr_init callback function. + * Process a request to (re)configure the driver. */ static void do_conf(const struct netdriver * __restrict ndp, const message * __restrict m_ptr) { - message m_reply; + netdriver_addr_t mcast_list[NETDRIVER_MCAST_MAX]; + uint32_t set, mode; + unsigned int mcast_count; + message m; + int r; + + set = m_ptr->m_ndev_netdriver_conf.set; + mode = m_ptr->m_ndev_netdriver_conf.mode; + + /* + * If the request includes taking down the interface, perform that step + * first: it is expected that in many cases, changing other settings + * requires stopping and restarting the device. + */ + if ((set & NDEV_SET_MODE) && mode == NDEV_MODE_DOWN && + ndp->ndr_set_mode != NULL) + ndp->ndr_set_mode(mode, NULL, 0); - if (ndp->ndr_mode != NULL) - ndp->ndr_mode(m_ptr->m_net_netdrv_dl_conf.mode); + if ((set & NDEV_SET_CAPS) && ndp->ndr_set_caps != NULL) + ndp->ndr_set_caps(m_ptr->m_ndev_netdriver_conf.caps); + + if ((set & NDEV_SET_FLAGS) && ndp->ndr_set_flags != NULL) + ndp->ndr_set_flags(m_ptr->m_ndev_netdriver_conf.flags); + + if ((set & NDEV_SET_MEDIA) && ndp->ndr_set_media != NULL) + ndp->ndr_set_media(m_ptr->m_ndev_netdriver_conf.media); + + if ((set & NDEV_SET_HWADDR) && ndp->ndr_set_hwaddr != NULL) { + /* Save the new hardware address. */ + memcpy(&device_hwaddr, m_ptr->m_ndev_netdriver_conf.hwaddr, + sizeof(device_hwaddr)); + + ndp->ndr_set_hwaddr(&device_hwaddr); + } + + if ((set & NDEV_SET_MODE) && mode != NDEV_MODE_DOWN && + ndp->ndr_set_mode != NULL) { + /* + * If we have a multicast list, copy it in, unless it is too + * large: in that case, enable all-multicast receipt mode. + */ + if ((mode & NDEV_MODE_MCAST_LIST) && + m_ptr->m_ndev_netdriver_conf.mcast_count > + __arraycount(mcast_list)) { + mode &= ~NDEV_MODE_MCAST_LIST; + mode |= NDEV_MODE_MCAST_ALL; + } + + if (mode & NDEV_MODE_MCAST_LIST) { + assert(m_ptr->m_ndev_netdriver_conf.mcast_grant != + GRANT_INVALID); + + mcast_count = m_ptr->m_ndev_netdriver_conf.mcast_count; + + if ((r = sys_safecopyfrom(m_ptr->m_source, + m_ptr->m_ndev_netdriver_conf.mcast_grant, 0, + (vir_bytes)mcast_list, + mcast_count * sizeof(mcast_list[0]))) != OK) + panic("netdriver: unable to copy data: %d", r); + + ndp->ndr_set_mode(mode, mcast_list, mcast_count); + } else + ndp->ndr_set_mode(mode, NULL, 0); + } - memset(&m_reply, 0, sizeof(m_reply)); - m_reply.m_type = DL_CONF_REPLY; - m_reply.m_netdrv_net_dl_conf.stat = OK; /* legacy */ - memcpy(&m_reply.m_netdrv_net_dl_conf.hw_addr, &hw_addr, - sizeof(m_reply.m_netdrv_net_dl_conf.hw_addr)); + /* We always report OK: the caller cannot do anything upon failure. */ + memset(&m, 0, sizeof(m)); + m.m_type = NDEV_CONF_REPLY; + m.m_netdriver_ndev_reply.id = m_ptr->m_ndev_netdriver_conf.id; + m.m_netdriver_ndev_reply.result = OK; - send_reply(m_ptr->m_source, &m_reply); + send_reply(m_ptr->m_source, &m); + + /* + * Finally, if the device has been taken down, abort pending send and + * receive requests. + */ + if (set & NDEV_SET_MODE) { + if (mode == NDEV_MODE_DOWN) { + while (pending_sends > 0) + finish_send(EINTR); + + while (pending_recvs > 0) + finish_recv(EINTR); + + up = FALSE; + } else + up = TRUE; + } } /* - * Process a request to obtain statistics from the driver. + * Request an update of the link state and active media of the device. This + * routine may be called both from the driver and internally. */ static void -do_getstat(const struct netdriver * __restrict ndp, - const message * __restrict m_ptr) +update_link(void) +{ + + if (netdriver_table->ndr_get_link != NULL) + device_link = netdriver_table->ndr_get_link(&device_media); + + pending_link = FALSE; +} + +/* + * Attempt to send a status update to the endpoint registered to receive status + * updates, if any. + */ +static void +send_status(void) { - message m_reply; - eth_stat_t st; + message m; int r; - memset(&st, 0, sizeof(st)); + assert(pending_link || pending_stat); + + if (status_endpt == NONE || pending_status) + return; - if (ndp->ndr_stat != NULL) - ndp->ndr_stat(&st); + if (pending_link) + update_link(); - if ((r = sys_safecopyto(m_ptr->m_source, - m_ptr->m_net_netdrv_dl_getstat_s.grant, 0, (vir_bytes)&st, - sizeof(st))) != OK) - panic("netdriver: unable to copy out statistics: %d", r); + memset(&m, 0, sizeof(m)); + m.m_type = NDEV_STATUS; + m.m_netdriver_ndev_status.id = 0; /* for now */ + m.m_netdriver_ndev_status.link = device_link; + m.m_netdriver_ndev_status.media = device_media; + m.m_netdriver_ndev_status.oerror = stat_oerror; + m.m_netdriver_ndev_status.coll = stat_coll; + m.m_netdriver_ndev_status.ierror = stat_ierror; + m.m_netdriver_ndev_status.iqdrop = stat_iqdrop; - memset(&m_reply, 0, sizeof(m_reply)); - m_reply.m_type = DL_STAT_REPLY; + if ((r = asynsend3(status_endpt, &m, AMF_NOREPLY)) != OK) + panic("netdriver: unable to send status: %d", r); - send_reply(m_ptr->m_source, &m_reply); + /* + * Do not send another status message until either the one we just sent + * gets acknowledged or we get a new initialization request. This way + * we get "natural pacing" (i.e., we avoid overflowing the asynsend + * message queue by design) without using timers. + */ + pending_status = TRUE; + + /* + * The status message sends incremental updates for statistics. This + * means that while a restart of the TCP/IP stack means the statistics + * are lost (not great), a restart of the driver leaves the statistics + * mostly intact (more important). + */ + stat_oerror = 0; + stat_coll = 0; + stat_ierror = 0; + stat_iqdrop = 0; + pending_stat = FALSE; +} + +/* + * Process a reply to a status update that we sent earlier on (supposedly). + */ +static void +do_status_reply(const struct netdriver * __restrict ndp __unused, + const message * __restrict m_ptr) +{ + + if (m_ptr->m_source != status_endpt) + return; + + if (!pending_status || m_ptr->m_ndev_netdriver_status_reply.id != 0) + panic("netdriver: unexpected status reply"); + + pending_status = FALSE; + + /* + * If the local status has changed since our last status update, + * send a new one right away. + */ + if (pending_link || pending_stat) + send_status(); +} + +/* + * The driver reports that the link state and/or active media may have changed. + * When convenient, request the new state from the driver and send a status + * message to the TCP/IP stack. + */ +void +netdriver_link(void) +{ + + pending_link = TRUE; + + send_status(); +} + +/* + * The driver reports that a number of output errors have occurred. Update + * statistics accordingly. + */ +void +netdriver_stat_oerror(uint32_t count) +{ + + if (count == 0) + return; + + stat_oerror += count; + pending_stat = TRUE; + + send_status(); +} + +/* + * The driver reports that one or more packet collisions have occurred. Update + * statistics accordingly. + */ +void +netdriver_stat_coll(uint32_t count) +{ + + if (count == 0) + return; + + stat_coll += count; + pending_stat = TRUE; + + send_status(); +} + +/* + * The driver reports that a number of input errors have occurred. Adjust + * statistics accordingly. + */ +void +netdriver_stat_ierror(uint32_t count) +{ + + if (count == 0) + return; + + stat_ierror += count; + pending_stat = TRUE; + + send_status(); +} + +/* + * The driver reports that a number of input queue drops have occurred. Update + * statistics accordingly. + */ +void +netdriver_stat_iqdrop(uint32_t count) +{ + + if (count == 0) + return; + + stat_iqdrop += count; + pending_stat = TRUE; + + send_status(); +} + +/* + * Process an initialization request. Actual initialization has already taken + * place, so we simply report the information gathered at that time. If the + * caller (the TCP/IP stack) has crashed and restarted, we will get another + * initialization request message, so keep the information up-to-date. + */ +static void +do_init(const struct netdriver * __restrict ndp, + const message * __restrict m_ptr) +{ + message m; + + /* + * First of all, an initialization request is a sure indication that + * the caller does not have any send or receive requests pending, and + * will not acknowledge our previous status request, if any. Forget + * any such previous requests and start sending status requests to the + * (new) endpoint. + */ + pending_sends = 0; + pending_recvs = 0; + pending_status = FALSE; + + status_endpt = m_ptr->m_source; + + /* + * Update link and media now, because we are about to send the initial + * values of those to the caller as well. + */ + update_link(); + + memset(&m, 0, sizeof(m)); + m.m_type = NDEV_INIT_REPLY; + m.m_netdriver_ndev_init_reply.id = m_ptr->m_ndev_netdriver_init.id; + m.m_netdriver_ndev_init_reply.link = device_link; + m.m_netdriver_ndev_init_reply.media = device_media; + m.m_netdriver_ndev_init_reply.caps = device_caps; + strlcpy(m.m_netdriver_ndev_init_reply.name, device_name, + sizeof(m.m_netdriver_ndev_init_reply.name)); + assert(sizeof(device_hwaddr) <= + sizeof(m.m_netdriver_ndev_init_reply.hwaddr)); + memcpy(m.m_netdriver_ndev_init_reply.hwaddr, &device_hwaddr, + sizeof(device_hwaddr)); + m.m_netdriver_ndev_init_reply.hwaddr_len = sizeof(device_hwaddr); + + m.m_netdriver_ndev_init_reply.max_send = __arraycount(pending_sendq); + m.m_netdriver_ndev_init_reply.max_recv = __arraycount(pending_recvq); + + send_reply(m_ptr->m_source, &m); + + /* + * Also send the current status. This is not required by the protocol + * and only serves to provide updated statistics to a new TCP/IP stack + * instance right away. + */ + if (pending_stat) + send_status(); } /* @@ -431,17 +768,18 @@ netdriver_process(const struct netdriver * __restrict ndp, /* Check for notifications first. */ if (is_ipc_notify(ipc_status)) { - defer_replies(); - - switch (_ENDPOINT_P(m_ptr->m_source)) { + switch (m_ptr->m_source) { case HARDWARE: if (ndp->ndr_intr != NULL) ndp->ndr_intr(m_ptr->m_notify.interrupts); break; case CLOCK: - if (ndp->ndr_alarm != NULL) - ndp->ndr_alarm(m_ptr->m_notify.timestamp); + if (ndp->ndr_tick != NULL) + ndp->ndr_tick(); + + if (ticks > 0) + (void)sys_setalarm(ticks, FALSE /*abs_time*/); break; default: @@ -449,62 +787,83 @@ netdriver_process(const struct netdriver * __restrict ndp, ndp->ndr_other(m_ptr, ipc_status); } - /* - * Any of the above calls may end up invoking netdriver_send() - * and/or netdriver_recv(), which may in turn have deferred - * sending a reply to an earlier request. See if we have to - * send the reply now. - */ - check_replies(TRUE /*deferred*/, FALSE /*always_send*/); + return; } /* - * Discard datalink requests preceding a first DL_CONF request, so that - * after a driver restart, any in-flight request is discarded. This is - * a rather blunt approach and must be revised if the protocol is ever - * made less inefficient (i.e. not strictly serialized). Note that for - * correct driver operation it is important that non-datalink requests, - * interrupts in particular, do not go through this check. + * Discard datalink requests preceding a first NDEV_INIT request, so + * that after a driver restart, any in-flight request is discarded. + * Note that for correct driver operation it is important that + * non-datalink requests, and interrupts in particular, do not go + * through this check. */ - if (IS_DL_RQ(m_ptr->m_type) && conf_expected) { - if (m_ptr->m_type != DL_CONF) + if (IS_NDEV_RQ(m_ptr->m_type) && init_expected) { + if (m_ptr->m_type != NDEV_INIT) return; /* do not send a reply */ - conf_expected = FALSE; + init_expected = FALSE; } switch (m_ptr->m_type) { - case DL_CONF: + case NDEV_INIT: + do_init(ndp, m_ptr); + break; + + case NDEV_CONF: do_conf(ndp, m_ptr); break; - case DL_GETSTAT_S: - do_getstat(ndp, m_ptr); + case NDEV_SEND: + do_transfer(ndp, m_ptr, TRUE /*do_write*/); break; - case DL_READV_S: - do_readwrite(ndp, m_ptr->m_source, - m_ptr->m_net_netdrv_dl_readv_s.grant, - m_ptr->m_net_netdrv_dl_readv_s.count, FALSE /*do_write*/); + case NDEV_RECV: + do_transfer(ndp, m_ptr, FALSE /*do_write*/); break; - case DL_WRITEV_S: - do_readwrite(ndp, m_ptr->m_source, - m_ptr->m_net_netdrv_dl_writev_s.grant, - m_ptr->m_net_netdrv_dl_writev_s.count, TRUE /*do_write*/); + case NDEV_STATUS_REPLY: + do_status_reply(ndp, m_ptr); break; default: - defer_replies(); - if (ndp->ndr_other != NULL) ndp->ndr_other(m_ptr, ipc_status); - - /* As above: see if we have to send a reply now. */ - check_replies(TRUE /*deferred*/, FALSE /*always_send*/); } } +/* + * Set a name for the device, based on the base name 'base' and the instance + * number 'instance'. + */ +static void +netdriver_set_name(const char * base, unsigned int instance) +{ + size_t len; + + assert(instance <= 255); + + len = strlen(base); + assert(len <= sizeof(device_name) - 4); + + memcpy(device_name, base, len); + if (instance >= 100) + device_name[len++] = '0' + instance / 100; + if (instance >= 10) + device_name[len++] = '0' + (instance % 100) / 10; + device_name[len++] = '0' + instance % 10; + device_name[len] = 0; +} + +/* + * Return the device name generated at driver initialization time. + */ +const char * +netdriver_name(void) +{ + + return device_name; +} + /* * Perform initialization. Return OK or an error code. */ @@ -516,44 +875,63 @@ netdriver_init(const struct netdriver * ndp) int r; /* Initialize global variables. */ - pending_recv.size = 0; - pending_send.size = 0; - pending_endpt = NONE; - defer_reply = FALSE; - pending_flags = 0; - pending_size = 0; - conf_expected = TRUE; - - /* Get the card instance number. */ + pending_sendtail = 0; + pending_sends = 0; + pending_recvtail = 0; + pending_recvs = 0; + + memset(device_name, 0, sizeof(device_name)); + + memset(&device_hwaddr, 0, sizeof(device_hwaddr)); + device_caps = 0; + + /* Use sensible defaults for the link state and active media. */ + device_link = NDEV_LINK_UNKNOWN; + device_media = IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0); + + status_endpt = NONE; + pending_status = FALSE; + pending_link = FALSE; + + up = FALSE; + + ticks = 0; + + /* Get the device instance number. */ v = 0; (void)env_parse("instance", "d", 0, &v, 0, 255); instance = (unsigned int)v; - /* Call the initialization routine. */ - memset(&hw_addr, 0, sizeof(hw_addr)); + /* Generate the full driver name. */ + netdriver_set_name(ndp->ndr_name, instance); - if (ndp->ndr_init != NULL && - (r = ndp->ndr_init(instance, &hw_addr)) != OK) + /* Call the initialization routine. */ + if ((r = ndp->ndr_init(instance, &device_hwaddr, &device_caps, + &ticks)) != OK) return r; /* Announce we are up! */ netdriver_announce(); + init_expected = TRUE; + running = TRUE; + + if (ticks > 0) + (void)sys_setalarm(ticks, FALSE /*abs_time*/); + return OK; } /* - * SEF initialization function. + * Perform SEF initialization. */ static int -do_init(int __unused type, sef_init_info_t * __unused info) +local_init(int type __unused, sef_init_info_t * info __unused) { - const struct netdriver *ndp; - ndp = netdriver_table; - assert(ndp != NULL); + assert(netdriver_table != NULL); - return netdriver_init(ndp); + return netdriver_init(netdriver_table); } /* @@ -594,18 +972,14 @@ netdriver_task(const struct netdriver * ndp) int r, ipc_status; /* Perform SEF initialization. */ - sef_setcb_init_fresh(do_init); + sef_setcb_init_fresh(local_init); sef_setcb_signal_handler(got_signal); netdriver_table = ndp; sef_startup(); - netdriver_table = NULL; - /* The main message loop. */ - running = TRUE; - while (running) { if ((r = sef_receive_status(ANY, &mess, &ipc_status)) != OK) { if (r == EINTR) diff --git a/minix/lib/libnetdriver/netdriver.h b/minix/lib/libnetdriver/netdriver.h index 24b9c5cc0..fae9739f6 100644 --- a/minix/lib/libnetdriver/netdriver.h +++ b/minix/lib/libnetdriver/netdriver.h @@ -4,9 +4,10 @@ /* Data (I/O) structure. */ struct netdriver_data { endpoint_t endpt; + uint32_t id; size_t size; unsigned int count; - iovec_s_t iovec[NR_IOREQS]; + iovec_s_t iovec[NDEV_IOV_MAX]; }; size_t netdriver_prepare_copy(struct netdriver_data *data, size_t offp, diff --git a/minix/lib/libsys/Makefile b/minix/lib/libsys/Makefile index e8702051c..bff698453 100644 --- a/minix/lib/libsys/Makefile +++ b/minix/lib/libsys/Makefile @@ -21,7 +21,6 @@ SRCS+= \ env_get_prm.c \ env_panic.c \ env_parse.c \ - env_prefix.c \ fkey_ctl.c \ getepinfo.c \ getprocnr.c \ diff --git a/minix/lib/libsys/env_prefix.c b/minix/lib/libsys/env_prefix.c deleted file mode 100644 index e1cf283f7..000000000 --- a/minix/lib/libsys/env_prefix.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "sysutil.h" -#include -#include - -/*=========================================================================* - * env_prefix * - *=========================================================================*/ -int env_prefix(const char *env, const char *prefix) -{ -/* An environment setting may be prefixed by a word, usually "pci". - * - env: environment variable to inspect - * - prefix: prefix to test for - * Return TRUE if a given prefix is used. - */ - char value[EP_BUF_SIZE]; - char punct[] = ":,;."; - int s; - size_t n; - - if ((s = env_get_param(env, value, sizeof(value))) != 0) { - if (s != ESRCH) /* only error allowed */ - printf("WARNING: env_get_param() failed in env_prefix(): %d\n", s); - return FALSE; - } - n = strlen(prefix); - return(strncmp(value, prefix, n) == 0 - && strchr(punct, value[n]) != NULL); -} -