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)
This commit is contained in:
Warner Losh 2002-11-27 06:56:29 +00:00
parent ba5fc4eed2
commit fbe9cff112
4 changed files with 97 additions and 3 deletions

View File

@ -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:

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */
};