summaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_main.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 50709da922c7..44adc9862826 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -513,8 +513,11 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
* @skb: skb currently being received and modified
**/
static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
- u32 status_err, struct sk_buff *skb)
+ union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb)
{
+ u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error);
+
skb->ip_summed = CHECKSUM_NONE;
/* Rx csum disabled */
@@ -532,6 +535,16 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
return;
if (status_err & IXGBE_RXDADV_ERR_TCPE) {
+ u16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
+
+ /*
+ * 82599 errata, UDP frames with a 0 checksum can be marked as
+ * checksum errors.
+ */
+ if ((pkt_info & IXGBE_RXDADV_PKTTYPE_UDP) &&
+ (adapter->hw.mac.type == ixgbe_mac_82599EB))
+ return;
+
adapter->hw_csum_rx_error++;
return;
}
@@ -769,7 +782,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
prefetch(next_rxd);
cleaned_count++;
- if (adapter->flags & IXGBE_FLAG2_RSC_CAPABLE)
+ if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
rsc_count = ixgbe_get_rsc_count(rx_desc);
if (rsc_count) {
@@ -805,7 +818,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
goto next_desc;
}
- ixgbe_rx_checksum(adapter, staterr, skb);
+ ixgbe_rx_checksum(adapter, rx_desc, skb);
/* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len;
@@ -2025,7 +2038,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
}
} else {
- if (!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED) &&
+ if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) &&
(netdev->mtu <= ETH_DATA_LEN))
rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
else
@@ -2154,7 +2167,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
}
- if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) {
+ if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
/* Enable 82599 HW-RSC */
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i].reg_idx;
@@ -3801,8 +3814,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598;
} else if (hw->mac.type == ixgbe_mac_82599EB) {
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
- adapter->flags |= IXGBE_FLAG2_RSC_CAPABLE;
- adapter->flags |= IXGBE_FLAG2_RSC_ENABLED;
+ adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE;
+ adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
adapter->ring_feature[RING_F_FDIR].indices =
IXGBE_MAX_FDIR_INDICES;
@@ -5349,12 +5362,19 @@ static int ixgbe_del_sanmac_netdev(struct net_device *dev)
static void ixgbe_netpoll(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ int i;
- disable_irq(adapter->pdev->irq);
adapter->flags |= IXGBE_FLAG_IN_NETPOLL;
- ixgbe_intr(adapter->pdev->irq, netdev);
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+ for (i = 0; i < num_q_vectors; i++) {
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
+ ixgbe_msix_clean_many(0, q_vector);
+ }
+ } else {
+ ixgbe_intr(adapter->pdev->irq, netdev);
+ }
adapter->flags &= ~IXGBE_FLAG_IN_NETPOLL;
- enable_irq(adapter->pdev->irq);
}
#endif
@@ -5600,7 +5620,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED)
+ if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
netdev->features |= NETIF_F_LRO;
/* make sure the EEPROM is good */