1
2
3
4#include "ice.h"
5#include "ice_fltr.h"
6
7
8
9
10
11
12
13
14
15void ice_fltr_free_list(struct device *dev, struct list_head *h)
16{
17 struct ice_fltr_list_entry *e, *tmp;
18
19 list_for_each_entry_safe(e, tmp, h, list_entry) {
20 list_del(&e->list_entry);
21 devm_kfree(dev, e);
22 }
23}
24
25
26
27
28
29
30
31static int
32ice_fltr_add_entry_to_list(struct device *dev, struct ice_fltr_info *info,
33 struct list_head *list)
34{
35 struct ice_fltr_list_entry *entry;
36
37 entry = devm_kzalloc(dev, sizeof(*entry), GFP_ATOMIC);
38 if (!entry)
39 return -ENOMEM;
40
41 entry->fltr_info = *info;
42
43 INIT_LIST_HEAD(&entry->list_entry);
44 list_add(&entry->list_entry, list);
45
46 return 0;
47}
48
49
50
51
52
53
54enum ice_status
55ice_fltr_add_mac_list(struct ice_vsi *vsi, struct list_head *list)
56{
57 return ice_add_mac(&vsi->back->hw, list);
58}
59
60
61
62
63
64
65enum ice_status
66ice_fltr_remove_mac_list(struct ice_vsi *vsi, struct list_head *list)
67{
68 return ice_remove_mac(&vsi->back->hw, list);
69}
70
71
72
73
74
75
76static enum ice_status
77ice_fltr_add_vlan_list(struct ice_vsi *vsi, struct list_head *list)
78{
79 return ice_add_vlan(&vsi->back->hw, list);
80}
81
82
83
84
85
86
87static enum ice_status
88ice_fltr_remove_vlan_list(struct ice_vsi *vsi, struct list_head *list)
89{
90 return ice_remove_vlan(&vsi->back->hw, list);
91}
92
93
94
95
96
97
98static enum ice_status
99ice_fltr_add_eth_list(struct ice_vsi *vsi, struct list_head *list)
100{
101 return ice_add_eth_mac(&vsi->back->hw, list);
102}
103
104
105
106
107
108
109static enum ice_status
110ice_fltr_remove_eth_list(struct ice_vsi *vsi, struct list_head *list)
111{
112 return ice_remove_eth_mac(&vsi->back->hw, list);
113}
114
115
116
117
118
119void ice_fltr_remove_all(struct ice_vsi *vsi)
120{
121 ice_remove_vsi_fltr(&vsi->back->hw, vsi->idx);
122}
123
124
125
126
127
128
129
130
131int
132ice_fltr_add_mac_to_list(struct ice_vsi *vsi, struct list_head *list,
133 const u8 *mac, enum ice_sw_fwd_act_type action)
134{
135 struct ice_fltr_info info = { 0 };
136
137 info.flag = ICE_FLTR_TX;
138 info.src_id = ICE_SRC_ID_VSI;
139 info.lkup_type = ICE_SW_LKUP_MAC;
140 info.fltr_act = action;
141 info.vsi_handle = vsi->idx;
142
143 ether_addr_copy(info.l_data.mac.mac_addr, mac);
144
145 return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
146 list);
147}
148
149
150
151
152
153
154
155
156static int
157ice_fltr_add_vlan_to_list(struct ice_vsi *vsi, struct list_head *list,
158 u16 vlan_id, enum ice_sw_fwd_act_type action)
159{
160 struct ice_fltr_info info = { 0 };
161
162 info.flag = ICE_FLTR_TX;
163 info.src_id = ICE_SRC_ID_VSI;
164 info.lkup_type = ICE_SW_LKUP_VLAN;
165 info.fltr_act = action;
166 info.vsi_handle = vsi->idx;
167 info.l_data.vlan.vlan_id = vlan_id;
168
169 return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
170 list);
171}
172
173
174
175
176
177
178
179
180
181static int
182ice_fltr_add_eth_to_list(struct ice_vsi *vsi, struct list_head *list,
183 u16 ethertype, u16 flag,
184 enum ice_sw_fwd_act_type action)
185{
186 struct ice_fltr_info info = { 0 };
187
188 info.flag = flag;
189 info.lkup_type = ICE_SW_LKUP_ETHERTYPE;
190 info.fltr_act = action;
191 info.vsi_handle = vsi->idx;
192 info.l_data.ethertype_mac.ethertype = ethertype;
193
194 if (flag == ICE_FLTR_TX)
195 info.src_id = ICE_SRC_ID_VSI;
196 else
197 info.src_id = ICE_SRC_ID_LPORT;
198
199 return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
200 list);
201}
202
203
204
205
206
207
208
209
210static enum ice_status
211ice_fltr_prepare_mac(struct ice_vsi *vsi, const u8 *mac,
212 enum ice_sw_fwd_act_type action,
213 enum ice_status (*mac_action)(struct ice_vsi *,
214 struct list_head *))
215{
216 enum ice_status result;
217 LIST_HEAD(tmp_list);
218
219 if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action)) {
220 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
221 return ICE_ERR_NO_MEMORY;
222 }
223
224 result = mac_action(vsi, &tmp_list);
225 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
226 return result;
227}
228
229
230
231
232
233
234
235
236static enum ice_status
237ice_fltr_prepare_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
238 enum ice_sw_fwd_act_type action,
239 enum ice_status(*mac_action)
240 (struct ice_vsi *, struct list_head *))
241{
242 u8 broadcast[ETH_ALEN];
243 enum ice_status result;
244 LIST_HEAD(tmp_list);
245
246 eth_broadcast_addr(broadcast);
247 if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action) ||
248 ice_fltr_add_mac_to_list(vsi, &tmp_list, broadcast, action)) {
249 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
250 return ICE_ERR_NO_MEMORY;
251 }
252
253 result = mac_action(vsi, &tmp_list);
254 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
255 return result;
256}
257
258
259
260
261
262
263
264
265static enum ice_status
266ice_fltr_prepare_vlan(struct ice_vsi *vsi, u16 vlan_id,
267 enum ice_sw_fwd_act_type action,
268 enum ice_status (*vlan_action)(struct ice_vsi *,
269 struct list_head *))
270{
271 enum ice_status result;
272 LIST_HEAD(tmp_list);
273
274 if (ice_fltr_add_vlan_to_list(vsi, &tmp_list, vlan_id, action))
275 return ICE_ERR_NO_MEMORY;
276
277 result = vlan_action(vsi, &tmp_list);
278 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
279 return result;
280}
281
282
283
284
285
286
287
288
289
290static enum ice_status
291ice_fltr_prepare_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
292 enum ice_sw_fwd_act_type action,
293 enum ice_status (*eth_action)(struct ice_vsi *,
294 struct list_head *))
295{
296 enum ice_status result;
297 LIST_HEAD(tmp_list);
298
299 if (ice_fltr_add_eth_to_list(vsi, &tmp_list, ethertype, flag, action))
300 return ICE_ERR_NO_MEMORY;
301
302 result = eth_action(vsi, &tmp_list);
303 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
304 return result;
305}
306
307
308
309
310
311
312
313enum ice_status ice_fltr_add_mac(struct ice_vsi *vsi, const u8 *mac,
314 enum ice_sw_fwd_act_type action)
315{
316 return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_add_mac_list);
317}
318
319
320
321
322
323
324
325enum ice_status
326ice_fltr_add_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
327 enum ice_sw_fwd_act_type action)
328{
329 return ice_fltr_prepare_mac_and_broadcast(vsi, mac, action,
330 ice_fltr_add_mac_list);
331}
332
333
334
335
336
337
338
339enum ice_status ice_fltr_remove_mac(struct ice_vsi *vsi, const u8 *mac,
340 enum ice_sw_fwd_act_type action)
341{
342 return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_remove_mac_list);
343}
344
345
346
347
348
349
350
351enum ice_status ice_fltr_add_vlan(struct ice_vsi *vsi, u16 vlan_id,
352 enum ice_sw_fwd_act_type action)
353{
354 return ice_fltr_prepare_vlan(vsi, vlan_id, action,
355 ice_fltr_add_vlan_list);
356}
357
358
359
360
361
362
363
364enum ice_status ice_fltr_remove_vlan(struct ice_vsi *vsi, u16 vlan_id,
365 enum ice_sw_fwd_act_type action)
366{
367 return ice_fltr_prepare_vlan(vsi, vlan_id, action,
368 ice_fltr_remove_vlan_list);
369}
370
371
372
373
374
375
376
377
378enum ice_status ice_fltr_add_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
379 enum ice_sw_fwd_act_type action)
380{
381 return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
382 ice_fltr_add_eth_list);
383}
384
385
386
387
388
389
390
391
392enum ice_status ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype,
393 u16 flag, enum ice_sw_fwd_act_type action)
394{
395 return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
396 ice_fltr_remove_eth_list);
397}
398