OSDN Git Service

net/mlx5: E-switch, Use PF num in metadata reg c0
authorsunils <sunils@nvidia.com>
Thu, 10 Sep 2020 21:13:26 +0000 (00:13 +0300)
committerSaeed Mahameed <saeedm@nvidia.com>
Thu, 1 Oct 2020 04:26:28 +0000 (21:26 -0700)
Currently only 256 vports can be supported as only 8 bits are
reserved for them and 8 bits are reserved for vhca_ids in
metadata reg c0. To support more than 256 vports, replace
vhca_id with a unique shorter 4-bit PF number which covers
upto 16 PF's. Use remaining 12 bits for vports ranging 1-4095.
This will continue to generate unique metadata even if
multiple PCI devices have same switch_id.

Signed-off-by: sunils <sunils@nvidia.com>
Reviewed-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
include/linux/mlx5/eswitch.h

index ffd5d54..6b49c0d 100644 (file)
@@ -2019,31 +2019,31 @@ esw_check_vport_match_metadata_supported(const struct mlx5_eswitch *esw)
 
 u32 mlx5_esw_match_metadata_alloc(struct mlx5_eswitch *esw)
 {
-       u32 num_vports = GENMASK(ESW_VPORT_BITS - 1, 0) - 1;
-       u32 vhca_id_mask = GENMASK(ESW_VHCA_ID_BITS - 1, 0);
-       u32 vhca_id = MLX5_CAP_GEN(esw->dev, vhca_id);
-       u32 start;
-       u32 end;
+       u32 vport_end_ida = (1 << ESW_VPORT_BITS) - 1;
+       u32 max_pf_num = (1 << ESW_PFNUM_BITS) - 1;
+       u32 pf_num;
        int id;
 
-       /* Make sure the vhca_id fits the ESW_VHCA_ID_BITS */
-       WARN_ON_ONCE(vhca_id >= BIT(ESW_VHCA_ID_BITS));
-
-       /* Trim vhca_id to ESW_VHCA_ID_BITS */
-       vhca_id &= vhca_id_mask;
-
-       start = (vhca_id << ESW_VPORT_BITS);
-       end = start + num_vports;
-       if (!vhca_id)
-               start += 1; /* zero is reserved/invalid metadata */
-       id = ida_alloc_range(&esw->offloads.vport_metadata_ida, start, end, GFP_KERNEL);
+       /* Only 4 bits of pf_num */
+       pf_num = PCI_FUNC(esw->dev->pdev->devfn);
+       if (pf_num > max_pf_num)
+               return 0;
 
-       return (id < 0) ? 0 : id;
+       /* Metadata is 4 bits of PFNUM and 12 bits of unique id */
+       /* Use only non-zero vport_id (1-4095) for all PF's */
+       id = ida_alloc_range(&esw->offloads.vport_metadata_ida, 1, vport_end_ida, GFP_KERNEL);
+       if (id < 0)
+               return 0;
+       id = (pf_num << ESW_VPORT_BITS) | id;
+       return id;
 }
 
 void mlx5_esw_match_metadata_free(struct mlx5_eswitch *esw, u32 metadata)
 {
-       ida_free(&esw->offloads.vport_metadata_ida, metadata);
+       u32 vport_bit_mask = (1 << ESW_VPORT_BITS) - 1;
+
+       /* Metadata contains only 12 bits of actual ida id */
+       ida_free(&esw->offloads.vport_metadata_ida, metadata & vport_bit_mask);
 }
 
 static int esw_offloads_vport_metadata_setup(struct mlx5_eswitch *esw,
index c16827e..b0ae802 100644 (file)
@@ -74,15 +74,16 @@ bool mlx5_eswitch_reg_c1_loopback_enabled(const struct mlx5_eswitch *esw);
 bool mlx5_eswitch_vport_match_metadata_enabled(const struct mlx5_eswitch *esw);
 
 /* Reg C0 usage:
- * Reg C0 = < ESW_VHCA_ID_BITS(8) | ESW_VPORT BITS(8) | ESW_CHAIN_TAG(16) >
+ * Reg C0 = < ESW_PFNUM_BITS(4) | ESW_VPORT BITS(12) | ESW_CHAIN_TAG(16) >
  *
- * Highest 8 bits of the reg c0 is the vhca_id, next 8 bits is vport_num,
- * the rest (lowest 16 bits) is left for tc chain tag restoration.
- * VHCA_ID + VPORT comprise the SOURCE_PORT matching.
+ * Highest 4 bits of the reg c0 is the PF_NUM (range 0-15), 12 bits of
+ * unique non-zero vport id (range 1-4095). The rest (lowest 16 bits) is left
+ * for tc chain tag restoration.
+ * PFNUM + VPORT comprise the SOURCE_PORT matching.
  */
-#define ESW_VHCA_ID_BITS 8
-#define ESW_VPORT_BITS 8
-#define ESW_SOURCE_PORT_METADATA_BITS (ESW_VHCA_ID_BITS + ESW_VPORT_BITS)
+#define ESW_VPORT_BITS 12
+#define ESW_PFNUM_BITS 4
+#define ESW_SOURCE_PORT_METADATA_BITS (ESW_PFNUM_BITS + ESW_VPORT_BITS)
 #define ESW_SOURCE_PORT_METADATA_OFFSET (32 - ESW_SOURCE_PORT_METADATA_BITS)
 #define ESW_CHAIN_TAG_METADATA_BITS (32 - ESW_SOURCE_PORT_METADATA_BITS)
 #define ESW_CHAIN_TAG_METADATA_MASK GENMASK(ESW_CHAIN_TAG_METADATA_BITS - 1,\