summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2002-11-27 06:56:29 +0000
committerimp <imp@FreeBSD.org>2002-11-27 06:56:29 +0000
commit7fba790820da57f694d05dd3433422165bcc78e5 (patch)
tree6367d5bd430a1f97e9f089ae24f95874017b90e9
parent5a806bdbdee9e13bd51cc934d44461cb417c21ba (diff)
downloadFreeBSD-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.c12
-rw-r--r--sys/dev/cardbus/cardbus_cis.c67
-rw-r--r--sys/dev/cardbus/cardbus_cis.h5
-rw-r--r--sys/dev/cardbus/cardbusvar.h16
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 */
};
OpenPOWER on IntegriCloud