Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pcmcia Improve the model identification and match. ...
details: https://anonhg.NetBSD.org/src/rev/82d5d0e3c705
branches: trunk
changeset: 495251:82d5d0e3c705
user: gmcgarry <gmcgarry%NetBSD.org@localhost>
date: Mon Jul 24 21:50:10 2000 +0000
description:
Improve the model identification and match. Addresses PR-10485.
diffstat:
sys/dev/pcmcia/if_xi.c | 151 ++++++++++++++++++++++++++++++++++++------------
1 files changed, 111 insertions(+), 40 deletions(-)
diffs (truncated from 332 to 300 lines):
diff -r ea6708b54968 -r 82d5d0e3c705 sys/dev/pcmcia/if_xi.c
--- a/sys/dev/pcmcia/if_xi.c Mon Jul 24 21:47:40 2000 +0000
+++ b/sys/dev/pcmcia/if_xi.c Mon Jul 24 21:50:10 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_xi.c,v 1.2 2000/06/09 08:22:13 gmcgarry Exp $ */
+/* $NetBSD: if_xi.c,v 1.3 2000/07/24 21:50:10 gmcgarry Exp $ */
/* OpenBSD: if_xe.c,v 1.9 1999/09/16 11:28:42 niklas Exp */
/*
@@ -185,6 +185,7 @@
static void xi_mediastatus __P((struct ifnet *, struct ifmediareq *));
static int xi_pcmcia_funce_enaddr __P((struct device *, u_int8_t *));
static int xi_pcmcia_lan_nid_ciscallback __P((struct pcmcia_tuple *, void *));
+static int xi_pcmcia_manfid_ciscallback __P((struct pcmcia_tuple *, void *));
static u_int16_t xi_get __P((struct xi_softc *));
static void xi_reset __P((struct xi_softc *));
static void xi_set_address __P((struct xi_softc *));
@@ -192,11 +193,13 @@
static void xi_statchg __P((struct device *));
static void xi_stop __P((struct xi_softc *));
static void xi_watchdog __P((struct ifnet *));
+struct xi_pcmcia_product *xi_pcmcia_identify __P((struct device *,
+ struct pcmcia_attach_args *));
/* flags */
-#define XI_FLAGS_MOHAWK 0x001 /* 100Mb capabilities (has phy) */
-#define XI_FLAGS_DINGO 0x002 /* realport cards ??? */
-#define XI_FLAGS_MODEM 0x004 /* modem also present */
+#define XIFLAGS_MOHAWK 0x001 /* 100Mb capabilities (has phy) */
+#define XIFLAGS_DINGO 0x002 /* realport cards ??? */
+#define XIFLAGS_MODEM 0x004 /* modem also present */
struct xi_pcmcia_product {
u_int32_t xpp_vendor; /* vendor ID */
@@ -206,44 +209,78 @@
const char *xpp_name; /* device name */
} xi_pcmcia_products[] = {
#ifdef NOT_SUPPORTED
- { PCMCIA_VENDOR_XIRCOM, PCMCIA_PRODUCT_XIRCOM_CE,
+ { PCMCIA_VENDOR_XIRCOM, 0x0141,
0, 0,
PCMCIA_STR_XIRCOM_CE },
#endif
- { PCMCIA_VENDOR_XIRCOM, PCMCIA_PRODUCT_XIRCOM_CE2,
+ { PCMCIA_VENDOR_XIRCOM, 0x0141,
+ 0, 0,
+ PCMCIA_STR_XIRCOM_CE2 },
+ { PCMCIA_VENDOR_XIRCOM, 0x0142,
0, 0,
PCMCIA_STR_XIRCOM_CE2 },
- { PCMCIA_VENDOR_XIRCOM, PCMCIA_PRODUCT_XIRCOM_CE3,
- 0, XI_FLAGS_MOHAWK,
+ { PCMCIA_VENDOR_XIRCOM, 0x0143,
+ 0, XIFLAGS_MOHAWK,
PCMCIA_STR_XIRCOM_CE3 },
- { PCMCIA_VENDOR_COMPAQ2, PCMCIA_PRODUCT_COMPAQ2_CPQ_10_100,
- 0, XI_FLAGS_MOHAWK,
+ { PCMCIA_VENDOR_COMPAQ2, 0x0143,
+ 0, XIFLAGS_MOHAWK,
PCMCIA_STR_COMPAQ2_CPQ_10_100 },
- { PCMCIA_VENDOR_INTEL, PCMCIA_PRODUCT_INTEL_EEPRO100,
- 0, XI_FLAGS_MOHAWK | XI_FLAGS_MODEM,
+ { PCMCIA_VENDOR_INTEL, 0x0143,
+ 0, XIFLAGS_MOHAWK | XIFLAGS_MODEM,
PCMCIA_STR_INTEL_EEPRO100 },
- { PCMCIA_VENDOR_XIRCOM, PCMCIA_PRODUCT_XIRCOM_CEM,
- 0, XI_FLAGS_MODEM,
+#ifdef NOT_SUPPORTED
+ { PCMCIA_VENDOR_XIRCOM, 0x1141,
+ 0, XIFLAGS_MODEM,
+ PCMCIA_STR_XIRCOM_CEM },
+#endif
+ { PCMCIA_VENDOR_XIRCOM, 0x1142,
+ 0, XIFLAGS_MODEM,
+ PCMCIA_STR_XIRCOM_CEM },
+ { PCMCIA_VENDOR_XIRCOM, 0x1143,
+ 0, XIFLAGS_MODEM,
PCMCIA_STR_XIRCOM_CEM },
- { PCMCIA_VENDOR_XIRCOM, PCMCIA_PRODUCT_XIRCOM_CEM28,
- 0, XI_FLAGS_MODEM,
- PCMCIA_STR_XIRCOM_CEM28 },
+ { PCMCIA_VENDOR_XIRCOM, 0x1144,
+ 0, XIFLAGS_MODEM,
+ PCMCIA_STR_XIRCOM_CEM33 },
+ { PCMCIA_VENDOR_XIRCOM, 0x1145,
+ 0, XIFLAGS_MOHAWK | XIFLAGS_MODEM,
+ PCMCIA_STR_XIRCOM_CEM56 },
+ { PCMCIA_VENDOR_XIRCOM, 0x1146,
+ 0, XIFLAGS_MOHAWK | XIFLAGS_DINGO | XIFLAGS_MODEM,
+ PCMCIA_STR_XIRCOM_REM56 },
+ { PCMCIA_VENDOR_XIRCOM, 0x1147,
+ 0, XIFLAGS_MOHAWK | XIFLAGS_DINGO | XIFLAGS_MODEM,
+ PCMCIA_STR_XIRCOM_REM56 },
{ 0, 0,
0, 0,
NULL },
};
-struct xi_pcmcia_product *xi_pcmcia_lookup __P((struct pcmcia_attach_args *));
struct xi_pcmcia_product *
-xi_pcmcia_lookup(pa)
+xi_pcmcia_identify(dev, pa)
+ struct device *dev;
struct pcmcia_attach_args *pa;
{
struct xi_pcmcia_product *xpp;
+ u_int8_t id;
+ u_int32_t prod;
+
+ /*
+ * The Xircom ethernet cards swap the revision and product fields
+ * inside the CIS, which makes identification just a little
+ * bit different.
+ */
+
+ pcmcia_scan_cis(dev, xi_pcmcia_manfid_ciscallback, &id);
+
+ prod = (pa->product & ~0xff) | id;
+
+ DPRINTF(XIDEBUG_CONFIG, ("product=0x%x\n", prod));
for (xpp = xi_pcmcia_products; xpp->xpp_name != NULL; xpp++)
if (pa->manufacturer == xpp->xpp_vendor &&
- pa->product == xpp->xpp_product &&
+ prod == xpp->xpp_product &&
pa->pf->number == xpp->xpp_expfunc)
return (xpp);
return (NULL);
@@ -298,8 +335,19 @@
if (pa->pf->function != PCMCIA_FUNCTION_NETWORK)
return (0);
- if (xi_pcmcia_lookup(pa) != NULL)
+ if (pa->manufacturer == PCMCIA_VENDOR_COMPAQ2 &&
+ pa->product == PCMCIA_PRODUCT_COMPAQ2_CPQ_10_100)
+ return (1);
+
+ if (pa->manufacturer == PCMCIA_VENDOR_INTEL &&
+ pa->product == PCMCIA_PRODUCT_INTEL_EEPRO100)
return (1);
+
+ if (pa->manufacturer == PCMCIA_VENDOR_XIRCOM &&
+ ((pa->product >> 8) == XIMEDIA_ETHER ||
+ (pa->product >> 8) == (XIMEDIA_ETHER | XIMEDIA_MODEM)))
+ return (1);
+
return (0);
}
@@ -344,9 +392,11 @@
sc->sc_offset = 0;
psc->sc_resource |= XI_RES_IO;
- xpp = xi_pcmcia_lookup(pa);
- if (xpp == NULL)
- panic("xi_pcmcia_attach: impossible");
+ xpp = xi_pcmcia_identify(parent,pa);
+ if (xpp == NULL) {
+ printf(": unrecognised model\n");
+ return;
+ }
sc->sc_flags = xpp->xpp_flags;
printf(": %s\n", xpp->xpp_name);
@@ -355,7 +405,7 @@
* Configuration as adviced by DINGO documentation.
* Dingo has some extra configuration registers in the CCR space.
*/
- if (sc->sc_flags & XI_FLAGS_DINGO) {
+ if (sc->sc_flags & XIFLAGS_DINGO) {
struct pcmcia_mem_handle pcmh;
int ccr_window;
bus_addr_t ccr_offset;
@@ -452,7 +502,7 @@
* time. The ugly media tickling seems to be necessary for getting
* autonegotiation to work too.
*/
- if (sc->sc_flags & XI_FLAGS_DINGO) {
+ if (sc->sc_flags & XIFLAGS_DINGO) {
xi_full_reset(sc);
xi_init(sc);
ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
@@ -615,6 +665,27 @@
return (0);
}
+int
+xi_pcmcia_manfid_ciscallback(tuple, arg)
+ struct pcmcia_tuple *tuple;
+ void *arg;
+{
+ u_int8_t *id = arg;
+
+ DPRINTF(XID_CONFIG, ("xi_pcmcia_manfid_callback()\n"));
+
+ if (tuple->code != PCMCIA_CISTPL_MANFID)
+ return (0);
+
+ if (tuple->length < 2)
+ return (0);
+
+ *id = pcmcia_tuple_read_1(tuple, 4);
+ return (1);
+}
+
+
+
static int
xi_intr(arg)
void *arg;
@@ -633,7 +704,7 @@
ifp->if_timer = 0; /* turn watchdog timer off */
- if (sc->sc_flags & XI_FLAGS_MOHAWK) {
+ if (sc->sc_flags & XIFLAGS_MOHAWK) {
/* Disable interrupt (Linux does it). */
bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
0);
@@ -1160,7 +1231,7 @@
MFREE(m, m0);
m = m0;
}
- if (sc->sc_flags & XI_FLAGS_MOHAWK)
+ if (sc->sc_flags & XIFLAGS_MOHAWK)
bus_space_write_1(bst, bsh, offset + CR, TX_PKT | ENABLE_INT);
else {
for (; pad > 1; pad -= 2)
@@ -1335,7 +1406,7 @@
PAGE(sc, 0x50);
for (i = 0; i < 6; i++) {
bus_space_write_1(bst, bsh, offset + IA + i,
- sc->sc_enaddr[(sc->sc_flags & XI_FLAGS_MOHAWK) ? 5-i : i]);
+ sc->sc_enaddr[(sc->sc_flags & XIFLAGS_MOHAWK) ? 5-i : i]);
}
if (ether->ec_multicnt > 0) {
@@ -1367,7 +1438,7 @@
for (i = 0; i < 6; i++) {
bus_space_write_1(bst, bsh, offset + pos,
enm->enm_addrlo[
- (sc->sc_flags & XI_FLAGS_MOHAWK) ? 5-i : i]);
+ (sc->sc_flags & XIFLAGS_MOHAWK) ? 5-i : i]);
if (++pos > 15) {
pos = IA;
@@ -1393,7 +1464,7 @@
DELAY(1);
bus_space_write_1(bst, bsh, offset + GP1, 0);
DELAY(40000);
- if (sc->sc_flags & XI_FLAGS_MOHAWK)
+ if (sc->sc_flags & XIFLAGS_MOHAWK)
bus_space_write_1(bst, bsh, offset + GP1, POWER_UP);
else
/* XXX What is bit 2 (aka AIC)? */
@@ -1417,7 +1488,7 @@
DELAY(20000);
bus_space_write_1(bst, bsh, offset + CR, 0);
DELAY(20000);
- if (sc->sc_flags & XI_FLAGS_MOHAWK) {
+ if (sc->sc_flags & XIFLAGS_MOHAWK) {
PAGE(sc, 4);
/*
* Drive GP1 low to power up ML6692 and GP2 high to power up
@@ -1430,10 +1501,10 @@
/* Get revision information. XXX Symbolic constants. */
sc->sc_rev = bus_space_read_1(bst, bsh, offset + BV) &
- ((sc->sc_flags & XI_FLAGS_MOHAWK) ? 0x70 : 0x30) >> 4;
+ ((sc->sc_flags & XIFLAGS_MOHAWK) ? 0x70 : 0x30) >> 4;
/* Media selection. XXX Maybe manual overriding too? */
- if (!(sc->sc_flags & XI_FLAGS_MOHAWK)) {
+ if (!(sc->sc_flags & XIFLAGS_MOHAWK)) {
PAGE(sc, 4);
/*
* XXX I have no idea what this really does, it is from the
@@ -1451,7 +1522,7 @@
#if 0
bus_space_write_1(bst, bsh, offset + IMR0, 0xff);
#endif
- if (!(sc->sc_flags & XI_FLAGS_DINGO)) {
+ if (!(sc->sc_flags & XIFLAGS_DINGO)) {
/* XXX What is this? Not for Dingo at least. */
bus_space_write_1(bst, bsh, offset + IMR1, 1);
}
@@ -1460,7 +1531,7 @@
* Disable source insertion.
* XXX Dingo does not have this bit, but Linux does it unconditionally.
*/
- if (!(sc->sc_flags & XI_FLAGS_DINGO)) {
+ if (!(sc->sc_flags & XIFLAGS_DINGO)) {
PAGE(sc, 0x42);
bus_space_write_1(bst, bsh, offset + SWC0, 0x20);
}
@@ -1488,7 +1559,7 @@
bus_space_write_1(bst, bsh, offset + TX0MSK,
CARRIER_LOST | EXCESSIVE_COLL | TX_UNDERRUN | LATE_COLLISION |
SQE | TX_ABORT | TX_OK);
Home |
Main Index |
Thread Index |
Old Index