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

Reply via email to