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 */
29static 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 */
34static 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 */
42static 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 */
48static const u32 req_queues_allowlist_opcodes[] = {
49 VIRTCHNL_OP_REQUEST_QUEUES,
50};
51
52/* VIRTCHNL_VF_OFFLOAD_VLAN */
53static 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_VLAN_V2 */
59static const u32 vlan_v2_allowlist_opcodes[] = {
60 VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS, VIRTCHNL_OP_ADD_VLAN_V2,
61 VIRTCHNL_OP_DEL_VLAN_V2, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2,
62 VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2,
63 VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2,
64 VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2,
65};
66
67/* VIRTCHNL_VF_OFFLOAD_RSS_PF */
68static const u32 rss_pf_allowlist_opcodes[] = {
69 VIRTCHNL_OP_CONFIG_RSS_KEY, VIRTCHNL_OP_CONFIG_RSS_LUT,
70 VIRTCHNL_OP_GET_RSS_HENA_CAPS, VIRTCHNL_OP_SET_RSS_HENA,
71};
72
73/* VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC */
74static const u32 rx_flex_desc_allowlist_opcodes[] = {
75 VIRTCHNL_OP_GET_SUPPORTED_RXDIDS,
76};
77
78/* VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF */
79static const u32 adv_rss_pf_allowlist_opcodes[] = {
80 VIRTCHNL_OP_ADD_RSS_CFG, VIRTCHNL_OP_DEL_RSS_CFG,
81};
82
83/* VIRTCHNL_VF_OFFLOAD_FDIR_PF */
84static const u32 fdir_pf_allowlist_opcodes[] = {
85 VIRTCHNL_OP_ADD_FDIR_FILTER, VIRTCHNL_OP_DEL_FDIR_FILTER,
86};
87
88struct allowlist_opcode_info {
89 const u32 *opcodes;
90 size_t size;
91};
92
93#define BIT_INDEX(caps) (HWEIGHT((caps) - 1))
94#define ALLOW_ITEM(caps, list) \
95 [BIT_INDEX(caps)] = { \
96 .opcodes = list, \
97 .size = ARRAY_SIZE(list) \
98 }
99static const struct allowlist_opcode_info allowlist_opcodes[] = {
100 ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_L2, l2_allowlist_opcodes),
101 ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_REQ_QUEUES, req_queues_allowlist_opcodes),
102 ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_VLAN, vlan_allowlist_opcodes),
103 ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_RSS_PF, rss_pf_allowlist_opcodes),
104 ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC, rx_flex_desc_allowlist_opcodes),
105 ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF, adv_rss_pf_allowlist_opcodes),
106 ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_FDIR_PF, fdir_pf_allowlist_opcodes),
107 ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_VLAN_V2, vlan_v2_allowlist_opcodes),
108};
109
110/**
111 * ice_vc_is_opcode_allowed - check if this opcode is allowed on this VF
112 * @vf: pointer to VF structure
113 * @opcode: virtchnl opcode
114 *
115 * Return true if message is allowed on this VF
116 */
117bool ice_vc_is_opcode_allowed(struct ice_vf *vf, u32 opcode)
118{
119 if (opcode >= VIRTCHNL_OP_MAX)
120 return false;
121
122 return test_bit(opcode, vf->opcodes_allowlist);
123}
124
125/**
126 * ice_vc_allowlist_opcodes - allowlist selected opcodes
127 * @vf: pointer to VF structure
128 * @opcodes: array of opocodes to allowlist
129 * @size: size of opcodes array
130 *
131 * Function should be called to allowlist opcodes on VF.
132 */
133static void
134ice_vc_allowlist_opcodes(struct ice_vf *vf, const u32 *opcodes, size_t size)
135{
136 unsigned int i;
137
138 for (i = 0; i < size; i++)
139 set_bit(nr: opcodes[i], addr: vf->opcodes_allowlist);
140}
141
142/**
143 * ice_vc_clear_allowlist - clear all allowlist opcodes
144 * @vf: pointer to VF structure
145 */
146static void ice_vc_clear_allowlist(struct ice_vf *vf)
147{
148 bitmap_zero(dst: vf->opcodes_allowlist, nbits: VIRTCHNL_OP_MAX);
149}
150
151/**
152 * ice_vc_set_default_allowlist - allowlist default opcodes for VF
153 * @vf: pointer to VF structure
154 */
155void ice_vc_set_default_allowlist(struct ice_vf *vf)
156{
157 ice_vc_clear_allowlist(vf);
158 ice_vc_allowlist_opcodes(vf, opcodes: default_allowlist_opcodes,
159 ARRAY_SIZE(default_allowlist_opcodes));
160}
161
162/**
163 * ice_vc_set_working_allowlist - allowlist opcodes needed to by VF to work
164 * @vf: pointer to VF structure
165 *
166 * allowlist opcodes that aren't associated with specific caps, but
167 * are needed by VF to work.
168 */
169void ice_vc_set_working_allowlist(struct ice_vf *vf)
170{
171 ice_vc_allowlist_opcodes(vf, opcodes: working_allowlist_opcodes,
172 ARRAY_SIZE(working_allowlist_opcodes));
173}
174
175/**
176 * ice_vc_set_caps_allowlist - allowlist VF opcodes according caps
177 * @vf: pointer to VF structure
178 */
179void ice_vc_set_caps_allowlist(struct ice_vf *vf)
180{
181 unsigned long caps = vf->driver_caps;
182 unsigned int i;
183
184 for_each_set_bit(i, &caps, ARRAY_SIZE(allowlist_opcodes))
185 ice_vc_allowlist_opcodes(vf, opcodes: allowlist_opcodes[i].opcodes,
186 size: allowlist_opcodes[i].size);
187}
188

source code of linux/drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.c