On Tue, Nov 27, 2012 at 13:50 +0100, mxb wrote:
> Hi tech@,
> 
> ix(4) does not detects link then cable is plugged in into already running 
> machine.
> 
> ix0: 
> flags=28b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST,NOINET6> 
> mtu 1500
>         lladdr bc:30:5b:f3:60:10
>         description: HW_EXT
>         priority: 0
>         media: Ethernet autoselect (1000baseT full-duplex)
>         status: active
>         inet 172.16.0.232 netmask 0xfffff800 broadcast 172.16.7.255
> ix1: 
> flags=28b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST,NOINET6> 
> mtu 1500
>         lladdr bc:30:5b:f3:60:12
>         description: HW_INT
>         priority: 0
>         media: Ethernet autoselect
>         status: no carrier
>         inet 192.168.10.3 netmask 0xffffff00 broadcast 192.168.10.255
> 
> ix0 at pci1 dev 0 function 0 "Intel X540T" rev 0x01: msi
> ix1 at pci1 dev 0 function 1 "Intel X540T" rev 0x01: msi
> 
> //maxim
> 

can you please try the diff below.  most of the stuff is obtained
from freebsd.  it also fixes a number of autonegotiation issues.
tested on x540 only at the moment, but i'll test it on 98'er and
99'er with sfp+ next week.

diff --git sys/dev/pci/if_ix.c sys/dev/pci/if_ix.c
index d0599d8..01dec51 100644
--- sys/dev/pci/if_ix.c
+++ sys/dev/pci/if_ix.c
@@ -305,6 +305,9 @@ ixgbe_attach(struct device *parent, struct device *self, 
void *aux)
                goto err_late;
        }
 
+       /* Detect and set physical type */
+       ixgbe_setup_optics(sc);
+
        bcopy(sc->hw.mac.addr, sc->arpcom.ac_enaddr,
            IXGBE_ETH_LENGTH_OF_ADDRESS);
 
@@ -401,7 +404,7 @@ ixgbe_start(struct ifnet * ifp)
 
        if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
                return;
-       if (!sc->link_active)
+       if (!sc->link_up)
                return;
 
 #if 0
@@ -1265,23 +1268,17 @@ out:
 void
 ixgbe_update_link_status(struct ix_softc *sc)
 {
-       int link_up = FALSE;
-       struct ifnet *ifp = &sc->arpcom.ac_if;
-       struct tx_ring *txr = sc->tx_rings;
-       int             link_state;
-       int             i;
-
-       ixgbe_hw(&sc->hw, check_link, &sc->link_speed, &link_up, 0);
-
-       link_state = link_up ? LINK_STATE_FULL_DUPLEX : LINK_STATE_DOWN;
+       struct ifnet    *ifp = &sc->arpcom.ac_if;
+       int             link_state = LINK_STATE_DOWN;
 
-       if (ifp->if_link_state != link_state) {
-               sc->link_active = link_up;
-               ifp->if_link_state = link_state;
-               if_link_state_change(ifp);
-       }
+       ixgbe_hw(&sc->hw, check_link, &sc->link_speed, &sc->link_up, 0);
 
-       if (LINK_STATE_IS_UP(ifp->if_link_state)) {
+       if (sc->link_up)
+               link_state = LINK_STATE_FULL_DUPLEX;
+       if (ifp->if_link_state == link_state)
+               return;
+       ifp->if_baudrate = 0;
+       if (link_state != LINK_STATE_DOWN) {
                switch (sc->link_speed) {
                case IXGBE_LINK_SPEED_UNKNOWN:
                        ifp->if_baudrate = 0;
@@ -1296,12 +1293,9 @@ ixgbe_update_link_status(struct ix_softc *sc)
                        ifp->if_baudrate = IF_Gbps(10);
                        break;
                }
-       } else {
-               ifp->if_baudrate = 0;
-               ifp->if_timer = 0;
-               for (i = 0; i < sc->num_queues; i++)
-                       txr[i].watchdog_timer = FALSE;
        }
+       ifp->if_link_state = link_state;
+       if_link_state_change(ifp);
 }
 
 
@@ -1374,66 +1368,54 @@ ixgbe_identify_hardware(struct ix_softc *sc)
        case PCI_PRODUCT_INTEL_82598_SR_DUAL_EM:
        case PCI_PRODUCT_INTEL_82598EB_SFP:
                sc->hw.mac.type = ixgbe_mac_82598EB;
-               sc->optics = IFM_10G_SR;
                break;
        case PCI_PRODUCT_INTEL_82598EB_CX4_DUAL:
        case PCI_PRODUCT_INTEL_82598EB_CX4:
                sc->hw.mac.type = ixgbe_mac_82598EB;
-               sc->optics = IFM_10G_CX4;
                break;
        case PCI_PRODUCT_INTEL_82598EB_XF_LR:
                sc->hw.mac.type = ixgbe_mac_82598EB;
-               sc->optics = IFM_10G_LR;
                break;
        case PCI_PRODUCT_INTEL_82598AT:
        case PCI_PRODUCT_INTEL_82598AT2:
        case PCI_PRODUCT_INTEL_82598AT_DUAL:
                sc->hw.mac.type = ixgbe_mac_82598EB;
-               sc->optics = IFM_10G_T;
                break;
        case PCI_PRODUCT_INTEL_82598_BX:
                sc->hw.mac.type = ixgbe_mac_82598EB;
-               sc->optics = IFM_AUTO;
                break;
        case PCI_PRODUCT_INTEL_82599_SFP:
        case PCI_PRODUCT_INTEL_82599_SFP_EM:
        case PCI_PRODUCT_INTEL_82599_SFP_FCOE:
        case PCI_PRODUCT_INTEL_82599_SFP_SF2:
                sc->hw.mac.type = ixgbe_mac_82599EB;
-               sc->optics = IFM_10G_SR;
                sc->hw.phy.smart_speed = ixgbe_smart_speed;
                break;
        case PCI_PRODUCT_INTEL_82599_KX4:
        case PCI_PRODUCT_INTEL_82599_KX4_MEZZ:
        case PCI_PRODUCT_INTEL_82599_CX4:
                sc->hw.mac.type = ixgbe_mac_82599EB;
-               sc->optics = IFM_10G_CX4;
                sc->hw.phy.smart_speed = ixgbe_smart_speed;
                break;
        case PCI_PRODUCT_INTEL_82599_T3_LOM:
                sc->hw.mac.type = ixgbe_mac_82599EB;
-               sc->optics = IFM_10G_T;
                sc->hw.phy.smart_speed = ixgbe_smart_speed;
                break;
        case PCI_PRODUCT_INTEL_82599_XAUI:
        case PCI_PRODUCT_INTEL_82599_COMBO_BACKPLANE:
        case PCI_PRODUCT_INTEL_82599_BPLANE_FCOE:
                sc->hw.mac.type = ixgbe_mac_82599EB;
-               sc->optics = IFM_AUTO;
                sc->hw.phy.smart_speed = ixgbe_smart_speed;
                break;
        case PCI_PRODUCT_INTEL_82599VF:
                sc->hw.mac.type = ixgbe_mac_82599_vf;
-               sc->optics = IFM_AUTO;
                sc->hw.phy.smart_speed = ixgbe_smart_speed;
                break;
        case PCI_PRODUCT_INTEL_X540T:
                sc->hw.mac.type = ixgbe_mac_X540;
-               sc->optics = IFM_10G_T;
                sc->hw.phy.smart_speed = ixgbe_smart_speed;
                break;
        default:
-               sc->optics = IFM_AUTO;
                break;
        }
 }
@@ -1450,35 +1432,23 @@ ixgbe_setup_optics(struct ix_softc *sc)
        int             layer;
 
        layer = ixgbe_hw(hw, get_supported_physical_layer);
-       switch (layer) {
-               case IXGBE_PHYSICAL_LAYER_10GBASE_T:
-                       sc->optics = IFM_10G_T;
-                       break;
-               case IXGBE_PHYSICAL_LAYER_1000BASE_T:
-                       sc->optics = IFM_1000_T;
-                       break;
-               case IXGBE_PHYSICAL_LAYER_10GBASE_LR:
-               case IXGBE_PHYSICAL_LAYER_10GBASE_LRM:
-                       sc->optics = IFM_10G_LR;
-                       break;
-               case IXGBE_PHYSICAL_LAYER_10GBASE_SR:
-                       sc->optics = IFM_10G_SR;
-                       break;
-               case IXGBE_PHYSICAL_LAYER_10GBASE_KX4:
-               case IXGBE_PHYSICAL_LAYER_10GBASE_CX4:
-                       sc->optics = IFM_10G_CX4;
-                       break;
-               case IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU:
-                       sc->optics = IFM_10G_SFP_CU;
-                       break;
-               case IXGBE_PHYSICAL_LAYER_1000BASE_KX:
-               case IXGBE_PHYSICAL_LAYER_10GBASE_KR:
-               case IXGBE_PHYSICAL_LAYER_10GBASE_XAUI:
-               case IXGBE_PHYSICAL_LAYER_UNKNOWN:
-               default:
-                       sc->optics = IFM_ETHER | IFM_AUTO;
-                       break;
-       }
+
+       if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T)
+               sc->optics = IFM_10G_T;
+       else if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_T)
+               sc->optics = IFM_1000_T;
+       else if (layer & (IXGBE_PHYSICAL_LAYER_10GBASE_LR |
+           IXGBE_PHYSICAL_LAYER_10GBASE_LRM))
+               sc->optics = IFM_10G_LR;
+       else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR)
+               sc->optics = IFM_10G_SR;
+       else if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU)
+               sc->optics = IFM_10G_SFP_CU;
+       else if (layer & (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
+           IXGBE_PHYSICAL_LAYER_10GBASE_CX4))
+               sc->optics = IFM_10G_CX4;
+       else
+               sc->optics = IFM_ETHER | IFM_AUTO;
 }
 
 /*********************************************************************
@@ -1680,6 +1650,10 @@ ixgbe_config_link(struct ix_softc *sc)
                            &sc->link_up, FALSE);
                if (err)
                        return;
+               /* XXX: must be changeable in ixgbe_media_change */
+               autoneg = IXGBE_LINK_SPEED_100_FULL |
+                         IXGBE_LINK_SPEED_1GB_FULL |
+                         IXGBE_LINK_SPEED_10GB_FULL;
                if ((!autoneg) && (sc->hw.mac.ops.get_link_capabilities))
                        err = sc->hw.mac.ops.get_link_capabilities(&sc->hw,
                            &autoneg, &negotiate);
diff --git sys/dev/pci/if_ix.h sys/dev/pci/if_ix.h
index 9f00301..0480521 100644
--- sys/dev/pci/if_ix.h
+++ sys/dev/pci/if_ix.h
@@ -261,7 +261,6 @@ struct ix_softc {
        /* Info about the interface */
        uint                    optics;
        int                     advertise;  /* link speeds */
-       int                     link_active;
        uint16_t                max_frame_size;
        uint16_t                num_segs;
        uint32_t                link_speed;
diff --git sys/dev/pci/ixgbe.c sys/dev/pci/ixgbe.c
index 43f39a0..2c62821 100644
--- sys/dev/pci/ixgbe.c
+++ sys/dev/pci/ixgbe.c
@@ -2902,12 +2902,6 @@ int32_t ixgbe_check_mac_link_generic(struct ixgbe_hw 
*hw, ixgbe_link_speed *spee
        else
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
 
-       /* if link is down, zero out the current_mode */
-       if (*link_up == FALSE) {
-               hw->fc.current_mode = ixgbe_fc_none;
-               hw->fc.fc_was_autonegged = FALSE;
-       }
-
        return IXGBE_SUCCESS;
 }

Reply via email to