diff options
-rw-r--r-- | sys/dev/dc/if_dc.c | 35 | ||||
-rw-r--r-- | sys/dev/dc/if_dcreg.h | 14 | ||||
-rw-r--r-- | sys/pci/if_dc.c | 35 | ||||
-rw-r--r-- | sys/pci/if_dcreg.h | 14 |
4 files changed, 74 insertions, 24 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index 4e284d3..6032703 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -1705,20 +1705,37 @@ dc_decode_leaf_sia(struct dc_softc *sc, struct dc_eblock_sia *l) struct dc_mediainfo *m; m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT | M_ZERO); - if (l->dc_sia_code == DC_SIA_CODE_10BT) + switch (l->dc_sia_code & ~DC_SIA_CODE_EXT) { + case DC_SIA_CODE_10BT: m->dc_media = IFM_10_T; - - if (l->dc_sia_code == DC_SIA_CODE_10BT_FDX) + break; + case DC_SIA_CODE_10BT_FDX: m->dc_media = IFM_10_T | IFM_FDX; - - if (l->dc_sia_code == DC_SIA_CODE_10B2) + break; + case DC_SIA_CODE_10B2: m->dc_media = IFM_10_2; - - if (l->dc_sia_code == DC_SIA_CODE_10B5) + break; + case DC_SIA_CODE_10B5: m->dc_media = IFM_10_5; + break; + default: + break; + } - m->dc_gp_len = 2; - m->dc_gp_ptr = (u_int8_t *)&l->dc_sia_gpio_ctl; + /* + * We need to ignore CSR13, CSR14, CSR15 for SIA mode. + * Things apparently already work for cards that do + * supply Media Specific Data. + */ + if (l->dc_sia_code & DC_SIA_CODE_EXT) { + m->dc_gp_len = 2; + m->dc_gp_ptr = + (u_int8_t *)&l->dc_un.dc_sia_ext.dc_sia_gpio_ctl; + } else { + m->dc_gp_len = 2; + m->dc_gp_ptr = + (u_int8_t *)&l->dc_un.dc_sia_noext.dc_sia_gpio_ctl; + } m->dc_next = sc->dc_mi; sc->dc_mi = m; diff --git a/sys/dev/dc/if_dcreg.h b/sys/dev/dc/if_dcreg.h index 204b1d1..14912b5 100644 --- a/sys/dev/dc/if_dcreg.h +++ b/sys/dev/dc/if_dcreg.h @@ -1171,9 +1171,17 @@ struct dc_eblock_hdr { struct dc_eblock_sia { struct dc_eblock_hdr dc_sia_hdr; u_int8_t dc_sia_code; - u_int8_t dc_sia_mediaspec[6]; /* CSR13, CSR14, CSR15 */ - u_int8_t dc_sia_gpio_ctl[2]; - u_int8_t dc_sia_gpio_dat[2]; + union { + struct dc_sia_ext { /* if (dc_sia_code & DC_SIA_CODE_EXT) */ + u_int8_t dc_sia_mediaspec[6]; /* CSR13, CSR14, CSR15 */ + u_int8_t dc_sia_gpio_ctl[2]; + u_int8_t dc_sia_gpio_dat[2]; + } dc_sia_ext; + struct dc_sia_noext { + u_int8_t dc_sia_gpio_ctl[2]; + u_int8_t dc_sia_gpio_dat[2]; + } dc_sia_noext; + } dc_un; }; #define DC_SIA_CODE_10BT 0x00 diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c index 4e284d3..6032703 100644 --- a/sys/pci/if_dc.c +++ b/sys/pci/if_dc.c @@ -1705,20 +1705,37 @@ dc_decode_leaf_sia(struct dc_softc *sc, struct dc_eblock_sia *l) struct dc_mediainfo *m; m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT | M_ZERO); - if (l->dc_sia_code == DC_SIA_CODE_10BT) + switch (l->dc_sia_code & ~DC_SIA_CODE_EXT) { + case DC_SIA_CODE_10BT: m->dc_media = IFM_10_T; - - if (l->dc_sia_code == DC_SIA_CODE_10BT_FDX) + break; + case DC_SIA_CODE_10BT_FDX: m->dc_media = IFM_10_T | IFM_FDX; - - if (l->dc_sia_code == DC_SIA_CODE_10B2) + break; + case DC_SIA_CODE_10B2: m->dc_media = IFM_10_2; - - if (l->dc_sia_code == DC_SIA_CODE_10B5) + break; + case DC_SIA_CODE_10B5: m->dc_media = IFM_10_5; + break; + default: + break; + } - m->dc_gp_len = 2; - m->dc_gp_ptr = (u_int8_t *)&l->dc_sia_gpio_ctl; + /* + * We need to ignore CSR13, CSR14, CSR15 for SIA mode. + * Things apparently already work for cards that do + * supply Media Specific Data. + */ + if (l->dc_sia_code & DC_SIA_CODE_EXT) { + m->dc_gp_len = 2; + m->dc_gp_ptr = + (u_int8_t *)&l->dc_un.dc_sia_ext.dc_sia_gpio_ctl; + } else { + m->dc_gp_len = 2; + m->dc_gp_ptr = + (u_int8_t *)&l->dc_un.dc_sia_noext.dc_sia_gpio_ctl; + } m->dc_next = sc->dc_mi; sc->dc_mi = m; diff --git a/sys/pci/if_dcreg.h b/sys/pci/if_dcreg.h index 204b1d1..14912b5 100644 --- a/sys/pci/if_dcreg.h +++ b/sys/pci/if_dcreg.h @@ -1171,9 +1171,17 @@ struct dc_eblock_hdr { struct dc_eblock_sia { struct dc_eblock_hdr dc_sia_hdr; u_int8_t dc_sia_code; - u_int8_t dc_sia_mediaspec[6]; /* CSR13, CSR14, CSR15 */ - u_int8_t dc_sia_gpio_ctl[2]; - u_int8_t dc_sia_gpio_dat[2]; + union { + struct dc_sia_ext { /* if (dc_sia_code & DC_SIA_CODE_EXT) */ + u_int8_t dc_sia_mediaspec[6]; /* CSR13, CSR14, CSR15 */ + u_int8_t dc_sia_gpio_ctl[2]; + u_int8_t dc_sia_gpio_dat[2]; + } dc_sia_ext; + struct dc_sia_noext { + u_int8_t dc_sia_gpio_ctl[2]; + u_int8_t dc_sia_gpio_dat[2]; + } dc_sia_noext; + } dc_un; }; #define DC_SIA_CODE_10BT 0x00 |