diff options
author | imp <imp@FreeBSD.org> | 2002-11-27 06:56:29 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2002-11-27 06:56:29 +0000 |
commit | 7fba790820da57f694d05dd3433422165bcc78e5 (patch) | |
tree | 6367d5bd430a1f97e9f089ae24f95874017b90e9 | |
parent | 5a806bdbdee9e13bd51cc934d44461cb417c21ba (diff) | |
download | FreeBSD-src-7fba790820da57f694d05dd3433422165bcc78e5.zip FreeBSD-src-7fba790820da57f694d05dd3433422165bcc78e5.tar.gz |
Implement PCI_IVAR_ETHADDR. Cardbus has the MAC addr in the CIS,
sometimes, so return it when requested and it does. Also a little
more infrastructure for a few other things.
Submitted by: sam
Approved by: re (blanket for NEWCARD)
-rw-r--r-- | sys/dev/cardbus/cardbus.c | 12 | ||||
-rw-r--r-- | sys/dev/cardbus/cardbus_cis.c | 67 | ||||
-rw-r--r-- | sys/dev/cardbus/cardbus_cis.h | 5 | ||||
-rw-r--r-- | sys/dev/cardbus/cardbusvar.h | 16 |
4 files changed, 97 insertions, 3 deletions
diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c index 35f7a7e..3b81861 100644 --- a/sys/dev/cardbus/cardbus.c +++ b/sys/dev/cardbus/cardbus.c @@ -946,6 +946,17 @@ cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result) cfg = &dinfo->pci.cfg; switch (which) { + case PCI_IVAR_ETHADDR: + /* + * The generic accessor doesn't deal with failure, so + * we set the return value, then return an error. + */ + if (dinfo->fepresent & (1<<TPL_FUNCE_LAN_NID) == 0) { + *((u_int8_t **) result) = NULL; + return (EINVAL); + } + *((u_int8_t **) result) = dinfo->funce.lan.nid; + break; case PCI_IVAR_SUBVENDOR: *result = cfg->subvendor; break; @@ -1004,6 +1015,7 @@ cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value) cfg = &dinfo->pci.cfg; switch (which) { + case PCI_IVAR_ETHADDR: case PCI_IVAR_SUBVENDOR: case PCI_IVAR_SUBDEVICE: case PCI_IVAR_VENDOR: diff --git a/sys/dev/cardbus/cardbus_cis.c b/sys/dev/cardbus/cardbus_cis.c index 20b0d33..7c7712a 100644 --- a/sys/dev/cardbus/cardbus_cis.c +++ b/sys/dev/cardbus/cardbus_cis.c @@ -211,6 +211,7 @@ DECODE_PROTOTYPE(linktarget) DECODE_PROTOTYPE(vers_1) { int i; + printf("Product version: %d.%d\n", tupledata[0], tupledata[1]); printf("Product name: "); for (i = 2; i < len; i++) { @@ -227,8 +228,9 @@ DECODE_PROTOTYPE(vers_1) DECODE_PROTOTYPE(funcid) { - int i; + struct cardbus_devinfo *dinfo = device_get_ivars(child); int numnames = sizeof(funcnames) / sizeof(funcnames[0]); + int i; printf("Functions: "); for (i = 0; i < len; i++) { @@ -239,27 +241,88 @@ DECODE_PROTOTYPE(funcid) if (i < len-1) printf(", "); } + + if (len > 0) + dinfo->funcid = tupledata[0]; /* use first in list */ printf("\n"); return (0); } DECODE_PROTOTYPE(manfid) { + struct cardbus_devinfo *dinfo = device_get_ivars(child); int i; + printf("Manufacturer ID: "); for (i = 0; i < len; i++) printf("%02x", tupledata[i]); printf("\n"); + + if (len == 5) { + dinfo->mfrid = tupledata[1] | (tupledata[2]<<8); + dinfo->prodid = tupledata[3] | (tupledata[4]<<8); + } return (0); } DECODE_PROTOTYPE(funce) { - int i; + struct cardbus_devinfo *dinfo = device_get_ivars(child); + int type, i; + printf("Function Extension: "); for (i = 0; i < len; i++) printf("%02x", tupledata[i]); printf("\n"); + if (len < 2) /* too short */ + return (0); + type = tupledata[0]; /* XXX <32 always? */ + switch (dinfo->funcid) { + case TPL_FUNC_SERIAL: + if (type == TPL_FUNCE_SER_UART) { /* NB: len known > 1 */ + dinfo->funce.sio.type = tupledata[1] & 0x1f; + } + dinfo->fepresent |= 1<<type; + break; + case TPL_FUNC_LAN: + switch (type) { + case TPL_FUNCE_LAN_TECH: + dinfo->funce.lan.tech = tupledata[1]; /* XXX mask? */ + break; +#if 0 + case TPL_FUNCE_LAN_SPEED: + for (i = 0; i < 3; i++) { + if (dinfo->funce.lan.speed[i] == 0) { + if (len > 4) { + dinfo->funce.lan.speed[i] = + ...; + } + break; + } + } + break; +#endif + case TPL_FUNCE_LAN_MEDIA: + for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) { + if (dinfo->funce.lan.media[i] == 0) { + /* NB: len known > 1 */ + dinfo->funce.lan.media[i] = + tupledata[1]; /*XXX? mask */ + break; + } + } + break; + case TPL_FUNCE_LAN_NID: + if (len > 6) + bcopy(&tupledata[1], dinfo->funce.lan.nid, 6); + break; + case TPL_FUNCE_LAN_CONN: + dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */ + break; + } + dinfo->fepresent |= 1<<type; + break; + } return (0); } diff --git a/sys/dev/cardbus/cardbus_cis.h b/sys/dev/cardbus/cardbus_cis.h index 36df335..5796a81 100644 --- a/sys/dev/cardbus/cardbus_cis.h +++ b/sys/dev/cardbus/cardbus_cis.h @@ -106,6 +106,9 @@ void cardbus_cis_free(device_t, struct cis_tupleinfo*, int*); /* TPL_FUNC_LAN */ #define TPL_FUNCE_LAN_TECH 1 /* technology */ #define TPL_FUNCE_LAN_SPEED 2 /* speed */ -#define TPL_FUNCE_LAN_MEDIA 2 /* which media do you use? */ +#define TPL_FUNCE_LAN_MEDIA 3 /* which media do you use? */ #define TPL_FUNCE_LAN_NID 4 /* node id (address) */ #define TPL_FUNCE_LAN_CONN 5 /* connector type (shape) */ + +/* TPL_FUNC_SERIAL */ +#define TPL_FUNCE_SER_UART 0 /* UART type */ diff --git a/sys/dev/cardbus/cardbusvar.h b/sys/dev/cardbus/cardbusvar.h index 4c13eb2..76a98a5 100644 --- a/sys/dev/cardbus/cardbusvar.h +++ b/sys/dev/cardbus/cardbusvar.h @@ -37,4 +37,20 @@ struct cardbus_devinfo { u_int8_t mbelow1mb; /* bit mask of BARs which require below 1Mb */ u_int8_t ibelow1mb; /* bit mask of BARs which require below 1Mb */ #define BARBIT(RID) (1<<(((RID)-CARDBUS_BASE0_REG)/4)) + u_int16_t mfrid; /* manufacturer id */ + u_int16_t prodid; /* product id */ + u_int funcid; /* function id */ + union { + struct { + u_int type; /* UART type */ + } sio; + struct { + u_int8_t nid[6]; /* MAC address */ + u_int8_t tech; /* technology */ + u_int8_t contype; /* connector type */ + u_int32_t speed[3]; /* available speeds */ + u_int8_t media[4]; /* media types */ + } lan; + } funce; + u_int32_t fepresent; /* bit mask of funce values present */ }; |