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