Commit 5d91c2d0 authored by David S. Miller's avatar David S. Miller
parents 17e6abee 560f20da
...@@ -309,6 +309,7 @@ struct e1000_adapter { ...@@ -309,6 +309,7 @@ struct e1000_adapter {
u32 txd_cmd; u32 txd_cmd;
bool detect_tx_hung; bool detect_tx_hung;
bool tx_hang_recheck;
u8 tx_timeout_factor; u8 tx_timeout_factor;
u32 tx_int_delay; u32 tx_int_delay;
......
...@@ -1014,6 +1014,7 @@ static void e1000_print_hw_hang(struct work_struct *work) ...@@ -1014,6 +1014,7 @@ static void e1000_print_hw_hang(struct work_struct *work)
struct e1000_adapter *adapter = container_of(work, struct e1000_adapter *adapter = container_of(work,
struct e1000_adapter, struct e1000_adapter,
print_hang_task); print_hang_task);
struct net_device *netdev = adapter->netdev;
struct e1000_ring *tx_ring = adapter->tx_ring; struct e1000_ring *tx_ring = adapter->tx_ring;
unsigned int i = tx_ring->next_to_clean; unsigned int i = tx_ring->next_to_clean;
unsigned int eop = tx_ring->buffer_info[i].next_to_watch; unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
...@@ -1025,6 +1026,21 @@ static void e1000_print_hw_hang(struct work_struct *work) ...@@ -1025,6 +1026,21 @@ static void e1000_print_hw_hang(struct work_struct *work)
if (test_bit(__E1000_DOWN, &adapter->state)) if (test_bit(__E1000_DOWN, &adapter->state))
return; return;
if (!adapter->tx_hang_recheck &&
(adapter->flags2 & FLAG2_DMA_BURST)) {
/* May be block on write-back, flush and detect again
* flush pending descriptor writebacks to memory
*/
ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
/* execute the writes immediately */
e1e_flush();
adapter->tx_hang_recheck = true;
return;
}
/* Real hang detected */
adapter->tx_hang_recheck = false;
netif_stop_queue(netdev);
e1e_rphy(hw, PHY_STATUS, &phy_status); e1e_rphy(hw, PHY_STATUS, &phy_status);
e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
...@@ -1145,10 +1161,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) ...@@ -1145,10 +1161,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
if (tx_ring->buffer_info[i].time_stamp && if (tx_ring->buffer_info[i].time_stamp &&
time_after(jiffies, tx_ring->buffer_info[i].time_stamp time_after(jiffies, tx_ring->buffer_info[i].time_stamp
+ (adapter->tx_timeout_factor * HZ)) && + (adapter->tx_timeout_factor * HZ)) &&
!(er32(STATUS) & E1000_STATUS_TXOFF)) { !(er32(STATUS) & E1000_STATUS_TXOFF))
schedule_work(&adapter->print_hang_task); schedule_work(&adapter->print_hang_task);
netif_stop_queue(netdev); else
} adapter->tx_hang_recheck = false;
} }
adapter->total_tx_bytes += total_tx_bytes; adapter->total_tx_bytes += total_tx_bytes;
adapter->total_tx_packets += total_tx_packets; adapter->total_tx_packets += total_tx_packets;
...@@ -3500,7 +3516,6 @@ int e1000e_up(struct e1000_adapter *adapter) ...@@ -3500,7 +3516,6 @@ int e1000e_up(struct e1000_adapter *adapter)
clear_bit(__E1000_DOWN, &adapter->state); clear_bit(__E1000_DOWN, &adapter->state);
napi_enable(&adapter->napi);
if (adapter->msix_entries) if (adapter->msix_entries)
e1000_configure_msix(adapter); e1000_configure_msix(adapter);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
...@@ -3562,7 +3577,6 @@ void e1000e_down(struct e1000_adapter *adapter) ...@@ -3562,7 +3577,6 @@ void e1000e_down(struct e1000_adapter *adapter)
e1e_flush(); e1e_flush();
usleep_range(10000, 20000); usleep_range(10000, 20000);
napi_disable(&adapter->napi);
e1000_irq_disable(adapter); e1000_irq_disable(adapter);
del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->watchdog_timer);
...@@ -3838,6 +3852,7 @@ static int e1000_open(struct net_device *netdev) ...@@ -3838,6 +3852,7 @@ static int e1000_open(struct net_device *netdev)
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
adapter->tx_hang_recheck = false;
netif_start_queue(netdev); netif_start_queue(netdev);
adapter->idle_check = true; adapter->idle_check = true;
...@@ -3884,6 +3899,8 @@ static int e1000_close(struct net_device *netdev) ...@@ -3884,6 +3899,8 @@ static int e1000_close(struct net_device *netdev)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
napi_disable(&adapter->napi);
if (!test_bit(__E1000_DOWN, &adapter->state)) { if (!test_bit(__E1000_DOWN, &adapter->state)) {
e1000e_down(adapter); e1000e_down(adapter);
e1000_free_irq(adapter); e1000_free_irq(adapter);
......
...@@ -7061,15 +7061,28 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) ...@@ -7061,15 +7061,28 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
wr32(E1000_DMCTXTH, 0); wr32(E1000_DMCTXTH, 0);
/* /*
* DMA Coalescing high water mark needs to be higher * DMA Coalescing high water mark needs to be greater
* than the RX threshold. set hwm to PBA - 2 * max * than the Rx threshold. Set hwm to PBA - max frame
* frame size * size in 16B units, capping it at PBA - 6KB.
*/ */
hwm = pba - (2 * adapter->max_frame_size); hwm = 64 * pba - adapter->max_frame_size / 16;
if (hwm < 64 * (pba - 6))
hwm = 64 * (pba - 6);
reg = rd32(E1000_FCRTC);
reg &= ~E1000_FCRTC_RTH_COAL_MASK;
reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
& E1000_FCRTC_RTH_COAL_MASK);
wr32(E1000_FCRTC, reg);
/*
* Set the DMA Coalescing Rx threshold to PBA - 2 * max
* frame size, capping it at PBA - 10KB.
*/
dmac_thr = pba - adapter->max_frame_size / 512;
if (dmac_thr < pba - 10)
dmac_thr = pba - 10;
reg = rd32(E1000_DMACR); reg = rd32(E1000_DMACR);
reg &= ~E1000_DMACR_DMACTHR_MASK; reg &= ~E1000_DMACR_DMACTHR_MASK;
dmac_thr = pba - 4;
reg |= ((dmac_thr << E1000_DMACR_DMACTHR_SHIFT) reg |= ((dmac_thr << E1000_DMACR_DMACTHR_SHIFT)
& E1000_DMACR_DMACTHR_MASK); & E1000_DMACR_DMACTHR_MASK);
...@@ -7085,7 +7098,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) ...@@ -7085,7 +7098,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
* coalescing(smart fifb)-UTRESH=0 * coalescing(smart fifb)-UTRESH=0
*/ */
wr32(E1000_DMCRTRH, 0); wr32(E1000_DMCRTRH, 0);
wr32(E1000_FCRTC, hwm);
reg = (IGB_DMCTLX_DCFLUSH_DIS | 0x4); reg = (IGB_DMCTLX_DCFLUSH_DIS | 0x4);
......
...@@ -158,10 +158,6 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, ...@@ -158,10 +158,6 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
/* Abort a bad configuration */
if (ffs(up_map) > adapter->dcb_cfg.num_tcs.pg_tcs)
return;
if (prio != DCB_ATTR_VALUE_UNDEFINED) if (prio != DCB_ATTR_VALUE_UNDEFINED)
adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio; adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio;
if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) if (bwg_id != DCB_ATTR_VALUE_UNDEFINED)
...@@ -185,7 +181,7 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, ...@@ -185,7 +181,7 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
if (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != if (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap !=
adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap) adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)
adapter->dcb_set_bitmap |= BIT_PFC; adapter->dcb_set_bitmap |= BIT_PFC | BIT_APP_UPCHG;
} }
static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
...@@ -206,10 +202,6 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, ...@@ -206,10 +202,6 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
/* Abort bad configurations */
if (ffs(up_map) > adapter->dcb_cfg.num_tcs.pg_tcs)
return;
if (prio != DCB_ATTR_VALUE_UNDEFINED) if (prio != DCB_ATTR_VALUE_UNDEFINED)
adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio; adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio;
if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) if (bwg_id != DCB_ATTR_VALUE_UNDEFINED)
...@@ -309,6 +301,27 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, ...@@ -309,6 +301,27 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
*setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc; *setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc;
} }
#ifdef IXGBE_FCOE
static void ixgbe_dcbnl_devreset(struct net_device *dev)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
usleep_range(1000, 2000);
if (netif_running(dev))
dev->netdev_ops->ndo_stop(dev);
ixgbe_clear_interrupt_scheme(adapter);
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(dev))
dev->netdev_ops->ndo_open(dev);
clear_bit(__IXGBE_RESETTING, &adapter->state);
}
#endif
static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
...@@ -338,27 +351,6 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) ...@@ -338,27 +351,6 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
if (ret) if (ret)
return DCB_NO_HW_CHG; return DCB_NO_HW_CHG;
#ifdef IXGBE_FCOE
if (up && !(up & (1 << adapter->fcoe.up)))
adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
/*
* Only take down the adapter if an app change occurred. FCoE
* may shuffle tx rings in this case and this can not be done
* without a reset currently.
*/
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
usleep_range(1000, 2000);
adapter->fcoe.up = ffs(up) - 1;
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_clear_interrupt_scheme(adapter);
}
#endif
if (adapter->dcb_cfg.pfc_mode_enable) { if (adapter->dcb_cfg.pfc_mode_enable) {
switch (adapter->hw.mac.type) { switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB: case ixgbe_mac_82599EB:
...@@ -385,15 +377,6 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) ...@@ -385,15 +377,6 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
} }
} }
#ifdef IXGBE_FCOE
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
netdev->netdev_ops->ndo_open(netdev);
ret = DCB_HW_CHG_RST;
}
#endif
if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) {
u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS];
u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS];
...@@ -442,8 +425,19 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) ...@@ -442,8 +425,19 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
if (adapter->dcb_cfg.pfc_mode_enable) if (adapter->dcb_cfg.pfc_mode_enable)
adapter->hw.fc.current_mode = ixgbe_fc_pfc; adapter->hw.fc.current_mode = ixgbe_fc_pfc;
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) #ifdef IXGBE_FCOE
clear_bit(__IXGBE_RESETTING, &adapter->state); /* Reprogam FCoE hardware offloads when the traffic class
* FCoE is using changes. This happens if the APP info
* changes or the up2tc mapping is updated.
*/
if ((up && !(up & (1 << adapter->fcoe.up))) ||
(adapter->dcb_set_bitmap & BIT_APP_UPCHG)) {
adapter->fcoe.up = ffs(up) - 1;
ixgbe_dcbnl_devreset(netdev);
ret = DCB_HW_CHG_RST;
}
#endif
adapter->dcb_set_bitmap = 0x00; adapter->dcb_set_bitmap = 0x00;
return ret; return ret;
} }
...@@ -661,22 +655,6 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, ...@@ -661,22 +655,6 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
return ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en, prio_tc); return ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en, prio_tc);
} }
#ifdef IXGBE_FCOE
static void ixgbe_dcbnl_devreset(struct net_device *dev)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
if (netif_running(dev))
dev->netdev_ops->ndo_stop(dev);
ixgbe_clear_interrupt_scheme(adapter);
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(dev))
dev->netdev_ops->ndo_open(dev);
}
#endif
static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
struct dcb_app *app) struct dcb_app *app)
{ {
...@@ -761,7 +739,9 @@ static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode) ...@@ -761,7 +739,9 @@ static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode)
ixgbe_dcbnl_ieee_setets(dev, &ets); ixgbe_dcbnl_ieee_setets(dev, &ets);
ixgbe_dcbnl_ieee_setpfc(dev, &pfc); ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
} else if (mode & DCB_CAP_DCBX_VER_CEE) { } else if (mode & DCB_CAP_DCBX_VER_CEE) {
adapter->dcb_set_bitmap |= (BIT_PFC & BIT_PG_TX & BIT_PG_RX); u8 mask = BIT_PFC | BIT_PG_TX | BIT_PG_RX | BIT_APP_UPCHG;
adapter->dcb_set_bitmap |= mask;
ixgbe_dcbnl_set_all(dev); ixgbe_dcbnl_set_all(dev);
} else { } else {
/* Drop into single TC mode strict priority as this /* Drop into single TC mode strict priority as this
......
...@@ -33,7 +33,6 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter); ...@@ -33,7 +33,6 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter);
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask); int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter); void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
void ixgbe_dump_registers(struct ixgbe_adapter *adapter);
int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
u8 qos); u8 qos);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment