On 16/08/17(Wed) 15:55, Mike Belopuhov wrote: > Hi, > > I haven't gotten any feedback on the following diff > but I think there's still hope. Please test. > > Original mail: > > I won't mind some broad testing of the following diff > which adds some additional media options to ix(4) from > FreeBSD and includes a fix for changing media from > Masanobu SAITOH. > > The fix makes sure that when the media operation speed > is selected manually, the device doesn't additionally > advertise other (slower) modes.
Time to get this broadly tested by committing it? > diff --git sys/dev/pci/if_ix.c sys/dev/pci/if_ix.c > index 339ba2bc4f1..8fca8742f7f 100644 > --- sys/dev/pci/if_ix.c > +++ sys/dev/pci/if_ix.c > @@ -1028,62 +1028,115 @@ ixgbe_intr(void *arg) > * This routine is called whenever the user queries the status of > * the interface using ifconfig. > * > **********************************************************************/ > void > -ixgbe_media_status(struct ifnet * ifp, struct ifmediareq *ifmr) > +ixgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) > { > struct ix_softc *sc = ifp->if_softc; > + int layer; > + > + layer = sc->hw.mac.ops.get_supported_physical_layer(&sc->hw); > > ifmr->ifm_active = IFM_ETHER; > ifmr->ifm_status = IFM_AVALID; > > INIT_DEBUGOUT("ixgbe_media_status: begin"); > ixgbe_update_link_status(sc); > > - if (LINK_STATE_IS_UP(ifp->if_link_state)) { > - ifmr->ifm_status |= IFM_ACTIVE; > + if (!LINK_STATE_IS_UP(ifp->if_link_state)) > + return; > + > + ifmr->ifm_status |= IFM_ACTIVE; > > + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T || > + layer & IXGBE_PHYSICAL_LAYER_1000BASE_T || > + layer & IXGBE_PHYSICAL_LAYER_100BASE_TX) > switch (sc->link_speed) { > + case IXGBE_LINK_SPEED_10GB_FULL: > + ifmr->ifm_active |= IFM_10G_T | IFM_FDX; > + break; > + case IXGBE_LINK_SPEED_1GB_FULL: > + ifmr->ifm_active |= IFM_1000_T | IFM_FDX; > + break; > case IXGBE_LINK_SPEED_100_FULL: > ifmr->ifm_active |= IFM_100_TX | IFM_FDX; > break; > + } > + if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU || > + layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA) > + switch (sc->link_speed) { > + case IXGBE_LINK_SPEED_10GB_FULL: > + ifmr->ifm_active |= IFM_10G_SFP_CU | IFM_FDX; > + break; > + } > + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LR) > + switch (sc->link_speed) { > + case IXGBE_LINK_SPEED_10GB_FULL: > + ifmr->ifm_active |= IFM_10G_LR | IFM_FDX; > + break; > case IXGBE_LINK_SPEED_1GB_FULL: > - switch (sc->optics) { > - case IFM_10G_SR: /* multi-speed fiber */ > - ifmr->ifm_active |= IFM_1000_SX | IFM_FDX; > - break; > - case IFM_10G_LR: /* multi-speed fiber */ > - ifmr->ifm_active |= IFM_1000_LX | IFM_FDX; > - break; > - default: > - ifmr->ifm_active |= sc->optics | IFM_FDX; > - break; > - } > + ifmr->ifm_active |= IFM_1000_LX | IFM_FDX; > break; > + } > + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LRM) > + switch (sc->link_speed) { > case IXGBE_LINK_SPEED_10GB_FULL: > - ifmr->ifm_active |= sc->optics | IFM_FDX; > + ifmr->ifm_active |= IFM_10G_LRM | IFM_FDX; > + break; > + case IXGBE_LINK_SPEED_1GB_FULL: > + ifmr->ifm_active |= IFM_1000_LX | IFM_FDX; > break; > } > - > - switch (sc->hw.fc.current_mode) { > - case ixgbe_fc_tx_pause: > - ifmr->ifm_active |= IFM_FLOW | IFM_ETH_TXPAUSE; > + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR || > + layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX) > + switch (sc->link_speed) { > + case IXGBE_LINK_SPEED_10GB_FULL: > + ifmr->ifm_active |= IFM_10G_SR | IFM_FDX; > + break; > + case IXGBE_LINK_SPEED_1GB_FULL: > + ifmr->ifm_active |= IFM_1000_SX | IFM_FDX; > break; > - case ixgbe_fc_rx_pause: > - ifmr->ifm_active |= IFM_FLOW | IFM_ETH_RXPAUSE; > + } > + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_CX4) > + switch (sc->link_speed) { > + case IXGBE_LINK_SPEED_10GB_FULL: > + ifmr->ifm_active |= IFM_10G_CX4 | IFM_FDX; > break; > - case ixgbe_fc_full: > - ifmr->ifm_active |= IFM_FLOW | IFM_ETH_RXPAUSE | > - IFM_ETH_TXPAUSE; > + } > + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) > + switch (sc->link_speed) { > + case IXGBE_LINK_SPEED_10GB_FULL: > + ifmr->ifm_active |= IFM_10G_KR | IFM_FDX; > break; > - default: > - ifmr->ifm_active &= ~(IFM_FLOW | IFM_ETH_RXPAUSE | > - IFM_ETH_TXPAUSE); > + case IXGBE_LINK_SPEED_2_5GB_FULL: > + ifmr->ifm_active |= IFM_2500_KX | IFM_FDX; > + break; > + case IXGBE_LINK_SPEED_1GB_FULL: > + ifmr->ifm_active |= IFM_1000_KX | IFM_FDX; > break; > } > - } > + else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4 > + || layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) > + switch (sc->link_speed) { > + case IXGBE_LINK_SPEED_10GB_FULL: > + ifmr->ifm_active |= IFM_10G_KX4 | IFM_FDX; > + break; > + case IXGBE_LINK_SPEED_2_5GB_FULL: > + ifmr->ifm_active |= IFM_2500_KX | IFM_FDX; > + break; > + case IXGBE_LINK_SPEED_1GB_FULL: > + ifmr->ifm_active |= IFM_1000_KX | IFM_FDX; > + break; > + } > + > + if (sc->hw.fc.current_mode == ixgbe_fc_rx_pause || > + sc->hw.fc.current_mode == ixgbe_fc_full) > + ifmr->ifm_active |= IFM_FLOW | IFM_ETH_RXPAUSE; > + if (sc->hw.fc.current_mode == ixgbe_fc_tx_pause || > + sc->hw.fc.current_mode == ixgbe_fc_full) > + ifmr->ifm_active |= IFM_FLOW | IFM_ETH_TXPAUSE; > } > > /********************************************************************* > * > * Media Ioctl callback > @@ -1097,37 +1150,43 @@ ixgbe_media_change(struct ifnet *ifp) > { > struct ix_softc *sc = ifp->if_softc; > struct ixgbe_hw *hw = &sc->hw; > struct ifmedia *ifm = &sc->media; > ixgbe_link_speed speed = 0; > + bool autoneg; > > if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) > return (EINVAL); > > if (hw->phy.media_type == ixgbe_media_type_backplane) > return (ENODEV); > > switch (IFM_SUBTYPE(ifm->ifm_media)) { > case IFM_AUTO: > + if (!hw->mac.ops.get_link_capabilities || > + hw->mac.ops.get_link_capabilities(hw, &speed, > + &autoneg)) > + return (EINVAL); > + break; > case IFM_10G_T: > - speed |= IXGBE_LINK_SPEED_100_FULL; > - case IFM_10G_SR: /* KR, too */ > + case IFM_10G_LRM: > + case IFM_10G_SR: > + case IFM_10G_KR: > case IFM_10G_LR: > - case IFM_10G_CX4: /* KX4 */ > - speed |= IXGBE_LINK_SPEED_1GB_FULL; > + case IFM_10G_KX4: > + case IFM_10G_CX4: > case IFM_10G_SFP_CU: > - speed |= IXGBE_LINK_SPEED_10GB_FULL; > + speed = IXGBE_LINK_SPEED_10GB_FULL; > break; > case IFM_1000_T: > - speed |= IXGBE_LINK_SPEED_100_FULL; > case IFM_1000_LX: > case IFM_1000_SX: > - case IFM_1000_CX: /* KX */ > - speed |= IXGBE_LINK_SPEED_1GB_FULL; > + case IFM_1000_KX: > + speed = IXGBE_LINK_SPEED_1GB_FULL; > break; > case IFM_100_TX: > - speed |= IXGBE_LINK_SPEED_100_FULL; > + speed = IXGBE_LINK_SPEED_100_FULL; > break; > default: > return (EINVAL); > } > > @@ -1675,15 +1734,15 @@ ixgbe_add_media_types(struct ix_softc *sc) > } else if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX) > ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_SX, 0, NULL); > if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_CX4) > ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_CX4, 0, NULL); > if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) > - ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_SR, 0, NULL); > + ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_KR, 0, NULL); > if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) > - ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_CX4, 0, NULL); > + ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_KX4, 0, NULL); > if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) > - ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_CX, 0, NULL); > + ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_KX, 0, NULL); > > if (hw->device_id == IXGBE_DEV_ID_82598AT) { > ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, > NULL); > ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_T, 0, NULL); >