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 }; 137 138 enum { 139 MLX5_ESW_BRIDGE_PORT_FLAG_PEER = BIT(0), 140 }; 141 142 struct mlx5_esw_bridge_fdb_entry { 143 struct mlx5_esw_bridge_fdb_key key; 144 struct rhash_head ht_node; 145 struct net_device *dev; 146 struct list_head list; 147 struct list_head vlan_list; 148 u16 vport_num; 149 u16 esw_owner_vhca_id; 150 u16 flags; 151 152 struct mlx5_flow_handle *ingress_handle; 153 struct mlx5_fc *ingress_counter; 154 unsigned long lastuse; 155 struct mlx5_flow_handle *egress_handle; 156 struct mlx5_flow_handle *filter_handle; 157 }; 158 159 struct mlx5_esw_bridge_mdb_entry { 160 struct mlx5_esw_bridge_mdb_key key; 161 struct rhash_head ht_node; 162 struct list_head list; 163 struct xarray ports; 164 int num_ports; 165 166 struct mlx5_flow_handle *egress_handle; 167 }; 168 169 struct mlx5_esw_bridge_vlan { 170 u16 vid; 171 u16 flags; 172 struct list_head fdb_list; 173 struct mlx5_pkt_reformat *pkt_reformat_push; 174 struct mlx5_pkt_reformat *pkt_reformat_pop; 175 struct mlx5_modify_hdr *pkt_mod_hdr_push_mark; 176 struct mlx5_flow_handle *mcast_handle; 177 }; 178 179 struct mlx5_esw_bridge_port { 180 u16 vport_num; 181 u16 esw_owner_vhca_id; 182 u16 flags; 183 struct mlx5_esw_bridge *bridge; 184 struct xarray vlans; 185 struct { 186 struct mlx5_flow_table *ft; 187 struct mlx5_flow_group *filter_fg; 188 struct mlx5_flow_group *vlan_fg; 189 struct mlx5_flow_group *qinq_fg; 190 struct mlx5_flow_group *fwd_fg; 191 192 struct mlx5_flow_handle *filter_handle; 193 struct mlx5_flow_handle *fwd_handle; 194 } mcast; 195 }; 196 197 struct mlx5_esw_bridge { 198 int ifindex; 199 int refcnt; 200 struct list_head list; 201 struct mlx5_esw_bridge_offloads *br_offloads; 202 203 struct list_head fdb_list; 204 struct rhashtable fdb_ht; 205 206 struct list_head mdb_list; 207 struct rhashtable mdb_ht; 208 209 struct mlx5_flow_table *egress_ft; 210 struct mlx5_flow_group *egress_vlan_fg; 211 struct mlx5_flow_group *egress_qinq_fg; 212 struct mlx5_flow_group *egress_mac_fg; 213 struct mlx5_flow_group *egress_miss_fg; 214 struct mlx5_pkt_reformat *egress_miss_pkt_reformat; 215 struct mlx5_flow_handle *egress_miss_handle; 216 unsigned long ageing_time; 217 u32 flags; 218 u16 vlan_proto; 219 }; 220 221 struct mlx5_flow_table *mlx5_esw_bridge_table_create(int max_fte, u32 level, 222 struct mlx5_eswitch *esw); 223 unsigned long mlx5_esw_bridge_port_key(struct mlx5_esw_bridge_port *port); 224 225 int mlx5_esw_bridge_port_mcast_init(struct mlx5_esw_bridge_port *port); 226 void mlx5_esw_bridge_port_mcast_cleanup(struct mlx5_esw_bridge_port *port); 227 int mlx5_esw_bridge_vlan_mcast_init(u16 vlan_proto, struct mlx5_esw_bridge_port *port, 228 struct mlx5_esw_bridge_vlan *vlan); 229 void mlx5_esw_bridge_vlan_mcast_cleanup(struct mlx5_esw_bridge_vlan *vlan); 230 231 int mlx5_esw_bridge_mcast_enable(struct mlx5_esw_bridge *bridge); 232 void mlx5_esw_bridge_mcast_disable(struct mlx5_esw_bridge *bridge); 233 234 int mlx5_esw_bridge_mdb_init(struct mlx5_esw_bridge *bridge); 235 void mlx5_esw_bridge_mdb_cleanup(struct mlx5_esw_bridge *bridge); 236 int mlx5_esw_bridge_port_mdb_attach(struct net_device *dev, struct mlx5_esw_bridge_port *port, 237 const unsigned char *addr, u16 vid); 238 void mlx5_esw_bridge_port_mdb_detach(struct net_device *dev, struct mlx5_esw_bridge_port *port, 239 const unsigned char *addr, u16 vid); 240 void mlx5_esw_bridge_port_mdb_vlan_flush(struct mlx5_esw_bridge_port *port, 241 struct mlx5_esw_bridge_vlan *vlan); 242 void mlx5_esw_bridge_mdb_flush(struct mlx5_esw_bridge *bridge); 243 244 #endif /* _MLX5_ESW_BRIDGE_PRIVATE_ */ 245