Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (C) 2021, Intel Corporation. */
0003 
0004 #include "ice_virtchnl_allowlist.h"
0005 
0006 /* Purpose of this file is to share functionality to allowlist or denylist
0007  * opcodes used in PF <-> VF communication. Group of opcodes:
0008  * - default -> should be always allowed after creating VF,
0009  *   default_allowlist_opcodes
0010  * - opcodes needed by VF to work correctly, but not associated with caps ->
0011  *   should be allowed after successful VF resources allocation,
0012  *   working_allowlist_opcodes
0013  * - opcodes needed by VF when caps are activated
0014  *
0015  * Caps that don't use new opcodes (no opcodes should be allowed):
0016  * - VIRTCHNL_VF_OFFLOAD_RSS_AQ
0017  * - VIRTCHNL_VF_OFFLOAD_RSS_REG
0018  * - VIRTCHNL_VF_OFFLOAD_WB_ON_ITR
0019  * - VIRTCHNL_VF_OFFLOAD_CRC
0020  * - VIRTCHNL_VF_OFFLOAD_RX_POLLING
0021  * - VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2
0022  * - VIRTCHNL_VF_OFFLOAD_ENCAP
0023  * - VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM
0024  * - VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM
0025  * - VIRTCHNL_VF_OFFLOAD_USO
0026  */
0027 
0028 /* default opcodes to communicate with VF */
0029 static const u32 default_allowlist_opcodes[] = {
0030     VIRTCHNL_OP_GET_VF_RESOURCES, VIRTCHNL_OP_VERSION, VIRTCHNL_OP_RESET_VF,
0031 };
0032 
0033 /* opcodes supported after successful VIRTCHNL_OP_GET_VF_RESOURCES */
0034 static const u32 working_allowlist_opcodes[] = {
0035     VIRTCHNL_OP_CONFIG_TX_QUEUE, VIRTCHNL_OP_CONFIG_RX_QUEUE,
0036     VIRTCHNL_OP_CONFIG_VSI_QUEUES, VIRTCHNL_OP_CONFIG_IRQ_MAP,
0037     VIRTCHNL_OP_ENABLE_QUEUES, VIRTCHNL_OP_DISABLE_QUEUES,
0038     VIRTCHNL_OP_GET_STATS, VIRTCHNL_OP_EVENT,
0039 };
0040 
0041 /* VIRTCHNL_VF_OFFLOAD_L2 */
0042 static const u32 l2_allowlist_opcodes[] = {
0043     VIRTCHNL_OP_ADD_ETH_ADDR, VIRTCHNL_OP_DEL_ETH_ADDR,
0044     VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
0045 };
0046 
0047 /* VIRTCHNL_VF_OFFLOAD_REQ_QUEUES */
0048 static const u32 req_queues_allowlist_opcodes[] = {
0049     VIRTCHNL_OP_REQUEST_QUEUES,
0050 };
0051 
0052 /* VIRTCHNL_VF_OFFLOAD_VLAN */
0053 static const u32 vlan_allowlist_opcodes[] = {
0054     VIRTCHNL_OP_ADD_VLAN, VIRTCHNL_OP_DEL_VLAN,
0055     VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING,
0056 };
0057 
0058 /* VIRTCHNL_VF_OFFLOAD_VLAN_V2 */
0059 static const u32 vlan_v2_allowlist_opcodes[] = {
0060     VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS, VIRTCHNL_OP_ADD_VLAN_V2,
0061     VIRTCHNL_OP_DEL_VLAN_V2, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2,
0062     VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2,
0063     VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2,
0064     VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2,
0065 };
0066 
0067 /* VIRTCHNL_VF_OFFLOAD_RSS_PF */
0068 static const u32 rss_pf_allowlist_opcodes[] = {
0069     VIRTCHNL_OP_CONFIG_RSS_KEY, VIRTCHNL_OP_CONFIG_RSS_LUT,
0070     VIRTCHNL_OP_GET_RSS_HENA_CAPS, VIRTCHNL_OP_SET_RSS_HENA,
0071 };
0072 
0073 /* VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF */
0074 static const u32 adv_rss_pf_allowlist_opcodes[] = {
0075     VIRTCHNL_OP_ADD_RSS_CFG, VIRTCHNL_OP_DEL_RSS_CFG,
0076 };
0077 
0078 /* VIRTCHNL_VF_OFFLOAD_FDIR_PF */
0079 static const u32 fdir_pf_allowlist_opcodes[] = {
0080     VIRTCHNL_OP_ADD_FDIR_FILTER, VIRTCHNL_OP_DEL_FDIR_FILTER,
0081 };
0082 
0083 struct allowlist_opcode_info {
0084     const u32 *opcodes;
0085     size_t size;
0086 };
0087 
0088 #define BIT_INDEX(caps) (HWEIGHT((caps) - 1))
0089 #define ALLOW_ITEM(caps, list) \
0090     [BIT_INDEX(caps)] = { \
0091         .opcodes = list, \
0092         .size = ARRAY_SIZE(list) \
0093     }
0094 static const struct allowlist_opcode_info allowlist_opcodes[] = {
0095     ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_L2, l2_allowlist_opcodes),
0096     ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_REQ_QUEUES, req_queues_allowlist_opcodes),
0097     ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_VLAN, vlan_allowlist_opcodes),
0098     ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_RSS_PF, rss_pf_allowlist_opcodes),
0099     ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF, adv_rss_pf_allowlist_opcodes),
0100     ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_FDIR_PF, fdir_pf_allowlist_opcodes),
0101     ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_VLAN_V2, vlan_v2_allowlist_opcodes),
0102 };
0103 
0104 /**
0105  * ice_vc_is_opcode_allowed - check if this opcode is allowed on this VF
0106  * @vf: pointer to VF structure
0107  * @opcode: virtchnl opcode
0108  *
0109  * Return true if message is allowed on this VF
0110  */
0111 bool ice_vc_is_opcode_allowed(struct ice_vf *vf, u32 opcode)
0112 {
0113     if (opcode >= VIRTCHNL_OP_MAX)
0114         return false;
0115 
0116     return test_bit(opcode, vf->opcodes_allowlist);
0117 }
0118 
0119 /**
0120  * ice_vc_allowlist_opcodes - allowlist selected opcodes
0121  * @vf: pointer to VF structure
0122  * @opcodes: array of opocodes to allowlist
0123  * @size: size of opcodes array
0124  *
0125  * Function should be called to allowlist opcodes on VF.
0126  */
0127 static void
0128 ice_vc_allowlist_opcodes(struct ice_vf *vf, const u32 *opcodes, size_t size)
0129 {
0130     unsigned int i;
0131 
0132     for (i = 0; i < size; i++)
0133         set_bit(opcodes[i], vf->opcodes_allowlist);
0134 }
0135 
0136 /**
0137  * ice_vc_clear_allowlist - clear all allowlist opcodes
0138  * @vf: pointer to VF structure
0139  */
0140 static void ice_vc_clear_allowlist(struct ice_vf *vf)
0141 {
0142     bitmap_zero(vf->opcodes_allowlist, VIRTCHNL_OP_MAX);
0143 }
0144 
0145 /**
0146  * ice_vc_set_default_allowlist - allowlist default opcodes for VF
0147  * @vf: pointer to VF structure
0148  */
0149 void ice_vc_set_default_allowlist(struct ice_vf *vf)
0150 {
0151     ice_vc_clear_allowlist(vf);
0152     ice_vc_allowlist_opcodes(vf, default_allowlist_opcodes,
0153                  ARRAY_SIZE(default_allowlist_opcodes));
0154 }
0155 
0156 /**
0157  * ice_vc_set_working_allowlist - allowlist opcodes needed to by VF to work
0158  * @vf: pointer to VF structure
0159  *
0160  * allowlist opcodes that aren't associated with specific caps, but
0161  * are needed by VF to work.
0162  */
0163 void ice_vc_set_working_allowlist(struct ice_vf *vf)
0164 {
0165     ice_vc_allowlist_opcodes(vf, working_allowlist_opcodes,
0166                  ARRAY_SIZE(working_allowlist_opcodes));
0167 }
0168 
0169 /**
0170  * ice_vc_set_caps_allowlist - allowlist VF opcodes according caps
0171  * @vf: pointer to VF structure
0172  */
0173 void ice_vc_set_caps_allowlist(struct ice_vf *vf)
0174 {
0175     unsigned long caps = vf->driver_caps;
0176     unsigned int i;
0177 
0178     for_each_set_bit(i, &caps, ARRAY_SIZE(allowlist_opcodes))
0179         ice_vc_allowlist_opcodes(vf, allowlist_opcodes[i].opcodes,
0180                      allowlist_opcodes[i].size);
0181 }