Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net/mlx5: MPFS, add support for dynamic enable/disable

MPFS (Multi PF Switch) is enabled by default in Multi-Host environments,
the driver keeps a list of desired unicast mac addresses of all vports
(vfs/Sfs) and applied to HW via L2_table FW command.

Add API to dynamically apply the list of MACs to HW when needed for next
patches, to utilize this new API in devlink eswitch active/in-active uAPI.

Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Adithya Jayachandran <ajayachandra@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://patch.msgid.link/20251108070404.1551708-3-saeed@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Saeed Mahameed and committed by
Paolo Abeni
9902b638 0e535824

+108 -17
+99 -17
drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c
··· 65 65 /* UC L2 table hash node */ 66 66 struct l2table_node { 67 67 struct l2addr_node node; 68 - u32 index; /* index in HW l2 table */ 68 + int index; /* index in HW l2 table */ 69 69 int ref_count; 70 70 }; 71 71 72 72 struct mlx5_mpfs { 73 73 struct hlist_head hash[MLX5_L2_ADDR_HASH_SIZE]; 74 74 struct mutex lock; /* Synchronize l2 table access */ 75 + bool enabled; 75 76 u32 size; 76 77 unsigned long *bitmap; 77 78 }; ··· 115 114 return -ENOMEM; 116 115 } 117 116 117 + mpfs->enabled = true; 118 + 118 119 dev->priv.mpfs = mpfs; 119 120 return 0; 120 121 } ··· 138 135 struct mlx5_mpfs *mpfs = dev->priv.mpfs; 139 136 struct l2table_node *l2addr; 140 137 int err = 0; 141 - u32 index; 138 + int index; 142 139 143 140 if (!mpfs) 144 141 return 0; ··· 151 148 goto out; 152 149 } 153 150 154 - err = alloc_l2table_index(mpfs, &index); 155 - if (err) 156 - goto out; 157 - 158 151 l2addr = l2addr_hash_add(mpfs->hash, mac, struct l2table_node, GFP_KERNEL); 159 152 if (!l2addr) { 160 153 err = -ENOMEM; 161 - goto hash_add_err; 154 + goto out; 162 155 } 163 156 164 - err = set_l2table_entry_cmd(dev, index, mac); 165 - if (err) 166 - goto set_table_entry_err; 157 + index = -1; 158 + 159 + if (mpfs->enabled) { 160 + err = alloc_l2table_index(mpfs, &index); 161 + if (err) 162 + goto hash_del; 163 + err = set_l2table_entry_cmd(dev, index, mac); 164 + if (err) 165 + goto free_l2table_index; 166 + mlx5_core_dbg(dev, "MPFS entry %pM, set @index (%d)\n", 167 + l2addr->node.addr, l2addr->index); 168 + } 167 169 168 170 l2addr->index = index; 169 171 l2addr->ref_count = 1; 170 172 171 173 mlx5_core_dbg(dev, "MPFS mac added %pM, index (%d)\n", mac, index); 172 174 goto out; 173 - 174 - set_table_entry_err: 175 - l2addr_hash_del(l2addr); 176 - hash_add_err: 175 + free_l2table_index: 177 176 free_l2table_index(mpfs, index); 177 + hash_del: 178 + l2addr_hash_del(l2addr); 178 179 out: 179 180 mutex_unlock(&mpfs->lock); 180 181 return err; ··· 190 183 struct mlx5_mpfs *mpfs = dev->priv.mpfs; 191 184 struct l2table_node *l2addr; 192 185 int err = 0; 193 - u32 index; 186 + int index; 194 187 195 188 if (!mpfs) 196 189 return 0; ··· 207 200 goto unlock; 208 201 209 202 index = l2addr->index; 210 - del_l2table_entry_cmd(dev, index); 203 + if (index >= 0) { 204 + del_l2table_entry_cmd(dev, index); 205 + free_l2table_index(mpfs, index); 206 + mlx5_core_dbg(dev, "MPFS entry %pM, deleted @index (%d)\n", 207 + mac, index); 208 + } 211 209 l2addr_hash_del(l2addr); 212 - free_l2table_index(mpfs, index); 213 210 mlx5_core_dbg(dev, "MPFS mac deleted %pM, index (%d)\n", mac, index); 214 211 unlock: 215 212 mutex_unlock(&mpfs->lock); 216 213 return err; 217 214 } 218 215 EXPORT_SYMBOL(mlx5_mpfs_del_mac); 216 + 217 + int mlx5_mpfs_enable(struct mlx5_core_dev *dev) 218 + { 219 + struct mlx5_mpfs *mpfs = dev->priv.mpfs; 220 + struct l2table_node *l2addr; 221 + struct hlist_node *n; 222 + int err = 0, i; 223 + 224 + if (!mpfs) 225 + return -ENODEV; 226 + 227 + mutex_lock(&mpfs->lock); 228 + if (mpfs->enabled) 229 + goto out; 230 + mpfs->enabled = true; 231 + mlx5_core_dbg(dev, "MPFS enabling mpfs\n"); 232 + 233 + mlx5_mpfs_foreach(l2addr, n, mpfs, i) { 234 + u32 index; 235 + 236 + err = alloc_l2table_index(mpfs, &index); 237 + if (err) { 238 + mlx5_core_err(dev, "Failed to allocated MPFS index for %pM, err(%d)\n", 239 + l2addr->node.addr, err); 240 + goto out; 241 + } 242 + 243 + err = set_l2table_entry_cmd(dev, index, l2addr->node.addr); 244 + if (err) { 245 + mlx5_core_err(dev, "Failed to set MPFS l2table entry for %pM index=%d, err(%d)\n", 246 + l2addr->node.addr, index, err); 247 + free_l2table_index(mpfs, index); 248 + goto out; 249 + } 250 + 251 + l2addr->index = index; 252 + mlx5_core_dbg(dev, "MPFS entry %pM, set @index (%d)\n", 253 + l2addr->node.addr, l2addr->index); 254 + } 255 + out: 256 + mutex_unlock(&mpfs->lock); 257 + return err; 258 + } 259 + 260 + void mlx5_mpfs_disable(struct mlx5_core_dev *dev) 261 + { 262 + struct mlx5_mpfs *mpfs = dev->priv.mpfs; 263 + struct l2table_node *l2addr; 264 + struct hlist_node *n; 265 + int i; 266 + 267 + if (!mpfs) 268 + return; 269 + 270 + mutex_lock(&mpfs->lock); 271 + if (!mpfs->enabled) 272 + goto unlock; 273 + mlx5_mpfs_foreach(l2addr, n, mpfs, i) { 274 + if (l2addr->index < 0) 275 + continue; 276 + del_l2table_entry_cmd(dev, l2addr->index); 277 + free_l2table_index(mpfs, l2addr->index); 278 + mlx5_core_dbg(dev, "MPFS entry %pM, deleted @index (%d)\n", 279 + l2addr->node.addr, l2addr->index); 280 + l2addr->index = -1; 281 + } 282 + mpfs->enabled = false; 283 + mlx5_core_dbg(dev, "MPFS disabled\n"); 284 + unlock: 285 + mutex_unlock(&mpfs->lock); 286 + }
+9
drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.h
··· 45 45 u8 addr[ETH_ALEN]; 46 46 }; 47 47 48 + #define mlx5_mpfs_foreach(hs, tmp, mpfs, i) \ 49 + for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \ 50 + hlist_for_each_entry_safe(hs, tmp, &(mpfs)->hash[i], node.hlist) 51 + 48 52 #define for_each_l2hash_node(hn, tmp, hash, i) \ 49 53 for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \ 50 54 hlist_for_each_entry_safe(hn, tmp, &(hash)[i], hlist) ··· 86 82 }) 87 83 88 84 #ifdef CONFIG_MLX5_MPFS 85 + struct mlx5_core_dev; 89 86 int mlx5_mpfs_init(struct mlx5_core_dev *dev); 90 87 void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev); 88 + int mlx5_mpfs_enable(struct mlx5_core_dev *dev); 89 + void mlx5_mpfs_disable(struct mlx5_core_dev *dev); 91 90 #else /* #ifndef CONFIG_MLX5_MPFS */ 92 91 static inline int mlx5_mpfs_init(struct mlx5_core_dev *dev) { return 0; } 93 92 static inline void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev) {} 93 + static inline int mlx5_mpfs_enable(struct mlx5_core_dev *dev) { return 0; } 94 + static inline void mlx5_mpfs_disable(struct mlx5_core_dev *dev) {} 94 95 #endif 95 96 96 97 #endif