summaryrefslogtreecommitdiff
path: root/sys/dev/fe
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2005-10-25 03:49:24 +0000
committerWarner Losh <imp@FreeBSD.org>2005-10-25 03:49:24 +0000
commit2a0146bdf122c1c55793f6490d24367d35c39a9e (patch)
tree4a3939b5412d94ff287d2f489a12be97b08a0191 /sys/dev/fe
parent9fc171584d598ff2a1985d6c43de7aaab33720fe (diff)
Notes
Diffstat (limited to 'sys/dev/fe')
-rw-r--r--sys/dev/fe/if_fe_pccard.c68
1 files changed, 55 insertions, 13 deletions
diff --git a/sys/dev/fe/if_fe_pccard.c b/sys/dev/fe/if_fe_pccard.c
index 86526e768f61..00b1fa4d0d8a 100644
--- a/sys/dev/fe/if_fe_pccard.c
+++ b/sys/dev/fe/if_fe_pccard.c
@@ -64,6 +64,7 @@ static const struct fe_pccard_product {
struct pccard_product mpp_product;
int mpp_flags;
#define MPP_MBH10302 1
+#define MPP_ANYFUNC 2
} fe_pccard_products[] = {
/* These need to be first */
{ PCMCIA_CARD(FUJITSU2, FMV_J181), MPP_MBH10302 },
@@ -81,31 +82,32 @@ static const struct fe_pccard_product {
{ PCMCIA_CARD(FUJITSU, LA10S), 0 },
{ PCMCIA_CARD(FUJITSU, NE200T), MPP_MBH10302 },/* Sold by Eagle */
{ PCMCIA_CARD(RATOC, REX_R280), 0 },
+ { PCMCIA_CARD(XIRCOM, CE), MPP_ANYFUNC },
{ { NULL } }
};
static int
fe_pccard_probe(device_t dev)
{
- const struct pccard_product *pp;
int error;
uint32_t fcn = PCCARD_FUNCTION_UNSPEC;
+ const struct fe_pccard_product *pp;
- /* Make sure we're a network function */
- error = pccard_get_function(dev, &fcn);
- if (error != 0)
- return (error);
- if (fcn != PCCARD_FUNCTION_NETWORK)
- return (ENXIO);
-
- if ((pp = pccard_product_lookup(dev,
+ if ((pp = (const struct fe_pccard_product *)pccard_product_lookup(dev,
(const struct pccard_product *)fe_pccard_products,
sizeof(fe_pccard_products[0]), NULL)) != NULL) {
- if (pp->pp_name != NULL)
- device_set_desc(dev, pp->pp_name);
- return 0;
+ if (pp->mpp_product.pp_name != NULL)
+ device_set_desc(dev, pp->mpp_product.pp_name);
+ if (pp->mpp_flags & MPP_ANYFUNC)
+ return (0);
+ /* Make sure we're a network function */
+ error = pccard_get_function(dev, &fcn);
+ if (error != 0)
+ return (error);
+ if (fcn != PCCARD_FUNCTION_NETWORK)
+ return (ENXIO);
}
- return EIO;
+ return (ENXIO);
}
static device_method_t fe_pccard_methods[] = {
@@ -248,6 +250,40 @@ fe_probe_mbh(device_t dev, const struct fe_pccard_product *pp)
return 0;
}
+static int
+sn_pccard_xircom_mac(const struct pccard_tuple *tuple, void *argp)
+{
+ uint8_t *enaddr = argp;
+ int i;
+
+#if 1
+ /*
+ * We fail to map the CIS twice, for reasons unknown. We
+ * may fix this in the future by loading the CIS with a sane
+ * CIS from userland.
+ */
+ static uint8_t defaultmac[ETHER_ADDR_LEN] = {
+ 0x00, 0x80, 0xc7, 0xed, 0x16, 0x7b};
+
+ /* Copy the MAC ADDR and return success */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ enaddr[i] = defaultmac[i];
+#else
+ /* FUNCE is not after FUNCID, so we gotta go find it */
+ if (tuple->code != 0x22)
+ return (0);
+
+ /* Make sure this is a sane node */
+ if (tuple->length < ETHER_ADDR_LEN + 3)
+ return (0);
+
+ /* Copy the MAC ADDR and return success */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ enaddr[i] = pccard_tuple_read_1(tuple, i + 3);
+#endif
+ return (1);
+}
+
/*
* Probe and initialization for TDK/CONTEC PCMCIA Ethernet interface.
* by MASUI Kenji <masui@cs.titech.ac.jp>
@@ -270,6 +306,7 @@ fe_probe_tdk (device_t dev, const struct fe_pccard_product *pp)
{ 0 }
};
+
/* C-NET(PC)C occupies 16 I/O addresses. */
if (fe_alloc_port(dev, 16))
return ENXIO;
@@ -290,6 +327,11 @@ fe_probe_tdk (device_t dev, const struct fe_pccard_product *pp)
pccard_get_ether(dev, sc->enaddr);
/* Make sure we got a valid station address. */
+ if (!fe_valid_Ether_p(sc->enaddr, 0)) {
+ pccard_cis_scan(dev, sn_pccard_xircom_mac, sc->enaddr);
+ }
+
+ /* Make sure we got a valid station address. */
if (!fe_valid_Ether_p(sc->enaddr, 0))
return ENXIO;