Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Snapshot of incomplete-but-working split of re(4) dr...



details:   https://anonhg.NetBSD.org/src/rev/c6fd1a4b5220
branches:  trunk
changeset: 572195:c6fd1a4b5220
user:      jonathan <jonathan%NetBSD.org@localhost>
date:      Thu Dec 23 06:26:30 2004 +0000

description:
Snapshot of incomplete-but-working split of re(4) driver into a
bus-independent backend, with PCI and CardBus attachment code.
The committed code has two serious bugs:

1. The driver makes no attempt to recover resources when a (Cardbus)
instance is removed; bus resources are leaked.

2. In testing with a NetGear GA-511, the Cardbus card never responded
   to a reset/wakeup if the card is powered down after attachment.
   So for now, leave cardbus instances powered up at attachment
   (insertion, or at boot if a card is already present).

That aside, it acutally works on my GA-511. Committed as-is despite
the bugs, after repeated requests to make the code available for
further testing.  Also requires sys/dev/mii/miidevs rev 1.54 -> 1.55,
and consequent regen of miidevs{,_data}.h.

diffstat:

 sys/dev/cardbus/if_re_cardbus.c |   426 +++++++
 sys/dev/ic/rtl8169.c            |  2212 +++++++++++++++++++++++++++++++++++++++
 sys/dev/ic/rtl8169var.h         |    34 +
 sys/dev/mii/rgephy.c            |   557 +++++++++
 sys/dev/mii/rgephyreg.h         |   142 ++
 sys/dev/pci/if_re_pci.c         |   275 ++++
 6 files changed, 3646 insertions(+), 0 deletions(-)

diffs (truncated from 3670 to 300 lines):

diff -r 2906ab19b24b -r c6fd1a4b5220 sys/dev/cardbus/if_re_cardbus.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/cardbus/if_re_cardbus.c   Thu Dec 23 06:26:30 2004 +0000
@@ -0,0 +1,426 @@
+/*     $NetBSD: if_re_cardbus.c,v 1.1 2004/12/23 06:26:30 jonathan Exp $       */
+
+/*
+ * Copyright (c) 2004 Jonathan Stone
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * if_re_cardbus.c:
+ *     Cardbus specific routines for Realtek 8169 ethernet adapter.
+ *     Tested for :
+ *             Netgear GA-511 (8169S)
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: if_re_cardbus.c,v 1.1 2004/12/23 06:26:30 jonathan Exp $");
+
+#include "opt_inet.h"
+#include "opt_ns.h"
+#include "bpfilter.h"
+#include "rnd.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/callout.h>
+#include <sys/device.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_ether.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_inarp.h>
+#endif
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+#if NRND > 0
+#include <sys/rnd.h>
+#endif
+
+#include <machine/bus.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/cardbus/cardbusvar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+/*
+ * Default to using PIO access for this driver. On SMP systems,
+ * there appear to be problems with memory mapped mode: it looks like
+ * doing too many memory mapped access back to back in rapid succession
+ * can hang the bus. I'm inclined to blame this on crummy design/construction
+ * on the part of Realtek. Memory mapped mode does appear to work on
+ * uniprocessor systems though.
+ */
+#define RTK_USEIOSPACE 
+
+#include <dev/ic/rtl81x9reg.h>
+#include <dev/ic/rtl81x9var.h>
+
+#include <dev/ic/rtl8169var.h>
+
+/*
+ * Various supported device vendors/types and their names.
+ */
+static const struct rtk_type re_cardbus_devs[] = {
+       { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169,
+               RTK_8169, "Realtek 10/100/1000baseT" },
+       { 0, 0, 0, NULL }
+};
+
+static int  re_cardbus_match(struct device *, struct cfdata *, void *);
+static void re_cardbus_attach(struct device *, struct device *, void *);
+static int  re_cardbus_detach(struct device *, int);
+
+struct re_cardbus_softc {
+       struct rtk_softc sc_rtk;        /* real rtk softc */ 
+
+       /* CardBus-specific goo. */
+       void *sc_ih;
+       cardbus_devfunc_t sc_ct;
+       cardbustag_t sc_tag;
+       int sc_csr;
+       int sc_cben;
+       int sc_bar_reg;
+       pcireg_t sc_bar_val;
+       bus_size_t sc_mapsize;
+       int sc_intrline;
+};
+
+CFATTACH_DECL(re_cardbus, sizeof(struct re_cardbus_softc),
+    re_cardbus_match, re_cardbus_attach, re_cardbus_detach, re_activate);
+
+const struct rtk_type *re_cardbus_lookup
+       __P((const struct cardbus_attach_args *));
+
+void re_cardbus_setup          __P((struct re_cardbus_softc *));
+
+int re_cardbus_enable          __P((struct rtk_softc *));
+void re_cardbus_disable        __P((struct rtk_softc *));
+void re_cardbus_power          __P((struct rtk_softc *, int));
+
+const struct rtk_type *
+re_cardbus_lookup(ca)
+       const struct cardbus_attach_args *ca;
+{
+       const struct rtk_type *t;
+
+       for (t = re_cardbus_devs; t->rtk_name != NULL; t++) {
+               if (CARDBUS_VENDOR(ca->ca_id) == t->rtk_vid &&
+                   CARDBUS_PRODUCT(ca->ca_id) == t->rtk_did) {
+                       return (t);
+               }
+       }
+       return (NULL);
+}
+
+int
+re_cardbus_match(parent, match, aux)
+       struct device *parent;
+       struct cfdata *match;
+       void *aux;
+{
+       struct cardbus_attach_args *ca = aux;
+
+       if (re_cardbus_lookup(ca) != NULL)
+               return (1);
+
+       return (0);
+}
+
+
+void
+re_cardbus_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct re_cardbus_softc *csc = (struct re_cardbus_softc *)self;
+       struct rtk_softc *sc = &csc->sc_rtk;
+       struct cardbus_attach_args *ca = aux;
+       cardbus_devfunc_t ct = ca->ca_ct;
+       const struct rtk_type *t;
+       bus_addr_t adr;
+
+       sc->sc_dmat = ca->ca_dmat;
+       csc->sc_ct = ct;
+       csc->sc_tag = ca->ca_tag;
+       csc->sc_intrline = ca->ca_intrline;
+
+       t = re_cardbus_lookup(ca); 
+       if (t == NULL) { 
+               printf("\n"); 
+               panic("re_cardbus_attach: impossible");
+        } 
+       printf(": %s\n", t->rtk_name); 
+       
+       /*
+        * Power management hooks.
+        */
+       sc->sc_enable = re_cardbus_enable;
+       sc->sc_disable = re_cardbus_disable;
+       sc->sc_power = re_cardbus_power;
+
+       /*
+        * Map control/status registers.
+        */
+       csc->sc_csr = CARDBUS_COMMAND_MASTER_ENABLE;
+#ifdef RTK_USEIOSPACE
+       if (Cardbus_mapreg_map(ct, RTK_PCI_LOIO, CARDBUS_MAPREG_TYPE_IO, 0,
+           &sc->rtk_btag, &sc->rtk_bhandle, &adr, &csc->sc_mapsize) == 0) {
+#if rbus
+#else
+               (*ct->ct_cf->cardbus_io_open)(cc, 0, adr, adr+csc->sc_mapsize);
+#endif
+               csc->sc_cben = CARDBUS_IO_ENABLE;
+               csc->sc_csr |= CARDBUS_COMMAND_IO_ENABLE;
+               csc->sc_bar_reg = RTK_PCI_LOIO;
+               csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_IO;
+       }
+#else
+       if (Cardbus_mapreg_map(ct, RTK_PCI_LOMEM, CARDBUS_MAPREG_TYPE_MEM, 0,
+           &sc->rtk_btag, &sc->rtk_bhandle, &adr, &csc->sc_mapsize) == 0) {
+#if rbus
+#else
+               (*ct->ct_cf->cardbus_mem_open)(cc, 0, adr, adr+csc->sc_mapsize);
+#endif
+               csc->sc_cben = CARDBUS_MEM_ENABLE;
+               csc->sc_csr |= CARDBUS_COMMAND_MEM_ENABLE;
+               csc->sc_bar_reg = RTK_PCI_LOMEM;
+               csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_MEM;
+       }
+#endif
+       else {
+               printf("%s: unable to map deviceregisters\n",
+                        sc->sc_dev.dv_xname);
+               return;
+       }
+       /*
+        * Handle power management nonsense and initialize the
+        * configuration registers.
+        */
+       re_cardbus_setup(csc);
+
+       sc->rtk_type = t->rtk_basetype;
+       sc->sc_dmat = ca->ca_dmat;
+       re_attach(sc);
+
+#ifdef notyet  /* XXX device times out if we disable, so for now, don't. */
+       /*
+        * Power down the socket.
+        */
+       Cardbus_function_disable(csc->sc_ct);
+#endif /* notyet */
+}
+
+int 
+re_cardbus_detach(struct device *self, int flags)
+{
+       struct re_cardbus_softc *csc = (void *) self;
+       struct rtk_softc *sc = &csc->sc_rtk;
+       struct cardbus_devfunc *ct = csc->sc_ct;
+       int     rv;
+
+#ifdef DIAGNOSTIC
+       if (ct == NULL)
+               panic("%s: cardbus softc, cardbus_devfunc NULL",
+                     sc->sc_dev.dv_xname);
+#endif
+       rv = re_detach(sc);
+       if (rv)
+               return (rv);
+       /*
+        * Unhook the interrupt handler.
+        */
+       if (csc->sc_ih != NULL)
+               cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih);
+       
+       /*
+        * Release bus space and close window.
+        */
+       if (csc->sc_bar_reg != 0)
+               Cardbus_mapreg_unmap(ct, csc->sc_bar_reg,
+                       sc->rtk_btag, sc->rtk_bhandle, csc->sc_mapsize);
+
+       return (0);
+}
+
+void 
+re_cardbus_setup(struct re_cardbus_softc *csc)
+{
+       struct rtk_softc *sc = &csc->sc_rtk;
+       cardbus_devfunc_t ct = csc->sc_ct;
+       cardbus_chipset_tag_t cc = ct->ct_cc;
+       cardbus_function_tag_t cf = ct->ct_cf;
+       pcireg_t        reg,command;
+       int             pmreg;
+
+       /*



Home | Main Index | Thread Index | Old Index