1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2021, Intel Corporation. */
3 
4 #include "ice_virtchnl_allowlist.h"
5 
6 /* Purpose of this file is to share functionality to allowlist or denylist
7  * opcodes used in PF <-> VF communication. Group of opcodes:
8  * - default -> should be always allowed after creating VF,
9  *   default_allowlist_opcodes
10  * - opcodes needed by VF to work correctly, but not associated with caps ->
11  *   should be allowed after successful VF resources allocation,
12  *   working_allowlist_opcodes
13  * - opcodes needed by VF when caps are activated
14  *
15  * Caps that don't use new opcodes (no opcodes should be allowed):
16  * - VIRTCHNL_VF_OFFLOAD_RSS_AQ
17  * - VIRTCHNL_VF_OFFLOAD_RSS_REG
18  * - VIRTCHNL_VF_OFFLOAD_WB_ON_ITR
19  * - VIRTCHNL_VF_OFFLOAD_CRC
20  * - VIRTCHNL_VF_OFFLOAD_RX_POLLING
21  * - VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2
22  * - VIRTCHNL_VF_OFFLOAD_ENCAP
23  * - VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM
24  * - VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM
25  * - VIRTCHNL_VF_OFFLOAD_USO
26  */
27 
28 /* default opcodes to communicate with VF */
29 static const u32 default_allowlist_opcodes[] = {
30 	VIRTCHNL_OP_GET_VF_RESOURCES, VIRTCHNL_OP_VERSION, VIRTCHNL_OP_RESET_VF,
31 };
32 
33 /* opcodes supported after successful VIRTCHNL_OP_GET_VF_RESOURCES */
34 static const u32 working_allowlist_opcodes[] = {
35 	VIRTCHNL_OP_CONFIG_TX_QUEUE, VIRTCHNL_OP_CONFIG_RX_QUEUE,
36 	VIRTCHNL_OP_CONFIG_VSI_QUEUES, VIRTCHNL_OP_CONFIG_IRQ_MAP,
37 	VIRTCHNL_OP_ENABLE_QUEUES, VIRTCHNL_OP_DISABLE_QUEUES,
38 	VIRTCHNL_OP_GET_STATS, VIRTCHNL_OP_EVENT,
39 };
40 
41 /* VIRTCHNL_VF_OFFLOAD_L2 */
42 static const u32 l2_allowlist_opcodes[] = {
43 	VIRTCHNL_OP_ADD_ETH_ADDR, VIRTCHNL_OP_DEL_ETH_ADDR,
44 	VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
45 };
46 
47 /* VIRTCHNL_VF_OFFLOAD_REQ_QUEUES */
48 static const u32 req_queues_allowlist_opcodes[] = {
49 	VIRTCHNL_OP_REQUEST_QUEUES,
50 };
51 
52 /* VIRTCHNL_VF_OFFLOAD_VLAN */
53 static const u32 vlan_allowlist_opcodes[] = {
54 	VIRTCHNL_OP_ADD_VLAN, VIRTCHNL_OP_DEL_VLAN,
55 	VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING,
56 };
57 
58 /* VIRTCHNL_VF_OFFLOAD_RSS_PF */
59 static const u32 rss_pf_allowlist_opcodes[] = {
60 	VIRTCHNL_OP_CONFIG_RSS_KEY, VIRTCHNL_OP_CONFIG_RSS_LUT,
61 	VIRTCHNL_OP_GET_RSS_HENA_CAPS, VIRTCHNL_OP_SET_RSS_HENA,
62 };
63 
64 /* VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF */
65 static const u32 adv_rss_pf_allowlist_opcodes[] = {
66 	VIRTCHNL_OP_ADD_RSS_CFG, VIRTCHNL_OP_DEL_RSS_CFG,
67 };
68 
69 /* VIRTCHNL_VF_OFFLOAD_FDIR_PF */
70 static const u32 fdir_pf_allowlist_opcodes[] = {
71 	VIRTCHNL_OP_ADD_FDIR_FILTER, VIRTCHNL_OP_DEL_FDIR_FILTER,
72 };
73 
74 struct allowlist_opcode_info {
75 	const u32 *opcodes;
76 	size_t size;
77 };
78 
79 #define BIT_INDEX(caps) (HWEIGHT((caps) - 1))
80 #define ALLOW_ITEM(caps, list) \
81 	[BIT_INDEX(caps)] = { \
82 		.opcodes = list, \
83 		.size = ARRAY_SIZE(list) \
84 	}
85 static const struct allowlist_opcode_info allowlist_opcodes[] = {
86 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_L2, l2_allowlist_opcodes),
87 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_REQ_QUEUES, req_queues_allowlist_opcodes),
88 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_VLAN, vlan_allowlist_opcodes),
89 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_RSS_PF, rss_pf_allowlist_opcodes),
90 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF, adv_rss_pf_allowlist_opcodes),
91 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_FDIR_PF, fdir_pf_allowlist_opcodes),
92 };
93 
94 /**
95  * ice_vc_is_opcode_allowed - check if this opcode is allowed on this VF
96  * @vf: pointer to VF structure
97  * @opcode: virtchnl opcode
98  *
99  * Return true if message is allowed on this VF
100  */
101 bool ice_vc_is_opcode_allowed(struct ice_vf *vf, u32 opcode)
102 {
103 	if (opcode >= VIRTCHNL_OP_MAX)
104 		return false;
105 
106 	return test_bit(opcode, vf->opcodes_allowlist);
107 }
108 
109 /**
110  * ice_vc_allowlist_opcodes - allowlist selected opcodes
111  * @vf: pointer to VF structure
112  * @opcodes: array of opocodes to allowlist
113  * @size: size of opcodes array
114  *
115  * Function should be called to allowlist opcodes on VF.
116  */
117 static void
118 ice_vc_allowlist_opcodes(struct ice_vf *vf, const u32 *opcodes, size_t size)
119 {
120 	unsigned int i;
121 
122 	for (i = 0; i < size; i++)
123 		set_bit(opcodes[i], vf->opcodes_allowlist);
124 }
125 
126 /**
127  * ice_vc_clear_allowlist - clear all allowlist opcodes
128  * @vf: pointer to VF structure
129  */
130 static void ice_vc_clear_allowlist(struct ice_vf *vf)
131 {
132 	bitmap_zero(vf->opcodes_allowlist, VIRTCHNL_OP_MAX);
133 }
134 
135 /**
136  * ice_vc_set_default_allowlist - allowlist default opcodes for VF
137  * @vf: pointer to VF structure
138  */
139 void ice_vc_set_default_allowlist(struct ice_vf *vf)
140 {
141 	ice_vc_clear_allowlist(vf);
142 	ice_vc_allowlist_opcodes(vf, default_allowlist_opcodes,
143 				 ARRAY_SIZE(default_allowlist_opcodes));
144 }
145 
146 /**
147  * ice_vc_set_working_allowlist - allowlist opcodes needed to by VF to work
148  * @vf: pointer to VF structure
149  *
150  * allowlist opcodes that aren't associated with specific caps, but
151  * are needed by VF to work.
152  */
153 void ice_vc_set_working_allowlist(struct ice_vf *vf)
154 {
155 	ice_vc_allowlist_opcodes(vf, working_allowlist_opcodes,
156 				 ARRAY_SIZE(working_allowlist_opcodes));
157 }
158 
159 /**
160  * ice_vc_set_caps_allowlist - allowlist VF opcodes according caps
161  * @vf: pointer to VF structure
162  */
163 void ice_vc_set_caps_allowlist(struct ice_vf *vf)
164 {
165 	unsigned long caps = vf->driver_caps;
166 	unsigned int i;
167 
168 	for_each_set_bit(i, &caps, ARRAY_SIZE(allowlist_opcodes))
169 		ice_vc_allowlist_opcodes(vf, allowlist_opcodes[i].opcodes,
170 					 allowlist_opcodes[i].size);
171 }
172