1*f4e667ebSPrzemek Kitszel // SPDX-License-Identifier: GPL-2.0 2*f4e667ebSPrzemek Kitszel /* Copyright (C) 2022, Intel Corporation. */ 3*f4e667ebSPrzemek Kitszel 4*f4e667ebSPrzemek Kitszel #include "virtchnl.h" 5*f4e667ebSPrzemek Kitszel #include "queues.h" 6*f4e667ebSPrzemek Kitszel #include "ice_vf_lib_private.h" 7*f4e667ebSPrzemek Kitszel #include "ice.h" 8*f4e667ebSPrzemek Kitszel #include "ice_base.h" 9*f4e667ebSPrzemek Kitszel #include "ice_lib.h" 10*f4e667ebSPrzemek Kitszel #include "ice_fltr.h" 11*f4e667ebSPrzemek Kitszel #include "allowlist.h" 12*f4e667ebSPrzemek Kitszel #include "ice_vf_vsi_vlan_ops.h" 13*f4e667ebSPrzemek Kitszel #include "ice_vlan.h" 14*f4e667ebSPrzemek Kitszel #include "ice_flex_pipe.h" 15*f4e667ebSPrzemek Kitszel #include "ice_dcb_lib.h" 16*f4e667ebSPrzemek Kitszel 17*f4e667ebSPrzemek Kitszel #define FIELD_SELECTOR(proto_hdr_field) \ 18*f4e667ebSPrzemek Kitszel BIT((proto_hdr_field) & PROTO_HDR_FIELD_MASK) 19*f4e667ebSPrzemek Kitszel 20*f4e667ebSPrzemek Kitszel struct ice_vc_hdr_match_type { 21*f4e667ebSPrzemek Kitszel u32 vc_hdr; /* virtchnl headers (VIRTCHNL_PROTO_HDR_XXX) */ 22*f4e667ebSPrzemek Kitszel u32 ice_hdr; /* ice headers (ICE_FLOW_SEG_HDR_XXX) */ 23*f4e667ebSPrzemek Kitszel }; 24*f4e667ebSPrzemek Kitszel 25*f4e667ebSPrzemek Kitszel static const struct ice_vc_hdr_match_type ice_vc_hdr_list[] = { 26*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_NONE, ICE_FLOW_SEG_HDR_NONE}, 27*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, ICE_FLOW_SEG_HDR_ETH}, 28*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_S_VLAN, ICE_FLOW_SEG_HDR_VLAN}, 29*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_C_VLAN, ICE_FLOW_SEG_HDR_VLAN}, 30*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, ICE_FLOW_SEG_HDR_IPV4 | 31*f4e667ebSPrzemek Kitszel ICE_FLOW_SEG_HDR_IPV_OTHER}, 32*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, ICE_FLOW_SEG_HDR_IPV6 | 33*f4e667ebSPrzemek Kitszel ICE_FLOW_SEG_HDR_IPV_OTHER}, 34*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_TCP, ICE_FLOW_SEG_HDR_TCP}, 35*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_UDP, ICE_FLOW_SEG_HDR_UDP}, 36*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_SCTP, ICE_FLOW_SEG_HDR_SCTP}, 37*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_PPPOE, ICE_FLOW_SEG_HDR_PPPOE}, 38*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_IP, ICE_FLOW_SEG_HDR_GTPU_IP}, 39*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_EH, ICE_FLOW_SEG_HDR_GTPU_EH}, 40*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN, 41*f4e667ebSPrzemek Kitszel ICE_FLOW_SEG_HDR_GTPU_DWN}, 42*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP, 43*f4e667ebSPrzemek Kitszel ICE_FLOW_SEG_HDR_GTPU_UP}, 44*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_L2TPV3, ICE_FLOW_SEG_HDR_L2TPV3}, 45*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ESP, ICE_FLOW_SEG_HDR_ESP}, 46*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_AH, ICE_FLOW_SEG_HDR_AH}, 47*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_PFCP, ICE_FLOW_SEG_HDR_PFCP_SESSION}, 48*f4e667ebSPrzemek Kitszel }; 49*f4e667ebSPrzemek Kitszel 50*f4e667ebSPrzemek Kitszel struct ice_vc_hash_field_match_type { 51*f4e667ebSPrzemek Kitszel u32 vc_hdr; /* virtchnl headers 52*f4e667ebSPrzemek Kitszel * (VIRTCHNL_PROTO_HDR_XXX) 53*f4e667ebSPrzemek Kitszel */ 54*f4e667ebSPrzemek Kitszel u32 vc_hash_field; /* virtchnl hash fields selector 55*f4e667ebSPrzemek Kitszel * FIELD_SELECTOR((VIRTCHNL_PROTO_HDR_ETH_XXX)) 56*f4e667ebSPrzemek Kitszel */ 57*f4e667ebSPrzemek Kitszel u64 ice_hash_field; /* ice hash fields 58*f4e667ebSPrzemek Kitszel * (BIT_ULL(ICE_FLOW_FIELD_IDX_XXX)) 59*f4e667ebSPrzemek Kitszel */ 60*f4e667ebSPrzemek Kitszel }; 61*f4e667ebSPrzemek Kitszel 62*f4e667ebSPrzemek Kitszel static const struct 63*f4e667ebSPrzemek Kitszel ice_vc_hash_field_match_type ice_vc_hash_field_list[] = { 64*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC), 65*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA)}, 66*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), 67*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA)}, 68*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) | 69*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), 70*f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_ETH}, 71*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ETH, 72*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE), 73*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE)}, 74*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_S_VLAN, 75*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID), 76*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN)}, 77*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_C_VLAN, 78*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID), 79*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN)}, 80*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC), 81*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)}, 82*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), 83*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)}, 84*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 85*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), 86*f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_IPV4}, 87*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 88*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 89*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | 90*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 91*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | 92*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 93*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | 94*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 95*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | 96*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | 97*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 98*f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_IPV4 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 99*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), 100*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)}, 101*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC), 102*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)}, 103*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), 104*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)}, 105*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 106*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), 107*f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_IPV6}, 108*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 109*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 110*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | 111*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 112*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | 113*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 114*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | 115*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 116*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | 117*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | 118*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 119*f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_IPV6 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 120*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), 121*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)}, 122*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_TCP, 123*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT), 124*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, 125*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_TCP, 126*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), 127*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, 128*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_TCP, 129*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) | 130*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), 131*f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_TCP_PORT}, 132*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_UDP, 133*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT), 134*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, 135*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_UDP, 136*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), 137*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, 138*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_UDP, 139*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) | 140*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), 141*f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_UDP_PORT}, 142*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_SCTP, 143*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT), 144*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, 145*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_SCTP, 146*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), 147*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, 148*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_SCTP, 149*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) | 150*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), 151*f4e667ebSPrzemek Kitszel ICE_FLOW_HASH_SCTP_PORT}, 152*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_PPPOE, 153*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID), 154*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID)}, 155*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_GTPU_IP, 156*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_GTPU_IP_TEID), 157*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID)}, 158*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_L2TPV3, 159*f4e667ebSPrzemek Kitszel FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID), 160*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID)}, 161*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_ESP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI), 162*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_ESP_SPI)}, 163*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_AH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI), 164*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_AH_SPI)}, 165*f4e667ebSPrzemek Kitszel {VIRTCHNL_PROTO_HDR_PFCP, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID), 166*f4e667ebSPrzemek Kitszel BIT_ULL(ICE_FLOW_FIELD_IDX_PFCP_SEID)}, 167*f4e667ebSPrzemek Kitszel }; 168*f4e667ebSPrzemek Kitszel 169*f4e667ebSPrzemek Kitszel /** 170*f4e667ebSPrzemek Kitszel * ice_vc_vf_broadcast - Broadcast a message to all VFs on PF 171*f4e667ebSPrzemek Kitszel * @pf: pointer to the PF structure 172*f4e667ebSPrzemek Kitszel * @v_opcode: operation code 173*f4e667ebSPrzemek Kitszel * @v_retval: return value 174*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 175*f4e667ebSPrzemek Kitszel * @msglen: msg length 176*f4e667ebSPrzemek Kitszel */ 177*f4e667ebSPrzemek Kitszel static void 178*f4e667ebSPrzemek Kitszel ice_vc_vf_broadcast(struct ice_pf *pf, enum virtchnl_ops v_opcode, 179*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_retval, u8 *msg, u16 msglen) 180*f4e667ebSPrzemek Kitszel { 181*f4e667ebSPrzemek Kitszel struct ice_hw *hw = &pf->hw; 182*f4e667ebSPrzemek Kitszel struct ice_vf *vf; 183*f4e667ebSPrzemek Kitszel unsigned int bkt; 184*f4e667ebSPrzemek Kitszel 185*f4e667ebSPrzemek Kitszel mutex_lock(&pf->vfs.table_lock); 186*f4e667ebSPrzemek Kitszel ice_for_each_vf(pf, bkt, vf) { 187*f4e667ebSPrzemek Kitszel /* Not all vfs are enabled so skip the ones that are not */ 188*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_INIT, vf->vf_states) && 189*f4e667ebSPrzemek Kitszel !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) 190*f4e667ebSPrzemek Kitszel continue; 191*f4e667ebSPrzemek Kitszel 192*f4e667ebSPrzemek Kitszel /* Ignore return value on purpose - a given VF may fail, but 193*f4e667ebSPrzemek Kitszel * we need to keep going and send to all of them 194*f4e667ebSPrzemek Kitszel */ 195*f4e667ebSPrzemek Kitszel ice_aq_send_msg_to_vf(hw, vf->vf_id, v_opcode, v_retval, msg, 196*f4e667ebSPrzemek Kitszel msglen, NULL); 197*f4e667ebSPrzemek Kitszel } 198*f4e667ebSPrzemek Kitszel mutex_unlock(&pf->vfs.table_lock); 199*f4e667ebSPrzemek Kitszel } 200*f4e667ebSPrzemek Kitszel 201*f4e667ebSPrzemek Kitszel /** 202*f4e667ebSPrzemek Kitszel * ice_set_pfe_link - Set the link speed/status of the virtchnl_pf_event 203*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF structure 204*f4e667ebSPrzemek Kitszel * @pfe: pointer to the virtchnl_pf_event to set link speed/status for 205*f4e667ebSPrzemek Kitszel * @ice_link_speed: link speed specified by ICE_AQ_LINK_SPEED_* 206*f4e667ebSPrzemek Kitszel * @link_up: whether or not to set the link up/down 207*f4e667ebSPrzemek Kitszel */ 208*f4e667ebSPrzemek Kitszel static void 209*f4e667ebSPrzemek Kitszel ice_set_pfe_link(struct ice_vf *vf, struct virtchnl_pf_event *pfe, 210*f4e667ebSPrzemek Kitszel int ice_link_speed, bool link_up) 211*f4e667ebSPrzemek Kitszel { 212*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_CAP_ADV_LINK_SPEED) { 213*f4e667ebSPrzemek Kitszel pfe->event_data.link_event_adv.link_status = link_up; 214*f4e667ebSPrzemek Kitszel /* Speed in Mbps */ 215*f4e667ebSPrzemek Kitszel pfe->event_data.link_event_adv.link_speed = 216*f4e667ebSPrzemek Kitszel ice_conv_link_speed_to_virtchnl(true, ice_link_speed); 217*f4e667ebSPrzemek Kitszel } else { 218*f4e667ebSPrzemek Kitszel pfe->event_data.link_event.link_status = link_up; 219*f4e667ebSPrzemek Kitszel /* Legacy method for virtchnl link speeds */ 220*f4e667ebSPrzemek Kitszel pfe->event_data.link_event.link_speed = 221*f4e667ebSPrzemek Kitszel (enum virtchnl_link_speed) 222*f4e667ebSPrzemek Kitszel ice_conv_link_speed_to_virtchnl(false, ice_link_speed); 223*f4e667ebSPrzemek Kitszel } 224*f4e667ebSPrzemek Kitszel } 225*f4e667ebSPrzemek Kitszel 226*f4e667ebSPrzemek Kitszel /** 227*f4e667ebSPrzemek Kitszel * ice_vc_notify_vf_link_state - Inform a VF of link status 228*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF structure 229*f4e667ebSPrzemek Kitszel * 230*f4e667ebSPrzemek Kitszel * send a link status message to a single VF 231*f4e667ebSPrzemek Kitszel */ 232*f4e667ebSPrzemek Kitszel void ice_vc_notify_vf_link_state(struct ice_vf *vf) 233*f4e667ebSPrzemek Kitszel { 234*f4e667ebSPrzemek Kitszel struct virtchnl_pf_event pfe = { 0 }; 235*f4e667ebSPrzemek Kitszel struct ice_hw *hw = &vf->pf->hw; 236*f4e667ebSPrzemek Kitszel 237*f4e667ebSPrzemek Kitszel pfe.event = VIRTCHNL_EVENT_LINK_CHANGE; 238*f4e667ebSPrzemek Kitszel pfe.severity = PF_EVENT_SEVERITY_INFO; 239*f4e667ebSPrzemek Kitszel 240*f4e667ebSPrzemek Kitszel if (ice_is_vf_link_up(vf)) 241*f4e667ebSPrzemek Kitszel ice_set_pfe_link(vf, &pfe, 242*f4e667ebSPrzemek Kitszel hw->port_info->phy.link_info.link_speed, true); 243*f4e667ebSPrzemek Kitszel else 244*f4e667ebSPrzemek Kitszel ice_set_pfe_link(vf, &pfe, ICE_AQ_LINK_SPEED_UNKNOWN, false); 245*f4e667ebSPrzemek Kitszel 246*f4e667ebSPrzemek Kitszel ice_aq_send_msg_to_vf(hw, vf->vf_id, VIRTCHNL_OP_EVENT, 247*f4e667ebSPrzemek Kitszel VIRTCHNL_STATUS_SUCCESS, (u8 *)&pfe, 248*f4e667ebSPrzemek Kitszel sizeof(pfe), NULL); 249*f4e667ebSPrzemek Kitszel } 250*f4e667ebSPrzemek Kitszel 251*f4e667ebSPrzemek Kitszel /** 252*f4e667ebSPrzemek Kitszel * ice_vc_notify_link_state - Inform all VFs on a PF of link status 253*f4e667ebSPrzemek Kitszel * @pf: pointer to the PF structure 254*f4e667ebSPrzemek Kitszel */ 255*f4e667ebSPrzemek Kitszel void ice_vc_notify_link_state(struct ice_pf *pf) 256*f4e667ebSPrzemek Kitszel { 257*f4e667ebSPrzemek Kitszel struct ice_vf *vf; 258*f4e667ebSPrzemek Kitszel unsigned int bkt; 259*f4e667ebSPrzemek Kitszel 260*f4e667ebSPrzemek Kitszel mutex_lock(&pf->vfs.table_lock); 261*f4e667ebSPrzemek Kitszel ice_for_each_vf(pf, bkt, vf) 262*f4e667ebSPrzemek Kitszel ice_vc_notify_vf_link_state(vf); 263*f4e667ebSPrzemek Kitszel mutex_unlock(&pf->vfs.table_lock); 264*f4e667ebSPrzemek Kitszel } 265*f4e667ebSPrzemek Kitszel 266*f4e667ebSPrzemek Kitszel /** 267*f4e667ebSPrzemek Kitszel * ice_vc_notify_reset - Send pending reset message to all VFs 268*f4e667ebSPrzemek Kitszel * @pf: pointer to the PF structure 269*f4e667ebSPrzemek Kitszel * 270*f4e667ebSPrzemek Kitszel * indicate a pending reset to all VFs on a given PF 271*f4e667ebSPrzemek Kitszel */ 272*f4e667ebSPrzemek Kitszel void ice_vc_notify_reset(struct ice_pf *pf) 273*f4e667ebSPrzemek Kitszel { 274*f4e667ebSPrzemek Kitszel struct virtchnl_pf_event pfe; 275*f4e667ebSPrzemek Kitszel 276*f4e667ebSPrzemek Kitszel if (!ice_has_vfs(pf)) 277*f4e667ebSPrzemek Kitszel return; 278*f4e667ebSPrzemek Kitszel 279*f4e667ebSPrzemek Kitszel pfe.event = VIRTCHNL_EVENT_RESET_IMPENDING; 280*f4e667ebSPrzemek Kitszel pfe.severity = PF_EVENT_SEVERITY_CERTAIN_DOOM; 281*f4e667ebSPrzemek Kitszel ice_vc_vf_broadcast(pf, VIRTCHNL_OP_EVENT, VIRTCHNL_STATUS_SUCCESS, 282*f4e667ebSPrzemek Kitszel (u8 *)&pfe, sizeof(struct virtchnl_pf_event)); 283*f4e667ebSPrzemek Kitszel } 284*f4e667ebSPrzemek Kitszel 285*f4e667ebSPrzemek Kitszel /** 286*f4e667ebSPrzemek Kitszel * ice_vc_send_msg_to_vf - Send message to VF 287*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 288*f4e667ebSPrzemek Kitszel * @v_opcode: virtual channel opcode 289*f4e667ebSPrzemek Kitszel * @v_retval: virtual channel return value 290*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 291*f4e667ebSPrzemek Kitszel * @msglen: msg length 292*f4e667ebSPrzemek Kitszel * 293*f4e667ebSPrzemek Kitszel * send msg to VF 294*f4e667ebSPrzemek Kitszel */ 295*f4e667ebSPrzemek Kitszel int 296*f4e667ebSPrzemek Kitszel ice_vc_send_msg_to_vf(struct ice_vf *vf, u32 v_opcode, 297*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_retval, u8 *msg, u16 msglen) 298*f4e667ebSPrzemek Kitszel { 299*f4e667ebSPrzemek Kitszel struct device *dev; 300*f4e667ebSPrzemek Kitszel struct ice_pf *pf; 301*f4e667ebSPrzemek Kitszel int aq_ret; 302*f4e667ebSPrzemek Kitszel 303*f4e667ebSPrzemek Kitszel pf = vf->pf; 304*f4e667ebSPrzemek Kitszel dev = ice_pf_to_dev(pf); 305*f4e667ebSPrzemek Kitszel 306*f4e667ebSPrzemek Kitszel aq_ret = ice_aq_send_msg_to_vf(&pf->hw, vf->vf_id, v_opcode, v_retval, 307*f4e667ebSPrzemek Kitszel msg, msglen, NULL); 308*f4e667ebSPrzemek Kitszel if (aq_ret && pf->hw.mailboxq.sq_last_status != LIBIE_AQ_RC_ENOSYS) { 309*f4e667ebSPrzemek Kitszel dev_info(dev, "Unable to send the message to VF %d ret %d aq_err %s\n", 310*f4e667ebSPrzemek Kitszel vf->vf_id, aq_ret, 311*f4e667ebSPrzemek Kitszel libie_aq_str(pf->hw.mailboxq.sq_last_status)); 312*f4e667ebSPrzemek Kitszel return -EIO; 313*f4e667ebSPrzemek Kitszel } 314*f4e667ebSPrzemek Kitszel 315*f4e667ebSPrzemek Kitszel return 0; 316*f4e667ebSPrzemek Kitszel } 317*f4e667ebSPrzemek Kitszel 318*f4e667ebSPrzemek Kitszel /** 319*f4e667ebSPrzemek Kitszel * ice_vc_get_ver_msg 320*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 321*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 322*f4e667ebSPrzemek Kitszel * 323*f4e667ebSPrzemek Kitszel * called from the VF to request the API version used by the PF 324*f4e667ebSPrzemek Kitszel */ 325*f4e667ebSPrzemek Kitszel static int ice_vc_get_ver_msg(struct ice_vf *vf, u8 *msg) 326*f4e667ebSPrzemek Kitszel { 327*f4e667ebSPrzemek Kitszel struct virtchnl_version_info info = { 328*f4e667ebSPrzemek Kitszel VIRTCHNL_VERSION_MAJOR, VIRTCHNL_VERSION_MINOR 329*f4e667ebSPrzemek Kitszel }; 330*f4e667ebSPrzemek Kitszel 331*f4e667ebSPrzemek Kitszel vf->vf_ver = *(struct virtchnl_version_info *)msg; 332*f4e667ebSPrzemek Kitszel /* VFs running the 1.0 API expect to get 1.0 back or they will cry. */ 333*f4e667ebSPrzemek Kitszel if (VF_IS_V10(&vf->vf_ver)) 334*f4e667ebSPrzemek Kitszel info.minor = VIRTCHNL_VERSION_MINOR_NO_VF_CAPS; 335*f4e667ebSPrzemek Kitszel 336*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_VERSION, 337*f4e667ebSPrzemek Kitszel VIRTCHNL_STATUS_SUCCESS, (u8 *)&info, 338*f4e667ebSPrzemek Kitszel sizeof(struct virtchnl_version_info)); 339*f4e667ebSPrzemek Kitszel } 340*f4e667ebSPrzemek Kitszel 341*f4e667ebSPrzemek Kitszel /** 342*f4e667ebSPrzemek Kitszel * ice_vc_get_vlan_caps 343*f4e667ebSPrzemek Kitszel * @hw: pointer to the hw 344*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 345*f4e667ebSPrzemek Kitszel * @vsi: pointer to the VSI 346*f4e667ebSPrzemek Kitszel * @driver_caps: current driver caps 347*f4e667ebSPrzemek Kitszel * 348*f4e667ebSPrzemek Kitszel * Return 0 if there is no VLAN caps supported, or VLAN caps value 349*f4e667ebSPrzemek Kitszel */ 350*f4e667ebSPrzemek Kitszel static u32 351*f4e667ebSPrzemek Kitszel ice_vc_get_vlan_caps(struct ice_hw *hw, struct ice_vf *vf, struct ice_vsi *vsi, 352*f4e667ebSPrzemek Kitszel u32 driver_caps) 353*f4e667ebSPrzemek Kitszel { 354*f4e667ebSPrzemek Kitszel if (ice_is_eswitch_mode_switchdev(vf->pf)) 355*f4e667ebSPrzemek Kitszel /* In switchdev setting VLAN from VF isn't supported */ 356*f4e667ebSPrzemek Kitszel return 0; 357*f4e667ebSPrzemek Kitszel 358*f4e667ebSPrzemek Kitszel if (driver_caps & VIRTCHNL_VF_OFFLOAD_VLAN_V2) { 359*f4e667ebSPrzemek Kitszel /* VLAN offloads based on current device configuration */ 360*f4e667ebSPrzemek Kitszel return VIRTCHNL_VF_OFFLOAD_VLAN_V2; 361*f4e667ebSPrzemek Kitszel } else if (driver_caps & VIRTCHNL_VF_OFFLOAD_VLAN) { 362*f4e667ebSPrzemek Kitszel /* allow VF to negotiate VIRTCHNL_VF_OFFLOAD explicitly for 363*f4e667ebSPrzemek Kitszel * these two conditions, which amounts to guest VLAN filtering 364*f4e667ebSPrzemek Kitszel * and offloads being based on the inner VLAN or the 365*f4e667ebSPrzemek Kitszel * inner/single VLAN respectively and don't allow VF to 366*f4e667ebSPrzemek Kitszel * negotiate VIRTCHNL_VF_OFFLOAD in any other cases 367*f4e667ebSPrzemek Kitszel */ 368*f4e667ebSPrzemek Kitszel if (ice_is_dvm_ena(hw) && ice_vf_is_port_vlan_ena(vf)) { 369*f4e667ebSPrzemek Kitszel return VIRTCHNL_VF_OFFLOAD_VLAN; 370*f4e667ebSPrzemek Kitszel } else if (!ice_is_dvm_ena(hw) && 371*f4e667ebSPrzemek Kitszel !ice_vf_is_port_vlan_ena(vf)) { 372*f4e667ebSPrzemek Kitszel /* configure backward compatible support for VFs that 373*f4e667ebSPrzemek Kitszel * only support VIRTCHNL_VF_OFFLOAD_VLAN, the PF is 374*f4e667ebSPrzemek Kitszel * configured in SVM, and no port VLAN is configured 375*f4e667ebSPrzemek Kitszel */ 376*f4e667ebSPrzemek Kitszel ice_vf_vsi_cfg_svm_legacy_vlan_mode(vsi); 377*f4e667ebSPrzemek Kitszel return VIRTCHNL_VF_OFFLOAD_VLAN; 378*f4e667ebSPrzemek Kitszel } else if (ice_is_dvm_ena(hw)) { 379*f4e667ebSPrzemek Kitszel /* configure software offloaded VLAN support when DVM 380*f4e667ebSPrzemek Kitszel * is enabled, but no port VLAN is enabled 381*f4e667ebSPrzemek Kitszel */ 382*f4e667ebSPrzemek Kitszel ice_vf_vsi_cfg_dvm_legacy_vlan_mode(vsi); 383*f4e667ebSPrzemek Kitszel } 384*f4e667ebSPrzemek Kitszel } 385*f4e667ebSPrzemek Kitszel 386*f4e667ebSPrzemek Kitszel return 0; 387*f4e667ebSPrzemek Kitszel } 388*f4e667ebSPrzemek Kitszel 389*f4e667ebSPrzemek Kitszel /** 390*f4e667ebSPrzemek Kitszel * ice_vc_get_vf_res_msg 391*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 392*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 393*f4e667ebSPrzemek Kitszel * 394*f4e667ebSPrzemek Kitszel * called from the VF to request its resources 395*f4e667ebSPrzemek Kitszel */ 396*f4e667ebSPrzemek Kitszel static int ice_vc_get_vf_res_msg(struct ice_vf *vf, u8 *msg) 397*f4e667ebSPrzemek Kitszel { 398*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 399*f4e667ebSPrzemek Kitszel struct virtchnl_vf_resource *vfres = NULL; 400*f4e667ebSPrzemek Kitszel struct ice_hw *hw = &vf->pf->hw; 401*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 402*f4e667ebSPrzemek Kitszel int len = 0; 403*f4e667ebSPrzemek Kitszel int ret; 404*f4e667ebSPrzemek Kitszel 405*f4e667ebSPrzemek Kitszel if (ice_check_vf_init(vf)) { 406*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 407*f4e667ebSPrzemek Kitszel goto err; 408*f4e667ebSPrzemek Kitszel } 409*f4e667ebSPrzemek Kitszel 410*f4e667ebSPrzemek Kitszel len = virtchnl_struct_size(vfres, vsi_res, 0); 411*f4e667ebSPrzemek Kitszel 412*f4e667ebSPrzemek Kitszel vfres = kzalloc(len, GFP_KERNEL); 413*f4e667ebSPrzemek Kitszel if (!vfres) { 414*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 415*f4e667ebSPrzemek Kitszel len = 0; 416*f4e667ebSPrzemek Kitszel goto err; 417*f4e667ebSPrzemek Kitszel } 418*f4e667ebSPrzemek Kitszel if (VF_IS_V11(&vf->vf_ver)) 419*f4e667ebSPrzemek Kitszel vf->driver_caps = *(u32 *)msg; 420*f4e667ebSPrzemek Kitszel else 421*f4e667ebSPrzemek Kitszel vf->driver_caps = VIRTCHNL_VF_OFFLOAD_L2 | 422*f4e667ebSPrzemek Kitszel VIRTCHNL_VF_OFFLOAD_VLAN; 423*f4e667ebSPrzemek Kitszel 424*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags = VIRTCHNL_VF_OFFLOAD_L2; 425*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 426*f4e667ebSPrzemek Kitszel if (!vsi) { 427*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 428*f4e667ebSPrzemek Kitszel goto err; 429*f4e667ebSPrzemek Kitszel } 430*f4e667ebSPrzemek Kitszel 431*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= ice_vc_get_vlan_caps(hw, vf, vsi, 432*f4e667ebSPrzemek Kitszel vf->driver_caps); 433*f4e667ebSPrzemek Kitszel 434*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RSS_PF) 435*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_RSS_PF; 436*f4e667ebSPrzemek Kitszel 437*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) 438*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC; 439*f4e667ebSPrzemek Kitszel 440*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_FDIR_PF) 441*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_FDIR_PF; 442*f4e667ebSPrzemek Kitszel 443*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_TC_U32 && 444*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_FDIR_PF) 445*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_TC_U32; 446*f4e667ebSPrzemek Kitszel 447*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2) 448*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2; 449*f4e667ebSPrzemek Kitszel 450*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ENCAP) 451*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_ENCAP; 452*f4e667ebSPrzemek Kitszel 453*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM) 454*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM; 455*f4e667ebSPrzemek Kitszel 456*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RX_POLLING) 457*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_RX_POLLING; 458*f4e667ebSPrzemek Kitszel 459*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) 460*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_WB_ON_ITR; 461*f4e667ebSPrzemek Kitszel 462*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_REQ_QUEUES) 463*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_REQ_QUEUES; 464*f4e667ebSPrzemek Kitszel 465*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_CRC) 466*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_CRC; 467*f4e667ebSPrzemek Kitszel 468*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_CAP_ADV_LINK_SPEED) 469*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_CAP_ADV_LINK_SPEED; 470*f4e667ebSPrzemek Kitszel 471*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF) 472*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF; 473*f4e667ebSPrzemek Kitszel 474*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) 475*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_USO; 476*f4e667ebSPrzemek Kitszel 477*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_QOS) 478*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_QOS; 479*f4e667ebSPrzemek Kitszel 480*f4e667ebSPrzemek Kitszel if (vf->driver_caps & VIRTCHNL_VF_CAP_PTP) 481*f4e667ebSPrzemek Kitszel vfres->vf_cap_flags |= VIRTCHNL_VF_CAP_PTP; 482*f4e667ebSPrzemek Kitszel 483*f4e667ebSPrzemek Kitszel vfres->num_vsis = 1; 484*f4e667ebSPrzemek Kitszel /* Tx and Rx queue are equal for VF */ 485*f4e667ebSPrzemek Kitszel vfres->num_queue_pairs = vsi->num_txq; 486*f4e667ebSPrzemek Kitszel vfres->max_vectors = vf->num_msix; 487*f4e667ebSPrzemek Kitszel vfres->rss_key_size = ICE_VSIQF_HKEY_ARRAY_SIZE; 488*f4e667ebSPrzemek Kitszel vfres->rss_lut_size = ICE_LUT_VSI_SIZE; 489*f4e667ebSPrzemek Kitszel vfres->max_mtu = ice_vc_get_max_frame_size(vf); 490*f4e667ebSPrzemek Kitszel 491*f4e667ebSPrzemek Kitszel vfres->vsi_res[0].vsi_id = ICE_VF_VSI_ID; 492*f4e667ebSPrzemek Kitszel vfres->vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV; 493*f4e667ebSPrzemek Kitszel vfres->vsi_res[0].num_queue_pairs = vsi->num_txq; 494*f4e667ebSPrzemek Kitszel ether_addr_copy(vfres->vsi_res[0].default_mac_addr, 495*f4e667ebSPrzemek Kitszel vf->hw_lan_addr); 496*f4e667ebSPrzemek Kitszel 497*f4e667ebSPrzemek Kitszel /* match guest capabilities */ 498*f4e667ebSPrzemek Kitszel vf->driver_caps = vfres->vf_cap_flags; 499*f4e667ebSPrzemek Kitszel 500*f4e667ebSPrzemek Kitszel ice_vc_set_caps_allowlist(vf); 501*f4e667ebSPrzemek Kitszel ice_vc_set_working_allowlist(vf); 502*f4e667ebSPrzemek Kitszel 503*f4e667ebSPrzemek Kitszel set_bit(ICE_VF_STATE_ACTIVE, vf->vf_states); 504*f4e667ebSPrzemek Kitszel 505*f4e667ebSPrzemek Kitszel err: 506*f4e667ebSPrzemek Kitszel /* send the response back to the VF */ 507*f4e667ebSPrzemek Kitszel ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_VF_RESOURCES, v_ret, 508*f4e667ebSPrzemek Kitszel (u8 *)vfres, len); 509*f4e667ebSPrzemek Kitszel 510*f4e667ebSPrzemek Kitszel kfree(vfres); 511*f4e667ebSPrzemek Kitszel return ret; 512*f4e667ebSPrzemek Kitszel } 513*f4e667ebSPrzemek Kitszel 514*f4e667ebSPrzemek Kitszel /** 515*f4e667ebSPrzemek Kitszel * ice_vc_reset_vf_msg 516*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 517*f4e667ebSPrzemek Kitszel * 518*f4e667ebSPrzemek Kitszel * called from the VF to reset itself, 519*f4e667ebSPrzemek Kitszel * unlike other virtchnl messages, PF driver 520*f4e667ebSPrzemek Kitszel * doesn't send the response back to the VF 521*f4e667ebSPrzemek Kitszel */ 522*f4e667ebSPrzemek Kitszel static void ice_vc_reset_vf_msg(struct ice_vf *vf) 523*f4e667ebSPrzemek Kitszel { 524*f4e667ebSPrzemek Kitszel if (test_bit(ICE_VF_STATE_INIT, vf->vf_states)) 525*f4e667ebSPrzemek Kitszel ice_reset_vf(vf, 0); 526*f4e667ebSPrzemek Kitszel } 527*f4e667ebSPrzemek Kitszel 528*f4e667ebSPrzemek Kitszel /** 529*f4e667ebSPrzemek Kitszel * ice_vc_isvalid_vsi_id 530*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 531*f4e667ebSPrzemek Kitszel * @vsi_id: VF relative VSI ID 532*f4e667ebSPrzemek Kitszel * 533*f4e667ebSPrzemek Kitszel * check for the valid VSI ID 534*f4e667ebSPrzemek Kitszel */ 535*f4e667ebSPrzemek Kitszel bool ice_vc_isvalid_vsi_id(struct ice_vf *vf, u16 vsi_id) 536*f4e667ebSPrzemek Kitszel { 537*f4e667ebSPrzemek Kitszel return vsi_id == ICE_VF_VSI_ID; 538*f4e667ebSPrzemek Kitszel } 539*f4e667ebSPrzemek Kitszel 540*f4e667ebSPrzemek Kitszel /** 541*f4e667ebSPrzemek Kitszel * ice_vc_validate_pattern 542*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 543*f4e667ebSPrzemek Kitszel * @proto: virtchnl protocol headers 544*f4e667ebSPrzemek Kitszel * 545*f4e667ebSPrzemek Kitszel * validate the pattern is supported or not. 546*f4e667ebSPrzemek Kitszel * 547*f4e667ebSPrzemek Kitszel * Return: true on success, false on error. 548*f4e667ebSPrzemek Kitszel */ 549*f4e667ebSPrzemek Kitszel bool 550*f4e667ebSPrzemek Kitszel ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto) 551*f4e667ebSPrzemek Kitszel { 552*f4e667ebSPrzemek Kitszel bool is_ipv4 = false; 553*f4e667ebSPrzemek Kitszel bool is_ipv6 = false; 554*f4e667ebSPrzemek Kitszel bool is_udp = false; 555*f4e667ebSPrzemek Kitszel u16 ptype = -1; 556*f4e667ebSPrzemek Kitszel int i = 0; 557*f4e667ebSPrzemek Kitszel 558*f4e667ebSPrzemek Kitszel while (i < proto->count && 559*f4e667ebSPrzemek Kitszel proto->proto_hdr[i].type != VIRTCHNL_PROTO_HDR_NONE) { 560*f4e667ebSPrzemek Kitszel switch (proto->proto_hdr[i].type) { 561*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_ETH: 562*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_MAC_PAY; 563*f4e667ebSPrzemek Kitszel break; 564*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_IPV4: 565*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV4_PAY; 566*f4e667ebSPrzemek Kitszel is_ipv4 = true; 567*f4e667ebSPrzemek Kitszel break; 568*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_IPV6: 569*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV6_PAY; 570*f4e667ebSPrzemek Kitszel is_ipv6 = true; 571*f4e667ebSPrzemek Kitszel break; 572*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_UDP: 573*f4e667ebSPrzemek Kitszel if (is_ipv4) 574*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV4_UDP_PAY; 575*f4e667ebSPrzemek Kitszel else if (is_ipv6) 576*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV6_UDP_PAY; 577*f4e667ebSPrzemek Kitszel is_udp = true; 578*f4e667ebSPrzemek Kitszel break; 579*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_TCP: 580*f4e667ebSPrzemek Kitszel if (is_ipv4) 581*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV4_TCP_PAY; 582*f4e667ebSPrzemek Kitszel else if (is_ipv6) 583*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV6_TCP_PAY; 584*f4e667ebSPrzemek Kitszel break; 585*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_SCTP: 586*f4e667ebSPrzemek Kitszel if (is_ipv4) 587*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV4_SCTP_PAY; 588*f4e667ebSPrzemek Kitszel else if (is_ipv6) 589*f4e667ebSPrzemek Kitszel ptype = ICE_PTYPE_IPV6_SCTP_PAY; 590*f4e667ebSPrzemek Kitszel break; 591*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_GTPU_IP: 592*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_GTPU_EH: 593*f4e667ebSPrzemek Kitszel if (is_ipv4) 594*f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV4_GTPU; 595*f4e667ebSPrzemek Kitszel else if (is_ipv6) 596*f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV6_GTPU; 597*f4e667ebSPrzemek Kitszel goto out; 598*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_L2TPV3: 599*f4e667ebSPrzemek Kitszel if (is_ipv4) 600*f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV4_L2TPV3; 601*f4e667ebSPrzemek Kitszel else if (is_ipv6) 602*f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV6_L2TPV3; 603*f4e667ebSPrzemek Kitszel goto out; 604*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_ESP: 605*f4e667ebSPrzemek Kitszel if (is_ipv4) 606*f4e667ebSPrzemek Kitszel ptype = is_udp ? ICE_MAC_IPV4_NAT_T_ESP : 607*f4e667ebSPrzemek Kitszel ICE_MAC_IPV4_ESP; 608*f4e667ebSPrzemek Kitszel else if (is_ipv6) 609*f4e667ebSPrzemek Kitszel ptype = is_udp ? ICE_MAC_IPV6_NAT_T_ESP : 610*f4e667ebSPrzemek Kitszel ICE_MAC_IPV6_ESP; 611*f4e667ebSPrzemek Kitszel goto out; 612*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_AH: 613*f4e667ebSPrzemek Kitszel if (is_ipv4) 614*f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV4_AH; 615*f4e667ebSPrzemek Kitszel else if (is_ipv6) 616*f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV6_AH; 617*f4e667ebSPrzemek Kitszel goto out; 618*f4e667ebSPrzemek Kitszel case VIRTCHNL_PROTO_HDR_PFCP: 619*f4e667ebSPrzemek Kitszel if (is_ipv4) 620*f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV4_PFCP_SESSION; 621*f4e667ebSPrzemek Kitszel else if (is_ipv6) 622*f4e667ebSPrzemek Kitszel ptype = ICE_MAC_IPV6_PFCP_SESSION; 623*f4e667ebSPrzemek Kitszel goto out; 624*f4e667ebSPrzemek Kitszel default: 625*f4e667ebSPrzemek Kitszel break; 626*f4e667ebSPrzemek Kitszel } 627*f4e667ebSPrzemek Kitszel i++; 628*f4e667ebSPrzemek Kitszel } 629*f4e667ebSPrzemek Kitszel 630*f4e667ebSPrzemek Kitszel out: 631*f4e667ebSPrzemek Kitszel return ice_hw_ptype_ena(&vf->pf->hw, ptype); 632*f4e667ebSPrzemek Kitszel } 633*f4e667ebSPrzemek Kitszel 634*f4e667ebSPrzemek Kitszel /** 635*f4e667ebSPrzemek Kitszel * ice_vc_parse_rss_cfg - parses hash fields and headers from 636*f4e667ebSPrzemek Kitszel * a specific virtchnl RSS cfg 637*f4e667ebSPrzemek Kitszel * @hw: pointer to the hardware 638*f4e667ebSPrzemek Kitszel * @rss_cfg: pointer to the virtchnl RSS cfg 639*f4e667ebSPrzemek Kitszel * @hash_cfg: pointer to the HW hash configuration 640*f4e667ebSPrzemek Kitszel * 641*f4e667ebSPrzemek Kitszel * Return true if all the protocol header and hash fields in the RSS cfg could 642*f4e667ebSPrzemek Kitszel * be parsed, else return false 643*f4e667ebSPrzemek Kitszel * 644*f4e667ebSPrzemek Kitszel * This function parses the virtchnl RSS cfg to be the intended 645*f4e667ebSPrzemek Kitszel * hash fields and the intended header for RSS configuration 646*f4e667ebSPrzemek Kitszel */ 647*f4e667ebSPrzemek Kitszel static bool ice_vc_parse_rss_cfg(struct ice_hw *hw, 648*f4e667ebSPrzemek Kitszel struct virtchnl_rss_cfg *rss_cfg, 649*f4e667ebSPrzemek Kitszel struct ice_rss_hash_cfg *hash_cfg) 650*f4e667ebSPrzemek Kitszel { 651*f4e667ebSPrzemek Kitszel const struct ice_vc_hash_field_match_type *hf_list; 652*f4e667ebSPrzemek Kitszel const struct ice_vc_hdr_match_type *hdr_list; 653*f4e667ebSPrzemek Kitszel int i, hf_list_len, hdr_list_len; 654*f4e667ebSPrzemek Kitszel u32 *addl_hdrs = &hash_cfg->addl_hdrs; 655*f4e667ebSPrzemek Kitszel u64 *hash_flds = &hash_cfg->hash_flds; 656*f4e667ebSPrzemek Kitszel 657*f4e667ebSPrzemek Kitszel /* set outer layer RSS as default */ 658*f4e667ebSPrzemek Kitszel hash_cfg->hdr_type = ICE_RSS_OUTER_HEADERS; 659*f4e667ebSPrzemek Kitszel 660*f4e667ebSPrzemek Kitszel if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC) 661*f4e667ebSPrzemek Kitszel hash_cfg->symm = true; 662*f4e667ebSPrzemek Kitszel else 663*f4e667ebSPrzemek Kitszel hash_cfg->symm = false; 664*f4e667ebSPrzemek Kitszel 665*f4e667ebSPrzemek Kitszel hf_list = ice_vc_hash_field_list; 666*f4e667ebSPrzemek Kitszel hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list); 667*f4e667ebSPrzemek Kitszel hdr_list = ice_vc_hdr_list; 668*f4e667ebSPrzemek Kitszel hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list); 669*f4e667ebSPrzemek Kitszel 670*f4e667ebSPrzemek Kitszel for (i = 0; i < rss_cfg->proto_hdrs.count; i++) { 671*f4e667ebSPrzemek Kitszel struct virtchnl_proto_hdr *proto_hdr = 672*f4e667ebSPrzemek Kitszel &rss_cfg->proto_hdrs.proto_hdr[i]; 673*f4e667ebSPrzemek Kitszel bool hdr_found = false; 674*f4e667ebSPrzemek Kitszel int j; 675*f4e667ebSPrzemek Kitszel 676*f4e667ebSPrzemek Kitszel /* Find matched ice headers according to virtchnl headers. */ 677*f4e667ebSPrzemek Kitszel for (j = 0; j < hdr_list_len; j++) { 678*f4e667ebSPrzemek Kitszel struct ice_vc_hdr_match_type hdr_map = hdr_list[j]; 679*f4e667ebSPrzemek Kitszel 680*f4e667ebSPrzemek Kitszel if (proto_hdr->type == hdr_map.vc_hdr) { 681*f4e667ebSPrzemek Kitszel *addl_hdrs |= hdr_map.ice_hdr; 682*f4e667ebSPrzemek Kitszel hdr_found = true; 683*f4e667ebSPrzemek Kitszel } 684*f4e667ebSPrzemek Kitszel } 685*f4e667ebSPrzemek Kitszel 686*f4e667ebSPrzemek Kitszel if (!hdr_found) 687*f4e667ebSPrzemek Kitszel return false; 688*f4e667ebSPrzemek Kitszel 689*f4e667ebSPrzemek Kitszel /* Find matched ice hash fields according to 690*f4e667ebSPrzemek Kitszel * virtchnl hash fields. 691*f4e667ebSPrzemek Kitszel */ 692*f4e667ebSPrzemek Kitszel for (j = 0; j < hf_list_len; j++) { 693*f4e667ebSPrzemek Kitszel struct ice_vc_hash_field_match_type hf_map = hf_list[j]; 694*f4e667ebSPrzemek Kitszel 695*f4e667ebSPrzemek Kitszel if (proto_hdr->type == hf_map.vc_hdr && 696*f4e667ebSPrzemek Kitszel proto_hdr->field_selector == hf_map.vc_hash_field) { 697*f4e667ebSPrzemek Kitszel *hash_flds |= hf_map.ice_hash_field; 698*f4e667ebSPrzemek Kitszel break; 699*f4e667ebSPrzemek Kitszel } 700*f4e667ebSPrzemek Kitszel } 701*f4e667ebSPrzemek Kitszel } 702*f4e667ebSPrzemek Kitszel 703*f4e667ebSPrzemek Kitszel return true; 704*f4e667ebSPrzemek Kitszel } 705*f4e667ebSPrzemek Kitszel 706*f4e667ebSPrzemek Kitszel /** 707*f4e667ebSPrzemek Kitszel * ice_vf_adv_rss_offload_ena - determine if capabilities support advanced 708*f4e667ebSPrzemek Kitszel * RSS offloads 709*f4e667ebSPrzemek Kitszel * @caps: VF driver negotiated capabilities 710*f4e667ebSPrzemek Kitszel * 711*f4e667ebSPrzemek Kitszel * Return true if VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF capability is set, 712*f4e667ebSPrzemek Kitszel * else return false 713*f4e667ebSPrzemek Kitszel */ 714*f4e667ebSPrzemek Kitszel static bool ice_vf_adv_rss_offload_ena(u32 caps) 715*f4e667ebSPrzemek Kitszel { 716*f4e667ebSPrzemek Kitszel return !!(caps & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF); 717*f4e667ebSPrzemek Kitszel } 718*f4e667ebSPrzemek Kitszel 719*f4e667ebSPrzemek Kitszel /** 720*f4e667ebSPrzemek Kitszel * ice_vc_handle_rss_cfg 721*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 722*f4e667ebSPrzemek Kitszel * @msg: pointer to the message buffer 723*f4e667ebSPrzemek Kitszel * @add: add a RSS config if true, otherwise delete a RSS config 724*f4e667ebSPrzemek Kitszel * 725*f4e667ebSPrzemek Kitszel * This function adds/deletes a RSS config 726*f4e667ebSPrzemek Kitszel */ 727*f4e667ebSPrzemek Kitszel static int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add) 728*f4e667ebSPrzemek Kitszel { 729*f4e667ebSPrzemek Kitszel u32 v_opcode = add ? VIRTCHNL_OP_ADD_RSS_CFG : VIRTCHNL_OP_DEL_RSS_CFG; 730*f4e667ebSPrzemek Kitszel struct virtchnl_rss_cfg *rss_cfg = (struct virtchnl_rss_cfg *)msg; 731*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 732*f4e667ebSPrzemek Kitszel struct device *dev = ice_pf_to_dev(vf->pf); 733*f4e667ebSPrzemek Kitszel struct ice_hw *hw = &vf->pf->hw; 734*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 735*f4e667ebSPrzemek Kitszel 736*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 737*f4e667ebSPrzemek Kitszel dev_dbg(dev, "VF %d attempting to configure RSS, but RSS is not supported by the PF\n", 738*f4e667ebSPrzemek Kitszel vf->vf_id); 739*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 740*f4e667ebSPrzemek Kitszel goto error_param; 741*f4e667ebSPrzemek Kitszel } 742*f4e667ebSPrzemek Kitszel 743*f4e667ebSPrzemek Kitszel if (!ice_vf_adv_rss_offload_ena(vf->driver_caps)) { 744*f4e667ebSPrzemek Kitszel dev_dbg(dev, "VF %d attempting to configure RSS, but Advanced RSS offload is not supported\n", 745*f4e667ebSPrzemek Kitszel vf->vf_id); 746*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 747*f4e667ebSPrzemek Kitszel goto error_param; 748*f4e667ebSPrzemek Kitszel } 749*f4e667ebSPrzemek Kitszel 750*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 751*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 752*f4e667ebSPrzemek Kitszel goto error_param; 753*f4e667ebSPrzemek Kitszel } 754*f4e667ebSPrzemek Kitszel 755*f4e667ebSPrzemek Kitszel if (rss_cfg->proto_hdrs.count > VIRTCHNL_MAX_NUM_PROTO_HDRS || 756*f4e667ebSPrzemek Kitszel rss_cfg->rss_algorithm < VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC || 757*f4e667ebSPrzemek Kitszel rss_cfg->rss_algorithm > VIRTCHNL_RSS_ALG_XOR_SYMMETRIC) { 758*f4e667ebSPrzemek Kitszel dev_dbg(dev, "VF %d attempting to configure RSS, but RSS configuration is not valid\n", 759*f4e667ebSPrzemek Kitszel vf->vf_id); 760*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 761*f4e667ebSPrzemek Kitszel goto error_param; 762*f4e667ebSPrzemek Kitszel } 763*f4e667ebSPrzemek Kitszel 764*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 765*f4e667ebSPrzemek Kitszel if (!vsi) { 766*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 767*f4e667ebSPrzemek Kitszel goto error_param; 768*f4e667ebSPrzemek Kitszel } 769*f4e667ebSPrzemek Kitszel 770*f4e667ebSPrzemek Kitszel if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) { 771*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 772*f4e667ebSPrzemek Kitszel goto error_param; 773*f4e667ebSPrzemek Kitszel } 774*f4e667ebSPrzemek Kitszel 775*f4e667ebSPrzemek Kitszel if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_R_ASYMMETRIC) { 776*f4e667ebSPrzemek Kitszel struct ice_vsi_ctx *ctx; 777*f4e667ebSPrzemek Kitszel u8 lut_type, hash_type; 778*f4e667ebSPrzemek Kitszel int status; 779*f4e667ebSPrzemek Kitszel 780*f4e667ebSPrzemek Kitszel lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; 781*f4e667ebSPrzemek Kitszel hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR : 782*f4e667ebSPrzemek Kitszel ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; 783*f4e667ebSPrzemek Kitszel 784*f4e667ebSPrzemek Kitszel ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 785*f4e667ebSPrzemek Kitszel if (!ctx) { 786*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 787*f4e667ebSPrzemek Kitszel goto error_param; 788*f4e667ebSPrzemek Kitszel } 789*f4e667ebSPrzemek Kitszel 790*f4e667ebSPrzemek Kitszel ctx->info.q_opt_rss = 791*f4e667ebSPrzemek Kitszel FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_LUT_M, lut_type) | 792*f4e667ebSPrzemek Kitszel FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hash_type); 793*f4e667ebSPrzemek Kitszel 794*f4e667ebSPrzemek Kitszel /* Preserve existing queueing option setting */ 795*f4e667ebSPrzemek Kitszel ctx->info.q_opt_rss |= (vsi->info.q_opt_rss & 796*f4e667ebSPrzemek Kitszel ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M); 797*f4e667ebSPrzemek Kitszel ctx->info.q_opt_tc = vsi->info.q_opt_tc; 798*f4e667ebSPrzemek Kitszel ctx->info.q_opt_flags = vsi->info.q_opt_rss; 799*f4e667ebSPrzemek Kitszel 800*f4e667ebSPrzemek Kitszel ctx->info.valid_sections = 801*f4e667ebSPrzemek Kitszel cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID); 802*f4e667ebSPrzemek Kitszel 803*f4e667ebSPrzemek Kitszel status = ice_update_vsi(hw, vsi->idx, ctx, NULL); 804*f4e667ebSPrzemek Kitszel if (status) { 805*f4e667ebSPrzemek Kitszel dev_err(dev, "update VSI for RSS failed, err %d aq_err %s\n", 806*f4e667ebSPrzemek Kitszel status, libie_aq_str(hw->adminq.sq_last_status)); 807*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 808*f4e667ebSPrzemek Kitszel } else { 809*f4e667ebSPrzemek Kitszel vsi->info.q_opt_rss = ctx->info.q_opt_rss; 810*f4e667ebSPrzemek Kitszel } 811*f4e667ebSPrzemek Kitszel 812*f4e667ebSPrzemek Kitszel kfree(ctx); 813*f4e667ebSPrzemek Kitszel } else { 814*f4e667ebSPrzemek Kitszel struct ice_rss_hash_cfg cfg; 815*f4e667ebSPrzemek Kitszel 816*f4e667ebSPrzemek Kitszel /* Only check for none raw pattern case */ 817*f4e667ebSPrzemek Kitszel if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) { 818*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 819*f4e667ebSPrzemek Kitszel goto error_param; 820*f4e667ebSPrzemek Kitszel } 821*f4e667ebSPrzemek Kitszel cfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE; 822*f4e667ebSPrzemek Kitszel cfg.hash_flds = ICE_HASH_INVALID; 823*f4e667ebSPrzemek Kitszel cfg.hdr_type = ICE_RSS_ANY_HEADERS; 824*f4e667ebSPrzemek Kitszel 825*f4e667ebSPrzemek Kitszel if (!ice_vc_parse_rss_cfg(hw, rss_cfg, &cfg)) { 826*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 827*f4e667ebSPrzemek Kitszel goto error_param; 828*f4e667ebSPrzemek Kitszel } 829*f4e667ebSPrzemek Kitszel 830*f4e667ebSPrzemek Kitszel if (add) { 831*f4e667ebSPrzemek Kitszel if (ice_add_rss_cfg(hw, vsi, &cfg)) { 832*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 833*f4e667ebSPrzemek Kitszel dev_err(dev, "ice_add_rss_cfg failed for vsi = %d, v_ret = %d\n", 834*f4e667ebSPrzemek Kitszel vsi->vsi_num, v_ret); 835*f4e667ebSPrzemek Kitszel } 836*f4e667ebSPrzemek Kitszel } else { 837*f4e667ebSPrzemek Kitszel int status; 838*f4e667ebSPrzemek Kitszel 839*f4e667ebSPrzemek Kitszel status = ice_rem_rss_cfg(hw, vsi->idx, &cfg); 840*f4e667ebSPrzemek Kitszel /* We just ignore -ENOENT, because if two configurations 841*f4e667ebSPrzemek Kitszel * share the same profile remove one of them actually 842*f4e667ebSPrzemek Kitszel * removes both, since the profile is deleted. 843*f4e667ebSPrzemek Kitszel */ 844*f4e667ebSPrzemek Kitszel if (status && status != -ENOENT) { 845*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 846*f4e667ebSPrzemek Kitszel dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%d\n", 847*f4e667ebSPrzemek Kitszel vf->vf_id, status); 848*f4e667ebSPrzemek Kitszel } 849*f4e667ebSPrzemek Kitszel } 850*f4e667ebSPrzemek Kitszel } 851*f4e667ebSPrzemek Kitszel 852*f4e667ebSPrzemek Kitszel error_param: 853*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, v_opcode, v_ret, NULL, 0); 854*f4e667ebSPrzemek Kitszel } 855*f4e667ebSPrzemek Kitszel 856*f4e667ebSPrzemek Kitszel /** 857*f4e667ebSPrzemek Kitszel * ice_vc_config_rss_key 858*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 859*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 860*f4e667ebSPrzemek Kitszel * 861*f4e667ebSPrzemek Kitszel * Configure the VF's RSS key 862*f4e667ebSPrzemek Kitszel */ 863*f4e667ebSPrzemek Kitszel static int ice_vc_config_rss_key(struct ice_vf *vf, u8 *msg) 864*f4e667ebSPrzemek Kitszel { 865*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 866*f4e667ebSPrzemek Kitszel struct virtchnl_rss_key *vrk = 867*f4e667ebSPrzemek Kitszel (struct virtchnl_rss_key *)msg; 868*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 869*f4e667ebSPrzemek Kitszel 870*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 871*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 872*f4e667ebSPrzemek Kitszel goto error_param; 873*f4e667ebSPrzemek Kitszel } 874*f4e667ebSPrzemek Kitszel 875*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vrk->vsi_id)) { 876*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 877*f4e667ebSPrzemek Kitszel goto error_param; 878*f4e667ebSPrzemek Kitszel } 879*f4e667ebSPrzemek Kitszel 880*f4e667ebSPrzemek Kitszel if (vrk->key_len != ICE_VSIQF_HKEY_ARRAY_SIZE) { 881*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 882*f4e667ebSPrzemek Kitszel goto error_param; 883*f4e667ebSPrzemek Kitszel } 884*f4e667ebSPrzemek Kitszel 885*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 886*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 887*f4e667ebSPrzemek Kitszel goto error_param; 888*f4e667ebSPrzemek Kitszel } 889*f4e667ebSPrzemek Kitszel 890*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 891*f4e667ebSPrzemek Kitszel if (!vsi) { 892*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 893*f4e667ebSPrzemek Kitszel goto error_param; 894*f4e667ebSPrzemek Kitszel } 895*f4e667ebSPrzemek Kitszel 896*f4e667ebSPrzemek Kitszel if (ice_set_rss_key(vsi, vrk->key)) 897*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 898*f4e667ebSPrzemek Kitszel error_param: 899*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_KEY, v_ret, 900*f4e667ebSPrzemek Kitszel NULL, 0); 901*f4e667ebSPrzemek Kitszel } 902*f4e667ebSPrzemek Kitszel 903*f4e667ebSPrzemek Kitszel /** 904*f4e667ebSPrzemek Kitszel * ice_vc_config_rss_lut 905*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 906*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 907*f4e667ebSPrzemek Kitszel * 908*f4e667ebSPrzemek Kitszel * Configure the VF's RSS LUT 909*f4e667ebSPrzemek Kitszel */ 910*f4e667ebSPrzemek Kitszel static int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg) 911*f4e667ebSPrzemek Kitszel { 912*f4e667ebSPrzemek Kitszel struct virtchnl_rss_lut *vrl = (struct virtchnl_rss_lut *)msg; 913*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 914*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 915*f4e667ebSPrzemek Kitszel 916*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 917*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 918*f4e667ebSPrzemek Kitszel goto error_param; 919*f4e667ebSPrzemek Kitszel } 920*f4e667ebSPrzemek Kitszel 921*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vrl->vsi_id)) { 922*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 923*f4e667ebSPrzemek Kitszel goto error_param; 924*f4e667ebSPrzemek Kitszel } 925*f4e667ebSPrzemek Kitszel 926*f4e667ebSPrzemek Kitszel if (vrl->lut_entries != ICE_LUT_VSI_SIZE) { 927*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 928*f4e667ebSPrzemek Kitszel goto error_param; 929*f4e667ebSPrzemek Kitszel } 930*f4e667ebSPrzemek Kitszel 931*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 932*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 933*f4e667ebSPrzemek Kitszel goto error_param; 934*f4e667ebSPrzemek Kitszel } 935*f4e667ebSPrzemek Kitszel 936*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 937*f4e667ebSPrzemek Kitszel if (!vsi) { 938*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 939*f4e667ebSPrzemek Kitszel goto error_param; 940*f4e667ebSPrzemek Kitszel } 941*f4e667ebSPrzemek Kitszel 942*f4e667ebSPrzemek Kitszel if (ice_set_rss_lut(vsi, vrl->lut, ICE_LUT_VSI_SIZE)) 943*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 944*f4e667ebSPrzemek Kitszel error_param: 945*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_LUT, v_ret, 946*f4e667ebSPrzemek Kitszel NULL, 0); 947*f4e667ebSPrzemek Kitszel } 948*f4e667ebSPrzemek Kitszel 949*f4e667ebSPrzemek Kitszel /** 950*f4e667ebSPrzemek Kitszel * ice_vc_config_rss_hfunc 951*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 952*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 953*f4e667ebSPrzemek Kitszel * 954*f4e667ebSPrzemek Kitszel * Configure the VF's RSS Hash function 955*f4e667ebSPrzemek Kitszel */ 956*f4e667ebSPrzemek Kitszel static int ice_vc_config_rss_hfunc(struct ice_vf *vf, u8 *msg) 957*f4e667ebSPrzemek Kitszel { 958*f4e667ebSPrzemek Kitszel struct virtchnl_rss_hfunc *vrh = (struct virtchnl_rss_hfunc *)msg; 959*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 960*f4e667ebSPrzemek Kitszel u8 hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; 961*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 962*f4e667ebSPrzemek Kitszel 963*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 964*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 965*f4e667ebSPrzemek Kitszel goto error_param; 966*f4e667ebSPrzemek Kitszel } 967*f4e667ebSPrzemek Kitszel 968*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vrh->vsi_id)) { 969*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 970*f4e667ebSPrzemek Kitszel goto error_param; 971*f4e667ebSPrzemek Kitszel } 972*f4e667ebSPrzemek Kitszel 973*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 974*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 975*f4e667ebSPrzemek Kitszel goto error_param; 976*f4e667ebSPrzemek Kitszel } 977*f4e667ebSPrzemek Kitszel 978*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 979*f4e667ebSPrzemek Kitszel if (!vsi) { 980*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 981*f4e667ebSPrzemek Kitszel goto error_param; 982*f4e667ebSPrzemek Kitszel } 983*f4e667ebSPrzemek Kitszel 984*f4e667ebSPrzemek Kitszel if (vrh->rss_algorithm == VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC) 985*f4e667ebSPrzemek Kitszel hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ; 986*f4e667ebSPrzemek Kitszel 987*f4e667ebSPrzemek Kitszel if (ice_set_rss_hfunc(vsi, hfunc)) 988*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 989*f4e667ebSPrzemek Kitszel error_param: 990*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_HFUNC, v_ret, 991*f4e667ebSPrzemek Kitszel NULL, 0); 992*f4e667ebSPrzemek Kitszel } 993*f4e667ebSPrzemek Kitszel 994*f4e667ebSPrzemek Kitszel /** 995*f4e667ebSPrzemek Kitszel * ice_vc_get_qos_caps - Get current QoS caps from PF 996*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 997*f4e667ebSPrzemek Kitszel * 998*f4e667ebSPrzemek Kitszel * Get VF's QoS capabilities, such as TC number, arbiter and 999*f4e667ebSPrzemek Kitszel * bandwidth from PF. 1000*f4e667ebSPrzemek Kitszel * 1001*f4e667ebSPrzemek Kitszel * Return: 0 on success or negative error value. 1002*f4e667ebSPrzemek Kitszel */ 1003*f4e667ebSPrzemek Kitszel static int ice_vc_get_qos_caps(struct ice_vf *vf) 1004*f4e667ebSPrzemek Kitszel { 1005*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1006*f4e667ebSPrzemek Kitszel struct virtchnl_qos_cap_list *cap_list = NULL; 1007*f4e667ebSPrzemek Kitszel u8 tc_prio[ICE_MAX_TRAFFIC_CLASS] = { 0 }; 1008*f4e667ebSPrzemek Kitszel struct virtchnl_qos_cap_elem *cfg = NULL; 1009*f4e667ebSPrzemek Kitszel struct ice_vsi_ctx *vsi_ctx; 1010*f4e667ebSPrzemek Kitszel struct ice_pf *pf = vf->pf; 1011*f4e667ebSPrzemek Kitszel struct ice_port_info *pi; 1012*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 1013*f4e667ebSPrzemek Kitszel u8 numtc, tc; 1014*f4e667ebSPrzemek Kitszel u16 len = 0; 1015*f4e667ebSPrzemek Kitszel int ret, i; 1016*f4e667ebSPrzemek Kitszel 1017*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1018*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1019*f4e667ebSPrzemek Kitszel goto err; 1020*f4e667ebSPrzemek Kitszel } 1021*f4e667ebSPrzemek Kitszel 1022*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 1023*f4e667ebSPrzemek Kitszel if (!vsi) { 1024*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1025*f4e667ebSPrzemek Kitszel goto err; 1026*f4e667ebSPrzemek Kitszel } 1027*f4e667ebSPrzemek Kitszel 1028*f4e667ebSPrzemek Kitszel pi = pf->hw.port_info; 1029*f4e667ebSPrzemek Kitszel numtc = vsi->tc_cfg.numtc; 1030*f4e667ebSPrzemek Kitszel 1031*f4e667ebSPrzemek Kitszel vsi_ctx = ice_get_vsi_ctx(pi->hw, vf->lan_vsi_idx); 1032*f4e667ebSPrzemek Kitszel if (!vsi_ctx) { 1033*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1034*f4e667ebSPrzemek Kitszel goto err; 1035*f4e667ebSPrzemek Kitszel } 1036*f4e667ebSPrzemek Kitszel 1037*f4e667ebSPrzemek Kitszel len = struct_size(cap_list, cap, numtc); 1038*f4e667ebSPrzemek Kitszel cap_list = kzalloc(len, GFP_KERNEL); 1039*f4e667ebSPrzemek Kitszel if (!cap_list) { 1040*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 1041*f4e667ebSPrzemek Kitszel len = 0; 1042*f4e667ebSPrzemek Kitszel goto err; 1043*f4e667ebSPrzemek Kitszel } 1044*f4e667ebSPrzemek Kitszel 1045*f4e667ebSPrzemek Kitszel cap_list->vsi_id = vsi->vsi_num; 1046*f4e667ebSPrzemek Kitszel cap_list->num_elem = numtc; 1047*f4e667ebSPrzemek Kitszel 1048*f4e667ebSPrzemek Kitszel /* Store the UP2TC configuration from DCB to a user priority bitmap 1049*f4e667ebSPrzemek Kitszel * of each TC. Each element of prio_of_tc represents one TC. Each 1050*f4e667ebSPrzemek Kitszel * bitmap indicates the user priorities belong to this TC. 1051*f4e667ebSPrzemek Kitszel */ 1052*f4e667ebSPrzemek Kitszel for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) { 1053*f4e667ebSPrzemek Kitszel tc = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[i]; 1054*f4e667ebSPrzemek Kitszel tc_prio[tc] |= BIT(i); 1055*f4e667ebSPrzemek Kitszel } 1056*f4e667ebSPrzemek Kitszel 1057*f4e667ebSPrzemek Kitszel for (i = 0; i < numtc; i++) { 1058*f4e667ebSPrzemek Kitszel cfg = &cap_list->cap[i]; 1059*f4e667ebSPrzemek Kitszel cfg->tc_num = i; 1060*f4e667ebSPrzemek Kitszel cfg->tc_prio = tc_prio[i]; 1061*f4e667ebSPrzemek Kitszel cfg->arbiter = pi->qos_cfg.local_dcbx_cfg.etscfg.tsatable[i]; 1062*f4e667ebSPrzemek Kitszel cfg->weight = VIRTCHNL_STRICT_WEIGHT; 1063*f4e667ebSPrzemek Kitszel cfg->type = VIRTCHNL_BW_SHAPER; 1064*f4e667ebSPrzemek Kitszel cfg->shaper.committed = vsi_ctx->sched.bw_t_info[i].cir_bw.bw; 1065*f4e667ebSPrzemek Kitszel cfg->shaper.peak = vsi_ctx->sched.bw_t_info[i].eir_bw.bw; 1066*f4e667ebSPrzemek Kitszel } 1067*f4e667ebSPrzemek Kitszel 1068*f4e667ebSPrzemek Kitszel err: 1069*f4e667ebSPrzemek Kitszel ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_QOS_CAPS, v_ret, 1070*f4e667ebSPrzemek Kitszel (u8 *)cap_list, len); 1071*f4e667ebSPrzemek Kitszel kfree(cap_list); 1072*f4e667ebSPrzemek Kitszel return ret; 1073*f4e667ebSPrzemek Kitszel } 1074*f4e667ebSPrzemek Kitszel 1075*f4e667ebSPrzemek Kitszel /** 1076*f4e667ebSPrzemek Kitszel * ice_vc_cfg_promiscuous_mode_msg 1077*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1078*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 1079*f4e667ebSPrzemek Kitszel * 1080*f4e667ebSPrzemek Kitszel * called from the VF to configure VF VSIs promiscuous mode 1081*f4e667ebSPrzemek Kitszel */ 1082*f4e667ebSPrzemek Kitszel static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg) 1083*f4e667ebSPrzemek Kitszel { 1084*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1085*f4e667ebSPrzemek Kitszel bool rm_promisc, alluni = false, allmulti = false; 1086*f4e667ebSPrzemek Kitszel struct virtchnl_promisc_info *info = 1087*f4e667ebSPrzemek Kitszel (struct virtchnl_promisc_info *)msg; 1088*f4e667ebSPrzemek Kitszel struct ice_vsi_vlan_ops *vlan_ops; 1089*f4e667ebSPrzemek Kitszel int mcast_err = 0, ucast_err = 0; 1090*f4e667ebSPrzemek Kitszel struct ice_pf *pf = vf->pf; 1091*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 1092*f4e667ebSPrzemek Kitszel u8 mcast_m, ucast_m; 1093*f4e667ebSPrzemek Kitszel struct device *dev; 1094*f4e667ebSPrzemek Kitszel int ret = 0; 1095*f4e667ebSPrzemek Kitszel 1096*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1097*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1098*f4e667ebSPrzemek Kitszel goto error_param; 1099*f4e667ebSPrzemek Kitszel } 1100*f4e667ebSPrzemek Kitszel 1101*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, info->vsi_id)) { 1102*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1103*f4e667ebSPrzemek Kitszel goto error_param; 1104*f4e667ebSPrzemek Kitszel } 1105*f4e667ebSPrzemek Kitszel 1106*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 1107*f4e667ebSPrzemek Kitszel if (!vsi) { 1108*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1109*f4e667ebSPrzemek Kitszel goto error_param; 1110*f4e667ebSPrzemek Kitszel } 1111*f4e667ebSPrzemek Kitszel 1112*f4e667ebSPrzemek Kitszel dev = ice_pf_to_dev(pf); 1113*f4e667ebSPrzemek Kitszel if (!ice_is_vf_trusted(vf)) { 1114*f4e667ebSPrzemek Kitszel dev_err(dev, "Unprivileged VF %d is attempting to configure promiscuous mode\n", 1115*f4e667ebSPrzemek Kitszel vf->vf_id); 1116*f4e667ebSPrzemek Kitszel /* Leave v_ret alone, lie to the VF on purpose. */ 1117*f4e667ebSPrzemek Kitszel goto error_param; 1118*f4e667ebSPrzemek Kitszel } 1119*f4e667ebSPrzemek Kitszel 1120*f4e667ebSPrzemek Kitszel if (info->flags & FLAG_VF_UNICAST_PROMISC) 1121*f4e667ebSPrzemek Kitszel alluni = true; 1122*f4e667ebSPrzemek Kitszel 1123*f4e667ebSPrzemek Kitszel if (info->flags & FLAG_VF_MULTICAST_PROMISC) 1124*f4e667ebSPrzemek Kitszel allmulti = true; 1125*f4e667ebSPrzemek Kitszel 1126*f4e667ebSPrzemek Kitszel rm_promisc = !allmulti && !alluni; 1127*f4e667ebSPrzemek Kitszel 1128*f4e667ebSPrzemek Kitszel vlan_ops = ice_get_compat_vsi_vlan_ops(vsi); 1129*f4e667ebSPrzemek Kitszel if (rm_promisc) 1130*f4e667ebSPrzemek Kitszel ret = vlan_ops->ena_rx_filtering(vsi); 1131*f4e667ebSPrzemek Kitszel else 1132*f4e667ebSPrzemek Kitszel ret = vlan_ops->dis_rx_filtering(vsi); 1133*f4e667ebSPrzemek Kitszel if (ret) { 1134*f4e667ebSPrzemek Kitszel dev_err(dev, "Failed to configure VLAN pruning in promiscuous mode\n"); 1135*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1136*f4e667ebSPrzemek Kitszel goto error_param; 1137*f4e667ebSPrzemek Kitszel } 1138*f4e667ebSPrzemek Kitszel 1139*f4e667ebSPrzemek Kitszel ice_vf_get_promisc_masks(vf, vsi, &ucast_m, &mcast_m); 1140*f4e667ebSPrzemek Kitszel 1141*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, pf->flags)) { 1142*f4e667ebSPrzemek Kitszel if (alluni) { 1143*f4e667ebSPrzemek Kitszel /* in this case we're turning on promiscuous mode */ 1144*f4e667ebSPrzemek Kitszel ret = ice_set_dflt_vsi(vsi); 1145*f4e667ebSPrzemek Kitszel } else { 1146*f4e667ebSPrzemek Kitszel /* in this case we're turning off promiscuous mode */ 1147*f4e667ebSPrzemek Kitszel if (ice_is_dflt_vsi_in_use(vsi->port_info)) 1148*f4e667ebSPrzemek Kitszel ret = ice_clear_dflt_vsi(vsi); 1149*f4e667ebSPrzemek Kitszel } 1150*f4e667ebSPrzemek Kitszel 1151*f4e667ebSPrzemek Kitszel /* in this case we're turning on/off only 1152*f4e667ebSPrzemek Kitszel * allmulticast 1153*f4e667ebSPrzemek Kitszel */ 1154*f4e667ebSPrzemek Kitszel if (allmulti) 1155*f4e667ebSPrzemek Kitszel mcast_err = ice_vf_set_vsi_promisc(vf, vsi, mcast_m); 1156*f4e667ebSPrzemek Kitszel else 1157*f4e667ebSPrzemek Kitszel mcast_err = ice_vf_clear_vsi_promisc(vf, vsi, mcast_m); 1158*f4e667ebSPrzemek Kitszel 1159*f4e667ebSPrzemek Kitszel if (ret) { 1160*f4e667ebSPrzemek Kitszel dev_err(dev, "Turning on/off promiscuous mode for VF %d failed, error: %d\n", 1161*f4e667ebSPrzemek Kitszel vf->vf_id, ret); 1162*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 1163*f4e667ebSPrzemek Kitszel goto error_param; 1164*f4e667ebSPrzemek Kitszel } 1165*f4e667ebSPrzemek Kitszel } else { 1166*f4e667ebSPrzemek Kitszel if (alluni) 1167*f4e667ebSPrzemek Kitszel ucast_err = ice_vf_set_vsi_promisc(vf, vsi, ucast_m); 1168*f4e667ebSPrzemek Kitszel else 1169*f4e667ebSPrzemek Kitszel ucast_err = ice_vf_clear_vsi_promisc(vf, vsi, ucast_m); 1170*f4e667ebSPrzemek Kitszel 1171*f4e667ebSPrzemek Kitszel if (allmulti) 1172*f4e667ebSPrzemek Kitszel mcast_err = ice_vf_set_vsi_promisc(vf, vsi, mcast_m); 1173*f4e667ebSPrzemek Kitszel else 1174*f4e667ebSPrzemek Kitszel mcast_err = ice_vf_clear_vsi_promisc(vf, vsi, mcast_m); 1175*f4e667ebSPrzemek Kitszel 1176*f4e667ebSPrzemek Kitszel if (ucast_err || mcast_err) 1177*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1178*f4e667ebSPrzemek Kitszel } 1179*f4e667ebSPrzemek Kitszel 1180*f4e667ebSPrzemek Kitszel if (!mcast_err) { 1181*f4e667ebSPrzemek Kitszel if (allmulti && 1182*f4e667ebSPrzemek Kitszel !test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) 1183*f4e667ebSPrzemek Kitszel dev_info(dev, "VF %u successfully set multicast promiscuous mode\n", 1184*f4e667ebSPrzemek Kitszel vf->vf_id); 1185*f4e667ebSPrzemek Kitszel else if (!allmulti && 1186*f4e667ebSPrzemek Kitszel test_and_clear_bit(ICE_VF_STATE_MC_PROMISC, 1187*f4e667ebSPrzemek Kitszel vf->vf_states)) 1188*f4e667ebSPrzemek Kitszel dev_info(dev, "VF %u successfully unset multicast promiscuous mode\n", 1189*f4e667ebSPrzemek Kitszel vf->vf_id); 1190*f4e667ebSPrzemek Kitszel } else { 1191*f4e667ebSPrzemek Kitszel dev_err(dev, "Error while modifying multicast promiscuous mode for VF %u, error: %d\n", 1192*f4e667ebSPrzemek Kitszel vf->vf_id, mcast_err); 1193*f4e667ebSPrzemek Kitszel } 1194*f4e667ebSPrzemek Kitszel 1195*f4e667ebSPrzemek Kitszel if (!ucast_err) { 1196*f4e667ebSPrzemek Kitszel if (alluni && 1197*f4e667ebSPrzemek Kitszel !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) 1198*f4e667ebSPrzemek Kitszel dev_info(dev, "VF %u successfully set unicast promiscuous mode\n", 1199*f4e667ebSPrzemek Kitszel vf->vf_id); 1200*f4e667ebSPrzemek Kitszel else if (!alluni && 1201*f4e667ebSPrzemek Kitszel test_and_clear_bit(ICE_VF_STATE_UC_PROMISC, 1202*f4e667ebSPrzemek Kitszel vf->vf_states)) 1203*f4e667ebSPrzemek Kitszel dev_info(dev, "VF %u successfully unset unicast promiscuous mode\n", 1204*f4e667ebSPrzemek Kitszel vf->vf_id); 1205*f4e667ebSPrzemek Kitszel } else { 1206*f4e667ebSPrzemek Kitszel dev_err(dev, "Error while modifying unicast promiscuous mode for VF %u, error: %d\n", 1207*f4e667ebSPrzemek Kitszel vf->vf_id, ucast_err); 1208*f4e667ebSPrzemek Kitszel } 1209*f4e667ebSPrzemek Kitszel 1210*f4e667ebSPrzemek Kitszel error_param: 1211*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, 1212*f4e667ebSPrzemek Kitszel v_ret, NULL, 0); 1213*f4e667ebSPrzemek Kitszel } 1214*f4e667ebSPrzemek Kitszel 1215*f4e667ebSPrzemek Kitszel /** 1216*f4e667ebSPrzemek Kitszel * ice_vc_get_stats_msg 1217*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1218*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 1219*f4e667ebSPrzemek Kitszel * 1220*f4e667ebSPrzemek Kitszel * called from the VF to get VSI stats 1221*f4e667ebSPrzemek Kitszel */ 1222*f4e667ebSPrzemek Kitszel static int ice_vc_get_stats_msg(struct ice_vf *vf, u8 *msg) 1223*f4e667ebSPrzemek Kitszel { 1224*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1225*f4e667ebSPrzemek Kitszel struct virtchnl_queue_select *vqs = 1226*f4e667ebSPrzemek Kitszel (struct virtchnl_queue_select *)msg; 1227*f4e667ebSPrzemek Kitszel struct ice_eth_stats stats = { 0 }; 1228*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 1229*f4e667ebSPrzemek Kitszel 1230*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1231*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1232*f4e667ebSPrzemek Kitszel goto error_param; 1233*f4e667ebSPrzemek Kitszel } 1234*f4e667ebSPrzemek Kitszel 1235*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vqs->vsi_id)) { 1236*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1237*f4e667ebSPrzemek Kitszel goto error_param; 1238*f4e667ebSPrzemek Kitszel } 1239*f4e667ebSPrzemek Kitszel 1240*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 1241*f4e667ebSPrzemek Kitszel if (!vsi) { 1242*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1243*f4e667ebSPrzemek Kitszel goto error_param; 1244*f4e667ebSPrzemek Kitszel } 1245*f4e667ebSPrzemek Kitszel 1246*f4e667ebSPrzemek Kitszel ice_update_eth_stats(vsi); 1247*f4e667ebSPrzemek Kitszel 1248*f4e667ebSPrzemek Kitszel stats = vsi->eth_stats; 1249*f4e667ebSPrzemek Kitszel 1250*f4e667ebSPrzemek Kitszel error_param: 1251*f4e667ebSPrzemek Kitszel /* send the response to the VF */ 1252*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_STATS, v_ret, 1253*f4e667ebSPrzemek Kitszel (u8 *)&stats, sizeof(stats)); 1254*f4e667ebSPrzemek Kitszel } 1255*f4e667ebSPrzemek Kitszel 1256*f4e667ebSPrzemek Kitszel /** 1257*f4e667ebSPrzemek Kitszel * ice_can_vf_change_mac 1258*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1259*f4e667ebSPrzemek Kitszel * 1260*f4e667ebSPrzemek Kitszel * Return true if the VF is allowed to change its MAC filters, false otherwise 1261*f4e667ebSPrzemek Kitszel */ 1262*f4e667ebSPrzemek Kitszel static bool ice_can_vf_change_mac(struct ice_vf *vf) 1263*f4e667ebSPrzemek Kitszel { 1264*f4e667ebSPrzemek Kitszel /* If the VF MAC address has been set administratively (via the 1265*f4e667ebSPrzemek Kitszel * ndo_set_vf_mac command), then deny permission to the VF to 1266*f4e667ebSPrzemek Kitszel * add/delete unicast MAC addresses, unless the VF is trusted 1267*f4e667ebSPrzemek Kitszel */ 1268*f4e667ebSPrzemek Kitszel if (vf->pf_set_mac && !ice_is_vf_trusted(vf)) 1269*f4e667ebSPrzemek Kitszel return false; 1270*f4e667ebSPrzemek Kitszel 1271*f4e667ebSPrzemek Kitszel return true; 1272*f4e667ebSPrzemek Kitszel } 1273*f4e667ebSPrzemek Kitszel 1274*f4e667ebSPrzemek Kitszel /** 1275*f4e667ebSPrzemek Kitszel * ice_vc_ether_addr_type - get type of virtchnl_ether_addr 1276*f4e667ebSPrzemek Kitszel * @vc_ether_addr: used to extract the type 1277*f4e667ebSPrzemek Kitszel */ 1278*f4e667ebSPrzemek Kitszel static u8 1279*f4e667ebSPrzemek Kitszel ice_vc_ether_addr_type(struct virtchnl_ether_addr *vc_ether_addr) 1280*f4e667ebSPrzemek Kitszel { 1281*f4e667ebSPrzemek Kitszel return (vc_ether_addr->type & VIRTCHNL_ETHER_ADDR_TYPE_MASK); 1282*f4e667ebSPrzemek Kitszel } 1283*f4e667ebSPrzemek Kitszel 1284*f4e667ebSPrzemek Kitszel /** 1285*f4e667ebSPrzemek Kitszel * ice_is_vc_addr_legacy - check if the MAC address is from an older VF 1286*f4e667ebSPrzemek Kitszel * @vc_ether_addr: VIRTCHNL structure that contains MAC and type 1287*f4e667ebSPrzemek Kitszel */ 1288*f4e667ebSPrzemek Kitszel static bool 1289*f4e667ebSPrzemek Kitszel ice_is_vc_addr_legacy(struct virtchnl_ether_addr *vc_ether_addr) 1290*f4e667ebSPrzemek Kitszel { 1291*f4e667ebSPrzemek Kitszel u8 type = ice_vc_ether_addr_type(vc_ether_addr); 1292*f4e667ebSPrzemek Kitszel 1293*f4e667ebSPrzemek Kitszel return (type == VIRTCHNL_ETHER_ADDR_LEGACY); 1294*f4e667ebSPrzemek Kitszel } 1295*f4e667ebSPrzemek Kitszel 1296*f4e667ebSPrzemek Kitszel /** 1297*f4e667ebSPrzemek Kitszel * ice_is_vc_addr_primary - check if the MAC address is the VF's primary MAC 1298*f4e667ebSPrzemek Kitszel * @vc_ether_addr: VIRTCHNL structure that contains MAC and type 1299*f4e667ebSPrzemek Kitszel * 1300*f4e667ebSPrzemek Kitszel * This function should only be called when the MAC address in 1301*f4e667ebSPrzemek Kitszel * virtchnl_ether_addr is a valid unicast MAC 1302*f4e667ebSPrzemek Kitszel */ 1303*f4e667ebSPrzemek Kitszel static bool 1304*f4e667ebSPrzemek Kitszel ice_is_vc_addr_primary(struct virtchnl_ether_addr __maybe_unused *vc_ether_addr) 1305*f4e667ebSPrzemek Kitszel { 1306*f4e667ebSPrzemek Kitszel u8 type = ice_vc_ether_addr_type(vc_ether_addr); 1307*f4e667ebSPrzemek Kitszel 1308*f4e667ebSPrzemek Kitszel return (type == VIRTCHNL_ETHER_ADDR_PRIMARY); 1309*f4e667ebSPrzemek Kitszel } 1310*f4e667ebSPrzemek Kitszel 1311*f4e667ebSPrzemek Kitszel /** 1312*f4e667ebSPrzemek Kitszel * ice_vfhw_mac_add - update the VF's cached hardware MAC if allowed 1313*f4e667ebSPrzemek Kitszel * @vf: VF to update 1314*f4e667ebSPrzemek Kitszel * @vc_ether_addr: structure from VIRTCHNL with MAC to add 1315*f4e667ebSPrzemek Kitszel */ 1316*f4e667ebSPrzemek Kitszel static void 1317*f4e667ebSPrzemek Kitszel ice_vfhw_mac_add(struct ice_vf *vf, struct virtchnl_ether_addr *vc_ether_addr) 1318*f4e667ebSPrzemek Kitszel { 1319*f4e667ebSPrzemek Kitszel u8 *mac_addr = vc_ether_addr->addr; 1320*f4e667ebSPrzemek Kitszel 1321*f4e667ebSPrzemek Kitszel if (!is_valid_ether_addr(mac_addr)) 1322*f4e667ebSPrzemek Kitszel return; 1323*f4e667ebSPrzemek Kitszel 1324*f4e667ebSPrzemek Kitszel /* only allow legacy VF drivers to set the device and hardware MAC if it 1325*f4e667ebSPrzemek Kitszel * is zero and allow new VF drivers to set the hardware MAC if the type 1326*f4e667ebSPrzemek Kitszel * was correctly specified over VIRTCHNL 1327*f4e667ebSPrzemek Kitszel */ 1328*f4e667ebSPrzemek Kitszel if ((ice_is_vc_addr_legacy(vc_ether_addr) && 1329*f4e667ebSPrzemek Kitszel is_zero_ether_addr(vf->hw_lan_addr)) || 1330*f4e667ebSPrzemek Kitszel ice_is_vc_addr_primary(vc_ether_addr)) { 1331*f4e667ebSPrzemek Kitszel ether_addr_copy(vf->dev_lan_addr, mac_addr); 1332*f4e667ebSPrzemek Kitszel ether_addr_copy(vf->hw_lan_addr, mac_addr); 1333*f4e667ebSPrzemek Kitszel } 1334*f4e667ebSPrzemek Kitszel 1335*f4e667ebSPrzemek Kitszel /* hardware and device MACs are already set, but its possible that the 1336*f4e667ebSPrzemek Kitszel * VF driver sent the VIRTCHNL_OP_ADD_ETH_ADDR message before the 1337*f4e667ebSPrzemek Kitszel * VIRTCHNL_OP_DEL_ETH_ADDR when trying to update its MAC, so save it 1338*f4e667ebSPrzemek Kitszel * away for the legacy VF driver case as it will be updated in the 1339*f4e667ebSPrzemek Kitszel * delete flow for this case 1340*f4e667ebSPrzemek Kitszel */ 1341*f4e667ebSPrzemek Kitszel if (ice_is_vc_addr_legacy(vc_ether_addr)) { 1342*f4e667ebSPrzemek Kitszel ether_addr_copy(vf->legacy_last_added_umac.addr, 1343*f4e667ebSPrzemek Kitszel mac_addr); 1344*f4e667ebSPrzemek Kitszel vf->legacy_last_added_umac.time_modified = jiffies; 1345*f4e667ebSPrzemek Kitszel } 1346*f4e667ebSPrzemek Kitszel } 1347*f4e667ebSPrzemek Kitszel 1348*f4e667ebSPrzemek Kitszel /** 1349*f4e667ebSPrzemek Kitszel * ice_is_mc_lldp_eth_addr - check if the given MAC is a multicast LLDP address 1350*f4e667ebSPrzemek Kitszel * @mac: address to check 1351*f4e667ebSPrzemek Kitszel * 1352*f4e667ebSPrzemek Kitszel * Return: true if the address is one of the three possible LLDP multicast 1353*f4e667ebSPrzemek Kitszel * addresses, false otherwise. 1354*f4e667ebSPrzemek Kitszel */ 1355*f4e667ebSPrzemek Kitszel static bool ice_is_mc_lldp_eth_addr(const u8 *mac) 1356*f4e667ebSPrzemek Kitszel { 1357*f4e667ebSPrzemek Kitszel const u8 lldp_mac_base[] = {0x01, 0x80, 0xc2, 0x00, 0x00}; 1358*f4e667ebSPrzemek Kitszel 1359*f4e667ebSPrzemek Kitszel if (memcmp(mac, lldp_mac_base, sizeof(lldp_mac_base))) 1360*f4e667ebSPrzemek Kitszel return false; 1361*f4e667ebSPrzemek Kitszel 1362*f4e667ebSPrzemek Kitszel return (mac[5] == 0x0e || mac[5] == 0x03 || mac[5] == 0x00); 1363*f4e667ebSPrzemek Kitszel } 1364*f4e667ebSPrzemek Kitszel 1365*f4e667ebSPrzemek Kitszel /** 1366*f4e667ebSPrzemek Kitszel * ice_vc_can_add_mac - check if the VF is allowed to add a given MAC 1367*f4e667ebSPrzemek Kitszel * @vf: a VF to add the address to 1368*f4e667ebSPrzemek Kitszel * @mac: address to check 1369*f4e667ebSPrzemek Kitszel * 1370*f4e667ebSPrzemek Kitszel * Return: true if the VF is allowed to add such MAC address, false otherwise. 1371*f4e667ebSPrzemek Kitszel */ 1372*f4e667ebSPrzemek Kitszel static bool ice_vc_can_add_mac(const struct ice_vf *vf, const u8 *mac) 1373*f4e667ebSPrzemek Kitszel { 1374*f4e667ebSPrzemek Kitszel struct device *dev = ice_pf_to_dev(vf->pf); 1375*f4e667ebSPrzemek Kitszel 1376*f4e667ebSPrzemek Kitszel if (is_unicast_ether_addr(mac) && 1377*f4e667ebSPrzemek Kitszel !ice_can_vf_change_mac((struct ice_vf *)vf)) { 1378*f4e667ebSPrzemek Kitszel dev_err(dev, 1379*f4e667ebSPrzemek Kitszel "VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n"); 1380*f4e667ebSPrzemek Kitszel return false; 1381*f4e667ebSPrzemek Kitszel } 1382*f4e667ebSPrzemek Kitszel 1383*f4e667ebSPrzemek Kitszel if (!vf->trusted && ice_is_mc_lldp_eth_addr(mac)) { 1384*f4e667ebSPrzemek Kitszel dev_warn(dev, 1385*f4e667ebSPrzemek Kitszel "An untrusted VF %u is attempting to configure an LLDP multicast address\n", 1386*f4e667ebSPrzemek Kitszel vf->vf_id); 1387*f4e667ebSPrzemek Kitszel return false; 1388*f4e667ebSPrzemek Kitszel } 1389*f4e667ebSPrzemek Kitszel 1390*f4e667ebSPrzemek Kitszel return true; 1391*f4e667ebSPrzemek Kitszel } 1392*f4e667ebSPrzemek Kitszel 1393*f4e667ebSPrzemek Kitszel /** 1394*f4e667ebSPrzemek Kitszel * ice_vc_add_mac_addr - attempt to add the MAC address passed in 1395*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1396*f4e667ebSPrzemek Kitszel * @vsi: pointer to the VF's VSI 1397*f4e667ebSPrzemek Kitszel * @vc_ether_addr: VIRTCHNL MAC address structure used to add MAC 1398*f4e667ebSPrzemek Kitszel */ 1399*f4e667ebSPrzemek Kitszel static int 1400*f4e667ebSPrzemek Kitszel ice_vc_add_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi, 1401*f4e667ebSPrzemek Kitszel struct virtchnl_ether_addr *vc_ether_addr) 1402*f4e667ebSPrzemek Kitszel { 1403*f4e667ebSPrzemek Kitszel struct device *dev = ice_pf_to_dev(vf->pf); 1404*f4e667ebSPrzemek Kitszel u8 *mac_addr = vc_ether_addr->addr; 1405*f4e667ebSPrzemek Kitszel int ret; 1406*f4e667ebSPrzemek Kitszel 1407*f4e667ebSPrzemek Kitszel /* device MAC already added */ 1408*f4e667ebSPrzemek Kitszel if (ether_addr_equal(mac_addr, vf->dev_lan_addr)) 1409*f4e667ebSPrzemek Kitszel return 0; 1410*f4e667ebSPrzemek Kitszel 1411*f4e667ebSPrzemek Kitszel if (!ice_vc_can_add_mac(vf, mac_addr)) 1412*f4e667ebSPrzemek Kitszel return -EPERM; 1413*f4e667ebSPrzemek Kitszel 1414*f4e667ebSPrzemek Kitszel ret = ice_fltr_add_mac(vsi, mac_addr, ICE_FWD_TO_VSI); 1415*f4e667ebSPrzemek Kitszel if (ret == -EEXIST) { 1416*f4e667ebSPrzemek Kitszel dev_dbg(dev, "MAC %pM already exists for VF %d\n", mac_addr, 1417*f4e667ebSPrzemek Kitszel vf->vf_id); 1418*f4e667ebSPrzemek Kitszel /* don't return since we might need to update 1419*f4e667ebSPrzemek Kitszel * the primary MAC in ice_vfhw_mac_add() below 1420*f4e667ebSPrzemek Kitszel */ 1421*f4e667ebSPrzemek Kitszel } else if (ret) { 1422*f4e667ebSPrzemek Kitszel dev_err(dev, "Failed to add MAC %pM for VF %d\n, error %d\n", 1423*f4e667ebSPrzemek Kitszel mac_addr, vf->vf_id, ret); 1424*f4e667ebSPrzemek Kitszel return ret; 1425*f4e667ebSPrzemek Kitszel } else { 1426*f4e667ebSPrzemek Kitszel vf->num_mac++; 1427*f4e667ebSPrzemek Kitszel if (ice_is_mc_lldp_eth_addr(mac_addr)) 1428*f4e667ebSPrzemek Kitszel ice_vf_update_mac_lldp_num(vf, vsi, true); 1429*f4e667ebSPrzemek Kitszel } 1430*f4e667ebSPrzemek Kitszel 1431*f4e667ebSPrzemek Kitszel ice_vfhw_mac_add(vf, vc_ether_addr); 1432*f4e667ebSPrzemek Kitszel 1433*f4e667ebSPrzemek Kitszel return ret; 1434*f4e667ebSPrzemek Kitszel } 1435*f4e667ebSPrzemek Kitszel 1436*f4e667ebSPrzemek Kitszel /** 1437*f4e667ebSPrzemek Kitszel * ice_is_legacy_umac_expired - check if last added legacy unicast MAC expired 1438*f4e667ebSPrzemek Kitszel * @last_added_umac: structure used to check expiration 1439*f4e667ebSPrzemek Kitszel */ 1440*f4e667ebSPrzemek Kitszel static bool ice_is_legacy_umac_expired(struct ice_time_mac *last_added_umac) 1441*f4e667ebSPrzemek Kitszel { 1442*f4e667ebSPrzemek Kitszel #define ICE_LEGACY_VF_MAC_CHANGE_EXPIRE_TIME msecs_to_jiffies(3000) 1443*f4e667ebSPrzemek Kitszel return time_is_before_jiffies(last_added_umac->time_modified + 1444*f4e667ebSPrzemek Kitszel ICE_LEGACY_VF_MAC_CHANGE_EXPIRE_TIME); 1445*f4e667ebSPrzemek Kitszel } 1446*f4e667ebSPrzemek Kitszel 1447*f4e667ebSPrzemek Kitszel /** 1448*f4e667ebSPrzemek Kitszel * ice_update_legacy_cached_mac - update cached hardware MAC for legacy VF 1449*f4e667ebSPrzemek Kitszel * @vf: VF to update 1450*f4e667ebSPrzemek Kitszel * @vc_ether_addr: structure from VIRTCHNL with MAC to check 1451*f4e667ebSPrzemek Kitszel * 1452*f4e667ebSPrzemek Kitszel * only update cached hardware MAC for legacy VF drivers on delete 1453*f4e667ebSPrzemek Kitszel * because we cannot guarantee order/type of MAC from the VF driver 1454*f4e667ebSPrzemek Kitszel */ 1455*f4e667ebSPrzemek Kitszel static void 1456*f4e667ebSPrzemek Kitszel ice_update_legacy_cached_mac(struct ice_vf *vf, 1457*f4e667ebSPrzemek Kitszel struct virtchnl_ether_addr *vc_ether_addr) 1458*f4e667ebSPrzemek Kitszel { 1459*f4e667ebSPrzemek Kitszel if (!ice_is_vc_addr_legacy(vc_ether_addr) || 1460*f4e667ebSPrzemek Kitszel ice_is_legacy_umac_expired(&vf->legacy_last_added_umac)) 1461*f4e667ebSPrzemek Kitszel return; 1462*f4e667ebSPrzemek Kitszel 1463*f4e667ebSPrzemek Kitszel ether_addr_copy(vf->dev_lan_addr, vf->legacy_last_added_umac.addr); 1464*f4e667ebSPrzemek Kitszel ether_addr_copy(vf->hw_lan_addr, vf->legacy_last_added_umac.addr); 1465*f4e667ebSPrzemek Kitszel } 1466*f4e667ebSPrzemek Kitszel 1467*f4e667ebSPrzemek Kitszel /** 1468*f4e667ebSPrzemek Kitszel * ice_vfhw_mac_del - update the VF's cached hardware MAC if allowed 1469*f4e667ebSPrzemek Kitszel * @vf: VF to update 1470*f4e667ebSPrzemek Kitszel * @vc_ether_addr: structure from VIRTCHNL with MAC to delete 1471*f4e667ebSPrzemek Kitszel */ 1472*f4e667ebSPrzemek Kitszel static void 1473*f4e667ebSPrzemek Kitszel ice_vfhw_mac_del(struct ice_vf *vf, struct virtchnl_ether_addr *vc_ether_addr) 1474*f4e667ebSPrzemek Kitszel { 1475*f4e667ebSPrzemek Kitszel u8 *mac_addr = vc_ether_addr->addr; 1476*f4e667ebSPrzemek Kitszel 1477*f4e667ebSPrzemek Kitszel if (!is_valid_ether_addr(mac_addr) || 1478*f4e667ebSPrzemek Kitszel !ether_addr_equal(vf->dev_lan_addr, mac_addr)) 1479*f4e667ebSPrzemek Kitszel return; 1480*f4e667ebSPrzemek Kitszel 1481*f4e667ebSPrzemek Kitszel /* allow the device MAC to be repopulated in the add flow and don't 1482*f4e667ebSPrzemek Kitszel * clear the hardware MAC (i.e. hw_lan_addr) here as that is meant 1483*f4e667ebSPrzemek Kitszel * to be persistent on VM reboot and across driver unload/load, which 1484*f4e667ebSPrzemek Kitszel * won't work if we clear the hardware MAC here 1485*f4e667ebSPrzemek Kitszel */ 1486*f4e667ebSPrzemek Kitszel eth_zero_addr(vf->dev_lan_addr); 1487*f4e667ebSPrzemek Kitszel 1488*f4e667ebSPrzemek Kitszel ice_update_legacy_cached_mac(vf, vc_ether_addr); 1489*f4e667ebSPrzemek Kitszel } 1490*f4e667ebSPrzemek Kitszel 1491*f4e667ebSPrzemek Kitszel /** 1492*f4e667ebSPrzemek Kitszel * ice_vc_del_mac_addr - attempt to delete the MAC address passed in 1493*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1494*f4e667ebSPrzemek Kitszel * @vsi: pointer to the VF's VSI 1495*f4e667ebSPrzemek Kitszel * @vc_ether_addr: VIRTCHNL MAC address structure used to delete MAC 1496*f4e667ebSPrzemek Kitszel */ 1497*f4e667ebSPrzemek Kitszel static int 1498*f4e667ebSPrzemek Kitszel ice_vc_del_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi, 1499*f4e667ebSPrzemek Kitszel struct virtchnl_ether_addr *vc_ether_addr) 1500*f4e667ebSPrzemek Kitszel { 1501*f4e667ebSPrzemek Kitszel struct device *dev = ice_pf_to_dev(vf->pf); 1502*f4e667ebSPrzemek Kitszel u8 *mac_addr = vc_ether_addr->addr; 1503*f4e667ebSPrzemek Kitszel int status; 1504*f4e667ebSPrzemek Kitszel 1505*f4e667ebSPrzemek Kitszel if (!ice_can_vf_change_mac(vf) && 1506*f4e667ebSPrzemek Kitszel ether_addr_equal(vf->dev_lan_addr, mac_addr)) 1507*f4e667ebSPrzemek Kitszel return 0; 1508*f4e667ebSPrzemek Kitszel 1509*f4e667ebSPrzemek Kitszel status = ice_fltr_remove_mac(vsi, mac_addr, ICE_FWD_TO_VSI); 1510*f4e667ebSPrzemek Kitszel if (status == -ENOENT) { 1511*f4e667ebSPrzemek Kitszel dev_err(dev, "MAC %pM does not exist for VF %d\n", mac_addr, 1512*f4e667ebSPrzemek Kitszel vf->vf_id); 1513*f4e667ebSPrzemek Kitszel return -ENOENT; 1514*f4e667ebSPrzemek Kitszel } else if (status) { 1515*f4e667ebSPrzemek Kitszel dev_err(dev, "Failed to delete MAC %pM for VF %d, error %d\n", 1516*f4e667ebSPrzemek Kitszel mac_addr, vf->vf_id, status); 1517*f4e667ebSPrzemek Kitszel return -EIO; 1518*f4e667ebSPrzemek Kitszel } 1519*f4e667ebSPrzemek Kitszel 1520*f4e667ebSPrzemek Kitszel ice_vfhw_mac_del(vf, vc_ether_addr); 1521*f4e667ebSPrzemek Kitszel 1522*f4e667ebSPrzemek Kitszel vf->num_mac--; 1523*f4e667ebSPrzemek Kitszel if (ice_is_mc_lldp_eth_addr(mac_addr)) 1524*f4e667ebSPrzemek Kitszel ice_vf_update_mac_lldp_num(vf, vsi, false); 1525*f4e667ebSPrzemek Kitszel 1526*f4e667ebSPrzemek Kitszel return 0; 1527*f4e667ebSPrzemek Kitszel } 1528*f4e667ebSPrzemek Kitszel 1529*f4e667ebSPrzemek Kitszel /** 1530*f4e667ebSPrzemek Kitszel * ice_vc_handle_mac_addr_msg 1531*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1532*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 1533*f4e667ebSPrzemek Kitszel * @set: true if MAC filters are being set, false otherwise 1534*f4e667ebSPrzemek Kitszel * 1535*f4e667ebSPrzemek Kitszel * add guest MAC address filter 1536*f4e667ebSPrzemek Kitszel */ 1537*f4e667ebSPrzemek Kitszel static int 1538*f4e667ebSPrzemek Kitszel ice_vc_handle_mac_addr_msg(struct ice_vf *vf, u8 *msg, bool set) 1539*f4e667ebSPrzemek Kitszel { 1540*f4e667ebSPrzemek Kitszel int (*ice_vc_cfg_mac) 1541*f4e667ebSPrzemek Kitszel (struct ice_vf *vf, struct ice_vsi *vsi, 1542*f4e667ebSPrzemek Kitszel struct virtchnl_ether_addr *virtchnl_ether_addr); 1543*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1544*f4e667ebSPrzemek Kitszel struct virtchnl_ether_addr_list *al = 1545*f4e667ebSPrzemek Kitszel (struct virtchnl_ether_addr_list *)msg; 1546*f4e667ebSPrzemek Kitszel struct ice_pf *pf = vf->pf; 1547*f4e667ebSPrzemek Kitszel enum virtchnl_ops vc_op; 1548*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 1549*f4e667ebSPrzemek Kitszel int i; 1550*f4e667ebSPrzemek Kitszel 1551*f4e667ebSPrzemek Kitszel if (set) { 1552*f4e667ebSPrzemek Kitszel vc_op = VIRTCHNL_OP_ADD_ETH_ADDR; 1553*f4e667ebSPrzemek Kitszel ice_vc_cfg_mac = ice_vc_add_mac_addr; 1554*f4e667ebSPrzemek Kitszel } else { 1555*f4e667ebSPrzemek Kitszel vc_op = VIRTCHNL_OP_DEL_ETH_ADDR; 1556*f4e667ebSPrzemek Kitszel ice_vc_cfg_mac = ice_vc_del_mac_addr; 1557*f4e667ebSPrzemek Kitszel } 1558*f4e667ebSPrzemek Kitszel 1559*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) || 1560*f4e667ebSPrzemek Kitszel !ice_vc_isvalid_vsi_id(vf, al->vsi_id)) { 1561*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1562*f4e667ebSPrzemek Kitszel goto handle_mac_exit; 1563*f4e667ebSPrzemek Kitszel } 1564*f4e667ebSPrzemek Kitszel 1565*f4e667ebSPrzemek Kitszel /* If this VF is not privileged, then we can't add more than a 1566*f4e667ebSPrzemek Kitszel * limited number of addresses. Check to make sure that the 1567*f4e667ebSPrzemek Kitszel * additions do not push us over the limit. 1568*f4e667ebSPrzemek Kitszel */ 1569*f4e667ebSPrzemek Kitszel if (set && !ice_is_vf_trusted(vf) && 1570*f4e667ebSPrzemek Kitszel (vf->num_mac + al->num_elements) > ICE_MAX_MACADDR_PER_VF) { 1571*f4e667ebSPrzemek Kitszel dev_err(ice_pf_to_dev(pf), "Can't add more MAC addresses, because VF-%d is not trusted, switch the VF to trusted mode in order to add more functionalities\n", 1572*f4e667ebSPrzemek Kitszel vf->vf_id); 1573*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1574*f4e667ebSPrzemek Kitszel goto handle_mac_exit; 1575*f4e667ebSPrzemek Kitszel } 1576*f4e667ebSPrzemek Kitszel 1577*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 1578*f4e667ebSPrzemek Kitszel if (!vsi) { 1579*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1580*f4e667ebSPrzemek Kitszel goto handle_mac_exit; 1581*f4e667ebSPrzemek Kitszel } 1582*f4e667ebSPrzemek Kitszel 1583*f4e667ebSPrzemek Kitszel for (i = 0; i < al->num_elements; i++) { 1584*f4e667ebSPrzemek Kitszel u8 *mac_addr = al->list[i].addr; 1585*f4e667ebSPrzemek Kitszel int result; 1586*f4e667ebSPrzemek Kitszel 1587*f4e667ebSPrzemek Kitszel if (is_broadcast_ether_addr(mac_addr) || 1588*f4e667ebSPrzemek Kitszel is_zero_ether_addr(mac_addr)) 1589*f4e667ebSPrzemek Kitszel continue; 1590*f4e667ebSPrzemek Kitszel 1591*f4e667ebSPrzemek Kitszel result = ice_vc_cfg_mac(vf, vsi, &al->list[i]); 1592*f4e667ebSPrzemek Kitszel if (result == -EEXIST || result == -ENOENT) { 1593*f4e667ebSPrzemek Kitszel continue; 1594*f4e667ebSPrzemek Kitszel } else if (result) { 1595*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR; 1596*f4e667ebSPrzemek Kitszel goto handle_mac_exit; 1597*f4e667ebSPrzemek Kitszel } 1598*f4e667ebSPrzemek Kitszel } 1599*f4e667ebSPrzemek Kitszel 1600*f4e667ebSPrzemek Kitszel handle_mac_exit: 1601*f4e667ebSPrzemek Kitszel /* send the response to the VF */ 1602*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, vc_op, v_ret, NULL, 0); 1603*f4e667ebSPrzemek Kitszel } 1604*f4e667ebSPrzemek Kitszel 1605*f4e667ebSPrzemek Kitszel /** 1606*f4e667ebSPrzemek Kitszel * ice_vc_add_mac_addr_msg 1607*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1608*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 1609*f4e667ebSPrzemek Kitszel * 1610*f4e667ebSPrzemek Kitszel * add guest MAC address filter 1611*f4e667ebSPrzemek Kitszel */ 1612*f4e667ebSPrzemek Kitszel static int ice_vc_add_mac_addr_msg(struct ice_vf *vf, u8 *msg) 1613*f4e667ebSPrzemek Kitszel { 1614*f4e667ebSPrzemek Kitszel return ice_vc_handle_mac_addr_msg(vf, msg, true); 1615*f4e667ebSPrzemek Kitszel } 1616*f4e667ebSPrzemek Kitszel 1617*f4e667ebSPrzemek Kitszel /** 1618*f4e667ebSPrzemek Kitszel * ice_vc_del_mac_addr_msg 1619*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1620*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 1621*f4e667ebSPrzemek Kitszel * 1622*f4e667ebSPrzemek Kitszel * remove guest MAC address filter 1623*f4e667ebSPrzemek Kitszel */ 1624*f4e667ebSPrzemek Kitszel static int ice_vc_del_mac_addr_msg(struct ice_vf *vf, u8 *msg) 1625*f4e667ebSPrzemek Kitszel { 1626*f4e667ebSPrzemek Kitszel return ice_vc_handle_mac_addr_msg(vf, msg, false); 1627*f4e667ebSPrzemek Kitszel } 1628*f4e667ebSPrzemek Kitszel 1629*f4e667ebSPrzemek Kitszel /** 1630*f4e667ebSPrzemek Kitszel * ice_vf_vlan_offload_ena - determine if capabilities support VLAN offloads 1631*f4e667ebSPrzemek Kitszel * @caps: VF driver negotiated capabilities 1632*f4e667ebSPrzemek Kitszel * 1633*f4e667ebSPrzemek Kitszel * Return true if VIRTCHNL_VF_OFFLOAD_VLAN capability is set, else return false 1634*f4e667ebSPrzemek Kitszel */ 1635*f4e667ebSPrzemek Kitszel static bool ice_vf_vlan_offload_ena(u32 caps) 1636*f4e667ebSPrzemek Kitszel { 1637*f4e667ebSPrzemek Kitszel return !!(caps & VIRTCHNL_VF_OFFLOAD_VLAN); 1638*f4e667ebSPrzemek Kitszel } 1639*f4e667ebSPrzemek Kitszel 1640*f4e667ebSPrzemek Kitszel /** 1641*f4e667ebSPrzemek Kitszel * ice_is_vlan_promisc_allowed - check if VLAN promiscuous config is allowed 1642*f4e667ebSPrzemek Kitszel * @vf: VF used to determine if VLAN promiscuous config is allowed 1643*f4e667ebSPrzemek Kitszel */ 1644*f4e667ebSPrzemek Kitszel bool ice_is_vlan_promisc_allowed(struct ice_vf *vf) 1645*f4e667ebSPrzemek Kitszel { 1646*f4e667ebSPrzemek Kitszel if ((test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states) || 1647*f4e667ebSPrzemek Kitszel test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) && 1648*f4e667ebSPrzemek Kitszel test_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, vf->pf->flags)) 1649*f4e667ebSPrzemek Kitszel return true; 1650*f4e667ebSPrzemek Kitszel 1651*f4e667ebSPrzemek Kitszel return false; 1652*f4e667ebSPrzemek Kitszel } 1653*f4e667ebSPrzemek Kitszel 1654*f4e667ebSPrzemek Kitszel /** 1655*f4e667ebSPrzemek Kitszel * ice_vf_ena_vlan_promisc - Enable Tx/Rx VLAN promiscuous for the VLAN 1656*f4e667ebSPrzemek Kitszel * @vf: VF to enable VLAN promisc on 1657*f4e667ebSPrzemek Kitszel * @vsi: VF's VSI used to enable VLAN promiscuous mode 1658*f4e667ebSPrzemek Kitszel * @vlan: VLAN used to enable VLAN promiscuous 1659*f4e667ebSPrzemek Kitszel * 1660*f4e667ebSPrzemek Kitszel * This function should only be called if VLAN promiscuous mode is allowed, 1661*f4e667ebSPrzemek Kitszel * which can be determined via ice_is_vlan_promisc_allowed(). 1662*f4e667ebSPrzemek Kitszel */ 1663*f4e667ebSPrzemek Kitszel int ice_vf_ena_vlan_promisc(struct ice_vf *vf, struct ice_vsi *vsi, 1664*f4e667ebSPrzemek Kitszel struct ice_vlan *vlan) 1665*f4e667ebSPrzemek Kitszel { 1666*f4e667ebSPrzemek Kitszel u8 promisc_m = 0; 1667*f4e667ebSPrzemek Kitszel int status; 1668*f4e667ebSPrzemek Kitszel 1669*f4e667ebSPrzemek Kitszel if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) 1670*f4e667ebSPrzemek Kitszel promisc_m |= ICE_UCAST_VLAN_PROMISC_BITS; 1671*f4e667ebSPrzemek Kitszel if (test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) 1672*f4e667ebSPrzemek Kitszel promisc_m |= ICE_MCAST_VLAN_PROMISC_BITS; 1673*f4e667ebSPrzemek Kitszel 1674*f4e667ebSPrzemek Kitszel if (!promisc_m) 1675*f4e667ebSPrzemek Kitszel return 0; 1676*f4e667ebSPrzemek Kitszel 1677*f4e667ebSPrzemek Kitszel status = ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx, promisc_m, 1678*f4e667ebSPrzemek Kitszel vlan->vid); 1679*f4e667ebSPrzemek Kitszel if (status && status != -EEXIST) 1680*f4e667ebSPrzemek Kitszel return status; 1681*f4e667ebSPrzemek Kitszel 1682*f4e667ebSPrzemek Kitszel return 0; 1683*f4e667ebSPrzemek Kitszel } 1684*f4e667ebSPrzemek Kitszel 1685*f4e667ebSPrzemek Kitszel /** 1686*f4e667ebSPrzemek Kitszel * ice_vf_dis_vlan_promisc - Disable Tx/Rx VLAN promiscuous for the VLAN 1687*f4e667ebSPrzemek Kitszel * @vsi: VF's VSI used to disable VLAN promiscuous mode for 1688*f4e667ebSPrzemek Kitszel * @vlan: VLAN used to disable VLAN promiscuous 1689*f4e667ebSPrzemek Kitszel * 1690*f4e667ebSPrzemek Kitszel * This function should only be called if VLAN promiscuous mode is allowed, 1691*f4e667ebSPrzemek Kitszel * which can be determined via ice_is_vlan_promisc_allowed(). 1692*f4e667ebSPrzemek Kitszel */ 1693*f4e667ebSPrzemek Kitszel static int ice_vf_dis_vlan_promisc(struct ice_vsi *vsi, struct ice_vlan *vlan) 1694*f4e667ebSPrzemek Kitszel { 1695*f4e667ebSPrzemek Kitszel u8 promisc_m = ICE_UCAST_VLAN_PROMISC_BITS | ICE_MCAST_VLAN_PROMISC_BITS; 1696*f4e667ebSPrzemek Kitszel int status; 1697*f4e667ebSPrzemek Kitszel 1698*f4e667ebSPrzemek Kitszel status = ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx, promisc_m, 1699*f4e667ebSPrzemek Kitszel vlan->vid); 1700*f4e667ebSPrzemek Kitszel if (status && status != -ENOENT) 1701*f4e667ebSPrzemek Kitszel return status; 1702*f4e667ebSPrzemek Kitszel 1703*f4e667ebSPrzemek Kitszel return 0; 1704*f4e667ebSPrzemek Kitszel } 1705*f4e667ebSPrzemek Kitszel 1706*f4e667ebSPrzemek Kitszel /** 1707*f4e667ebSPrzemek Kitszel * ice_vf_has_max_vlans - check if VF already has the max allowed VLAN filters 1708*f4e667ebSPrzemek Kitszel * @vf: VF to check against 1709*f4e667ebSPrzemek Kitszel * @vsi: VF's VSI 1710*f4e667ebSPrzemek Kitszel * 1711*f4e667ebSPrzemek Kitszel * If the VF is trusted then the VF is allowed to add as many VLANs as it 1712*f4e667ebSPrzemek Kitszel * wants to, so return false. 1713*f4e667ebSPrzemek Kitszel * 1714*f4e667ebSPrzemek Kitszel * When the VF is untrusted compare the number of non-zero VLANs + 1 to the max 1715*f4e667ebSPrzemek Kitszel * allowed VLANs for an untrusted VF. Return the result of this comparison. 1716*f4e667ebSPrzemek Kitszel */ 1717*f4e667ebSPrzemek Kitszel static bool ice_vf_has_max_vlans(struct ice_vf *vf, struct ice_vsi *vsi) 1718*f4e667ebSPrzemek Kitszel { 1719*f4e667ebSPrzemek Kitszel if (ice_is_vf_trusted(vf)) 1720*f4e667ebSPrzemek Kitszel return false; 1721*f4e667ebSPrzemek Kitszel 1722*f4e667ebSPrzemek Kitszel #define ICE_VF_ADDED_VLAN_ZERO_FLTRS 1 1723*f4e667ebSPrzemek Kitszel return ((ice_vsi_num_non_zero_vlans(vsi) + 1724*f4e667ebSPrzemek Kitszel ICE_VF_ADDED_VLAN_ZERO_FLTRS) >= ICE_MAX_VLAN_PER_VF); 1725*f4e667ebSPrzemek Kitszel } 1726*f4e667ebSPrzemek Kitszel 1727*f4e667ebSPrzemek Kitszel /** 1728*f4e667ebSPrzemek Kitszel * ice_vc_process_vlan_msg 1729*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1730*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 1731*f4e667ebSPrzemek Kitszel * @add_v: Add VLAN if true, otherwise delete VLAN 1732*f4e667ebSPrzemek Kitszel * 1733*f4e667ebSPrzemek Kitszel * Process virtchnl op to add or remove programmed guest VLAN ID 1734*f4e667ebSPrzemek Kitszel */ 1735*f4e667ebSPrzemek Kitszel static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v) 1736*f4e667ebSPrzemek Kitszel { 1737*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1738*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter_list *vfl = 1739*f4e667ebSPrzemek Kitszel (struct virtchnl_vlan_filter_list *)msg; 1740*f4e667ebSPrzemek Kitszel struct ice_pf *pf = vf->pf; 1741*f4e667ebSPrzemek Kitszel bool vlan_promisc = false; 1742*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 1743*f4e667ebSPrzemek Kitszel struct device *dev; 1744*f4e667ebSPrzemek Kitszel int status = 0; 1745*f4e667ebSPrzemek Kitszel int i; 1746*f4e667ebSPrzemek Kitszel 1747*f4e667ebSPrzemek Kitszel dev = ice_pf_to_dev(pf); 1748*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1749*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1750*f4e667ebSPrzemek Kitszel goto error_param; 1751*f4e667ebSPrzemek Kitszel } 1752*f4e667ebSPrzemek Kitszel 1753*f4e667ebSPrzemek Kitszel if (!ice_vf_vlan_offload_ena(vf->driver_caps)) { 1754*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1755*f4e667ebSPrzemek Kitszel goto error_param; 1756*f4e667ebSPrzemek Kitszel } 1757*f4e667ebSPrzemek Kitszel 1758*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vfl->vsi_id)) { 1759*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1760*f4e667ebSPrzemek Kitszel goto error_param; 1761*f4e667ebSPrzemek Kitszel } 1762*f4e667ebSPrzemek Kitszel 1763*f4e667ebSPrzemek Kitszel for (i = 0; i < vfl->num_elements; i++) { 1764*f4e667ebSPrzemek Kitszel if (vfl->vlan_id[i] >= VLAN_N_VID) { 1765*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1766*f4e667ebSPrzemek Kitszel dev_err(dev, "invalid VF VLAN id %d\n", 1767*f4e667ebSPrzemek Kitszel vfl->vlan_id[i]); 1768*f4e667ebSPrzemek Kitszel goto error_param; 1769*f4e667ebSPrzemek Kitszel } 1770*f4e667ebSPrzemek Kitszel } 1771*f4e667ebSPrzemek Kitszel 1772*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 1773*f4e667ebSPrzemek Kitszel if (!vsi) { 1774*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1775*f4e667ebSPrzemek Kitszel goto error_param; 1776*f4e667ebSPrzemek Kitszel } 1777*f4e667ebSPrzemek Kitszel 1778*f4e667ebSPrzemek Kitszel if (add_v && ice_vf_has_max_vlans(vf, vsi)) { 1779*f4e667ebSPrzemek Kitszel dev_info(dev, "VF-%d is not trusted, switch the VF to trusted mode, in order to add more VLAN addresses\n", 1780*f4e667ebSPrzemek Kitszel vf->vf_id); 1781*f4e667ebSPrzemek Kitszel /* There is no need to let VF know about being not trusted, 1782*f4e667ebSPrzemek Kitszel * so we can just return success message here 1783*f4e667ebSPrzemek Kitszel */ 1784*f4e667ebSPrzemek Kitszel goto error_param; 1785*f4e667ebSPrzemek Kitszel } 1786*f4e667ebSPrzemek Kitszel 1787*f4e667ebSPrzemek Kitszel /* in DVM a VF can add/delete inner VLAN filters when 1788*f4e667ebSPrzemek Kitszel * VIRTCHNL_VF_OFFLOAD_VLAN is negotiated, so only reject in SVM 1789*f4e667ebSPrzemek Kitszel */ 1790*f4e667ebSPrzemek Kitszel if (ice_vf_is_port_vlan_ena(vf) && !ice_is_dvm_ena(&pf->hw)) { 1791*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1792*f4e667ebSPrzemek Kitszel goto error_param; 1793*f4e667ebSPrzemek Kitszel } 1794*f4e667ebSPrzemek Kitszel 1795*f4e667ebSPrzemek Kitszel /* in DVM VLAN promiscuous is based on the outer VLAN, which would be 1796*f4e667ebSPrzemek Kitszel * the port VLAN if VIRTCHNL_VF_OFFLOAD_VLAN was negotiated, so only 1797*f4e667ebSPrzemek Kitszel * allow vlan_promisc = true in SVM and if no port VLAN is configured 1798*f4e667ebSPrzemek Kitszel */ 1799*f4e667ebSPrzemek Kitszel vlan_promisc = ice_is_vlan_promisc_allowed(vf) && 1800*f4e667ebSPrzemek Kitszel !ice_is_dvm_ena(&pf->hw) && 1801*f4e667ebSPrzemek Kitszel !ice_vf_is_port_vlan_ena(vf); 1802*f4e667ebSPrzemek Kitszel 1803*f4e667ebSPrzemek Kitszel if (add_v) { 1804*f4e667ebSPrzemek Kitszel for (i = 0; i < vfl->num_elements; i++) { 1805*f4e667ebSPrzemek Kitszel u16 vid = vfl->vlan_id[i]; 1806*f4e667ebSPrzemek Kitszel struct ice_vlan vlan; 1807*f4e667ebSPrzemek Kitszel 1808*f4e667ebSPrzemek Kitszel if (ice_vf_has_max_vlans(vf, vsi)) { 1809*f4e667ebSPrzemek Kitszel dev_info(dev, "VF-%d is not trusted, switch the VF to trusted mode, in order to add more VLAN addresses\n", 1810*f4e667ebSPrzemek Kitszel vf->vf_id); 1811*f4e667ebSPrzemek Kitszel /* There is no need to let VF know about being 1812*f4e667ebSPrzemek Kitszel * not trusted, so we can just return success 1813*f4e667ebSPrzemek Kitszel * message here as well. 1814*f4e667ebSPrzemek Kitszel */ 1815*f4e667ebSPrzemek Kitszel goto error_param; 1816*f4e667ebSPrzemek Kitszel } 1817*f4e667ebSPrzemek Kitszel 1818*f4e667ebSPrzemek Kitszel /* we add VLAN 0 by default for each VF so we can enable 1819*f4e667ebSPrzemek Kitszel * Tx VLAN anti-spoof without triggering MDD events so 1820*f4e667ebSPrzemek Kitszel * we don't need to add it again here 1821*f4e667ebSPrzemek Kitszel */ 1822*f4e667ebSPrzemek Kitszel if (!vid) 1823*f4e667ebSPrzemek Kitszel continue; 1824*f4e667ebSPrzemek Kitszel 1825*f4e667ebSPrzemek Kitszel vlan = ICE_VLAN(ETH_P_8021Q, vid, 0); 1826*f4e667ebSPrzemek Kitszel status = vsi->inner_vlan_ops.add_vlan(vsi, &vlan); 1827*f4e667ebSPrzemek Kitszel if (status) { 1828*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1829*f4e667ebSPrzemek Kitszel goto error_param; 1830*f4e667ebSPrzemek Kitszel } 1831*f4e667ebSPrzemek Kitszel 1832*f4e667ebSPrzemek Kitszel /* Enable VLAN filtering on first non-zero VLAN */ 1833*f4e667ebSPrzemek Kitszel if (!vlan_promisc && vid && !ice_is_dvm_ena(&pf->hw)) { 1834*f4e667ebSPrzemek Kitszel if (vf->spoofchk) { 1835*f4e667ebSPrzemek Kitszel status = vsi->inner_vlan_ops.ena_tx_filtering(vsi); 1836*f4e667ebSPrzemek Kitszel if (status) { 1837*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1838*f4e667ebSPrzemek Kitszel dev_err(dev, "Enable VLAN anti-spoofing on VLAN ID: %d failed error-%d\n", 1839*f4e667ebSPrzemek Kitszel vid, status); 1840*f4e667ebSPrzemek Kitszel goto error_param; 1841*f4e667ebSPrzemek Kitszel } 1842*f4e667ebSPrzemek Kitszel } 1843*f4e667ebSPrzemek Kitszel if (vsi->inner_vlan_ops.ena_rx_filtering(vsi)) { 1844*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1845*f4e667ebSPrzemek Kitszel dev_err(dev, "Enable VLAN pruning on VLAN ID: %d failed error-%d\n", 1846*f4e667ebSPrzemek Kitszel vid, status); 1847*f4e667ebSPrzemek Kitszel goto error_param; 1848*f4e667ebSPrzemek Kitszel } 1849*f4e667ebSPrzemek Kitszel } else if (vlan_promisc) { 1850*f4e667ebSPrzemek Kitszel status = ice_vf_ena_vlan_promisc(vf, vsi, &vlan); 1851*f4e667ebSPrzemek Kitszel if (status) { 1852*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1853*f4e667ebSPrzemek Kitszel dev_err(dev, "Enable Unicast/multicast promiscuous mode on VLAN ID:%d failed error-%d\n", 1854*f4e667ebSPrzemek Kitszel vid, status); 1855*f4e667ebSPrzemek Kitszel } 1856*f4e667ebSPrzemek Kitszel } 1857*f4e667ebSPrzemek Kitszel } 1858*f4e667ebSPrzemek Kitszel } else { 1859*f4e667ebSPrzemek Kitszel /* In case of non_trusted VF, number of VLAN elements passed 1860*f4e667ebSPrzemek Kitszel * to PF for removal might be greater than number of VLANs 1861*f4e667ebSPrzemek Kitszel * filter programmed for that VF - So, use actual number of 1862*f4e667ebSPrzemek Kitszel * VLANS added earlier with add VLAN opcode. In order to avoid 1863*f4e667ebSPrzemek Kitszel * removing VLAN that doesn't exist, which result to sending 1864*f4e667ebSPrzemek Kitszel * erroneous failed message back to the VF 1865*f4e667ebSPrzemek Kitszel */ 1866*f4e667ebSPrzemek Kitszel int num_vf_vlan; 1867*f4e667ebSPrzemek Kitszel 1868*f4e667ebSPrzemek Kitszel num_vf_vlan = vsi->num_vlan; 1869*f4e667ebSPrzemek Kitszel for (i = 0; i < vfl->num_elements && i < num_vf_vlan; i++) { 1870*f4e667ebSPrzemek Kitszel u16 vid = vfl->vlan_id[i]; 1871*f4e667ebSPrzemek Kitszel struct ice_vlan vlan; 1872*f4e667ebSPrzemek Kitszel 1873*f4e667ebSPrzemek Kitszel /* we add VLAN 0 by default for each VF so we can enable 1874*f4e667ebSPrzemek Kitszel * Tx VLAN anti-spoof without triggering MDD events so 1875*f4e667ebSPrzemek Kitszel * we don't want a VIRTCHNL request to remove it 1876*f4e667ebSPrzemek Kitszel */ 1877*f4e667ebSPrzemek Kitszel if (!vid) 1878*f4e667ebSPrzemek Kitszel continue; 1879*f4e667ebSPrzemek Kitszel 1880*f4e667ebSPrzemek Kitszel vlan = ICE_VLAN(ETH_P_8021Q, vid, 0); 1881*f4e667ebSPrzemek Kitszel status = vsi->inner_vlan_ops.del_vlan(vsi, &vlan); 1882*f4e667ebSPrzemek Kitszel if (status) { 1883*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1884*f4e667ebSPrzemek Kitszel goto error_param; 1885*f4e667ebSPrzemek Kitszel } 1886*f4e667ebSPrzemek Kitszel 1887*f4e667ebSPrzemek Kitszel /* Disable VLAN filtering when only VLAN 0 is left */ 1888*f4e667ebSPrzemek Kitszel if (!ice_vsi_has_non_zero_vlans(vsi)) { 1889*f4e667ebSPrzemek Kitszel vsi->inner_vlan_ops.dis_tx_filtering(vsi); 1890*f4e667ebSPrzemek Kitszel vsi->inner_vlan_ops.dis_rx_filtering(vsi); 1891*f4e667ebSPrzemek Kitszel } 1892*f4e667ebSPrzemek Kitszel 1893*f4e667ebSPrzemek Kitszel if (vlan_promisc) 1894*f4e667ebSPrzemek Kitszel ice_vf_dis_vlan_promisc(vsi, &vlan); 1895*f4e667ebSPrzemek Kitszel } 1896*f4e667ebSPrzemek Kitszel } 1897*f4e667ebSPrzemek Kitszel 1898*f4e667ebSPrzemek Kitszel error_param: 1899*f4e667ebSPrzemek Kitszel /* send the response to the VF */ 1900*f4e667ebSPrzemek Kitszel if (add_v) 1901*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_VLAN, v_ret, 1902*f4e667ebSPrzemek Kitszel NULL, 0); 1903*f4e667ebSPrzemek Kitszel else 1904*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DEL_VLAN, v_ret, 1905*f4e667ebSPrzemek Kitszel NULL, 0); 1906*f4e667ebSPrzemek Kitszel } 1907*f4e667ebSPrzemek Kitszel 1908*f4e667ebSPrzemek Kitszel /** 1909*f4e667ebSPrzemek Kitszel * ice_vc_add_vlan_msg 1910*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1911*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 1912*f4e667ebSPrzemek Kitszel * 1913*f4e667ebSPrzemek Kitszel * Add and program guest VLAN ID 1914*f4e667ebSPrzemek Kitszel */ 1915*f4e667ebSPrzemek Kitszel static int ice_vc_add_vlan_msg(struct ice_vf *vf, u8 *msg) 1916*f4e667ebSPrzemek Kitszel { 1917*f4e667ebSPrzemek Kitszel return ice_vc_process_vlan_msg(vf, msg, true); 1918*f4e667ebSPrzemek Kitszel } 1919*f4e667ebSPrzemek Kitszel 1920*f4e667ebSPrzemek Kitszel /** 1921*f4e667ebSPrzemek Kitszel * ice_vc_remove_vlan_msg 1922*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1923*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 1924*f4e667ebSPrzemek Kitszel * 1925*f4e667ebSPrzemek Kitszel * remove programmed guest VLAN ID 1926*f4e667ebSPrzemek Kitszel */ 1927*f4e667ebSPrzemek Kitszel static int ice_vc_remove_vlan_msg(struct ice_vf *vf, u8 *msg) 1928*f4e667ebSPrzemek Kitszel { 1929*f4e667ebSPrzemek Kitszel return ice_vc_process_vlan_msg(vf, msg, false); 1930*f4e667ebSPrzemek Kitszel } 1931*f4e667ebSPrzemek Kitszel 1932*f4e667ebSPrzemek Kitszel /** 1933*f4e667ebSPrzemek Kitszel * ice_vsi_is_rxq_crc_strip_dis - check if Rx queue CRC strip is disabled or not 1934*f4e667ebSPrzemek Kitszel * @vsi: pointer to the VF VSI info 1935*f4e667ebSPrzemek Kitszel */ 1936*f4e667ebSPrzemek Kitszel static bool ice_vsi_is_rxq_crc_strip_dis(struct ice_vsi *vsi) 1937*f4e667ebSPrzemek Kitszel { 1938*f4e667ebSPrzemek Kitszel unsigned int i; 1939*f4e667ebSPrzemek Kitszel 1940*f4e667ebSPrzemek Kitszel ice_for_each_alloc_rxq(vsi, i) 1941*f4e667ebSPrzemek Kitszel if (vsi->rx_rings[i]->flags & ICE_RX_FLAGS_CRC_STRIP_DIS) 1942*f4e667ebSPrzemek Kitszel return true; 1943*f4e667ebSPrzemek Kitszel 1944*f4e667ebSPrzemek Kitszel return false; 1945*f4e667ebSPrzemek Kitszel } 1946*f4e667ebSPrzemek Kitszel 1947*f4e667ebSPrzemek Kitszel /** 1948*f4e667ebSPrzemek Kitszel * ice_vc_ena_vlan_stripping 1949*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1950*f4e667ebSPrzemek Kitszel * 1951*f4e667ebSPrzemek Kitszel * Enable VLAN header stripping for a given VF 1952*f4e667ebSPrzemek Kitszel */ 1953*f4e667ebSPrzemek Kitszel static int ice_vc_ena_vlan_stripping(struct ice_vf *vf) 1954*f4e667ebSPrzemek Kitszel { 1955*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1956*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 1957*f4e667ebSPrzemek Kitszel 1958*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1959*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1960*f4e667ebSPrzemek Kitszel goto error_param; 1961*f4e667ebSPrzemek Kitszel } 1962*f4e667ebSPrzemek Kitszel 1963*f4e667ebSPrzemek Kitszel if (!ice_vf_vlan_offload_ena(vf->driver_caps)) { 1964*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1965*f4e667ebSPrzemek Kitszel goto error_param; 1966*f4e667ebSPrzemek Kitszel } 1967*f4e667ebSPrzemek Kitszel 1968*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 1969*f4e667ebSPrzemek Kitszel if (!vsi) { 1970*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1971*f4e667ebSPrzemek Kitszel goto error_param; 1972*f4e667ebSPrzemek Kitszel } 1973*f4e667ebSPrzemek Kitszel 1974*f4e667ebSPrzemek Kitszel if (vsi->inner_vlan_ops.ena_stripping(vsi, ETH_P_8021Q)) 1975*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1976*f4e667ebSPrzemek Kitszel else 1977*f4e667ebSPrzemek Kitszel vf->vlan_strip_ena |= ICE_INNER_VLAN_STRIP_ENA; 1978*f4e667ebSPrzemek Kitszel 1979*f4e667ebSPrzemek Kitszel error_param: 1980*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, 1981*f4e667ebSPrzemek Kitszel v_ret, NULL, 0); 1982*f4e667ebSPrzemek Kitszel } 1983*f4e667ebSPrzemek Kitszel 1984*f4e667ebSPrzemek Kitszel /** 1985*f4e667ebSPrzemek Kitszel * ice_vc_dis_vlan_stripping 1986*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 1987*f4e667ebSPrzemek Kitszel * 1988*f4e667ebSPrzemek Kitszel * Disable VLAN header stripping for a given VF 1989*f4e667ebSPrzemek Kitszel */ 1990*f4e667ebSPrzemek Kitszel static int ice_vc_dis_vlan_stripping(struct ice_vf *vf) 1991*f4e667ebSPrzemek Kitszel { 1992*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 1993*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 1994*f4e667ebSPrzemek Kitszel 1995*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1996*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1997*f4e667ebSPrzemek Kitszel goto error_param; 1998*f4e667ebSPrzemek Kitszel } 1999*f4e667ebSPrzemek Kitszel 2000*f4e667ebSPrzemek Kitszel if (!ice_vf_vlan_offload_ena(vf->driver_caps)) { 2001*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2002*f4e667ebSPrzemek Kitszel goto error_param; 2003*f4e667ebSPrzemek Kitszel } 2004*f4e667ebSPrzemek Kitszel 2005*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 2006*f4e667ebSPrzemek Kitszel if (!vsi) { 2007*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2008*f4e667ebSPrzemek Kitszel goto error_param; 2009*f4e667ebSPrzemek Kitszel } 2010*f4e667ebSPrzemek Kitszel 2011*f4e667ebSPrzemek Kitszel if (vsi->inner_vlan_ops.dis_stripping(vsi)) 2012*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2013*f4e667ebSPrzemek Kitszel else 2014*f4e667ebSPrzemek Kitszel vf->vlan_strip_ena &= ~ICE_INNER_VLAN_STRIP_ENA; 2015*f4e667ebSPrzemek Kitszel 2016*f4e667ebSPrzemek Kitszel error_param: 2017*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, 2018*f4e667ebSPrzemek Kitszel v_ret, NULL, 0); 2019*f4e667ebSPrzemek Kitszel } 2020*f4e667ebSPrzemek Kitszel 2021*f4e667ebSPrzemek Kitszel /** 2022*f4e667ebSPrzemek Kitszel * ice_vc_get_rss_hashcfg - return the RSS Hash configuration 2023*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 2024*f4e667ebSPrzemek Kitszel */ 2025*f4e667ebSPrzemek Kitszel static int ice_vc_get_rss_hashcfg(struct ice_vf *vf) 2026*f4e667ebSPrzemek Kitszel { 2027*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 2028*f4e667ebSPrzemek Kitszel struct virtchnl_rss_hashcfg *vrh = NULL; 2029*f4e667ebSPrzemek Kitszel int len = 0, ret; 2030*f4e667ebSPrzemek Kitszel 2031*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 2032*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2033*f4e667ebSPrzemek Kitszel goto err; 2034*f4e667ebSPrzemek Kitszel } 2035*f4e667ebSPrzemek Kitszel 2036*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { 2037*f4e667ebSPrzemek Kitszel dev_err(ice_pf_to_dev(vf->pf), "RSS not supported by PF\n"); 2038*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2039*f4e667ebSPrzemek Kitszel goto err; 2040*f4e667ebSPrzemek Kitszel } 2041*f4e667ebSPrzemek Kitszel 2042*f4e667ebSPrzemek Kitszel len = sizeof(struct virtchnl_rss_hashcfg); 2043*f4e667ebSPrzemek Kitszel vrh = kzalloc(len, GFP_KERNEL); 2044*f4e667ebSPrzemek Kitszel if (!vrh) { 2045*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 2046*f4e667ebSPrzemek Kitszel len = 0; 2047*f4e667ebSPrzemek Kitszel goto err; 2048*f4e667ebSPrzemek Kitszel } 2049*f4e667ebSPrzemek Kitszel 2050*f4e667ebSPrzemek Kitszel vrh->hashcfg = ICE_DEFAULT_RSS_HASHCFG; 2051*f4e667ebSPrzemek Kitszel err: 2052*f4e667ebSPrzemek Kitszel /* send the response back to the VF */ 2053*f4e667ebSPrzemek Kitszel ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_RSS_HASHCFG_CAPS, v_ret, 2054*f4e667ebSPrzemek Kitszel (u8 *)vrh, len); 2055*f4e667ebSPrzemek Kitszel kfree(vrh); 2056*f4e667ebSPrzemek Kitszel return ret; 2057*f4e667ebSPrzemek Kitszel } 2058*f4e667ebSPrzemek Kitszel 2059*f4e667ebSPrzemek Kitszel /** 2060*f4e667ebSPrzemek Kitszel * ice_vc_set_rss_hashcfg - set RSS Hash configuration bits for the VF 2061*f4e667ebSPrzemek Kitszel * @vf: pointer to the VF info 2062*f4e667ebSPrzemek Kitszel * @msg: pointer to the msg buffer 2063*f4e667ebSPrzemek Kitszel */ 2064*f4e667ebSPrzemek Kitszel static int ice_vc_set_rss_hashcfg(struct ice_vf *vf, u8 *msg) 2065*f4e667ebSPrzemek Kitszel { 2066*f4e667ebSPrzemek Kitszel struct virtchnl_rss_hashcfg *vrh = (struct virtchnl_rss_hashcfg *)msg; 2067*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 2068*f4e667ebSPrzemek Kitszel struct ice_pf *pf = vf->pf; 2069*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 2070*f4e667ebSPrzemek Kitszel struct device *dev; 2071*f4e667ebSPrzemek Kitszel int status; 2072*f4e667ebSPrzemek Kitszel 2073*f4e667ebSPrzemek Kitszel dev = ice_pf_to_dev(pf); 2074*f4e667ebSPrzemek Kitszel 2075*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 2076*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2077*f4e667ebSPrzemek Kitszel goto err; 2078*f4e667ebSPrzemek Kitszel } 2079*f4e667ebSPrzemek Kitszel 2080*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 2081*f4e667ebSPrzemek Kitszel dev_err(dev, "RSS not supported by PF\n"); 2082*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2083*f4e667ebSPrzemek Kitszel goto err; 2084*f4e667ebSPrzemek Kitszel } 2085*f4e667ebSPrzemek Kitszel 2086*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 2087*f4e667ebSPrzemek Kitszel if (!vsi) { 2088*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2089*f4e667ebSPrzemek Kitszel goto err; 2090*f4e667ebSPrzemek Kitszel } 2091*f4e667ebSPrzemek Kitszel 2092*f4e667ebSPrzemek Kitszel /* clear all previously programmed RSS configuration to allow VF drivers 2093*f4e667ebSPrzemek Kitszel * the ability to customize the RSS configuration and/or completely 2094*f4e667ebSPrzemek Kitszel * disable RSS 2095*f4e667ebSPrzemek Kitszel */ 2096*f4e667ebSPrzemek Kitszel status = ice_rem_vsi_rss_cfg(&pf->hw, vsi->idx); 2097*f4e667ebSPrzemek Kitszel if (status && !vrh->hashcfg) { 2098*f4e667ebSPrzemek Kitszel /* only report failure to clear the current RSS configuration if 2099*f4e667ebSPrzemek Kitszel * that was clearly the VF's intention (i.e. vrh->hashcfg = 0) 2100*f4e667ebSPrzemek Kitszel */ 2101*f4e667ebSPrzemek Kitszel v_ret = ice_err_to_virt_err(status); 2102*f4e667ebSPrzemek Kitszel goto err; 2103*f4e667ebSPrzemek Kitszel } else if (status) { 2104*f4e667ebSPrzemek Kitszel /* allow the VF to update the RSS configuration even on failure 2105*f4e667ebSPrzemek Kitszel * to clear the current RSS confguration in an attempt to keep 2106*f4e667ebSPrzemek Kitszel * RSS in a working state 2107*f4e667ebSPrzemek Kitszel */ 2108*f4e667ebSPrzemek Kitszel dev_warn(dev, "Failed to clear the RSS configuration for VF %u\n", 2109*f4e667ebSPrzemek Kitszel vf->vf_id); 2110*f4e667ebSPrzemek Kitszel } 2111*f4e667ebSPrzemek Kitszel 2112*f4e667ebSPrzemek Kitszel if (vrh->hashcfg) { 2113*f4e667ebSPrzemek Kitszel status = ice_add_avf_rss_cfg(&pf->hw, vsi, vrh->hashcfg); 2114*f4e667ebSPrzemek Kitszel v_ret = ice_err_to_virt_err(status); 2115*f4e667ebSPrzemek Kitszel } 2116*f4e667ebSPrzemek Kitszel 2117*f4e667ebSPrzemek Kitszel /* save the requested VF configuration */ 2118*f4e667ebSPrzemek Kitszel if (!v_ret) 2119*f4e667ebSPrzemek Kitszel vf->rss_hashcfg = vrh->hashcfg; 2120*f4e667ebSPrzemek Kitszel 2121*f4e667ebSPrzemek Kitszel /* send the response to the VF */ 2122*f4e667ebSPrzemek Kitszel err: 2123*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_SET_RSS_HASHCFG, v_ret, 2124*f4e667ebSPrzemek Kitszel NULL, 0); 2125*f4e667ebSPrzemek Kitszel } 2126*f4e667ebSPrzemek Kitszel 2127*f4e667ebSPrzemek Kitszel /** 2128*f4e667ebSPrzemek Kitszel * ice_vc_query_rxdid - query RXDID supported by DDP package 2129*f4e667ebSPrzemek Kitszel * @vf: pointer to VF info 2130*f4e667ebSPrzemek Kitszel * 2131*f4e667ebSPrzemek Kitszel * Called from VF to query a bitmap of supported flexible 2132*f4e667ebSPrzemek Kitszel * descriptor RXDIDs of a DDP package. 2133*f4e667ebSPrzemek Kitszel */ 2134*f4e667ebSPrzemek Kitszel static int ice_vc_query_rxdid(struct ice_vf *vf) 2135*f4e667ebSPrzemek Kitszel { 2136*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 2137*f4e667ebSPrzemek Kitszel struct ice_pf *pf = vf->pf; 2138*f4e667ebSPrzemek Kitszel u64 rxdid; 2139*f4e667ebSPrzemek Kitszel 2140*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 2141*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2142*f4e667ebSPrzemek Kitszel goto err; 2143*f4e667ebSPrzemek Kitszel } 2144*f4e667ebSPrzemek Kitszel 2145*f4e667ebSPrzemek Kitszel if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC)) { 2146*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2147*f4e667ebSPrzemek Kitszel goto err; 2148*f4e667ebSPrzemek Kitszel } 2149*f4e667ebSPrzemek Kitszel 2150*f4e667ebSPrzemek Kitszel rxdid = pf->supported_rxdids; 2151*f4e667ebSPrzemek Kitszel 2152*f4e667ebSPrzemek Kitszel err: 2153*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_SUPPORTED_RXDIDS, 2154*f4e667ebSPrzemek Kitszel v_ret, (u8 *)&rxdid, sizeof(rxdid)); 2155*f4e667ebSPrzemek Kitszel } 2156*f4e667ebSPrzemek Kitszel 2157*f4e667ebSPrzemek Kitszel /** 2158*f4e667ebSPrzemek Kitszel * ice_vf_init_vlan_stripping - enable/disable VLAN stripping on initialization 2159*f4e667ebSPrzemek Kitszel * @vf: VF to enable/disable VLAN stripping for on initialization 2160*f4e667ebSPrzemek Kitszel * 2161*f4e667ebSPrzemek Kitszel * Set the default for VLAN stripping based on whether a port VLAN is configured 2162*f4e667ebSPrzemek Kitszel * and the current VLAN mode of the device. 2163*f4e667ebSPrzemek Kitszel */ 2164*f4e667ebSPrzemek Kitszel static int ice_vf_init_vlan_stripping(struct ice_vf *vf) 2165*f4e667ebSPrzemek Kitszel { 2166*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi = ice_get_vf_vsi(vf); 2167*f4e667ebSPrzemek Kitszel 2168*f4e667ebSPrzemek Kitszel vf->vlan_strip_ena = 0; 2169*f4e667ebSPrzemek Kitszel 2170*f4e667ebSPrzemek Kitszel if (!vsi) 2171*f4e667ebSPrzemek Kitszel return -EINVAL; 2172*f4e667ebSPrzemek Kitszel 2173*f4e667ebSPrzemek Kitszel /* don't modify stripping if port VLAN is configured in SVM since the 2174*f4e667ebSPrzemek Kitszel * port VLAN is based on the inner/single VLAN in SVM 2175*f4e667ebSPrzemek Kitszel */ 2176*f4e667ebSPrzemek Kitszel if (ice_vf_is_port_vlan_ena(vf) && !ice_is_dvm_ena(&vsi->back->hw)) 2177*f4e667ebSPrzemek Kitszel return 0; 2178*f4e667ebSPrzemek Kitszel 2179*f4e667ebSPrzemek Kitszel if (ice_vf_vlan_offload_ena(vf->driver_caps)) { 2180*f4e667ebSPrzemek Kitszel int err; 2181*f4e667ebSPrzemek Kitszel 2182*f4e667ebSPrzemek Kitszel err = vsi->inner_vlan_ops.ena_stripping(vsi, ETH_P_8021Q); 2183*f4e667ebSPrzemek Kitszel if (!err) 2184*f4e667ebSPrzemek Kitszel vf->vlan_strip_ena |= ICE_INNER_VLAN_STRIP_ENA; 2185*f4e667ebSPrzemek Kitszel return err; 2186*f4e667ebSPrzemek Kitszel } 2187*f4e667ebSPrzemek Kitszel 2188*f4e667ebSPrzemek Kitszel return vsi->inner_vlan_ops.dis_stripping(vsi); 2189*f4e667ebSPrzemek Kitszel } 2190*f4e667ebSPrzemek Kitszel 2191*f4e667ebSPrzemek Kitszel static u16 ice_vc_get_max_vlan_fltrs(struct ice_vf *vf) 2192*f4e667ebSPrzemek Kitszel { 2193*f4e667ebSPrzemek Kitszel if (vf->trusted) 2194*f4e667ebSPrzemek Kitszel return VLAN_N_VID; 2195*f4e667ebSPrzemek Kitszel else 2196*f4e667ebSPrzemek Kitszel return ICE_MAX_VLAN_PER_VF; 2197*f4e667ebSPrzemek Kitszel } 2198*f4e667ebSPrzemek Kitszel 2199*f4e667ebSPrzemek Kitszel /** 2200*f4e667ebSPrzemek Kitszel * ice_vf_outer_vlan_not_allowed - check if outer VLAN can be used 2201*f4e667ebSPrzemek Kitszel * @vf: VF that being checked for 2202*f4e667ebSPrzemek Kitszel * 2203*f4e667ebSPrzemek Kitszel * When the device is in double VLAN mode, check whether or not the outer VLAN 2204*f4e667ebSPrzemek Kitszel * is allowed. 2205*f4e667ebSPrzemek Kitszel */ 2206*f4e667ebSPrzemek Kitszel static bool ice_vf_outer_vlan_not_allowed(struct ice_vf *vf) 2207*f4e667ebSPrzemek Kitszel { 2208*f4e667ebSPrzemek Kitszel if (ice_vf_is_port_vlan_ena(vf)) 2209*f4e667ebSPrzemek Kitszel return true; 2210*f4e667ebSPrzemek Kitszel 2211*f4e667ebSPrzemek Kitszel return false; 2212*f4e667ebSPrzemek Kitszel } 2213*f4e667ebSPrzemek Kitszel 2214*f4e667ebSPrzemek Kitszel /** 2215*f4e667ebSPrzemek Kitszel * ice_vc_set_dvm_caps - set VLAN capabilities when the device is in DVM 2216*f4e667ebSPrzemek Kitszel * @vf: VF that capabilities are being set for 2217*f4e667ebSPrzemek Kitszel * @caps: VLAN capabilities to populate 2218*f4e667ebSPrzemek Kitszel * 2219*f4e667ebSPrzemek Kitszel * Determine VLAN capabilities support based on whether a port VLAN is 2220*f4e667ebSPrzemek Kitszel * configured. If a port VLAN is configured then the VF should use the inner 2221*f4e667ebSPrzemek Kitszel * filtering/offload capabilities since the port VLAN is using the outer VLAN 2222*f4e667ebSPrzemek Kitszel * capabilies. 2223*f4e667ebSPrzemek Kitszel */ 2224*f4e667ebSPrzemek Kitszel static void 2225*f4e667ebSPrzemek Kitszel ice_vc_set_dvm_caps(struct ice_vf *vf, struct virtchnl_vlan_caps *caps) 2226*f4e667ebSPrzemek Kitszel { 2227*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_supported_caps *supported_caps; 2228*f4e667ebSPrzemek Kitszel 2229*f4e667ebSPrzemek Kitszel if (ice_vf_outer_vlan_not_allowed(vf)) { 2230*f4e667ebSPrzemek Kitszel /* until support for inner VLAN filtering is added when a port 2231*f4e667ebSPrzemek Kitszel * VLAN is configured, only support software offloaded inner 2232*f4e667ebSPrzemek Kitszel * VLANs when a port VLAN is confgured in DVM 2233*f4e667ebSPrzemek Kitszel */ 2234*f4e667ebSPrzemek Kitszel supported_caps = &caps->filtering.filtering_support; 2235*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_UNSUPPORTED; 2236*f4e667ebSPrzemek Kitszel 2237*f4e667ebSPrzemek Kitszel supported_caps = &caps->offloads.stripping_support; 2238*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_ETHERTYPE_8100 | 2239*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TOGGLE | 2240*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1; 2241*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_UNSUPPORTED; 2242*f4e667ebSPrzemek Kitszel 2243*f4e667ebSPrzemek Kitszel supported_caps = &caps->offloads.insertion_support; 2244*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_ETHERTYPE_8100 | 2245*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TOGGLE | 2246*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1; 2247*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_UNSUPPORTED; 2248*f4e667ebSPrzemek Kitszel 2249*f4e667ebSPrzemek Kitszel caps->offloads.ethertype_init = VIRTCHNL_VLAN_ETHERTYPE_8100; 2250*f4e667ebSPrzemek Kitszel caps->offloads.ethertype_match = 2251*f4e667ebSPrzemek Kitszel VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION; 2252*f4e667ebSPrzemek Kitszel } else { 2253*f4e667ebSPrzemek Kitszel supported_caps = &caps->filtering.filtering_support; 2254*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_UNSUPPORTED; 2255*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_ETHERTYPE_8100 | 2256*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_88A8 | 2257*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_9100 | 2258*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_AND; 2259*f4e667ebSPrzemek Kitszel caps->filtering.ethertype_init = VIRTCHNL_VLAN_ETHERTYPE_8100 | 2260*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_88A8 | 2261*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_9100; 2262*f4e667ebSPrzemek Kitszel 2263*f4e667ebSPrzemek Kitszel supported_caps = &caps->offloads.stripping_support; 2264*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_TOGGLE | 2265*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_8100 | 2266*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1; 2267*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_TOGGLE | 2268*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_8100 | 2269*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_88A8 | 2270*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_9100 | 2271*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_XOR | 2272*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2_2; 2273*f4e667ebSPrzemek Kitszel 2274*f4e667ebSPrzemek Kitszel supported_caps = &caps->offloads.insertion_support; 2275*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_TOGGLE | 2276*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_8100 | 2277*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1; 2278*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_TOGGLE | 2279*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_8100 | 2280*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_88A8 | 2281*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_9100 | 2282*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_ETHERTYPE_XOR | 2283*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2; 2284*f4e667ebSPrzemek Kitszel 2285*f4e667ebSPrzemek Kitszel caps->offloads.ethertype_init = VIRTCHNL_VLAN_ETHERTYPE_8100; 2286*f4e667ebSPrzemek Kitszel 2287*f4e667ebSPrzemek Kitszel caps->offloads.ethertype_match = 2288*f4e667ebSPrzemek Kitszel VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION; 2289*f4e667ebSPrzemek Kitszel } 2290*f4e667ebSPrzemek Kitszel 2291*f4e667ebSPrzemek Kitszel caps->filtering.max_filters = ice_vc_get_max_vlan_fltrs(vf); 2292*f4e667ebSPrzemek Kitszel } 2293*f4e667ebSPrzemek Kitszel 2294*f4e667ebSPrzemek Kitszel /** 2295*f4e667ebSPrzemek Kitszel * ice_vc_set_svm_caps - set VLAN capabilities when the device is in SVM 2296*f4e667ebSPrzemek Kitszel * @vf: VF that capabilities are being set for 2297*f4e667ebSPrzemek Kitszel * @caps: VLAN capabilities to populate 2298*f4e667ebSPrzemek Kitszel * 2299*f4e667ebSPrzemek Kitszel * Determine VLAN capabilities support based on whether a port VLAN is 2300*f4e667ebSPrzemek Kitszel * configured. If a port VLAN is configured then the VF does not have any VLAN 2301*f4e667ebSPrzemek Kitszel * filtering or offload capabilities since the port VLAN is using the inner VLAN 2302*f4e667ebSPrzemek Kitszel * capabilities in single VLAN mode (SVM). Otherwise allow the VF to use inner 2303*f4e667ebSPrzemek Kitszel * VLAN fitlering and offload capabilities. 2304*f4e667ebSPrzemek Kitszel */ 2305*f4e667ebSPrzemek Kitszel static void 2306*f4e667ebSPrzemek Kitszel ice_vc_set_svm_caps(struct ice_vf *vf, struct virtchnl_vlan_caps *caps) 2307*f4e667ebSPrzemek Kitszel { 2308*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_supported_caps *supported_caps; 2309*f4e667ebSPrzemek Kitszel 2310*f4e667ebSPrzemek Kitszel if (ice_vf_is_port_vlan_ena(vf)) { 2311*f4e667ebSPrzemek Kitszel supported_caps = &caps->filtering.filtering_support; 2312*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_UNSUPPORTED; 2313*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_UNSUPPORTED; 2314*f4e667ebSPrzemek Kitszel 2315*f4e667ebSPrzemek Kitszel supported_caps = &caps->offloads.stripping_support; 2316*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_UNSUPPORTED; 2317*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_UNSUPPORTED; 2318*f4e667ebSPrzemek Kitszel 2319*f4e667ebSPrzemek Kitszel supported_caps = &caps->offloads.insertion_support; 2320*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_UNSUPPORTED; 2321*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_UNSUPPORTED; 2322*f4e667ebSPrzemek Kitszel 2323*f4e667ebSPrzemek Kitszel caps->offloads.ethertype_init = VIRTCHNL_VLAN_UNSUPPORTED; 2324*f4e667ebSPrzemek Kitszel caps->offloads.ethertype_match = VIRTCHNL_VLAN_UNSUPPORTED; 2325*f4e667ebSPrzemek Kitszel caps->filtering.max_filters = 0; 2326*f4e667ebSPrzemek Kitszel } else { 2327*f4e667ebSPrzemek Kitszel supported_caps = &caps->filtering.filtering_support; 2328*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_ETHERTYPE_8100; 2329*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_UNSUPPORTED; 2330*f4e667ebSPrzemek Kitszel caps->filtering.ethertype_init = VIRTCHNL_VLAN_ETHERTYPE_8100; 2331*f4e667ebSPrzemek Kitszel 2332*f4e667ebSPrzemek Kitszel supported_caps = &caps->offloads.stripping_support; 2333*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_ETHERTYPE_8100 | 2334*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TOGGLE | 2335*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1; 2336*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_UNSUPPORTED; 2337*f4e667ebSPrzemek Kitszel 2338*f4e667ebSPrzemek Kitszel supported_caps = &caps->offloads.insertion_support; 2339*f4e667ebSPrzemek Kitszel supported_caps->inner = VIRTCHNL_VLAN_ETHERTYPE_8100 | 2340*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TOGGLE | 2341*f4e667ebSPrzemek Kitszel VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1; 2342*f4e667ebSPrzemek Kitszel supported_caps->outer = VIRTCHNL_VLAN_UNSUPPORTED; 2343*f4e667ebSPrzemek Kitszel 2344*f4e667ebSPrzemek Kitszel caps->offloads.ethertype_init = VIRTCHNL_VLAN_ETHERTYPE_8100; 2345*f4e667ebSPrzemek Kitszel caps->offloads.ethertype_match = 2346*f4e667ebSPrzemek Kitszel VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION; 2347*f4e667ebSPrzemek Kitszel caps->filtering.max_filters = ice_vc_get_max_vlan_fltrs(vf); 2348*f4e667ebSPrzemek Kitszel } 2349*f4e667ebSPrzemek Kitszel } 2350*f4e667ebSPrzemek Kitszel 2351*f4e667ebSPrzemek Kitszel /** 2352*f4e667ebSPrzemek Kitszel * ice_vc_get_offload_vlan_v2_caps - determine VF's VLAN capabilities 2353*f4e667ebSPrzemek Kitszel * @vf: VF to determine VLAN capabilities for 2354*f4e667ebSPrzemek Kitszel * 2355*f4e667ebSPrzemek Kitszel * This will only be called if the VF and PF successfully negotiated 2356*f4e667ebSPrzemek Kitszel * VIRTCHNL_VF_OFFLOAD_VLAN_V2. 2357*f4e667ebSPrzemek Kitszel * 2358*f4e667ebSPrzemek Kitszel * Set VLAN capabilities based on the current VLAN mode and whether a port VLAN 2359*f4e667ebSPrzemek Kitszel * is configured or not. 2360*f4e667ebSPrzemek Kitszel */ 2361*f4e667ebSPrzemek Kitszel static int ice_vc_get_offload_vlan_v2_caps(struct ice_vf *vf) 2362*f4e667ebSPrzemek Kitszel { 2363*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 2364*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_caps *caps = NULL; 2365*f4e667ebSPrzemek Kitszel int err, len = 0; 2366*f4e667ebSPrzemek Kitszel 2367*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 2368*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2369*f4e667ebSPrzemek Kitszel goto out; 2370*f4e667ebSPrzemek Kitszel } 2371*f4e667ebSPrzemek Kitszel 2372*f4e667ebSPrzemek Kitszel caps = kzalloc(sizeof(*caps), GFP_KERNEL); 2373*f4e667ebSPrzemek Kitszel if (!caps) { 2374*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 2375*f4e667ebSPrzemek Kitszel goto out; 2376*f4e667ebSPrzemek Kitszel } 2377*f4e667ebSPrzemek Kitszel len = sizeof(*caps); 2378*f4e667ebSPrzemek Kitszel 2379*f4e667ebSPrzemek Kitszel if (ice_is_dvm_ena(&vf->pf->hw)) 2380*f4e667ebSPrzemek Kitszel ice_vc_set_dvm_caps(vf, caps); 2381*f4e667ebSPrzemek Kitszel else 2382*f4e667ebSPrzemek Kitszel ice_vc_set_svm_caps(vf, caps); 2383*f4e667ebSPrzemek Kitszel 2384*f4e667ebSPrzemek Kitszel /* store negotiated caps to prevent invalid VF messages */ 2385*f4e667ebSPrzemek Kitszel memcpy(&vf->vlan_v2_caps, caps, sizeof(*caps)); 2386*f4e667ebSPrzemek Kitszel 2387*f4e667ebSPrzemek Kitszel out: 2388*f4e667ebSPrzemek Kitszel err = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS, 2389*f4e667ebSPrzemek Kitszel v_ret, (u8 *)caps, len); 2390*f4e667ebSPrzemek Kitszel kfree(caps); 2391*f4e667ebSPrzemek Kitszel return err; 2392*f4e667ebSPrzemek Kitszel } 2393*f4e667ebSPrzemek Kitszel 2394*f4e667ebSPrzemek Kitszel /** 2395*f4e667ebSPrzemek Kitszel * ice_vc_validate_vlan_tpid - validate VLAN TPID 2396*f4e667ebSPrzemek Kitszel * @filtering_caps: negotiated/supported VLAN filtering capabilities 2397*f4e667ebSPrzemek Kitszel * @tpid: VLAN TPID used for validation 2398*f4e667ebSPrzemek Kitszel * 2399*f4e667ebSPrzemek Kitszel * Convert the VLAN TPID to a VIRTCHNL_VLAN_ETHERTYPE_* and then compare against 2400*f4e667ebSPrzemek Kitszel * the negotiated/supported filtering caps to see if the VLAN TPID is valid. 2401*f4e667ebSPrzemek Kitszel */ 2402*f4e667ebSPrzemek Kitszel static bool ice_vc_validate_vlan_tpid(u16 filtering_caps, u16 tpid) 2403*f4e667ebSPrzemek Kitszel { 2404*f4e667ebSPrzemek Kitszel enum virtchnl_vlan_support vlan_ethertype = VIRTCHNL_VLAN_UNSUPPORTED; 2405*f4e667ebSPrzemek Kitszel 2406*f4e667ebSPrzemek Kitszel switch (tpid) { 2407*f4e667ebSPrzemek Kitszel case ETH_P_8021Q: 2408*f4e667ebSPrzemek Kitszel vlan_ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100; 2409*f4e667ebSPrzemek Kitszel break; 2410*f4e667ebSPrzemek Kitszel case ETH_P_8021AD: 2411*f4e667ebSPrzemek Kitszel vlan_ethertype = VIRTCHNL_VLAN_ETHERTYPE_88A8; 2412*f4e667ebSPrzemek Kitszel break; 2413*f4e667ebSPrzemek Kitszel case ETH_P_QINQ1: 2414*f4e667ebSPrzemek Kitszel vlan_ethertype = VIRTCHNL_VLAN_ETHERTYPE_9100; 2415*f4e667ebSPrzemek Kitszel break; 2416*f4e667ebSPrzemek Kitszel } 2417*f4e667ebSPrzemek Kitszel 2418*f4e667ebSPrzemek Kitszel if (!(filtering_caps & vlan_ethertype)) 2419*f4e667ebSPrzemek Kitszel return false; 2420*f4e667ebSPrzemek Kitszel 2421*f4e667ebSPrzemek Kitszel return true; 2422*f4e667ebSPrzemek Kitszel } 2423*f4e667ebSPrzemek Kitszel 2424*f4e667ebSPrzemek Kitszel /** 2425*f4e667ebSPrzemek Kitszel * ice_vc_is_valid_vlan - validate the virtchnl_vlan 2426*f4e667ebSPrzemek Kitszel * @vc_vlan: virtchnl_vlan to validate 2427*f4e667ebSPrzemek Kitszel * 2428*f4e667ebSPrzemek Kitszel * If the VLAN TCI and VLAN TPID are 0, then this filter is invalid, so return 2429*f4e667ebSPrzemek Kitszel * false. Otherwise return true. 2430*f4e667ebSPrzemek Kitszel */ 2431*f4e667ebSPrzemek Kitszel static bool ice_vc_is_valid_vlan(struct virtchnl_vlan *vc_vlan) 2432*f4e667ebSPrzemek Kitszel { 2433*f4e667ebSPrzemek Kitszel if (!vc_vlan->tci || !vc_vlan->tpid) 2434*f4e667ebSPrzemek Kitszel return false; 2435*f4e667ebSPrzemek Kitszel 2436*f4e667ebSPrzemek Kitszel return true; 2437*f4e667ebSPrzemek Kitszel } 2438*f4e667ebSPrzemek Kitszel 2439*f4e667ebSPrzemek Kitszel /** 2440*f4e667ebSPrzemek Kitszel * ice_vc_validate_vlan_filter_list - validate the filter list from the VF 2441*f4e667ebSPrzemek Kitszel * @vfc: negotiated/supported VLAN filtering capabilities 2442*f4e667ebSPrzemek Kitszel * @vfl: VLAN filter list from VF to validate 2443*f4e667ebSPrzemek Kitszel * 2444*f4e667ebSPrzemek Kitszel * Validate all of the filters in the VLAN filter list from the VF. If any of 2445*f4e667ebSPrzemek Kitszel * the checks fail then return false. Otherwise return true. 2446*f4e667ebSPrzemek Kitszel */ 2447*f4e667ebSPrzemek Kitszel static bool 2448*f4e667ebSPrzemek Kitszel ice_vc_validate_vlan_filter_list(struct virtchnl_vlan_filtering_caps *vfc, 2449*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter_list_v2 *vfl) 2450*f4e667ebSPrzemek Kitszel { 2451*f4e667ebSPrzemek Kitszel u16 i; 2452*f4e667ebSPrzemek Kitszel 2453*f4e667ebSPrzemek Kitszel if (!vfl->num_elements) 2454*f4e667ebSPrzemek Kitszel return false; 2455*f4e667ebSPrzemek Kitszel 2456*f4e667ebSPrzemek Kitszel for (i = 0; i < vfl->num_elements; i++) { 2457*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_supported_caps *filtering_support = 2458*f4e667ebSPrzemek Kitszel &vfc->filtering_support; 2459*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter *vlan_fltr = &vfl->filters[i]; 2460*f4e667ebSPrzemek Kitszel struct virtchnl_vlan *outer = &vlan_fltr->outer; 2461*f4e667ebSPrzemek Kitszel struct virtchnl_vlan *inner = &vlan_fltr->inner; 2462*f4e667ebSPrzemek Kitszel 2463*f4e667ebSPrzemek Kitszel if ((ice_vc_is_valid_vlan(outer) && 2464*f4e667ebSPrzemek Kitszel filtering_support->outer == VIRTCHNL_VLAN_UNSUPPORTED) || 2465*f4e667ebSPrzemek Kitszel (ice_vc_is_valid_vlan(inner) && 2466*f4e667ebSPrzemek Kitszel filtering_support->inner == VIRTCHNL_VLAN_UNSUPPORTED)) 2467*f4e667ebSPrzemek Kitszel return false; 2468*f4e667ebSPrzemek Kitszel 2469*f4e667ebSPrzemek Kitszel if ((outer->tci_mask && 2470*f4e667ebSPrzemek Kitszel !(filtering_support->outer & VIRTCHNL_VLAN_FILTER_MASK)) || 2471*f4e667ebSPrzemek Kitszel (inner->tci_mask && 2472*f4e667ebSPrzemek Kitszel !(filtering_support->inner & VIRTCHNL_VLAN_FILTER_MASK))) 2473*f4e667ebSPrzemek Kitszel return false; 2474*f4e667ebSPrzemek Kitszel 2475*f4e667ebSPrzemek Kitszel if (((outer->tci & VLAN_PRIO_MASK) && 2476*f4e667ebSPrzemek Kitszel !(filtering_support->outer & VIRTCHNL_VLAN_PRIO)) || 2477*f4e667ebSPrzemek Kitszel ((inner->tci & VLAN_PRIO_MASK) && 2478*f4e667ebSPrzemek Kitszel !(filtering_support->inner & VIRTCHNL_VLAN_PRIO))) 2479*f4e667ebSPrzemek Kitszel return false; 2480*f4e667ebSPrzemek Kitszel 2481*f4e667ebSPrzemek Kitszel if ((ice_vc_is_valid_vlan(outer) && 2482*f4e667ebSPrzemek Kitszel !ice_vc_validate_vlan_tpid(filtering_support->outer, 2483*f4e667ebSPrzemek Kitszel outer->tpid)) || 2484*f4e667ebSPrzemek Kitszel (ice_vc_is_valid_vlan(inner) && 2485*f4e667ebSPrzemek Kitszel !ice_vc_validate_vlan_tpid(filtering_support->inner, 2486*f4e667ebSPrzemek Kitszel inner->tpid))) 2487*f4e667ebSPrzemek Kitszel return false; 2488*f4e667ebSPrzemek Kitszel } 2489*f4e667ebSPrzemek Kitszel 2490*f4e667ebSPrzemek Kitszel return true; 2491*f4e667ebSPrzemek Kitszel } 2492*f4e667ebSPrzemek Kitszel 2493*f4e667ebSPrzemek Kitszel /** 2494*f4e667ebSPrzemek Kitszel * ice_vc_to_vlan - transform from struct virtchnl_vlan to struct ice_vlan 2495*f4e667ebSPrzemek Kitszel * @vc_vlan: struct virtchnl_vlan to transform 2496*f4e667ebSPrzemek Kitszel */ 2497*f4e667ebSPrzemek Kitszel static struct ice_vlan ice_vc_to_vlan(struct virtchnl_vlan *vc_vlan) 2498*f4e667ebSPrzemek Kitszel { 2499*f4e667ebSPrzemek Kitszel struct ice_vlan vlan = { 0 }; 2500*f4e667ebSPrzemek Kitszel 2501*f4e667ebSPrzemek Kitszel vlan.prio = FIELD_GET(VLAN_PRIO_MASK, vc_vlan->tci); 2502*f4e667ebSPrzemek Kitszel vlan.vid = vc_vlan->tci & VLAN_VID_MASK; 2503*f4e667ebSPrzemek Kitszel vlan.tpid = vc_vlan->tpid; 2504*f4e667ebSPrzemek Kitszel 2505*f4e667ebSPrzemek Kitszel return vlan; 2506*f4e667ebSPrzemek Kitszel } 2507*f4e667ebSPrzemek Kitszel 2508*f4e667ebSPrzemek Kitszel /** 2509*f4e667ebSPrzemek Kitszel * ice_vc_vlan_action - action to perform on the virthcnl_vlan 2510*f4e667ebSPrzemek Kitszel * @vsi: VF's VSI used to perform the action 2511*f4e667ebSPrzemek Kitszel * @vlan_action: function to perform the action with (i.e. add/del) 2512*f4e667ebSPrzemek Kitszel * @vlan: VLAN filter to perform the action with 2513*f4e667ebSPrzemek Kitszel */ 2514*f4e667ebSPrzemek Kitszel static int 2515*f4e667ebSPrzemek Kitszel ice_vc_vlan_action(struct ice_vsi *vsi, 2516*f4e667ebSPrzemek Kitszel int (*vlan_action)(struct ice_vsi *, struct ice_vlan *), 2517*f4e667ebSPrzemek Kitszel struct ice_vlan *vlan) 2518*f4e667ebSPrzemek Kitszel { 2519*f4e667ebSPrzemek Kitszel int err; 2520*f4e667ebSPrzemek Kitszel 2521*f4e667ebSPrzemek Kitszel err = vlan_action(vsi, vlan); 2522*f4e667ebSPrzemek Kitszel if (err) 2523*f4e667ebSPrzemek Kitszel return err; 2524*f4e667ebSPrzemek Kitszel 2525*f4e667ebSPrzemek Kitszel return 0; 2526*f4e667ebSPrzemek Kitszel } 2527*f4e667ebSPrzemek Kitszel 2528*f4e667ebSPrzemek Kitszel /** 2529*f4e667ebSPrzemek Kitszel * ice_vc_del_vlans - delete VLAN(s) from the virtchnl filter list 2530*f4e667ebSPrzemek Kitszel * @vf: VF used to delete the VLAN(s) 2531*f4e667ebSPrzemek Kitszel * @vsi: VF's VSI used to delete the VLAN(s) 2532*f4e667ebSPrzemek Kitszel * @vfl: virthchnl filter list used to delete the filters 2533*f4e667ebSPrzemek Kitszel */ 2534*f4e667ebSPrzemek Kitszel static int 2535*f4e667ebSPrzemek Kitszel ice_vc_del_vlans(struct ice_vf *vf, struct ice_vsi *vsi, 2536*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter_list_v2 *vfl) 2537*f4e667ebSPrzemek Kitszel { 2538*f4e667ebSPrzemek Kitszel bool vlan_promisc = ice_is_vlan_promisc_allowed(vf); 2539*f4e667ebSPrzemek Kitszel int err; 2540*f4e667ebSPrzemek Kitszel u16 i; 2541*f4e667ebSPrzemek Kitszel 2542*f4e667ebSPrzemek Kitszel for (i = 0; i < vfl->num_elements; i++) { 2543*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter *vlan_fltr = &vfl->filters[i]; 2544*f4e667ebSPrzemek Kitszel struct virtchnl_vlan *vc_vlan; 2545*f4e667ebSPrzemek Kitszel 2546*f4e667ebSPrzemek Kitszel vc_vlan = &vlan_fltr->outer; 2547*f4e667ebSPrzemek Kitszel if (ice_vc_is_valid_vlan(vc_vlan)) { 2548*f4e667ebSPrzemek Kitszel struct ice_vlan vlan = ice_vc_to_vlan(vc_vlan); 2549*f4e667ebSPrzemek Kitszel 2550*f4e667ebSPrzemek Kitszel err = ice_vc_vlan_action(vsi, 2551*f4e667ebSPrzemek Kitszel vsi->outer_vlan_ops.del_vlan, 2552*f4e667ebSPrzemek Kitszel &vlan); 2553*f4e667ebSPrzemek Kitszel if (err) 2554*f4e667ebSPrzemek Kitszel return err; 2555*f4e667ebSPrzemek Kitszel 2556*f4e667ebSPrzemek Kitszel if (vlan_promisc) 2557*f4e667ebSPrzemek Kitszel ice_vf_dis_vlan_promisc(vsi, &vlan); 2558*f4e667ebSPrzemek Kitszel 2559*f4e667ebSPrzemek Kitszel /* Disable VLAN filtering when only VLAN 0 is left */ 2560*f4e667ebSPrzemek Kitszel if (!ice_vsi_has_non_zero_vlans(vsi) && ice_is_dvm_ena(&vsi->back->hw)) { 2561*f4e667ebSPrzemek Kitszel err = vsi->outer_vlan_ops.dis_tx_filtering(vsi); 2562*f4e667ebSPrzemek Kitszel if (err) 2563*f4e667ebSPrzemek Kitszel return err; 2564*f4e667ebSPrzemek Kitszel } 2565*f4e667ebSPrzemek Kitszel } 2566*f4e667ebSPrzemek Kitszel 2567*f4e667ebSPrzemek Kitszel vc_vlan = &vlan_fltr->inner; 2568*f4e667ebSPrzemek Kitszel if (ice_vc_is_valid_vlan(vc_vlan)) { 2569*f4e667ebSPrzemek Kitszel struct ice_vlan vlan = ice_vc_to_vlan(vc_vlan); 2570*f4e667ebSPrzemek Kitszel 2571*f4e667ebSPrzemek Kitszel err = ice_vc_vlan_action(vsi, 2572*f4e667ebSPrzemek Kitszel vsi->inner_vlan_ops.del_vlan, 2573*f4e667ebSPrzemek Kitszel &vlan); 2574*f4e667ebSPrzemek Kitszel if (err) 2575*f4e667ebSPrzemek Kitszel return err; 2576*f4e667ebSPrzemek Kitszel 2577*f4e667ebSPrzemek Kitszel /* no support for VLAN promiscuous on inner VLAN unless 2578*f4e667ebSPrzemek Kitszel * we are in Single VLAN Mode (SVM) 2579*f4e667ebSPrzemek Kitszel */ 2580*f4e667ebSPrzemek Kitszel if (!ice_is_dvm_ena(&vsi->back->hw)) { 2581*f4e667ebSPrzemek Kitszel if (vlan_promisc) 2582*f4e667ebSPrzemek Kitszel ice_vf_dis_vlan_promisc(vsi, &vlan); 2583*f4e667ebSPrzemek Kitszel 2584*f4e667ebSPrzemek Kitszel /* Disable VLAN filtering when only VLAN 0 is left */ 2585*f4e667ebSPrzemek Kitszel if (!ice_vsi_has_non_zero_vlans(vsi)) { 2586*f4e667ebSPrzemek Kitszel err = vsi->inner_vlan_ops.dis_tx_filtering(vsi); 2587*f4e667ebSPrzemek Kitszel if (err) 2588*f4e667ebSPrzemek Kitszel return err; 2589*f4e667ebSPrzemek Kitszel } 2590*f4e667ebSPrzemek Kitszel } 2591*f4e667ebSPrzemek Kitszel } 2592*f4e667ebSPrzemek Kitszel } 2593*f4e667ebSPrzemek Kitszel 2594*f4e667ebSPrzemek Kitszel return 0; 2595*f4e667ebSPrzemek Kitszel } 2596*f4e667ebSPrzemek Kitszel 2597*f4e667ebSPrzemek Kitszel /** 2598*f4e667ebSPrzemek Kitszel * ice_vc_remove_vlan_v2_msg - virtchnl handler for VIRTCHNL_OP_DEL_VLAN_V2 2599*f4e667ebSPrzemek Kitszel * @vf: VF the message was received from 2600*f4e667ebSPrzemek Kitszel * @msg: message received from the VF 2601*f4e667ebSPrzemek Kitszel */ 2602*f4e667ebSPrzemek Kitszel static int ice_vc_remove_vlan_v2_msg(struct ice_vf *vf, u8 *msg) 2603*f4e667ebSPrzemek Kitszel { 2604*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter_list_v2 *vfl = 2605*f4e667ebSPrzemek Kitszel (struct virtchnl_vlan_filter_list_v2 *)msg; 2606*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 2607*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 2608*f4e667ebSPrzemek Kitszel 2609*f4e667ebSPrzemek Kitszel if (!ice_vc_validate_vlan_filter_list(&vf->vlan_v2_caps.filtering, 2610*f4e667ebSPrzemek Kitszel vfl)) { 2611*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2612*f4e667ebSPrzemek Kitszel goto out; 2613*f4e667ebSPrzemek Kitszel } 2614*f4e667ebSPrzemek Kitszel 2615*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vfl->vport_id)) { 2616*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2617*f4e667ebSPrzemek Kitszel goto out; 2618*f4e667ebSPrzemek Kitszel } 2619*f4e667ebSPrzemek Kitszel 2620*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 2621*f4e667ebSPrzemek Kitszel if (!vsi) { 2622*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2623*f4e667ebSPrzemek Kitszel goto out; 2624*f4e667ebSPrzemek Kitszel } 2625*f4e667ebSPrzemek Kitszel 2626*f4e667ebSPrzemek Kitszel if (ice_vc_del_vlans(vf, vsi, vfl)) 2627*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2628*f4e667ebSPrzemek Kitszel 2629*f4e667ebSPrzemek Kitszel out: 2630*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DEL_VLAN_V2, v_ret, NULL, 2631*f4e667ebSPrzemek Kitszel 0); 2632*f4e667ebSPrzemek Kitszel } 2633*f4e667ebSPrzemek Kitszel 2634*f4e667ebSPrzemek Kitszel /** 2635*f4e667ebSPrzemek Kitszel * ice_vc_add_vlans - add VLAN(s) from the virtchnl filter list 2636*f4e667ebSPrzemek Kitszel * @vf: VF used to add the VLAN(s) 2637*f4e667ebSPrzemek Kitszel * @vsi: VF's VSI used to add the VLAN(s) 2638*f4e667ebSPrzemek Kitszel * @vfl: virthchnl filter list used to add the filters 2639*f4e667ebSPrzemek Kitszel */ 2640*f4e667ebSPrzemek Kitszel static int 2641*f4e667ebSPrzemek Kitszel ice_vc_add_vlans(struct ice_vf *vf, struct ice_vsi *vsi, 2642*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter_list_v2 *vfl) 2643*f4e667ebSPrzemek Kitszel { 2644*f4e667ebSPrzemek Kitszel bool vlan_promisc = ice_is_vlan_promisc_allowed(vf); 2645*f4e667ebSPrzemek Kitszel int err; 2646*f4e667ebSPrzemek Kitszel u16 i; 2647*f4e667ebSPrzemek Kitszel 2648*f4e667ebSPrzemek Kitszel for (i = 0; i < vfl->num_elements; i++) { 2649*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter *vlan_fltr = &vfl->filters[i]; 2650*f4e667ebSPrzemek Kitszel struct virtchnl_vlan *vc_vlan; 2651*f4e667ebSPrzemek Kitszel 2652*f4e667ebSPrzemek Kitszel vc_vlan = &vlan_fltr->outer; 2653*f4e667ebSPrzemek Kitszel if (ice_vc_is_valid_vlan(vc_vlan)) { 2654*f4e667ebSPrzemek Kitszel struct ice_vlan vlan = ice_vc_to_vlan(vc_vlan); 2655*f4e667ebSPrzemek Kitszel 2656*f4e667ebSPrzemek Kitszel err = ice_vc_vlan_action(vsi, 2657*f4e667ebSPrzemek Kitszel vsi->outer_vlan_ops.add_vlan, 2658*f4e667ebSPrzemek Kitszel &vlan); 2659*f4e667ebSPrzemek Kitszel if (err) 2660*f4e667ebSPrzemek Kitszel return err; 2661*f4e667ebSPrzemek Kitszel 2662*f4e667ebSPrzemek Kitszel if (vlan_promisc) { 2663*f4e667ebSPrzemek Kitszel err = ice_vf_ena_vlan_promisc(vf, vsi, &vlan); 2664*f4e667ebSPrzemek Kitszel if (err) 2665*f4e667ebSPrzemek Kitszel return err; 2666*f4e667ebSPrzemek Kitszel } 2667*f4e667ebSPrzemek Kitszel 2668*f4e667ebSPrzemek Kitszel /* Enable VLAN filtering on first non-zero VLAN */ 2669*f4e667ebSPrzemek Kitszel if (vf->spoofchk && vlan.vid && ice_is_dvm_ena(&vsi->back->hw)) { 2670*f4e667ebSPrzemek Kitszel err = vsi->outer_vlan_ops.ena_tx_filtering(vsi); 2671*f4e667ebSPrzemek Kitszel if (err) 2672*f4e667ebSPrzemek Kitszel return err; 2673*f4e667ebSPrzemek Kitszel } 2674*f4e667ebSPrzemek Kitszel } 2675*f4e667ebSPrzemek Kitszel 2676*f4e667ebSPrzemek Kitszel vc_vlan = &vlan_fltr->inner; 2677*f4e667ebSPrzemek Kitszel if (ice_vc_is_valid_vlan(vc_vlan)) { 2678*f4e667ebSPrzemek Kitszel struct ice_vlan vlan = ice_vc_to_vlan(vc_vlan); 2679*f4e667ebSPrzemek Kitszel 2680*f4e667ebSPrzemek Kitszel err = ice_vc_vlan_action(vsi, 2681*f4e667ebSPrzemek Kitszel vsi->inner_vlan_ops.add_vlan, 2682*f4e667ebSPrzemek Kitszel &vlan); 2683*f4e667ebSPrzemek Kitszel if (err) 2684*f4e667ebSPrzemek Kitszel return err; 2685*f4e667ebSPrzemek Kitszel 2686*f4e667ebSPrzemek Kitszel /* no support for VLAN promiscuous on inner VLAN unless 2687*f4e667ebSPrzemek Kitszel * we are in Single VLAN Mode (SVM) 2688*f4e667ebSPrzemek Kitszel */ 2689*f4e667ebSPrzemek Kitszel if (!ice_is_dvm_ena(&vsi->back->hw)) { 2690*f4e667ebSPrzemek Kitszel if (vlan_promisc) { 2691*f4e667ebSPrzemek Kitszel err = ice_vf_ena_vlan_promisc(vf, vsi, 2692*f4e667ebSPrzemek Kitszel &vlan); 2693*f4e667ebSPrzemek Kitszel if (err) 2694*f4e667ebSPrzemek Kitszel return err; 2695*f4e667ebSPrzemek Kitszel } 2696*f4e667ebSPrzemek Kitszel 2697*f4e667ebSPrzemek Kitszel /* Enable VLAN filtering on first non-zero VLAN */ 2698*f4e667ebSPrzemek Kitszel if (vf->spoofchk && vlan.vid) { 2699*f4e667ebSPrzemek Kitszel err = vsi->inner_vlan_ops.ena_tx_filtering(vsi); 2700*f4e667ebSPrzemek Kitszel if (err) 2701*f4e667ebSPrzemek Kitszel return err; 2702*f4e667ebSPrzemek Kitszel } 2703*f4e667ebSPrzemek Kitszel } 2704*f4e667ebSPrzemek Kitszel } 2705*f4e667ebSPrzemek Kitszel } 2706*f4e667ebSPrzemek Kitszel 2707*f4e667ebSPrzemek Kitszel return 0; 2708*f4e667ebSPrzemek Kitszel } 2709*f4e667ebSPrzemek Kitszel 2710*f4e667ebSPrzemek Kitszel /** 2711*f4e667ebSPrzemek Kitszel * ice_vc_validate_add_vlan_filter_list - validate add filter list from the VF 2712*f4e667ebSPrzemek Kitszel * @vsi: VF VSI used to get number of existing VLAN filters 2713*f4e667ebSPrzemek Kitszel * @vfc: negotiated/supported VLAN filtering capabilities 2714*f4e667ebSPrzemek Kitszel * @vfl: VLAN filter list from VF to validate 2715*f4e667ebSPrzemek Kitszel * 2716*f4e667ebSPrzemek Kitszel * Validate all of the filters in the VLAN filter list from the VF during the 2717*f4e667ebSPrzemek Kitszel * VIRTCHNL_OP_ADD_VLAN_V2 opcode. If any of the checks fail then return false. 2718*f4e667ebSPrzemek Kitszel * Otherwise return true. 2719*f4e667ebSPrzemek Kitszel */ 2720*f4e667ebSPrzemek Kitszel static bool 2721*f4e667ebSPrzemek Kitszel ice_vc_validate_add_vlan_filter_list(struct ice_vsi *vsi, 2722*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filtering_caps *vfc, 2723*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter_list_v2 *vfl) 2724*f4e667ebSPrzemek Kitszel { 2725*f4e667ebSPrzemek Kitszel u16 num_requested_filters = ice_vsi_num_non_zero_vlans(vsi) + 2726*f4e667ebSPrzemek Kitszel vfl->num_elements; 2727*f4e667ebSPrzemek Kitszel 2728*f4e667ebSPrzemek Kitszel if (num_requested_filters > vfc->max_filters) 2729*f4e667ebSPrzemek Kitszel return false; 2730*f4e667ebSPrzemek Kitszel 2731*f4e667ebSPrzemek Kitszel return ice_vc_validate_vlan_filter_list(vfc, vfl); 2732*f4e667ebSPrzemek Kitszel } 2733*f4e667ebSPrzemek Kitszel 2734*f4e667ebSPrzemek Kitszel /** 2735*f4e667ebSPrzemek Kitszel * ice_vc_add_vlan_v2_msg - virtchnl handler for VIRTCHNL_OP_ADD_VLAN_V2 2736*f4e667ebSPrzemek Kitszel * @vf: VF the message was received from 2737*f4e667ebSPrzemek Kitszel * @msg: message received from the VF 2738*f4e667ebSPrzemek Kitszel */ 2739*f4e667ebSPrzemek Kitszel static int ice_vc_add_vlan_v2_msg(struct ice_vf *vf, u8 *msg) 2740*f4e667ebSPrzemek Kitszel { 2741*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 2742*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_filter_list_v2 *vfl = 2743*f4e667ebSPrzemek Kitszel (struct virtchnl_vlan_filter_list_v2 *)msg; 2744*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 2745*f4e667ebSPrzemek Kitszel 2746*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 2747*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2748*f4e667ebSPrzemek Kitszel goto out; 2749*f4e667ebSPrzemek Kitszel } 2750*f4e667ebSPrzemek Kitszel 2751*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, vfl->vport_id)) { 2752*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2753*f4e667ebSPrzemek Kitszel goto out; 2754*f4e667ebSPrzemek Kitszel } 2755*f4e667ebSPrzemek Kitszel 2756*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 2757*f4e667ebSPrzemek Kitszel if (!vsi) { 2758*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2759*f4e667ebSPrzemek Kitszel goto out; 2760*f4e667ebSPrzemek Kitszel } 2761*f4e667ebSPrzemek Kitszel 2762*f4e667ebSPrzemek Kitszel if (!ice_vc_validate_add_vlan_filter_list(vsi, 2763*f4e667ebSPrzemek Kitszel &vf->vlan_v2_caps.filtering, 2764*f4e667ebSPrzemek Kitszel vfl)) { 2765*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2766*f4e667ebSPrzemek Kitszel goto out; 2767*f4e667ebSPrzemek Kitszel } 2768*f4e667ebSPrzemek Kitszel 2769*f4e667ebSPrzemek Kitszel if (ice_vc_add_vlans(vf, vsi, vfl)) 2770*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2771*f4e667ebSPrzemek Kitszel 2772*f4e667ebSPrzemek Kitszel out: 2773*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_VLAN_V2, v_ret, NULL, 2774*f4e667ebSPrzemek Kitszel 0); 2775*f4e667ebSPrzemek Kitszel } 2776*f4e667ebSPrzemek Kitszel 2777*f4e667ebSPrzemek Kitszel /** 2778*f4e667ebSPrzemek Kitszel * ice_vc_valid_vlan_setting - validate VLAN setting 2779*f4e667ebSPrzemek Kitszel * @negotiated_settings: negotiated VLAN settings during VF init 2780*f4e667ebSPrzemek Kitszel * @ethertype_setting: ethertype(s) requested for the VLAN setting 2781*f4e667ebSPrzemek Kitszel */ 2782*f4e667ebSPrzemek Kitszel static bool 2783*f4e667ebSPrzemek Kitszel ice_vc_valid_vlan_setting(u32 negotiated_settings, u32 ethertype_setting) 2784*f4e667ebSPrzemek Kitszel { 2785*f4e667ebSPrzemek Kitszel if (ethertype_setting && !(negotiated_settings & ethertype_setting)) 2786*f4e667ebSPrzemek Kitszel return false; 2787*f4e667ebSPrzemek Kitszel 2788*f4e667ebSPrzemek Kitszel /* only allow a single VIRTCHNL_VLAN_ETHERTYPE if 2789*f4e667ebSPrzemek Kitszel * VIRTHCNL_VLAN_ETHERTYPE_AND is not negotiated/supported 2790*f4e667ebSPrzemek Kitszel */ 2791*f4e667ebSPrzemek Kitszel if (!(negotiated_settings & VIRTCHNL_VLAN_ETHERTYPE_AND) && 2792*f4e667ebSPrzemek Kitszel hweight32(ethertype_setting) > 1) 2793*f4e667ebSPrzemek Kitszel return false; 2794*f4e667ebSPrzemek Kitszel 2795*f4e667ebSPrzemek Kitszel /* ability to modify the VLAN setting was not negotiated */ 2796*f4e667ebSPrzemek Kitszel if (!(negotiated_settings & VIRTCHNL_VLAN_TOGGLE)) 2797*f4e667ebSPrzemek Kitszel return false; 2798*f4e667ebSPrzemek Kitszel 2799*f4e667ebSPrzemek Kitszel return true; 2800*f4e667ebSPrzemek Kitszel } 2801*f4e667ebSPrzemek Kitszel 2802*f4e667ebSPrzemek Kitszel /** 2803*f4e667ebSPrzemek Kitszel * ice_vc_valid_vlan_setting_msg - validate the VLAN setting message 2804*f4e667ebSPrzemek Kitszel * @caps: negotiated VLAN settings during VF init 2805*f4e667ebSPrzemek Kitszel * @msg: message to validate 2806*f4e667ebSPrzemek Kitszel * 2807*f4e667ebSPrzemek Kitszel * Used to validate any VLAN virtchnl message sent as a 2808*f4e667ebSPrzemek Kitszel * virtchnl_vlan_setting structure. Validates the message against the 2809*f4e667ebSPrzemek Kitszel * negotiated/supported caps during VF driver init. 2810*f4e667ebSPrzemek Kitszel */ 2811*f4e667ebSPrzemek Kitszel static bool 2812*f4e667ebSPrzemek Kitszel ice_vc_valid_vlan_setting_msg(struct virtchnl_vlan_supported_caps *caps, 2813*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_setting *msg) 2814*f4e667ebSPrzemek Kitszel { 2815*f4e667ebSPrzemek Kitszel if ((!msg->outer_ethertype_setting && 2816*f4e667ebSPrzemek Kitszel !msg->inner_ethertype_setting) || 2817*f4e667ebSPrzemek Kitszel (!caps->outer && !caps->inner)) 2818*f4e667ebSPrzemek Kitszel return false; 2819*f4e667ebSPrzemek Kitszel 2820*f4e667ebSPrzemek Kitszel if (msg->outer_ethertype_setting && 2821*f4e667ebSPrzemek Kitszel !ice_vc_valid_vlan_setting(caps->outer, 2822*f4e667ebSPrzemek Kitszel msg->outer_ethertype_setting)) 2823*f4e667ebSPrzemek Kitszel return false; 2824*f4e667ebSPrzemek Kitszel 2825*f4e667ebSPrzemek Kitszel if (msg->inner_ethertype_setting && 2826*f4e667ebSPrzemek Kitszel !ice_vc_valid_vlan_setting(caps->inner, 2827*f4e667ebSPrzemek Kitszel msg->inner_ethertype_setting)) 2828*f4e667ebSPrzemek Kitszel return false; 2829*f4e667ebSPrzemek Kitszel 2830*f4e667ebSPrzemek Kitszel return true; 2831*f4e667ebSPrzemek Kitszel } 2832*f4e667ebSPrzemek Kitszel 2833*f4e667ebSPrzemek Kitszel /** 2834*f4e667ebSPrzemek Kitszel * ice_vc_get_tpid - transform from VIRTCHNL_VLAN_ETHERTYPE_* to VLAN TPID 2835*f4e667ebSPrzemek Kitszel * @ethertype_setting: VIRTCHNL_VLAN_ETHERTYPE_* used to get VLAN TPID 2836*f4e667ebSPrzemek Kitszel * @tpid: VLAN TPID to populate 2837*f4e667ebSPrzemek Kitszel */ 2838*f4e667ebSPrzemek Kitszel static int ice_vc_get_tpid(u32 ethertype_setting, u16 *tpid) 2839*f4e667ebSPrzemek Kitszel { 2840*f4e667ebSPrzemek Kitszel switch (ethertype_setting) { 2841*f4e667ebSPrzemek Kitszel case VIRTCHNL_VLAN_ETHERTYPE_8100: 2842*f4e667ebSPrzemek Kitszel *tpid = ETH_P_8021Q; 2843*f4e667ebSPrzemek Kitszel break; 2844*f4e667ebSPrzemek Kitszel case VIRTCHNL_VLAN_ETHERTYPE_88A8: 2845*f4e667ebSPrzemek Kitszel *tpid = ETH_P_8021AD; 2846*f4e667ebSPrzemek Kitszel break; 2847*f4e667ebSPrzemek Kitszel case VIRTCHNL_VLAN_ETHERTYPE_9100: 2848*f4e667ebSPrzemek Kitszel *tpid = ETH_P_QINQ1; 2849*f4e667ebSPrzemek Kitszel break; 2850*f4e667ebSPrzemek Kitszel default: 2851*f4e667ebSPrzemek Kitszel *tpid = 0; 2852*f4e667ebSPrzemek Kitszel return -EINVAL; 2853*f4e667ebSPrzemek Kitszel } 2854*f4e667ebSPrzemek Kitszel 2855*f4e667ebSPrzemek Kitszel return 0; 2856*f4e667ebSPrzemek Kitszel } 2857*f4e667ebSPrzemek Kitszel 2858*f4e667ebSPrzemek Kitszel /** 2859*f4e667ebSPrzemek Kitszel * ice_vc_ena_vlan_offload - enable VLAN offload based on the ethertype_setting 2860*f4e667ebSPrzemek Kitszel * @vsi: VF's VSI used to enable the VLAN offload 2861*f4e667ebSPrzemek Kitszel * @ena_offload: function used to enable the VLAN offload 2862*f4e667ebSPrzemek Kitszel * @ethertype_setting: VIRTCHNL_VLAN_ETHERTYPE_* to enable offloads for 2863*f4e667ebSPrzemek Kitszel */ 2864*f4e667ebSPrzemek Kitszel static int 2865*f4e667ebSPrzemek Kitszel ice_vc_ena_vlan_offload(struct ice_vsi *vsi, 2866*f4e667ebSPrzemek Kitszel int (*ena_offload)(struct ice_vsi *vsi, u16 tpid), 2867*f4e667ebSPrzemek Kitszel u32 ethertype_setting) 2868*f4e667ebSPrzemek Kitszel { 2869*f4e667ebSPrzemek Kitszel u16 tpid; 2870*f4e667ebSPrzemek Kitszel int err; 2871*f4e667ebSPrzemek Kitszel 2872*f4e667ebSPrzemek Kitszel err = ice_vc_get_tpid(ethertype_setting, &tpid); 2873*f4e667ebSPrzemek Kitszel if (err) 2874*f4e667ebSPrzemek Kitszel return err; 2875*f4e667ebSPrzemek Kitszel 2876*f4e667ebSPrzemek Kitszel err = ena_offload(vsi, tpid); 2877*f4e667ebSPrzemek Kitszel if (err) 2878*f4e667ebSPrzemek Kitszel return err; 2879*f4e667ebSPrzemek Kitszel 2880*f4e667ebSPrzemek Kitszel return 0; 2881*f4e667ebSPrzemek Kitszel } 2882*f4e667ebSPrzemek Kitszel 2883*f4e667ebSPrzemek Kitszel /** 2884*f4e667ebSPrzemek Kitszel * ice_vc_ena_vlan_stripping_v2_msg 2885*f4e667ebSPrzemek Kitszel * @vf: VF the message was received from 2886*f4e667ebSPrzemek Kitszel * @msg: message received from the VF 2887*f4e667ebSPrzemek Kitszel * 2888*f4e667ebSPrzemek Kitszel * virthcnl handler for VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 2889*f4e667ebSPrzemek Kitszel */ 2890*f4e667ebSPrzemek Kitszel static int ice_vc_ena_vlan_stripping_v2_msg(struct ice_vf *vf, u8 *msg) 2891*f4e667ebSPrzemek Kitszel { 2892*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 2893*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_supported_caps *stripping_support; 2894*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_setting *strip_msg = 2895*f4e667ebSPrzemek Kitszel (struct virtchnl_vlan_setting *)msg; 2896*f4e667ebSPrzemek Kitszel u32 ethertype_setting; 2897*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 2898*f4e667ebSPrzemek Kitszel 2899*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 2900*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2901*f4e667ebSPrzemek Kitszel goto out; 2902*f4e667ebSPrzemek Kitszel } 2903*f4e667ebSPrzemek Kitszel 2904*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, strip_msg->vport_id)) { 2905*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2906*f4e667ebSPrzemek Kitszel goto out; 2907*f4e667ebSPrzemek Kitszel } 2908*f4e667ebSPrzemek Kitszel 2909*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 2910*f4e667ebSPrzemek Kitszel if (!vsi) { 2911*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2912*f4e667ebSPrzemek Kitszel goto out; 2913*f4e667ebSPrzemek Kitszel } 2914*f4e667ebSPrzemek Kitszel 2915*f4e667ebSPrzemek Kitszel stripping_support = &vf->vlan_v2_caps.offloads.stripping_support; 2916*f4e667ebSPrzemek Kitszel if (!ice_vc_valid_vlan_setting_msg(stripping_support, strip_msg)) { 2917*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2918*f4e667ebSPrzemek Kitszel goto out; 2919*f4e667ebSPrzemek Kitszel } 2920*f4e667ebSPrzemek Kitszel 2921*f4e667ebSPrzemek Kitszel if (ice_vsi_is_rxq_crc_strip_dis(vsi)) { 2922*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 2923*f4e667ebSPrzemek Kitszel goto out; 2924*f4e667ebSPrzemek Kitszel } 2925*f4e667ebSPrzemek Kitszel 2926*f4e667ebSPrzemek Kitszel ethertype_setting = strip_msg->outer_ethertype_setting; 2927*f4e667ebSPrzemek Kitszel if (ethertype_setting) { 2928*f4e667ebSPrzemek Kitszel if (ice_vc_ena_vlan_offload(vsi, 2929*f4e667ebSPrzemek Kitszel vsi->outer_vlan_ops.ena_stripping, 2930*f4e667ebSPrzemek Kitszel ethertype_setting)) { 2931*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2932*f4e667ebSPrzemek Kitszel goto out; 2933*f4e667ebSPrzemek Kitszel } else { 2934*f4e667ebSPrzemek Kitszel enum ice_l2tsel l2tsel = 2935*f4e667ebSPrzemek Kitszel ICE_L2TSEL_EXTRACT_FIRST_TAG_L2TAG2_2ND; 2936*f4e667ebSPrzemek Kitszel 2937*f4e667ebSPrzemek Kitszel /* PF tells the VF that the outer VLAN tag is always 2938*f4e667ebSPrzemek Kitszel * extracted to VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2_2 and 2939*f4e667ebSPrzemek Kitszel * inner is always extracted to 2940*f4e667ebSPrzemek Kitszel * VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1. This is needed to 2941*f4e667ebSPrzemek Kitszel * support outer stripping so the first tag always ends 2942*f4e667ebSPrzemek Kitszel * up in L2TAG2_2ND and the second/inner tag, if 2943*f4e667ebSPrzemek Kitszel * enabled, is extracted in L2TAG1. 2944*f4e667ebSPrzemek Kitszel */ 2945*f4e667ebSPrzemek Kitszel ice_vsi_update_l2tsel(vsi, l2tsel); 2946*f4e667ebSPrzemek Kitszel 2947*f4e667ebSPrzemek Kitszel vf->vlan_strip_ena |= ICE_OUTER_VLAN_STRIP_ENA; 2948*f4e667ebSPrzemek Kitszel } 2949*f4e667ebSPrzemek Kitszel } 2950*f4e667ebSPrzemek Kitszel 2951*f4e667ebSPrzemek Kitszel ethertype_setting = strip_msg->inner_ethertype_setting; 2952*f4e667ebSPrzemek Kitszel if (ethertype_setting && 2953*f4e667ebSPrzemek Kitszel ice_vc_ena_vlan_offload(vsi, vsi->inner_vlan_ops.ena_stripping, 2954*f4e667ebSPrzemek Kitszel ethertype_setting)) { 2955*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2956*f4e667ebSPrzemek Kitszel goto out; 2957*f4e667ebSPrzemek Kitszel } 2958*f4e667ebSPrzemek Kitszel 2959*f4e667ebSPrzemek Kitszel if (ethertype_setting) 2960*f4e667ebSPrzemek Kitszel vf->vlan_strip_ena |= ICE_INNER_VLAN_STRIP_ENA; 2961*f4e667ebSPrzemek Kitszel 2962*f4e667ebSPrzemek Kitszel out: 2963*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2, 2964*f4e667ebSPrzemek Kitszel v_ret, NULL, 0); 2965*f4e667ebSPrzemek Kitszel } 2966*f4e667ebSPrzemek Kitszel 2967*f4e667ebSPrzemek Kitszel /** 2968*f4e667ebSPrzemek Kitszel * ice_vc_dis_vlan_stripping_v2_msg 2969*f4e667ebSPrzemek Kitszel * @vf: VF the message was received from 2970*f4e667ebSPrzemek Kitszel * @msg: message received from the VF 2971*f4e667ebSPrzemek Kitszel * 2972*f4e667ebSPrzemek Kitszel * virthcnl handler for VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2 2973*f4e667ebSPrzemek Kitszel */ 2974*f4e667ebSPrzemek Kitszel static int ice_vc_dis_vlan_stripping_v2_msg(struct ice_vf *vf, u8 *msg) 2975*f4e667ebSPrzemek Kitszel { 2976*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 2977*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_supported_caps *stripping_support; 2978*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_setting *strip_msg = 2979*f4e667ebSPrzemek Kitszel (struct virtchnl_vlan_setting *)msg; 2980*f4e667ebSPrzemek Kitszel u32 ethertype_setting; 2981*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 2982*f4e667ebSPrzemek Kitszel 2983*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 2984*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2985*f4e667ebSPrzemek Kitszel goto out; 2986*f4e667ebSPrzemek Kitszel } 2987*f4e667ebSPrzemek Kitszel 2988*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, strip_msg->vport_id)) { 2989*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2990*f4e667ebSPrzemek Kitszel goto out; 2991*f4e667ebSPrzemek Kitszel } 2992*f4e667ebSPrzemek Kitszel 2993*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 2994*f4e667ebSPrzemek Kitszel if (!vsi) { 2995*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2996*f4e667ebSPrzemek Kitszel goto out; 2997*f4e667ebSPrzemek Kitszel } 2998*f4e667ebSPrzemek Kitszel 2999*f4e667ebSPrzemek Kitszel stripping_support = &vf->vlan_v2_caps.offloads.stripping_support; 3000*f4e667ebSPrzemek Kitszel if (!ice_vc_valid_vlan_setting_msg(stripping_support, strip_msg)) { 3001*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3002*f4e667ebSPrzemek Kitszel goto out; 3003*f4e667ebSPrzemek Kitszel } 3004*f4e667ebSPrzemek Kitszel 3005*f4e667ebSPrzemek Kitszel ethertype_setting = strip_msg->outer_ethertype_setting; 3006*f4e667ebSPrzemek Kitszel if (ethertype_setting) { 3007*f4e667ebSPrzemek Kitszel if (vsi->outer_vlan_ops.dis_stripping(vsi)) { 3008*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3009*f4e667ebSPrzemek Kitszel goto out; 3010*f4e667ebSPrzemek Kitszel } else { 3011*f4e667ebSPrzemek Kitszel enum ice_l2tsel l2tsel = 3012*f4e667ebSPrzemek Kitszel ICE_L2TSEL_EXTRACT_FIRST_TAG_L2TAG1; 3013*f4e667ebSPrzemek Kitszel 3014*f4e667ebSPrzemek Kitszel /* PF tells the VF that the outer VLAN tag is always 3015*f4e667ebSPrzemek Kitszel * extracted to VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2_2 and 3016*f4e667ebSPrzemek Kitszel * inner is always extracted to 3017*f4e667ebSPrzemek Kitszel * VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1. This is needed to 3018*f4e667ebSPrzemek Kitszel * support inner stripping while outer stripping is 3019*f4e667ebSPrzemek Kitszel * disabled so that the first and only tag is extracted 3020*f4e667ebSPrzemek Kitszel * in L2TAG1. 3021*f4e667ebSPrzemek Kitszel */ 3022*f4e667ebSPrzemek Kitszel ice_vsi_update_l2tsel(vsi, l2tsel); 3023*f4e667ebSPrzemek Kitszel 3024*f4e667ebSPrzemek Kitszel vf->vlan_strip_ena &= ~ICE_OUTER_VLAN_STRIP_ENA; 3025*f4e667ebSPrzemek Kitszel } 3026*f4e667ebSPrzemek Kitszel } 3027*f4e667ebSPrzemek Kitszel 3028*f4e667ebSPrzemek Kitszel ethertype_setting = strip_msg->inner_ethertype_setting; 3029*f4e667ebSPrzemek Kitszel if (ethertype_setting && vsi->inner_vlan_ops.dis_stripping(vsi)) { 3030*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3031*f4e667ebSPrzemek Kitszel goto out; 3032*f4e667ebSPrzemek Kitszel } 3033*f4e667ebSPrzemek Kitszel 3034*f4e667ebSPrzemek Kitszel if (ethertype_setting) 3035*f4e667ebSPrzemek Kitszel vf->vlan_strip_ena &= ~ICE_INNER_VLAN_STRIP_ENA; 3036*f4e667ebSPrzemek Kitszel 3037*f4e667ebSPrzemek Kitszel out: 3038*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2, 3039*f4e667ebSPrzemek Kitszel v_ret, NULL, 0); 3040*f4e667ebSPrzemek Kitszel } 3041*f4e667ebSPrzemek Kitszel 3042*f4e667ebSPrzemek Kitszel /** 3043*f4e667ebSPrzemek Kitszel * ice_vc_ena_vlan_insertion_v2_msg 3044*f4e667ebSPrzemek Kitszel * @vf: VF the message was received from 3045*f4e667ebSPrzemek Kitszel * @msg: message received from the VF 3046*f4e667ebSPrzemek Kitszel * 3047*f4e667ebSPrzemek Kitszel * virthcnl handler for VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 3048*f4e667ebSPrzemek Kitszel */ 3049*f4e667ebSPrzemek Kitszel static int ice_vc_ena_vlan_insertion_v2_msg(struct ice_vf *vf, u8 *msg) 3050*f4e667ebSPrzemek Kitszel { 3051*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 3052*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_supported_caps *insertion_support; 3053*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_setting *insertion_msg = 3054*f4e667ebSPrzemek Kitszel (struct virtchnl_vlan_setting *)msg; 3055*f4e667ebSPrzemek Kitszel u32 ethertype_setting; 3056*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 3057*f4e667ebSPrzemek Kitszel 3058*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 3059*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3060*f4e667ebSPrzemek Kitszel goto out; 3061*f4e667ebSPrzemek Kitszel } 3062*f4e667ebSPrzemek Kitszel 3063*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, insertion_msg->vport_id)) { 3064*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3065*f4e667ebSPrzemek Kitszel goto out; 3066*f4e667ebSPrzemek Kitszel } 3067*f4e667ebSPrzemek Kitszel 3068*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 3069*f4e667ebSPrzemek Kitszel if (!vsi) { 3070*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3071*f4e667ebSPrzemek Kitszel goto out; 3072*f4e667ebSPrzemek Kitszel } 3073*f4e667ebSPrzemek Kitszel 3074*f4e667ebSPrzemek Kitszel insertion_support = &vf->vlan_v2_caps.offloads.insertion_support; 3075*f4e667ebSPrzemek Kitszel if (!ice_vc_valid_vlan_setting_msg(insertion_support, insertion_msg)) { 3076*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3077*f4e667ebSPrzemek Kitszel goto out; 3078*f4e667ebSPrzemek Kitszel } 3079*f4e667ebSPrzemek Kitszel 3080*f4e667ebSPrzemek Kitszel ethertype_setting = insertion_msg->outer_ethertype_setting; 3081*f4e667ebSPrzemek Kitszel if (ethertype_setting && 3082*f4e667ebSPrzemek Kitszel ice_vc_ena_vlan_offload(vsi, vsi->outer_vlan_ops.ena_insertion, 3083*f4e667ebSPrzemek Kitszel ethertype_setting)) { 3084*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3085*f4e667ebSPrzemek Kitszel goto out; 3086*f4e667ebSPrzemek Kitszel } 3087*f4e667ebSPrzemek Kitszel 3088*f4e667ebSPrzemek Kitszel ethertype_setting = insertion_msg->inner_ethertype_setting; 3089*f4e667ebSPrzemek Kitszel if (ethertype_setting && 3090*f4e667ebSPrzemek Kitszel ice_vc_ena_vlan_offload(vsi, vsi->inner_vlan_ops.ena_insertion, 3091*f4e667ebSPrzemek Kitszel ethertype_setting)) { 3092*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3093*f4e667ebSPrzemek Kitszel goto out; 3094*f4e667ebSPrzemek Kitszel } 3095*f4e667ebSPrzemek Kitszel 3096*f4e667ebSPrzemek Kitszel out: 3097*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2, 3098*f4e667ebSPrzemek Kitszel v_ret, NULL, 0); 3099*f4e667ebSPrzemek Kitszel } 3100*f4e667ebSPrzemek Kitszel 3101*f4e667ebSPrzemek Kitszel /** 3102*f4e667ebSPrzemek Kitszel * ice_vc_dis_vlan_insertion_v2_msg 3103*f4e667ebSPrzemek Kitszel * @vf: VF the message was received from 3104*f4e667ebSPrzemek Kitszel * @msg: message received from the VF 3105*f4e667ebSPrzemek Kitszel * 3106*f4e667ebSPrzemek Kitszel * virthcnl handler for VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2 3107*f4e667ebSPrzemek Kitszel */ 3108*f4e667ebSPrzemek Kitszel static int ice_vc_dis_vlan_insertion_v2_msg(struct ice_vf *vf, u8 *msg) 3109*f4e667ebSPrzemek Kitszel { 3110*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 3111*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_supported_caps *insertion_support; 3112*f4e667ebSPrzemek Kitszel struct virtchnl_vlan_setting *insertion_msg = 3113*f4e667ebSPrzemek Kitszel (struct virtchnl_vlan_setting *)msg; 3114*f4e667ebSPrzemek Kitszel u32 ethertype_setting; 3115*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 3116*f4e667ebSPrzemek Kitszel 3117*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 3118*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3119*f4e667ebSPrzemek Kitszel goto out; 3120*f4e667ebSPrzemek Kitszel } 3121*f4e667ebSPrzemek Kitszel 3122*f4e667ebSPrzemek Kitszel if (!ice_vc_isvalid_vsi_id(vf, insertion_msg->vport_id)) { 3123*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3124*f4e667ebSPrzemek Kitszel goto out; 3125*f4e667ebSPrzemek Kitszel } 3126*f4e667ebSPrzemek Kitszel 3127*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 3128*f4e667ebSPrzemek Kitszel if (!vsi) { 3129*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3130*f4e667ebSPrzemek Kitszel goto out; 3131*f4e667ebSPrzemek Kitszel } 3132*f4e667ebSPrzemek Kitszel 3133*f4e667ebSPrzemek Kitszel insertion_support = &vf->vlan_v2_caps.offloads.insertion_support; 3134*f4e667ebSPrzemek Kitszel if (!ice_vc_valid_vlan_setting_msg(insertion_support, insertion_msg)) { 3135*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3136*f4e667ebSPrzemek Kitszel goto out; 3137*f4e667ebSPrzemek Kitszel } 3138*f4e667ebSPrzemek Kitszel 3139*f4e667ebSPrzemek Kitszel ethertype_setting = insertion_msg->outer_ethertype_setting; 3140*f4e667ebSPrzemek Kitszel if (ethertype_setting && vsi->outer_vlan_ops.dis_insertion(vsi)) { 3141*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3142*f4e667ebSPrzemek Kitszel goto out; 3143*f4e667ebSPrzemek Kitszel } 3144*f4e667ebSPrzemek Kitszel 3145*f4e667ebSPrzemek Kitszel ethertype_setting = insertion_msg->inner_ethertype_setting; 3146*f4e667ebSPrzemek Kitszel if (ethertype_setting && vsi->inner_vlan_ops.dis_insertion(vsi)) { 3147*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3148*f4e667ebSPrzemek Kitszel goto out; 3149*f4e667ebSPrzemek Kitszel } 3150*f4e667ebSPrzemek Kitszel 3151*f4e667ebSPrzemek Kitszel out: 3152*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2, 3153*f4e667ebSPrzemek Kitszel v_ret, NULL, 0); 3154*f4e667ebSPrzemek Kitszel } 3155*f4e667ebSPrzemek Kitszel 3156*f4e667ebSPrzemek Kitszel static int ice_vc_get_ptp_cap(struct ice_vf *vf, 3157*f4e667ebSPrzemek Kitszel const struct virtchnl_ptp_caps *msg) 3158*f4e667ebSPrzemek Kitszel { 3159*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3160*f4e667ebSPrzemek Kitszel u32 caps = VIRTCHNL_1588_PTP_CAP_RX_TSTAMP | 3161*f4e667ebSPrzemek Kitszel VIRTCHNL_1588_PTP_CAP_READ_PHC; 3162*f4e667ebSPrzemek Kitszel 3163*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) 3164*f4e667ebSPrzemek Kitszel goto err; 3165*f4e667ebSPrzemek Kitszel 3166*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_SUCCESS; 3167*f4e667ebSPrzemek Kitszel 3168*f4e667ebSPrzemek Kitszel if (msg->caps & caps) 3169*f4e667ebSPrzemek Kitszel vf->ptp_caps = caps; 3170*f4e667ebSPrzemek Kitszel 3171*f4e667ebSPrzemek Kitszel err: 3172*f4e667ebSPrzemek Kitszel /* send the response back to the VF */ 3173*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_1588_PTP_GET_CAPS, v_ret, 3174*f4e667ebSPrzemek Kitszel (u8 *)&vf->ptp_caps, 3175*f4e667ebSPrzemek Kitszel sizeof(struct virtchnl_ptp_caps)); 3176*f4e667ebSPrzemek Kitszel } 3177*f4e667ebSPrzemek Kitszel 3178*f4e667ebSPrzemek Kitszel static int ice_vc_get_phc_time(struct ice_vf *vf) 3179*f4e667ebSPrzemek Kitszel { 3180*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3181*f4e667ebSPrzemek Kitszel struct virtchnl_phc_time *phc_time = NULL; 3182*f4e667ebSPrzemek Kitszel struct ice_pf *pf = vf->pf; 3183*f4e667ebSPrzemek Kitszel u32 len = 0; 3184*f4e667ebSPrzemek Kitszel int ret; 3185*f4e667ebSPrzemek Kitszel 3186*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) 3187*f4e667ebSPrzemek Kitszel goto err; 3188*f4e667ebSPrzemek Kitszel 3189*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_SUCCESS; 3190*f4e667ebSPrzemek Kitszel 3191*f4e667ebSPrzemek Kitszel phc_time = kzalloc(sizeof(*phc_time), GFP_KERNEL); 3192*f4e667ebSPrzemek Kitszel if (!phc_time) { 3193*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; 3194*f4e667ebSPrzemek Kitszel goto err; 3195*f4e667ebSPrzemek Kitszel } 3196*f4e667ebSPrzemek Kitszel 3197*f4e667ebSPrzemek Kitszel len = sizeof(*phc_time); 3198*f4e667ebSPrzemek Kitszel 3199*f4e667ebSPrzemek Kitszel phc_time->time = ice_ptp_read_src_clk_reg(pf, NULL); 3200*f4e667ebSPrzemek Kitszel 3201*f4e667ebSPrzemek Kitszel err: 3202*f4e667ebSPrzemek Kitszel /* send the response back to the VF */ 3203*f4e667ebSPrzemek Kitszel ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_1588_PTP_GET_TIME, v_ret, 3204*f4e667ebSPrzemek Kitszel (u8 *)phc_time, len); 3205*f4e667ebSPrzemek Kitszel kfree(phc_time); 3206*f4e667ebSPrzemek Kitszel return ret; 3207*f4e667ebSPrzemek Kitszel } 3208*f4e667ebSPrzemek Kitszel 3209*f4e667ebSPrzemek Kitszel static const struct ice_virtchnl_ops ice_virtchnl_dflt_ops = { 3210*f4e667ebSPrzemek Kitszel .get_ver_msg = ice_vc_get_ver_msg, 3211*f4e667ebSPrzemek Kitszel .get_vf_res_msg = ice_vc_get_vf_res_msg, 3212*f4e667ebSPrzemek Kitszel .reset_vf = ice_vc_reset_vf_msg, 3213*f4e667ebSPrzemek Kitszel .add_mac_addr_msg = ice_vc_add_mac_addr_msg, 3214*f4e667ebSPrzemek Kitszel .del_mac_addr_msg = ice_vc_del_mac_addr_msg, 3215*f4e667ebSPrzemek Kitszel .cfg_qs_msg = ice_vc_cfg_qs_msg, 3216*f4e667ebSPrzemek Kitszel .ena_qs_msg = ice_vc_ena_qs_msg, 3217*f4e667ebSPrzemek Kitszel .dis_qs_msg = ice_vc_dis_qs_msg, 3218*f4e667ebSPrzemek Kitszel .request_qs_msg = ice_vc_request_qs_msg, 3219*f4e667ebSPrzemek Kitszel .cfg_irq_map_msg = ice_vc_cfg_irq_map_msg, 3220*f4e667ebSPrzemek Kitszel .config_rss_key = ice_vc_config_rss_key, 3221*f4e667ebSPrzemek Kitszel .config_rss_lut = ice_vc_config_rss_lut, 3222*f4e667ebSPrzemek Kitszel .config_rss_hfunc = ice_vc_config_rss_hfunc, 3223*f4e667ebSPrzemek Kitszel .get_stats_msg = ice_vc_get_stats_msg, 3224*f4e667ebSPrzemek Kitszel .cfg_promiscuous_mode_msg = ice_vc_cfg_promiscuous_mode_msg, 3225*f4e667ebSPrzemek Kitszel .add_vlan_msg = ice_vc_add_vlan_msg, 3226*f4e667ebSPrzemek Kitszel .remove_vlan_msg = ice_vc_remove_vlan_msg, 3227*f4e667ebSPrzemek Kitszel .query_rxdid = ice_vc_query_rxdid, 3228*f4e667ebSPrzemek Kitszel .get_rss_hashcfg = ice_vc_get_rss_hashcfg, 3229*f4e667ebSPrzemek Kitszel .set_rss_hashcfg = ice_vc_set_rss_hashcfg, 3230*f4e667ebSPrzemek Kitszel .ena_vlan_stripping = ice_vc_ena_vlan_stripping, 3231*f4e667ebSPrzemek Kitszel .dis_vlan_stripping = ice_vc_dis_vlan_stripping, 3232*f4e667ebSPrzemek Kitszel .handle_rss_cfg_msg = ice_vc_handle_rss_cfg, 3233*f4e667ebSPrzemek Kitszel .add_fdir_fltr_msg = ice_vc_add_fdir_fltr, 3234*f4e667ebSPrzemek Kitszel .del_fdir_fltr_msg = ice_vc_del_fdir_fltr, 3235*f4e667ebSPrzemek Kitszel .get_offload_vlan_v2_caps = ice_vc_get_offload_vlan_v2_caps, 3236*f4e667ebSPrzemek Kitszel .add_vlan_v2_msg = ice_vc_add_vlan_v2_msg, 3237*f4e667ebSPrzemek Kitszel .remove_vlan_v2_msg = ice_vc_remove_vlan_v2_msg, 3238*f4e667ebSPrzemek Kitszel .ena_vlan_stripping_v2_msg = ice_vc_ena_vlan_stripping_v2_msg, 3239*f4e667ebSPrzemek Kitszel .dis_vlan_stripping_v2_msg = ice_vc_dis_vlan_stripping_v2_msg, 3240*f4e667ebSPrzemek Kitszel .ena_vlan_insertion_v2_msg = ice_vc_ena_vlan_insertion_v2_msg, 3241*f4e667ebSPrzemek Kitszel .dis_vlan_insertion_v2_msg = ice_vc_dis_vlan_insertion_v2_msg, 3242*f4e667ebSPrzemek Kitszel .get_qos_caps = ice_vc_get_qos_caps, 3243*f4e667ebSPrzemek Kitszel .cfg_q_bw = ice_vc_cfg_q_bw, 3244*f4e667ebSPrzemek Kitszel .cfg_q_quanta = ice_vc_cfg_q_quanta, 3245*f4e667ebSPrzemek Kitszel .get_ptp_cap = ice_vc_get_ptp_cap, 3246*f4e667ebSPrzemek Kitszel .get_phc_time = ice_vc_get_phc_time, 3247*f4e667ebSPrzemek Kitszel /* If you add a new op here please make sure to add it to 3248*f4e667ebSPrzemek Kitszel * ice_virtchnl_repr_ops as well. 3249*f4e667ebSPrzemek Kitszel */ 3250*f4e667ebSPrzemek Kitszel }; 3251*f4e667ebSPrzemek Kitszel 3252*f4e667ebSPrzemek Kitszel /** 3253*f4e667ebSPrzemek Kitszel * ice_virtchnl_set_dflt_ops - Switch to default virtchnl ops 3254*f4e667ebSPrzemek Kitszel * @vf: the VF to switch ops 3255*f4e667ebSPrzemek Kitszel */ 3256*f4e667ebSPrzemek Kitszel void ice_virtchnl_set_dflt_ops(struct ice_vf *vf) 3257*f4e667ebSPrzemek Kitszel { 3258*f4e667ebSPrzemek Kitszel vf->virtchnl_ops = &ice_virtchnl_dflt_ops; 3259*f4e667ebSPrzemek Kitszel } 3260*f4e667ebSPrzemek Kitszel 3261*f4e667ebSPrzemek Kitszel /** 3262*f4e667ebSPrzemek Kitszel * ice_vc_repr_add_mac 3263*f4e667ebSPrzemek Kitszel * @vf: pointer to VF 3264*f4e667ebSPrzemek Kitszel * @msg: virtchannel message 3265*f4e667ebSPrzemek Kitszel * 3266*f4e667ebSPrzemek Kitszel * When port representors are created, we do not add MAC rule 3267*f4e667ebSPrzemek Kitszel * to firmware, we store it so that PF could report same 3268*f4e667ebSPrzemek Kitszel * MAC as VF. 3269*f4e667ebSPrzemek Kitszel */ 3270*f4e667ebSPrzemek Kitszel static int ice_vc_repr_add_mac(struct ice_vf *vf, u8 *msg) 3271*f4e667ebSPrzemek Kitszel { 3272*f4e667ebSPrzemek Kitszel enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 3273*f4e667ebSPrzemek Kitszel struct virtchnl_ether_addr_list *al = 3274*f4e667ebSPrzemek Kitszel (struct virtchnl_ether_addr_list *)msg; 3275*f4e667ebSPrzemek Kitszel struct ice_vsi *vsi; 3276*f4e667ebSPrzemek Kitszel struct ice_pf *pf; 3277*f4e667ebSPrzemek Kitszel int i; 3278*f4e667ebSPrzemek Kitszel 3279*f4e667ebSPrzemek Kitszel if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) || 3280*f4e667ebSPrzemek Kitszel !ice_vc_isvalid_vsi_id(vf, al->vsi_id)) { 3281*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3282*f4e667ebSPrzemek Kitszel goto handle_mac_exit; 3283*f4e667ebSPrzemek Kitszel } 3284*f4e667ebSPrzemek Kitszel 3285*f4e667ebSPrzemek Kitszel pf = vf->pf; 3286*f4e667ebSPrzemek Kitszel 3287*f4e667ebSPrzemek Kitszel vsi = ice_get_vf_vsi(vf); 3288*f4e667ebSPrzemek Kitszel if (!vsi) { 3289*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_PARAM; 3290*f4e667ebSPrzemek Kitszel goto handle_mac_exit; 3291*f4e667ebSPrzemek Kitszel } 3292*f4e667ebSPrzemek Kitszel 3293*f4e667ebSPrzemek Kitszel for (i = 0; i < al->num_elements; i++) { 3294*f4e667ebSPrzemek Kitszel u8 *mac_addr = al->list[i].addr; 3295*f4e667ebSPrzemek Kitszel 3296*f4e667ebSPrzemek Kitszel if (!is_unicast_ether_addr(mac_addr) || 3297*f4e667ebSPrzemek Kitszel ether_addr_equal(mac_addr, vf->hw_lan_addr)) 3298*f4e667ebSPrzemek Kitszel continue; 3299*f4e667ebSPrzemek Kitszel 3300*f4e667ebSPrzemek Kitszel if (vf->pf_set_mac) { 3301*f4e667ebSPrzemek Kitszel dev_err(ice_pf_to_dev(pf), "VF attempting to override administratively set MAC address\n"); 3302*f4e667ebSPrzemek Kitszel v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 3303*f4e667ebSPrzemek Kitszel goto handle_mac_exit; 3304*f4e667ebSPrzemek Kitszel } 3305*f4e667ebSPrzemek Kitszel 3306*f4e667ebSPrzemek Kitszel ice_vfhw_mac_add(vf, &al->list[i]); 3307*f4e667ebSPrzemek Kitszel break; 3308*f4e667ebSPrzemek Kitszel } 3309*f4e667ebSPrzemek Kitszel 3310*f4e667ebSPrzemek Kitszel handle_mac_exit: 3311*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_ETH_ADDR, 3312*f4e667ebSPrzemek Kitszel v_ret, NULL, 0); 3313*f4e667ebSPrzemek Kitszel } 3314*f4e667ebSPrzemek Kitszel 3315*f4e667ebSPrzemek Kitszel /** 3316*f4e667ebSPrzemek Kitszel * ice_vc_repr_del_mac - response with success for deleting MAC 3317*f4e667ebSPrzemek Kitszel * @vf: pointer to VF 3318*f4e667ebSPrzemek Kitszel * @msg: virtchannel message 3319*f4e667ebSPrzemek Kitszel * 3320*f4e667ebSPrzemek Kitszel * Respond with success to not break normal VF flow. 3321*f4e667ebSPrzemek Kitszel * For legacy VF driver try to update cached MAC address. 3322*f4e667ebSPrzemek Kitszel */ 3323*f4e667ebSPrzemek Kitszel static int 3324*f4e667ebSPrzemek Kitszel ice_vc_repr_del_mac(struct ice_vf __always_unused *vf, u8 __always_unused *msg) 3325*f4e667ebSPrzemek Kitszel { 3326*f4e667ebSPrzemek Kitszel struct virtchnl_ether_addr_list *al = 3327*f4e667ebSPrzemek Kitszel (struct virtchnl_ether_addr_list *)msg; 3328*f4e667ebSPrzemek Kitszel 3329*f4e667ebSPrzemek Kitszel ice_update_legacy_cached_mac(vf, &al->list[0]); 3330*f4e667ebSPrzemek Kitszel 3331*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DEL_ETH_ADDR, 3332*f4e667ebSPrzemek Kitszel VIRTCHNL_STATUS_SUCCESS, NULL, 0); 3333*f4e667ebSPrzemek Kitszel } 3334*f4e667ebSPrzemek Kitszel 3335*f4e667ebSPrzemek Kitszel static int 3336*f4e667ebSPrzemek Kitszel ice_vc_repr_cfg_promiscuous_mode(struct ice_vf *vf, u8 __always_unused *msg) 3337*f4e667ebSPrzemek Kitszel { 3338*f4e667ebSPrzemek Kitszel dev_dbg(ice_pf_to_dev(vf->pf), 3339*f4e667ebSPrzemek Kitszel "Can't config promiscuous mode in switchdev mode for VF %d\n", 3340*f4e667ebSPrzemek Kitszel vf->vf_id); 3341*f4e667ebSPrzemek Kitszel return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, 3342*f4e667ebSPrzemek Kitszel VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, 3343*f4e667ebSPrzemek Kitszel NULL, 0); 3344*f4e667ebSPrzemek Kitszel } 3345*f4e667ebSPrzemek Kitszel 3346*f4e667ebSPrzemek Kitszel static const struct ice_virtchnl_ops ice_virtchnl_repr_ops = { 3347*f4e667ebSPrzemek Kitszel .get_ver_msg = ice_vc_get_ver_msg, 3348*f4e667ebSPrzemek Kitszel .get_vf_res_msg = ice_vc_get_vf_res_msg, 3349*f4e667ebSPrzemek Kitszel .reset_vf = ice_vc_reset_vf_msg, 3350*f4e667ebSPrzemek Kitszel .add_mac_addr_msg = ice_vc_repr_add_mac, 3351*f4e667ebSPrzemek Kitszel .del_mac_addr_msg = ice_vc_repr_del_mac, 3352*f4e667ebSPrzemek Kitszel .cfg_qs_msg = ice_vc_cfg_qs_msg, 3353*f4e667ebSPrzemek Kitszel .ena_qs_msg = ice_vc_ena_qs_msg, 3354*f4e667ebSPrzemek Kitszel .dis_qs_msg = ice_vc_dis_qs_msg, 3355*f4e667ebSPrzemek Kitszel .request_qs_msg = ice_vc_request_qs_msg, 3356*f4e667ebSPrzemek Kitszel .cfg_irq_map_msg = ice_vc_cfg_irq_map_msg, 3357*f4e667ebSPrzemek Kitszel .config_rss_key = ice_vc_config_rss_key, 3358*f4e667ebSPrzemek Kitszel .config_rss_lut = ice_vc_config_rss_lut, 3359*f4e667ebSPrzemek Kitszel .config_rss_hfunc = ice_vc_config_rss_hfunc, 3360*f4e667ebSPrzemek Kitszel .get_stats_msg = ice_vc_get_stats_msg, 3361*f4e667ebSPrzemek Kitszel .cfg_promiscuous_mode_msg = ice_vc_repr_cfg_promiscuous_mode, 3362*f4e667ebSPrzemek Kitszel .add_vlan_msg = ice_vc_add_vlan_msg, 3363*f4e667ebSPrzemek Kitszel .remove_vlan_msg = ice_vc_remove_vlan_msg, 3364*f4e667ebSPrzemek Kitszel .query_rxdid = ice_vc_query_rxdid, 3365*f4e667ebSPrzemek Kitszel .get_rss_hashcfg = ice_vc_get_rss_hashcfg, 3366*f4e667ebSPrzemek Kitszel .set_rss_hashcfg = ice_vc_set_rss_hashcfg, 3367*f4e667ebSPrzemek Kitszel .ena_vlan_stripping = ice_vc_ena_vlan_stripping, 3368*f4e667ebSPrzemek Kitszel .dis_vlan_stripping = ice_vc_dis_vlan_stripping, 3369*f4e667ebSPrzemek Kitszel .handle_rss_cfg_msg = ice_vc_handle_rss_cfg, 3370*f4e667ebSPrzemek Kitszel .add_fdir_fltr_msg = ice_vc_add_fdir_fltr, 3371*f4e667ebSPrzemek Kitszel .del_fdir_fltr_msg = ice_vc_del_fdir_fltr, 3372*f4e667ebSPrzemek Kitszel .get_offload_vlan_v2_caps = ice_vc_get_offload_vlan_v2_caps, 3373*f4e667ebSPrzemek Kitszel .add_vlan_v2_msg = ice_vc_add_vlan_v2_msg, 3374*f4e667ebSPrzemek Kitszel .remove_vlan_v2_msg = ice_vc_remove_vlan_v2_msg, 3375*f4e667ebSPrzemek Kitszel .ena_vlan_stripping_v2_msg = ice_vc_ena_vlan_stripping_v2_msg, 3376*f4e667ebSPrzemek Kitszel .dis_vlan_stripping_v2_msg = ice_vc_dis_vlan_stripping_v2_msg, 3377*f4e667ebSPrzemek Kitszel .ena_vlan_insertion_v2_msg = ice_vc_ena_vlan_insertion_v2_msg, 3378*f4e667ebSPrzemek Kitszel .dis_vlan_insertion_v2_msg = ice_vc_dis_vlan_insertion_v2_msg, 3379*f4e667ebSPrzemek Kitszel .get_qos_caps = ice_vc_get_qos_caps, 3380*f4e667ebSPrzemek Kitszel .cfg_q_bw = ice_vc_cfg_q_bw, 3381*f4e667ebSPrzemek Kitszel .cfg_q_quanta = ice_vc_cfg_q_quanta, 3382*f4e667ebSPrzemek Kitszel .get_ptp_cap = ice_vc_get_ptp_cap, 3383*f4e667ebSPrzemek Kitszel .get_phc_time = ice_vc_get_phc_time, 3384*f4e667ebSPrzemek Kitszel }; 3385*f4e667ebSPrzemek Kitszel 3386*f4e667ebSPrzemek Kitszel /** 3387*f4e667ebSPrzemek Kitszel * ice_virtchnl_set_repr_ops - Switch to representor virtchnl ops 3388*f4e667ebSPrzemek Kitszel * @vf: the VF to switch ops 3389*f4e667ebSPrzemek Kitszel */ 3390*f4e667ebSPrzemek Kitszel void ice_virtchnl_set_repr_ops(struct ice_vf *vf) 3391*f4e667ebSPrzemek Kitszel { 3392*f4e667ebSPrzemek Kitszel vf->virtchnl_ops = &ice_virtchnl_repr_ops; 3393*f4e667ebSPrzemek Kitszel } 3394*f4e667ebSPrzemek Kitszel 3395*f4e667ebSPrzemek Kitszel /** 3396*f4e667ebSPrzemek Kitszel * ice_is_malicious_vf - check if this vf might be overflowing mailbox 3397*f4e667ebSPrzemek Kitszel * @vf: the VF to check 3398*f4e667ebSPrzemek Kitszel * @mbxdata: data about the state of the mailbox 3399*f4e667ebSPrzemek Kitszel * 3400*f4e667ebSPrzemek Kitszel * Detect if a given VF might be malicious and attempting to overflow the PF 3401*f4e667ebSPrzemek Kitszel * mailbox. If so, log a warning message and ignore this event. 3402*f4e667ebSPrzemek Kitszel */ 3403*f4e667ebSPrzemek Kitszel static bool 3404*f4e667ebSPrzemek Kitszel ice_is_malicious_vf(struct ice_vf *vf, struct ice_mbx_data *mbxdata) 3405*f4e667ebSPrzemek Kitszel { 3406*f4e667ebSPrzemek Kitszel bool report_malvf = false; 3407*f4e667ebSPrzemek Kitszel struct device *dev; 3408*f4e667ebSPrzemek Kitszel struct ice_pf *pf; 3409*f4e667ebSPrzemek Kitszel int status; 3410*f4e667ebSPrzemek Kitszel 3411*f4e667ebSPrzemek Kitszel pf = vf->pf; 3412*f4e667ebSPrzemek Kitszel dev = ice_pf_to_dev(pf); 3413*f4e667ebSPrzemek Kitszel 3414*f4e667ebSPrzemek Kitszel if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) 3415*f4e667ebSPrzemek Kitszel return vf->mbx_info.malicious; 3416*f4e667ebSPrzemek Kitszel 3417*f4e667ebSPrzemek Kitszel /* check to see if we have a newly malicious VF */ 3418*f4e667ebSPrzemek Kitszel status = ice_mbx_vf_state_handler(&pf->hw, mbxdata, &vf->mbx_info, 3419*f4e667ebSPrzemek Kitszel &report_malvf); 3420*f4e667ebSPrzemek Kitszel if (status) 3421*f4e667ebSPrzemek Kitszel dev_warn_ratelimited(dev, "Unable to check status of mailbox overflow for VF %u MAC %pM, status %d\n", 3422*f4e667ebSPrzemek Kitszel vf->vf_id, vf->dev_lan_addr, status); 3423*f4e667ebSPrzemek Kitszel 3424*f4e667ebSPrzemek Kitszel if (report_malvf) { 3425*f4e667ebSPrzemek Kitszel struct ice_vsi *pf_vsi = ice_get_main_vsi(pf); 3426*f4e667ebSPrzemek Kitszel u8 zero_addr[ETH_ALEN] = {}; 3427*f4e667ebSPrzemek Kitszel 3428*f4e667ebSPrzemek Kitszel dev_warn(dev, "VF MAC %pM on PF MAC %pM is generating asynchronous messages and may be overflowing the PF message queue. Please see the Adapter User Guide for more information\n", 3429*f4e667ebSPrzemek Kitszel vf->dev_lan_addr, 3430*f4e667ebSPrzemek Kitszel pf_vsi ? pf_vsi->netdev->dev_addr : zero_addr); 3431*f4e667ebSPrzemek Kitszel } 3432*f4e667ebSPrzemek Kitszel 3433*f4e667ebSPrzemek Kitszel return vf->mbx_info.malicious; 3434*f4e667ebSPrzemek Kitszel } 3435*f4e667ebSPrzemek Kitszel 3436*f4e667ebSPrzemek Kitszel /** 3437*f4e667ebSPrzemek Kitszel * ice_vc_process_vf_msg - Process request from VF 3438*f4e667ebSPrzemek Kitszel * @pf: pointer to the PF structure 3439*f4e667ebSPrzemek Kitszel * @event: pointer to the AQ event 3440*f4e667ebSPrzemek Kitszel * @mbxdata: information used to detect VF attempting mailbox overflow 3441*f4e667ebSPrzemek Kitszel * 3442*f4e667ebSPrzemek Kitszel * Called from the common asq/arq handler to process request from VF. When this 3443*f4e667ebSPrzemek Kitszel * flow is used for devices with hardware VF to PF message queue overflow 3444*f4e667ebSPrzemek Kitszel * support (ICE_F_MBX_LIMIT) mbxdata is set to NULL and ice_is_malicious_vf 3445*f4e667ebSPrzemek Kitszel * check is skipped. 3446*f4e667ebSPrzemek Kitszel */ 3447*f4e667ebSPrzemek Kitszel void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event, 3448*f4e667ebSPrzemek Kitszel struct ice_mbx_data *mbxdata) 3449*f4e667ebSPrzemek Kitszel { 3450*f4e667ebSPrzemek Kitszel u32 v_opcode = le32_to_cpu(event->desc.cookie_high); 3451*f4e667ebSPrzemek Kitszel s16 vf_id = le16_to_cpu(event->desc.retval); 3452*f4e667ebSPrzemek Kitszel const struct ice_virtchnl_ops *ops; 3453*f4e667ebSPrzemek Kitszel u16 msglen = event->msg_len; 3454*f4e667ebSPrzemek Kitszel u8 *msg = event->msg_buf; 3455*f4e667ebSPrzemek Kitszel struct ice_vf *vf = NULL; 3456*f4e667ebSPrzemek Kitszel struct device *dev; 3457*f4e667ebSPrzemek Kitszel int err = 0; 3458*f4e667ebSPrzemek Kitszel 3459*f4e667ebSPrzemek Kitszel dev = ice_pf_to_dev(pf); 3460*f4e667ebSPrzemek Kitszel 3461*f4e667ebSPrzemek Kitszel vf = ice_get_vf_by_id(pf, vf_id); 3462*f4e667ebSPrzemek Kitszel if (!vf) { 3463*f4e667ebSPrzemek Kitszel dev_err(dev, "Unable to locate VF for message from VF ID %d, opcode %d, len %d\n", 3464*f4e667ebSPrzemek Kitszel vf_id, v_opcode, msglen); 3465*f4e667ebSPrzemek Kitszel return; 3466*f4e667ebSPrzemek Kitszel } 3467*f4e667ebSPrzemek Kitszel 3468*f4e667ebSPrzemek Kitszel mutex_lock(&vf->cfg_lock); 3469*f4e667ebSPrzemek Kitszel 3470*f4e667ebSPrzemek Kitszel /* Check if the VF is trying to overflow the mailbox */ 3471*f4e667ebSPrzemek Kitszel if (mbxdata && ice_is_malicious_vf(vf, mbxdata)) 3472*f4e667ebSPrzemek Kitszel goto finish; 3473*f4e667ebSPrzemek Kitszel 3474*f4e667ebSPrzemek Kitszel /* Check if VF is disabled. */ 3475*f4e667ebSPrzemek Kitszel if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) { 3476*f4e667ebSPrzemek Kitszel err = -EPERM; 3477*f4e667ebSPrzemek Kitszel goto error_handler; 3478*f4e667ebSPrzemek Kitszel } 3479*f4e667ebSPrzemek Kitszel 3480*f4e667ebSPrzemek Kitszel ops = vf->virtchnl_ops; 3481*f4e667ebSPrzemek Kitszel 3482*f4e667ebSPrzemek Kitszel /* Perform basic checks on the msg */ 3483*f4e667ebSPrzemek Kitszel err = virtchnl_vc_validate_vf_msg(&vf->vf_ver, v_opcode, msg, msglen); 3484*f4e667ebSPrzemek Kitszel if (err) { 3485*f4e667ebSPrzemek Kitszel if (err == VIRTCHNL_STATUS_ERR_PARAM) 3486*f4e667ebSPrzemek Kitszel err = -EPERM; 3487*f4e667ebSPrzemek Kitszel else 3488*f4e667ebSPrzemek Kitszel err = -EINVAL; 3489*f4e667ebSPrzemek Kitszel } 3490*f4e667ebSPrzemek Kitszel 3491*f4e667ebSPrzemek Kitszel error_handler: 3492*f4e667ebSPrzemek Kitszel if (err) { 3493*f4e667ebSPrzemek Kitszel ice_vc_send_msg_to_vf(vf, v_opcode, VIRTCHNL_STATUS_ERR_PARAM, 3494*f4e667ebSPrzemek Kitszel NULL, 0); 3495*f4e667ebSPrzemek Kitszel dev_err(dev, "Invalid message from VF %d, opcode %d, len %d, error %d\n", 3496*f4e667ebSPrzemek Kitszel vf_id, v_opcode, msglen, err); 3497*f4e667ebSPrzemek Kitszel goto finish; 3498*f4e667ebSPrzemek Kitszel } 3499*f4e667ebSPrzemek Kitszel 3500*f4e667ebSPrzemek Kitszel if (!ice_vc_is_opcode_allowed(vf, v_opcode)) { 3501*f4e667ebSPrzemek Kitszel ice_vc_send_msg_to_vf(vf, v_opcode, 3502*f4e667ebSPrzemek Kitszel VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, NULL, 3503*f4e667ebSPrzemek Kitszel 0); 3504*f4e667ebSPrzemek Kitszel goto finish; 3505*f4e667ebSPrzemek Kitszel } 3506*f4e667ebSPrzemek Kitszel 3507*f4e667ebSPrzemek Kitszel switch (v_opcode) { 3508*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_VERSION: 3509*f4e667ebSPrzemek Kitszel err = ops->get_ver_msg(vf, msg); 3510*f4e667ebSPrzemek Kitszel break; 3511*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_GET_VF_RESOURCES: 3512*f4e667ebSPrzemek Kitszel err = ops->get_vf_res_msg(vf, msg); 3513*f4e667ebSPrzemek Kitszel if (ice_vf_init_vlan_stripping(vf)) 3514*f4e667ebSPrzemek Kitszel dev_dbg(dev, "Failed to initialize VLAN stripping for VF %d\n", 3515*f4e667ebSPrzemek Kitszel vf->vf_id); 3516*f4e667ebSPrzemek Kitszel ice_vc_notify_vf_link_state(vf); 3517*f4e667ebSPrzemek Kitszel break; 3518*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_RESET_VF: 3519*f4e667ebSPrzemek Kitszel ops->reset_vf(vf); 3520*f4e667ebSPrzemek Kitszel break; 3521*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ADD_ETH_ADDR: 3522*f4e667ebSPrzemek Kitszel err = ops->add_mac_addr_msg(vf, msg); 3523*f4e667ebSPrzemek Kitszel break; 3524*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DEL_ETH_ADDR: 3525*f4e667ebSPrzemek Kitszel err = ops->del_mac_addr_msg(vf, msg); 3526*f4e667ebSPrzemek Kitszel break; 3527*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_CONFIG_VSI_QUEUES: 3528*f4e667ebSPrzemek Kitszel err = ops->cfg_qs_msg(vf, msg); 3529*f4e667ebSPrzemek Kitszel break; 3530*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ENABLE_QUEUES: 3531*f4e667ebSPrzemek Kitszel err = ops->ena_qs_msg(vf, msg); 3532*f4e667ebSPrzemek Kitszel ice_vc_notify_vf_link_state(vf); 3533*f4e667ebSPrzemek Kitszel break; 3534*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DISABLE_QUEUES: 3535*f4e667ebSPrzemek Kitszel err = ops->dis_qs_msg(vf, msg); 3536*f4e667ebSPrzemek Kitszel break; 3537*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_REQUEST_QUEUES: 3538*f4e667ebSPrzemek Kitszel err = ops->request_qs_msg(vf, msg); 3539*f4e667ebSPrzemek Kitszel break; 3540*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_CONFIG_IRQ_MAP: 3541*f4e667ebSPrzemek Kitszel err = ops->cfg_irq_map_msg(vf, msg); 3542*f4e667ebSPrzemek Kitszel break; 3543*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_CONFIG_RSS_KEY: 3544*f4e667ebSPrzemek Kitszel err = ops->config_rss_key(vf, msg); 3545*f4e667ebSPrzemek Kitszel break; 3546*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_CONFIG_RSS_LUT: 3547*f4e667ebSPrzemek Kitszel err = ops->config_rss_lut(vf, msg); 3548*f4e667ebSPrzemek Kitszel break; 3549*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_CONFIG_RSS_HFUNC: 3550*f4e667ebSPrzemek Kitszel err = ops->config_rss_hfunc(vf, msg); 3551*f4e667ebSPrzemek Kitszel break; 3552*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_GET_STATS: 3553*f4e667ebSPrzemek Kitszel err = ops->get_stats_msg(vf, msg); 3554*f4e667ebSPrzemek Kitszel break; 3555*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: 3556*f4e667ebSPrzemek Kitszel err = ops->cfg_promiscuous_mode_msg(vf, msg); 3557*f4e667ebSPrzemek Kitszel break; 3558*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ADD_VLAN: 3559*f4e667ebSPrzemek Kitszel err = ops->add_vlan_msg(vf, msg); 3560*f4e667ebSPrzemek Kitszel break; 3561*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DEL_VLAN: 3562*f4e667ebSPrzemek Kitszel err = ops->remove_vlan_msg(vf, msg); 3563*f4e667ebSPrzemek Kitszel break; 3564*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS: 3565*f4e667ebSPrzemek Kitszel err = ops->query_rxdid(vf); 3566*f4e667ebSPrzemek Kitszel break; 3567*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_GET_RSS_HASHCFG_CAPS: 3568*f4e667ebSPrzemek Kitszel err = ops->get_rss_hashcfg(vf); 3569*f4e667ebSPrzemek Kitszel break; 3570*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_SET_RSS_HASHCFG: 3571*f4e667ebSPrzemek Kitszel err = ops->set_rss_hashcfg(vf, msg); 3572*f4e667ebSPrzemek Kitszel break; 3573*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING: 3574*f4e667ebSPrzemek Kitszel err = ops->ena_vlan_stripping(vf); 3575*f4e667ebSPrzemek Kitszel break; 3576*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING: 3577*f4e667ebSPrzemek Kitszel err = ops->dis_vlan_stripping(vf); 3578*f4e667ebSPrzemek Kitszel break; 3579*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ADD_FDIR_FILTER: 3580*f4e667ebSPrzemek Kitszel err = ops->add_fdir_fltr_msg(vf, msg); 3581*f4e667ebSPrzemek Kitszel break; 3582*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DEL_FDIR_FILTER: 3583*f4e667ebSPrzemek Kitszel err = ops->del_fdir_fltr_msg(vf, msg); 3584*f4e667ebSPrzemek Kitszel break; 3585*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ADD_RSS_CFG: 3586*f4e667ebSPrzemek Kitszel err = ops->handle_rss_cfg_msg(vf, msg, true); 3587*f4e667ebSPrzemek Kitszel break; 3588*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DEL_RSS_CFG: 3589*f4e667ebSPrzemek Kitszel err = ops->handle_rss_cfg_msg(vf, msg, false); 3590*f4e667ebSPrzemek Kitszel break; 3591*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS: 3592*f4e667ebSPrzemek Kitszel err = ops->get_offload_vlan_v2_caps(vf); 3593*f4e667ebSPrzemek Kitszel break; 3594*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ADD_VLAN_V2: 3595*f4e667ebSPrzemek Kitszel err = ops->add_vlan_v2_msg(vf, msg); 3596*f4e667ebSPrzemek Kitszel break; 3597*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DEL_VLAN_V2: 3598*f4e667ebSPrzemek Kitszel err = ops->remove_vlan_v2_msg(vf, msg); 3599*f4e667ebSPrzemek Kitszel break; 3600*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2: 3601*f4e667ebSPrzemek Kitszel err = ops->ena_vlan_stripping_v2_msg(vf, msg); 3602*f4e667ebSPrzemek Kitszel break; 3603*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2: 3604*f4e667ebSPrzemek Kitszel err = ops->dis_vlan_stripping_v2_msg(vf, msg); 3605*f4e667ebSPrzemek Kitszel break; 3606*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2: 3607*f4e667ebSPrzemek Kitszel err = ops->ena_vlan_insertion_v2_msg(vf, msg); 3608*f4e667ebSPrzemek Kitszel break; 3609*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2: 3610*f4e667ebSPrzemek Kitszel err = ops->dis_vlan_insertion_v2_msg(vf, msg); 3611*f4e667ebSPrzemek Kitszel break; 3612*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_GET_QOS_CAPS: 3613*f4e667ebSPrzemek Kitszel err = ops->get_qos_caps(vf); 3614*f4e667ebSPrzemek Kitszel break; 3615*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_CONFIG_QUEUE_BW: 3616*f4e667ebSPrzemek Kitszel err = ops->cfg_q_bw(vf, msg); 3617*f4e667ebSPrzemek Kitszel break; 3618*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_CONFIG_QUANTA: 3619*f4e667ebSPrzemek Kitszel err = ops->cfg_q_quanta(vf, msg); 3620*f4e667ebSPrzemek Kitszel break; 3621*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_1588_PTP_GET_CAPS: 3622*f4e667ebSPrzemek Kitszel err = ops->get_ptp_cap(vf, (const void *)msg); 3623*f4e667ebSPrzemek Kitszel break; 3624*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_1588_PTP_GET_TIME: 3625*f4e667ebSPrzemek Kitszel err = ops->get_phc_time(vf); 3626*f4e667ebSPrzemek Kitszel break; 3627*f4e667ebSPrzemek Kitszel case VIRTCHNL_OP_UNKNOWN: 3628*f4e667ebSPrzemek Kitszel default: 3629*f4e667ebSPrzemek Kitszel dev_err(dev, "Unsupported opcode %d from VF %d\n", v_opcode, 3630*f4e667ebSPrzemek Kitszel vf_id); 3631*f4e667ebSPrzemek Kitszel err = ice_vc_send_msg_to_vf(vf, v_opcode, 3632*f4e667ebSPrzemek Kitszel VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, 3633*f4e667ebSPrzemek Kitszel NULL, 0); 3634*f4e667ebSPrzemek Kitszel break; 3635*f4e667ebSPrzemek Kitszel } 3636*f4e667ebSPrzemek Kitszel if (err) { 3637*f4e667ebSPrzemek Kitszel /* Helper function cares less about error return values here 3638*f4e667ebSPrzemek Kitszel * as it is busy with pending work. 3639*f4e667ebSPrzemek Kitszel */ 3640*f4e667ebSPrzemek Kitszel dev_info(dev, "PF failed to honor VF %d, opcode %d, error %d\n", 3641*f4e667ebSPrzemek Kitszel vf_id, v_opcode, err); 3642*f4e667ebSPrzemek Kitszel } 3643*f4e667ebSPrzemek Kitszel 3644*f4e667ebSPrzemek Kitszel finish: 3645*f4e667ebSPrzemek Kitszel mutex_unlock(&vf->cfg_lock); 3646*f4e667ebSPrzemek Kitszel ice_put_vf(vf); 3647*f4e667ebSPrzemek Kitszel } 3648