]> Zhao Yanbai Git Server - minix.git/commitdiff
libnetdriver: rewrite 76/3476/2
authorDavid van Moolenbroek <david@minix3.org>
Wed, 12 Oct 2016 04:41:08 +0000 (04:41 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Sun, 30 Apr 2017 13:15:28 +0000 (13:15 +0000)
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

63 files changed:
minix/drivers/net/3c90x/3c90x.c
minix/drivers/net/3c90x/3c90x.h
minix/drivers/net/3c90x/Makefile
minix/drivers/net/atl2/Makefile
minix/drivers/net/atl2/atl2.c
minix/drivers/net/atl2/atl2.h
minix/drivers/net/dec21140A/Makefile
minix/drivers/net/dec21140A/README.txt
minix/drivers/net/dec21140A/dec21140A.c
minix/drivers/net/dec21140A/dec21140A.h
minix/drivers/net/dp8390/3c503.c
minix/drivers/net/dp8390/Makefile
minix/drivers/net/dp8390/dp8390.c
minix/drivers/net/dp8390/dp8390.h
minix/drivers/net/dp8390/ne2000.c
minix/drivers/net/dp8390/rtl8029.c
minix/drivers/net/dp8390/wdeth.c
minix/drivers/net/dpeth/3c501.c
minix/drivers/net/dpeth/3c503.c
minix/drivers/net/dpeth/3c509.c
minix/drivers/net/dpeth/8390.c
minix/drivers/net/dpeth/Makefile
minix/drivers/net/dpeth/devio.c
minix/drivers/net/dpeth/dp.c
minix/drivers/net/dpeth/dp.h
minix/drivers/net/dpeth/ne.c
minix/drivers/net/dpeth/netbuff.c
minix/drivers/net/dpeth/wd.c
minix/drivers/net/e1000/Makefile
minix/drivers/net/e1000/e1000.c
minix/drivers/net/e1000/e1000.h
minix/drivers/net/e1000/e1000_reg.h
minix/drivers/net/fxp/Makefile
minix/drivers/net/fxp/fxp.c
minix/drivers/net/fxp/fxp.h
minix/drivers/net/ip1000/ip1000.c
minix/drivers/net/ip1000/ip1000.h
minix/drivers/net/lan8710a/Makefile
minix/drivers/net/lan8710a/lan8710a.c
minix/drivers/net/lan8710a/lan8710a.h
minix/drivers/net/lance/Makefile
minix/drivers/net/lance/lance.c
minix/drivers/net/lance/lance.h
minix/drivers/net/rtl8139/Makefile
minix/drivers/net/rtl8139/rtl8139.c
minix/drivers/net/rtl8139/rtl8139.h
minix/drivers/net/rtl8169/Makefile
minix/drivers/net/rtl8169/rtl8169.c
minix/drivers/net/virtio_net/Makefile
minix/drivers/net/virtio_net/virtio_net.c
minix/drivers/net/vt6105/vt6105.c
minix/drivers/net/vt6105/vt6105.h
minix/include/minix/com.h
minix/include/minix/config.h
minix/include/minix/const.h
minix/include/minix/ipc.h
minix/include/minix/netdriver.h
minix/include/minix/sysutil.h
minix/lib/libnetdriver/Makefile
minix/lib/libnetdriver/netdriver.c
minix/lib/libnetdriver/netdriver.h
minix/lib/libsys/Makefile
minix/lib/libsys/env_prefix.c [deleted file]

index dda93600565cc1702d798b991ac46d01c8218e18..8b0304cc1399591955442a23216d0cd33abd3b46 100644 (file)
@@ -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 : "<unknown>", 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 */
 }
 
 /*
index 96ebf44d6615fb536171ec90bebc1f47d0292b7a..6ce637c0f895519d709e74b307161ce81dfbbd8d 100644 (file)
@@ -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 */
 
index 1358767d6bf456c8287c4be81a8e8b98b328ce1e..f7a9000fdb870cbc893bd201963db820637c7db8 100644 (file)
@@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
+WARNS?= 5
+
 .include <minix.service.mk>
index 4165db4c338f28e6be205cf348a4e95ad80ff9e8..202ada0acbfa922f0ef67ab42a50dcd9a796a75d 100644 (file)
@@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
+WARNS?= 5
+
 .include <minix.service.mk>
index e9f332fbd0634f34c3aa935f36d9d25b8753fad9..454515e0975cb1d6e8348e50ee3df839e0caf517 100644 (file)
@@ -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 : "<unknown>", 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;
 }
 
index 7d53c4741e1f3e017a317f8d9ec6e3168ec2717b..c7d6cc565cf812a55ffd0ac6757e3996d8baa9e3 100644 (file)
@@ -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) */
index 6ef33c09a425e9e6810addd4b0c74d43719a7ee7..c388360f06dfbcae92942530bc4e05cc4c7bbe43 100644 (file)
@@ -11,4 +11,6 @@ LDADD+=       -lnetdriver -lsys
 
 CPPFLAGS+=     -Ddebug=0
 
+WARNS?= 5
+
 .include <minix.service.mk>
index d62ccb8c77a868c7e885d34801a669b988be405b..99eb37455df4e02592e9227f5665041471b083f0 100644 (file)
@@ -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.
index 5d9eec3b54f241f6dc584f42c6611f97386e054b..50f643c868f43b1e7b54f9e02ecb379a49da3f72 100644 (file)
 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;
 }
 
index 74f8af910e39045cbd400a55d1d10c12acb29e15..b0a13e91a73b4388c43cdb3f91e8ec55915d511b 100644 (file)
@@ -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)*
index 54702c67778c3e374bbf88ead8af31cef85ed5e7..d88505fd98079d757b64d454b11165266e808cf9 100644 (file)
@@ -14,9 +14,6 @@
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
 
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
-
 #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;
index bd3b36632be4dfeedebef0cf7959bf92c867f33a..9189c05836cf3f1dbeea73d20d165bfcb0c78b45 100644 (file)
@@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
+WARNS?= 5
+
 .include <minix.service.mk>
index c68d634cb61dadb20c1b8d78c3f21767a2151b72..99242fd18789075d15e0c1a28300632059c8a314 100644 (file)
@@ -16,7 +16,6 @@
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
 
-#include <net/hton.h>
 #include <sys/mman.h>
 #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), &eth_type);
+                       2*sizeof(netdriver_addr_t), sizeof(eth_type),
+                       &eth_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;
index ab02f7baf8c7d4372775704fa41c1597b64221c2..d55d9c01abbdc380da05c78dc98f6488d73073e3 100644 (file)
@@ -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; 
index de0ee889df9638fa9ce0892a51362afe16df5e59..4aa990c5b7a99e9fbd0a1b58aca0d9aac4f90722 100644 (file)
@@ -10,9 +10,6 @@ Created:      March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com>
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
 
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
-
 #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;
        }
index c66f43bae7496a9288a962a2d29d22353444c7b7..864e5abe4620fe6e1374491f520d878092f78bb4 100644 (file)
@@ -11,8 +11,6 @@ Created:      April 2000 by Philip Homburg <philip@f-mnx.phicoh.com>
 
 #include <stdlib.h>
 #include <sys/types.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #include <machine/pci.h>
 
 #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;
 
index e9feb79915b842b961e927f272073fd20d1814c7..60299da98c4f1371d005cce365619de5418c3fd1 100644 (file)
@@ -7,9 +7,7 @@ Created:        March 14, 1994 by Philip Homburg
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
 
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
-#include "assert.h"
+#include <assert.h>
 
 #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 ||
index 2fd87e5f36d32706ed35cb4dcd852b1d580dfda9..df2d881f1908741caf0382e9baa51f1338e577f1 100644 (file)
@@ -11,8 +11,6 @@
 
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #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);
index 8b3503e1b158c687b9dc8c063e444c7ce72075fe..5612a81ec8177579a2c846e86c085dfab8c8ed66 100644 (file)
@@ -11,8 +11,6 @@
 
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #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');
 }
 
index debcb2f2cbc496878c334b6494986f5489bede71..a089d6cd0e5300e41c69b6fde22282258a925013 100644 (file)
@@ -11,8 +11,6 @@
 
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 
 #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');
 }
 
index 8007d0b0bd80fa3eb3d84e228ddba8fbf7e2842b..4405bacb2917e39dfc989c1ae87c4a9e9210af2f 100644 (file)
@@ -12,8 +12,6 @@
 
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #include <assert.h>
 #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), &eth_type);
+           2 * sizeof(netdriver_addr_t), sizeof(eth_type), &eth_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);
 
index 1b3843dd9dd5d5b784b99b22c06849a06b143098..7416e8998bf1662db39671ae453833386825ea46 100644 (file)
@@ -11,4 +11,6 @@ LDADD+=       -lnetdriver -lsys
 
 CPPFLAGS+=     -DVERBOSE=0
 
+WARNS?= 5
+
 .include <minix.service.mk>
index 1e388b0f22b8b900fa3fcc6cb160f071c170914f..14e701723f9bf6897733ee092236055b87090355 100644 (file)
@@ -9,8 +9,6 @@
 
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #include "dp.h"
 
 #if (USE_IOPL == 0)
index 0099dcef19abdc43f077ead86e7e1d0f3447406b..f3d2025886be82e1ce281d1353f729f6b8216e0b 100644 (file)
@@ -14,8 +14,6 @@
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
 #include <minix/endpoint.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #include <sys/mman.h>
 #include <assert.h>
 
@@ -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.
index 6a0b56f0ee1d3123268aaac97c3f75155b2fe539..9923c6340310d1aa85448048b0069e224d4ec045 100644 (file)
@@ -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;
index 4b8add035dba9a32c53c9a7ab2bd521c7e67c123..a6ea8d1f824de6054c70592057641106b87dd9d2 100644 (file)
@@ -14,8 +14,6 @@
 
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #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 */
index 955c466e73456bc99b1e6118bc4a74e5946a670e..7a3877ba2e67168f177849795c60d08845654454 100644 (file)
@@ -9,8 +9,6 @@
 
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #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;
        }
   }
index 2e3d5d1dfced46e675a42e09320c0a7ccb95820c..9a46dce10e3209dec5455ee3cecd6eece0296903 100644 (file)
@@ -14,8 +14,6 @@
 
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #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;
index 510936c04a4fc27bfa3f1deb57c4698e6b9c0fba..9a6a6675b02b8fa80624192d9c072d5041c3e126 100644 (file)
@@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
+WARNS?= 5
+
 .include <minix.service.mk>
index 3632c6da0a6d60a6b143d164382e31899146cc87..b8a30691c5eb13099c7506b34092b2b0f2a8c868 100644 (file)
 #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);
 }
index f97b437e7a3fa9078eacd401241545da0e2dc20f..308b934daf63a36d672899c750faab4725f869d9 100644 (file)
  */
 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. */
index bcaefd1142e35820920271291eb4e35028fa0362..5ba7ef8cc5ad0d332f65bee22241cbde4d7d986c 100644 (file)
 /** 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 */
+
 /**
  * @}
  */
 /** 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. */
index 3fc4548f3fd9bfb3e4bc735d618580c12686d94e..3d67dda000536fd714ec6f3f219a35e77617c860 100644 (file)
@@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
+WARNS?= 5
+
 .include <minix.service.mk>
index 48d4bdcb5747cd7ef7d4ef9058ef0ea94b3e95a5..bc70627d9fa1e2ffe02d0b23581dfc63894f6290 100644 (file)
@@ -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
 }
 
index 58a7e93bbf7b51548e6fce561e1135414175a44a..5c64f222dfec18c8115b52b7b7d2e88291d3a3f6 100644 (file)
@@ -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 */
index aa3be54dd167b21abac98472dd7a87695bc5bdaf..919b1eb4f9aa13f11e3b36c7f23314f483133a11 100644 (file)
@@ -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--;
 
index d07f4f4314b4d670eb00b78ab10d94909bc702c0..7ed366505a17eee234784eb9a4dbdbca5c152e4d 100644 (file)
@@ -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
index 9a610343cc2e360c9ef61f3fd1b9167b4cc3bd89..1c21460cb40eaf46ab575898806c1ed2b7e5c6c7 100644 (file)
@@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
+WARNS?= 5
+
 .include <minix.service.mk>
index eb5ecbdeafa683c0ab4f9dadebce5f10537aebc3..ed34c940c89443e46e7fcb0cc073a85bb6d8b712 100644 (file)
@@ -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;
        }
index 3dca3a7872cabdbb39e787d862927212f8aad578..3bcce840db0dcae51b2b9957d09abccb02d6bbdf 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef LAN8710A_H_
 #define LAN8710A_H_
 
-#include <net/gen/ether.h>
-
 #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 */
index 5825ff2a184db0b44f78e4b2c9d67ee311ab5b6c..ee1d645ed653fcdcd8e328cc2538aa39164c8166 100644 (file)
@@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
+WARNS?= 5
+
 .include <minix.service.mk>
index b63d400291853d5109e86dc53ed0e3aac4da54b0..d360047b22c1d3c055c8812f970b52896f17aa4f 100644 (file)
@@ -14,9 +14,6 @@
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
 
-#include <net/hton.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
 #include <assert.h>
 
 #include <minix/syslib.h>
 
 #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; i<RX_RING_SIZE; i++)
    {
@@ -915,13 +859,14 @@ static void lance_init_hw(ether_card_t *ec, ether_addr_t *addr)
    }
 
    /* 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);
       }
index 5a1b3e5dcf63169bc6061f953712840b2e0373ed..87227a8b79ab1b878d7191bf7031ef03fa24ddbd 100644 (file)
@@ -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;
index 0a3b4096b2c83f3bdb0cf41d58b3d9db37968025..dfba27e701181d73f7203c7beedd1f0436252ab9 100644 (file)
@@ -11,4 +11,6 @@ LDADD+=       -lnetdriver -lsys
 
 CPPFLAGS+=     -I${NETBSDSRCDIR}/minix
 
+WARNS?= 5
+
 .include <minix.service.mk>
index 2a259e42aae584805c118921a0214748f13e8424..1aedde49980c286b96b7e36c6e487f73e50b64ff 100644 (file)
@@ -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),
index 19b9952871c9cc513c6811ff8de65bff4270d71e..0f6372e9489f21952c58fcf547e0fb9edb2f7921 100644 (file)
@@ -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;
 
 /*
index 9650f69aa090d7479e3ff620e25185984f5894e3..d4861ac106237b602909bccd316ccd21d70e9e1e 100644 (file)
@@ -11,4 +11,6 @@ LDADD+=       -lnetdriver -lsys
 
 CPPFLAGS+=     -I${NETBSDSRCDIR}/minix
 
+WARNS?= 5
+
 .include <minix.service.mk>
index 47c7bcab9f1a907ab9028982d701a5c5aad5a76e..e59e2155b3c2c45291e7ed32f491281a342852dd 100644 (file)
@@ -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;
index 9901125404f2249a0905043765f4131fc77b8bf4..b718ac40d71112ba663d4b8e2ef05fd307144d6b 100644 (file)
@@ -9,4 +9,6 @@ FILESDIR= /etc/system.conf.d
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS} ${LIBVIRTIO}
 LDADD+=        -lnetdriver -lsys -lvirtio
 
+WARNS?= 5
+
 .include <minix.service.mk>
index 9ba7313a4c24d1b78d0b30065d6b004455b9310b..5f2dd679e42e25cfe64588f6fb316a7a74fc8712 100644 (file)
 #include <assert.h>
 #include <sys/types.h>
 
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
-
 #include <minix/drivers.h>
 #include <minix/netdriver.h>
-#include <minix/sysutil.h>
 #include <minix/virtio.h>
 
 #include <sys/queue.h>
@@ -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;
 }
 
 /*
index 92b89d0cf095e6a37444dfc5c5a7f3956be49f08..58e97c2798f9955ba4c2a333fad3284e63122621 100644 (file)
@@ -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--;
 
index c804c4a8825514081ef5ec075bc80c5f823278e8..286acdd5021e8a6d46953f03a14631c3c452451a 100644 (file)
@@ -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
index f43d01856df72fbd56a1f4db4dfa33d87a19999f..0cef8fdefe3262d4c10a65796c06e0ca213041c1 100644 (file)
@@ -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.
  */
 #  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                      *
  *===========================================================================*/
index e8c944b6bace8087d34174b2eb6b6b07c2bd00de..74e1185439bb94a70e2480f645b9075911c44492 100644 (file)
@@ -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 */
index 43b3fbc139b072bb3f45bb8266fe6b0e1d900d3b..2ab957fcd6b39bbd8fc8a308142fd47b98113b2d 100644 (file)
  */
 #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 */
index 6ca59a3f5d3f0314079c83bf424b5d150537ca3f..fab92f976130377df0f049e759b49796553b1f5d 100644 (file)
@@ -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;
index 693855838bb01f7ea1af8ee78ca15ba0c93ab53d..a4cee50adfaf651dd1282abfbb7b2f95cb3dba1f 100644 (file)
@@ -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 <minix/config.h>
 #include <minix/endpoint.h>
 #include <minix/ipc.h>
 #include <minix/com.h>
 
-/* 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 <net/gen/ether.h>
-#include <net/gen/eth_io.h>
+#include <net/if_media.h>
 
 /* 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 */
index bd976f80950ca1ba9e27f90e0741bcd15c77b739..dc259949d2beee8ace8321929e4f1c7000ebd07b 100644 (file)
@@ -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);
index 1549d44cc20bf0e2ddceab634e160c497c2d8825..a3c9584d1b672dafaa80b0bf0b51346aa2c1ed26 100644 (file)
@@ -6,4 +6,6 @@ LIB=    netdriver
 
 SRCS=  netdriver.c portio.c
 
+WARNS?=        5
+
 .include <bsd.lib.mk>
index 9cf12e006e033566aa0802ed826d50fde640ddaa..a42db2edfe1815e7cd255df87ee148361606f43e 100644 (file)
@@ -1,32 +1,60 @@
 /* The device-independent network driver framework. */
 
 #include <minix/drivers.h>
-#include <minix/endpoint.h>
 #include <minix/netdriver.h>
 #include <minix/ds.h>
 #include <assert.h>
 
 #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)
index 24b9c5cc000040cf16ee322a2b23768fb91fb192..fae9739f688a5b4d37954e219bc490a1217dfab5 100644 (file)
@@ -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,
index e8702051ca031bc7e65a23e8ab832b48550f9305..bff698453454b116a5f1382d1c3147a00a41d6e2 100644 (file)
@@ -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 (file)
index e1cf283..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "sysutil.h"
-#include <stdlib.h>
-#include <string.h>
-
-/*=========================================================================*
- *                             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);
-}
-