|
@@ -44,6 +44,7 @@
|
|
|
|
|
|
#include "ixgbe.h"
|
|
|
#include "ixgbe_common.h"
|
|
|
+#include "ixgbe_dcb_82599.h"
|
|
|
|
|
|
char ixgbe_driver_name[] = "ixgbe";
|
|
|
static const char ixgbe_driver_string[] =
|
|
@@ -228,6 +229,56 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
|
|
|
/* tx_buffer_info must be completely set up in the transmit path */
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * ixgbe_tx_is_paused - check if the tx ring is paused
|
|
|
+ * @adapter: the ixgbe adapter
|
|
|
+ * @tx_ring: the corresponding tx_ring
|
|
|
+ *
|
|
|
+ * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the
|
|
|
+ * corresponding TC of this tx_ring when checking TFCS.
|
|
|
+ *
|
|
|
+ * Returns : true if paused
|
|
|
+ */
|
|
|
+static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
|
|
|
+ struct ixgbe_ring *tx_ring)
|
|
|
+{
|
|
|
+ int tc;
|
|
|
+ u32 txoff = IXGBE_TFCS_TXOFF;
|
|
|
+
|
|
|
+#ifdef CONFIG_IXGBE_DCB
|
|
|
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
|
|
|
+ int reg_idx = tx_ring->reg_idx;
|
|
|
+ int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
|
|
|
+
|
|
|
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
|
|
|
+ tc = reg_idx >> 2;
|
|
|
+ txoff = IXGBE_TFCS_TXOFF0;
|
|
|
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
|
|
|
+ tc = 0;
|
|
|
+ txoff = IXGBE_TFCS_TXOFF;
|
|
|
+ if (dcb_i == 8) {
|
|
|
+ /* TC0, TC1 */
|
|
|
+ tc = reg_idx >> 5;
|
|
|
+ if (tc == 2) /* TC2, TC3 */
|
|
|
+ tc += (reg_idx - 64) >> 4;
|
|
|
+ else if (tc == 3) /* TC4, TC5, TC6, TC7 */
|
|
|
+ tc += 1 + ((reg_idx - 96) >> 3);
|
|
|
+ } else if (dcb_i == 4) {
|
|
|
+ /* TC0, TC1 */
|
|
|
+ tc = reg_idx >> 6;
|
|
|
+ if (tc == 1) {
|
|
|
+ tc += (reg_idx - 64) >> 5;
|
|
|
+ if (tc == 2) /* TC2, TC3 */
|
|
|
+ tc += (reg_idx - 96) >> 4;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ txoff <<= tc;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff;
|
|
|
+}
|
|
|
+
|
|
|
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
|
|
|
struct ixgbe_ring *tx_ring,
|
|
|
unsigned int eop)
|
|
@@ -239,7 +290,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
|
|
|
adapter->detect_tx_hung = false;
|
|
|
if (tx_ring->tx_buffer_info[eop].time_stamp &&
|
|
|
time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
|
|
|
- !(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) {
|
|
|
+ !ixgbe_tx_is_paused(adapter, tx_ring)) {
|
|
|
/* detected Tx unit hang */
|
|
|
union ixgbe_adv_tx_desc *tx_desc;
|
|
|
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
|
|
@@ -414,19 +465,23 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
|
|
|
u32 txctrl;
|
|
|
int cpu = get_cpu();
|
|
|
int q = tx_ring - adapter->tx_ring;
|
|
|
+ struct ixgbe_hw *hw = &adapter->hw;
|
|
|
|
|
|
if (tx_ring->cpu != cpu) {
|
|
|
- txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q));
|
|
|
if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
|
|
|
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(q));
|
|
|
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
|
|
|
txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
|
|
|
+ txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(q), txctrl);
|
|
|
} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
|
|
|
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q));
|
|
|
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
|
|
|
txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
|
|
|
- IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
|
|
|
+ IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
|
|
|
+ txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl);
|
|
|
}
|
|
|
- txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
|
|
|
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl);
|
|
|
tx_ring->cpu = cpu;
|
|
|
}
|
|
|
put_cpu();
|
|
@@ -1908,11 +1963,25 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
if (hw->mac.type == ixgbe_mac_82599EB) {
|
|
|
+ u32 rttdcs;
|
|
|
+
|
|
|
+ /* disable the arbiter while setting MTQC */
|
|
|
+ rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
|
|
|
+ rttdcs |= IXGBE_RTTDCS_ARBDIS;
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
|
|
|
+
|
|
|
/* We enable 8 traffic classes, DCB only */
|
|
|
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_RT_ENA |
|
|
|
IXGBE_MTQC_8TC_8TQ));
|
|
|
+ else
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
|
|
|
+
|
|
|
+ /* re-eable the arbiter */
|
|
|
+ rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2466,7 +2535,10 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
|
|
|
ixgbe_restore_vlan(adapter);
|
|
|
#ifdef CONFIG_IXGBE_DCB
|
|
|
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
|
|
|
- netif_set_gso_max_size(netdev, 32768);
|
|
|
+ if (hw->mac.type == ixgbe_mac_82598EB)
|
|
|
+ netif_set_gso_max_size(netdev, 32768);
|
|
|
+ else
|
|
|
+ netif_set_gso_max_size(netdev, 65536);
|
|
|
ixgbe_configure_dcb(adapter);
|
|
|
} else {
|
|
|
netif_set_gso_max_size(netdev, 65536);
|