1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2021, Intel Corporation. */
3 
4 #include "ice.h"
5 #include "ice_base.h"
6 #include "ice_lib.h"
7 #include "ice_flow.h"
8 #include "ice_vf_lib_private.h"
9 
10 #define to_fltr_conf_from_desc(p) \
11 	container_of(p, struct virtchnl_fdir_fltr_conf, input)
12 
13 #define ICE_FLOW_PROF_TYPE_S	0
14 #define ICE_FLOW_PROF_TYPE_M	(0xFFFFFFFFULL << ICE_FLOW_PROF_TYPE_S)
15 #define ICE_FLOW_PROF_VSI_S	32
16 #define ICE_FLOW_PROF_VSI_M	(0xFFFFFFFFULL << ICE_FLOW_PROF_VSI_S)
17 
18 /* Flow profile ID format:
19  * [0:31] - flow type, flow + tun_offs
20  * [32:63] - VSI index
21  */
22 #define ICE_FLOW_PROF_FD(vsi, flow, tun_offs) \
23 	((u64)(((((flow) + (tun_offs)) & ICE_FLOW_PROF_TYPE_M)) | \
24 	      (((u64)(vsi) << ICE_FLOW_PROF_VSI_S) & ICE_FLOW_PROF_VSI_M)))
25 
26 #define GTPU_TEID_OFFSET 4
27 #define GTPU_EH_QFI_OFFSET 1
28 #define GTPU_EH_QFI_MASK 0x3F
29 #define PFCP_S_OFFSET 0
30 #define PFCP_S_MASK 0x1
31 #define PFCP_PORT_NR 8805
32 
33 #define FDIR_INSET_FLAG_ESP_S 0
34 #define FDIR_INSET_FLAG_ESP_M BIT_ULL(FDIR_INSET_FLAG_ESP_S)
35 #define FDIR_INSET_FLAG_ESP_UDP BIT_ULL(FDIR_INSET_FLAG_ESP_S)
36 #define FDIR_INSET_FLAG_ESP_IPSEC (0ULL << FDIR_INSET_FLAG_ESP_S)
37 
38 enum ice_fdir_tunnel_type {
39 	ICE_FDIR_TUNNEL_TYPE_NONE = 0,
40 	ICE_FDIR_TUNNEL_TYPE_GTPU,
41 	ICE_FDIR_TUNNEL_TYPE_GTPU_EH,
42 };
43 
44 struct virtchnl_fdir_fltr_conf {
45 	struct ice_fdir_fltr input;
46 	enum ice_fdir_tunnel_type ttype;
47 	u64 inset_flag;
48 	u32 flow_id;
49 };
50 
51 struct virtchnl_fdir_inset_map {
52 	enum virtchnl_proto_hdr_field field;
53 	enum ice_flow_field fld;
54 	u64 flag;
55 	u64 mask;
56 };
57 
58 static const struct virtchnl_fdir_inset_map fdir_inset_map[] = {
59 	{VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE, ICE_FLOW_FIELD_IDX_ETH_TYPE, 0, 0},
60 	{VIRTCHNL_PROTO_HDR_IPV4_SRC, ICE_FLOW_FIELD_IDX_IPV4_SA, 0, 0},
61 	{VIRTCHNL_PROTO_HDR_IPV4_DST, ICE_FLOW_FIELD_IDX_IPV4_DA, 0, 0},
62 	{VIRTCHNL_PROTO_HDR_IPV4_DSCP, ICE_FLOW_FIELD_IDX_IPV4_DSCP, 0, 0},
63 	{VIRTCHNL_PROTO_HDR_IPV4_TTL, ICE_FLOW_FIELD_IDX_IPV4_TTL, 0, 0},
64 	{VIRTCHNL_PROTO_HDR_IPV4_PROT, ICE_FLOW_FIELD_IDX_IPV4_PROT, 0, 0},
65 	{VIRTCHNL_PROTO_HDR_IPV6_SRC, ICE_FLOW_FIELD_IDX_IPV6_SA, 0, 0},
66 	{VIRTCHNL_PROTO_HDR_IPV6_DST, ICE_FLOW_FIELD_IDX_IPV6_DA, 0, 0},
67 	{VIRTCHNL_PROTO_HDR_IPV6_TC, ICE_FLOW_FIELD_IDX_IPV6_DSCP, 0, 0},
68 	{VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT, ICE_FLOW_FIELD_IDX_IPV6_TTL, 0, 0},
69 	{VIRTCHNL_PROTO_HDR_IPV6_PROT, ICE_FLOW_FIELD_IDX_IPV6_PROT, 0, 0},
70 	{VIRTCHNL_PROTO_HDR_UDP_SRC_PORT, ICE_FLOW_FIELD_IDX_UDP_SRC_PORT, 0, 0},
71 	{VIRTCHNL_PROTO_HDR_UDP_DST_PORT, ICE_FLOW_FIELD_IDX_UDP_DST_PORT, 0, 0},
72 	{VIRTCHNL_PROTO_HDR_TCP_SRC_PORT, ICE_FLOW_FIELD_IDX_TCP_SRC_PORT, 0, 0},
73 	{VIRTCHNL_PROTO_HDR_TCP_DST_PORT, ICE_FLOW_FIELD_IDX_TCP_DST_PORT, 0, 0},
74 	{VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT, ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT, 0, 0},
75 	{VIRTCHNL_PROTO_HDR_SCTP_DST_PORT, ICE_FLOW_FIELD_IDX_SCTP_DST_PORT, 0, 0},
76 	{VIRTCHNL_PROTO_HDR_GTPU_IP_TEID, ICE_FLOW_FIELD_IDX_GTPU_IP_TEID, 0, 0},
77 	{VIRTCHNL_PROTO_HDR_GTPU_EH_QFI, ICE_FLOW_FIELD_IDX_GTPU_EH_QFI, 0, 0},
78 	{VIRTCHNL_PROTO_HDR_ESP_SPI, ICE_FLOW_FIELD_IDX_ESP_SPI,
79 		FDIR_INSET_FLAG_ESP_IPSEC, FDIR_INSET_FLAG_ESP_M},
80 	{VIRTCHNL_PROTO_HDR_ESP_SPI, ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI,
81 		FDIR_INSET_FLAG_ESP_UDP, FDIR_INSET_FLAG_ESP_M},
82 	{VIRTCHNL_PROTO_HDR_AH_SPI, ICE_FLOW_FIELD_IDX_AH_SPI, 0, 0},
83 	{VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID, ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID, 0, 0},
84 	{VIRTCHNL_PROTO_HDR_PFCP_S_FIELD, ICE_FLOW_FIELD_IDX_UDP_DST_PORT, 0, 0},
85 };
86 
87 /**
88  * ice_vc_fdir_param_check
89  * @vf: pointer to the VF structure
90  * @vsi_id: VF relative VSI ID
91  *
92  * Check for the valid VSI ID, PF's state and VF's state
93  *
94  * Return: 0 on success, and -EINVAL on error.
95  */
96 static int
ice_vc_fdir_param_check(struct ice_vf * vf,u16 vsi_id)97 ice_vc_fdir_param_check(struct ice_vf *vf, u16 vsi_id)
98 {
99 	struct ice_pf *pf = vf->pf;
100 
101 	if (!test_bit(ICE_FLAG_FD_ENA, pf->flags))
102 		return -EINVAL;
103 
104 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
105 		return -EINVAL;
106 
107 	if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_FDIR_PF))
108 		return -EINVAL;
109 
110 	if (!ice_vc_isvalid_vsi_id(vf, vsi_id))
111 		return -EINVAL;
112 
113 	if (!ice_get_vf_vsi(vf))
114 		return -EINVAL;
115 
116 	return 0;
117 }
118 
119 /**
120  * ice_vf_start_ctrl_vsi
121  * @vf: pointer to the VF structure
122  *
123  * Allocate ctrl_vsi for the first time and open the ctrl_vsi port for VF
124  *
125  * Return: 0 on success, and other on error.
126  */
ice_vf_start_ctrl_vsi(struct ice_vf * vf)127 static int ice_vf_start_ctrl_vsi(struct ice_vf *vf)
128 {
129 	struct ice_pf *pf = vf->pf;
130 	struct ice_vsi *ctrl_vsi;
131 	struct device *dev;
132 	int err;
133 
134 	dev = ice_pf_to_dev(pf);
135 	if (vf->ctrl_vsi_idx != ICE_NO_VSI)
136 		return -EEXIST;
137 
138 	ctrl_vsi = ice_vf_ctrl_vsi_setup(vf);
139 	if (!ctrl_vsi) {
140 		dev_dbg(dev, "Could not setup control VSI for VF %d\n",
141 			vf->vf_id);
142 		return -ENOMEM;
143 	}
144 
145 	err = ice_vsi_open_ctrl(ctrl_vsi);
146 	if (err) {
147 		dev_dbg(dev, "Could not open control VSI for VF %d\n",
148 			vf->vf_id);
149 		goto err_vsi_open;
150 	}
151 
152 	return 0;
153 
154 err_vsi_open:
155 	ice_vsi_release(ctrl_vsi);
156 	if (vf->ctrl_vsi_idx != ICE_NO_VSI) {
157 		pf->vsi[vf->ctrl_vsi_idx] = NULL;
158 		vf->ctrl_vsi_idx = ICE_NO_VSI;
159 	}
160 	return err;
161 }
162 
163 /**
164  * ice_vc_fdir_alloc_prof - allocate profile for this filter flow type
165  * @vf: pointer to the VF structure
166  * @flow: filter flow type
167  *
168  * Return: 0 on success, and other on error.
169  */
170 static int
ice_vc_fdir_alloc_prof(struct ice_vf * vf,enum ice_fltr_ptype flow)171 ice_vc_fdir_alloc_prof(struct ice_vf *vf, enum ice_fltr_ptype flow)
172 {
173 	struct ice_vf_fdir *fdir = &vf->fdir;
174 
175 	if (!fdir->fdir_prof) {
176 		fdir->fdir_prof = devm_kcalloc(ice_pf_to_dev(vf->pf),
177 					       ICE_FLTR_PTYPE_MAX,
178 					       sizeof(*fdir->fdir_prof),
179 					       GFP_KERNEL);
180 		if (!fdir->fdir_prof)
181 			return -ENOMEM;
182 	}
183 
184 	if (!fdir->fdir_prof[flow]) {
185 		fdir->fdir_prof[flow] = devm_kzalloc(ice_pf_to_dev(vf->pf),
186 						     sizeof(**fdir->fdir_prof),
187 						     GFP_KERNEL);
188 		if (!fdir->fdir_prof[flow])
189 			return -ENOMEM;
190 	}
191 
192 	return 0;
193 }
194 
195 /**
196  * ice_vc_fdir_free_prof - free profile for this filter flow type
197  * @vf: pointer to the VF structure
198  * @flow: filter flow type
199  */
200 static void
ice_vc_fdir_free_prof(struct ice_vf * vf,enum ice_fltr_ptype flow)201 ice_vc_fdir_free_prof(struct ice_vf *vf, enum ice_fltr_ptype flow)
202 {
203 	struct ice_vf_fdir *fdir = &vf->fdir;
204 
205 	if (!fdir->fdir_prof)
206 		return;
207 
208 	if (!fdir->fdir_prof[flow])
209 		return;
210 
211 	devm_kfree(ice_pf_to_dev(vf->pf), fdir->fdir_prof[flow]);
212 	fdir->fdir_prof[flow] = NULL;
213 }
214 
215 /**
216  * ice_vc_fdir_free_prof_all - free all the profile for this VF
217  * @vf: pointer to the VF structure
218  */
ice_vc_fdir_free_prof_all(struct ice_vf * vf)219 static void ice_vc_fdir_free_prof_all(struct ice_vf *vf)
220 {
221 	struct ice_vf_fdir *fdir = &vf->fdir;
222 	enum ice_fltr_ptype flow;
223 
224 	if (!fdir->fdir_prof)
225 		return;
226 
227 	for (flow = ICE_FLTR_PTYPE_NONF_NONE; flow < ICE_FLTR_PTYPE_MAX; flow++)
228 		ice_vc_fdir_free_prof(vf, flow);
229 
230 	devm_kfree(ice_pf_to_dev(vf->pf), fdir->fdir_prof);
231 	fdir->fdir_prof = NULL;
232 }
233 
234 /**
235  * ice_vc_fdir_parse_flow_fld
236  * @proto_hdr: virtual channel protocol filter header
237  * @conf: FDIR configuration for each filter
238  * @fld: field type array
239  * @fld_cnt: field counter
240  *
241  * Parse the virtual channel filter header and store them into field type array
242  *
243  * Return: 0 on success, and other on error.
244  */
245 static int
ice_vc_fdir_parse_flow_fld(struct virtchnl_proto_hdr * proto_hdr,struct virtchnl_fdir_fltr_conf * conf,enum ice_flow_field * fld,int * fld_cnt)246 ice_vc_fdir_parse_flow_fld(struct virtchnl_proto_hdr *proto_hdr,
247 			   struct virtchnl_fdir_fltr_conf *conf,
248 			   enum ice_flow_field *fld, int *fld_cnt)
249 {
250 	struct virtchnl_proto_hdr hdr;
251 	u32 i;
252 
253 	memcpy(&hdr, proto_hdr, sizeof(hdr));
254 
255 	for (i = 0; (i < ARRAY_SIZE(fdir_inset_map)) &&
256 	     VIRTCHNL_GET_PROTO_HDR_FIELD(&hdr); i++)
257 		if (VIRTCHNL_TEST_PROTO_HDR(&hdr, fdir_inset_map[i].field)) {
258 			if (fdir_inset_map[i].mask &&
259 			    ((fdir_inset_map[i].mask & conf->inset_flag) !=
260 			     fdir_inset_map[i].flag))
261 				continue;
262 
263 			fld[*fld_cnt] = fdir_inset_map[i].fld;
264 			*fld_cnt += 1;
265 			if (*fld_cnt >= ICE_FLOW_FIELD_IDX_MAX)
266 				return -EINVAL;
267 			VIRTCHNL_DEL_PROTO_HDR_FIELD(&hdr,
268 						     fdir_inset_map[i].field);
269 		}
270 
271 	return 0;
272 }
273 
274 /**
275  * ice_vc_fdir_set_flow_fld
276  * @vf: pointer to the VF structure
277  * @fltr: virtual channel add cmd buffer
278  * @conf: FDIR configuration for each filter
279  * @seg: array of one or more packet segments that describe the flow
280  *
281  * Parse the virtual channel add msg buffer's field vector and store them into
282  * flow's packet segment field
283  *
284  * Return: 0 on success, and other on error.
285  */
286 static int
ice_vc_fdir_set_flow_fld(struct ice_vf * vf,struct virtchnl_fdir_add * fltr,struct virtchnl_fdir_fltr_conf * conf,struct ice_flow_seg_info * seg)287 ice_vc_fdir_set_flow_fld(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
288 			 struct virtchnl_fdir_fltr_conf *conf,
289 			 struct ice_flow_seg_info *seg)
290 {
291 	struct virtchnl_fdir_rule *rule = &fltr->rule_cfg;
292 	enum ice_flow_field fld[ICE_FLOW_FIELD_IDX_MAX];
293 	struct device *dev = ice_pf_to_dev(vf->pf);
294 	struct virtchnl_proto_hdrs *proto;
295 	int fld_cnt = 0;
296 	int i;
297 
298 	proto = &rule->proto_hdrs;
299 	for (i = 0; i < proto->count; i++) {
300 		struct virtchnl_proto_hdr *hdr = &proto->proto_hdr[i];
301 		int ret;
302 
303 		ret = ice_vc_fdir_parse_flow_fld(hdr, conf, fld, &fld_cnt);
304 		if (ret)
305 			return ret;
306 	}
307 
308 	if (fld_cnt == 0) {
309 		dev_dbg(dev, "Empty input set for VF %d\n", vf->vf_id);
310 		return -EINVAL;
311 	}
312 
313 	for (i = 0; i < fld_cnt; i++)
314 		ice_flow_set_fld(seg, fld[i],
315 				 ICE_FLOW_FLD_OFF_INVAL,
316 				 ICE_FLOW_FLD_OFF_INVAL,
317 				 ICE_FLOW_FLD_OFF_INVAL, false);
318 
319 	return 0;
320 }
321 
322 /**
323  * ice_vc_fdir_set_flow_hdr - config the flow's packet segment header
324  * @vf: pointer to the VF structure
325  * @conf: FDIR configuration for each filter
326  * @seg: array of one or more packet segments that describe the flow
327  *
328  * Return: 0 on success, and other on error.
329  */
330 static int
ice_vc_fdir_set_flow_hdr(struct ice_vf * vf,struct virtchnl_fdir_fltr_conf * conf,struct ice_flow_seg_info * seg)331 ice_vc_fdir_set_flow_hdr(struct ice_vf *vf,
332 			 struct virtchnl_fdir_fltr_conf *conf,
333 			 struct ice_flow_seg_info *seg)
334 {
335 	enum ice_fltr_ptype flow = conf->input.flow_type;
336 	enum ice_fdir_tunnel_type ttype = conf->ttype;
337 	struct device *dev = ice_pf_to_dev(vf->pf);
338 
339 	switch (flow) {
340 	case ICE_FLTR_PTYPE_NON_IP_L2:
341 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ETH_NON_IP);
342 		break;
343 	case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3:
344 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_L2TPV3 |
345 				  ICE_FLOW_SEG_HDR_IPV4 |
346 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
347 		break;
348 	case ICE_FLTR_PTYPE_NONF_IPV4_ESP:
349 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ESP |
350 				  ICE_FLOW_SEG_HDR_IPV4 |
351 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
352 		break;
353 	case ICE_FLTR_PTYPE_NONF_IPV4_AH:
354 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_AH |
355 				  ICE_FLOW_SEG_HDR_IPV4 |
356 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
357 		break;
358 	case ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP:
359 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_NAT_T_ESP |
360 				  ICE_FLOW_SEG_HDR_IPV4 |
361 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
362 		break;
363 	case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE:
364 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_PFCP_NODE |
365 				  ICE_FLOW_SEG_HDR_IPV4 |
366 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
367 		break;
368 	case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION:
369 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_PFCP_SESSION |
370 				  ICE_FLOW_SEG_HDR_IPV4 |
371 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
372 		break;
373 	case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
374 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4 |
375 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
376 		break;
377 	case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
378 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_TCP |
379 				  ICE_FLOW_SEG_HDR_IPV4 |
380 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
381 		break;
382 	case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
383 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_UDP |
384 				  ICE_FLOW_SEG_HDR_IPV4 |
385 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
386 		break;
387 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
388 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
389 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
390 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
391 		if (ttype == ICE_FDIR_TUNNEL_TYPE_GTPU) {
392 			ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_IP |
393 					  ICE_FLOW_SEG_HDR_IPV4 |
394 					  ICE_FLOW_SEG_HDR_IPV_OTHER);
395 		} else if (ttype == ICE_FDIR_TUNNEL_TYPE_GTPU_EH) {
396 			ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_EH |
397 					  ICE_FLOW_SEG_HDR_GTPU_IP |
398 					  ICE_FLOW_SEG_HDR_IPV4 |
399 					  ICE_FLOW_SEG_HDR_IPV_OTHER);
400 		} else {
401 			dev_dbg(dev, "Invalid tunnel type 0x%x for VF %d\n",
402 				flow, vf->vf_id);
403 			return -EINVAL;
404 		}
405 		break;
406 	case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
407 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_SCTP |
408 				  ICE_FLOW_SEG_HDR_IPV4 |
409 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
410 		break;
411 	case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3:
412 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_L2TPV3 |
413 				  ICE_FLOW_SEG_HDR_IPV6 |
414 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
415 		break;
416 	case ICE_FLTR_PTYPE_NONF_IPV6_ESP:
417 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ESP |
418 				  ICE_FLOW_SEG_HDR_IPV6 |
419 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
420 		break;
421 	case ICE_FLTR_PTYPE_NONF_IPV6_AH:
422 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_AH |
423 				  ICE_FLOW_SEG_HDR_IPV6 |
424 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
425 		break;
426 	case ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP:
427 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_NAT_T_ESP |
428 				  ICE_FLOW_SEG_HDR_IPV6 |
429 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
430 		break;
431 	case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE:
432 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_PFCP_NODE |
433 				  ICE_FLOW_SEG_HDR_IPV6 |
434 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
435 		break;
436 	case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION:
437 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_PFCP_SESSION |
438 				  ICE_FLOW_SEG_HDR_IPV6 |
439 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
440 		break;
441 	case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
442 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV6 |
443 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
444 		break;
445 	case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
446 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_TCP |
447 				  ICE_FLOW_SEG_HDR_IPV6 |
448 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
449 		break;
450 	case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
451 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_UDP |
452 				  ICE_FLOW_SEG_HDR_IPV6 |
453 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
454 		break;
455 	case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
456 		ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_SCTP |
457 				  ICE_FLOW_SEG_HDR_IPV6 |
458 				  ICE_FLOW_SEG_HDR_IPV_OTHER);
459 		break;
460 	default:
461 		dev_dbg(dev, "Invalid flow type 0x%x for VF %d failed\n",
462 			flow, vf->vf_id);
463 		return -EINVAL;
464 	}
465 
466 	return 0;
467 }
468 
469 /**
470  * ice_vc_fdir_rem_prof - remove profile for this filter flow type
471  * @vf: pointer to the VF structure
472  * @flow: filter flow type
473  * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter
474  */
475 static void
ice_vc_fdir_rem_prof(struct ice_vf * vf,enum ice_fltr_ptype flow,int tun)476 ice_vc_fdir_rem_prof(struct ice_vf *vf, enum ice_fltr_ptype flow, int tun)
477 {
478 	struct ice_vf_fdir *fdir = &vf->fdir;
479 	struct ice_fd_hw_prof *vf_prof;
480 	struct ice_pf *pf = vf->pf;
481 	struct ice_vsi *vf_vsi;
482 	struct device *dev;
483 	struct ice_hw *hw;
484 	u64 prof_id;
485 	int i;
486 
487 	dev = ice_pf_to_dev(pf);
488 	hw = &pf->hw;
489 	if (!fdir->fdir_prof || !fdir->fdir_prof[flow])
490 		return;
491 
492 	vf_prof = fdir->fdir_prof[flow];
493 
494 	vf_vsi = ice_get_vf_vsi(vf);
495 	if (!vf_vsi) {
496 		dev_dbg(dev, "NULL vf %d vsi pointer\n", vf->vf_id);
497 		return;
498 	}
499 
500 	if (!fdir->prof_entry_cnt[flow][tun])
501 		return;
502 
503 	prof_id = ICE_FLOW_PROF_FD(vf_vsi->vsi_num,
504 				   flow, tun ? ICE_FLTR_PTYPE_MAX : 0);
505 
506 	for (i = 0; i < fdir->prof_entry_cnt[flow][tun]; i++)
507 		if (vf_prof->entry_h[i][tun]) {
508 			u16 vsi_num = ice_get_hw_vsi_num(hw, vf_prof->vsi_h[i]);
509 
510 			ice_rem_prof_id_flow(hw, ICE_BLK_FD, vsi_num, prof_id);
511 			ice_flow_rem_entry(hw, ICE_BLK_FD,
512 					   vf_prof->entry_h[i][tun]);
513 			vf_prof->entry_h[i][tun] = 0;
514 		}
515 
516 	ice_flow_rem_prof(hw, ICE_BLK_FD, prof_id);
517 	devm_kfree(dev, vf_prof->fdir_seg[tun]);
518 	vf_prof->fdir_seg[tun] = NULL;
519 
520 	for (i = 0; i < vf_prof->cnt; i++)
521 		vf_prof->vsi_h[i] = 0;
522 
523 	fdir->prof_entry_cnt[flow][tun] = 0;
524 }
525 
526 /**
527  * ice_vc_fdir_rem_prof_all - remove profile for this VF
528  * @vf: pointer to the VF structure
529  */
ice_vc_fdir_rem_prof_all(struct ice_vf * vf)530 static void ice_vc_fdir_rem_prof_all(struct ice_vf *vf)
531 {
532 	enum ice_fltr_ptype flow;
533 
534 	for (flow = ICE_FLTR_PTYPE_NONF_NONE;
535 	     flow < ICE_FLTR_PTYPE_MAX; flow++) {
536 		ice_vc_fdir_rem_prof(vf, flow, 0);
537 		ice_vc_fdir_rem_prof(vf, flow, 1);
538 	}
539 }
540 
541 /**
542  * ice_vc_fdir_reset_cnt_all - reset all FDIR counters for this VF FDIR
543  * @fdir: pointer to the VF FDIR structure
544  */
ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir * fdir)545 static void ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir *fdir)
546 {
547 	enum ice_fltr_ptype flow;
548 
549 	for (flow = ICE_FLTR_PTYPE_NONF_NONE;
550 	     flow < ICE_FLTR_PTYPE_MAX; flow++) {
551 		fdir->fdir_fltr_cnt[flow][0] = 0;
552 		fdir->fdir_fltr_cnt[flow][1] = 0;
553 	}
554 
555 	fdir->fdir_fltr_cnt_total = 0;
556 }
557 
558 /**
559  * ice_vc_fdir_has_prof_conflict
560  * @vf: pointer to the VF structure
561  * @conf: FDIR configuration for each filter
562  *
563  * Check if @conf has conflicting profile with existing profiles
564  *
565  * Return: true on success, and false on error.
566  */
567 static bool
ice_vc_fdir_has_prof_conflict(struct ice_vf * vf,struct virtchnl_fdir_fltr_conf * conf)568 ice_vc_fdir_has_prof_conflict(struct ice_vf *vf,
569 			      struct virtchnl_fdir_fltr_conf *conf)
570 {
571 	struct ice_fdir_fltr *desc;
572 
573 	list_for_each_entry(desc, &vf->fdir.fdir_rule_list, fltr_node) {
574 		struct virtchnl_fdir_fltr_conf *existing_conf;
575 		enum ice_fltr_ptype flow_type_a, flow_type_b;
576 		struct ice_fdir_fltr *a, *b;
577 
578 		existing_conf = to_fltr_conf_from_desc(desc);
579 		a = &existing_conf->input;
580 		b = &conf->input;
581 		flow_type_a = a->flow_type;
582 		flow_type_b = b->flow_type;
583 
584 		/* No need to compare two rules with different tunnel types or
585 		 * with the same protocol type.
586 		 */
587 		if (existing_conf->ttype != conf->ttype ||
588 		    flow_type_a == flow_type_b)
589 			continue;
590 
591 		switch (flow_type_a) {
592 		case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
593 		case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
594 		case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
595 			if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
596 				return true;
597 			break;
598 		case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
599 			if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
600 			    flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
601 			    flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_SCTP)
602 				return true;
603 			break;
604 		case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
605 		case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
606 		case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
607 			if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_OTHER)
608 				return true;
609 			break;
610 		case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
611 			if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
612 			    flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
613 			    flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_SCTP)
614 				return true;
615 			break;
616 		default:
617 			break;
618 		}
619 	}
620 
621 	return false;
622 }
623 
624 /**
625  * ice_vc_fdir_write_flow_prof
626  * @vf: pointer to the VF structure
627  * @flow: filter flow type
628  * @seg: array of one or more packet segments that describe the flow
629  * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter
630  *
631  * Write the flow's profile config and packet segment into the hardware
632  *
633  * Return: 0 on success, and other on error.
634  */
635 static int
ice_vc_fdir_write_flow_prof(struct ice_vf * vf,enum ice_fltr_ptype flow,struct ice_flow_seg_info * seg,int tun)636 ice_vc_fdir_write_flow_prof(struct ice_vf *vf, enum ice_fltr_ptype flow,
637 			    struct ice_flow_seg_info *seg, int tun)
638 {
639 	struct ice_vf_fdir *fdir = &vf->fdir;
640 	struct ice_vsi *vf_vsi, *ctrl_vsi;
641 	struct ice_flow_seg_info *old_seg;
642 	struct ice_flow_prof *prof = NULL;
643 	struct ice_fd_hw_prof *vf_prof;
644 	struct device *dev;
645 	struct ice_pf *pf;
646 	struct ice_hw *hw;
647 	u64 entry1_h = 0;
648 	u64 entry2_h = 0;
649 	u64 prof_id;
650 	int ret;
651 
652 	pf = vf->pf;
653 	dev = ice_pf_to_dev(pf);
654 	hw = &pf->hw;
655 	vf_vsi = ice_get_vf_vsi(vf);
656 	if (!vf_vsi)
657 		return -EINVAL;
658 
659 	ctrl_vsi = pf->vsi[vf->ctrl_vsi_idx];
660 	if (!ctrl_vsi)
661 		return -EINVAL;
662 
663 	vf_prof = fdir->fdir_prof[flow];
664 	old_seg = vf_prof->fdir_seg[tun];
665 	if (old_seg) {
666 		if (!memcmp(old_seg, seg, sizeof(*seg))) {
667 			dev_dbg(dev, "Duplicated profile for VF %d!\n",
668 				vf->vf_id);
669 			return -EEXIST;
670 		}
671 
672 		if (fdir->fdir_fltr_cnt[flow][tun]) {
673 			ret = -EINVAL;
674 			dev_dbg(dev, "Input set conflicts for VF %d\n",
675 				vf->vf_id);
676 			goto err_exit;
677 		}
678 
679 		/* remove previously allocated profile */
680 		ice_vc_fdir_rem_prof(vf, flow, tun);
681 	}
682 
683 	prof_id = ICE_FLOW_PROF_FD(vf_vsi->vsi_num, flow,
684 				   tun ? ICE_FLTR_PTYPE_MAX : 0);
685 
686 	ret = ice_flow_add_prof(hw, ICE_BLK_FD, ICE_FLOW_RX, prof_id, seg,
687 				tun + 1, &prof);
688 	if (ret) {
689 		dev_dbg(dev, "Could not add VSI flow 0x%x for VF %d\n",
690 			flow, vf->vf_id);
691 		goto err_exit;
692 	}
693 
694 	ret = ice_flow_add_entry(hw, ICE_BLK_FD, prof_id, vf_vsi->idx,
695 				 vf_vsi->idx, ICE_FLOW_PRIO_NORMAL,
696 				 seg, &entry1_h);
697 	if (ret) {
698 		dev_dbg(dev, "Could not add flow 0x%x VSI entry for VF %d\n",
699 			flow, vf->vf_id);
700 		goto err_prof;
701 	}
702 
703 	ret = ice_flow_add_entry(hw, ICE_BLK_FD, prof_id, vf_vsi->idx,
704 				 ctrl_vsi->idx, ICE_FLOW_PRIO_NORMAL,
705 				 seg, &entry2_h);
706 	if (ret) {
707 		dev_dbg(dev,
708 			"Could not add flow 0x%x Ctrl VSI entry for VF %d\n",
709 			flow, vf->vf_id);
710 		goto err_entry_1;
711 	}
712 
713 	vf_prof->fdir_seg[tun] = seg;
714 	vf_prof->cnt = 0;
715 	fdir->prof_entry_cnt[flow][tun] = 0;
716 
717 	vf_prof->entry_h[vf_prof->cnt][tun] = entry1_h;
718 	vf_prof->vsi_h[vf_prof->cnt] = vf_vsi->idx;
719 	vf_prof->cnt++;
720 	fdir->prof_entry_cnt[flow][tun]++;
721 
722 	vf_prof->entry_h[vf_prof->cnt][tun] = entry2_h;
723 	vf_prof->vsi_h[vf_prof->cnt] = ctrl_vsi->idx;
724 	vf_prof->cnt++;
725 	fdir->prof_entry_cnt[flow][tun]++;
726 
727 	return 0;
728 
729 err_entry_1:
730 	ice_rem_prof_id_flow(hw, ICE_BLK_FD,
731 			     ice_get_hw_vsi_num(hw, vf_vsi->idx), prof_id);
732 	ice_flow_rem_entry(hw, ICE_BLK_FD, entry1_h);
733 err_prof:
734 	ice_flow_rem_prof(hw, ICE_BLK_FD, prof_id);
735 err_exit:
736 	return ret;
737 }
738 
739 /**
740  * ice_vc_fdir_config_input_set
741  * @vf: pointer to the VF structure
742  * @fltr: virtual channel add cmd buffer
743  * @conf: FDIR configuration for each filter
744  * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter
745  *
746  * Config the input set type and value for virtual channel add msg buffer
747  *
748  * Return: 0 on success, and other on error.
749  */
750 static int
ice_vc_fdir_config_input_set(struct ice_vf * vf,struct virtchnl_fdir_add * fltr,struct virtchnl_fdir_fltr_conf * conf,int tun)751 ice_vc_fdir_config_input_set(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
752 			     struct virtchnl_fdir_fltr_conf *conf, int tun)
753 {
754 	struct ice_fdir_fltr *input = &conf->input;
755 	struct device *dev = ice_pf_to_dev(vf->pf);
756 	struct ice_flow_seg_info *seg;
757 	enum ice_fltr_ptype flow;
758 	int ret;
759 
760 	ret = ice_vc_fdir_has_prof_conflict(vf, conf);
761 	if (ret) {
762 		dev_dbg(dev, "Found flow profile conflict for VF %d\n",
763 			vf->vf_id);
764 		return ret;
765 	}
766 
767 	flow = input->flow_type;
768 	ret = ice_vc_fdir_alloc_prof(vf, flow);
769 	if (ret) {
770 		dev_dbg(dev, "Alloc flow prof for VF %d failed\n", vf->vf_id);
771 		return ret;
772 	}
773 
774 	seg = devm_kzalloc(dev, sizeof(*seg), GFP_KERNEL);
775 	if (!seg)
776 		return -ENOMEM;
777 
778 	ret = ice_vc_fdir_set_flow_fld(vf, fltr, conf, seg);
779 	if (ret) {
780 		dev_dbg(dev, "Set flow field for VF %d failed\n", vf->vf_id);
781 		goto err_exit;
782 	}
783 
784 	ret = ice_vc_fdir_set_flow_hdr(vf, conf, seg);
785 	if (ret) {
786 		dev_dbg(dev, "Set flow hdr for VF %d failed\n", vf->vf_id);
787 		goto err_exit;
788 	}
789 
790 	ret = ice_vc_fdir_write_flow_prof(vf, flow, seg, tun);
791 	if (ret == -EEXIST) {
792 		devm_kfree(dev, seg);
793 	} else if (ret) {
794 		dev_dbg(dev, "Write flow profile for VF %d failed\n",
795 			vf->vf_id);
796 		goto err_exit;
797 	}
798 
799 	return 0;
800 
801 err_exit:
802 	devm_kfree(dev, seg);
803 	return ret;
804 }
805 
806 /**
807  * ice_vc_fdir_parse_pattern
808  * @vf: pointer to the VF info
809  * @fltr: virtual channel add cmd buffer
810  * @conf: FDIR configuration for each filter
811  *
812  * Parse the virtual channel filter's pattern and store them into conf
813  *
814  * Return: 0 on success, and other on error.
815  */
816 static int
ice_vc_fdir_parse_pattern(struct ice_vf * vf,struct virtchnl_fdir_add * fltr,struct virtchnl_fdir_fltr_conf * conf)817 ice_vc_fdir_parse_pattern(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
818 			  struct virtchnl_fdir_fltr_conf *conf)
819 {
820 	struct virtchnl_proto_hdrs *proto = &fltr->rule_cfg.proto_hdrs;
821 	enum virtchnl_proto_hdr_type l3 = VIRTCHNL_PROTO_HDR_NONE;
822 	enum virtchnl_proto_hdr_type l4 = VIRTCHNL_PROTO_HDR_NONE;
823 	struct device *dev = ice_pf_to_dev(vf->pf);
824 	struct ice_fdir_fltr *input = &conf->input;
825 	int i;
826 
827 	if (proto->count > VIRTCHNL_MAX_NUM_PROTO_HDRS) {
828 		dev_dbg(dev, "Invalid protocol count:0x%x for VF %d\n",
829 			proto->count, vf->vf_id);
830 		return -EINVAL;
831 	}
832 
833 	for (i = 0; i < proto->count; i++) {
834 		struct virtchnl_proto_hdr *hdr = &proto->proto_hdr[i];
835 		struct ip_esp_hdr *esph;
836 		struct ip_auth_hdr *ah;
837 		struct sctphdr *sctph;
838 		struct ipv6hdr *ip6h;
839 		struct udphdr *udph;
840 		struct tcphdr *tcph;
841 		struct ethhdr *eth;
842 		struct iphdr *iph;
843 		u8 s_field;
844 		u8 *rawh;
845 
846 		switch (hdr->type) {
847 		case VIRTCHNL_PROTO_HDR_ETH:
848 			eth = (struct ethhdr *)hdr->buffer;
849 			input->flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
850 
851 			if (hdr->field_selector)
852 				input->ext_data.ether_type = eth->h_proto;
853 			break;
854 		case VIRTCHNL_PROTO_HDR_IPV4:
855 			iph = (struct iphdr *)hdr->buffer;
856 			l3 = VIRTCHNL_PROTO_HDR_IPV4;
857 			input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
858 
859 			if (hdr->field_selector) {
860 				input->ip.v4.src_ip = iph->saddr;
861 				input->ip.v4.dst_ip = iph->daddr;
862 				input->ip.v4.tos = iph->tos;
863 				input->ip.v4.proto = iph->protocol;
864 			}
865 			break;
866 		case VIRTCHNL_PROTO_HDR_IPV6:
867 			ip6h = (struct ipv6hdr *)hdr->buffer;
868 			l3 = VIRTCHNL_PROTO_HDR_IPV6;
869 			input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
870 
871 			if (hdr->field_selector) {
872 				memcpy(input->ip.v6.src_ip,
873 				       ip6h->saddr.in6_u.u6_addr8,
874 				       sizeof(ip6h->saddr));
875 				memcpy(input->ip.v6.dst_ip,
876 				       ip6h->daddr.in6_u.u6_addr8,
877 				       sizeof(ip6h->daddr));
878 				input->ip.v6.tc = ((u8)(ip6h->priority) << 4) |
879 						  (ip6h->flow_lbl[0] >> 4);
880 				input->ip.v6.proto = ip6h->nexthdr;
881 			}
882 			break;
883 		case VIRTCHNL_PROTO_HDR_TCP:
884 			tcph = (struct tcphdr *)hdr->buffer;
885 			if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
886 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
887 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
888 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
889 
890 			if (hdr->field_selector) {
891 				if (l3 == VIRTCHNL_PROTO_HDR_IPV4) {
892 					input->ip.v4.src_port = tcph->source;
893 					input->ip.v4.dst_port = tcph->dest;
894 				} else if (l3 == VIRTCHNL_PROTO_HDR_IPV6) {
895 					input->ip.v6.src_port = tcph->source;
896 					input->ip.v6.dst_port = tcph->dest;
897 				}
898 			}
899 			break;
900 		case VIRTCHNL_PROTO_HDR_UDP:
901 			udph = (struct udphdr *)hdr->buffer;
902 			if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
903 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
904 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
905 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
906 
907 			if (hdr->field_selector) {
908 				if (l3 == VIRTCHNL_PROTO_HDR_IPV4) {
909 					input->ip.v4.src_port = udph->source;
910 					input->ip.v4.dst_port = udph->dest;
911 				} else if (l3 == VIRTCHNL_PROTO_HDR_IPV6) {
912 					input->ip.v6.src_port = udph->source;
913 					input->ip.v6.dst_port = udph->dest;
914 				}
915 			}
916 			break;
917 		case VIRTCHNL_PROTO_HDR_SCTP:
918 			sctph = (struct sctphdr *)hdr->buffer;
919 			if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
920 				input->flow_type =
921 					ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
922 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
923 				input->flow_type =
924 					ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
925 
926 			if (hdr->field_selector) {
927 				if (l3 == VIRTCHNL_PROTO_HDR_IPV4) {
928 					input->ip.v4.src_port = sctph->source;
929 					input->ip.v4.dst_port = sctph->dest;
930 				} else if (l3 == VIRTCHNL_PROTO_HDR_IPV6) {
931 					input->ip.v6.src_port = sctph->source;
932 					input->ip.v6.dst_port = sctph->dest;
933 				}
934 			}
935 			break;
936 		case VIRTCHNL_PROTO_HDR_L2TPV3:
937 			if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
938 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3;
939 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
940 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3;
941 
942 			if (hdr->field_selector)
943 				input->l2tpv3_data.session_id = *((__be32 *)hdr->buffer);
944 			break;
945 		case VIRTCHNL_PROTO_HDR_ESP:
946 			esph = (struct ip_esp_hdr *)hdr->buffer;
947 			if (l3 == VIRTCHNL_PROTO_HDR_IPV4 &&
948 			    l4 == VIRTCHNL_PROTO_HDR_UDP)
949 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP;
950 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6 &&
951 				 l4 == VIRTCHNL_PROTO_HDR_UDP)
952 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP;
953 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV4 &&
954 				 l4 == VIRTCHNL_PROTO_HDR_NONE)
955 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_ESP;
956 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6 &&
957 				 l4 == VIRTCHNL_PROTO_HDR_NONE)
958 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_ESP;
959 
960 			if (l4 == VIRTCHNL_PROTO_HDR_UDP)
961 				conf->inset_flag |= FDIR_INSET_FLAG_ESP_UDP;
962 			else
963 				conf->inset_flag |= FDIR_INSET_FLAG_ESP_IPSEC;
964 
965 			if (hdr->field_selector) {
966 				if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
967 					input->ip.v4.sec_parm_idx = esph->spi;
968 				else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
969 					input->ip.v6.sec_parm_idx = esph->spi;
970 			}
971 			break;
972 		case VIRTCHNL_PROTO_HDR_AH:
973 			ah = (struct ip_auth_hdr *)hdr->buffer;
974 			if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
975 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_AH;
976 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
977 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_AH;
978 
979 			if (hdr->field_selector) {
980 				if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
981 					input->ip.v4.sec_parm_idx = ah->spi;
982 				else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
983 					input->ip.v6.sec_parm_idx = ah->spi;
984 			}
985 			break;
986 		case VIRTCHNL_PROTO_HDR_PFCP:
987 			rawh = (u8 *)hdr->buffer;
988 			s_field = (rawh[0] >> PFCP_S_OFFSET) & PFCP_S_MASK;
989 			if (l3 == VIRTCHNL_PROTO_HDR_IPV4 && s_field == 0)
990 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE;
991 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV4 && s_field == 1)
992 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION;
993 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6 && s_field == 0)
994 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE;
995 			else if (l3 == VIRTCHNL_PROTO_HDR_IPV6 && s_field == 1)
996 				input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION;
997 
998 			if (hdr->field_selector) {
999 				if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
1000 					input->ip.v4.dst_port = cpu_to_be16(PFCP_PORT_NR);
1001 				else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
1002 					input->ip.v6.dst_port = cpu_to_be16(PFCP_PORT_NR);
1003 			}
1004 			break;
1005 		case VIRTCHNL_PROTO_HDR_GTPU_IP:
1006 			rawh = (u8 *)hdr->buffer;
1007 			input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER;
1008 
1009 			if (hdr->field_selector)
1010 				input->gtpu_data.teid = *(__be32 *)(&rawh[GTPU_TEID_OFFSET]);
1011 			conf->ttype = ICE_FDIR_TUNNEL_TYPE_GTPU;
1012 			break;
1013 		case VIRTCHNL_PROTO_HDR_GTPU_EH:
1014 			rawh = (u8 *)hdr->buffer;
1015 
1016 			if (hdr->field_selector)
1017 				input->gtpu_data.qfi = rawh[GTPU_EH_QFI_OFFSET] & GTPU_EH_QFI_MASK;
1018 			conf->ttype = ICE_FDIR_TUNNEL_TYPE_GTPU_EH;
1019 			break;
1020 		default:
1021 			dev_dbg(dev, "Invalid header type 0x:%x for VF %d\n",
1022 				hdr->type, vf->vf_id);
1023 			return -EINVAL;
1024 		}
1025 	}
1026 
1027 	return 0;
1028 }
1029 
1030 /**
1031  * ice_vc_fdir_parse_action
1032  * @vf: pointer to the VF info
1033  * @fltr: virtual channel add cmd buffer
1034  * @conf: FDIR configuration for each filter
1035  *
1036  * Parse the virtual channel filter's action and store them into conf
1037  *
1038  * Return: 0 on success, and other on error.
1039  */
1040 static int
ice_vc_fdir_parse_action(struct ice_vf * vf,struct virtchnl_fdir_add * fltr,struct virtchnl_fdir_fltr_conf * conf)1041 ice_vc_fdir_parse_action(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
1042 			 struct virtchnl_fdir_fltr_conf *conf)
1043 {
1044 	struct virtchnl_filter_action_set *as = &fltr->rule_cfg.action_set;
1045 	struct device *dev = ice_pf_to_dev(vf->pf);
1046 	struct ice_fdir_fltr *input = &conf->input;
1047 	u32 dest_num = 0;
1048 	u32 mark_num = 0;
1049 	int i;
1050 
1051 	if (as->count > VIRTCHNL_MAX_NUM_ACTIONS) {
1052 		dev_dbg(dev, "Invalid action numbers:0x%x for VF %d\n",
1053 			as->count, vf->vf_id);
1054 		return -EINVAL;
1055 	}
1056 
1057 	for (i = 0; i < as->count; i++) {
1058 		struct virtchnl_filter_action *action = &as->actions[i];
1059 
1060 		switch (action->type) {
1061 		case VIRTCHNL_ACTION_PASSTHRU:
1062 			dest_num++;
1063 			input->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER;
1064 			break;
1065 		case VIRTCHNL_ACTION_DROP:
1066 			dest_num++;
1067 			input->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DROP_PKT;
1068 			break;
1069 		case VIRTCHNL_ACTION_QUEUE:
1070 			dest_num++;
1071 			input->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX;
1072 			input->q_index = action->act_conf.queue.index;
1073 			break;
1074 		case VIRTCHNL_ACTION_Q_REGION:
1075 			dest_num++;
1076 			input->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP;
1077 			input->q_index = action->act_conf.queue.index;
1078 			input->q_region = action->act_conf.queue.region;
1079 			break;
1080 		case VIRTCHNL_ACTION_MARK:
1081 			mark_num++;
1082 			input->fltr_id = action->act_conf.mark_id;
1083 			input->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_THREE;
1084 			break;
1085 		default:
1086 			dev_dbg(dev, "Invalid action type:0x%x for VF %d\n",
1087 				action->type, vf->vf_id);
1088 			return -EINVAL;
1089 		}
1090 	}
1091 
1092 	if (dest_num == 0 || dest_num >= 2) {
1093 		dev_dbg(dev, "Invalid destination action for VF %d\n",
1094 			vf->vf_id);
1095 		return -EINVAL;
1096 	}
1097 
1098 	if (mark_num >= 2) {
1099 		dev_dbg(dev, "Too many mark actions for VF %d\n", vf->vf_id);
1100 		return -EINVAL;
1101 	}
1102 
1103 	return 0;
1104 }
1105 
1106 /**
1107  * ice_vc_validate_fdir_fltr - validate the virtual channel filter
1108  * @vf: pointer to the VF info
1109  * @fltr: virtual channel add cmd buffer
1110  * @conf: FDIR configuration for each filter
1111  *
1112  * Return: 0 on success, and other on error.
1113  */
1114 static int
ice_vc_validate_fdir_fltr(struct ice_vf * vf,struct virtchnl_fdir_add * fltr,struct virtchnl_fdir_fltr_conf * conf)1115 ice_vc_validate_fdir_fltr(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
1116 			  struct virtchnl_fdir_fltr_conf *conf)
1117 {
1118 	struct virtchnl_proto_hdrs *proto = &fltr->rule_cfg.proto_hdrs;
1119 	int ret;
1120 
1121 	if (!ice_vc_validate_pattern(vf, proto))
1122 		return -EINVAL;
1123 
1124 	ret = ice_vc_fdir_parse_pattern(vf, fltr, conf);
1125 	if (ret)
1126 		return ret;
1127 
1128 	return ice_vc_fdir_parse_action(vf, fltr, conf);
1129 }
1130 
1131 /**
1132  * ice_vc_fdir_comp_rules - compare if two filter rules have the same value
1133  * @conf_a: FDIR configuration for filter a
1134  * @conf_b: FDIR configuration for filter b
1135  *
1136  * Return: 0 on success, and other on error.
1137  */
1138 static bool
ice_vc_fdir_comp_rules(struct virtchnl_fdir_fltr_conf * conf_a,struct virtchnl_fdir_fltr_conf * conf_b)1139 ice_vc_fdir_comp_rules(struct virtchnl_fdir_fltr_conf *conf_a,
1140 		       struct virtchnl_fdir_fltr_conf *conf_b)
1141 {
1142 	struct ice_fdir_fltr *a = &conf_a->input;
1143 	struct ice_fdir_fltr *b = &conf_b->input;
1144 
1145 	if (conf_a->ttype != conf_b->ttype)
1146 		return false;
1147 	if (a->flow_type != b->flow_type)
1148 		return false;
1149 	if (memcmp(&a->ip, &b->ip, sizeof(a->ip)))
1150 		return false;
1151 	if (memcmp(&a->mask, &b->mask, sizeof(a->mask)))
1152 		return false;
1153 	if (memcmp(&a->gtpu_data, &b->gtpu_data, sizeof(a->gtpu_data)))
1154 		return false;
1155 	if (memcmp(&a->gtpu_mask, &b->gtpu_mask, sizeof(a->gtpu_mask)))
1156 		return false;
1157 	if (memcmp(&a->l2tpv3_data, &b->l2tpv3_data, sizeof(a->l2tpv3_data)))
1158 		return false;
1159 	if (memcmp(&a->l2tpv3_mask, &b->l2tpv3_mask, sizeof(a->l2tpv3_mask)))
1160 		return false;
1161 	if (memcmp(&a->ext_data, &b->ext_data, sizeof(a->ext_data)))
1162 		return false;
1163 	if (memcmp(&a->ext_mask, &b->ext_mask, sizeof(a->ext_mask)))
1164 		return false;
1165 
1166 	return true;
1167 }
1168 
1169 /**
1170  * ice_vc_fdir_is_dup_fltr
1171  * @vf: pointer to the VF info
1172  * @conf: FDIR configuration for each filter
1173  *
1174  * Check if there is duplicated rule with same conf value
1175  *
1176  * Return: 0 true success, and false on error.
1177  */
1178 static bool
ice_vc_fdir_is_dup_fltr(struct ice_vf * vf,struct virtchnl_fdir_fltr_conf * conf)1179 ice_vc_fdir_is_dup_fltr(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf)
1180 {
1181 	struct ice_fdir_fltr *desc;
1182 	bool ret;
1183 
1184 	list_for_each_entry(desc, &vf->fdir.fdir_rule_list, fltr_node) {
1185 		struct virtchnl_fdir_fltr_conf *node =
1186 				to_fltr_conf_from_desc(desc);
1187 
1188 		ret = ice_vc_fdir_comp_rules(node, conf);
1189 		if (ret)
1190 			return true;
1191 	}
1192 
1193 	return false;
1194 }
1195 
1196 /**
1197  * ice_vc_fdir_insert_entry
1198  * @vf: pointer to the VF info
1199  * @conf: FDIR configuration for each filter
1200  * @id: pointer to ID value allocated by driver
1201  *
1202  * Insert FDIR conf entry into list and allocate ID for this filter
1203  *
1204  * Return: 0 true success, and other on error.
1205  */
1206 static int
ice_vc_fdir_insert_entry(struct ice_vf * vf,struct virtchnl_fdir_fltr_conf * conf,u32 * id)1207 ice_vc_fdir_insert_entry(struct ice_vf *vf,
1208 			 struct virtchnl_fdir_fltr_conf *conf, u32 *id)
1209 {
1210 	struct ice_fdir_fltr *input = &conf->input;
1211 	int i;
1212 
1213 	/* alloc ID corresponding with conf */
1214 	i = idr_alloc(&vf->fdir.fdir_rule_idr, conf, 0,
1215 		      ICE_FDIR_MAX_FLTRS, GFP_KERNEL);
1216 	if (i < 0)
1217 		return -EINVAL;
1218 	*id = i;
1219 
1220 	list_add(&input->fltr_node, &vf->fdir.fdir_rule_list);
1221 	return 0;
1222 }
1223 
1224 /**
1225  * ice_vc_fdir_remove_entry - remove FDIR conf entry by ID value
1226  * @vf: pointer to the VF info
1227  * @conf: FDIR configuration for each filter
1228  * @id: filter rule's ID
1229  */
1230 static void
ice_vc_fdir_remove_entry(struct ice_vf * vf,struct virtchnl_fdir_fltr_conf * conf,u32 id)1231 ice_vc_fdir_remove_entry(struct ice_vf *vf,
1232 			 struct virtchnl_fdir_fltr_conf *conf, u32 id)
1233 {
1234 	struct ice_fdir_fltr *input = &conf->input;
1235 
1236 	idr_remove(&vf->fdir.fdir_rule_idr, id);
1237 	list_del(&input->fltr_node);
1238 }
1239 
1240 /**
1241  * ice_vc_fdir_lookup_entry - lookup FDIR conf entry by ID value
1242  * @vf: pointer to the VF info
1243  * @id: filter rule's ID
1244  *
1245  * Return: NULL on error, and other on success.
1246  */
1247 static struct virtchnl_fdir_fltr_conf *
ice_vc_fdir_lookup_entry(struct ice_vf * vf,u32 id)1248 ice_vc_fdir_lookup_entry(struct ice_vf *vf, u32 id)
1249 {
1250 	return idr_find(&vf->fdir.fdir_rule_idr, id);
1251 }
1252 
1253 /**
1254  * ice_vc_fdir_flush_entry - remove all FDIR conf entry
1255  * @vf: pointer to the VF info
1256  */
ice_vc_fdir_flush_entry(struct ice_vf * vf)1257 static void ice_vc_fdir_flush_entry(struct ice_vf *vf)
1258 {
1259 	struct virtchnl_fdir_fltr_conf *conf;
1260 	struct ice_fdir_fltr *desc, *temp;
1261 
1262 	list_for_each_entry_safe(desc, temp,
1263 				 &vf->fdir.fdir_rule_list, fltr_node) {
1264 		conf = to_fltr_conf_from_desc(desc);
1265 		list_del(&desc->fltr_node);
1266 		devm_kfree(ice_pf_to_dev(vf->pf), conf);
1267 	}
1268 }
1269 
1270 /**
1271  * ice_vc_fdir_write_fltr - write filter rule into hardware
1272  * @vf: pointer to the VF info
1273  * @conf: FDIR configuration for each filter
1274  * @add: true implies add rule, false implies del rules
1275  * @is_tun: false implies non-tunnel type filter, true implies tunnel filter
1276  *
1277  * Return: 0 on success, and other on error.
1278  */
ice_vc_fdir_write_fltr(struct ice_vf * vf,struct virtchnl_fdir_fltr_conf * conf,bool add,bool is_tun)1279 static int ice_vc_fdir_write_fltr(struct ice_vf *vf,
1280 				  struct virtchnl_fdir_fltr_conf *conf,
1281 				  bool add, bool is_tun)
1282 {
1283 	struct ice_fdir_fltr *input = &conf->input;
1284 	struct ice_vsi *vsi, *ctrl_vsi;
1285 	struct ice_fltr_desc desc;
1286 	struct device *dev;
1287 	struct ice_pf *pf;
1288 	struct ice_hw *hw;
1289 	int ret;
1290 	u8 *pkt;
1291 
1292 	pf = vf->pf;
1293 	dev = ice_pf_to_dev(pf);
1294 	hw = &pf->hw;
1295 	vsi = ice_get_vf_vsi(vf);
1296 	if (!vsi) {
1297 		dev_dbg(dev, "Invalid vsi for VF %d\n", vf->vf_id);
1298 		return -EINVAL;
1299 	}
1300 
1301 	input->dest_vsi = vsi->idx;
1302 	input->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
1303 
1304 	ctrl_vsi = pf->vsi[vf->ctrl_vsi_idx];
1305 	if (!ctrl_vsi) {
1306 		dev_dbg(dev, "Invalid ctrl_vsi for VF %d\n", vf->vf_id);
1307 		return -EINVAL;
1308 	}
1309 
1310 	pkt = devm_kzalloc(dev, ICE_FDIR_MAX_RAW_PKT_SIZE, GFP_KERNEL);
1311 	if (!pkt)
1312 		return -ENOMEM;
1313 
1314 	ice_fdir_get_prgm_desc(hw, input, &desc, add);
1315 	ret = ice_fdir_get_gen_prgm_pkt(hw, input, pkt, false, is_tun);
1316 	if (ret) {
1317 		dev_dbg(dev, "Gen training pkt for VF %d ptype %d failed\n",
1318 			vf->vf_id, input->flow_type);
1319 		goto err_free_pkt;
1320 	}
1321 
1322 	ret = ice_prgm_fdir_fltr(ctrl_vsi, &desc, pkt);
1323 	if (ret)
1324 		goto err_free_pkt;
1325 
1326 	return 0;
1327 
1328 err_free_pkt:
1329 	devm_kfree(dev, pkt);
1330 	return ret;
1331 }
1332 
1333 /**
1334  * ice_vf_fdir_timer - FDIR program waiting timer interrupt handler
1335  * @t: pointer to timer_list
1336  */
ice_vf_fdir_timer(struct timer_list * t)1337 static void ice_vf_fdir_timer(struct timer_list *t)
1338 {
1339 	struct ice_vf_fdir_ctx *ctx_irq = from_timer(ctx_irq, t, rx_tmr);
1340 	struct ice_vf_fdir_ctx *ctx_done;
1341 	struct ice_vf_fdir *fdir;
1342 	unsigned long flags;
1343 	struct ice_vf *vf;
1344 	struct ice_pf *pf;
1345 
1346 	fdir = container_of(ctx_irq, struct ice_vf_fdir, ctx_irq);
1347 	vf = container_of(fdir, struct ice_vf, fdir);
1348 	ctx_done = &fdir->ctx_done;
1349 	pf = vf->pf;
1350 	spin_lock_irqsave(&fdir->ctx_lock, flags);
1351 	if (!(ctx_irq->flags & ICE_VF_FDIR_CTX_VALID)) {
1352 		spin_unlock_irqrestore(&fdir->ctx_lock, flags);
1353 		WARN_ON_ONCE(1);
1354 		return;
1355 	}
1356 
1357 	ctx_irq->flags &= ~ICE_VF_FDIR_CTX_VALID;
1358 
1359 	ctx_done->flags |= ICE_VF_FDIR_CTX_VALID;
1360 	ctx_done->conf = ctx_irq->conf;
1361 	ctx_done->stat = ICE_FDIR_CTX_TIMEOUT;
1362 	ctx_done->v_opcode = ctx_irq->v_opcode;
1363 	spin_unlock_irqrestore(&fdir->ctx_lock, flags);
1364 
1365 	set_bit(ICE_FD_VF_FLUSH_CTX, pf->state);
1366 	ice_service_task_schedule(pf);
1367 }
1368 
1369 /**
1370  * ice_vc_fdir_irq_handler - ctrl_vsi Rx queue interrupt handler
1371  * @ctrl_vsi: pointer to a VF's CTRL VSI
1372  * @rx_desc: pointer to FDIR Rx queue descriptor
1373  */
1374 void
ice_vc_fdir_irq_handler(struct ice_vsi * ctrl_vsi,union ice_32b_rx_flex_desc * rx_desc)1375 ice_vc_fdir_irq_handler(struct ice_vsi *ctrl_vsi,
1376 			union ice_32b_rx_flex_desc *rx_desc)
1377 {
1378 	struct ice_pf *pf = ctrl_vsi->back;
1379 	struct ice_vf *vf = ctrl_vsi->vf;
1380 	struct ice_vf_fdir_ctx *ctx_done;
1381 	struct ice_vf_fdir_ctx *ctx_irq;
1382 	struct ice_vf_fdir *fdir;
1383 	unsigned long flags;
1384 	struct device *dev;
1385 	int ret;
1386 
1387 	if (WARN_ON(!vf))
1388 		return;
1389 
1390 	fdir = &vf->fdir;
1391 	ctx_done = &fdir->ctx_done;
1392 	ctx_irq = &fdir->ctx_irq;
1393 	dev = ice_pf_to_dev(pf);
1394 	spin_lock_irqsave(&fdir->ctx_lock, flags);
1395 	if (!(ctx_irq->flags & ICE_VF_FDIR_CTX_VALID)) {
1396 		spin_unlock_irqrestore(&fdir->ctx_lock, flags);
1397 		WARN_ON_ONCE(1);
1398 		return;
1399 	}
1400 
1401 	ctx_irq->flags &= ~ICE_VF_FDIR_CTX_VALID;
1402 
1403 	ctx_done->flags |= ICE_VF_FDIR_CTX_VALID;
1404 	ctx_done->conf = ctx_irq->conf;
1405 	ctx_done->stat = ICE_FDIR_CTX_IRQ;
1406 	ctx_done->v_opcode = ctx_irq->v_opcode;
1407 	memcpy(&ctx_done->rx_desc, rx_desc, sizeof(*rx_desc));
1408 	spin_unlock_irqrestore(&fdir->ctx_lock, flags);
1409 
1410 	ret = del_timer(&ctx_irq->rx_tmr);
1411 	if (!ret)
1412 		dev_err(dev, "VF %d: Unexpected inactive timer!\n", vf->vf_id);
1413 
1414 	set_bit(ICE_FD_VF_FLUSH_CTX, pf->state);
1415 	ice_service_task_schedule(pf);
1416 }
1417 
1418 /**
1419  * ice_vf_fdir_dump_info - dump FDIR information for diagnosis
1420  * @vf: pointer to the VF info
1421  */
ice_vf_fdir_dump_info(struct ice_vf * vf)1422 static void ice_vf_fdir_dump_info(struct ice_vf *vf)
1423 {
1424 	struct ice_vsi *vf_vsi;
1425 	u32 fd_size, fd_cnt;
1426 	struct device *dev;
1427 	struct ice_pf *pf;
1428 	struct ice_hw *hw;
1429 	u16 vsi_num;
1430 
1431 	pf = vf->pf;
1432 	hw = &pf->hw;
1433 	dev = ice_pf_to_dev(pf);
1434 	vf_vsi = ice_get_vf_vsi(vf);
1435 	if (!vf_vsi) {
1436 		dev_dbg(dev, "VF %d: invalid VSI pointer\n", vf->vf_id);
1437 		return;
1438 	}
1439 
1440 	vsi_num = ice_get_hw_vsi_num(hw, vf_vsi->idx);
1441 
1442 	fd_size = rd32(hw, VSIQF_FD_SIZE(vsi_num));
1443 	fd_cnt = rd32(hw, VSIQF_FD_CNT(vsi_num));
1444 	dev_dbg(dev, "VF %d: space allocated: guar:0x%x, be:0x%x, space consumed: guar:0x%x, be:0x%x\n",
1445 		vf->vf_id,
1446 		(fd_size & VSIQF_FD_CNT_FD_GCNT_M) >> VSIQF_FD_CNT_FD_GCNT_S,
1447 		(fd_size & VSIQF_FD_CNT_FD_BCNT_M) >> VSIQF_FD_CNT_FD_BCNT_S,
1448 		(fd_cnt & VSIQF_FD_CNT_FD_GCNT_M) >> VSIQF_FD_CNT_FD_GCNT_S,
1449 		(fd_cnt & VSIQF_FD_CNT_FD_BCNT_M) >> VSIQF_FD_CNT_FD_BCNT_S);
1450 }
1451 
1452 /**
1453  * ice_vf_verify_rx_desc - verify received FDIR programming status descriptor
1454  * @vf: pointer to the VF info
1455  * @ctx: FDIR context info for post processing
1456  * @status: virtchnl FDIR program status
1457  *
1458  * Return: 0 on success, and other on error.
1459  */
1460 static int
ice_vf_verify_rx_desc(struct ice_vf * vf,struct ice_vf_fdir_ctx * ctx,enum virtchnl_fdir_prgm_status * status)1461 ice_vf_verify_rx_desc(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx,
1462 		      enum virtchnl_fdir_prgm_status *status)
1463 {
1464 	struct device *dev = ice_pf_to_dev(vf->pf);
1465 	u32 stat_err, error, prog_id;
1466 	int ret;
1467 
1468 	stat_err = le16_to_cpu(ctx->rx_desc.wb.status_error0);
1469 	if (((stat_err & ICE_FXD_FLTR_WB_QW1_DD_M) >>
1470 	    ICE_FXD_FLTR_WB_QW1_DD_S) != ICE_FXD_FLTR_WB_QW1_DD_YES) {
1471 		*status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1472 		dev_err(dev, "VF %d: Desc Done not set\n", vf->vf_id);
1473 		ret = -EINVAL;
1474 		goto err_exit;
1475 	}
1476 
1477 	prog_id = (stat_err & ICE_FXD_FLTR_WB_QW1_PROG_ID_M) >>
1478 		ICE_FXD_FLTR_WB_QW1_PROG_ID_S;
1479 	if (prog_id == ICE_FXD_FLTR_WB_QW1_PROG_ADD &&
1480 	    ctx->v_opcode != VIRTCHNL_OP_ADD_FDIR_FILTER) {
1481 		dev_err(dev, "VF %d: Desc show add, but ctx not",
1482 			vf->vf_id);
1483 		*status = VIRTCHNL_FDIR_FAILURE_RULE_INVALID;
1484 		ret = -EINVAL;
1485 		goto err_exit;
1486 	}
1487 
1488 	if (prog_id == ICE_FXD_FLTR_WB_QW1_PROG_DEL &&
1489 	    ctx->v_opcode != VIRTCHNL_OP_DEL_FDIR_FILTER) {
1490 		dev_err(dev, "VF %d: Desc show del, but ctx not",
1491 			vf->vf_id);
1492 		*status = VIRTCHNL_FDIR_FAILURE_RULE_INVALID;
1493 		ret = -EINVAL;
1494 		goto err_exit;
1495 	}
1496 
1497 	error = (stat_err & ICE_FXD_FLTR_WB_QW1_FAIL_M) >>
1498 		ICE_FXD_FLTR_WB_QW1_FAIL_S;
1499 	if (error == ICE_FXD_FLTR_WB_QW1_FAIL_YES) {
1500 		if (prog_id == ICE_FXD_FLTR_WB_QW1_PROG_ADD) {
1501 			dev_err(dev, "VF %d, Failed to add FDIR rule due to no space in the table",
1502 				vf->vf_id);
1503 			*status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1504 		} else {
1505 			dev_err(dev, "VF %d, Failed to remove FDIR rule, attempt to remove non-existent entry",
1506 				vf->vf_id);
1507 			*status = VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST;
1508 		}
1509 		ret = -EINVAL;
1510 		goto err_exit;
1511 	}
1512 
1513 	error = (stat_err & ICE_FXD_FLTR_WB_QW1_FAIL_PROF_M) >>
1514 		ICE_FXD_FLTR_WB_QW1_FAIL_PROF_S;
1515 	if (error == ICE_FXD_FLTR_WB_QW1_FAIL_PROF_YES) {
1516 		dev_err(dev, "VF %d: Profile matching error", vf->vf_id);
1517 		*status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1518 		ret = -EINVAL;
1519 		goto err_exit;
1520 	}
1521 
1522 	*status = VIRTCHNL_FDIR_SUCCESS;
1523 
1524 	return 0;
1525 
1526 err_exit:
1527 	ice_vf_fdir_dump_info(vf);
1528 	return ret;
1529 }
1530 
1531 /**
1532  * ice_vc_add_fdir_fltr_post
1533  * @vf: pointer to the VF structure
1534  * @ctx: FDIR context info for post processing
1535  * @status: virtchnl FDIR program status
1536  * @success: true implies success, false implies failure
1537  *
1538  * Post process for flow director add command. If success, then do post process
1539  * and send back success msg by virtchnl. Otherwise, do context reversion and
1540  * send back failure msg by virtchnl.
1541  *
1542  * Return: 0 on success, and other on error.
1543  */
1544 static int
ice_vc_add_fdir_fltr_post(struct ice_vf * vf,struct ice_vf_fdir_ctx * ctx,enum virtchnl_fdir_prgm_status status,bool success)1545 ice_vc_add_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx,
1546 			  enum virtchnl_fdir_prgm_status status,
1547 			  bool success)
1548 {
1549 	struct virtchnl_fdir_fltr_conf *conf = ctx->conf;
1550 	struct device *dev = ice_pf_to_dev(vf->pf);
1551 	enum virtchnl_status_code v_ret;
1552 	struct virtchnl_fdir_add *resp;
1553 	int ret, len, is_tun;
1554 
1555 	v_ret = VIRTCHNL_STATUS_SUCCESS;
1556 	len = sizeof(*resp);
1557 	resp = kzalloc(len, GFP_KERNEL);
1558 	if (!resp) {
1559 		len = 0;
1560 		v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
1561 		dev_dbg(dev, "VF %d: Alloc resp buf fail", vf->vf_id);
1562 		goto err_exit;
1563 	}
1564 
1565 	if (!success)
1566 		goto err_exit;
1567 
1568 	is_tun = 0;
1569 	resp->status = status;
1570 	resp->flow_id = conf->flow_id;
1571 	vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]++;
1572 	vf->fdir.fdir_fltr_cnt_total++;
1573 
1574 	ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
1575 				    (u8 *)resp, len);
1576 	kfree(resp);
1577 
1578 	dev_dbg(dev, "VF %d: flow_id:0x%X, FDIR %s success!\n",
1579 		vf->vf_id, conf->flow_id,
1580 		(ctx->v_opcode == VIRTCHNL_OP_ADD_FDIR_FILTER) ?
1581 		"add" : "del");
1582 	return ret;
1583 
1584 err_exit:
1585 	if (resp)
1586 		resp->status = status;
1587 	ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
1588 	devm_kfree(dev, conf);
1589 
1590 	ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
1591 				    (u8 *)resp, len);
1592 	kfree(resp);
1593 	return ret;
1594 }
1595 
1596 /**
1597  * ice_vc_del_fdir_fltr_post
1598  * @vf: pointer to the VF structure
1599  * @ctx: FDIR context info for post processing
1600  * @status: virtchnl FDIR program status
1601  * @success: true implies success, false implies failure
1602  *
1603  * Post process for flow director del command. If success, then do post process
1604  * and send back success msg by virtchnl. Otherwise, do context reversion and
1605  * send back failure msg by virtchnl.
1606  *
1607  * Return: 0 on success, and other on error.
1608  */
1609 static int
ice_vc_del_fdir_fltr_post(struct ice_vf * vf,struct ice_vf_fdir_ctx * ctx,enum virtchnl_fdir_prgm_status status,bool success)1610 ice_vc_del_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx,
1611 			  enum virtchnl_fdir_prgm_status status,
1612 			  bool success)
1613 {
1614 	struct virtchnl_fdir_fltr_conf *conf = ctx->conf;
1615 	struct device *dev = ice_pf_to_dev(vf->pf);
1616 	enum virtchnl_status_code v_ret;
1617 	struct virtchnl_fdir_del *resp;
1618 	int ret, len, is_tun;
1619 
1620 	v_ret = VIRTCHNL_STATUS_SUCCESS;
1621 	len = sizeof(*resp);
1622 	resp = kzalloc(len, GFP_KERNEL);
1623 	if (!resp) {
1624 		len = 0;
1625 		v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
1626 		dev_dbg(dev, "VF %d: Alloc resp buf fail", vf->vf_id);
1627 		goto err_exit;
1628 	}
1629 
1630 	if (!success)
1631 		goto err_exit;
1632 
1633 	is_tun = 0;
1634 	resp->status = status;
1635 	ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
1636 	vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]--;
1637 	vf->fdir.fdir_fltr_cnt_total--;
1638 
1639 	ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
1640 				    (u8 *)resp, len);
1641 	kfree(resp);
1642 
1643 	dev_dbg(dev, "VF %d: flow_id:0x%X, FDIR %s success!\n",
1644 		vf->vf_id, conf->flow_id,
1645 		(ctx->v_opcode == VIRTCHNL_OP_ADD_FDIR_FILTER) ?
1646 		"add" : "del");
1647 	devm_kfree(dev, conf);
1648 	return ret;
1649 
1650 err_exit:
1651 	if (resp)
1652 		resp->status = status;
1653 	if (success)
1654 		devm_kfree(dev, conf);
1655 
1656 	ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
1657 				    (u8 *)resp, len);
1658 	kfree(resp);
1659 	return ret;
1660 }
1661 
1662 /**
1663  * ice_flush_fdir_ctx
1664  * @pf: pointer to the PF structure
1665  *
1666  * Flush all the pending event on ctx_done list and process them.
1667  */
ice_flush_fdir_ctx(struct ice_pf * pf)1668 void ice_flush_fdir_ctx(struct ice_pf *pf)
1669 {
1670 	struct ice_vf *vf;
1671 	unsigned int bkt;
1672 
1673 	if (!test_and_clear_bit(ICE_FD_VF_FLUSH_CTX, pf->state))
1674 		return;
1675 
1676 	mutex_lock(&pf->vfs.table_lock);
1677 	ice_for_each_vf(pf, bkt, vf) {
1678 		struct device *dev = ice_pf_to_dev(pf);
1679 		enum virtchnl_fdir_prgm_status status;
1680 		struct ice_vf_fdir_ctx *ctx;
1681 		unsigned long flags;
1682 		int ret;
1683 
1684 		if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
1685 			continue;
1686 
1687 		if (vf->ctrl_vsi_idx == ICE_NO_VSI)
1688 			continue;
1689 
1690 		ctx = &vf->fdir.ctx_done;
1691 		spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
1692 		if (!(ctx->flags & ICE_VF_FDIR_CTX_VALID)) {
1693 			spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
1694 			continue;
1695 		}
1696 		spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
1697 
1698 		WARN_ON(ctx->stat == ICE_FDIR_CTX_READY);
1699 		if (ctx->stat == ICE_FDIR_CTX_TIMEOUT) {
1700 			status = VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT;
1701 			dev_err(dev, "VF %d: ctrl_vsi irq timeout\n",
1702 				vf->vf_id);
1703 			goto err_exit;
1704 		}
1705 
1706 		ret = ice_vf_verify_rx_desc(vf, ctx, &status);
1707 		if (ret)
1708 			goto err_exit;
1709 
1710 		if (ctx->v_opcode == VIRTCHNL_OP_ADD_FDIR_FILTER)
1711 			ice_vc_add_fdir_fltr_post(vf, ctx, status, true);
1712 		else if (ctx->v_opcode == VIRTCHNL_OP_DEL_FDIR_FILTER)
1713 			ice_vc_del_fdir_fltr_post(vf, ctx, status, true);
1714 		else
1715 			dev_err(dev, "VF %d: Unsupported opcode\n", vf->vf_id);
1716 
1717 		spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
1718 		ctx->flags &= ~ICE_VF_FDIR_CTX_VALID;
1719 		spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
1720 		continue;
1721 err_exit:
1722 		if (ctx->v_opcode == VIRTCHNL_OP_ADD_FDIR_FILTER)
1723 			ice_vc_add_fdir_fltr_post(vf, ctx, status, false);
1724 		else if (ctx->v_opcode == VIRTCHNL_OP_DEL_FDIR_FILTER)
1725 			ice_vc_del_fdir_fltr_post(vf, ctx, status, false);
1726 		else
1727 			dev_err(dev, "VF %d: Unsupported opcode\n", vf->vf_id);
1728 
1729 		spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
1730 		ctx->flags &= ~ICE_VF_FDIR_CTX_VALID;
1731 		spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
1732 	}
1733 	mutex_unlock(&pf->vfs.table_lock);
1734 }
1735 
1736 /**
1737  * ice_vc_fdir_set_irq_ctx - set FDIR context info for later IRQ handler
1738  * @vf: pointer to the VF structure
1739  * @conf: FDIR configuration for each filter
1740  * @v_opcode: virtual channel operation code
1741  *
1742  * Return: 0 on success, and other on error.
1743  */
1744 static int
ice_vc_fdir_set_irq_ctx(struct ice_vf * vf,struct virtchnl_fdir_fltr_conf * conf,enum virtchnl_ops v_opcode)1745 ice_vc_fdir_set_irq_ctx(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf,
1746 			enum virtchnl_ops v_opcode)
1747 {
1748 	struct device *dev = ice_pf_to_dev(vf->pf);
1749 	struct ice_vf_fdir_ctx *ctx;
1750 	unsigned long flags;
1751 
1752 	ctx = &vf->fdir.ctx_irq;
1753 	spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
1754 	if ((vf->fdir.ctx_irq.flags & ICE_VF_FDIR_CTX_VALID) ||
1755 	    (vf->fdir.ctx_done.flags & ICE_VF_FDIR_CTX_VALID)) {
1756 		spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
1757 		dev_dbg(dev, "VF %d: Last request is still in progress\n",
1758 			vf->vf_id);
1759 		return -EBUSY;
1760 	}
1761 	ctx->flags |= ICE_VF_FDIR_CTX_VALID;
1762 	spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
1763 
1764 	ctx->conf = conf;
1765 	ctx->v_opcode = v_opcode;
1766 	ctx->stat = ICE_FDIR_CTX_READY;
1767 	timer_setup(&ctx->rx_tmr, ice_vf_fdir_timer, 0);
1768 
1769 	mod_timer(&ctx->rx_tmr, round_jiffies(msecs_to_jiffies(10) + jiffies));
1770 
1771 	return 0;
1772 }
1773 
1774 /**
1775  * ice_vc_fdir_clear_irq_ctx - clear FDIR context info for IRQ handler
1776  * @vf: pointer to the VF structure
1777  *
1778  * Return: 0 on success, and other on error.
1779  */
ice_vc_fdir_clear_irq_ctx(struct ice_vf * vf)1780 static void ice_vc_fdir_clear_irq_ctx(struct ice_vf *vf)
1781 {
1782 	struct ice_vf_fdir_ctx *ctx = &vf->fdir.ctx_irq;
1783 	unsigned long flags;
1784 
1785 	del_timer(&ctx->rx_tmr);
1786 	spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
1787 	ctx->flags &= ~ICE_VF_FDIR_CTX_VALID;
1788 	spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
1789 }
1790 
1791 /**
1792  * ice_vc_add_fdir_fltr - add a FDIR filter for VF by the msg buffer
1793  * @vf: pointer to the VF info
1794  * @msg: pointer to the msg buffer
1795  *
1796  * Return: 0 on success, and other on error.
1797  */
ice_vc_add_fdir_fltr(struct ice_vf * vf,u8 * msg)1798 int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg)
1799 {
1800 	struct virtchnl_fdir_add *fltr = (struct virtchnl_fdir_add *)msg;
1801 	struct virtchnl_fdir_add *stat = NULL;
1802 	struct virtchnl_fdir_fltr_conf *conf;
1803 	enum virtchnl_status_code v_ret;
1804 	struct ice_vsi *vf_vsi;
1805 	struct device *dev;
1806 	struct ice_pf *pf;
1807 	int is_tun = 0;
1808 	int len = 0;
1809 	int ret;
1810 
1811 	pf = vf->pf;
1812 	dev = ice_pf_to_dev(pf);
1813 	vf_vsi = ice_get_vf_vsi(vf);
1814 
1815 #define ICE_VF_MAX_FDIR_FILTERS	128
1816 	if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) ||
1817 	    vf->fdir.fdir_fltr_cnt_total >= ICE_VF_MAX_FDIR_FILTERS) {
1818 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
1819 		dev_err(dev, "Max number of FDIR filters for VF %d is reached\n",
1820 			vf->vf_id);
1821 		goto err_exit;
1822 	}
1823 
1824 	ret = ice_vc_fdir_param_check(vf, fltr->vsi_id);
1825 	if (ret) {
1826 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
1827 		dev_dbg(dev, "Parameter check for VF %d failed\n", vf->vf_id);
1828 		goto err_exit;
1829 	}
1830 
1831 	ret = ice_vf_start_ctrl_vsi(vf);
1832 	if (ret && (ret != -EEXIST)) {
1833 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
1834 		dev_err(dev, "Init FDIR for VF %d failed, ret:%d\n",
1835 			vf->vf_id, ret);
1836 		goto err_exit;
1837 	}
1838 
1839 	stat = kzalloc(sizeof(*stat), GFP_KERNEL);
1840 	if (!stat) {
1841 		v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
1842 		dev_dbg(dev, "Alloc stat for VF %d failed\n", vf->vf_id);
1843 		goto err_exit;
1844 	}
1845 
1846 	conf = devm_kzalloc(dev, sizeof(*conf), GFP_KERNEL);
1847 	if (!conf) {
1848 		v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
1849 		dev_dbg(dev, "Alloc conf for VF %d failed\n", vf->vf_id);
1850 		goto err_exit;
1851 	}
1852 
1853 	len = sizeof(*stat);
1854 	ret = ice_vc_validate_fdir_fltr(vf, fltr, conf);
1855 	if (ret) {
1856 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1857 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_INVALID;
1858 		dev_dbg(dev, "Invalid FDIR filter from VF %d\n", vf->vf_id);
1859 		goto err_free_conf;
1860 	}
1861 
1862 	if (fltr->validate_only) {
1863 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1864 		stat->status = VIRTCHNL_FDIR_SUCCESS;
1865 		devm_kfree(dev, conf);
1866 		ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_FDIR_FILTER,
1867 					    v_ret, (u8 *)stat, len);
1868 		goto exit;
1869 	}
1870 
1871 	ret = ice_vc_fdir_config_input_set(vf, fltr, conf, is_tun);
1872 	if (ret) {
1873 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1874 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT;
1875 		dev_err(dev, "VF %d: FDIR input set configure failed, ret:%d\n",
1876 			vf->vf_id, ret);
1877 		goto err_free_conf;
1878 	}
1879 
1880 	ret = ice_vc_fdir_is_dup_fltr(vf, conf);
1881 	if (ret) {
1882 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1883 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_EXIST;
1884 		dev_dbg(dev, "VF %d: duplicated FDIR rule detected\n",
1885 			vf->vf_id);
1886 		goto err_free_conf;
1887 	}
1888 
1889 	ret = ice_vc_fdir_insert_entry(vf, conf, &conf->flow_id);
1890 	if (ret) {
1891 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1892 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1893 		dev_dbg(dev, "VF %d: insert FDIR list failed\n", vf->vf_id);
1894 		goto err_free_conf;
1895 	}
1896 
1897 	ret = ice_vc_fdir_set_irq_ctx(vf, conf, VIRTCHNL_OP_ADD_FDIR_FILTER);
1898 	if (ret) {
1899 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1900 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1901 		dev_dbg(dev, "VF %d: set FDIR context failed\n", vf->vf_id);
1902 		goto err_rem_entry;
1903 	}
1904 
1905 	ret = ice_vc_fdir_write_fltr(vf, conf, true, is_tun);
1906 	if (ret) {
1907 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1908 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1909 		dev_err(dev, "VF %d: writing FDIR rule failed, ret:%d\n",
1910 			vf->vf_id, ret);
1911 		goto err_clr_irq;
1912 	}
1913 
1914 exit:
1915 	kfree(stat);
1916 	return ret;
1917 
1918 err_clr_irq:
1919 	ice_vc_fdir_clear_irq_ctx(vf);
1920 err_rem_entry:
1921 	ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
1922 err_free_conf:
1923 	devm_kfree(dev, conf);
1924 err_exit:
1925 	ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_FDIR_FILTER, v_ret,
1926 				    (u8 *)stat, len);
1927 	kfree(stat);
1928 	return ret;
1929 }
1930 
1931 /**
1932  * ice_vc_del_fdir_fltr - delete a FDIR filter for VF by the msg buffer
1933  * @vf: pointer to the VF info
1934  * @msg: pointer to the msg buffer
1935  *
1936  * Return: 0 on success, and other on error.
1937  */
ice_vc_del_fdir_fltr(struct ice_vf * vf,u8 * msg)1938 int ice_vc_del_fdir_fltr(struct ice_vf *vf, u8 *msg)
1939 {
1940 	struct virtchnl_fdir_del *fltr = (struct virtchnl_fdir_del *)msg;
1941 	struct virtchnl_fdir_del *stat = NULL;
1942 	struct virtchnl_fdir_fltr_conf *conf;
1943 	enum virtchnl_status_code v_ret;
1944 	struct device *dev;
1945 	struct ice_pf *pf;
1946 	int is_tun = 0;
1947 	int len = 0;
1948 	int ret;
1949 
1950 	pf = vf->pf;
1951 	dev = ice_pf_to_dev(pf);
1952 	ret = ice_vc_fdir_param_check(vf, fltr->vsi_id);
1953 	if (ret) {
1954 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
1955 		dev_dbg(dev, "Parameter check for VF %d failed\n", vf->vf_id);
1956 		goto err_exit;
1957 	}
1958 
1959 	stat = kzalloc(sizeof(*stat), GFP_KERNEL);
1960 	if (!stat) {
1961 		v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
1962 		dev_dbg(dev, "Alloc stat for VF %d failed\n", vf->vf_id);
1963 		goto err_exit;
1964 	}
1965 
1966 	len = sizeof(*stat);
1967 
1968 	conf = ice_vc_fdir_lookup_entry(vf, fltr->flow_id);
1969 	if (!conf) {
1970 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1971 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST;
1972 		dev_dbg(dev, "VF %d: FDIR invalid flow_id:0x%X\n",
1973 			vf->vf_id, fltr->flow_id);
1974 		goto err_exit;
1975 	}
1976 
1977 	/* Just return failure when ctrl_vsi idx is invalid */
1978 	if (vf->ctrl_vsi_idx == ICE_NO_VSI) {
1979 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1980 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1981 		dev_err(dev, "Invalid FDIR ctrl_vsi for VF %d\n", vf->vf_id);
1982 		goto err_exit;
1983 	}
1984 
1985 	ret = ice_vc_fdir_set_irq_ctx(vf, conf, VIRTCHNL_OP_DEL_FDIR_FILTER);
1986 	if (ret) {
1987 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1988 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1989 		dev_dbg(dev, "VF %d: set FDIR context failed\n", vf->vf_id);
1990 		goto err_exit;
1991 	}
1992 
1993 	ret = ice_vc_fdir_write_fltr(vf, conf, false, is_tun);
1994 	if (ret) {
1995 		v_ret = VIRTCHNL_STATUS_SUCCESS;
1996 		stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
1997 		dev_err(dev, "VF %d: writing FDIR rule failed, ret:%d\n",
1998 			vf->vf_id, ret);
1999 		goto err_del_tmr;
2000 	}
2001 
2002 	kfree(stat);
2003 
2004 	return ret;
2005 
2006 err_del_tmr:
2007 	ice_vc_fdir_clear_irq_ctx(vf);
2008 err_exit:
2009 	ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DEL_FDIR_FILTER, v_ret,
2010 				    (u8 *)stat, len);
2011 	kfree(stat);
2012 	return ret;
2013 }
2014 
2015 /**
2016  * ice_vf_fdir_init - init FDIR resource for VF
2017  * @vf: pointer to the VF info
2018  */
ice_vf_fdir_init(struct ice_vf * vf)2019 void ice_vf_fdir_init(struct ice_vf *vf)
2020 {
2021 	struct ice_vf_fdir *fdir = &vf->fdir;
2022 
2023 	idr_init(&fdir->fdir_rule_idr);
2024 	INIT_LIST_HEAD(&fdir->fdir_rule_list);
2025 
2026 	spin_lock_init(&fdir->ctx_lock);
2027 	fdir->ctx_irq.flags = 0;
2028 	fdir->ctx_done.flags = 0;
2029 	ice_vc_fdir_reset_cnt_all(fdir);
2030 }
2031 
2032 /**
2033  * ice_vf_fdir_exit - destroy FDIR resource for VF
2034  * @vf: pointer to the VF info
2035  */
ice_vf_fdir_exit(struct ice_vf * vf)2036 void ice_vf_fdir_exit(struct ice_vf *vf)
2037 {
2038 	ice_vc_fdir_flush_entry(vf);
2039 	idr_destroy(&vf->fdir.fdir_rule_idr);
2040 	ice_vc_fdir_rem_prof_all(vf);
2041 	ice_vc_fdir_free_prof_all(vf);
2042 }
2043