Commit 3ceb90fd authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Kirsher

igb: leave staterr in place and instead us a helper function to check bits

Instead of doing a byte swap on the staterr bits in the Rx descriptor we can
save ourselves a bit of space and some CPU time by instead just testing for
the various bits out of the Rx descriptor directly.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Tested-by: default avatarAaron Brown  <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 294e7d78
...@@ -259,6 +259,13 @@ enum e1000_ring_flags_t { ...@@ -259,6 +259,13 @@ enum e1000_ring_flags_t {
#define IGB_TX_CTXTDESC(R, i) \ #define IGB_TX_CTXTDESC(R, i) \
(&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i])) (&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i]))
/* igb_test_staterr - tests bits within Rx descriptor status and error fields */
static inline __le32 igb_test_staterr(union e1000_adv_rx_desc *rx_desc,
const u32 stat_err_bits)
{
return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits);
}
/* igb_desc_unused - calculate if we have unused descriptors */ /* igb_desc_unused - calculate if we have unused descriptors */
static inline int igb_desc_unused(struct igb_ring *ring) static inline int igb_desc_unused(struct igb_ring *ring)
{ {
......
...@@ -1581,16 +1581,14 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring, ...@@ -1581,16 +1581,14 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring,
union e1000_adv_rx_desc *rx_desc; union e1000_adv_rx_desc *rx_desc;
struct igb_rx_buffer *rx_buffer_info; struct igb_rx_buffer *rx_buffer_info;
struct igb_tx_buffer *tx_buffer_info; struct igb_tx_buffer *tx_buffer_info;
u32 staterr;
u16 rx_ntc, tx_ntc, count = 0; u16 rx_ntc, tx_ntc, count = 0;
/* initialize next to clean and descriptor values */ /* initialize next to clean and descriptor values */
rx_ntc = rx_ring->next_to_clean; rx_ntc = rx_ring->next_to_clean;
tx_ntc = tx_ring->next_to_clean; tx_ntc = tx_ring->next_to_clean;
rx_desc = IGB_RX_DESC(rx_ring, rx_ntc); rx_desc = IGB_RX_DESC(rx_ring, rx_ntc);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
while (staterr & E1000_RXD_STAT_DD) { while (igb_test_staterr(rx_desc, E1000_RXD_STAT_DD)) {
/* check rx buffer */ /* check rx buffer */
rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc]; rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc];
...@@ -1619,7 +1617,6 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring, ...@@ -1619,7 +1617,6 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring,
/* fetch next descriptor */ /* fetch next descriptor */
rx_desc = IGB_RX_DESC(rx_ring, rx_ntc); rx_desc = IGB_RX_DESC(rx_ring, rx_ntc);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
} }
/* re-map buffers to ring, store next to clean values */ /* re-map buffers to ring, store next to clean values */
......
...@@ -5790,12 +5790,13 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) ...@@ -5790,12 +5790,13 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
} }
static inline void igb_rx_checksum(struct igb_ring *ring, static inline void igb_rx_checksum(struct igb_ring *ring,
u32 status_err, struct sk_buff *skb) union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb)
{ {
skb_checksum_none_assert(skb); skb_checksum_none_assert(skb);
/* Ignore Checksum bit is set */ /* Ignore Checksum bit is set */
if (status_err & E1000_RXD_STAT_IXSM) if (igb_test_staterr(rx_desc, E1000_RXD_STAT_IXSM))
return; return;
/* Rx checksum disabled via ethtool */ /* Rx checksum disabled via ethtool */
...@@ -5803,8 +5804,9 @@ static inline void igb_rx_checksum(struct igb_ring *ring, ...@@ -5803,8 +5804,9 @@ static inline void igb_rx_checksum(struct igb_ring *ring,
return; return;
/* TCP/UDP checksum error bit is set */ /* TCP/UDP checksum error bit is set */
if (status_err & if (igb_test_staterr(rx_desc,
(E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) { E1000_RXDEXT_STATERR_TCPE |
E1000_RXDEXT_STATERR_IPE)) {
/* /*
* work around errata with sctp packets where the TCPE aka * work around errata with sctp packets where the TCPE aka
* L4E bit is set incorrectly on 64 byte (60 byte w/o crc) * L4E bit is set incorrectly on 64 byte (60 byte w/o crc)
...@@ -5820,19 +5822,26 @@ static inline void igb_rx_checksum(struct igb_ring *ring, ...@@ -5820,19 +5822,26 @@ static inline void igb_rx_checksum(struct igb_ring *ring,
return; return;
} }
/* It must be a TCP or UDP packet with a valid checksum */ /* It must be a TCP or UDP packet with a valid checksum */
if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) if (igb_test_staterr(rx_desc, E1000_RXD_STAT_TCPCS |
E1000_RXD_STAT_UDPCS))
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
dev_dbg(ring->dev, "cksum success: bits %08X\n", status_err); dev_dbg(ring->dev, "cksum success: bits %08X\n",
le32_to_cpu(rx_desc->wb.upper.status_error));
} }
static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, static void igb_rx_hwtstamp(struct igb_q_vector *q_vector,
union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct igb_adapter *adapter = q_vector->adapter; struct igb_adapter *adapter = q_vector->adapter;
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u64 regval; u64 regval;
if (!igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP |
E1000_RXDADV_STAT_TS))
return;
/* /*
* If this bit is set, then the RX registers contain the time stamp. No * If this bit is set, then the RX registers contain the time stamp. No
* other packet will be time stamped until we read these registers, so * other packet will be time stamped until we read these registers, so
...@@ -5844,7 +5853,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, ...@@ -5844,7 +5853,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr,
* If nothing went wrong, then it should have a shared tx_flags that we * If nothing went wrong, then it should have a shared tx_flags that we
* can turn into a skb_shared_hwtstamps. * can turn into a skb_shared_hwtstamps.
*/ */
if (staterr & E1000_RXDADV_STAT_TSIP) { if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
u32 *stamp = (u32 *)skb->data; u32 *stamp = (u32 *)skb->data;
regval = le32_to_cpu(*(stamp + 2)); regval = le32_to_cpu(*(stamp + 2));
regval |= (u64)le32_to_cpu(*(stamp + 3)) << 32; regval |= (u64)le32_to_cpu(*(stamp + 3)) << 32;
...@@ -5878,14 +5887,12 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget) ...@@ -5878,14 +5887,12 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
union e1000_adv_rx_desc *rx_desc; union e1000_adv_rx_desc *rx_desc;
const int current_node = numa_node_id(); const int current_node = numa_node_id();
unsigned int total_bytes = 0, total_packets = 0; unsigned int total_bytes = 0, total_packets = 0;
u32 staterr;
u16 cleaned_count = igb_desc_unused(rx_ring); u16 cleaned_count = igb_desc_unused(rx_ring);
u16 i = rx_ring->next_to_clean; u16 i = rx_ring->next_to_clean;
rx_desc = IGB_RX_DESC(rx_ring, i); rx_desc = IGB_RX_DESC(rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
while (staterr & E1000_RXD_STAT_DD) { while (igb_test_staterr(rx_desc, E1000_RXD_STAT_DD)) {
struct igb_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i]; struct igb_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i];
struct sk_buff *skb = buffer_info->skb; struct sk_buff *skb = buffer_info->skb;
union e1000_adv_rx_desc *next_rxd; union e1000_adv_rx_desc *next_rxd;
...@@ -5938,7 +5945,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget) ...@@ -5938,7 +5945,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
buffer_info->page_dma = 0; buffer_info->page_dma = 0;
} }
if (!(staterr & E1000_RXD_STAT_EOP)) { if (!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP)) {
struct igb_rx_buffer *next_buffer; struct igb_rx_buffer *next_buffer;
next_buffer = &rx_ring->rx_buffer_info[i]; next_buffer = &rx_ring->rx_buffer_info[i];
buffer_info->skb = next_buffer->skb; buffer_info->skb = next_buffer->skb;
...@@ -5948,25 +5955,26 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget) ...@@ -5948,25 +5955,26 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
goto next_desc; goto next_desc;
} }
if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { if (igb_test_staterr(rx_desc,
E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
goto next_desc; goto next_desc;
} }
if (staterr & (E1000_RXDADV_STAT_TSIP | E1000_RXDADV_STAT_TS)) igb_rx_hwtstamp(q_vector, rx_desc, skb);
igb_rx_hwtstamp(q_vector, staterr, skb); igb_rx_checksum(rx_ring, rx_desc, skb);
total_bytes += skb->len;
total_packets++;
igb_rx_checksum(rx_ring, staterr, skb); if (igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
if (staterr & E1000_RXD_STAT_VP) {
u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan);
__vlan_hwaccel_put_tag(skb, vid); __vlan_hwaccel_put_tag(skb, vid);
} }
total_bytes += skb->len;
total_packets++;
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
napi_gro_receive(&q_vector->napi, skb); napi_gro_receive(&q_vector->napi, skb);
budget--; budget--;
...@@ -5983,7 +5991,6 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget) ...@@ -5983,7 +5991,6 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
/* use prefetched values */ /* use prefetched values */
rx_desc = next_rxd; rx_desc = next_rxd;
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
} }
rx_ring->next_to_clean = i; rx_ring->next_to_clean = i;
......
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