linux/drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.c
<<
>>
Prefs
   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_RSS_PF */
  59static 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 */
  65static 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 */
  70static const u32 fdir_pf_allowlist_opcodes[] = {
  71        VIRTCHNL_OP_ADD_FDIR_FILTER, VIRTCHNL_OP_DEL_FDIR_FILTER,
  72};
  73
  74struct 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        }
  85static 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 */
 101bool 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 */
 117static void
 118ice_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 */
 130static 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 */
 139void 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 */
 153void 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 */
 163void 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