xref: /freebsd/sys/dev/mlx5/mlx5_core/eswitch.h (revision 95ee2897)
1 /*-
2  * Copyright (c) 2013-2017, Mellanox Technologies, Ltd.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 #ifndef __MLX5_ESWITCH_H__
27 #define __MLX5_ESWITCH_H__
28 
29 #include <linux/if_ether.h>
30 #include <dev/mlx5/device.h>
31 
32 #define MLX5_MAX_UC_PER_VPORT(dev) \
33 	(1 << MLX5_CAP_GEN(dev, log_max_current_uc_list))
34 
35 #define MLX5_MAX_MC_PER_VPORT(dev) \
36 	(1 << MLX5_CAP_GEN(dev, log_max_current_mc_list))
37 
38 #define MLX5_L2_ADDR_HASH_SIZE (BIT(BITS_PER_BYTE))
39 #define MLX5_L2_ADDR_HASH(addr) (addr[5])
40 
41 /* L2 -mac address based- hash helpers */
42 struct l2addr_node {
43 	struct hlist_node hlist;
44 	u8                addr[ETH_ALEN];
45 };
46 
47 #define for_each_l2hash_node(hn, tmp, hash, i) \
48 	for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \
49 		hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist)
50 
51 #define l2addr_hash_find(hash, mac, type) ({                \
52 	int ix = MLX5_L2_ADDR_HASH(mac);                    \
53 	bool found = false;                                 \
54 	type *ptr = NULL;                                   \
55 							    \
56 	hlist_for_each_entry(ptr, &hash[ix], node.hlist)    \
57 		if (ether_addr_equal(ptr->node.addr, mac)) {\
58 			found = true;                       \
59 			break;                              \
60 		}                                           \
61 	if (!found)                                         \
62 		ptr = NULL;                                 \
63 	ptr;                                                \
64 })
65 
66 #define l2addr_hash_add(hash, mac, type, gfp) ({            \
67 	int ix = MLX5_L2_ADDR_HASH(mac);                    \
68 	type *ptr = NULL;                                   \
69 							    \
70 	ptr = kzalloc(sizeof(type), gfp);                   \
71 	if (ptr) {                                          \
72 		ether_addr_copy(ptr->node.addr, mac);       \
73 		hlist_add_head(&ptr->node.hlist, &hash[ix]);\
74 	}                                                   \
75 	ptr;                                                \
76 })
77 
78 #define l2addr_hash_del(ptr) ({                             \
79 	hlist_del(&ptr->node.hlist);                        \
80 	kfree(ptr);                                         \
81 })
82 
83 struct vport_ingress {
84 	struct mlx5_flow_table *acl;
85 	struct mlx5_flow_group *drop_grp;
86 	struct mlx5_flow_rule  *drop_rule;
87 };
88 
89 struct vport_egress {
90 	struct mlx5_flow_table *acl;
91 	struct mlx5_flow_group *allowed_vlans_grp;
92 	struct mlx5_flow_group *drop_grp;
93 	struct mlx5_flow_rule  *allowed_vlan;
94 	struct mlx5_flow_rule  *drop_rule;
95 };
96 
97 struct mlx5_vport {
98 	struct mlx5_core_dev    *dev;
99 	int                     vport;
100 	struct hlist_head       uc_list[MLX5_L2_ADDR_HASH_SIZE];
101 	struct hlist_head       mc_list[MLX5_L2_ADDR_HASH_SIZE];
102 	struct work_struct      vport_change_handler;
103 
104 	struct vport_ingress    ingress;
105 	struct vport_egress     egress;
106 
107 	u16                     vlan;
108 	u8                      qos;
109 	struct mutex	state_lock; /* protect dynamic state changes */
110 	/* This spinlock protects access to vport data, between
111 	 * "esw_vport_disable" and ongoing interrupt "mlx5_eswitch_vport_event"
112 	 * once vport marked as disabled new interrupts are discarded.
113 	 */
114 	spinlock_t              lock; /* vport events sync */
115 	bool                    enabled;
116 	u16                     enabled_events;
117 };
118 
119 struct mlx5_l2_table {
120 	struct hlist_head l2_hash[MLX5_L2_ADDR_HASH_SIZE];
121 	u32                  size;
122 	unsigned long        *bitmap;
123 };
124 
125 struct mlx5_eswitch_fdb {
126 	void *fdb;
127 	struct mlx5_flow_group *addr_grp;
128 };
129 
130 struct mlx5_eswitch {
131 	struct mlx5_core_dev    *dev;
132 	struct mlx5_l2_table    l2_table;
133 	struct mlx5_eswitch_fdb fdb_table;
134 	struct hlist_head       mc_table[MLX5_L2_ADDR_HASH_SIZE];
135 	struct workqueue_struct *work_queue;
136 	struct mlx5_vport       *vports;
137 	int                     total_vports;
138 	int                     enabled_vports;
139 };
140 
141 struct mlx5_esw_vport_info {
142 	__u32 vf;
143 	__u8 mac[32];
144 	__u32 vlan;
145 	__u32 qos;
146 	__u32 spoofchk;
147 	__u32 linkstate;
148 	__u32 min_tx_rate;
149 	__u32 max_tx_rate;
150 };
151 
152 /* E-Switch API */
153 int mlx5_eswitch_init(struct mlx5_core_dev *dev, int total_vports);
154 void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
155 void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
156 int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs);
157 void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
158 int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
159 			       int vport, u8 mac[ETH_ALEN]);
160 int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
161 				 int vport, int link_state);
162 int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
163 				int vport, u16 vlan, u8 qos);
164 int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
165 				  int vport, struct mlx5_esw_vport_info *evi);
166 
167 #endif /* __MLX5_ESWITCH_H__ */
168