Commit 9113302b authored by Jan Sokolowski's avatar Jan Sokolowski Committed by David S. Miller
Browse files

ice: Fix undersized tx_flags variable



As not all ICE_TX_FLAGS_* fit in current 16-bit limited
tx_flags field that was introduced in the Fixes commit,
VLAN-related information would be discarded completely.
As such, creating a vlan and trying to run ping through
would result in no traffic passing.

Fix that by refactoring tx_flags variable into flags only and
a separate variable that holds VLAN ID. As there is some space left,
type variable can fit between those two. Pahole reports no size
change to ice_tx_buf struct.

Fixes: aa1d3faf ("ice: Robustify cleaning/completing XDP Tx buffers")
Signed-off-by: default avatarJan Sokolowski <jan.sokolowski@intel.com>
Reviewed-by: default avatarAlexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 47af4291
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -932,10 +932,9 @@ ice_tx_prepare_vlan_flags_dcb(struct ice_tx_ring *tx_ring,
	if ((first->tx_flags & ICE_TX_FLAGS_HW_VLAN ||
	     first->tx_flags & ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN) ||
	    skb->priority != TC_PRIO_CONTROL) {
		first->tx_flags &= ~ICE_TX_FLAGS_VLAN_PR_M;
		first->vid &= ~VLAN_PRIO_MASK;
		/* Mask the lower 3 bits to set the 802.1p priority */
		first->tx_flags |= (skb->priority & 0x7) <<
				   ICE_TX_FLAGS_VLAN_PR_S;
		first->vid |= (skb->priority << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK;
		/* if this is not already set it means a VLAN 0 + priority needs
		 * to be offloaded
		 */
+3 −5
Original line number Diff line number Diff line
@@ -1664,8 +1664,7 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first,

	if (first->tx_flags & ICE_TX_FLAGS_HW_VLAN) {
		td_cmd |= (u64)ICE_TX_DESC_CMD_IL2TAG1;
		td_tag = (first->tx_flags & ICE_TX_FLAGS_VLAN_M) >>
			  ICE_TX_FLAGS_VLAN_S;
		td_tag = first->vid;
	}

	dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
@@ -1998,7 +1997,7 @@ ice_tx_prepare_vlan_flags(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first)
	 * VLAN offloads exclusively so we only care about the VLAN ID here
	 */
	if (skb_vlan_tag_present(skb)) {
		first->tx_flags |= skb_vlan_tag_get(skb) << ICE_TX_FLAGS_VLAN_S;
		first->vid = skb_vlan_tag_get(skb);
		if (tx_ring->flags & ICE_TX_FLAGS_RING_VLAN_L2TAG2)
			first->tx_flags |= ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN;
		else
@@ -2388,8 +2387,7 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
		offload.cd_qw1 |= (u64)(ICE_TX_DESC_DTYPE_CTX |
					(ICE_TX_CTX_DESC_IL2TAG2 <<
					ICE_TXD_CTX_QW1_CMD_S));
		offload.cd_l2tag2 = (first->tx_flags & ICE_TX_FLAGS_VLAN_M) >>
			ICE_TX_FLAGS_VLAN_S;
		offload.cd_l2tag2 = first->vid;
	}

	/* set up TSO offload */
+3 −6
Original line number Diff line number Diff line
@@ -127,10 +127,6 @@ static inline int ice_skb_pad(void)
#define ICE_TX_FLAGS_IPV6	BIT(6)
#define ICE_TX_FLAGS_TUNNEL	BIT(7)
#define ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN	BIT(8)
#define ICE_TX_FLAGS_VLAN_M	0xffff0000
#define ICE_TX_FLAGS_VLAN_PR_M	0xe0000000
#define ICE_TX_FLAGS_VLAN_PR_S	29
#define ICE_TX_FLAGS_VLAN_S	16

#define ICE_XDP_PASS		0
#define ICE_XDP_CONSUMED	BIT(0)
@@ -182,8 +178,9 @@ struct ice_tx_buf {
		unsigned int gso_segs;
		unsigned int nr_frags;	/* used for mbuf XDP */
	};
	u32 type:16;			/* &ice_tx_buf_type */
	u32 tx_flags:16;
	u32 tx_flags:12;
	u32 type:4;			/* &ice_tx_buf_type */
	u32 vid:16;
	DEFINE_DMA_UNMAP_LEN(len);
	DEFINE_DMA_UNMAP_ADDR(dma);
};