191ad1bd9SKonstantin Belousov /*- 291ad1bd9SKonstantin Belousov * Copyright (c) 2013-2017, Mellanox Technologies, Ltd. All rights reserved. 391ad1bd9SKonstantin Belousov * 491ad1bd9SKonstantin Belousov * Redistribution and use in source and binary forms, with or without 591ad1bd9SKonstantin Belousov * modification, are permitted provided that the following conditions 691ad1bd9SKonstantin Belousov * are met: 791ad1bd9SKonstantin Belousov * 1. Redistributions of source code must retain the above copyright 891ad1bd9SKonstantin Belousov * notice, this list of conditions and the following disclaimer. 991ad1bd9SKonstantin Belousov * 2. Redistributions in binary form must reproduce the above copyright 1091ad1bd9SKonstantin Belousov * notice, this list of conditions and the following disclaimer in the 1191ad1bd9SKonstantin Belousov * documentation and/or other materials provided with the distribution. 1291ad1bd9SKonstantin Belousov * 1391ad1bd9SKonstantin Belousov * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 1491ad1bd9SKonstantin Belousov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1591ad1bd9SKonstantin Belousov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1691ad1bd9SKonstantin Belousov * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 1791ad1bd9SKonstantin Belousov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1891ad1bd9SKonstantin Belousov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1991ad1bd9SKonstantin Belousov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2091ad1bd9SKonstantin Belousov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2191ad1bd9SKonstantin Belousov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2291ad1bd9SKonstantin Belousov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2391ad1bd9SKonstantin Belousov * SUCH DAMAGE. 2491ad1bd9SKonstantin Belousov * 2591ad1bd9SKonstantin Belousov * $FreeBSD$ 2691ad1bd9SKonstantin Belousov */ 2791ad1bd9SKonstantin Belousov 2891ad1bd9SKonstantin Belousov #ifndef __MLX5_ESWITCH_H__ 2991ad1bd9SKonstantin Belousov #define __MLX5_ESWITCH_H__ 3091ad1bd9SKonstantin Belousov 3191ad1bd9SKonstantin Belousov #include <linux/if_ether.h> 3291ad1bd9SKonstantin Belousov #include <dev/mlx5/device.h> 3391ad1bd9SKonstantin Belousov 3491ad1bd9SKonstantin Belousov #define MLX5_MAX_UC_PER_VPORT(dev) \ 3591ad1bd9SKonstantin Belousov (1 << MLX5_CAP_GEN(dev, log_max_current_uc_list)) 3691ad1bd9SKonstantin Belousov 3791ad1bd9SKonstantin Belousov #define MLX5_MAX_MC_PER_VPORT(dev) \ 3891ad1bd9SKonstantin Belousov (1 << MLX5_CAP_GEN(dev, log_max_current_mc_list)) 3991ad1bd9SKonstantin Belousov 4091ad1bd9SKonstantin Belousov #define MLX5_L2_ADDR_HASH_SIZE (BIT(BITS_PER_BYTE)) 4191ad1bd9SKonstantin Belousov #define MLX5_L2_ADDR_HASH(addr) (addr[5]) 4291ad1bd9SKonstantin Belousov 4391ad1bd9SKonstantin Belousov /* L2 -mac address based- hash helpers */ 4491ad1bd9SKonstantin Belousov struct l2addr_node { 4591ad1bd9SKonstantin Belousov struct hlist_node hlist; 4691ad1bd9SKonstantin Belousov u8 addr[ETH_ALEN]; 4791ad1bd9SKonstantin Belousov }; 4891ad1bd9SKonstantin Belousov 4991ad1bd9SKonstantin Belousov #define for_each_l2hash_node(hn, tmp, hash, i) \ 5091ad1bd9SKonstantin Belousov for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \ 5191ad1bd9SKonstantin Belousov hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist) 5291ad1bd9SKonstantin Belousov 5391ad1bd9SKonstantin Belousov #define l2addr_hash_find(hash, mac, type) ({ \ 5491ad1bd9SKonstantin Belousov int ix = MLX5_L2_ADDR_HASH(mac); \ 5591ad1bd9SKonstantin Belousov bool found = false; \ 5691ad1bd9SKonstantin Belousov type *ptr = NULL; \ 5791ad1bd9SKonstantin Belousov \ 5891ad1bd9SKonstantin Belousov hlist_for_each_entry(ptr, &hash[ix], node.hlist) \ 5991ad1bd9SKonstantin Belousov if (ether_addr_equal(ptr->node.addr, mac)) {\ 6091ad1bd9SKonstantin Belousov found = true; \ 6191ad1bd9SKonstantin Belousov break; \ 6291ad1bd9SKonstantin Belousov } \ 6391ad1bd9SKonstantin Belousov if (!found) \ 6491ad1bd9SKonstantin Belousov ptr = NULL; \ 6591ad1bd9SKonstantin Belousov ptr; \ 6691ad1bd9SKonstantin Belousov }) 6791ad1bd9SKonstantin Belousov 6891ad1bd9SKonstantin Belousov #define l2addr_hash_add(hash, mac, type, gfp) ({ \ 6991ad1bd9SKonstantin Belousov int ix = MLX5_L2_ADDR_HASH(mac); \ 7091ad1bd9SKonstantin Belousov type *ptr = NULL; \ 7191ad1bd9SKonstantin Belousov \ 7291ad1bd9SKonstantin Belousov ptr = kzalloc(sizeof(type), gfp); \ 7391ad1bd9SKonstantin Belousov if (ptr) { \ 7491ad1bd9SKonstantin Belousov ether_addr_copy(ptr->node.addr, mac); \ 7591ad1bd9SKonstantin Belousov hlist_add_head(&ptr->node.hlist, &hash[ix]);\ 7691ad1bd9SKonstantin Belousov } \ 7791ad1bd9SKonstantin Belousov ptr; \ 7891ad1bd9SKonstantin Belousov }) 7991ad1bd9SKonstantin Belousov 8091ad1bd9SKonstantin Belousov #define l2addr_hash_del(ptr) ({ \ 8191ad1bd9SKonstantin Belousov hlist_del(&ptr->node.hlist); \ 8291ad1bd9SKonstantin Belousov kfree(ptr); \ 8391ad1bd9SKonstantin Belousov }) 8491ad1bd9SKonstantin Belousov 8591ad1bd9SKonstantin Belousov struct vport_ingress { 8691ad1bd9SKonstantin Belousov struct mlx5_flow_table *acl; 8791ad1bd9SKonstantin Belousov struct mlx5_flow_group *drop_grp; 8891ad1bd9SKonstantin Belousov struct mlx5_flow_rule *drop_rule; 8991ad1bd9SKonstantin Belousov }; 9091ad1bd9SKonstantin Belousov 9191ad1bd9SKonstantin Belousov struct vport_egress { 9291ad1bd9SKonstantin Belousov struct mlx5_flow_table *acl; 9391ad1bd9SKonstantin Belousov struct mlx5_flow_group *allowed_vlans_grp; 9491ad1bd9SKonstantin Belousov struct mlx5_flow_group *drop_grp; 9591ad1bd9SKonstantin Belousov struct mlx5_flow_rule *allowed_vlan; 9691ad1bd9SKonstantin Belousov struct mlx5_flow_rule *drop_rule; 9791ad1bd9SKonstantin Belousov }; 9891ad1bd9SKonstantin Belousov 9991ad1bd9SKonstantin Belousov struct mlx5_vport { 10091ad1bd9SKonstantin Belousov struct mlx5_core_dev *dev; 10191ad1bd9SKonstantin Belousov int vport; 10291ad1bd9SKonstantin Belousov struct hlist_head uc_list[MLX5_L2_ADDR_HASH_SIZE]; 10391ad1bd9SKonstantin Belousov struct hlist_head mc_list[MLX5_L2_ADDR_HASH_SIZE]; 10491ad1bd9SKonstantin Belousov struct work_struct vport_change_handler; 10591ad1bd9SKonstantin Belousov 10691ad1bd9SKonstantin Belousov struct vport_ingress ingress; 10791ad1bd9SKonstantin Belousov struct vport_egress egress; 10891ad1bd9SKonstantin Belousov 10991ad1bd9SKonstantin Belousov u16 vlan; 11091ad1bd9SKonstantin Belousov u8 qos; 11191ad1bd9SKonstantin Belousov struct mutex state_lock; /* protect dynamic state changes */ 11291ad1bd9SKonstantin Belousov /* This spinlock protects access to vport data, between 11391ad1bd9SKonstantin Belousov * "esw_vport_disable" and ongoing interrupt "mlx5_eswitch_vport_event" 11491ad1bd9SKonstantin Belousov * once vport marked as disabled new interrupts are discarded. 11591ad1bd9SKonstantin Belousov */ 11691ad1bd9SKonstantin Belousov spinlock_t lock; /* vport events sync */ 11791ad1bd9SKonstantin Belousov bool enabled; 11891ad1bd9SKonstantin Belousov u16 enabled_events; 11991ad1bd9SKonstantin Belousov }; 12091ad1bd9SKonstantin Belousov 12191ad1bd9SKonstantin Belousov struct mlx5_l2_table { 12291ad1bd9SKonstantin Belousov struct hlist_head l2_hash[MLX5_L2_ADDR_HASH_SIZE]; 12391ad1bd9SKonstantin Belousov u32 size; 12491ad1bd9SKonstantin Belousov unsigned long *bitmap; 12591ad1bd9SKonstantin Belousov }; 12691ad1bd9SKonstantin Belousov 12791ad1bd9SKonstantin Belousov struct mlx5_eswitch_fdb { 12891ad1bd9SKonstantin Belousov void *fdb; 12991ad1bd9SKonstantin Belousov struct mlx5_flow_group *addr_grp; 13091ad1bd9SKonstantin Belousov }; 13191ad1bd9SKonstantin Belousov 13291ad1bd9SKonstantin Belousov struct mlx5_eswitch { 13391ad1bd9SKonstantin Belousov struct mlx5_core_dev *dev; 13491ad1bd9SKonstantin Belousov struct mlx5_l2_table l2_table; 13591ad1bd9SKonstantin Belousov struct mlx5_eswitch_fdb fdb_table; 13691ad1bd9SKonstantin Belousov struct hlist_head mc_table[MLX5_L2_ADDR_HASH_SIZE]; 13791ad1bd9SKonstantin Belousov struct workqueue_struct *work_queue; 13891ad1bd9SKonstantin Belousov struct mlx5_vport *vports; 13991ad1bd9SKonstantin Belousov int total_vports; 14091ad1bd9SKonstantin Belousov int enabled_vports; 14191ad1bd9SKonstantin Belousov }; 14291ad1bd9SKonstantin Belousov 14391ad1bd9SKonstantin Belousov struct mlx5_esw_vport_info { 14491ad1bd9SKonstantin Belousov __u32 vf; 14591ad1bd9SKonstantin Belousov __u8 mac[32]; 14691ad1bd9SKonstantin Belousov __u32 vlan; 14791ad1bd9SKonstantin Belousov __u32 qos; 14891ad1bd9SKonstantin Belousov __u32 spoofchk; 14991ad1bd9SKonstantin Belousov __u32 linkstate; 15091ad1bd9SKonstantin Belousov __u32 min_tx_rate; 15191ad1bd9SKonstantin Belousov __u32 max_tx_rate; 15291ad1bd9SKonstantin Belousov }; 15391ad1bd9SKonstantin Belousov 15491ad1bd9SKonstantin Belousov /* E-Switch API */ 15591ad1bd9SKonstantin Belousov int mlx5_eswitch_init(struct mlx5_core_dev *dev); 15691ad1bd9SKonstantin Belousov void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw); 15791ad1bd9SKonstantin Belousov void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe); 15891ad1bd9SKonstantin Belousov int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs); 15991ad1bd9SKonstantin Belousov void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw); 16091ad1bd9SKonstantin Belousov int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, 16191ad1bd9SKonstantin Belousov int vport, u8 mac[ETH_ALEN]); 16291ad1bd9SKonstantin Belousov int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, 16391ad1bd9SKonstantin Belousov int vport, int link_state); 16491ad1bd9SKonstantin Belousov int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, 16591ad1bd9SKonstantin Belousov int vport, u16 vlan, u8 qos); 16691ad1bd9SKonstantin Belousov int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, 16791ad1bd9SKonstantin Belousov int vport, struct mlx5_esw_vport_info *evi); 16891ad1bd9SKonstantin Belousov 16991ad1bd9SKonstantin Belousov #endif /* __MLX5_ESWITCH_H__ */ 170