summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/e1000/if_em.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/e1000/if_em.c')
-rw-r--r--freebsd/sys/dev/e1000/if_em.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c
index 32eb4afe..9b52c35a 100644
--- a/freebsd/sys/dev/e1000/if_em.c
+++ b/freebsd/sys/dev/e1000/if_em.c
@@ -176,6 +176,7 @@ static pci_vendor_info_t em_vendor_info_array[] =
PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V8, "Intel(R) PRO/1000 Network Connection"),
PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_LM9, "Intel(R) PRO/1000 Network Connection"),
PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V9, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V10, "Intel(R) PRO/1000 Network Connection"),
/* required last entry */
PVID_END
};
@@ -1397,10 +1398,8 @@ em_intr(void *arg)
IFDI_INTR_DISABLE(ctx);
/* Link status change */
- if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- adapter->hw.mac.get_link_status = 1;
- iflib_admin_intr_deferred(ctx);
- }
+ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))
+ em_handle_link(ctx);
if (reg_icr & E1000_ICR_RXO)
adapter->rx_overruns++;
@@ -1483,22 +1482,24 @@ em_msix_link(void *arg)
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
em_handle_link(adapter->ctx);
- } else {
- E1000_WRITE_REG(&adapter->hw, E1000_IMS,
- EM_MSIX_LINK | E1000_IMS_LSC);
- if (adapter->hw.mac.type >= igb_mac_min)
- 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);
}
- /*
- * Because we must read the ICR for this interrupt
- * it may clear other causes using autoclear, for
- * this reason we simply create a soft interrupt
- * for all these vectors.
- */
- if (reg_icr && adapter->hw.mac.type < igb_mac_min) {
- E1000_WRITE_REG(&adapter->hw,
- E1000_ICS, adapter->ims);
+ 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
+ * simply create a soft interrupt for all these vectors.
+ */
+ if (reg_icr)
+ E1000_WRITE_REG(&adapter->hw, E1000_ICS, adapter->ims);
+ } 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);
@@ -1514,7 +1515,6 @@ em_handle_link(void *context)
iflib_admin_intr_deferred(ctx);
}
-
/*********************************************************************
*
* Media Ioctl callback
@@ -1831,14 +1831,15 @@ em_if_update_admin_status(if_ctx_t ctx)
em_update_stats_counters(adapter);
/* Reset LAA into RAR[0] on 82571 */
- if ((adapter->hw.mac.type == e1000_82571) &&
- e1000_get_laa_state_82571(&adapter->hw))
- e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+ if (hw->mac.type == e1000_82571 && e1000_get_laa_state_82571(hw))
+ e1000_rar_set(hw, hw->mac.addr, 0);
- if (adapter->hw.mac.type < em_mac_min)
+ if (hw->mac.type < em_mac_min)
lem_smartspeed(adapter);
-
- E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK | E1000_IMS_LSC);
+ else if (hw->mac.type == e1000_82574 &&
+ adapter->intr_type == IFLIB_INTR_MSIX)
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK |
+ E1000_IMS_LSC);
}
static void
@@ -3905,6 +3906,7 @@ em_disable_aspm(struct adapter *adapter)
static void
em_update_stats_counters(struct adapter *adapter)
{
+ u64 prev_xoffrxc = adapter->stats.xoffrxc;
if(adapter->hw.phy.media_type == e1000_media_type_copper ||
(E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
@@ -3928,7 +3930,8 @@ em_update_stats_counters(struct adapter *adapter)
** For watchdog management we need to know if we have been
** paused during the last interval, so capture that here.
*/
- adapter->shared->isc_pause_frames = adapter->stats.xoffrxc;
+ if (adapter->stats.xoffrxc != prev_xoffrxc)
+ adapter->shared->isc_pause_frames = 1;
adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC);
adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC);
adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64);