Commit 3b076cfe authored by David S. Miller's avatar David S. Miller

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue

Jeff Kirsher says:

====================
Intel Wired LAN Driver Fixes 2018-12-12

This series contains fixes to i40e and ixgbe.

Stefan Assmann fixes an issue created by a previous fix, where
ether_addr_copy() was moved to avoid a race but did not take into
account that it alters the MAC address being handed to
i40e_del_mac_filter().

Michał Mirosław provides 2 fixes for i40e, first resolves issues in the
hardware VLAN offload where VLAN.TCI equal to 0 was being dropped and a
race between disabling VLAN receive feature in hardware and processing
the receive queue, where packets could have their VLAN information
dropped.

Ross Lagerwall fixes a racy condition during a ixgbe VF reset, where
writing the register to issue a reset and sending the reset message via
the mailbox API could result of the mailbox memory getting cleared
during the reset before the message gets successfully sent which results
in a VF driver malfunction.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 18330c58 96d1a731
...@@ -1543,17 +1543,17 @@ static int i40e_set_mac(struct net_device *netdev, void *p) ...@@ -1543,17 +1543,17 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
netdev_info(netdev, "set new mac address %pM\n", addr->sa_data); netdev_info(netdev, "set new mac address %pM\n", addr->sa_data);
/* Copy the address first, so that we avoid a possible race with /* Copy the address first, so that we avoid a possible race with
* .set_rx_mode(). If we copy after changing the address in the filter * .set_rx_mode().
* list, we might open ourselves to a narrow race window where * - Remove old address from MAC filter
* .set_rx_mode could delete our dev_addr filter and prevent traffic * - Copy new address
* from passing. * - Add new address to MAC filter
*/ */
ether_addr_copy(netdev->dev_addr, addr->sa_data);
spin_lock_bh(&vsi->mac_filter_hash_lock); spin_lock_bh(&vsi->mac_filter_hash_lock);
i40e_del_mac_filter(vsi, netdev->dev_addr); i40e_del_mac_filter(vsi, netdev->dev_addr);
i40e_add_mac_filter(vsi, addr->sa_data); ether_addr_copy(netdev->dev_addr, addr->sa_data);
i40e_add_mac_filter(vsi, netdev->dev_addr);
spin_unlock_bh(&vsi->mac_filter_hash_lock); spin_unlock_bh(&vsi->mac_filter_hash_lock);
if (vsi->type == I40E_VSI_MAIN) { if (vsi->type == I40E_VSI_MAIN) {
i40e_status ret; i40e_status ret;
......
...@@ -1558,24 +1558,6 @@ static bool i40e_alloc_mapped_page(struct i40e_ring *rx_ring, ...@@ -1558,24 +1558,6 @@ static bool i40e_alloc_mapped_page(struct i40e_ring *rx_ring,
return true; return true;
} }
/**
* i40e_receive_skb - Send a completed packet up the stack
* @rx_ring: rx ring in play
* @skb: packet to send up
* @vlan_tag: vlan tag for packet
**/
void i40e_receive_skb(struct i40e_ring *rx_ring,
struct sk_buff *skb, u16 vlan_tag)
{
struct i40e_q_vector *q_vector = rx_ring->q_vector;
if ((rx_ring->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
(vlan_tag & VLAN_VID_MASK))
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
napi_gro_receive(&q_vector->napi, skb);
}
/** /**
* i40e_alloc_rx_buffers - Replace used receive buffers * i40e_alloc_rx_buffers - Replace used receive buffers
* @rx_ring: ring to place buffers on * @rx_ring: ring to place buffers on
...@@ -1793,8 +1775,7 @@ static inline void i40e_rx_hash(struct i40e_ring *ring, ...@@ -1793,8 +1775,7 @@ static inline void i40e_rx_hash(struct i40e_ring *ring,
* other fields within the skb. * other fields within the skb.
**/ **/
void i40e_process_skb_fields(struct i40e_ring *rx_ring, void i40e_process_skb_fields(struct i40e_ring *rx_ring,
union i40e_rx_desc *rx_desc, struct sk_buff *skb, union i40e_rx_desc *rx_desc, struct sk_buff *skb)
u8 rx_ptype)
{ {
u64 qword = le64_to_cpu(rx_desc->wb.qword1.status_error_len); u64 qword = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
u32 rx_status = (qword & I40E_RXD_QW1_STATUS_MASK) >> u32 rx_status = (qword & I40E_RXD_QW1_STATUS_MASK) >>
...@@ -1802,6 +1783,8 @@ void i40e_process_skb_fields(struct i40e_ring *rx_ring, ...@@ -1802,6 +1783,8 @@ void i40e_process_skb_fields(struct i40e_ring *rx_ring,
u32 tsynvalid = rx_status & I40E_RXD_QW1_STATUS_TSYNVALID_MASK; u32 tsynvalid = rx_status & I40E_RXD_QW1_STATUS_TSYNVALID_MASK;
u32 tsyn = (rx_status & I40E_RXD_QW1_STATUS_TSYNINDX_MASK) >> u32 tsyn = (rx_status & I40E_RXD_QW1_STATUS_TSYNINDX_MASK) >>
I40E_RXD_QW1_STATUS_TSYNINDX_SHIFT; I40E_RXD_QW1_STATUS_TSYNINDX_SHIFT;
u8 rx_ptype = (qword & I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT;
if (unlikely(tsynvalid)) if (unlikely(tsynvalid))
i40e_ptp_rx_hwtstamp(rx_ring->vsi->back, skb, tsyn); i40e_ptp_rx_hwtstamp(rx_ring->vsi->back, skb, tsyn);
...@@ -1812,6 +1795,13 @@ void i40e_process_skb_fields(struct i40e_ring *rx_ring, ...@@ -1812,6 +1795,13 @@ void i40e_process_skb_fields(struct i40e_ring *rx_ring,
skb_record_rx_queue(skb, rx_ring->queue_index); skb_record_rx_queue(skb, rx_ring->queue_index);
if (qword & BIT(I40E_RX_DESC_STATUS_L2TAG1P_SHIFT)) {
u16 vlan_tag = rx_desc->wb.qword0.lo_dword.l2tag1;
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
le16_to_cpu(vlan_tag));
}
/* modifies the skb - consumes the enet header */ /* modifies the skb - consumes the enet header */
skb->protocol = eth_type_trans(skb, rx_ring->netdev); skb->protocol = eth_type_trans(skb, rx_ring->netdev);
} }
...@@ -2350,8 +2340,6 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) ...@@ -2350,8 +2340,6 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
struct i40e_rx_buffer *rx_buffer; struct i40e_rx_buffer *rx_buffer;
union i40e_rx_desc *rx_desc; union i40e_rx_desc *rx_desc;
unsigned int size; unsigned int size;
u16 vlan_tag;
u8 rx_ptype;
u64 qword; u64 qword;
/* return some buffers to hardware, one at a time is too slow */ /* return some buffers to hardware, one at a time is too slow */
...@@ -2444,18 +2432,11 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) ...@@ -2444,18 +2432,11 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
/* probably a little skewed due to removing CRC */ /* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len; total_rx_bytes += skb->len;
qword = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
rx_ptype = (qword & I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT;
/* populate checksum, VLAN, and protocol */ /* populate checksum, VLAN, and protocol */
i40e_process_skb_fields(rx_ring, rx_desc, skb, rx_ptype); i40e_process_skb_fields(rx_ring, rx_desc, skb);
vlan_tag = (qword & BIT(I40E_RX_DESC_STATUS_L2TAG1P_SHIFT)) ?
le16_to_cpu(rx_desc->wb.qword0.lo_dword.l2tag1) : 0;
i40e_trace(clean_rx_irq_rx, rx_ring, rx_desc, skb); i40e_trace(clean_rx_irq_rx, rx_ring, rx_desc, skb);
i40e_receive_skb(rx_ring, skb, vlan_tag); napi_gro_receive(&rx_ring->q_vector->napi, skb);
skb = NULL; skb = NULL;
/* update budget accounting */ /* update budget accounting */
......
...@@ -12,10 +12,7 @@ struct i40e_rx_buffer *i40e_clean_programming_status( ...@@ -12,10 +12,7 @@ struct i40e_rx_buffer *i40e_clean_programming_status(
union i40e_rx_desc *rx_desc, union i40e_rx_desc *rx_desc,
u64 qw); u64 qw);
void i40e_process_skb_fields(struct i40e_ring *rx_ring, void i40e_process_skb_fields(struct i40e_ring *rx_ring,
union i40e_rx_desc *rx_desc, struct sk_buff *skb, union i40e_rx_desc *rx_desc, struct sk_buff *skb);
u8 rx_ptype);
void i40e_receive_skb(struct i40e_ring *rx_ring,
struct sk_buff *skb, u16 vlan_tag);
void i40e_xdp_ring_update_tail(struct i40e_ring *xdp_ring); void i40e_xdp_ring_update_tail(struct i40e_ring *xdp_ring);
void i40e_update_rx_stats(struct i40e_ring *rx_ring, void i40e_update_rx_stats(struct i40e_ring *rx_ring,
unsigned int total_rx_bytes, unsigned int total_rx_bytes,
......
...@@ -634,8 +634,6 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget) ...@@ -634,8 +634,6 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
struct i40e_rx_buffer *bi; struct i40e_rx_buffer *bi;
union i40e_rx_desc *rx_desc; union i40e_rx_desc *rx_desc;
unsigned int size; unsigned int size;
u16 vlan_tag;
u8 rx_ptype;
u64 qword; u64 qword;
if (cleaned_count >= I40E_RX_BUFFER_WRITE) { if (cleaned_count >= I40E_RX_BUFFER_WRITE) {
...@@ -713,14 +711,8 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget) ...@@ -713,14 +711,8 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
total_rx_bytes += skb->len; total_rx_bytes += skb->len;
total_rx_packets++; total_rx_packets++;
qword = le64_to_cpu(rx_desc->wb.qword1.status_error_len); i40e_process_skb_fields(rx_ring, rx_desc, skb);
rx_ptype = (qword & I40E_RXD_QW1_PTYPE_MASK) >> napi_gro_receive(&rx_ring->q_vector->napi, skb);
I40E_RXD_QW1_PTYPE_SHIFT;
i40e_process_skb_fields(rx_ring, rx_desc, skb, rx_ptype);
vlan_tag = (qword & BIT(I40E_RX_DESC_STATUS_L2TAG1P_SHIFT)) ?
le16_to_cpu(rx_desc->wb.qword0.lo_dword.l2tag1) : 0;
i40e_receive_skb(rx_ring, skb, vlan_tag);
} }
i40e_finalize_xdp_rx(rx_ring, xdp_xmit); i40e_finalize_xdp_rx(rx_ring, xdp_xmit);
......
...@@ -700,7 +700,6 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) ...@@ -700,7 +700,6 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
u8 num_tcs = adapter->hw_tcs; u8 num_tcs = adapter->hw_tcs;
u32 reg_val; u32 reg_val;
u32 queue; u32 queue;
u32 word;
/* remove VLAN filters beloning to this VF */ /* remove VLAN filters beloning to this VF */
ixgbe_clear_vf_vlans(adapter, vf); ixgbe_clear_vf_vlans(adapter, vf);
...@@ -758,6 +757,14 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) ...@@ -758,6 +757,14 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
} }
} }
IXGBE_WRITE_FLUSH(hw);
}
static void ixgbe_vf_clear_mbx(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 word;
/* Clear VF's mailbox memory */ /* Clear VF's mailbox memory */
for (word = 0; word < IXGBE_VFMAILBOX_SIZE; word++) for (word = 0; word < IXGBE_VFMAILBOX_SIZE; word++)
IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf), word, 0); IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf), word, 0);
...@@ -831,6 +838,8 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) ...@@ -831,6 +838,8 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
/* reset the filters for the device */ /* reset the filters for the device */
ixgbe_vf_reset_event(adapter, vf); ixgbe_vf_reset_event(adapter, vf);
ixgbe_vf_clear_mbx(adapter, vf);
/* set vf mac address */ /* set vf mac address */
if (!is_zero_ether_addr(vf_mac)) if (!is_zero_ether_addr(vf_mac))
ixgbe_set_vf_mac(adapter, vf, vf_mac); ixgbe_set_vf_mac(adapter, vf, vf_mac);
......
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