Index: sys/dev/msk/if_msk.c =================================================================== --- sys/dev/msk/if_msk.c (revision 197042) +++ sys/dev/msk/if_msk.c (working copy) @@ -224,7 +224,9 @@ { VENDORID_DLINK, DEVICEID_DLINK_DGE550SX, "D-Link 550SX Gigabit Ethernet" }, { VENDORID_DLINK, DEVICEID_DLINK_DGE560T, - "D-Link 560T Gigabit Ethernet" } + "D-Link 560T Gigabit Ethernet" }, + { VENDORID_DLINK, DEVICEID_DLINK_DGE560SX, + "D-Link 560SX Gigabit Ethernet" } }; static const char *model_name[] = { @@ -1445,6 +1447,7 @@ struct msk_softc *sc; struct msk_if_softc *sc_if; struct ifnet *ifp; + struct msk_mii_data *mmd; int i, port, error; uint8_t eaddr[6]; @@ -1454,7 +1457,8 @@ error = 0; sc_if = device_get_softc(dev); sc = device_get_softc(device_get_parent(dev)); - port = *(int *)device_get_ivars(dev); + mmd = device_get_ivars(dev); + port = mmd->port; sc_if->msk_if_dev = dev; sc_if->msk_port = port; @@ -1600,7 +1604,8 @@ mskc_attach(device_t dev) { struct msk_softc *sc; - int error, msic, msir, *port, reg; + struct msk_mii_data *mmd; + int error, msic, msir, reg; sc = device_get_softc(dev); sc->msk_dev = dev; @@ -1669,10 +1674,6 @@ CSR_WRITE_2(sc, B0_CTST, CS_RST_SET); CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); sc->msk_pmd = CSR_READ_1(sc, B2_PMD_TYP); - if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S') - sc->msk_coppertype = 0; - else - sc->msk_coppertype = 1; /* Check number of MACs. */ sc->msk_num_port = 1; if ((CSR_READ_1(sc, B2_Y2_HW_RES) & CFG_DUAL_MAC_MSK) == @@ -1812,15 +1813,18 @@ error = ENXIO; goto fail; } - port = malloc(sizeof(int), M_DEVBUF, M_WAITOK); - if (port == NULL) { + mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | M_ZERO); + if (mmd == NULL) { device_printf(dev, "failed to allocate memory for " "ivars of PORT_A\n"); error = ENXIO; goto fail; } - *port = MSK_PORT_A; - device_set_ivars(sc->msk_devs[MSK_PORT_A], port); + mmd->port = MSK_PORT_A; + mmd->pmd = sc->msk_pmd; + if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S' || sc->msk_pmd == 'P') + mmd->mii_flags |= MIIF_HAVEFIBER; + device_set_ivars(sc->msk_devs[MSK_PORT_A], mmd); if (sc->msk_num_port > 1) { sc->msk_devs[MSK_PORT_B] = device_add_child(dev, "msk", -1); @@ -1829,15 +1833,18 @@ error = ENXIO; goto fail; } - port = malloc(sizeof(int), M_DEVBUF, M_WAITOK); - if (port == NULL) { + mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | M_ZERO); + if (mmd == NULL) { device_printf(dev, "failed to allocate memory for " "ivars of PORT_B\n"); error = ENXIO; goto fail; } - *port = MSK_PORT_B; - device_set_ivars(sc->msk_devs[MSK_PORT_B], port); + mmd->port = MSK_PORT_B; + mmd->pmd = sc->msk_pmd; + if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S' || sc->msk_pmd == 'P') + mmd->mii_flags |= MIIF_HAVEFIBER; + device_set_ivars(sc->msk_devs[MSK_PORT_B], mmd); } error = bus_generic_attach(dev); @@ -3794,9 +3801,14 @@ /* Set receive filter. */ msk_rxfilter(sc_if); - /* Flush Rx MAC FIFO on any flow control or error. */ - CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_MSK), - GMR_FS_ANY_ERR); + if (sc->msk_hw_id == CHIP_ID_YUKON_XL) { + /* Clear flush mask - HW bug. */ + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_MSK), 0); + } else { + /* Flush Rx MAC FIFO on any flow control or error. */ + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_MSK), + GMR_FS_ANY_ERR); + } /* * Set Rx FIFO flush threshold to 64 bytes + 1 FIFO word Index: sys/dev/msk/if_mskreg.h =================================================================== --- sys/dev/msk/if_mskreg.h (revision 197042) +++ sys/dev/msk/if_mskreg.h (working copy) @@ -149,6 +149,7 @@ */ #define DEVICEID_DLINK_DGE550SX 0x4001 #define DEVICEID_DLINK_DGE560T 0x4b00 +#define DEVICEID_DLINK_DGE560SX 0x4b02 #define BIT_31 (1 << 31) #define BIT_30 (1 << 30) @@ -2403,6 +2404,12 @@ #define MSK_TX_TIMEOUT 5 #define MSK_PUT_WM 10 +struct msk_mii_data { + int port; + uint32_t pmd; + int mii_flags; +}; + /* Forward decl. */ struct msk_if_softc; @@ -2466,7 +2473,6 @@ uint8_t msk_num_port; int msk_ramsize; /* amount of SRAM on NIC */ uint32_t msk_pmd; /* physical media type */ - uint32_t msk_coppertype; uint32_t msk_intrmask; uint32_t msk_intrhwemask; uint32_t msk_pflags; Index: sys/dev/mii/e1000phy.c =================================================================== --- sys/dev/mii/e1000phy.c (revision 197042) +++ sys/dev/mii/e1000phy.c (working copy) @@ -59,6 +59,9 @@ #include "miidevs.h" #include +/* XXX */ +#include +#include #include "miibus_if.h" @@ -68,6 +71,7 @@ struct e1000phy_softc { struct mii_softc mii_sc; int mii_model; + struct msk_mii_data *mmd; }; static device_method_t e1000phy_methods[] = { @@ -130,6 +134,7 @@ struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; + struct ifnet *ifp; esc = device_get_softc(dev); sc = &esc->mii_sc; @@ -145,6 +150,16 @@ mii->mii_instance++; esc->mii_model = MII_MODEL(ma->mii_id2); + ifp = sc->mii_pdata->mii_ifp; + if (strcmp(ifp->if_dname, "msk") == 0) { + /* XXX */ + esc->mmd = device_get_ivars( + device_get_parent(device_get_parent(dev))); + if (esc->mmd != NULL && + (esc->mmd->mii_flags & MIIF_HAVEFIBER) != 0) + sc->mii_flags |= MIIF_HAVEFIBER; + } + switch (esc->mii_model) { case MII_MODEL_MARVELL_E1011: case MII_MODEL_MARVELL_E1112: @@ -199,6 +214,13 @@ reg &= ~E1000_SCR_MODE_MASK; reg |= E1000_SCR_MODE_1000BX; PHY_WRITE(sc, E1000_SCR, reg); + if (esc->mmd != NULL && esc->mmd->pmd == 'P') { + /* Set SIGDET polarity low for SFP module. */ + PHY_WRITE(sc, E1000_EADR, 1); + reg = PHY_READ(sc, E1000_SCR); + reg |= E1000_SCR_FIB_SIGDET_POLARITY; + PHY_WRITE(sc, E1000_SCR, reg); + } PHY_WRITE(sc, E1000_EADR, page); } } else { @@ -485,8 +507,11 @@ return; } } else { - if (ssr & E1000_SSR_1000MBS) - mii->mii_media_active |= IFM_1000_SX; + /* + * Some fiber PHY(88E8112) does not seem to set resolved + * speed so always assume we've got IFM_1000_SX. + */ + mii->mii_media_active |= IFM_1000_SX; } if (ssr & E1000_SSR_DUPLEX) Index: sys/dev/mii/e1000phyreg.h =================================================================== --- sys/dev/mii/e1000phyreg.h (revision 197042) +++ sys/dev/mii/e1000phyreg.h (working copy) @@ -248,6 +248,11 @@ #define E1000_SCR_EN_DETECT_MASK 0x0300 +/* 88E1112 page 1 fiber specific control */ +#define E1000_SCR_FIB_TX_DIS 0x0008 +#define E1000_SCR_FIB_SIGDET_POLARITY 0x0200 +#define E1000_SCR_FIB_FORCE_LINK 0x0400 + /* 88E1112 page 2 */ #define E1000_SCR_MODE_MASK 0x0380 #define E1000_SCR_MODE_AUTO 0x0180