|
@@ -1071,7 +1071,8 @@ next_desc:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void e1000_put_txbuf(struct e1000_ring *tx_ring,
|
|
static void e1000_put_txbuf(struct e1000_ring *tx_ring,
|
|
|
- struct e1000_buffer *buffer_info)
|
|
|
|
|
|
|
+ struct e1000_buffer *buffer_info,
|
|
|
|
|
+ bool drop)
|
|
|
{
|
|
{
|
|
|
struct e1000_adapter *adapter = tx_ring->adapter;
|
|
struct e1000_adapter *adapter = tx_ring->adapter;
|
|
|
|
|
|
|
@@ -1085,7 +1086,10 @@ static void e1000_put_txbuf(struct e1000_ring *tx_ring,
|
|
|
buffer_info->dma = 0;
|
|
buffer_info->dma = 0;
|
|
|
}
|
|
}
|
|
|
if (buffer_info->skb) {
|
|
if (buffer_info->skb) {
|
|
|
- dev_kfree_skb_any(buffer_info->skb);
|
|
|
|
|
|
|
+ if (drop)
|
|
|
|
|
+ dev_kfree_skb_any(buffer_info->skb);
|
|
|
|
|
+ else
|
|
|
|
|
+ dev_consume_skb_any(buffer_info->skb);
|
|
|
buffer_info->skb = NULL;
|
|
buffer_info->skb = NULL;
|
|
|
}
|
|
}
|
|
|
buffer_info->time_stamp = 0;
|
|
buffer_info->time_stamp = 0;
|
|
@@ -1199,7 +1203,7 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work)
|
|
|
wmb(); /* force write prior to skb_tstamp_tx */
|
|
wmb(); /* force write prior to skb_tstamp_tx */
|
|
|
|
|
|
|
|
skb_tstamp_tx(skb, &shhwtstamps);
|
|
skb_tstamp_tx(skb, &shhwtstamps);
|
|
|
- dev_kfree_skb_any(skb);
|
|
|
|
|
|
|
+ dev_consume_skb_any(skb);
|
|
|
} else if (time_after(jiffies, adapter->tx_hwtstamp_start
|
|
} else if (time_after(jiffies, adapter->tx_hwtstamp_start
|
|
|
+ adapter->tx_timeout_factor * HZ)) {
|
|
+ adapter->tx_timeout_factor * HZ)) {
|
|
|
dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
|
|
dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
|
|
@@ -1254,7 +1258,7 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- e1000_put_txbuf(tx_ring, buffer_info);
|
|
|
|
|
|
|
+ e1000_put_txbuf(tx_ring, buffer_info, false);
|
|
|
tx_desc->upper.data = 0;
|
|
tx_desc->upper.data = 0;
|
|
|
|
|
|
|
|
i++;
|
|
i++;
|
|
@@ -1910,14 +1914,30 @@ static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
|
|
|
struct net_device *netdev = data;
|
|
struct net_device *netdev = data;
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
+ u32 icr;
|
|
|
|
|
+ bool enable = true;
|
|
|
|
|
+
|
|
|
|
|
+ icr = er32(ICR);
|
|
|
|
|
+ if (icr & E1000_ICR_RXO) {
|
|
|
|
|
+ ew32(ICR, E1000_ICR_RXO);
|
|
|
|
|
+ enable = false;
|
|
|
|
|
+ /* napi poll will re-enable Other, make sure it runs */
|
|
|
|
|
+ if (napi_schedule_prep(&adapter->napi)) {
|
|
|
|
|
+ adapter->total_rx_bytes = 0;
|
|
|
|
|
+ adapter->total_rx_packets = 0;
|
|
|
|
|
+ __napi_schedule(&adapter->napi);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (icr & E1000_ICR_LSC) {
|
|
|
|
|
+ ew32(ICR, E1000_ICR_LSC);
|
|
|
|
|
+ hw->mac.get_link_status = true;
|
|
|
|
|
+ /* guard against interrupt when we're going down */
|
|
|
|
|
+ if (!test_bit(__E1000_DOWN, &adapter->state))
|
|
|
|
|
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- hw->mac.get_link_status = true;
|
|
|
|
|
-
|
|
|
|
|
- /* guard against interrupt when we're going down */
|
|
|
|
|
- if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
|
|
|
|
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
|
|
|
|
|
|
+ if (enable && !test_bit(__E1000_DOWN, &adapter->state))
|
|
|
ew32(IMS, E1000_IMS_OTHER);
|
|
ew32(IMS, E1000_IMS_OTHER);
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
}
|
|
@@ -2421,7 +2441,7 @@ static void e1000_clean_tx_ring(struct e1000_ring *tx_ring)
|
|
|
|
|
|
|
|
for (i = 0; i < tx_ring->count; i++) {
|
|
for (i = 0; i < tx_ring->count; i++) {
|
|
|
buffer_info = &tx_ring->buffer_info[i];
|
|
buffer_info = &tx_ring->buffer_info[i];
|
|
|
- e1000_put_txbuf(tx_ring, buffer_info);
|
|
|
|
|
|
|
+ e1000_put_txbuf(tx_ring, buffer_info, false);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
netdev_reset_queue(adapter->netdev);
|
|
netdev_reset_queue(adapter->netdev);
|
|
@@ -2687,7 +2707,8 @@ static int e1000e_poll(struct napi_struct *napi, int weight)
|
|
|
napi_complete_done(napi, work_done);
|
|
napi_complete_done(napi, work_done);
|
|
|
if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
|
if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
|
|
if (adapter->msix_entries)
|
|
if (adapter->msix_entries)
|
|
|
- ew32(IMS, adapter->rx_ring->ims_val);
|
|
|
|
|
|
|
+ ew32(IMS, adapter->rx_ring->ims_val |
|
|
|
|
|
+ E1000_IMS_OTHER);
|
|
|
else
|
|
else
|
|
|
e1000_irq_enable(adapter);
|
|
e1000_irq_enable(adapter);
|
|
|
}
|
|
}
|
|
@@ -3004,8 +3025,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
|
|
|
|
|
|
|
|
hw->mac.ops.config_collision_dist(hw);
|
|
hw->mac.ops.config_collision_dist(hw);
|
|
|
|
|
|
|
|
- /* SPT and CNP Si errata workaround to avoid data corruption */
|
|
|
|
|
- if (hw->mac.type >= e1000_pch_spt) {
|
|
|
|
|
|
|
+ /* SPT and KBL Si errata workaround to avoid data corruption */
|
|
|
|
|
+ if (hw->mac.type == e1000_pch_spt) {
|
|
|
u32 reg_val;
|
|
u32 reg_val;
|
|
|
|
|
|
|
|
reg_val = er32(IOSFPC);
|
|
reg_val = er32(IOSFPC);
|
|
@@ -3013,7 +3034,9 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
|
|
|
ew32(IOSFPC, reg_val);
|
|
ew32(IOSFPC, reg_val);
|
|
|
|
|
|
|
|
reg_val = er32(TARC(0));
|
|
reg_val = er32(TARC(0));
|
|
|
- reg_val |= E1000_TARC0_CB_MULTIQ_3_REQ;
|
|
|
|
|
|
|
+ /* SPT and KBL Si errata workaround to avoid Tx hang */
|
|
|
|
|
+ reg_val &= ~BIT(28);
|
|
|
|
|
+ reg_val |= BIT(29);
|
|
|
ew32(TARC(0), reg_val);
|
|
ew32(TARC(0), reg_val);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -3223,14 +3246,6 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
|
|
|
*/
|
|
*/
|
|
|
ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
|
|
ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
|
|
|
ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
|
|
ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
|
|
|
-
|
|
|
|
|
- /* override the delay timers for enabling bursting, only if
|
|
|
|
|
- * the value was not set by the user via module options
|
|
|
|
|
- */
|
|
|
|
|
- if (adapter->rx_int_delay == DEFAULT_RDTR)
|
|
|
|
|
- adapter->rx_int_delay = BURST_RDTR;
|
|
|
|
|
- if (adapter->rx_abs_int_delay == DEFAULT_RADV)
|
|
|
|
|
- adapter->rx_abs_int_delay = BURST_RADV;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* set the Receive Delay Timer Register */
|
|
/* set the Receive Delay Timer Register */
|
|
@@ -4204,7 +4219,7 @@ static void e1000e_trigger_lsc(struct e1000_adapter *adapter)
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
|
|
if (adapter->msix_entries)
|
|
if (adapter->msix_entries)
|
|
|
- ew32(ICS, E1000_ICS_OTHER);
|
|
|
|
|
|
|
+ ew32(ICS, E1000_ICS_LSC | E1000_ICS_OTHER);
|
|
|
else
|
|
else
|
|
|
ew32(ICS, E1000_ICS_LSC);
|
|
ew32(ICS, E1000_ICS_LSC);
|
|
|
}
|
|
}
|
|
@@ -5074,14 +5089,14 @@ static bool e1000e_has_link(struct e1000_adapter *adapter)
|
|
|
|
|
|
|
|
/* get_link_status is set on LSC (link status) interrupt or
|
|
/* get_link_status is set on LSC (link status) interrupt or
|
|
|
* Rx sequence error interrupt. get_link_status will stay
|
|
* Rx sequence error interrupt. get_link_status will stay
|
|
|
- * false until the check_for_link establishes link
|
|
|
|
|
|
|
+ * true until the check_for_link establishes link
|
|
|
* for copper adapters ONLY
|
|
* for copper adapters ONLY
|
|
|
*/
|
|
*/
|
|
|
switch (hw->phy.media_type) {
|
|
switch (hw->phy.media_type) {
|
|
|
case e1000_media_type_copper:
|
|
case e1000_media_type_copper:
|
|
|
if (hw->mac.get_link_status) {
|
|
if (hw->mac.get_link_status) {
|
|
|
ret_val = hw->mac.ops.check_for_link(hw);
|
|
ret_val = hw->mac.ops.check_for_link(hw);
|
|
|
- link_active = !hw->mac.get_link_status;
|
|
|
|
|
|
|
+ link_active = ret_val > 0;
|
|
|
} else {
|
|
} else {
|
|
|
link_active = true;
|
|
link_active = true;
|
|
|
}
|
|
}
|
|
@@ -5092,14 +5107,14 @@ static bool e1000e_has_link(struct e1000_adapter *adapter)
|
|
|
break;
|
|
break;
|
|
|
case e1000_media_type_internal_serdes:
|
|
case e1000_media_type_internal_serdes:
|
|
|
ret_val = hw->mac.ops.check_for_link(hw);
|
|
ret_val = hw->mac.ops.check_for_link(hw);
|
|
|
- link_active = adapter->hw.mac.serdes_has_link;
|
|
|
|
|
|
|
+ link_active = hw->mac.serdes_has_link;
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
case e1000_media_type_unknown:
|
|
case e1000_media_type_unknown:
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
|
|
|
|
|
|
|
+ if ((ret_val == -E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
|
|
|
(er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
|
|
(er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
|
|
|
/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
|
|
/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
|
|
|
e_info("Gigabit has been disabled, downgrading speed\n");
|
|
e_info("Gigabit has been disabled, downgrading speed\n");
|
|
@@ -5614,7 +5629,7 @@ dma_error:
|
|
|
i += tx_ring->count;
|
|
i += tx_ring->count;
|
|
|
i--;
|
|
i--;
|
|
|
buffer_info = &tx_ring->buffer_info[i];
|
|
buffer_info = &tx_ring->buffer_info[i];
|
|
|
- e1000_put_txbuf(tx_ring, buffer_info);
|
|
|
|
|
|
|
+ e1000_put_txbuf(tx_ring, buffer_info, true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -7408,7 +7423,7 @@ static void e1000_remove(struct pci_dev *pdev)
|
|
|
if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
|
|
if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
|
|
|
cancel_work_sync(&adapter->tx_hwtstamp_work);
|
|
cancel_work_sync(&adapter->tx_hwtstamp_work);
|
|
|
if (adapter->tx_hwtstamp_skb) {
|
|
if (adapter->tx_hwtstamp_skb) {
|
|
|
- dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
|
|
|
|
|
|
|
+ dev_consume_skb_any(adapter->tx_hwtstamp_skb);
|
|
|
adapter->tx_hwtstamp_skb = NULL;
|
|
adapter->tx_hwtstamp_skb = NULL;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|