Index: sys/dev/e1000/if_em.h =================================================================== --- sys/dev/e1000/if_em.h +++ sys/dev/e1000/if_em.h @@ -341,8 +341,6 @@ #define EM_VFTA_SIZE 128 #define EM_TSO_SIZE 65535 #define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */ -#define EM_MSIX_MASK 0x01F00000 /* For 82574 use */ -#define EM_MSIX_LINK 0x01000000 /* For 82574 use */ #define ETH_ZLEN 60 #define EM_CSUM_OFFLOAD (CSUM_IP | CSUM_IP_UDP | CSUM_IP_TCP) /* Offload bits in mbuf flag */ #define IGB_CSUM_OFFLOAD (CSUM_IP | CSUM_IP_UDP | CSUM_IP_TCP | \ Index: sys/dev/e1000/if_em.c =================================================================== --- sys/dev/e1000/if_em.c +++ sys/dev/e1000/if_em.c @@ -1514,13 +1514,18 @@ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { em_handle_link(adapter->ctx); + + /* Handle spurious interrupts */ + if (adapter->hw.mac.type >= igb_mac_min) { + /* Re-arm unconditionally */ + E1000_WRITE_REG(&adapter->hw, E1000_IMS, E1000_IMS_LSC); + E1000_WRITE_REG(&adapter->hw, E1000_EIMS, adapter->link_mask); } else if (adapter->hw.mac.type == e1000_82574) { - /* Only re-arm 82574 if em_if_update_admin_status() won't. */ - E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK | - E1000_IMS_LSC); - } + /* Only re-arm 82574 link if em_handle_link() above won't. */ + if (!(reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) + E1000_WRITE_REG(&adapter->hw, E1000_IMS, E1000_IMS_OTHER | + E1000_IMS_LSC); - if (adapter->hw.mac.type == e1000_82574) { /* * Because we must read the ICR for this interrupt it may * clear other causes using autoclear, for this reason we @@ -1531,7 +1536,6 @@ } else { /* Re-arm unconditionally */ E1000_WRITE_REG(&adapter->hw, E1000_IMS, E1000_IMS_LSC); - E1000_WRITE_REG(&adapter->hw, E1000_EIMS, adapter->link_mask); } return (FILTER_HANDLED); @@ -1878,7 +1882,7 @@ lem_smartspeed(adapter); else if (hw->mac.type == e1000_82574 && adapter->intr_type == IFLIB_INTR_MSIX) - E1000_WRITE_REG(hw, E1000_IMS, EM_MSIX_LINK | E1000_IMS_LSC); + E1000_WRITE_REG(hw, E1000_IMS, E1000_IMS_OTHER | E1000_IMS_LSC); } static void @@ -2091,6 +2095,11 @@ adapter->ivars |= (8 | rx_vectors) << 16; adapter->ivars |= 0x80000000; } + /* Enable the "Other" interrupt type for 82574 for link status change */ + if (adapter->hw.mac.type == e1000_82574 && + adapter->intr_type == IFLIB_INTR_MSIX) + adapter->ims |= E1000_IMS_OTHER; + return (0); fail: iflib_irq_free(ctx, &adapter->irq); @@ -3468,7 +3477,7 @@ u32 ims_mask = IMS_ENABLE_MASK; if (hw->mac.type == e1000_82574) { - E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK); + E1000_WRITE_REG(hw, EM_EIAC, adapter->ims); ims_mask |= adapter->ims; } E1000_WRITE_REG(hw, E1000_IMS, ims_mask);