summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/dc/if_dc.c35
-rw-r--r--sys/dev/dc/if_dcreg.h14
-rw-r--r--sys/pci/if_dc.c35
-rw-r--r--sys/pci/if_dcreg.h14
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
OpenPOWER on IntegriCloud