net: txgbe: Support the FDIR rules assigned to VFs
authorJiawen Wu <jiawenwu@trustnetic.com>
Fri, 23 May 2025 08:04:38 +0000 (16:04 +0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 28 May 2025 01:17:11 +0000 (18:17 -0700)
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: Jiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/BE7EA355FDDAAA97+20250523080438.27968-2-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
drivers/net/ethernet/wangxun/txgbe/txgbe_fdir.c
drivers/net/ethernet/wangxun/txgbe/txgbe_type.h

index fa770961df5f818a6038bdbdf5b4fc20bbb9b52d..a4753402660e18f0aaa85165e3ec064b9ae4f3af 100644 (file)
@@ -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 */
-               queue = wx->rx_ring[ring]->reg_idx;
+               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 */
index ef50efbaec0f51416deeda01b06b7f7919682f9b..a840108285517f63cf959121696e1eee5d489bc0 100644 (file)
@@ -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
index 7a00e3343be637510318b1c11fb07556673b2c0e..42ec815159e83fe7c7a1fc6a1b587f34ca0d33ff 100644 (file)
@@ -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 */