Commit 7a91722e authored by Jiawen Wu's avatar Jiawen Wu Committed by Jakub Kicinski
Browse files

net: txgbe: Support the FDIR rules assigned to VFs



When SR-IOV is enabled, the FDIR rule is supported to filter packets to
VFs. The action queue id is calculated as an absolute id.

Signed-off-by: default avatarJiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/BE7EA355FDDAAA97+20250523080438.27968-2-jiawenwu@trustnetic.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 06ac0776
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -367,12 +367,19 @@ static int txgbe_add_ethtool_fdir_entry(struct txgbe *txgbe,
		queue = TXGBE_RDB_FDIR_DROP_QUEUE;
	} else {
		u32 ring = ethtool_get_flow_spec_ring(fsp->ring_cookie);
		u8 vf = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie);

		if (ring >= wx->num_rx_queues)
		if (!vf && ring >= wx->num_rx_queues)
			return -EINVAL;
		else if (vf && (vf > wx->num_vfs ||
				ring >= wx->num_rx_queues_per_pool))
			return -EINVAL;

		/* Map the ring onto the absolute queue index */
		if (!vf)
			queue = wx->rx_ring[ring]->reg_idx;
		else
			queue = ((vf - 1) * wx->num_rx_queues_per_pool) + ring;
	}

	/* Don't allow indexes to exist outside of available space */
+14 −9
Original line number Diff line number Diff line
@@ -307,6 +307,7 @@ void txgbe_atr(struct wx_ring *ring, struct wx_tx_buffer *first, u8 ptype)
int txgbe_fdir_set_input_mask(struct wx *wx, union txgbe_atr_input *input_mask)
{
	u32 fdirm = 0, fdirtcpm = 0, flex = 0;
	int index, offset;

	/* Program the relevant mask registers. If src/dst_port or src/dst_addr
	 * are zero, then assume a full mask for that field.  Also assume that
@@ -352,15 +353,17 @@ int txgbe_fdir_set_input_mask(struct wx *wx, union txgbe_atr_input *input_mask)
	/* Now mask VM pool and destination IPv6 - bits 5 and 2 */
	wr32(wx, TXGBE_RDB_FDIR_OTHER_MSK, fdirm);

	flex = rd32(wx, TXGBE_RDB_FDIR_FLEX_CFG(0));
	flex &= ~TXGBE_RDB_FDIR_FLEX_CFG_FIELD0;
	index = VMDQ_P(0) / 4;
	offset = VMDQ_P(0) % 4;
	flex = rd32(wx, TXGBE_RDB_FDIR_FLEX_CFG(index));
	flex &= ~(TXGBE_RDB_FDIR_FLEX_CFG_FIELD0 << (offset * 8));
	flex |= (TXGBE_RDB_FDIR_FLEX_CFG_BASE_MAC |
		 TXGBE_RDB_FDIR_FLEX_CFG_OFST(0x6));
		 TXGBE_RDB_FDIR_FLEX_CFG_OFST(0x6)) << (offset * 8);

	switch ((__force u16)input_mask->formatted.flex_bytes & 0xFFFF) {
	case 0x0000:
		/* Mask Flex Bytes */
		flex |= TXGBE_RDB_FDIR_FLEX_CFG_MSK;
		flex |= TXGBE_RDB_FDIR_FLEX_CFG_MSK << (offset * 8);
		break;
	case 0xFFFF:
		break;
@@ -368,7 +371,7 @@ int txgbe_fdir_set_input_mask(struct wx *wx, union txgbe_atr_input *input_mask)
		wx_err(wx, "Error on flexible byte mask\n");
		return -EINVAL;
	}
	wr32(wx, TXGBE_RDB_FDIR_FLEX_CFG(0), flex);
	wr32(wx, TXGBE_RDB_FDIR_FLEX_CFG(index), flex);

	/* store the TCP/UDP port masks, bit reversed from port layout */
	fdirtcpm = ntohs(input_mask->formatted.dst_port);
@@ -516,14 +519,16 @@ static void txgbe_fdir_enable(struct wx *wx, u32 fdirctrl)
static void txgbe_init_fdir_signature(struct wx *wx)
{
	u32 fdirctrl = TXGBE_FDIR_PBALLOC_64K;
	int index = VMDQ_P(0) / 4;
	int offset = VMDQ_P(0) % 4;
	u32 flex = 0;

	flex = rd32(wx, TXGBE_RDB_FDIR_FLEX_CFG(0));
	flex &= ~TXGBE_RDB_FDIR_FLEX_CFG_FIELD0;
	flex = rd32(wx, TXGBE_RDB_FDIR_FLEX_CFG(index));
	flex &= ~(TXGBE_RDB_FDIR_FLEX_CFG_FIELD0 << (offset * 8));

	flex |= (TXGBE_RDB_FDIR_FLEX_CFG_BASE_MAC |
		 TXGBE_RDB_FDIR_FLEX_CFG_OFST(0x6));
	wr32(wx, TXGBE_RDB_FDIR_FLEX_CFG(0), flex);
		 TXGBE_RDB_FDIR_FLEX_CFG_OFST(0x6)) << (offset * 8);
	wr32(wx, TXGBE_RDB_FDIR_FLEX_CFG(index), flex);

	/* Continue setup of fdirctrl register bits:
	 *  Move the flexible bytes to use the ethertype - shift 6 words
+1 −1
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ struct txgbe_fdir_filter {
	struct hlist_node fdir_node;
	union txgbe_atr_input filter;
	u16 sw_idx;
	u16 action;
	u64 action;
};

/* TX/RX descriptor defines */