1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2 /* Copyright (c) 2021 Mellanox Technologies. */ 3 4 #ifndef _MLX5_ESW_BRIDGE_PRIVATE_ 5 #define _MLX5_ESW_BRIDGE_PRIVATE_ 6 7 #include <linux/netdevice.h> 8 #include <linux/if_bridge.h> 9 #include <linux/if_vlan.h> 10 #include <linux/if_ether.h> 11 #include <linux/rhashtable.h> 12 #include <linux/xarray.h> 13 #include "fs_core.h" 14 15 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_SIZE 1 16 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_SIZE 3 17 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE 131072 18 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_UNTAGGED_GRP_SIZE \ 19 (524288 - MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_SIZE - \ 20 MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_SIZE) 21 22 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_IDX_FROM 0 23 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_IDX_TO \ 24 (MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_SIZE - 1) 25 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_IDX_FROM \ 26 (MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_IDX_TO + 1) 27 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_IDX_TO \ 28 (MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_IDX_FROM + \ 29 MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_SIZE - 1) 30 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_FROM \ 31 (MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_IDX_TO + 1) 32 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_TO \ 33 (MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_FROM + \ 34 MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE - 1) 35 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_FILTER_GRP_IDX_FROM \ 36 (MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_TO + 1) 37 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_FILTER_GRP_IDX_TO \ 38 (MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_FILTER_GRP_IDX_FROM + \ 39 MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE - 1) 40 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_GRP_IDX_FROM \ 41 (MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_FILTER_GRP_IDX_TO + 1) 42 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_GRP_IDX_TO \ 43 (MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_GRP_IDX_FROM + \ 44 MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE - 1) 45 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_FILTER_GRP_IDX_FROM \ 46 (MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_GRP_IDX_TO + 1) 47 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_FILTER_GRP_IDX_TO \ 48 (MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_FILTER_GRP_IDX_FROM + \ 49 MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE - 1) 50 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MAC_GRP_IDX_FROM \ 51 (MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_FILTER_GRP_IDX_TO + 1) 52 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MAC_GRP_IDX_TO \ 53 (MLX5_ESW_BRIDGE_INGRESS_TABLE_MAC_GRP_IDX_FROM + \ 54 MLX5_ESW_BRIDGE_INGRESS_TABLE_UNTAGGED_GRP_SIZE - 1) 55 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_SIZE \ 56 (MLX5_ESW_BRIDGE_INGRESS_TABLE_MAC_GRP_IDX_TO + 1) 57 static_assert(MLX5_ESW_BRIDGE_INGRESS_TABLE_SIZE == 1048576); 58 59 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_SIZE 131072 60 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_SIZE (262144 - 1) 61 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_IDX_FROM 0 62 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_IDX_TO \ 63 (MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_SIZE - 1) 64 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_QINQ_GRP_IDX_FROM \ 65 (MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_IDX_TO + 1) 66 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_QINQ_GRP_IDX_TO \ 67 (MLX5_ESW_BRIDGE_EGRESS_TABLE_QINQ_GRP_IDX_FROM + \ 68 MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_SIZE - 1) 69 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_FROM \ 70 (MLX5_ESW_BRIDGE_EGRESS_TABLE_QINQ_GRP_IDX_TO + 1) 71 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_TO \ 72 (MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_FROM + \ 73 MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_SIZE - 1) 74 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_FROM \ 75 (MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_TO + 1) 76 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_TO \ 77 MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_FROM 78 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_SIZE \ 79 (MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_TO + 1) 80 static_assert(MLX5_ESW_BRIDGE_EGRESS_TABLE_SIZE == 524288); 81 82 #define MLX5_ESW_BRIDGE_SKIP_TABLE_SIZE 0 83 84 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_SIZE 1 85 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_SIZE 1 86 #define MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_SIZE 4095 87 #define MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_SIZE MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_SIZE 88 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_IDX_FROM 0 89 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_IDX_TO \ 90 (MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_SIZE - 1) 91 #define MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_IDX_FROM \ 92 (MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_IDX_TO + 1) 93 #define MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_IDX_TO \ 94 (MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_IDX_FROM + \ 95 MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_SIZE - 1) 96 #define MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_IDX_FROM \ 97 (MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_IDX_TO + 1) 98 #define MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_IDX_TO \ 99 (MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_IDX_FROM + \ 100 MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_SIZE - 1) 101 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_IDX_FROM \ 102 (MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_IDX_TO + 1) 103 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_IDX_TO \ 104 (MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_IDX_FROM + \ 105 MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_SIZE - 1) 106 107 #define MLX5_ESW_BRIDGE_MCAST_TABLE_SIZE \ 108 (MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_IDX_TO + 1) 109 static_assert(MLX5_ESW_BRIDGE_MCAST_TABLE_SIZE == 8192); 110 111 enum { 112 MLX5_ESW_BRIDGE_LEVEL_INGRESS_TABLE, 113 MLX5_ESW_BRIDGE_LEVEL_EGRESS_TABLE, 114 MLX5_ESW_BRIDGE_LEVEL_MCAST_TABLE, 115 MLX5_ESW_BRIDGE_LEVEL_SKIP_TABLE, 116 }; 117 118 enum { 119 MLX5_ESW_BRIDGE_VLAN_FILTERING_FLAG = BIT(0), 120 MLX5_ESW_BRIDGE_MCAST_FLAG = BIT(1), 121 }; 122 123 struct mlx5_esw_bridge_fdb_key { 124 unsigned char addr[ETH_ALEN]; 125 u16 vid; 126 }; 127 128 struct mlx5_esw_bridge_mdb_key { 129 unsigned char addr[ETH_ALEN]; 130 u16 vid; 131 }; 132 133 enum { 134 MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER = BIT(0), 135 MLX5_ESW_BRIDGE_FLAG_PEER = BIT(1), 136 MLX5_ESW_BRIDGE_FLAG_DELETED = BIT(2), 137 }; 138 139 enum { 140 MLX5_ESW_BRIDGE_PORT_FLAG_PEER = BIT(0), 141 }; 142 143 struct mlx5_esw_bridge_fdb_entry { 144 struct mlx5_esw_bridge_fdb_key key; 145 struct rhash_head ht_node; 146 struct net_device *dev; 147 struct list_head list; 148 struct list_head vlan_list; 149 u16 vport_num; 150 u16 esw_owner_vhca_id; 151 u16 flags; 152 153 struct mlx5_flow_handle *ingress_handle; 154 struct mlx5_fc *ingress_counter; 155 unsigned long lastuse; 156 struct mlx5_flow_handle *egress_handle; 157 struct mlx5_flow_handle *filter_handle; 158 }; 159 160 struct mlx5_esw_bridge_mdb_entry { 161 struct mlx5_esw_bridge_mdb_key key; 162 struct rhash_head ht_node; 163 struct list_head list; 164 struct xarray ports; 165 int num_ports; 166 167 struct mlx5_flow_handle *egress_handle; 168 }; 169 170 struct mlx5_esw_bridge_vlan { 171 u16 vid; 172 u16 flags; 173 struct list_head fdb_list; 174 struct mlx5_pkt_reformat *pkt_reformat_push; 175 struct mlx5_pkt_reformat *pkt_reformat_pop; 176 struct mlx5_modify_hdr *pkt_mod_hdr_push_mark; 177 struct mlx5_flow_handle *mcast_handle; 178 }; 179 180 struct mlx5_esw_bridge_port { 181 u16 vport_num; 182 u16 esw_owner_vhca_id; 183 u16 flags; 184 struct mlx5_esw_bridge *bridge; 185 struct xarray vlans; 186 struct { 187 struct mlx5_flow_table *ft; 188 struct mlx5_flow_group *filter_fg; 189 struct mlx5_flow_group *vlan_fg; 190 struct mlx5_flow_group *qinq_fg; 191 struct mlx5_flow_group *fwd_fg; 192 193 struct mlx5_flow_handle *filter_handle; 194 struct mlx5_flow_handle *fwd_handle; 195 } mcast; 196 }; 197 198 struct mlx5_esw_bridge { 199 int ifindex; 200 int refcnt; 201 struct list_head list; 202 struct mlx5_esw_bridge_offloads *br_offloads; 203 struct dentry *debugfs_dir; 204 205 struct list_head fdb_list; 206 struct rhashtable fdb_ht; 207 208 struct list_head mdb_list; 209 struct rhashtable mdb_ht; 210 211 struct mlx5_flow_table *egress_ft; 212 struct mlx5_flow_group *egress_vlan_fg; 213 struct mlx5_flow_group *egress_qinq_fg; 214 struct mlx5_flow_group *egress_mac_fg; 215 struct mlx5_flow_group *egress_miss_fg; 216 struct mlx5_pkt_reformat *egress_miss_pkt_reformat; 217 struct mlx5_flow_handle *egress_miss_handle; 218 unsigned long ageing_time; 219 u32 flags; 220 u16 vlan_proto; 221 }; 222 223 struct mlx5_flow_table *mlx5_esw_bridge_table_create(int max_fte, u32 level, 224 struct mlx5_eswitch *esw); 225 unsigned long mlx5_esw_bridge_port_key(struct mlx5_esw_bridge_port *port); 226 227 int mlx5_esw_bridge_port_mcast_init(struct mlx5_esw_bridge_port *port); 228 void mlx5_esw_bridge_port_mcast_cleanup(struct mlx5_esw_bridge_port *port); 229 int mlx5_esw_bridge_vlan_mcast_init(u16 vlan_proto, struct mlx5_esw_bridge_port *port, 230 struct mlx5_esw_bridge_vlan *vlan); 231 void mlx5_esw_bridge_vlan_mcast_cleanup(struct mlx5_esw_bridge_vlan *vlan); 232 233 int mlx5_esw_bridge_mcast_enable(struct mlx5_esw_bridge *bridge); 234 void mlx5_esw_bridge_mcast_disable(struct mlx5_esw_bridge *bridge); 235 236 int mlx5_esw_bridge_mdb_init(struct mlx5_esw_bridge *bridge); 237 void mlx5_esw_bridge_mdb_cleanup(struct mlx5_esw_bridge *bridge); 238 int mlx5_esw_bridge_port_mdb_attach(struct net_device *dev, struct mlx5_esw_bridge_port *port, 239 const unsigned char *addr, u16 vid); 240 void mlx5_esw_bridge_port_mdb_detach(struct net_device *dev, struct mlx5_esw_bridge_port *port, 241 const unsigned char *addr, u16 vid); 242 void mlx5_esw_bridge_port_mdb_vlan_flush(struct mlx5_esw_bridge_port *port, 243 struct mlx5_esw_bridge_vlan *vlan); 244 void mlx5_esw_bridge_mdb_flush(struct mlx5_esw_bridge *bridge); 245 246 void mlx5_esw_bridge_debugfs_offloads_init(struct mlx5_esw_bridge_offloads *br_offloads); 247 void mlx5_esw_bridge_debugfs_offloads_cleanup(struct mlx5_esw_bridge_offloads *br_offloads); 248 void mlx5_esw_bridge_debugfs_init(struct net_device *br_netdev, struct mlx5_esw_bridge *bridge); 249 void mlx5_esw_bridge_debugfs_cleanup(struct mlx5_esw_bridge *bridge); 250 251 #endif /* _MLX5_ESW_BRIDGE_PRIVATE_ */ 252