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 * $FreeBSD$
26 */
27
28 #ifndef __MLX5_ESWITCH_H__
29 #define __MLX5_ESWITCH_H__
30
31 #include <linux/if_ether.h>
32 #include <dev/mlx5/device.h>
33
34 #define MLX5_MAX_UC_PER_VPORT(dev) \
35 (1 << MLX5_CAP_GEN(dev, log_max_current_uc_list))
36
37 #define MLX5_MAX_MC_PER_VPORT(dev) \
38 (1 << MLX5_CAP_GEN(dev, log_max_current_mc_list))
39
40 #define MLX5_L2_ADDR_HASH_SIZE (BIT(BITS_PER_BYTE))
41 #define MLX5_L2_ADDR_HASH(addr) (addr[5])
42
43 /* L2 -mac address based- hash helpers */
44 struct l2addr_node {
45 struct hlist_node hlist;
46 u8 addr[ETH_ALEN];
47 };
48
49 #define for_each_l2hash_node(hn, tmp, hash, i) \
50 for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \
51 hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist)
52
53 #define l2addr_hash_find(hash, mac, type) ({ \
54 int ix = MLX5_L2_ADDR_HASH(mac); \
55 bool found = false; \
56 type *ptr = NULL; \
57 \
58 hlist_for_each_entry(ptr, &hash[ix], node.hlist) \
59 if (ether_addr_equal(ptr->node.addr, mac)) {\
60 found = true; \
61 break; \
62 } \
63 if (!found) \
64 ptr = NULL; \
65 ptr; \
66 })
67
68 #define l2addr_hash_add(hash, mac, type, gfp) ({ \
69 int ix = MLX5_L2_ADDR_HASH(mac); \
70 type *ptr = NULL; \
71 \
72 ptr = kzalloc(sizeof(type), gfp); \
73 if (ptr) { \
74 ether_addr_copy(ptr->node.addr, mac); \
75 hlist_add_head(&ptr->node.hlist, &hash[ix]);\
76 } \
77 ptr; \
78 })
79
80 #define l2addr_hash_del(ptr) ({ \
81 hlist_del(&ptr->node.hlist); \
82 kfree(ptr); \
83 })
84
85 struct vport_ingress {
86 struct mlx5_flow_table *acl;
87 struct mlx5_flow_group *drop_grp;
88 struct mlx5_flow_rule *drop_rule;
89 };
90
91 struct vport_egress {
92 struct mlx5_flow_table *acl;
93 struct mlx5_flow_group *allowed_vlans_grp;
94 struct mlx5_flow_group *drop_grp;
95 struct mlx5_flow_rule *allowed_vlan;
96 struct mlx5_flow_rule *drop_rule;
97 };
98
99 struct mlx5_vport {
100 struct mlx5_core_dev *dev;
101 int vport;
102 struct hlist_head uc_list[MLX5_L2_ADDR_HASH_SIZE];
103 struct hlist_head mc_list[MLX5_L2_ADDR_HASH_SIZE];
104 struct work_struct vport_change_handler;
105
106 struct vport_ingress ingress;
107 struct vport_egress egress;
108
109 u16 vlan;
110 u8 qos;
111 struct mutex state_lock; /* protect dynamic state changes */
112 /* This spinlock protects access to vport data, between
113 * "esw_vport_disable" and ongoing interrupt "mlx5_eswitch_vport_event"
114 * once vport marked as disabled new interrupts are discarded.
115 */
116 spinlock_t lock; /* vport events sync */
117 bool enabled;
118 u16 enabled_events;
119 };
120
121 struct mlx5_l2_table {
122 struct hlist_head l2_hash[MLX5_L2_ADDR_HASH_SIZE];
123 u32 size;
124 unsigned long *bitmap;
125 };
126
127 struct mlx5_eswitch_fdb {
128 void *fdb;
129 struct mlx5_flow_group *addr_grp;
130 };
131
132 struct mlx5_eswitch {
133 struct mlx5_core_dev *dev;
134 struct mlx5_l2_table l2_table;
135 struct mlx5_eswitch_fdb fdb_table;
136 struct hlist_head mc_table[MLX5_L2_ADDR_HASH_SIZE];
137 struct workqueue_struct *work_queue;
138 struct mlx5_vport *vports;
139 int total_vports;
140 int enabled_vports;
141 };
142
143 struct mlx5_esw_vport_info {
144 __u32 vf;
145 __u8 mac[32];
146 __u32 vlan;
147 __u32 qos;
148 __u32 spoofchk;
149 __u32 linkstate;
150 __u32 min_tx_rate;
151 __u32 max_tx_rate;
152 };
153
154 /* E-Switch API */
155 int mlx5_eswitch_init(struct mlx5_core_dev *dev, int total_vports);
156 void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
157 void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
158 int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs);
159 void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
160 int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
161 int vport, u8 mac[ETH_ALEN]);
162 int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
163 int vport, int link_state);
164 int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
165 int vport, u16 vlan, u8 qos);
166 int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
167 int vport, struct mlx5_esw_vport_info *evi);
168
169 #endif /* __MLX5_ESWITCH_H__ */
Cache object: d71e5816777bca3315b112ad1ede4a1c
|