diff options
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/defines.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/e1000.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 46 |
6 files changed, 71 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index 02a12b69555f..4dab6fc265a2 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h | |||
@@ -232,6 +232,7 @@ | |||
232 | #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ | 232 | #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ |
233 | #define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */ | 233 | #define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */ |
234 | #define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */ | 234 | #define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */ |
235 | #define E1000_CTRL_MEHE 0x00080000 /* Memory Error Handling Enable */ | ||
235 | #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ | 236 | #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ |
236 | #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ | 237 | #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ |
237 | #define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ | 238 | #define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ |
@@ -389,6 +390,12 @@ | |||
389 | 390 | ||
390 | #define E1000_PBS_16K E1000_PBA_16K | 391 | #define E1000_PBS_16K E1000_PBA_16K |
391 | 392 | ||
393 | /* Uncorrectable/correctable ECC Error counts and enable bits */ | ||
394 | #define E1000_PBECCSTS_CORR_ERR_CNT_MASK 0x000000FF | ||
395 | #define E1000_PBECCSTS_UNCORR_ERR_CNT_MASK 0x0000FF00 | ||
396 | #define E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT 8 | ||
397 | #define E1000_PBECCSTS_ECC_ENABLE 0x00010000 | ||
398 | |||
392 | #define IFS_MAX 80 | 399 | #define IFS_MAX 80 |
393 | #define IFS_MIN 40 | 400 | #define IFS_MIN 40 |
394 | #define IFS_RATIO 4 | 401 | #define IFS_RATIO 4 |
@@ -408,6 +415,7 @@ | |||
408 | #define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */ | 415 | #define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */ |
409 | #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ | 416 | #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ |
410 | #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ | 417 | #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ |
418 | #define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */ | ||
411 | #define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ | 419 | #define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ |
412 | #define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ | 420 | #define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ |
413 | #define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ | 421 | #define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ |
@@ -443,6 +451,7 @@ | |||
443 | #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ | 451 | #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ |
444 | #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ | 452 | #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ |
445 | #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ | 453 | #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ |
454 | #define E1000_IMS_ECCER E1000_ICR_ECCER /* Uncorrectable ECC Error */ | ||
446 | #define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ | 455 | #define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ |
447 | #define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ | 456 | #define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ |
448 | #define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ | 457 | #define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ |
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 6782a2eea1bc..7e95f221d60b 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h | |||
@@ -309,6 +309,8 @@ struct e1000_adapter { | |||
309 | 309 | ||
310 | struct napi_struct napi; | 310 | struct napi_struct napi; |
311 | 311 | ||
312 | unsigned int uncorr_errors; /* uncorrectable ECC errors */ | ||
313 | unsigned int corr_errors; /* correctable ECC errors */ | ||
312 | unsigned int restart_queue; | 314 | unsigned int restart_queue; |
313 | u32 txd_cmd; | 315 | u32 txd_cmd; |
314 | 316 | ||
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index f95bc6ee1c22..fd4772a2691c 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c | |||
@@ -108,6 +108,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = { | |||
108 | E1000_STAT("dropped_smbus", stats.mgpdc), | 108 | E1000_STAT("dropped_smbus", stats.mgpdc), |
109 | E1000_STAT("rx_dma_failed", rx_dma_failed), | 109 | E1000_STAT("rx_dma_failed", rx_dma_failed), |
110 | E1000_STAT("tx_dma_failed", tx_dma_failed), | 110 | E1000_STAT("tx_dma_failed", tx_dma_failed), |
111 | E1000_STAT("uncorr_ecc_errors", uncorr_errors), | ||
112 | E1000_STAT("corr_ecc_errors", corr_errors), | ||
111 | }; | 113 | }; |
112 | 114 | ||
113 | #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) | 115 | #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) |
diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index cf217777586c..b88676ff3d86 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h | |||
@@ -77,6 +77,7 @@ enum e1e_registers { | |||
77 | #define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */ | 77 | #define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */ |
78 | E1000_PBA = 0x01000, /* Packet Buffer Allocation - RW */ | 78 | E1000_PBA = 0x01000, /* Packet Buffer Allocation - RW */ |
79 | E1000_PBS = 0x01008, /* Packet Buffer Size */ | 79 | E1000_PBS = 0x01008, /* Packet Buffer Size */ |
80 | E1000_PBECCSTS = 0x0100C, /* Packet Buffer ECC Status - RW */ | ||
80 | E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */ | 81 | E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */ |
81 | E1000_EEWR = 0x0102C, /* EEPROM Write Register - RW */ | 82 | E1000_EEWR = 0x0102C, /* EEPROM Write Register - RW */ |
82 | E1000_FLOP = 0x0103C, /* FLASH Opcode Register */ | 83 | E1000_FLOP = 0x0103C, /* FLASH Opcode Register */ |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 976336547607..24d9f61956f0 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
@@ -3624,6 +3624,17 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) | |||
3624 | if (hw->mac.type == e1000_ich8lan) | 3624 | if (hw->mac.type == e1000_ich8lan) |
3625 | reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); | 3625 | reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); |
3626 | ew32(RFCTL, reg); | 3626 | ew32(RFCTL, reg); |
3627 | |||
3628 | /* Enable ECC on Lynxpoint */ | ||
3629 | if (hw->mac.type == e1000_pch_lpt) { | ||
3630 | reg = er32(PBECCSTS); | ||
3631 | reg |= E1000_PBECCSTS_ECC_ENABLE; | ||
3632 | ew32(PBECCSTS, reg); | ||
3633 | |||
3634 | reg = er32(CTRL); | ||
3635 | reg |= E1000_CTRL_MEHE; | ||
3636 | ew32(CTRL, reg); | ||
3637 | } | ||
3627 | } | 3638 | } |
3628 | 3639 | ||
3629 | /** | 3640 | /** |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index fbf75fdca994..643c883dd795 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -1678,6 +1678,23 @@ static irqreturn_t e1000_intr_msi(int irq, void *data) | |||
1678 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 1678 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
1679 | } | 1679 | } |
1680 | 1680 | ||
1681 | /* Reset on uncorrectable ECC error */ | ||
1682 | if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) { | ||
1683 | u32 pbeccsts = er32(PBECCSTS); | ||
1684 | |||
1685 | adapter->corr_errors += | ||
1686 | pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; | ||
1687 | adapter->uncorr_errors += | ||
1688 | (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> | ||
1689 | E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; | ||
1690 | |||
1691 | /* Do the reset outside of interrupt context */ | ||
1692 | schedule_work(&adapter->reset_task); | ||
1693 | |||
1694 | /* return immediately since reset is imminent */ | ||
1695 | return IRQ_HANDLED; | ||
1696 | } | ||
1697 | |||
1681 | if (napi_schedule_prep(&adapter->napi)) { | 1698 | if (napi_schedule_prep(&adapter->napi)) { |
1682 | adapter->total_tx_bytes = 0; | 1699 | adapter->total_tx_bytes = 0; |
1683 | adapter->total_tx_packets = 0; | 1700 | adapter->total_tx_packets = 0; |
@@ -1741,6 +1758,23 @@ static irqreturn_t e1000_intr(int irq, void *data) | |||
1741 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 1758 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
1742 | } | 1759 | } |
1743 | 1760 | ||
1761 | /* Reset on uncorrectable ECC error */ | ||
1762 | if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) { | ||
1763 | u32 pbeccsts = er32(PBECCSTS); | ||
1764 | |||
1765 | adapter->corr_errors += | ||
1766 | pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; | ||
1767 | adapter->uncorr_errors += | ||
1768 | (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> | ||
1769 | E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; | ||
1770 | |||
1771 | /* Do the reset outside of interrupt context */ | ||
1772 | schedule_work(&adapter->reset_task); | ||
1773 | |||
1774 | /* return immediately since reset is imminent */ | ||
1775 | return IRQ_HANDLED; | ||
1776 | } | ||
1777 | |||
1744 | if (napi_schedule_prep(&adapter->napi)) { | 1778 | if (napi_schedule_prep(&adapter->napi)) { |
1745 | adapter->total_tx_bytes = 0; | 1779 | adapter->total_tx_bytes = 0; |
1746 | adapter->total_tx_packets = 0; | 1780 | adapter->total_tx_packets = 0; |
@@ -2104,6 +2138,8 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) | |||
2104 | if (adapter->msix_entries) { | 2138 | if (adapter->msix_entries) { |
2105 | ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); | 2139 | ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); |
2106 | ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); | 2140 | ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); |
2141 | } else if (hw->mac.type == e1000_pch_lpt) { | ||
2142 | ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER); | ||
2107 | } else { | 2143 | } else { |
2108 | ew32(IMS, IMS_ENABLE_MASK); | 2144 | ew32(IMS, IMS_ENABLE_MASK); |
2109 | } | 2145 | } |
@@ -4251,6 +4287,16 @@ static void e1000e_update_stats(struct e1000_adapter *adapter) | |||
4251 | adapter->stats.mgptc += er32(MGTPTC); | 4287 | adapter->stats.mgptc += er32(MGTPTC); |
4252 | adapter->stats.mgprc += er32(MGTPRC); | 4288 | adapter->stats.mgprc += er32(MGTPRC); |
4253 | adapter->stats.mgpdc += er32(MGTPDC); | 4289 | adapter->stats.mgpdc += er32(MGTPDC); |
4290 | |||
4291 | /* Correctable ECC Errors */ | ||
4292 | if (hw->mac.type == e1000_pch_lpt) { | ||
4293 | u32 pbeccsts = er32(PBECCSTS); | ||
4294 | adapter->corr_errors += | ||
4295 | pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; | ||
4296 | adapter->uncorr_errors += | ||
4297 | (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> | ||
4298 | E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; | ||
4299 | } | ||
4254 | } | 4300 | } |
4255 | 4301 | ||
4256 | /** | 4302 | /** |