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_WB_ON_ITR
17  * - VIRTCHNL_VF_OFFLOAD_CRC
18  * - VIRTCHNL_VF_OFFLOAD_RX_POLLING
19  * - VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2
20  * - VIRTCHNL_VF_OFFLOAD_ENCAP
21  * - VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM
22  * - VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM
23  * - VIRTCHNL_VF_OFFLOAD_USO
24  */
25 
26 /* default opcodes to communicate with VF */
27 static const u32 default_allowlist_opcodes[] = {
28 	VIRTCHNL_OP_GET_VF_RESOURCES, VIRTCHNL_OP_VERSION, VIRTCHNL_OP_RESET_VF,
29 };
30 
31 /* opcodes supported after successful VIRTCHNL_OP_GET_VF_RESOURCES */
32 static const u32 working_allowlist_opcodes[] = {
33 	VIRTCHNL_OP_CONFIG_TX_QUEUE, VIRTCHNL_OP_CONFIG_RX_QUEUE,
34 	VIRTCHNL_OP_CONFIG_VSI_QUEUES, VIRTCHNL_OP_CONFIG_IRQ_MAP,
35 	VIRTCHNL_OP_ENABLE_QUEUES, VIRTCHNL_OP_DISABLE_QUEUES,
36 	VIRTCHNL_OP_GET_STATS, VIRTCHNL_OP_EVENT,
37 };
38 
39 /* VIRTCHNL_VF_OFFLOAD_L2 */
40 static const u32 l2_allowlist_opcodes[] = {
41 	VIRTCHNL_OP_ADD_ETH_ADDR, VIRTCHNL_OP_DEL_ETH_ADDR,
42 	VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
43 };
44 
45 /* VIRTCHNL_VF_OFFLOAD_REQ_QUEUES */
46 static const u32 req_queues_allowlist_opcodes[] = {
47 	VIRTCHNL_OP_REQUEST_QUEUES,
48 };
49 
50 /* VIRTCHNL_VF_OFFLOAD_VLAN */
51 static const u32 vlan_allowlist_opcodes[] = {
52 	VIRTCHNL_OP_ADD_VLAN, VIRTCHNL_OP_DEL_VLAN,
53 	VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING,
54 };
55 
56 /* VIRTCHNL_VF_OFFLOAD_VLAN_V2 */
57 static const u32 vlan_v2_allowlist_opcodes[] = {
58 	VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS, VIRTCHNL_OP_ADD_VLAN_V2,
59 	VIRTCHNL_OP_DEL_VLAN_V2, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2,
60 	VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2,
61 	VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2,
62 	VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2,
63 };
64 
65 /* VIRTCHNL_VF_OFFLOAD_RSS_PF */
66 static const u32 rss_pf_allowlist_opcodes[] = {
67 	VIRTCHNL_OP_CONFIG_RSS_KEY, VIRTCHNL_OP_CONFIG_RSS_LUT,
68 	VIRTCHNL_OP_GET_RSS_HENA_CAPS, VIRTCHNL_OP_SET_RSS_HENA,
69 	VIRTCHNL_OP_CONFIG_RSS_HFUNC,
70 };
71 
72 /* VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC */
73 static const u32 rx_flex_desc_allowlist_opcodes[] = {
74 	VIRTCHNL_OP_GET_SUPPORTED_RXDIDS,
75 };
76 
77 /* VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF */
78 static const u32 adv_rss_pf_allowlist_opcodes[] = {
79 	VIRTCHNL_OP_ADD_RSS_CFG, VIRTCHNL_OP_DEL_RSS_CFG,
80 };
81 
82 /* VIRTCHNL_VF_OFFLOAD_FDIR_PF */
83 static const u32 fdir_pf_allowlist_opcodes[] = {
84 	VIRTCHNL_OP_ADD_FDIR_FILTER, VIRTCHNL_OP_DEL_FDIR_FILTER,
85 };
86 
87 /* VIRTCHNL_VF_CAP_PTP */
88 static const u32 ptp_allowlist_opcodes[] = {
89 	VIRTCHNL_OP_1588_PTP_GET_CAPS,
90 	VIRTCHNL_OP_1588_PTP_GET_TIME,
91 };
92 
93 static const u32 tc_allowlist_opcodes[] = {
94 	VIRTCHNL_OP_GET_QOS_CAPS, VIRTCHNL_OP_CONFIG_QUEUE_BW,
95 	VIRTCHNL_OP_CONFIG_QUANTA,
96 };
97 
98 struct allowlist_opcode_info {
99 	const u32 *opcodes;
100 	size_t size;
101 };
102 
103 #define BIT_INDEX(caps) (HWEIGHT((caps) - 1))
104 #define ALLOW_ITEM(caps, list) \
105 	[BIT_INDEX(caps)] = { \
106 		.opcodes = list, \
107 		.size = ARRAY_SIZE(list) \
108 	}
109 static const struct allowlist_opcode_info allowlist_opcodes[] = {
110 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_L2, l2_allowlist_opcodes),
111 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_REQ_QUEUES, req_queues_allowlist_opcodes),
112 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_VLAN, vlan_allowlist_opcodes),
113 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_RSS_PF, rss_pf_allowlist_opcodes),
114 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC, rx_flex_desc_allowlist_opcodes),
115 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF, adv_rss_pf_allowlist_opcodes),
116 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_FDIR_PF, fdir_pf_allowlist_opcodes),
117 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_VLAN_V2, vlan_v2_allowlist_opcodes),
118 	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_QOS, tc_allowlist_opcodes),
119 	ALLOW_ITEM(VIRTCHNL_VF_CAP_PTP, ptp_allowlist_opcodes),
120 };
121 
122 /**
123  * ice_vc_is_opcode_allowed - check if this opcode is allowed on this VF
124  * @vf: pointer to VF structure
125  * @opcode: virtchnl opcode
126  *
127  * Return true if message is allowed on this VF
128  */
ice_vc_is_opcode_allowed(struct ice_vf * vf,u32 opcode)129 bool ice_vc_is_opcode_allowed(struct ice_vf *vf, u32 opcode)
130 {
131 	if (opcode >= VIRTCHNL_OP_MAX)
132 		return false;
133 
134 	return test_bit(opcode, vf->opcodes_allowlist);
135 }
136 
137 /**
138  * ice_vc_allowlist_opcodes - allowlist selected opcodes
139  * @vf: pointer to VF structure
140  * @opcodes: array of opocodes to allowlist
141  * @size: size of opcodes array
142  *
143  * Function should be called to allowlist opcodes on VF.
144  */
145 static void
ice_vc_allowlist_opcodes(struct ice_vf * vf,const u32 * opcodes,size_t size)146 ice_vc_allowlist_opcodes(struct ice_vf *vf, const u32 *opcodes, size_t size)
147 {
148 	unsigned int i;
149 
150 	for (i = 0; i < size; i++)
151 		set_bit(opcodes[i], vf->opcodes_allowlist);
152 }
153 
154 /**
155  * ice_vc_clear_allowlist - clear all allowlist opcodes
156  * @vf: pointer to VF structure
157  */
ice_vc_clear_allowlist(struct ice_vf * vf)158 static void ice_vc_clear_allowlist(struct ice_vf *vf)
159 {
160 	bitmap_zero(vf->opcodes_allowlist, VIRTCHNL_OP_MAX);
161 }
162 
163 /**
164  * ice_vc_set_default_allowlist - allowlist default opcodes for VF
165  * @vf: pointer to VF structure
166  */
ice_vc_set_default_allowlist(struct ice_vf * vf)167 void ice_vc_set_default_allowlist(struct ice_vf *vf)
168 {
169 	ice_vc_clear_allowlist(vf);
170 	ice_vc_allowlist_opcodes(vf, default_allowlist_opcodes,
171 				 ARRAY_SIZE(default_allowlist_opcodes));
172 }
173 
174 /**
175  * ice_vc_set_working_allowlist - allowlist opcodes needed to by VF to work
176  * @vf: pointer to VF structure
177  *
178  * allowlist opcodes that aren't associated with specific caps, but
179  * are needed by VF to work.
180  */
ice_vc_set_working_allowlist(struct ice_vf * vf)181 void ice_vc_set_working_allowlist(struct ice_vf *vf)
182 {
183 	ice_vc_allowlist_opcodes(vf, working_allowlist_opcodes,
184 				 ARRAY_SIZE(working_allowlist_opcodes));
185 }
186 
187 /**
188  * ice_vc_set_caps_allowlist - allowlist VF opcodes according caps
189  * @vf: pointer to VF structure
190  */
ice_vc_set_caps_allowlist(struct ice_vf * vf)191 void ice_vc_set_caps_allowlist(struct ice_vf *vf)
192 {
193 	unsigned long caps = vf->driver_caps;
194 	unsigned int i;
195 
196 	for_each_set_bit(i, &caps, ARRAY_SIZE(allowlist_opcodes))
197 		ice_vc_allowlist_opcodes(vf, allowlist_opcodes[i].opcodes,
198 					 allowlist_opcodes[i].size);
199 }
200