145d3d428SAnirudh Venkataramanan // SPDX-License-Identifier: GPL-2.0 245d3d428SAnirudh Venkataramanan /* Copyright (c) 2018, Intel Corporation. */ 345d3d428SAnirudh Venkataramanan 445d3d428SAnirudh Venkataramanan #include "ice.h" 5eff380aaSAnirudh Venkataramanan #include "ice_base.h" 6c90ed40cSTony Nguyen #include "ice_flow.h" 745d3d428SAnirudh Venkataramanan #include "ice_lib.h" 81b8f15b6SMichal Swiatkowski #include "ice_fltr.h" 97b9ffc76SAnirudh Venkataramanan #include "ice_dcb_lib.h" 1048d40025SJacob Keller #include "ice_devlink.h" 1145d3d428SAnirudh Venkataramanan 1245d3d428SAnirudh Venkataramanan /** 13964674f1SAnirudh Venkataramanan * ice_vsi_type_str - maps VSI type enum to string equivalents 146dae8aa0SBruce Allan * @vsi_type: VSI type enum 15964674f1SAnirudh Venkataramanan */ 166dae8aa0SBruce Allan const char *ice_vsi_type_str(enum ice_vsi_type vsi_type) 17964674f1SAnirudh Venkataramanan { 186dae8aa0SBruce Allan switch (vsi_type) { 19964674f1SAnirudh Venkataramanan case ICE_VSI_PF: 20964674f1SAnirudh Venkataramanan return "ICE_VSI_PF"; 21964674f1SAnirudh Venkataramanan case ICE_VSI_VF: 22964674f1SAnirudh Venkataramanan return "ICE_VSI_VF"; 23148beb61SHenry Tieman case ICE_VSI_CTRL: 24148beb61SHenry Tieman return "ICE_VSI_CTRL"; 25*0754d65bSKiran Patil case ICE_VSI_CHNL: 26*0754d65bSKiran Patil return "ICE_VSI_CHNL"; 27964674f1SAnirudh Venkataramanan case ICE_VSI_LB: 28964674f1SAnirudh Venkataramanan return "ICE_VSI_LB"; 29f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 30f66756e0SGrzegorz Nitka return "ICE_VSI_SWITCHDEV_CTRL"; 31964674f1SAnirudh Venkataramanan default: 32964674f1SAnirudh Venkataramanan return "unknown"; 33964674f1SAnirudh Venkataramanan } 34964674f1SAnirudh Venkataramanan } 35964674f1SAnirudh Venkataramanan 36964674f1SAnirudh Venkataramanan /** 3713a6233bSBrett Creeley * ice_vsi_ctrl_all_rx_rings - Start or stop a VSI's Rx rings 38d02f734cSMaciej Fijalkowski * @vsi: the VSI being configured 39d02f734cSMaciej Fijalkowski * @ena: start or stop the Rx rings 4013a6233bSBrett Creeley * 4113a6233bSBrett Creeley * First enable/disable all of the Rx rings, flush any remaining writes, and 4213a6233bSBrett Creeley * then verify that they have all been enabled/disabled successfully. This will 4313a6233bSBrett Creeley * let all of the register writes complete when enabling/disabling the Rx rings 4413a6233bSBrett Creeley * before waiting for the change in hardware to complete. 45d02f734cSMaciej Fijalkowski */ 4613a6233bSBrett Creeley static int ice_vsi_ctrl_all_rx_rings(struct ice_vsi *vsi, bool ena) 47d02f734cSMaciej Fijalkowski { 4888865fc4SKarol Kolacinski int ret = 0; 4988865fc4SKarol Kolacinski u16 i; 50d02f734cSMaciej Fijalkowski 512faf63b6SMaciej Fijalkowski ice_for_each_rxq(vsi, i) 5213a6233bSBrett Creeley ice_vsi_ctrl_one_rx_ring(vsi, ena, i, false); 5313a6233bSBrett Creeley 5413a6233bSBrett Creeley ice_flush(&vsi->back->hw); 5513a6233bSBrett Creeley 562faf63b6SMaciej Fijalkowski ice_for_each_rxq(vsi, i) { 5713a6233bSBrett Creeley ret = ice_vsi_wait_one_rx_ring(vsi, ena, i); 58d02f734cSMaciej Fijalkowski if (ret) 59d02f734cSMaciej Fijalkowski break; 6072adf242SAnirudh Venkataramanan } 6172adf242SAnirudh Venkataramanan 6272adf242SAnirudh Venkataramanan return ret; 6372adf242SAnirudh Venkataramanan } 6472adf242SAnirudh Venkataramanan 6572adf242SAnirudh Venkataramanan /** 6628c2a645SAnirudh Venkataramanan * ice_vsi_alloc_arrays - Allocate queue and vector pointer arrays for the VSI 6728c2a645SAnirudh Venkataramanan * @vsi: VSI pointer 6828c2a645SAnirudh Venkataramanan * 6928c2a645SAnirudh Venkataramanan * On error: returns error code (negative) 7028c2a645SAnirudh Venkataramanan * On success: returns 0 7128c2a645SAnirudh Venkataramanan */ 72a85a3847SBrett Creeley static int ice_vsi_alloc_arrays(struct ice_vsi *vsi) 7328c2a645SAnirudh Venkataramanan { 7428c2a645SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 754015d11eSBrett Creeley struct device *dev; 764015d11eSBrett Creeley 774015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 78*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL) 79*0754d65bSKiran Patil return 0; 8028c2a645SAnirudh Venkataramanan 8128c2a645SAnirudh Venkataramanan /* allocate memory for both Tx and Rx ring pointers */ 824015d11eSBrett Creeley vsi->tx_rings = devm_kcalloc(dev, vsi->alloc_txq, 83c6dfd690SBruce Allan sizeof(*vsi->tx_rings), GFP_KERNEL); 8428c2a645SAnirudh Venkataramanan if (!vsi->tx_rings) 8578b5713aSAnirudh Venkataramanan return -ENOMEM; 8628c2a645SAnirudh Venkataramanan 874015d11eSBrett Creeley vsi->rx_rings = devm_kcalloc(dev, vsi->alloc_rxq, 88c6dfd690SBruce Allan sizeof(*vsi->rx_rings), GFP_KERNEL); 8928c2a645SAnirudh Venkataramanan if (!vsi->rx_rings) 9078b5713aSAnirudh Venkataramanan goto err_rings; 9178b5713aSAnirudh Venkataramanan 92efc2214bSMaciej Fijalkowski /* XDP will have vsi->alloc_txq Tx queues as well, so double the size */ 934015d11eSBrett Creeley vsi->txq_map = devm_kcalloc(dev, (2 * vsi->alloc_txq), 9478b5713aSAnirudh Venkataramanan sizeof(*vsi->txq_map), GFP_KERNEL); 9578b5713aSAnirudh Venkataramanan 9678b5713aSAnirudh Venkataramanan if (!vsi->txq_map) 9778b5713aSAnirudh Venkataramanan goto err_txq_map; 9878b5713aSAnirudh Venkataramanan 994015d11eSBrett Creeley vsi->rxq_map = devm_kcalloc(dev, vsi->alloc_rxq, 10078b5713aSAnirudh Venkataramanan sizeof(*vsi->rxq_map), GFP_KERNEL); 10178b5713aSAnirudh Venkataramanan if (!vsi->rxq_map) 10278b5713aSAnirudh Venkataramanan goto err_rxq_map; 10378b5713aSAnirudh Venkataramanan 1040e674aebSAnirudh Venkataramanan /* There is no need to allocate q_vectors for a loopback VSI. */ 1050e674aebSAnirudh Venkataramanan if (vsi->type == ICE_VSI_LB) 1060e674aebSAnirudh Venkataramanan return 0; 1070e674aebSAnirudh Venkataramanan 10828c2a645SAnirudh Venkataramanan /* allocate memory for q_vector pointers */ 1094015d11eSBrett Creeley vsi->q_vectors = devm_kcalloc(dev, vsi->num_q_vectors, 110a85a3847SBrett Creeley sizeof(*vsi->q_vectors), GFP_KERNEL); 11128c2a645SAnirudh Venkataramanan if (!vsi->q_vectors) 11228c2a645SAnirudh Venkataramanan goto err_vectors; 11328c2a645SAnirudh Venkataramanan 114e102db78SMaciej Fijalkowski vsi->af_xdp_zc_qps = bitmap_zalloc(max_t(int, vsi->alloc_txq, vsi->alloc_rxq), GFP_KERNEL); 115e102db78SMaciej Fijalkowski if (!vsi->af_xdp_zc_qps) 116e102db78SMaciej Fijalkowski goto err_zc_qps; 117e102db78SMaciej Fijalkowski 11828c2a645SAnirudh Venkataramanan return 0; 11928c2a645SAnirudh Venkataramanan 120e102db78SMaciej Fijalkowski err_zc_qps: 121e102db78SMaciej Fijalkowski devm_kfree(dev, vsi->q_vectors); 12228c2a645SAnirudh Venkataramanan err_vectors: 1234015d11eSBrett Creeley devm_kfree(dev, vsi->rxq_map); 12478b5713aSAnirudh Venkataramanan err_rxq_map: 1254015d11eSBrett Creeley devm_kfree(dev, vsi->txq_map); 12678b5713aSAnirudh Venkataramanan err_txq_map: 1274015d11eSBrett Creeley devm_kfree(dev, vsi->rx_rings); 12878b5713aSAnirudh Venkataramanan err_rings: 1294015d11eSBrett Creeley devm_kfree(dev, vsi->tx_rings); 13028c2a645SAnirudh Venkataramanan return -ENOMEM; 13128c2a645SAnirudh Venkataramanan } 13228c2a645SAnirudh Venkataramanan 13328c2a645SAnirudh Venkataramanan /** 134ad71b256SBrett Creeley * ice_vsi_set_num_desc - Set number of descriptors for queues on this VSI 135ad71b256SBrett Creeley * @vsi: the VSI being configured 136ad71b256SBrett Creeley */ 137ad71b256SBrett Creeley static void ice_vsi_set_num_desc(struct ice_vsi *vsi) 138ad71b256SBrett Creeley { 139ad71b256SBrett Creeley switch (vsi->type) { 140ad71b256SBrett Creeley case ICE_VSI_PF: 141f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 142148beb61SHenry Tieman case ICE_VSI_CTRL: 1430e674aebSAnirudh Venkataramanan case ICE_VSI_LB: 144a02016deSPaul M Stillwell Jr /* a user could change the values of num_[tr]x_desc using 145a02016deSPaul M Stillwell Jr * ethtool -G so we should keep those values instead of 146a02016deSPaul M Stillwell Jr * overwriting them with the defaults. 147a02016deSPaul M Stillwell Jr */ 148a02016deSPaul M Stillwell Jr if (!vsi->num_rx_desc) 149ad71b256SBrett Creeley vsi->num_rx_desc = ICE_DFLT_NUM_RX_DESC; 150a02016deSPaul M Stillwell Jr if (!vsi->num_tx_desc) 151ad71b256SBrett Creeley vsi->num_tx_desc = ICE_DFLT_NUM_TX_DESC; 152ad71b256SBrett Creeley break; 153ad71b256SBrett Creeley default: 15419cce2c6SAnirudh Venkataramanan dev_dbg(ice_pf_to_dev(vsi->back), "Not setting number of Tx/Rx descriptors for VSI type %d\n", 155ad71b256SBrett Creeley vsi->type); 156ad71b256SBrett Creeley break; 157ad71b256SBrett Creeley } 158ad71b256SBrett Creeley } 159ad71b256SBrett Creeley 160ad71b256SBrett Creeley /** 161ad71b256SBrett Creeley * ice_vsi_set_num_qs - Set number of queues, descriptors and vectors for a VSI 16228c2a645SAnirudh Venkataramanan * @vsi: the VSI being configured 163f9867df6SAnirudh Venkataramanan * @vf_id: ID of the VF being configured 16428c2a645SAnirudh Venkataramanan * 16528c2a645SAnirudh Venkataramanan * Return 0 on success and a negative value on error 16628c2a645SAnirudh Venkataramanan */ 1675743020dSAkeem G Abodunrin static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id) 16828c2a645SAnirudh Venkataramanan { 16928c2a645SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 1705743020dSAkeem G Abodunrin struct ice_vf *vf = NULL; 1715743020dSAkeem G Abodunrin 1725743020dSAkeem G Abodunrin if (vsi->type == ICE_VSI_VF) 1735743020dSAkeem G Abodunrin vsi->vf_id = vf_id; 174c931c782SBrett Creeley else 175c931c782SBrett Creeley vsi->vf_id = ICE_INVAL_VFID; 1765743020dSAkeem G Abodunrin 17728c2a645SAnirudh Venkataramanan switch (vsi->type) { 17828c2a645SAnirudh Venkataramanan case ICE_VSI_PF: 17987324e74SHenry Tieman if (vsi->req_txq) { 18087324e74SHenry Tieman vsi->alloc_txq = vsi->req_txq; 18187324e74SHenry Tieman vsi->num_txq = vsi->req_txq; 182b38b7f2bSSalil Mehta } else { 183b38b7f2bSSalil Mehta vsi->alloc_txq = min3(pf->num_lan_msix, 184b38b7f2bSSalil Mehta ice_get_avail_txq_count(pf), 185b38b7f2bSSalil Mehta (u16)num_online_cpus()); 18687324e74SHenry Tieman } 1878c243700SAnirudh Venkataramanan 1888c243700SAnirudh Venkataramanan pf->num_lan_tx = vsi->alloc_txq; 1898c243700SAnirudh Venkataramanan 1908c243700SAnirudh Venkataramanan /* only 1 Rx queue unless RSS is enabled */ 19187324e74SHenry Tieman if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 1928c243700SAnirudh Venkataramanan vsi->alloc_rxq = 1; 19387324e74SHenry Tieman } else { 19487324e74SHenry Tieman if (vsi->req_rxq) { 19587324e74SHenry Tieman vsi->alloc_rxq = vsi->req_rxq; 19687324e74SHenry Tieman vsi->num_rxq = vsi->req_rxq; 197b38b7f2bSSalil Mehta } else { 198b38b7f2bSSalil Mehta vsi->alloc_rxq = min3(pf->num_lan_msix, 199b38b7f2bSSalil Mehta ice_get_avail_rxq_count(pf), 200b38b7f2bSSalil Mehta (u16)num_online_cpus()); 20187324e74SHenry Tieman } 20287324e74SHenry Tieman } 2038c243700SAnirudh Venkataramanan 2048c243700SAnirudh Venkataramanan pf->num_lan_rx = vsi->alloc_rxq; 2058c243700SAnirudh Venkataramanan 206f3fe97f6SBrett Creeley vsi->num_q_vectors = min_t(int, pf->num_lan_msix, 207f3fe97f6SBrett Creeley max_t(int, vsi->alloc_rxq, 208f3fe97f6SBrett Creeley vsi->alloc_txq)); 20928c2a645SAnirudh Venkataramanan break; 210f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 211f66756e0SGrzegorz Nitka /* The number of queues for ctrl VSI is equal to number of VFs. 212f66756e0SGrzegorz Nitka * Each ring is associated to the corresponding VF_PR netdev. 213f66756e0SGrzegorz Nitka */ 214f66756e0SGrzegorz Nitka vsi->alloc_txq = pf->num_alloc_vfs; 215f66756e0SGrzegorz Nitka vsi->alloc_rxq = pf->num_alloc_vfs; 216f66756e0SGrzegorz Nitka vsi->num_q_vectors = 1; 217f66756e0SGrzegorz Nitka break; 2188ede0178SAnirudh Venkataramanan case ICE_VSI_VF: 2195743020dSAkeem G Abodunrin vf = &pf->vf[vsi->vf_id]; 220f0457690SBrett Creeley if (vf->num_req_qs) 221f0457690SBrett Creeley vf->num_vf_qs = vf->num_req_qs; 2225743020dSAkeem G Abodunrin vsi->alloc_txq = vf->num_vf_qs; 2235743020dSAkeem G Abodunrin vsi->alloc_rxq = vf->num_vf_qs; 22446c276ceSBrett Creeley /* pf->num_msix_per_vf includes (VF miscellaneous vector + 2258ede0178SAnirudh Venkataramanan * data queue interrupts). Since vsi->num_q_vectors is number 226047e52c0SAnirudh Venkataramanan * of queues vectors, subtract 1 (ICE_NONQ_VECS_VF) from the 227047e52c0SAnirudh Venkataramanan * original vector count 2288ede0178SAnirudh Venkataramanan */ 22946c276ceSBrett Creeley vsi->num_q_vectors = pf->num_msix_per_vf - ICE_NONQ_VECS_VF; 2308ede0178SAnirudh Venkataramanan break; 231148beb61SHenry Tieman case ICE_VSI_CTRL: 232148beb61SHenry Tieman vsi->alloc_txq = 1; 233148beb61SHenry Tieman vsi->alloc_rxq = 1; 234148beb61SHenry Tieman vsi->num_q_vectors = 1; 235148beb61SHenry Tieman break; 236*0754d65bSKiran Patil case ICE_VSI_CHNL: 237*0754d65bSKiran Patil vsi->alloc_txq = 0; 238*0754d65bSKiran Patil vsi->alloc_rxq = 0; 239*0754d65bSKiran Patil break; 2400e674aebSAnirudh Venkataramanan case ICE_VSI_LB: 2410e674aebSAnirudh Venkataramanan vsi->alloc_txq = 1; 2420e674aebSAnirudh Venkataramanan vsi->alloc_rxq = 1; 2430e674aebSAnirudh Venkataramanan break; 24428c2a645SAnirudh Venkataramanan default: 2454015d11eSBrett Creeley dev_warn(ice_pf_to_dev(pf), "Unknown VSI type %d\n", vsi->type); 24628c2a645SAnirudh Venkataramanan break; 24728c2a645SAnirudh Venkataramanan } 248ad71b256SBrett Creeley 249ad71b256SBrett Creeley ice_vsi_set_num_desc(vsi); 25028c2a645SAnirudh Venkataramanan } 25128c2a645SAnirudh Venkataramanan 25228c2a645SAnirudh Venkataramanan /** 25328c2a645SAnirudh Venkataramanan * ice_get_free_slot - get the next non-NULL location index in array 25428c2a645SAnirudh Venkataramanan * @array: array to search 25528c2a645SAnirudh Venkataramanan * @size: size of the array 25628c2a645SAnirudh Venkataramanan * @curr: last known occupied index to be used as a search hint 25728c2a645SAnirudh Venkataramanan * 25828c2a645SAnirudh Venkataramanan * void * is being used to keep the functionality generic. This lets us use this 25928c2a645SAnirudh Venkataramanan * function on any array of pointers. 26028c2a645SAnirudh Venkataramanan */ 26137bb8390SAnirudh Venkataramanan static int ice_get_free_slot(void *array, int size, int curr) 26228c2a645SAnirudh Venkataramanan { 26328c2a645SAnirudh Venkataramanan int **tmp_array = (int **)array; 26428c2a645SAnirudh Venkataramanan int next; 26528c2a645SAnirudh Venkataramanan 26628c2a645SAnirudh Venkataramanan if (curr < (size - 1) && !tmp_array[curr + 1]) { 26728c2a645SAnirudh Venkataramanan next = curr + 1; 26828c2a645SAnirudh Venkataramanan } else { 26928c2a645SAnirudh Venkataramanan int i = 0; 27028c2a645SAnirudh Venkataramanan 27128c2a645SAnirudh Venkataramanan while ((i < size) && (tmp_array[i])) 27228c2a645SAnirudh Venkataramanan i++; 27328c2a645SAnirudh Venkataramanan if (i == size) 27428c2a645SAnirudh Venkataramanan next = ICE_NO_VSI; 27528c2a645SAnirudh Venkataramanan else 27628c2a645SAnirudh Venkataramanan next = i; 27728c2a645SAnirudh Venkataramanan } 27828c2a645SAnirudh Venkataramanan return next; 27928c2a645SAnirudh Venkataramanan } 28028c2a645SAnirudh Venkataramanan 28128c2a645SAnirudh Venkataramanan /** 2825153a18eSAnirudh Venkataramanan * ice_vsi_delete - delete a VSI from the switch 2835153a18eSAnirudh Venkataramanan * @vsi: pointer to VSI being removed 2845153a18eSAnirudh Venkataramanan */ 285*0754d65bSKiran Patil void ice_vsi_delete(struct ice_vsi *vsi) 2865153a18eSAnirudh Venkataramanan { 2875153a18eSAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 288198a666aSBruce Allan struct ice_vsi_ctx *ctxt; 2895153a18eSAnirudh Venkataramanan enum ice_status status; 2905153a18eSAnirudh Venkataramanan 2919efe35d0STony Nguyen ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); 292198a666aSBruce Allan if (!ctxt) 293198a666aSBruce Allan return; 294198a666aSBruce Allan 2958ede0178SAnirudh Venkataramanan if (vsi->type == ICE_VSI_VF) 296198a666aSBruce Allan ctxt->vf_num = vsi->vf_id; 297198a666aSBruce Allan ctxt->vsi_num = vsi->vsi_num; 2985153a18eSAnirudh Venkataramanan 299198a666aSBruce Allan memcpy(&ctxt->info, &vsi->info, sizeof(ctxt->info)); 3005153a18eSAnirudh Venkataramanan 301198a666aSBruce Allan status = ice_free_vsi(&pf->hw, vsi->idx, ctxt, false, NULL); 3025153a18eSAnirudh Venkataramanan if (status) 3030fee3577SLihong Yang dev_err(ice_pf_to_dev(pf), "Failed to delete VSI %i in FW - error: %s\n", 3040fee3577SLihong Yang vsi->vsi_num, ice_stat_str(status)); 305198a666aSBruce Allan 3069efe35d0STony Nguyen kfree(ctxt); 3075153a18eSAnirudh Venkataramanan } 3085153a18eSAnirudh Venkataramanan 3095153a18eSAnirudh Venkataramanan /** 310a85a3847SBrett Creeley * ice_vsi_free_arrays - De-allocate queue and vector pointer arrays for the VSI 31107309a0eSAnirudh Venkataramanan * @vsi: pointer to VSI being cleared 31207309a0eSAnirudh Venkataramanan */ 313a85a3847SBrett Creeley static void ice_vsi_free_arrays(struct ice_vsi *vsi) 31407309a0eSAnirudh Venkataramanan { 31507309a0eSAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 3164015d11eSBrett Creeley struct device *dev; 3174015d11eSBrett Creeley 3184015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 31907309a0eSAnirudh Venkataramanan 320e102db78SMaciej Fijalkowski if (vsi->af_xdp_zc_qps) { 321e102db78SMaciej Fijalkowski bitmap_free(vsi->af_xdp_zc_qps); 322e102db78SMaciej Fijalkowski vsi->af_xdp_zc_qps = NULL; 323e102db78SMaciej Fijalkowski } 32407309a0eSAnirudh Venkataramanan /* free the ring and vector containers */ 325a85a3847SBrett Creeley if (vsi->q_vectors) { 3264015d11eSBrett Creeley devm_kfree(dev, vsi->q_vectors); 32707309a0eSAnirudh Venkataramanan vsi->q_vectors = NULL; 32807309a0eSAnirudh Venkataramanan } 32907309a0eSAnirudh Venkataramanan if (vsi->tx_rings) { 3304015d11eSBrett Creeley devm_kfree(dev, vsi->tx_rings); 33107309a0eSAnirudh Venkataramanan vsi->tx_rings = NULL; 33207309a0eSAnirudh Venkataramanan } 33307309a0eSAnirudh Venkataramanan if (vsi->rx_rings) { 3344015d11eSBrett Creeley devm_kfree(dev, vsi->rx_rings); 33507309a0eSAnirudh Venkataramanan vsi->rx_rings = NULL; 33607309a0eSAnirudh Venkataramanan } 33778b5713aSAnirudh Venkataramanan if (vsi->txq_map) { 3384015d11eSBrett Creeley devm_kfree(dev, vsi->txq_map); 33978b5713aSAnirudh Venkataramanan vsi->txq_map = NULL; 34078b5713aSAnirudh Venkataramanan } 34178b5713aSAnirudh Venkataramanan if (vsi->rxq_map) { 3424015d11eSBrett Creeley devm_kfree(dev, vsi->rxq_map); 34378b5713aSAnirudh Venkataramanan vsi->rxq_map = NULL; 34478b5713aSAnirudh Venkataramanan } 34507309a0eSAnirudh Venkataramanan } 34607309a0eSAnirudh Venkataramanan 34707309a0eSAnirudh Venkataramanan /** 34807309a0eSAnirudh Venkataramanan * ice_vsi_clear - clean up and deallocate the provided VSI 34907309a0eSAnirudh Venkataramanan * @vsi: pointer to VSI being cleared 35007309a0eSAnirudh Venkataramanan * 35107309a0eSAnirudh Venkataramanan * This deallocates the VSI's queue resources, removes it from the PF's 35207309a0eSAnirudh Venkataramanan * VSI array if necessary, and deallocates the VSI 35307309a0eSAnirudh Venkataramanan * 35407309a0eSAnirudh Venkataramanan * Returns 0 on success, negative on failure 35507309a0eSAnirudh Venkataramanan */ 356*0754d65bSKiran Patil int ice_vsi_clear(struct ice_vsi *vsi) 35707309a0eSAnirudh Venkataramanan { 35807309a0eSAnirudh Venkataramanan struct ice_pf *pf = NULL; 3594015d11eSBrett Creeley struct device *dev; 36007309a0eSAnirudh Venkataramanan 36107309a0eSAnirudh Venkataramanan if (!vsi) 36207309a0eSAnirudh Venkataramanan return 0; 36307309a0eSAnirudh Venkataramanan 36407309a0eSAnirudh Venkataramanan if (!vsi->back) 36507309a0eSAnirudh Venkataramanan return -EINVAL; 36607309a0eSAnirudh Venkataramanan 36707309a0eSAnirudh Venkataramanan pf = vsi->back; 3684015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 36907309a0eSAnirudh Venkataramanan 37007309a0eSAnirudh Venkataramanan if (!pf->vsi[vsi->idx] || pf->vsi[vsi->idx] != vsi) { 3714015d11eSBrett Creeley dev_dbg(dev, "vsi does not exist at pf->vsi[%d]\n", vsi->idx); 37207309a0eSAnirudh Venkataramanan return -EINVAL; 37307309a0eSAnirudh Venkataramanan } 37407309a0eSAnirudh Venkataramanan 37507309a0eSAnirudh Venkataramanan mutex_lock(&pf->sw_mutex); 37607309a0eSAnirudh Venkataramanan /* updates the PF for this cleared VSI */ 37707309a0eSAnirudh Venkataramanan 37807309a0eSAnirudh Venkataramanan pf->vsi[vsi->idx] = NULL; 379148beb61SHenry Tieman if (vsi->idx < pf->next_vsi && vsi->type != ICE_VSI_CTRL) 38007309a0eSAnirudh Venkataramanan pf->next_vsi = vsi->idx; 381da62c5ffSQi Zhang if (vsi->idx < pf->next_vsi && vsi->type == ICE_VSI_CTRL && 382da62c5ffSQi Zhang vsi->vf_id != ICE_INVAL_VFID) 383da62c5ffSQi Zhang pf->next_vsi = vsi->idx; 38407309a0eSAnirudh Venkataramanan 385a85a3847SBrett Creeley ice_vsi_free_arrays(vsi); 38607309a0eSAnirudh Venkataramanan mutex_unlock(&pf->sw_mutex); 3874015d11eSBrett Creeley devm_kfree(dev, vsi); 38807309a0eSAnirudh Venkataramanan 38907309a0eSAnirudh Venkataramanan return 0; 39007309a0eSAnirudh Venkataramanan } 39107309a0eSAnirudh Venkataramanan 39207309a0eSAnirudh Venkataramanan /** 393148beb61SHenry Tieman * ice_msix_clean_ctrl_vsi - MSIX mode interrupt handler for ctrl VSI 394148beb61SHenry Tieman * @irq: interrupt number 395148beb61SHenry Tieman * @data: pointer to a q_vector 396148beb61SHenry Tieman */ 397148beb61SHenry Tieman static irqreturn_t ice_msix_clean_ctrl_vsi(int __always_unused irq, void *data) 398148beb61SHenry Tieman { 399148beb61SHenry Tieman struct ice_q_vector *q_vector = (struct ice_q_vector *)data; 400148beb61SHenry Tieman 401e72bba21SMaciej Fijalkowski if (!q_vector->tx.tx_ring) 402148beb61SHenry Tieman return IRQ_HANDLED; 403148beb61SHenry Tieman 404148beb61SHenry Tieman #define FDIR_RX_DESC_CLEAN_BUDGET 64 405e72bba21SMaciej Fijalkowski ice_clean_rx_irq(q_vector->rx.rx_ring, FDIR_RX_DESC_CLEAN_BUDGET); 406e72bba21SMaciej Fijalkowski ice_clean_ctrl_tx_irq(q_vector->tx.tx_ring); 407148beb61SHenry Tieman 408148beb61SHenry Tieman return IRQ_HANDLED; 409148beb61SHenry Tieman } 410148beb61SHenry Tieman 411148beb61SHenry Tieman /** 4125153a18eSAnirudh Venkataramanan * ice_msix_clean_rings - MSIX mode Interrupt Handler 4135153a18eSAnirudh Venkataramanan * @irq: interrupt number 4145153a18eSAnirudh Venkataramanan * @data: pointer to a q_vector 4155153a18eSAnirudh Venkataramanan */ 416f3aaaaaaSAnirudh Venkataramanan static irqreturn_t ice_msix_clean_rings(int __always_unused irq, void *data) 4175153a18eSAnirudh Venkataramanan { 4185153a18eSAnirudh Venkataramanan struct ice_q_vector *q_vector = (struct ice_q_vector *)data; 4195153a18eSAnirudh Venkataramanan 420e72bba21SMaciej Fijalkowski if (!q_vector->tx.tx_ring && !q_vector->rx.rx_ring) 4215153a18eSAnirudh Venkataramanan return IRQ_HANDLED; 4225153a18eSAnirudh Venkataramanan 423cdf1f1f1SJacob Keller q_vector->total_events++; 424cdf1f1f1SJacob Keller 4255153a18eSAnirudh Venkataramanan napi_schedule(&q_vector->napi); 4265153a18eSAnirudh Venkataramanan 4275153a18eSAnirudh Venkataramanan return IRQ_HANDLED; 4285153a18eSAnirudh Venkataramanan } 4295153a18eSAnirudh Venkataramanan 430f66756e0SGrzegorz Nitka static irqreturn_t ice_eswitch_msix_clean_rings(int __always_unused irq, void *data) 431f66756e0SGrzegorz Nitka { 432f66756e0SGrzegorz Nitka struct ice_q_vector *q_vector = (struct ice_q_vector *)data; 433f66756e0SGrzegorz Nitka struct ice_pf *pf = q_vector->vsi->back; 434f66756e0SGrzegorz Nitka int i; 435f66756e0SGrzegorz Nitka 436e72bba21SMaciej Fijalkowski if (!q_vector->tx.tx_ring && !q_vector->rx.rx_ring) 437f66756e0SGrzegorz Nitka return IRQ_HANDLED; 438f66756e0SGrzegorz Nitka 439f66756e0SGrzegorz Nitka ice_for_each_vf(pf, i) 440f66756e0SGrzegorz Nitka napi_schedule(&pf->vf[i].repr->q_vector->napi); 441f66756e0SGrzegorz Nitka 442f66756e0SGrzegorz Nitka return IRQ_HANDLED; 443f66756e0SGrzegorz Nitka } 444f66756e0SGrzegorz Nitka 4455153a18eSAnirudh Venkataramanan /** 44637bb8390SAnirudh Venkataramanan * ice_vsi_alloc - Allocates the next available struct VSI in the PF 44737bb8390SAnirudh Venkataramanan * @pf: board private structure 4486dae8aa0SBruce Allan * @vsi_type: type of VSI 449*0754d65bSKiran Patil * @ch: ptr to channel 450f9867df6SAnirudh Venkataramanan * @vf_id: ID of the VF being configured 45137bb8390SAnirudh Venkataramanan * 45237bb8390SAnirudh Venkataramanan * returns a pointer to a VSI on success, NULL on failure. 45337bb8390SAnirudh Venkataramanan */ 4545743020dSAkeem G Abodunrin static struct ice_vsi * 455*0754d65bSKiran Patil ice_vsi_alloc(struct ice_pf *pf, enum ice_vsi_type vsi_type, 456*0754d65bSKiran Patil struct ice_channel *ch, u16 vf_id) 45737bb8390SAnirudh Venkataramanan { 4584015d11eSBrett Creeley struct device *dev = ice_pf_to_dev(pf); 45937bb8390SAnirudh Venkataramanan struct ice_vsi *vsi = NULL; 46037bb8390SAnirudh Venkataramanan 46137bb8390SAnirudh Venkataramanan /* Need to protect the allocation of the VSIs at the PF level */ 46237bb8390SAnirudh Venkataramanan mutex_lock(&pf->sw_mutex); 46337bb8390SAnirudh Venkataramanan 46437bb8390SAnirudh Venkataramanan /* If we have already allocated our maximum number of VSIs, 46537bb8390SAnirudh Venkataramanan * pf->next_vsi will be ICE_NO_VSI. If not, pf->next_vsi index 46637bb8390SAnirudh Venkataramanan * is available to be populated 46737bb8390SAnirudh Venkataramanan */ 46837bb8390SAnirudh Venkataramanan if (pf->next_vsi == ICE_NO_VSI) { 4694015d11eSBrett Creeley dev_dbg(dev, "out of VSI slots!\n"); 47037bb8390SAnirudh Venkataramanan goto unlock_pf; 47137bb8390SAnirudh Venkataramanan } 47237bb8390SAnirudh Venkataramanan 4734015d11eSBrett Creeley vsi = devm_kzalloc(dev, sizeof(*vsi), GFP_KERNEL); 47437bb8390SAnirudh Venkataramanan if (!vsi) 47537bb8390SAnirudh Venkataramanan goto unlock_pf; 47637bb8390SAnirudh Venkataramanan 4776dae8aa0SBruce Allan vsi->type = vsi_type; 47837bb8390SAnirudh Venkataramanan vsi->back = pf; 479e97fb1aeSAnirudh Venkataramanan set_bit(ICE_VSI_DOWN, vsi->state); 4809d56b7fdSJesse Brandeburg 4816dae8aa0SBruce Allan if (vsi_type == ICE_VSI_VF) 4825743020dSAkeem G Abodunrin ice_vsi_set_num_qs(vsi, vf_id); 483*0754d65bSKiran Patil else if (vsi_type != ICE_VSI_CHNL) 4845743020dSAkeem G Abodunrin ice_vsi_set_num_qs(vsi, ICE_INVAL_VFID); 48537bb8390SAnirudh Venkataramanan 48637bb8390SAnirudh Venkataramanan switch (vsi->type) { 487f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 488f66756e0SGrzegorz Nitka if (ice_vsi_alloc_arrays(vsi)) 489f66756e0SGrzegorz Nitka goto err_rings; 490f66756e0SGrzegorz Nitka 491f66756e0SGrzegorz Nitka /* Setup eswitch MSIX irq handler for VSI */ 492f66756e0SGrzegorz Nitka vsi->irq_handler = ice_eswitch_msix_clean_rings; 493f66756e0SGrzegorz Nitka break; 49437bb8390SAnirudh Venkataramanan case ICE_VSI_PF: 495a85a3847SBrett Creeley if (ice_vsi_alloc_arrays(vsi)) 49637bb8390SAnirudh Venkataramanan goto err_rings; 49737bb8390SAnirudh Venkataramanan 49837bb8390SAnirudh Venkataramanan /* Setup default MSIX irq handler for VSI */ 49937bb8390SAnirudh Venkataramanan vsi->irq_handler = ice_msix_clean_rings; 50037bb8390SAnirudh Venkataramanan break; 501148beb61SHenry Tieman case ICE_VSI_CTRL: 502148beb61SHenry Tieman if (ice_vsi_alloc_arrays(vsi)) 503148beb61SHenry Tieman goto err_rings; 504148beb61SHenry Tieman 505148beb61SHenry Tieman /* Setup ctrl VSI MSIX irq handler */ 506148beb61SHenry Tieman vsi->irq_handler = ice_msix_clean_ctrl_vsi; 507148beb61SHenry Tieman break; 5088ede0178SAnirudh Venkataramanan case ICE_VSI_VF: 509a85a3847SBrett Creeley if (ice_vsi_alloc_arrays(vsi)) 5108ede0178SAnirudh Venkataramanan goto err_rings; 5118ede0178SAnirudh Venkataramanan break; 512*0754d65bSKiran Patil case ICE_VSI_CHNL: 513*0754d65bSKiran Patil if (!ch) 514*0754d65bSKiran Patil goto err_rings; 515*0754d65bSKiran Patil vsi->num_rxq = ch->num_rxq; 516*0754d65bSKiran Patil vsi->num_txq = ch->num_txq; 517*0754d65bSKiran Patil vsi->next_base_q = ch->base_q; 518*0754d65bSKiran Patil break; 5190e674aebSAnirudh Venkataramanan case ICE_VSI_LB: 5200e674aebSAnirudh Venkataramanan if (ice_vsi_alloc_arrays(vsi)) 5210e674aebSAnirudh Venkataramanan goto err_rings; 5220e674aebSAnirudh Venkataramanan break; 52337bb8390SAnirudh Venkataramanan default: 5244015d11eSBrett Creeley dev_warn(dev, "Unknown VSI type %d\n", vsi->type); 52537bb8390SAnirudh Venkataramanan goto unlock_pf; 52637bb8390SAnirudh Venkataramanan } 52737bb8390SAnirudh Venkataramanan 528da62c5ffSQi Zhang if (vsi->type == ICE_VSI_CTRL && vf_id == ICE_INVAL_VFID) { 529da62c5ffSQi Zhang /* Use the last VSI slot as the index for PF control VSI */ 530148beb61SHenry Tieman vsi->idx = pf->num_alloc_vsi - 1; 531148beb61SHenry Tieman pf->ctrl_vsi_idx = vsi->idx; 532148beb61SHenry Tieman pf->vsi[vsi->idx] = vsi; 533148beb61SHenry Tieman } else { 534148beb61SHenry Tieman /* fill slot and make note of the index */ 535148beb61SHenry Tieman vsi->idx = pf->next_vsi; 53637bb8390SAnirudh Venkataramanan pf->vsi[pf->next_vsi] = vsi; 53737bb8390SAnirudh Venkataramanan 53837bb8390SAnirudh Venkataramanan /* prepare pf->next_vsi for next use */ 53937bb8390SAnirudh Venkataramanan pf->next_vsi = ice_get_free_slot(pf->vsi, pf->num_alloc_vsi, 54037bb8390SAnirudh Venkataramanan pf->next_vsi); 541148beb61SHenry Tieman } 542da62c5ffSQi Zhang 543da62c5ffSQi Zhang if (vsi->type == ICE_VSI_CTRL && vf_id != ICE_INVAL_VFID) 544da62c5ffSQi Zhang pf->vf[vf_id].ctrl_vsi_idx = vsi->idx; 54537bb8390SAnirudh Venkataramanan goto unlock_pf; 54637bb8390SAnirudh Venkataramanan 54737bb8390SAnirudh Venkataramanan err_rings: 5484015d11eSBrett Creeley devm_kfree(dev, vsi); 54937bb8390SAnirudh Venkataramanan vsi = NULL; 55037bb8390SAnirudh Venkataramanan unlock_pf: 55137bb8390SAnirudh Venkataramanan mutex_unlock(&pf->sw_mutex); 55237bb8390SAnirudh Venkataramanan return vsi; 55337bb8390SAnirudh Venkataramanan } 55437bb8390SAnirudh Venkataramanan 55537bb8390SAnirudh Venkataramanan /** 556148beb61SHenry Tieman * ice_alloc_fd_res - Allocate FD resource for a VSI 557148beb61SHenry Tieman * @vsi: pointer to the ice_vsi 558148beb61SHenry Tieman * 559148beb61SHenry Tieman * This allocates the FD resources 560148beb61SHenry Tieman * 561148beb61SHenry Tieman * Returns 0 on success, -EPERM on no-op or -EIO on failure 562148beb61SHenry Tieman */ 563148beb61SHenry Tieman static int ice_alloc_fd_res(struct ice_vsi *vsi) 564148beb61SHenry Tieman { 565148beb61SHenry Tieman struct ice_pf *pf = vsi->back; 566148beb61SHenry Tieman u32 g_val, b_val; 567148beb61SHenry Tieman 568148beb61SHenry Tieman /* Flow Director filters are only allocated/assigned to the PF VSI which 569148beb61SHenry Tieman * passes the traffic. The CTRL VSI is only used to add/delete filters 570148beb61SHenry Tieman * so we don't allocate resources to it 571148beb61SHenry Tieman */ 572148beb61SHenry Tieman 573148beb61SHenry Tieman /* FD filters from guaranteed pool per VSI */ 574148beb61SHenry Tieman g_val = pf->hw.func_caps.fd_fltr_guar; 575148beb61SHenry Tieman if (!g_val) 576148beb61SHenry Tieman return -EPERM; 577148beb61SHenry Tieman 578148beb61SHenry Tieman /* FD filters from best effort pool */ 579148beb61SHenry Tieman b_val = pf->hw.func_caps.fd_fltr_best_effort; 580148beb61SHenry Tieman if (!b_val) 581148beb61SHenry Tieman return -EPERM; 582148beb61SHenry Tieman 583da62c5ffSQi Zhang if (!(vsi->type == ICE_VSI_PF || vsi->type == ICE_VSI_VF)) 584148beb61SHenry Tieman return -EPERM; 585148beb61SHenry Tieman 586148beb61SHenry Tieman if (!test_bit(ICE_FLAG_FD_ENA, pf->flags)) 587148beb61SHenry Tieman return -EPERM; 588148beb61SHenry Tieman 589148beb61SHenry Tieman vsi->num_gfltr = g_val / pf->num_alloc_vsi; 590148beb61SHenry Tieman 591148beb61SHenry Tieman /* each VSI gets same "best_effort" quota */ 592148beb61SHenry Tieman vsi->num_bfltr = b_val; 593148beb61SHenry Tieman 594da62c5ffSQi Zhang if (vsi->type == ICE_VSI_VF) { 595da62c5ffSQi Zhang vsi->num_gfltr = 0; 596da62c5ffSQi Zhang 597da62c5ffSQi Zhang /* each VSI gets same "best_effort" quota */ 598da62c5ffSQi Zhang vsi->num_bfltr = b_val; 599da62c5ffSQi Zhang } 600da62c5ffSQi Zhang 601148beb61SHenry Tieman return 0; 602148beb61SHenry Tieman } 603148beb61SHenry Tieman 604148beb61SHenry Tieman /** 605df0f8479SAnirudh Venkataramanan * ice_vsi_get_qs - Assign queues from PF to VSI 606df0f8479SAnirudh Venkataramanan * @vsi: the VSI to assign queues to 607df0f8479SAnirudh Venkataramanan * 608df0f8479SAnirudh Venkataramanan * Returns 0 on success and a negative value on error 609df0f8479SAnirudh Venkataramanan */ 61037bb8390SAnirudh Venkataramanan static int ice_vsi_get_qs(struct ice_vsi *vsi) 611df0f8479SAnirudh Venkataramanan { 61203f7a986SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 61303f7a986SAnirudh Venkataramanan struct ice_qs_cfg tx_qs_cfg = { 61403f7a986SAnirudh Venkataramanan .qs_mutex = &pf->avail_q_mutex, 61503f7a986SAnirudh Venkataramanan .pf_map = pf->avail_txqs, 61678b5713aSAnirudh Venkataramanan .pf_map_size = pf->max_pf_txqs, 61703f7a986SAnirudh Venkataramanan .q_count = vsi->alloc_txq, 61803f7a986SAnirudh Venkataramanan .scatter_count = ICE_MAX_SCATTER_TXQS, 61903f7a986SAnirudh Venkataramanan .vsi_map = vsi->txq_map, 62003f7a986SAnirudh Venkataramanan .vsi_map_offset = 0, 62139066dc5SBrett Creeley .mapping_mode = ICE_VSI_MAP_CONTIG 62203f7a986SAnirudh Venkataramanan }; 62303f7a986SAnirudh Venkataramanan struct ice_qs_cfg rx_qs_cfg = { 62403f7a986SAnirudh Venkataramanan .qs_mutex = &pf->avail_q_mutex, 62503f7a986SAnirudh Venkataramanan .pf_map = pf->avail_rxqs, 62678b5713aSAnirudh Venkataramanan .pf_map_size = pf->max_pf_rxqs, 62703f7a986SAnirudh Venkataramanan .q_count = vsi->alloc_rxq, 62803f7a986SAnirudh Venkataramanan .scatter_count = ICE_MAX_SCATTER_RXQS, 62903f7a986SAnirudh Venkataramanan .vsi_map = vsi->rxq_map, 63003f7a986SAnirudh Venkataramanan .vsi_map_offset = 0, 63139066dc5SBrett Creeley .mapping_mode = ICE_VSI_MAP_CONTIG 63203f7a986SAnirudh Venkataramanan }; 63339066dc5SBrett Creeley int ret; 634df0f8479SAnirudh Venkataramanan 635*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL) 636*0754d65bSKiran Patil return 0; 637*0754d65bSKiran Patil 63803f7a986SAnirudh Venkataramanan ret = __ice_vsi_get_qs(&tx_qs_cfg); 63939066dc5SBrett Creeley if (ret) 640df0f8479SAnirudh Venkataramanan return ret; 64139066dc5SBrett Creeley vsi->tx_mapping_mode = tx_qs_cfg.mapping_mode; 64239066dc5SBrett Creeley 64339066dc5SBrett Creeley ret = __ice_vsi_get_qs(&rx_qs_cfg); 64439066dc5SBrett Creeley if (ret) 64539066dc5SBrett Creeley return ret; 64639066dc5SBrett Creeley vsi->rx_mapping_mode = rx_qs_cfg.mapping_mode; 64739066dc5SBrett Creeley 64839066dc5SBrett Creeley return 0; 649df0f8479SAnirudh Venkataramanan } 650df0f8479SAnirudh Venkataramanan 651df0f8479SAnirudh Venkataramanan /** 6525153a18eSAnirudh Venkataramanan * ice_vsi_put_qs - Release queues from VSI to PF 6535153a18eSAnirudh Venkataramanan * @vsi: the VSI that is going to release queues 6545153a18eSAnirudh Venkataramanan */ 655135f4b9eSJacob Keller static void ice_vsi_put_qs(struct ice_vsi *vsi) 6565153a18eSAnirudh Venkataramanan { 6575153a18eSAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 6585153a18eSAnirudh Venkataramanan int i; 6595153a18eSAnirudh Venkataramanan 6605153a18eSAnirudh Venkataramanan mutex_lock(&pf->avail_q_mutex); 6615153a18eSAnirudh Venkataramanan 6622faf63b6SMaciej Fijalkowski ice_for_each_alloc_txq(vsi, i) { 6635153a18eSAnirudh Venkataramanan clear_bit(vsi->txq_map[i], pf->avail_txqs); 6645153a18eSAnirudh Venkataramanan vsi->txq_map[i] = ICE_INVAL_Q_INDEX; 6655153a18eSAnirudh Venkataramanan } 6665153a18eSAnirudh Venkataramanan 6672faf63b6SMaciej Fijalkowski ice_for_each_alloc_rxq(vsi, i) { 6685153a18eSAnirudh Venkataramanan clear_bit(vsi->rxq_map[i], pf->avail_rxqs); 6695153a18eSAnirudh Venkataramanan vsi->rxq_map[i] = ICE_INVAL_Q_INDEX; 6705153a18eSAnirudh Venkataramanan } 6715153a18eSAnirudh Venkataramanan 6725153a18eSAnirudh Venkataramanan mutex_unlock(&pf->avail_q_mutex); 6735153a18eSAnirudh Venkataramanan } 6745153a18eSAnirudh Venkataramanan 6755153a18eSAnirudh Venkataramanan /** 676462acf6aSTony Nguyen * ice_is_safe_mode 677462acf6aSTony Nguyen * @pf: pointer to the PF struct 678462acf6aSTony Nguyen * 679462acf6aSTony Nguyen * returns true if driver is in safe mode, false otherwise 680462acf6aSTony Nguyen */ 681462acf6aSTony Nguyen bool ice_is_safe_mode(struct ice_pf *pf) 682462acf6aSTony Nguyen { 683462acf6aSTony Nguyen return !test_bit(ICE_FLAG_ADV_FEATURES, pf->flags); 684462acf6aSTony Nguyen } 685462acf6aSTony Nguyen 686462acf6aSTony Nguyen /** 687d25a0fc4SDave Ertman * ice_is_aux_ena 688d25a0fc4SDave Ertman * @pf: pointer to the PF struct 689d25a0fc4SDave Ertman * 690d25a0fc4SDave Ertman * returns true if AUX devices/drivers are supported, false otherwise 691d25a0fc4SDave Ertman */ 692d25a0fc4SDave Ertman bool ice_is_aux_ena(struct ice_pf *pf) 693d25a0fc4SDave Ertman { 694d25a0fc4SDave Ertman return test_bit(ICE_FLAG_AUX_ENA, pf->flags); 695d25a0fc4SDave Ertman } 696d25a0fc4SDave Ertman 697d25a0fc4SDave Ertman /** 6982c61054cSTony Nguyen * ice_vsi_clean_rss_flow_fld - Delete RSS configuration 6992c61054cSTony Nguyen * @vsi: the VSI being cleaned up 7002c61054cSTony Nguyen * 7012c61054cSTony Nguyen * This function deletes RSS input set for all flows that were configured 7022c61054cSTony Nguyen * for this VSI 7032c61054cSTony Nguyen */ 7042c61054cSTony Nguyen static void ice_vsi_clean_rss_flow_fld(struct ice_vsi *vsi) 7052c61054cSTony Nguyen { 7062c61054cSTony Nguyen struct ice_pf *pf = vsi->back; 7072c61054cSTony Nguyen enum ice_status status; 7082c61054cSTony Nguyen 7092c61054cSTony Nguyen if (ice_is_safe_mode(pf)) 7102c61054cSTony Nguyen return; 7112c61054cSTony Nguyen 7122c61054cSTony Nguyen status = ice_rem_vsi_rss_cfg(&pf->hw, vsi->idx); 7132c61054cSTony Nguyen if (status) 7140fee3577SLihong Yang dev_dbg(ice_pf_to_dev(pf), "ice_rem_vsi_rss_cfg failed for vsi = %d, error = %s\n", 7150fee3577SLihong Yang vsi->vsi_num, ice_stat_str(status)); 7162c61054cSTony Nguyen } 7172c61054cSTony Nguyen 7182c61054cSTony Nguyen /** 7192c61054cSTony Nguyen * ice_rss_clean - Delete RSS related VSI structures and configuration 720df0f8479SAnirudh Venkataramanan * @vsi: the VSI being removed 721df0f8479SAnirudh Venkataramanan */ 722df0f8479SAnirudh Venkataramanan static void ice_rss_clean(struct ice_vsi *vsi) 723df0f8479SAnirudh Venkataramanan { 7244015d11eSBrett Creeley struct ice_pf *pf = vsi->back; 7254015d11eSBrett Creeley struct device *dev; 726df0f8479SAnirudh Venkataramanan 7274015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 728df0f8479SAnirudh Venkataramanan 729df0f8479SAnirudh Venkataramanan if (vsi->rss_hkey_user) 7304015d11eSBrett Creeley devm_kfree(dev, vsi->rss_hkey_user); 731df0f8479SAnirudh Venkataramanan if (vsi->rss_lut_user) 7324015d11eSBrett Creeley devm_kfree(dev, vsi->rss_lut_user); 7332c61054cSTony Nguyen 7342c61054cSTony Nguyen ice_vsi_clean_rss_flow_fld(vsi); 7352c61054cSTony Nguyen /* remove RSS replay list */ 7362c61054cSTony Nguyen if (!ice_is_safe_mode(pf)) 7372c61054cSTony Nguyen ice_rem_vsi_rss_list(&pf->hw, vsi->idx); 738df0f8479SAnirudh Venkataramanan } 739df0f8479SAnirudh Venkataramanan 740df0f8479SAnirudh Venkataramanan /** 74128c2a645SAnirudh Venkataramanan * ice_vsi_set_rss_params - Setup RSS capabilities per VSI type 74228c2a645SAnirudh Venkataramanan * @vsi: the VSI being configured 74328c2a645SAnirudh Venkataramanan */ 74437bb8390SAnirudh Venkataramanan static void ice_vsi_set_rss_params(struct ice_vsi *vsi) 74528c2a645SAnirudh Venkataramanan { 74628c2a645SAnirudh Venkataramanan struct ice_hw_common_caps *cap; 74728c2a645SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 74828c2a645SAnirudh Venkataramanan 74928c2a645SAnirudh Venkataramanan if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 75028c2a645SAnirudh Venkataramanan vsi->rss_size = 1; 75128c2a645SAnirudh Venkataramanan return; 75228c2a645SAnirudh Venkataramanan } 75328c2a645SAnirudh Venkataramanan 75428c2a645SAnirudh Venkataramanan cap = &pf->hw.func_caps.common_cap; 75528c2a645SAnirudh Venkataramanan switch (vsi->type) { 756*0754d65bSKiran Patil case ICE_VSI_CHNL: 75728c2a645SAnirudh Venkataramanan case ICE_VSI_PF: 75828c2a645SAnirudh Venkataramanan /* PF VSI will inherit RSS instance of PF */ 75988865fc4SKarol Kolacinski vsi->rss_table_size = (u16)cap->rss_table_size; 760*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL) 761*0754d65bSKiran Patil vsi->rss_size = min_t(u16, vsi->num_rxq, 762*0754d65bSKiran Patil BIT(cap->rss_table_entry_width)); 763*0754d65bSKiran Patil else 76488865fc4SKarol Kolacinski vsi->rss_size = min_t(u16, num_online_cpus(), 76528c2a645SAnirudh Venkataramanan BIT(cap->rss_table_entry_width)); 76628c2a645SAnirudh Venkataramanan vsi->rss_lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF; 76728c2a645SAnirudh Venkataramanan break; 768f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 769f66756e0SGrzegorz Nitka vsi->rss_table_size = ICE_VSIQF_HLUT_ARRAY_SIZE; 770f66756e0SGrzegorz Nitka vsi->rss_size = min_t(u16, num_online_cpus(), 771f66756e0SGrzegorz Nitka BIT(cap->rss_table_entry_width)); 772f66756e0SGrzegorz Nitka vsi->rss_lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI; 773f66756e0SGrzegorz Nitka break; 7748ede0178SAnirudh Venkataramanan case ICE_VSI_VF: 7750ca469fbSMitch Williams /* VF VSI will get a small RSS table. 7760ca469fbSMitch Williams * For VSI_LUT, LUT size should be set to 64 bytes. 7778ede0178SAnirudh Venkataramanan */ 7788ede0178SAnirudh Venkataramanan vsi->rss_table_size = ICE_VSIQF_HLUT_ARRAY_SIZE; 7790ca469fbSMitch Williams vsi->rss_size = ICE_MAX_RSS_QS_PER_VF; 7808ede0178SAnirudh Venkataramanan vsi->rss_lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI; 7818ede0178SAnirudh Venkataramanan break; 7820e674aebSAnirudh Venkataramanan case ICE_VSI_LB: 7830e674aebSAnirudh Venkataramanan break; 78428c2a645SAnirudh Venkataramanan default: 785148beb61SHenry Tieman dev_dbg(ice_pf_to_dev(pf), "Unsupported VSI type %s\n", 786148beb61SHenry Tieman ice_vsi_type_str(vsi->type)); 78728c2a645SAnirudh Venkataramanan break; 78828c2a645SAnirudh Venkataramanan } 78928c2a645SAnirudh Venkataramanan } 79028c2a645SAnirudh Venkataramanan 79128c2a645SAnirudh Venkataramanan /** 79228c2a645SAnirudh Venkataramanan * ice_set_dflt_vsi_ctx - Set default VSI context before adding a VSI 79328c2a645SAnirudh Venkataramanan * @ctxt: the VSI context being set 79428c2a645SAnirudh Venkataramanan * 79528c2a645SAnirudh Venkataramanan * This initializes a default VSI context for all sections except the Queues. 79628c2a645SAnirudh Venkataramanan */ 79728c2a645SAnirudh Venkataramanan static void ice_set_dflt_vsi_ctx(struct ice_vsi_ctx *ctxt) 79828c2a645SAnirudh Venkataramanan { 79928c2a645SAnirudh Venkataramanan u32 table = 0; 80028c2a645SAnirudh Venkataramanan 80128c2a645SAnirudh Venkataramanan memset(&ctxt->info, 0, sizeof(ctxt->info)); 80228c2a645SAnirudh Venkataramanan /* VSI's should be allocated from shared pool */ 80328c2a645SAnirudh Venkataramanan ctxt->alloc_from_pool = true; 80428c2a645SAnirudh Venkataramanan /* Src pruning enabled by default */ 80528c2a645SAnirudh Venkataramanan ctxt->info.sw_flags = ICE_AQ_VSI_SW_FLAG_SRC_PRUNE; 80628c2a645SAnirudh Venkataramanan /* Traffic from VSI can be sent to LAN */ 80728c2a645SAnirudh Venkataramanan ctxt->info.sw_flags2 = ICE_AQ_VSI_SW_FLAG_LAN_ENA; 80828c2a645SAnirudh Venkataramanan /* By default bits 3 and 4 in vlan_flags are 0's which results in legacy 80928c2a645SAnirudh Venkataramanan * behavior (show VLAN, DEI, and UP) in descriptor. Also, allow all 81028c2a645SAnirudh Venkataramanan * packets untagged/tagged. 81128c2a645SAnirudh Venkataramanan */ 81228c2a645SAnirudh Venkataramanan ctxt->info.vlan_flags = ((ICE_AQ_VSI_VLAN_MODE_ALL & 81328c2a645SAnirudh Venkataramanan ICE_AQ_VSI_VLAN_MODE_M) >> 81428c2a645SAnirudh Venkataramanan ICE_AQ_VSI_VLAN_MODE_S); 81528c2a645SAnirudh Venkataramanan /* Have 1:1 UP mapping for both ingress/egress tables */ 81628c2a645SAnirudh Venkataramanan table |= ICE_UP_TABLE_TRANSLATE(0, 0); 81728c2a645SAnirudh Venkataramanan table |= ICE_UP_TABLE_TRANSLATE(1, 1); 81828c2a645SAnirudh Venkataramanan table |= ICE_UP_TABLE_TRANSLATE(2, 2); 81928c2a645SAnirudh Venkataramanan table |= ICE_UP_TABLE_TRANSLATE(3, 3); 82028c2a645SAnirudh Venkataramanan table |= ICE_UP_TABLE_TRANSLATE(4, 4); 82128c2a645SAnirudh Venkataramanan table |= ICE_UP_TABLE_TRANSLATE(5, 5); 82228c2a645SAnirudh Venkataramanan table |= ICE_UP_TABLE_TRANSLATE(6, 6); 82328c2a645SAnirudh Venkataramanan table |= ICE_UP_TABLE_TRANSLATE(7, 7); 82428c2a645SAnirudh Venkataramanan ctxt->info.ingress_table = cpu_to_le32(table); 82528c2a645SAnirudh Venkataramanan ctxt->info.egress_table = cpu_to_le32(table); 82628c2a645SAnirudh Venkataramanan /* Have 1:1 UP mapping for outer to inner UP table */ 82728c2a645SAnirudh Venkataramanan ctxt->info.outer_up_table = cpu_to_le32(table); 82828c2a645SAnirudh Venkataramanan /* No Outer tag support outer_tag_flags remains to zero */ 82928c2a645SAnirudh Venkataramanan } 83028c2a645SAnirudh Venkataramanan 83128c2a645SAnirudh Venkataramanan /** 83228c2a645SAnirudh Venkataramanan * ice_vsi_setup_q_map - Setup a VSI queue map 83328c2a645SAnirudh Venkataramanan * @vsi: the VSI being configured 83428c2a645SAnirudh Venkataramanan * @ctxt: VSI context structure 83528c2a645SAnirudh Venkataramanan */ 83628c2a645SAnirudh Venkataramanan static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt) 83728c2a645SAnirudh Venkataramanan { 8388134d5ffSBrett Creeley u16 offset = 0, qmap = 0, tx_count = 0, pow = 0; 8398134d5ffSBrett Creeley u16 num_txq_per_tc, num_rxq_per_tc; 84028c2a645SAnirudh Venkataramanan u16 qcount_tx = vsi->alloc_txq; 84128c2a645SAnirudh Venkataramanan u16 qcount_rx = vsi->alloc_rxq; 842c5a2a4a3SUsha Ketineni u8 netdev_tc = 0; 84328c2a645SAnirudh Venkataramanan int i; 84428c2a645SAnirudh Venkataramanan 845*0754d65bSKiran Patil if (!vsi->tc_cfg.numtc) { 84628c2a645SAnirudh Venkataramanan /* at least TC0 should be enabled by default */ 847*0754d65bSKiran Patil vsi->tc_cfg.numtc = 1; 848*0754d65bSKiran Patil vsi->tc_cfg.ena_tc = 1; 84928c2a645SAnirudh Venkataramanan } 85028c2a645SAnirudh Venkataramanan 8518134d5ffSBrett Creeley num_rxq_per_tc = min_t(u16, qcount_rx / vsi->tc_cfg.numtc, ICE_MAX_RXQS_PER_TC); 8528134d5ffSBrett Creeley if (!num_rxq_per_tc) 8538134d5ffSBrett Creeley num_rxq_per_tc = 1; 8548134d5ffSBrett Creeley num_txq_per_tc = qcount_tx / vsi->tc_cfg.numtc; 8558134d5ffSBrett Creeley if (!num_txq_per_tc) 8568134d5ffSBrett Creeley num_txq_per_tc = 1; 8578134d5ffSBrett Creeley 8588134d5ffSBrett Creeley /* find the (rounded up) power-of-2 of qcount */ 8598134d5ffSBrett Creeley pow = (u16)order_base_2(num_rxq_per_tc); 86028c2a645SAnirudh Venkataramanan 86128c2a645SAnirudh Venkataramanan /* TC mapping is a function of the number of Rx queues assigned to the 86228c2a645SAnirudh Venkataramanan * VSI for each traffic class and the offset of these queues. 86328c2a645SAnirudh Venkataramanan * The first 10 bits are for queue offset for TC0, next 4 bits for no:of 86428c2a645SAnirudh Venkataramanan * queues allocated to TC0. No:of queues is a power-of-2. 86528c2a645SAnirudh Venkataramanan * 86628c2a645SAnirudh Venkataramanan * If TC is not enabled, the queue offset is set to 0, and allocate one 86728c2a645SAnirudh Venkataramanan * queue, this way, traffic for the given TC will be sent to the default 86828c2a645SAnirudh Venkataramanan * queue. 86928c2a645SAnirudh Venkataramanan * 87028c2a645SAnirudh Venkataramanan * Setup number and offset of Rx queues for all TCs for the VSI 87128c2a645SAnirudh Venkataramanan */ 8722bdc97beSBruce Allan ice_for_each_traffic_class(i) { 87328c2a645SAnirudh Venkataramanan if (!(vsi->tc_cfg.ena_tc & BIT(i))) { 87428c2a645SAnirudh Venkataramanan /* TC is not enabled */ 87528c2a645SAnirudh Venkataramanan vsi->tc_cfg.tc_info[i].qoffset = 0; 876c5a2a4a3SUsha Ketineni vsi->tc_cfg.tc_info[i].qcount_rx = 1; 877c5a2a4a3SUsha Ketineni vsi->tc_cfg.tc_info[i].qcount_tx = 1; 878c5a2a4a3SUsha Ketineni vsi->tc_cfg.tc_info[i].netdev_tc = 0; 87928c2a645SAnirudh Venkataramanan ctxt->info.tc_mapping[i] = 0; 88028c2a645SAnirudh Venkataramanan continue; 88128c2a645SAnirudh Venkataramanan } 88228c2a645SAnirudh Venkataramanan 88328c2a645SAnirudh Venkataramanan /* TC is enabled */ 88428c2a645SAnirudh Venkataramanan vsi->tc_cfg.tc_info[i].qoffset = offset; 8858134d5ffSBrett Creeley vsi->tc_cfg.tc_info[i].qcount_rx = num_rxq_per_tc; 8868134d5ffSBrett Creeley vsi->tc_cfg.tc_info[i].qcount_tx = num_txq_per_tc; 887c5a2a4a3SUsha Ketineni vsi->tc_cfg.tc_info[i].netdev_tc = netdev_tc++; 88828c2a645SAnirudh Venkataramanan 88928c2a645SAnirudh Venkataramanan qmap = ((offset << ICE_AQ_VSI_TC_Q_OFFSET_S) & 89028c2a645SAnirudh Venkataramanan ICE_AQ_VSI_TC_Q_OFFSET_M) | 89128c2a645SAnirudh Venkataramanan ((pow << ICE_AQ_VSI_TC_Q_NUM_S) & 89228c2a645SAnirudh Venkataramanan ICE_AQ_VSI_TC_Q_NUM_M); 8938134d5ffSBrett Creeley offset += num_rxq_per_tc; 8948134d5ffSBrett Creeley tx_count += num_txq_per_tc; 89528c2a645SAnirudh Venkataramanan ctxt->info.tc_mapping[i] = cpu_to_le16(qmap); 89628c2a645SAnirudh Venkataramanan } 89760dcc39eSKiran Patil 89860dcc39eSKiran Patil /* if offset is non-zero, means it is calculated correctly based on 89960dcc39eSKiran Patil * enabled TCs for a given VSI otherwise qcount_rx will always 90060dcc39eSKiran Patil * be correct and non-zero because it is based off - VSI's 90160dcc39eSKiran Patil * allocated Rx queues which is at least 1 (hence qcount_tx will be 90260dcc39eSKiran Patil * at least 1) 90360dcc39eSKiran Patil */ 90460dcc39eSKiran Patil if (offset) 90528c2a645SAnirudh Venkataramanan vsi->num_rxq = offset; 90660dcc39eSKiran Patil else 9078134d5ffSBrett Creeley vsi->num_rxq = num_rxq_per_tc; 90860dcc39eSKiran Patil 909c5a2a4a3SUsha Ketineni vsi->num_txq = tx_count; 91028c2a645SAnirudh Venkataramanan 9118ede0178SAnirudh Venkataramanan if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) { 9129a946843SAnirudh Venkataramanan dev_dbg(ice_pf_to_dev(vsi->back), "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n"); 9138ede0178SAnirudh Venkataramanan /* since there is a chance that num_rxq could have been changed 9148ede0178SAnirudh Venkataramanan * in the above for loop, make num_txq equal to num_rxq. 9158ede0178SAnirudh Venkataramanan */ 9168ede0178SAnirudh Venkataramanan vsi->num_txq = vsi->num_rxq; 9178ede0178SAnirudh Venkataramanan } 9188ede0178SAnirudh Venkataramanan 91928c2a645SAnirudh Venkataramanan /* Rx queue mapping */ 92028c2a645SAnirudh Venkataramanan ctxt->info.mapping_flags |= cpu_to_le16(ICE_AQ_VSI_Q_MAP_CONTIG); 92128c2a645SAnirudh Venkataramanan /* q_mapping buffer holds the info for the first queue allocated for 92228c2a645SAnirudh Venkataramanan * this VSI in the PF space and also the number of queues associated 92328c2a645SAnirudh Venkataramanan * with this VSI. 92428c2a645SAnirudh Venkataramanan */ 92528c2a645SAnirudh Venkataramanan ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]); 92628c2a645SAnirudh Venkataramanan ctxt->info.q_mapping[1] = cpu_to_le16(vsi->num_rxq); 92728c2a645SAnirudh Venkataramanan } 92828c2a645SAnirudh Venkataramanan 92928c2a645SAnirudh Venkataramanan /** 930148beb61SHenry Tieman * ice_set_fd_vsi_ctx - Set FD VSI context before adding a VSI 931148beb61SHenry Tieman * @ctxt: the VSI context being set 932148beb61SHenry Tieman * @vsi: the VSI being configured 933148beb61SHenry Tieman */ 934148beb61SHenry Tieman static void ice_set_fd_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) 935148beb61SHenry Tieman { 936148beb61SHenry Tieman u8 dflt_q_group, dflt_q_prio; 937148beb61SHenry Tieman u16 dflt_q, report_q, val; 938148beb61SHenry Tieman 939da62c5ffSQi Zhang if (vsi->type != ICE_VSI_PF && vsi->type != ICE_VSI_CTRL && 940da62c5ffSQi Zhang vsi->type != ICE_VSI_VF) 941148beb61SHenry Tieman return; 942148beb61SHenry Tieman 943148beb61SHenry Tieman val = ICE_AQ_VSI_PROP_FLOW_DIR_VALID; 944148beb61SHenry Tieman ctxt->info.valid_sections |= cpu_to_le16(val); 945148beb61SHenry Tieman dflt_q = 0; 946148beb61SHenry Tieman dflt_q_group = 0; 947148beb61SHenry Tieman report_q = 0; 948148beb61SHenry Tieman dflt_q_prio = 0; 949148beb61SHenry Tieman 950148beb61SHenry Tieman /* enable flow director filtering/programming */ 951148beb61SHenry Tieman val = ICE_AQ_VSI_FD_ENABLE | ICE_AQ_VSI_FD_PROG_ENABLE; 952148beb61SHenry Tieman ctxt->info.fd_options = cpu_to_le16(val); 953148beb61SHenry Tieman /* max of allocated flow director filters */ 954148beb61SHenry Tieman ctxt->info.max_fd_fltr_dedicated = 955148beb61SHenry Tieman cpu_to_le16(vsi->num_gfltr); 956148beb61SHenry Tieman /* max of shared flow director filters any VSI may program */ 957148beb61SHenry Tieman ctxt->info.max_fd_fltr_shared = 958148beb61SHenry Tieman cpu_to_le16(vsi->num_bfltr); 959148beb61SHenry Tieman /* default queue index within the VSI of the default FD */ 960148beb61SHenry Tieman val = ((dflt_q << ICE_AQ_VSI_FD_DEF_Q_S) & 961148beb61SHenry Tieman ICE_AQ_VSI_FD_DEF_Q_M); 962148beb61SHenry Tieman /* target queue or queue group to the FD filter */ 963148beb61SHenry Tieman val |= ((dflt_q_group << ICE_AQ_VSI_FD_DEF_GRP_S) & 964148beb61SHenry Tieman ICE_AQ_VSI_FD_DEF_GRP_M); 965148beb61SHenry Tieman ctxt->info.fd_def_q = cpu_to_le16(val); 966148beb61SHenry Tieman /* queue index on which FD filter completion is reported */ 967148beb61SHenry Tieman val = ((report_q << ICE_AQ_VSI_FD_REPORT_Q_S) & 968148beb61SHenry Tieman ICE_AQ_VSI_FD_REPORT_Q_M); 969148beb61SHenry Tieman /* priority of the default qindex action */ 970148beb61SHenry Tieman val |= ((dflt_q_prio << ICE_AQ_VSI_FD_DEF_PRIORITY_S) & 971148beb61SHenry Tieman ICE_AQ_VSI_FD_DEF_PRIORITY_M); 972148beb61SHenry Tieman ctxt->info.fd_report_opt = cpu_to_le16(val); 973148beb61SHenry Tieman } 974148beb61SHenry Tieman 975148beb61SHenry Tieman /** 97628c2a645SAnirudh Venkataramanan * ice_set_rss_vsi_ctx - Set RSS VSI context before adding a VSI 97728c2a645SAnirudh Venkataramanan * @ctxt: the VSI context being set 97828c2a645SAnirudh Venkataramanan * @vsi: the VSI being configured 97928c2a645SAnirudh Venkataramanan */ 98028c2a645SAnirudh Venkataramanan static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) 98128c2a645SAnirudh Venkataramanan { 98228c2a645SAnirudh Venkataramanan u8 lut_type, hash_type; 9834015d11eSBrett Creeley struct device *dev; 984819d8998SJesse Brandeburg struct ice_pf *pf; 985819d8998SJesse Brandeburg 986819d8998SJesse Brandeburg pf = vsi->back; 9874015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 98828c2a645SAnirudh Venkataramanan 98928c2a645SAnirudh Venkataramanan switch (vsi->type) { 990*0754d65bSKiran Patil case ICE_VSI_CHNL: 99128c2a645SAnirudh Venkataramanan case ICE_VSI_PF: 99228c2a645SAnirudh Venkataramanan /* PF VSI will inherit RSS instance of PF */ 99328c2a645SAnirudh Venkataramanan lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_PF; 99428c2a645SAnirudh Venkataramanan hash_type = ICE_AQ_VSI_Q_OPT_RSS_TPLZ; 99528c2a645SAnirudh Venkataramanan break; 9968ede0178SAnirudh Venkataramanan case ICE_VSI_VF: 9978ede0178SAnirudh Venkataramanan /* VF VSI will gets a small RSS table which is a VSI LUT type */ 9988ede0178SAnirudh Venkataramanan lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; 9998ede0178SAnirudh Venkataramanan hash_type = ICE_AQ_VSI_Q_OPT_RSS_TPLZ; 10008ede0178SAnirudh Venkataramanan break; 1001148beb61SHenry Tieman default: 10024015d11eSBrett Creeley dev_dbg(dev, "Unsupported VSI type %s\n", 1003964674f1SAnirudh Venkataramanan ice_vsi_type_str(vsi->type)); 10040e674aebSAnirudh Venkataramanan return; 100528c2a645SAnirudh Venkataramanan } 100628c2a645SAnirudh Venkataramanan 100728c2a645SAnirudh Venkataramanan ctxt->info.q_opt_rss = ((lut_type << ICE_AQ_VSI_Q_OPT_RSS_LUT_S) & 100828c2a645SAnirudh Venkataramanan ICE_AQ_VSI_Q_OPT_RSS_LUT_M) | 100928c2a645SAnirudh Venkataramanan ((hash_type << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) & 101028c2a645SAnirudh Venkataramanan ICE_AQ_VSI_Q_OPT_RSS_HASH_M); 101128c2a645SAnirudh Venkataramanan } 101228c2a645SAnirudh Venkataramanan 1013*0754d65bSKiran Patil static void 1014*0754d65bSKiran Patil ice_chnl_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt) 1015*0754d65bSKiran Patil { 1016*0754d65bSKiran Patil struct ice_pf *pf = vsi->back; 1017*0754d65bSKiran Patil u16 qcount, qmap; 1018*0754d65bSKiran Patil u8 offset = 0; 1019*0754d65bSKiran Patil int pow; 1020*0754d65bSKiran Patil 1021*0754d65bSKiran Patil qcount = min_t(int, vsi->num_rxq, pf->num_lan_msix); 1022*0754d65bSKiran Patil 1023*0754d65bSKiran Patil pow = order_base_2(qcount); 1024*0754d65bSKiran Patil qmap = ((offset << ICE_AQ_VSI_TC_Q_OFFSET_S) & 1025*0754d65bSKiran Patil ICE_AQ_VSI_TC_Q_OFFSET_M) | 1026*0754d65bSKiran Patil ((pow << ICE_AQ_VSI_TC_Q_NUM_S) & 1027*0754d65bSKiran Patil ICE_AQ_VSI_TC_Q_NUM_M); 1028*0754d65bSKiran Patil 1029*0754d65bSKiran Patil ctxt->info.tc_mapping[0] = cpu_to_le16(qmap); 1030*0754d65bSKiran Patil ctxt->info.mapping_flags |= cpu_to_le16(ICE_AQ_VSI_Q_MAP_CONTIG); 1031*0754d65bSKiran Patil ctxt->info.q_mapping[0] = cpu_to_le16(vsi->next_base_q); 1032*0754d65bSKiran Patil ctxt->info.q_mapping[1] = cpu_to_le16(qcount); 1033*0754d65bSKiran Patil } 1034*0754d65bSKiran Patil 103528c2a645SAnirudh Venkataramanan /** 103628c2a645SAnirudh Venkataramanan * ice_vsi_init - Create and initialize a VSI 103728c2a645SAnirudh Venkataramanan * @vsi: the VSI being configured 103887324e74SHenry Tieman * @init_vsi: is this call creating a VSI 103928c2a645SAnirudh Venkataramanan * 104028c2a645SAnirudh Venkataramanan * This initializes a VSI context depending on the VSI type to be added and 104128c2a645SAnirudh Venkataramanan * passes it down to the add_vsi aq command to create a new VSI. 104228c2a645SAnirudh Venkataramanan */ 104387324e74SHenry Tieman static int ice_vsi_init(struct ice_vsi *vsi, bool init_vsi) 104428c2a645SAnirudh Venkataramanan { 104528c2a645SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 104628c2a645SAnirudh Venkataramanan struct ice_hw *hw = &pf->hw; 1047198a666aSBruce Allan struct ice_vsi_ctx *ctxt; 104887324e74SHenry Tieman struct device *dev; 104928c2a645SAnirudh Venkataramanan int ret = 0; 105028c2a645SAnirudh Venkataramanan 105187324e74SHenry Tieman dev = ice_pf_to_dev(pf); 10529efe35d0STony Nguyen ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); 1053198a666aSBruce Allan if (!ctxt) 1054198a666aSBruce Allan return -ENOMEM; 1055198a666aSBruce Allan 105628c2a645SAnirudh Venkataramanan switch (vsi->type) { 1057148beb61SHenry Tieman case ICE_VSI_CTRL: 10580e674aebSAnirudh Venkataramanan case ICE_VSI_LB: 105928c2a645SAnirudh Venkataramanan case ICE_VSI_PF: 1060198a666aSBruce Allan ctxt->flags = ICE_AQ_VSI_TYPE_PF; 106128c2a645SAnirudh Venkataramanan break; 1062f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 1063*0754d65bSKiran Patil case ICE_VSI_CHNL: 1064f66756e0SGrzegorz Nitka ctxt->flags = ICE_AQ_VSI_TYPE_VMDQ2; 1065f66756e0SGrzegorz Nitka break; 10668ede0178SAnirudh Venkataramanan case ICE_VSI_VF: 1067198a666aSBruce Allan ctxt->flags = ICE_AQ_VSI_TYPE_VF; 10688ede0178SAnirudh Venkataramanan /* VF number here is the absolute VF number (0-255) */ 1069198a666aSBruce Allan ctxt->vf_num = vsi->vf_id + hw->func_caps.vf_base_id; 10708ede0178SAnirudh Venkataramanan break; 107128c2a645SAnirudh Venkataramanan default: 10729efe35d0STony Nguyen ret = -ENODEV; 10739efe35d0STony Nguyen goto out; 107428c2a645SAnirudh Venkataramanan } 107528c2a645SAnirudh Venkataramanan 1076*0754d65bSKiran Patil /* Handle VLAN pruning for channel VSI if main VSI has VLAN 1077*0754d65bSKiran Patil * prune enabled 1078*0754d65bSKiran Patil */ 1079*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL) { 1080*0754d65bSKiran Patil struct ice_vsi *main_vsi; 1081*0754d65bSKiran Patil 1082*0754d65bSKiran Patil main_vsi = ice_get_main_vsi(pf); 1083*0754d65bSKiran Patil if (main_vsi && ice_vsi_is_vlan_pruning_ena(main_vsi)) 1084*0754d65bSKiran Patil ctxt->info.sw_flags2 |= 1085*0754d65bSKiran Patil ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA; 1086*0754d65bSKiran Patil else 1087*0754d65bSKiran Patil ctxt->info.sw_flags2 &= 1088*0754d65bSKiran Patil ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA; 1089*0754d65bSKiran Patil } 1090*0754d65bSKiran Patil 1091198a666aSBruce Allan ice_set_dflt_vsi_ctx(ctxt); 1092148beb61SHenry Tieman if (test_bit(ICE_FLAG_FD_ENA, pf->flags)) 1093148beb61SHenry Tieman ice_set_fd_vsi_ctx(ctxt, vsi); 109428c2a645SAnirudh Venkataramanan /* if the switch is in VEB mode, allow VSI loopback */ 109528c2a645SAnirudh Venkataramanan if (vsi->vsw->bridge_mode == BRIDGE_MODE_VEB) 1096198a666aSBruce Allan ctxt->info.sw_flags |= ICE_AQ_VSI_SW_FLAG_ALLOW_LB; 109728c2a645SAnirudh Venkataramanan 109828c2a645SAnirudh Venkataramanan /* Set LUT type and HASH type if RSS is enabled */ 1099148beb61SHenry Tieman if (test_bit(ICE_FLAG_RSS_ENA, pf->flags) && 1100148beb61SHenry Tieman vsi->type != ICE_VSI_CTRL) { 1101198a666aSBruce Allan ice_set_rss_vsi_ctx(ctxt, vsi); 110287324e74SHenry Tieman /* if updating VSI context, make sure to set valid_section: 110387324e74SHenry Tieman * to indicate which section of VSI context being updated 110487324e74SHenry Tieman */ 110587324e74SHenry Tieman if (!init_vsi) 110687324e74SHenry Tieman ctxt->info.valid_sections |= 110787324e74SHenry Tieman cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID); 110887324e74SHenry Tieman } 110928c2a645SAnirudh Venkataramanan 1110198a666aSBruce Allan ctxt->info.sw_id = vsi->port_info->sw_id; 1111*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL) { 1112*0754d65bSKiran Patil ice_chnl_vsi_setup_q_map(vsi, ctxt); 1113*0754d65bSKiran Patil } else { 1114198a666aSBruce Allan ice_vsi_setup_q_map(vsi, ctxt); 111587324e74SHenry Tieman if (!init_vsi) /* means VSI being updated */ 111687324e74SHenry Tieman /* must to indicate which section of VSI context are 111787324e74SHenry Tieman * being modified 111887324e74SHenry Tieman */ 111987324e74SHenry Tieman ctxt->info.valid_sections |= 112087324e74SHenry Tieman cpu_to_le16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID); 1121*0754d65bSKiran Patil } 112228c2a645SAnirudh Venkataramanan 1123cd6d6b83SBrett Creeley /* enable/disable MAC and VLAN anti-spoof when spoofchk is on/off 1124cd6d6b83SBrett Creeley * respectively 1125cd6d6b83SBrett Creeley */ 1126cd6d6b83SBrett Creeley if (vsi->type == ICE_VSI_VF) { 1127cb93a952SAkeem G Abodunrin ctxt->info.valid_sections |= 1128cb93a952SAkeem G Abodunrin cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID); 1129cd6d6b83SBrett Creeley if (pf->vf[vsi->vf_id].spoofchk) { 1130cb93a952SAkeem G Abodunrin ctxt->info.sec_flags |= 1131cd6d6b83SBrett Creeley ICE_AQ_VSI_SEC_FLAG_ENA_MAC_ANTI_SPOOF | 1132cd6d6b83SBrett Creeley (ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA << 1133cd6d6b83SBrett Creeley ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S); 1134cd6d6b83SBrett Creeley } else { 1135cd6d6b83SBrett Creeley ctxt->info.sec_flags &= 1136cd6d6b83SBrett Creeley ~(ICE_AQ_VSI_SEC_FLAG_ENA_MAC_ANTI_SPOOF | 1137cd6d6b83SBrett Creeley (ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA << 1138cd6d6b83SBrett Creeley ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S)); 1139cd6d6b83SBrett Creeley } 1140cb93a952SAkeem G Abodunrin } 1141cb93a952SAkeem G Abodunrin 11420c3a6101SDave Ertman /* Allow control frames out of main VSI */ 11430c3a6101SDave Ertman if (vsi->type == ICE_VSI_PF) { 11440c3a6101SDave Ertman ctxt->info.sec_flags |= ICE_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD; 11450c3a6101SDave Ertman ctxt->info.valid_sections |= 11460c3a6101SDave Ertman cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID); 11470c3a6101SDave Ertman } 11480c3a6101SDave Ertman 114987324e74SHenry Tieman if (init_vsi) { 1150198a666aSBruce Allan ret = ice_add_vsi(hw, vsi->idx, ctxt, NULL); 115128c2a645SAnirudh Venkataramanan if (ret) { 115287324e74SHenry Tieman dev_err(dev, "Add VSI failed, err %d\n", ret); 11539efe35d0STony Nguyen ret = -EIO; 11549efe35d0STony Nguyen goto out; 115528c2a645SAnirudh Venkataramanan } 115687324e74SHenry Tieman } else { 115787324e74SHenry Tieman ret = ice_update_vsi(hw, vsi->idx, ctxt, NULL); 115887324e74SHenry Tieman if (ret) { 115987324e74SHenry Tieman dev_err(dev, "Update VSI failed, err %d\n", ret); 116087324e74SHenry Tieman ret = -EIO; 116187324e74SHenry Tieman goto out; 116287324e74SHenry Tieman } 116387324e74SHenry Tieman } 116428c2a645SAnirudh Venkataramanan 116528c2a645SAnirudh Venkataramanan /* keep context for update VSI operations */ 1166198a666aSBruce Allan vsi->info = ctxt->info; 116728c2a645SAnirudh Venkataramanan 116828c2a645SAnirudh Venkataramanan /* record VSI number returned */ 1169198a666aSBruce Allan vsi->vsi_num = ctxt->vsi_num; 117028c2a645SAnirudh Venkataramanan 11719efe35d0STony Nguyen out: 11729efe35d0STony Nguyen kfree(ctxt); 117328c2a645SAnirudh Venkataramanan return ret; 117428c2a645SAnirudh Venkataramanan } 117528c2a645SAnirudh Venkataramanan 117628c2a645SAnirudh Venkataramanan /** 117746c276ceSBrett Creeley * ice_free_res - free a block of resources 117846c276ceSBrett Creeley * @res: pointer to the resource 117946c276ceSBrett Creeley * @index: starting index previously returned by ice_get_res 118046c276ceSBrett Creeley * @id: identifier to track owner 118146c276ceSBrett Creeley * 118246c276ceSBrett Creeley * Returns number of resources freed 118346c276ceSBrett Creeley */ 118446c276ceSBrett Creeley int ice_free_res(struct ice_res_tracker *res, u16 index, u16 id) 118546c276ceSBrett Creeley { 118646c276ceSBrett Creeley int count = 0; 118746c276ceSBrett Creeley int i; 118846c276ceSBrett Creeley 118946c276ceSBrett Creeley if (!res || index >= res->end) 119046c276ceSBrett Creeley return -EINVAL; 119146c276ceSBrett Creeley 119246c276ceSBrett Creeley id |= ICE_RES_VALID_BIT; 119346c276ceSBrett Creeley for (i = index; i < res->end && res->list[i] == id; i++) { 119446c276ceSBrett Creeley res->list[i] = 0; 119546c276ceSBrett Creeley count++; 119646c276ceSBrett Creeley } 119746c276ceSBrett Creeley 119846c276ceSBrett Creeley return count; 119946c276ceSBrett Creeley } 120046c276ceSBrett Creeley 120146c276ceSBrett Creeley /** 120246c276ceSBrett Creeley * ice_search_res - Search the tracker for a block of resources 120346c276ceSBrett Creeley * @res: pointer to the resource 120446c276ceSBrett Creeley * @needed: size of the block needed 120546c276ceSBrett Creeley * @id: identifier to track owner 120646c276ceSBrett Creeley * 120746c276ceSBrett Creeley * Returns the base item index of the block, or -ENOMEM for error 120846c276ceSBrett Creeley */ 120946c276ceSBrett Creeley static int ice_search_res(struct ice_res_tracker *res, u16 needed, u16 id) 121046c276ceSBrett Creeley { 121188865fc4SKarol Kolacinski u16 start = 0, end = 0; 121246c276ceSBrett Creeley 121346c276ceSBrett Creeley if (needed > res->end) 121446c276ceSBrett Creeley return -ENOMEM; 121546c276ceSBrett Creeley 121646c276ceSBrett Creeley id |= ICE_RES_VALID_BIT; 121746c276ceSBrett Creeley 121846c276ceSBrett Creeley do { 121946c276ceSBrett Creeley /* skip already allocated entries */ 122046c276ceSBrett Creeley if (res->list[end++] & ICE_RES_VALID_BIT) { 122146c276ceSBrett Creeley start = end; 122246c276ceSBrett Creeley if ((start + needed) > res->end) 122346c276ceSBrett Creeley break; 122446c276ceSBrett Creeley } 122546c276ceSBrett Creeley 122646c276ceSBrett Creeley if (end == (start + needed)) { 122746c276ceSBrett Creeley int i = start; 122846c276ceSBrett Creeley 122946c276ceSBrett Creeley /* there was enough, so assign it to the requestor */ 123046c276ceSBrett Creeley while (i != end) 123146c276ceSBrett Creeley res->list[i++] = id; 123246c276ceSBrett Creeley 123346c276ceSBrett Creeley return start; 123446c276ceSBrett Creeley } 123546c276ceSBrett Creeley } while (end < res->end); 123646c276ceSBrett Creeley 123746c276ceSBrett Creeley return -ENOMEM; 123846c276ceSBrett Creeley } 123946c276ceSBrett Creeley 124046c276ceSBrett Creeley /** 124146c276ceSBrett Creeley * ice_get_free_res_count - Get free count from a resource tracker 124246c276ceSBrett Creeley * @res: Resource tracker instance 124346c276ceSBrett Creeley */ 124446c276ceSBrett Creeley static u16 ice_get_free_res_count(struct ice_res_tracker *res) 124546c276ceSBrett Creeley { 124646c276ceSBrett Creeley u16 i, count = 0; 124746c276ceSBrett Creeley 124846c276ceSBrett Creeley for (i = 0; i < res->end; i++) 124946c276ceSBrett Creeley if (!(res->list[i] & ICE_RES_VALID_BIT)) 125046c276ceSBrett Creeley count++; 125146c276ceSBrett Creeley 125246c276ceSBrett Creeley return count; 125346c276ceSBrett Creeley } 125446c276ceSBrett Creeley 125546c276ceSBrett Creeley /** 125646c276ceSBrett Creeley * ice_get_res - get a block of resources 125746c276ceSBrett Creeley * @pf: board private structure 125846c276ceSBrett Creeley * @res: pointer to the resource 125946c276ceSBrett Creeley * @needed: size of the block needed 126046c276ceSBrett Creeley * @id: identifier to track owner 126146c276ceSBrett Creeley * 126246c276ceSBrett Creeley * Returns the base item index of the block, or negative for error 126346c276ceSBrett Creeley */ 126446c276ceSBrett Creeley int 126546c276ceSBrett Creeley ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res, u16 needed, u16 id) 126646c276ceSBrett Creeley { 126746c276ceSBrett Creeley if (!res || !pf) 126846c276ceSBrett Creeley return -EINVAL; 126946c276ceSBrett Creeley 127046c276ceSBrett Creeley if (!needed || needed > res->num_entries || id >= ICE_RES_VALID_BIT) { 127146c276ceSBrett Creeley dev_err(ice_pf_to_dev(pf), "param err: needed=%d, num_entries = %d id=0x%04x\n", 127246c276ceSBrett Creeley needed, res->num_entries, id); 127346c276ceSBrett Creeley return -EINVAL; 127446c276ceSBrett Creeley } 127546c276ceSBrett Creeley 127646c276ceSBrett Creeley return ice_search_res(res, needed, id); 127746c276ceSBrett Creeley } 127846c276ceSBrett Creeley 127946c276ceSBrett Creeley /** 1280df0f8479SAnirudh Venkataramanan * ice_vsi_setup_vector_base - Set up the base vector for the given VSI 1281df0f8479SAnirudh Venkataramanan * @vsi: ptr to the VSI 1282df0f8479SAnirudh Venkataramanan * 1283df0f8479SAnirudh Venkataramanan * This should only be called after ice_vsi_alloc() which allocates the 1284df0f8479SAnirudh Venkataramanan * corresponding SW VSI structure and initializes num_queue_pairs for the 1285df0f8479SAnirudh Venkataramanan * newly allocated VSI. 1286df0f8479SAnirudh Venkataramanan * 1287df0f8479SAnirudh Venkataramanan * Returns 0 on success or negative on failure 1288df0f8479SAnirudh Venkataramanan */ 128937bb8390SAnirudh Venkataramanan static int ice_vsi_setup_vector_base(struct ice_vsi *vsi) 1290df0f8479SAnirudh Venkataramanan { 1291df0f8479SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 12924015d11eSBrett Creeley struct device *dev; 1293cbe66bfeSBrett Creeley u16 num_q_vectors; 129488865fc4SKarol Kolacinski int base; 1295df0f8479SAnirudh Venkataramanan 12964015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 1297cbe66bfeSBrett Creeley /* SRIOV doesn't grab irq_tracker entries for each VSI */ 1298cbe66bfeSBrett Creeley if (vsi->type == ICE_VSI_VF) 1299cbe66bfeSBrett Creeley return 0; 1300*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL) 1301*0754d65bSKiran Patil return 0; 1302cbe66bfeSBrett Creeley 1303cbe66bfeSBrett Creeley if (vsi->base_vector) { 13044015d11eSBrett Creeley dev_dbg(dev, "VSI %d has non-zero base vector %d\n", 1305cbe66bfeSBrett Creeley vsi->vsi_num, vsi->base_vector); 1306df0f8479SAnirudh Venkataramanan return -EEXIST; 1307df0f8479SAnirudh Venkataramanan } 1308df0f8479SAnirudh Venkataramanan 1309df0f8479SAnirudh Venkataramanan num_q_vectors = vsi->num_q_vectors; 1310eb0208ecSPreethi Banala /* reserve slots from OS requested IRQs */ 1311da62c5ffSQi Zhang if (vsi->type == ICE_VSI_CTRL && vsi->vf_id != ICE_INVAL_VFID) { 1312da62c5ffSQi Zhang int i; 1313da62c5ffSQi Zhang 1314da62c5ffSQi Zhang ice_for_each_vf(pf, i) { 1315b6b0501dSPaul M Stillwell Jr struct ice_vf *vf = &pf->vf[i]; 1316b6b0501dSPaul M Stillwell Jr 1317da62c5ffSQi Zhang if (i != vsi->vf_id && vf->ctrl_vsi_idx != ICE_NO_VSI) { 1318da62c5ffSQi Zhang base = pf->vsi[vf->ctrl_vsi_idx]->base_vector; 1319da62c5ffSQi Zhang break; 1320da62c5ffSQi Zhang } 1321da62c5ffSQi Zhang } 1322da62c5ffSQi Zhang if (i == pf->num_alloc_vfs) 1323da62c5ffSQi Zhang base = ice_get_res(pf, pf->irq_tracker, num_q_vectors, 1324da62c5ffSQi Zhang ICE_RES_VF_CTRL_VEC_ID); 1325da62c5ffSQi Zhang } else { 1326da62c5ffSQi Zhang base = ice_get_res(pf, pf->irq_tracker, num_q_vectors, 1327da62c5ffSQi Zhang vsi->idx); 1328da62c5ffSQi Zhang } 132988865fc4SKarol Kolacinski 133088865fc4SKarol Kolacinski if (base < 0) { 133146c276ceSBrett Creeley dev_err(dev, "%d MSI-X interrupts available. %s %d failed to get %d MSI-X vectors\n", 133246c276ceSBrett Creeley ice_get_free_res_count(pf->irq_tracker), 133346c276ceSBrett Creeley ice_vsi_type_str(vsi->type), vsi->idx, num_q_vectors); 1334eb0208ecSPreethi Banala return -ENOENT; 1335eb0208ecSPreethi Banala } 133688865fc4SKarol Kolacinski vsi->base_vector = (u16)base; 1337eb0208ecSPreethi Banala pf->num_avail_sw_msix -= num_q_vectors; 1338eb0208ecSPreethi Banala 1339df0f8479SAnirudh Venkataramanan return 0; 1340df0f8479SAnirudh Venkataramanan } 1341df0f8479SAnirudh Venkataramanan 1342df0f8479SAnirudh Venkataramanan /** 134328c2a645SAnirudh Venkataramanan * ice_vsi_clear_rings - Deallocates the Tx and Rx rings for VSI 134428c2a645SAnirudh Venkataramanan * @vsi: the VSI having rings deallocated 134528c2a645SAnirudh Venkataramanan */ 1346df0f8479SAnirudh Venkataramanan static void ice_vsi_clear_rings(struct ice_vsi *vsi) 134728c2a645SAnirudh Venkataramanan { 134828c2a645SAnirudh Venkataramanan int i; 134928c2a645SAnirudh Venkataramanan 1350f6a07271SJacob Keller /* Avoid stale references by clearing map from vector to ring */ 1351f6a07271SJacob Keller if (vsi->q_vectors) { 1352f6a07271SJacob Keller ice_for_each_q_vector(vsi, i) { 1353f6a07271SJacob Keller struct ice_q_vector *q_vector = vsi->q_vectors[i]; 1354f6a07271SJacob Keller 1355f6a07271SJacob Keller if (q_vector) { 1356e72bba21SMaciej Fijalkowski q_vector->tx.tx_ring = NULL; 1357e72bba21SMaciej Fijalkowski q_vector->rx.rx_ring = NULL; 1358f6a07271SJacob Keller } 1359f6a07271SJacob Keller } 1360f6a07271SJacob Keller } 1361f6a07271SJacob Keller 136228c2a645SAnirudh Venkataramanan if (vsi->tx_rings) { 13632faf63b6SMaciej Fijalkowski ice_for_each_alloc_txq(vsi, i) { 136428c2a645SAnirudh Venkataramanan if (vsi->tx_rings[i]) { 136528c2a645SAnirudh Venkataramanan kfree_rcu(vsi->tx_rings[i], rcu); 1366b1d95cc2SCiara Loftus WRITE_ONCE(vsi->tx_rings[i], NULL); 136728c2a645SAnirudh Venkataramanan } 136828c2a645SAnirudh Venkataramanan } 136928c2a645SAnirudh Venkataramanan } 137028c2a645SAnirudh Venkataramanan if (vsi->rx_rings) { 13712faf63b6SMaciej Fijalkowski ice_for_each_alloc_rxq(vsi, i) { 137228c2a645SAnirudh Venkataramanan if (vsi->rx_rings[i]) { 137328c2a645SAnirudh Venkataramanan kfree_rcu(vsi->rx_rings[i], rcu); 1374b1d95cc2SCiara Loftus WRITE_ONCE(vsi->rx_rings[i], NULL); 137528c2a645SAnirudh Venkataramanan } 137628c2a645SAnirudh Venkataramanan } 137728c2a645SAnirudh Venkataramanan } 137828c2a645SAnirudh Venkataramanan } 137928c2a645SAnirudh Venkataramanan 138028c2a645SAnirudh Venkataramanan /** 138128c2a645SAnirudh Venkataramanan * ice_vsi_alloc_rings - Allocates Tx and Rx rings for the VSI 138228c2a645SAnirudh Venkataramanan * @vsi: VSI which is having rings allocated 138328c2a645SAnirudh Venkataramanan */ 138437bb8390SAnirudh Venkataramanan static int ice_vsi_alloc_rings(struct ice_vsi *vsi) 138528c2a645SAnirudh Venkataramanan { 138628c2a645SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 13874015d11eSBrett Creeley struct device *dev; 138888865fc4SKarol Kolacinski u16 i; 138928c2a645SAnirudh Venkataramanan 13904015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 1391d337f2afSAnirudh Venkataramanan /* Allocate Tx rings */ 13922faf63b6SMaciej Fijalkowski ice_for_each_alloc_txq(vsi, i) { 1393e72bba21SMaciej Fijalkowski struct ice_tx_ring *ring; 139428c2a645SAnirudh Venkataramanan 139528c2a645SAnirudh Venkataramanan /* allocate with kzalloc(), free with kfree_rcu() */ 139628c2a645SAnirudh Venkataramanan ring = kzalloc(sizeof(*ring), GFP_KERNEL); 139728c2a645SAnirudh Venkataramanan 139828c2a645SAnirudh Venkataramanan if (!ring) 139928c2a645SAnirudh Venkataramanan goto err_out; 140028c2a645SAnirudh Venkataramanan 140128c2a645SAnirudh Venkataramanan ring->q_index = i; 140228c2a645SAnirudh Venkataramanan ring->reg_idx = vsi->txq_map[i]; 140328c2a645SAnirudh Venkataramanan ring->vsi = vsi; 1404ea9b847cSJacob Keller ring->tx_tstamps = &pf->ptp.port.tx; 14054015d11eSBrett Creeley ring->dev = dev; 1406ad71b256SBrett Creeley ring->count = vsi->num_tx_desc; 1407b1d95cc2SCiara Loftus WRITE_ONCE(vsi->tx_rings[i], ring); 140828c2a645SAnirudh Venkataramanan } 140928c2a645SAnirudh Venkataramanan 1410d337f2afSAnirudh Venkataramanan /* Allocate Rx rings */ 14112faf63b6SMaciej Fijalkowski ice_for_each_alloc_rxq(vsi, i) { 1412e72bba21SMaciej Fijalkowski struct ice_rx_ring *ring; 141328c2a645SAnirudh Venkataramanan 141428c2a645SAnirudh Venkataramanan /* allocate with kzalloc(), free with kfree_rcu() */ 141528c2a645SAnirudh Venkataramanan ring = kzalloc(sizeof(*ring), GFP_KERNEL); 141628c2a645SAnirudh Venkataramanan if (!ring) 141728c2a645SAnirudh Venkataramanan goto err_out; 141828c2a645SAnirudh Venkataramanan 141928c2a645SAnirudh Venkataramanan ring->q_index = i; 142028c2a645SAnirudh Venkataramanan ring->reg_idx = vsi->rxq_map[i]; 142128c2a645SAnirudh Venkataramanan ring->vsi = vsi; 142228c2a645SAnirudh Venkataramanan ring->netdev = vsi->netdev; 14234015d11eSBrett Creeley ring->dev = dev; 1424ad71b256SBrett Creeley ring->count = vsi->num_rx_desc; 1425b1d95cc2SCiara Loftus WRITE_ONCE(vsi->rx_rings[i], ring); 142628c2a645SAnirudh Venkataramanan } 142728c2a645SAnirudh Venkataramanan 142828c2a645SAnirudh Venkataramanan return 0; 142928c2a645SAnirudh Venkataramanan 143028c2a645SAnirudh Venkataramanan err_out: 143128c2a645SAnirudh Venkataramanan ice_vsi_clear_rings(vsi); 143228c2a645SAnirudh Venkataramanan return -ENOMEM; 143328c2a645SAnirudh Venkataramanan } 143428c2a645SAnirudh Venkataramanan 143528c2a645SAnirudh Venkataramanan /** 1436492af0abSMd Fahad Iqbal Polash * ice_vsi_manage_rss_lut - disable/enable RSS 1437492af0abSMd Fahad Iqbal Polash * @vsi: the VSI being changed 1438492af0abSMd Fahad Iqbal Polash * @ena: boolean value indicating if this is an enable or disable request 1439492af0abSMd Fahad Iqbal Polash * 1440492af0abSMd Fahad Iqbal Polash * In the event of disable request for RSS, this function will zero out RSS 1441492af0abSMd Fahad Iqbal Polash * LUT, while in the event of enable request for RSS, it will reconfigure RSS 1442492af0abSMd Fahad Iqbal Polash * LUT. 1443492af0abSMd Fahad Iqbal Polash */ 14444fe36226SPaul M Stillwell Jr void ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena) 1445492af0abSMd Fahad Iqbal Polash { 1446492af0abSMd Fahad Iqbal Polash u8 *lut; 1447492af0abSMd Fahad Iqbal Polash 14489efe35d0STony Nguyen lut = kzalloc(vsi->rss_table_size, GFP_KERNEL); 1449492af0abSMd Fahad Iqbal Polash if (!lut) 14504fe36226SPaul M Stillwell Jr return; 1451492af0abSMd Fahad Iqbal Polash 1452492af0abSMd Fahad Iqbal Polash if (ena) { 1453492af0abSMd Fahad Iqbal Polash if (vsi->rss_lut_user) 1454492af0abSMd Fahad Iqbal Polash memcpy(lut, vsi->rss_lut_user, vsi->rss_table_size); 1455492af0abSMd Fahad Iqbal Polash else 1456492af0abSMd Fahad Iqbal Polash ice_fill_rss_lut(lut, vsi->rss_table_size, 1457492af0abSMd Fahad Iqbal Polash vsi->rss_size); 1458492af0abSMd Fahad Iqbal Polash } 1459492af0abSMd Fahad Iqbal Polash 14604fe36226SPaul M Stillwell Jr ice_set_rss_lut(vsi, lut, vsi->rss_table_size); 14619efe35d0STony Nguyen kfree(lut); 1462492af0abSMd Fahad Iqbal Polash } 1463492af0abSMd Fahad Iqbal Polash 1464492af0abSMd Fahad Iqbal Polash /** 146537bb8390SAnirudh Venkataramanan * ice_vsi_cfg_rss_lut_key - Configure RSS params for a VSI 146637bb8390SAnirudh Venkataramanan * @vsi: VSI to be configured 146737bb8390SAnirudh Venkataramanan */ 1468*0754d65bSKiran Patil int ice_vsi_cfg_rss_lut_key(struct ice_vsi *vsi) 146937bb8390SAnirudh Venkataramanan { 147037bb8390SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 14714015d11eSBrett Creeley struct device *dev; 1472b66a972aSBrett Creeley u8 *lut, *key; 1473b66a972aSBrett Creeley int err; 147437bb8390SAnirudh Venkataramanan 14754015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 1476*0754d65bSKiran Patil if (vsi->type == ICE_VSI_PF && vsi->ch_rss_size && 1477*0754d65bSKiran Patil (test_bit(ICE_FLAG_TC_MQPRIO, pf->flags))) { 1478*0754d65bSKiran Patil vsi->rss_size = min_t(u16, vsi->rss_size, vsi->ch_rss_size); 1479*0754d65bSKiran Patil } else { 148088865fc4SKarol Kolacinski vsi->rss_size = min_t(u16, vsi->rss_size, vsi->num_rxq); 148137bb8390SAnirudh Venkataramanan 1482*0754d65bSKiran Patil /* If orig_rss_size is valid and it is less than determined 1483*0754d65bSKiran Patil * main VSI's rss_size, update main VSI's rss_size to be 1484*0754d65bSKiran Patil * orig_rss_size so that when tc-qdisc is deleted, main VSI 1485*0754d65bSKiran Patil * RSS table gets programmed to be correct (whatever it was 1486*0754d65bSKiran Patil * to begin with (prior to setup-tc for ADQ config) 1487*0754d65bSKiran Patil */ 1488*0754d65bSKiran Patil if (vsi->orig_rss_size && vsi->rss_size < vsi->orig_rss_size && 1489*0754d65bSKiran Patil vsi->orig_rss_size <= vsi->num_rxq) { 1490*0754d65bSKiran Patil vsi->rss_size = vsi->orig_rss_size; 1491*0754d65bSKiran Patil /* now orig_rss_size is used, reset it to zero */ 1492*0754d65bSKiran Patil vsi->orig_rss_size = 0; 1493*0754d65bSKiran Patil } 1494*0754d65bSKiran Patil } 1495*0754d65bSKiran Patil 14969efe35d0STony Nguyen lut = kzalloc(vsi->rss_table_size, GFP_KERNEL); 149737bb8390SAnirudh Venkataramanan if (!lut) 149837bb8390SAnirudh Venkataramanan return -ENOMEM; 149937bb8390SAnirudh Venkataramanan 150037bb8390SAnirudh Venkataramanan if (vsi->rss_lut_user) 150137bb8390SAnirudh Venkataramanan memcpy(lut, vsi->rss_lut_user, vsi->rss_table_size); 150237bb8390SAnirudh Venkataramanan else 150337bb8390SAnirudh Venkataramanan ice_fill_rss_lut(lut, vsi->rss_table_size, vsi->rss_size); 150437bb8390SAnirudh Venkataramanan 1505b66a972aSBrett Creeley err = ice_set_rss_lut(vsi, lut, vsi->rss_table_size); 1506b66a972aSBrett Creeley if (err) { 1507b66a972aSBrett Creeley dev_err(dev, "set_rss_lut failed, error %d\n", err); 150837bb8390SAnirudh Venkataramanan goto ice_vsi_cfg_rss_exit; 150937bb8390SAnirudh Venkataramanan } 151037bb8390SAnirudh Venkataramanan 1511b66a972aSBrett Creeley key = kzalloc(ICE_GET_SET_RSS_KEY_EXTEND_KEY_SIZE, GFP_KERNEL); 151237bb8390SAnirudh Venkataramanan if (!key) { 151337bb8390SAnirudh Venkataramanan err = -ENOMEM; 151437bb8390SAnirudh Venkataramanan goto ice_vsi_cfg_rss_exit; 151537bb8390SAnirudh Venkataramanan } 151637bb8390SAnirudh Venkataramanan 151737bb8390SAnirudh Venkataramanan if (vsi->rss_hkey_user) 1518b66a972aSBrett Creeley memcpy(key, vsi->rss_hkey_user, ICE_GET_SET_RSS_KEY_EXTEND_KEY_SIZE); 151937bb8390SAnirudh Venkataramanan else 1520b66a972aSBrett Creeley netdev_rss_key_fill((void *)key, ICE_GET_SET_RSS_KEY_EXTEND_KEY_SIZE); 152137bb8390SAnirudh Venkataramanan 1522b66a972aSBrett Creeley err = ice_set_rss_key(vsi, key); 1523b66a972aSBrett Creeley if (err) 1524b66a972aSBrett Creeley dev_err(dev, "set_rss_key failed, error %d\n", err); 152537bb8390SAnirudh Venkataramanan 15269efe35d0STony Nguyen kfree(key); 152737bb8390SAnirudh Venkataramanan ice_vsi_cfg_rss_exit: 15289efe35d0STony Nguyen kfree(lut); 152937bb8390SAnirudh Venkataramanan return err; 153037bb8390SAnirudh Venkataramanan } 153137bb8390SAnirudh Venkataramanan 153237bb8390SAnirudh Venkataramanan /** 15331c01c8c6SMd Fahad Iqbal Polash * ice_vsi_set_vf_rss_flow_fld - Sets VF VSI RSS input set for different flows 15341c01c8c6SMd Fahad Iqbal Polash * @vsi: VSI to be configured 15351c01c8c6SMd Fahad Iqbal Polash * 15361c01c8c6SMd Fahad Iqbal Polash * This function will only be called during the VF VSI setup. Upon successful 15371c01c8c6SMd Fahad Iqbal Polash * completion of package download, this function will configure default RSS 15381c01c8c6SMd Fahad Iqbal Polash * input sets for VF VSI. 15391c01c8c6SMd Fahad Iqbal Polash */ 15401c01c8c6SMd Fahad Iqbal Polash static void ice_vsi_set_vf_rss_flow_fld(struct ice_vsi *vsi) 15411c01c8c6SMd Fahad Iqbal Polash { 15421c01c8c6SMd Fahad Iqbal Polash struct ice_pf *pf = vsi->back; 15431c01c8c6SMd Fahad Iqbal Polash enum ice_status status; 15441c01c8c6SMd Fahad Iqbal Polash struct device *dev; 15451c01c8c6SMd Fahad Iqbal Polash 15461c01c8c6SMd Fahad Iqbal Polash dev = ice_pf_to_dev(pf); 15471c01c8c6SMd Fahad Iqbal Polash if (ice_is_safe_mode(pf)) { 15481c01c8c6SMd Fahad Iqbal Polash dev_dbg(dev, "Advanced RSS disabled. Package download failed, vsi num = %d\n", 15491c01c8c6SMd Fahad Iqbal Polash vsi->vsi_num); 15501c01c8c6SMd Fahad Iqbal Polash return; 15511c01c8c6SMd Fahad Iqbal Polash } 15521c01c8c6SMd Fahad Iqbal Polash 15531c01c8c6SMd Fahad Iqbal Polash status = ice_add_avf_rss_cfg(&pf->hw, vsi->idx, ICE_DEFAULT_RSS_HENA); 15541c01c8c6SMd Fahad Iqbal Polash if (status) 15550fee3577SLihong Yang dev_dbg(dev, "ice_add_avf_rss_cfg failed for vsi = %d, error = %s\n", 15560fee3577SLihong Yang vsi->vsi_num, ice_stat_str(status)); 15571c01c8c6SMd Fahad Iqbal Polash } 15581c01c8c6SMd Fahad Iqbal Polash 15591c01c8c6SMd Fahad Iqbal Polash /** 1560c90ed40cSTony Nguyen * ice_vsi_set_rss_flow_fld - Sets RSS input set for different flows 1561c90ed40cSTony Nguyen * @vsi: VSI to be configured 1562c90ed40cSTony Nguyen * 1563c90ed40cSTony Nguyen * This function will only be called after successful download package call 1564c90ed40cSTony Nguyen * during initialization of PF. Since the downloaded package will erase the 1565c90ed40cSTony Nguyen * RSS section, this function will configure RSS input sets for different 1566c90ed40cSTony Nguyen * flow types. The last profile added has the highest priority, therefore 2 1567c90ed40cSTony Nguyen * tuple profiles (i.e. IPv4 src/dst) are added before 4 tuple profiles 1568c90ed40cSTony Nguyen * (i.e. IPv4 src/dst TCP src/dst port). 1569c90ed40cSTony Nguyen */ 1570c90ed40cSTony Nguyen static void ice_vsi_set_rss_flow_fld(struct ice_vsi *vsi) 1571c90ed40cSTony Nguyen { 1572c90ed40cSTony Nguyen u16 vsi_handle = vsi->idx, vsi_num = vsi->vsi_num; 1573c90ed40cSTony Nguyen struct ice_pf *pf = vsi->back; 1574c90ed40cSTony Nguyen struct ice_hw *hw = &pf->hw; 1575c90ed40cSTony Nguyen enum ice_status status; 1576c90ed40cSTony Nguyen struct device *dev; 1577c90ed40cSTony Nguyen 1578c90ed40cSTony Nguyen dev = ice_pf_to_dev(pf); 1579c90ed40cSTony Nguyen if (ice_is_safe_mode(pf)) { 1580c90ed40cSTony Nguyen dev_dbg(dev, "Advanced RSS disabled. Package download failed, vsi num = %d\n", 1581c90ed40cSTony Nguyen vsi_num); 1582c90ed40cSTony Nguyen return; 1583c90ed40cSTony Nguyen } 1584c90ed40cSTony Nguyen /* configure RSS for IPv4 with input set IP src/dst */ 1585c90ed40cSTony Nguyen status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV4, 1586c90ed40cSTony Nguyen ICE_FLOW_SEG_HDR_IPV4); 1587c90ed40cSTony Nguyen if (status) 15880fee3577SLihong Yang dev_dbg(dev, "ice_add_rss_cfg failed for ipv4 flow, vsi = %d, error = %s\n", 15890fee3577SLihong Yang vsi_num, ice_stat_str(status)); 1590c90ed40cSTony Nguyen 1591c90ed40cSTony Nguyen /* configure RSS for IPv6 with input set IPv6 src/dst */ 1592c90ed40cSTony Nguyen status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV6, 1593c90ed40cSTony Nguyen ICE_FLOW_SEG_HDR_IPV6); 1594c90ed40cSTony Nguyen if (status) 15950fee3577SLihong Yang dev_dbg(dev, "ice_add_rss_cfg failed for ipv6 flow, vsi = %d, error = %s\n", 15960fee3577SLihong Yang vsi_num, ice_stat_str(status)); 1597c90ed40cSTony Nguyen 1598c90ed40cSTony Nguyen /* configure RSS for tcp4 with input set IP src/dst, TCP src/dst */ 1599c90ed40cSTony Nguyen status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_TCP_IPV4, 1600c90ed40cSTony Nguyen ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4); 1601c90ed40cSTony Nguyen if (status) 16020fee3577SLihong Yang dev_dbg(dev, "ice_add_rss_cfg failed for tcp4 flow, vsi = %d, error = %s\n", 16030fee3577SLihong Yang vsi_num, ice_stat_str(status)); 1604c90ed40cSTony Nguyen 1605c90ed40cSTony Nguyen /* configure RSS for udp4 with input set IP src/dst, UDP src/dst */ 1606c90ed40cSTony Nguyen status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_UDP_IPV4, 1607c90ed40cSTony Nguyen ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4); 1608c90ed40cSTony Nguyen if (status) 16090fee3577SLihong Yang dev_dbg(dev, "ice_add_rss_cfg failed for udp4 flow, vsi = %d, error = %s\n", 16100fee3577SLihong Yang vsi_num, ice_stat_str(status)); 1611c90ed40cSTony Nguyen 1612c90ed40cSTony Nguyen /* configure RSS for sctp4 with input set IP src/dst */ 1613c90ed40cSTony Nguyen status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV4, 1614c90ed40cSTony Nguyen ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4); 1615c90ed40cSTony Nguyen if (status) 16160fee3577SLihong Yang dev_dbg(dev, "ice_add_rss_cfg failed for sctp4 flow, vsi = %d, error = %s\n", 16170fee3577SLihong Yang vsi_num, ice_stat_str(status)); 1618c90ed40cSTony Nguyen 1619c90ed40cSTony Nguyen /* configure RSS for tcp6 with input set IPv6 src/dst, TCP src/dst */ 1620c90ed40cSTony Nguyen status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_TCP_IPV6, 1621c90ed40cSTony Nguyen ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6); 1622c90ed40cSTony Nguyen if (status) 16230fee3577SLihong Yang dev_dbg(dev, "ice_add_rss_cfg failed for tcp6 flow, vsi = %d, error = %s\n", 16240fee3577SLihong Yang vsi_num, ice_stat_str(status)); 1625c90ed40cSTony Nguyen 1626c90ed40cSTony Nguyen /* configure RSS for udp6 with input set IPv6 src/dst, UDP src/dst */ 1627c90ed40cSTony Nguyen status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_UDP_IPV6, 1628c90ed40cSTony Nguyen ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6); 1629c90ed40cSTony Nguyen if (status) 16300fee3577SLihong Yang dev_dbg(dev, "ice_add_rss_cfg failed for udp6 flow, vsi = %d, error = %s\n", 16310fee3577SLihong Yang vsi_num, ice_stat_str(status)); 1632c90ed40cSTony Nguyen 1633c90ed40cSTony Nguyen /* configure RSS for sctp6 with input set IPv6 src/dst */ 1634c90ed40cSTony Nguyen status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV6, 1635c90ed40cSTony Nguyen ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6); 1636c90ed40cSTony Nguyen if (status) 16370fee3577SLihong Yang dev_dbg(dev, "ice_add_rss_cfg failed for sctp6 flow, vsi = %d, error = %s\n", 16380fee3577SLihong Yang vsi_num, ice_stat_str(status)); 1639c90ed40cSTony Nguyen } 1640c90ed40cSTony Nguyen 1641c90ed40cSTony Nguyen /** 1642769c500dSAkeem G Abodunrin * ice_pf_state_is_nominal - checks the PF for nominal state 1643769c500dSAkeem G Abodunrin * @pf: pointer to PF to check 1644769c500dSAkeem G Abodunrin * 1645769c500dSAkeem G Abodunrin * Check the PF's state for a collection of bits that would indicate 1646769c500dSAkeem G Abodunrin * the PF is in a state that would inhibit normal operation for 1647769c500dSAkeem G Abodunrin * driver functionality. 1648769c500dSAkeem G Abodunrin * 1649769c500dSAkeem G Abodunrin * Returns true if PF is in a nominal state, false otherwise 1650769c500dSAkeem G Abodunrin */ 1651769c500dSAkeem G Abodunrin bool ice_pf_state_is_nominal(struct ice_pf *pf) 1652769c500dSAkeem G Abodunrin { 16537e408e07SAnirudh Venkataramanan DECLARE_BITMAP(check_bits, ICE_STATE_NBITS) = { 0 }; 1654769c500dSAkeem G Abodunrin 1655769c500dSAkeem G Abodunrin if (!pf) 1656769c500dSAkeem G Abodunrin return false; 1657769c500dSAkeem G Abodunrin 16587e408e07SAnirudh Venkataramanan bitmap_set(check_bits, 0, ICE_STATE_NOMINAL_CHECK_BITS); 16597e408e07SAnirudh Venkataramanan if (bitmap_intersects(pf->state, check_bits, ICE_STATE_NBITS)) 1660769c500dSAkeem G Abodunrin return false; 1661769c500dSAkeem G Abodunrin 1662769c500dSAkeem G Abodunrin return true; 1663769c500dSAkeem G Abodunrin } 1664769c500dSAkeem G Abodunrin 1665769c500dSAkeem G Abodunrin /** 166645d3d428SAnirudh Venkataramanan * ice_update_eth_stats - Update VSI-specific ethernet statistics counters 166745d3d428SAnirudh Venkataramanan * @vsi: the VSI to be updated 166845d3d428SAnirudh Venkataramanan */ 166945d3d428SAnirudh Venkataramanan void ice_update_eth_stats(struct ice_vsi *vsi) 167045d3d428SAnirudh Venkataramanan { 167145d3d428SAnirudh Venkataramanan struct ice_eth_stats *prev_es, *cur_es; 167245d3d428SAnirudh Venkataramanan struct ice_hw *hw = &vsi->back->hw; 167345d3d428SAnirudh Venkataramanan u16 vsi_num = vsi->vsi_num; /* HW absolute index of a VSI */ 167445d3d428SAnirudh Venkataramanan 167545d3d428SAnirudh Venkataramanan prev_es = &vsi->eth_stats_prev; 167645d3d428SAnirudh Venkataramanan cur_es = &vsi->eth_stats; 167745d3d428SAnirudh Venkataramanan 167836517fd3SJacob Keller ice_stat_update40(hw, GLV_GORCL(vsi_num), vsi->stat_offsets_loaded, 167936517fd3SJacob Keller &prev_es->rx_bytes, &cur_es->rx_bytes); 168045d3d428SAnirudh Venkataramanan 168136517fd3SJacob Keller ice_stat_update40(hw, GLV_UPRCL(vsi_num), vsi->stat_offsets_loaded, 168236517fd3SJacob Keller &prev_es->rx_unicast, &cur_es->rx_unicast); 168345d3d428SAnirudh Venkataramanan 168436517fd3SJacob Keller ice_stat_update40(hw, GLV_MPRCL(vsi_num), vsi->stat_offsets_loaded, 168536517fd3SJacob Keller &prev_es->rx_multicast, &cur_es->rx_multicast); 168645d3d428SAnirudh Venkataramanan 168736517fd3SJacob Keller ice_stat_update40(hw, GLV_BPRCL(vsi_num), vsi->stat_offsets_loaded, 168836517fd3SJacob Keller &prev_es->rx_broadcast, &cur_es->rx_broadcast); 168945d3d428SAnirudh Venkataramanan 169045d3d428SAnirudh Venkataramanan ice_stat_update32(hw, GLV_RDPC(vsi_num), vsi->stat_offsets_loaded, 169145d3d428SAnirudh Venkataramanan &prev_es->rx_discards, &cur_es->rx_discards); 169245d3d428SAnirudh Venkataramanan 169336517fd3SJacob Keller ice_stat_update40(hw, GLV_GOTCL(vsi_num), vsi->stat_offsets_loaded, 169436517fd3SJacob Keller &prev_es->tx_bytes, &cur_es->tx_bytes); 169545d3d428SAnirudh Venkataramanan 169636517fd3SJacob Keller ice_stat_update40(hw, GLV_UPTCL(vsi_num), vsi->stat_offsets_loaded, 169736517fd3SJacob Keller &prev_es->tx_unicast, &cur_es->tx_unicast); 169845d3d428SAnirudh Venkataramanan 169936517fd3SJacob Keller ice_stat_update40(hw, GLV_MPTCL(vsi_num), vsi->stat_offsets_loaded, 170036517fd3SJacob Keller &prev_es->tx_multicast, &cur_es->tx_multicast); 170145d3d428SAnirudh Venkataramanan 170236517fd3SJacob Keller ice_stat_update40(hw, GLV_BPTCL(vsi_num), vsi->stat_offsets_loaded, 170336517fd3SJacob Keller &prev_es->tx_broadcast, &cur_es->tx_broadcast); 170445d3d428SAnirudh Venkataramanan 170545d3d428SAnirudh Venkataramanan ice_stat_update32(hw, GLV_TEPC(vsi_num), vsi->stat_offsets_loaded, 170645d3d428SAnirudh Venkataramanan &prev_es->tx_errors, &cur_es->tx_errors); 170745d3d428SAnirudh Venkataramanan 170845d3d428SAnirudh Venkataramanan vsi->stat_offsets_loaded = true; 170945d3d428SAnirudh Venkataramanan } 171045d3d428SAnirudh Venkataramanan 171145d3d428SAnirudh Venkataramanan /** 171245d3d428SAnirudh Venkataramanan * ice_vsi_add_vlan - Add VSI membership for given VLAN 171345d3d428SAnirudh Venkataramanan * @vsi: the VSI being configured 1714f9867df6SAnirudh Venkataramanan * @vid: VLAN ID to be added 17151b8f15b6SMichal Swiatkowski * @action: filter action to be performed on match 171645d3d428SAnirudh Venkataramanan */ 17171b8f15b6SMichal Swiatkowski int 17181b8f15b6SMichal Swiatkowski ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid, enum ice_sw_fwd_act_type action) 171945d3d428SAnirudh Venkataramanan { 172045d3d428SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 17214015d11eSBrett Creeley struct device *dev; 172245d3d428SAnirudh Venkataramanan int err = 0; 172345d3d428SAnirudh Venkataramanan 17244015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 172545d3d428SAnirudh Venkataramanan 17261b8f15b6SMichal Swiatkowski if (!ice_fltr_add_vlan(vsi, vid, action)) { 172742f3efefSBrett Creeley vsi->num_vlan++; 172842f3efefSBrett Creeley } else { 172945d3d428SAnirudh Venkataramanan err = -ENODEV; 17304015d11eSBrett Creeley dev_err(dev, "Failure Adding VLAN %d on VSI %i\n", vid, 17314015d11eSBrett Creeley vsi->vsi_num); 173245d3d428SAnirudh Venkataramanan } 173345d3d428SAnirudh Venkataramanan 173445d3d428SAnirudh Venkataramanan return err; 173545d3d428SAnirudh Venkataramanan } 173645d3d428SAnirudh Venkataramanan 173745d3d428SAnirudh Venkataramanan /** 173845d3d428SAnirudh Venkataramanan * ice_vsi_kill_vlan - Remove VSI membership for a given VLAN 173945d3d428SAnirudh Venkataramanan * @vsi: the VSI being configured 1740f9867df6SAnirudh Venkataramanan * @vid: VLAN ID to be removed 174145d3d428SAnirudh Venkataramanan * 174245d3d428SAnirudh Venkataramanan * Returns 0 on success and negative on failure 174345d3d428SAnirudh Venkataramanan */ 174445d3d428SAnirudh Venkataramanan int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid) 174545d3d428SAnirudh Venkataramanan { 174645d3d428SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 17475079b853SAkeem G Abodunrin enum ice_status status; 17484015d11eSBrett Creeley struct device *dev; 17495079b853SAkeem G Abodunrin int err = 0; 175045d3d428SAnirudh Venkataramanan 17514015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 175245d3d428SAnirudh Venkataramanan 17531b8f15b6SMichal Swiatkowski status = ice_fltr_remove_vlan(vsi, vid, ICE_FWD_TO_VSI); 175442f3efefSBrett Creeley if (!status) { 175542f3efefSBrett Creeley vsi->num_vlan--; 175642f3efefSBrett Creeley } else if (status == ICE_ERR_DOES_NOT_EXIST) { 17570fee3577SLihong Yang dev_dbg(dev, "Failed to remove VLAN %d on VSI %i, it does not exist, status: %s\n", 17580fee3577SLihong Yang vid, vsi->vsi_num, ice_stat_str(status)); 175942f3efefSBrett Creeley } else { 17600fee3577SLihong Yang dev_err(dev, "Error removing VLAN %d on vsi %i error: %s\n", 17610fee3577SLihong Yang vid, vsi->vsi_num, ice_stat_str(status)); 17625079b853SAkeem G Abodunrin err = -EIO; 176345d3d428SAnirudh Venkataramanan } 176445d3d428SAnirudh Venkataramanan 17655079b853SAkeem G Abodunrin return err; 176645d3d428SAnirudh Venkataramanan } 176745d3d428SAnirudh Venkataramanan 176845d3d428SAnirudh Venkataramanan /** 1769efc2214bSMaciej Fijalkowski * ice_vsi_cfg_frame_size - setup max frame size and Rx buffer length 1770efc2214bSMaciej Fijalkowski * @vsi: VSI 1771efc2214bSMaciej Fijalkowski */ 1772efc2214bSMaciej Fijalkowski void ice_vsi_cfg_frame_size(struct ice_vsi *vsi) 1773efc2214bSMaciej Fijalkowski { 17747237f5b0SMaciej Fijalkowski if (!vsi->netdev || test_bit(ICE_FLAG_LEGACY_RX, vsi->back->flags)) { 17757237f5b0SMaciej Fijalkowski vsi->max_frame = ICE_AQ_SET_MAC_FRAME_SIZE_MAX; 1776efc2214bSMaciej Fijalkowski vsi->rx_buf_len = ICE_RXBUF_2048; 17777237f5b0SMaciej Fijalkowski #if (PAGE_SIZE < 8192) 177859bb0808SMaciej Fijalkowski } else if (!ICE_2K_TOO_SMALL_WITH_PADDING && 177959bb0808SMaciej Fijalkowski (vsi->netdev->mtu <= ETH_DATA_LEN)) { 17807237f5b0SMaciej Fijalkowski vsi->max_frame = ICE_RXBUF_1536 - NET_IP_ALIGN; 17817237f5b0SMaciej Fijalkowski vsi->rx_buf_len = ICE_RXBUF_1536 - NET_IP_ALIGN; 17827237f5b0SMaciej Fijalkowski #endif 17837237f5b0SMaciej Fijalkowski } else { 17847237f5b0SMaciej Fijalkowski vsi->max_frame = ICE_AQ_SET_MAC_FRAME_SIZE_MAX; 17857237f5b0SMaciej Fijalkowski #if (PAGE_SIZE < 8192) 17867237f5b0SMaciej Fijalkowski vsi->rx_buf_len = ICE_RXBUF_3072; 17877237f5b0SMaciej Fijalkowski #else 17887237f5b0SMaciej Fijalkowski vsi->rx_buf_len = ICE_RXBUF_2048; 17897237f5b0SMaciej Fijalkowski #endif 17907237f5b0SMaciej Fijalkowski } 1791efc2214bSMaciej Fijalkowski } 1792efc2214bSMaciej Fijalkowski 1793efc2214bSMaciej Fijalkowski /** 1794401ce33bSBrett Creeley * ice_write_qrxflxp_cntxt - write/configure QRXFLXP_CNTXT register 1795401ce33bSBrett Creeley * @hw: HW pointer 1796401ce33bSBrett Creeley * @pf_q: index of the Rx queue in the PF's queue space 1797401ce33bSBrett Creeley * @rxdid: flexible descriptor RXDID 1798401ce33bSBrett Creeley * @prio: priority for the RXDID for this queue 179977a78115SJacob Keller * @ena_ts: true to enable timestamp and false to disable timestamp 1800401ce33bSBrett Creeley */ 1801401ce33bSBrett Creeley void 180277a78115SJacob Keller ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio, 180377a78115SJacob Keller bool ena_ts) 1804401ce33bSBrett Creeley { 1805401ce33bSBrett Creeley int regval = rd32(hw, QRXFLXP_CNTXT(pf_q)); 1806401ce33bSBrett Creeley 1807401ce33bSBrett Creeley /* clear any previous values */ 1808401ce33bSBrett Creeley regval &= ~(QRXFLXP_CNTXT_RXDID_IDX_M | 1809401ce33bSBrett Creeley QRXFLXP_CNTXT_RXDID_PRIO_M | 1810401ce33bSBrett Creeley QRXFLXP_CNTXT_TS_M); 1811401ce33bSBrett Creeley 1812401ce33bSBrett Creeley regval |= (rxdid << QRXFLXP_CNTXT_RXDID_IDX_S) & 1813401ce33bSBrett Creeley QRXFLXP_CNTXT_RXDID_IDX_M; 1814401ce33bSBrett Creeley 1815401ce33bSBrett Creeley regval |= (prio << QRXFLXP_CNTXT_RXDID_PRIO_S) & 1816401ce33bSBrett Creeley QRXFLXP_CNTXT_RXDID_PRIO_M; 1817401ce33bSBrett Creeley 181877a78115SJacob Keller if (ena_ts) 181977a78115SJacob Keller /* Enable TimeSync on this queue */ 182077a78115SJacob Keller regval |= QRXFLXP_CNTXT_TS_M; 182177a78115SJacob Keller 1822401ce33bSBrett Creeley wr32(hw, QRXFLXP_CNTXT(pf_q), regval); 1823401ce33bSBrett Creeley } 1824401ce33bSBrett Creeley 18257ad15440SBrett Creeley int ice_vsi_cfg_single_rxq(struct ice_vsi *vsi, u16 q_idx) 18267ad15440SBrett Creeley { 18277ad15440SBrett Creeley if (q_idx >= vsi->num_rxq) 18287ad15440SBrett Creeley return -EINVAL; 18297ad15440SBrett Creeley 18307ad15440SBrett Creeley return ice_vsi_cfg_rxq(vsi->rx_rings[q_idx]); 18317ad15440SBrett Creeley } 18327ad15440SBrett Creeley 1833e72bba21SMaciej Fijalkowski int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings, u16 q_idx) 18347ad15440SBrett Creeley { 18357ad15440SBrett Creeley struct ice_aqc_add_tx_qgrp *qg_buf; 18367ad15440SBrett Creeley int err; 18377ad15440SBrett Creeley 18387ad15440SBrett Creeley if (q_idx >= vsi->alloc_txq || !tx_rings || !tx_rings[q_idx]) 18397ad15440SBrett Creeley return -EINVAL; 18407ad15440SBrett Creeley 18417ad15440SBrett Creeley qg_buf = kzalloc(struct_size(qg_buf, txqs, 1), GFP_KERNEL); 18427ad15440SBrett Creeley if (!qg_buf) 18437ad15440SBrett Creeley return -ENOMEM; 18447ad15440SBrett Creeley 18457ad15440SBrett Creeley qg_buf->num_txqs = 1; 18467ad15440SBrett Creeley 18477ad15440SBrett Creeley err = ice_vsi_cfg_txq(vsi, tx_rings[q_idx], qg_buf); 18487ad15440SBrett Creeley kfree(qg_buf); 18497ad15440SBrett Creeley return err; 18507ad15440SBrett Creeley } 18517ad15440SBrett Creeley 1852401ce33bSBrett Creeley /** 185372adf242SAnirudh Venkataramanan * ice_vsi_cfg_rxqs - Configure the VSI for Rx 185472adf242SAnirudh Venkataramanan * @vsi: the VSI being configured 185572adf242SAnirudh Venkataramanan * 185672adf242SAnirudh Venkataramanan * Return 0 on success and a negative value on error 185772adf242SAnirudh Venkataramanan * Configure the Rx VSI for operation. 185872adf242SAnirudh Venkataramanan */ 185972adf242SAnirudh Venkataramanan int ice_vsi_cfg_rxqs(struct ice_vsi *vsi) 186072adf242SAnirudh Venkataramanan { 186172adf242SAnirudh Venkataramanan u16 i; 186272adf242SAnirudh Venkataramanan 18638ede0178SAnirudh Venkataramanan if (vsi->type == ICE_VSI_VF) 18648ede0178SAnirudh Venkataramanan goto setup_rings; 18658ede0178SAnirudh Venkataramanan 1866efc2214bSMaciej Fijalkowski ice_vsi_cfg_frame_size(vsi); 18678ede0178SAnirudh Venkataramanan setup_rings: 186872adf242SAnirudh Venkataramanan /* set up individual rings */ 186943c7f919SKrzysztof Kazimierczak ice_for_each_rxq(vsi, i) { 187043c7f919SKrzysztof Kazimierczak int err = ice_vsi_cfg_rxq(vsi->rx_rings[i]); 187172adf242SAnirudh Venkataramanan 187243c7f919SKrzysztof Kazimierczak if (err) 187372adf242SAnirudh Venkataramanan return err; 187472adf242SAnirudh Venkataramanan } 18751553f4f7SBrett Creeley 18761553f4f7SBrett Creeley return 0; 18771553f4f7SBrett Creeley } 187872adf242SAnirudh Venkataramanan 187972adf242SAnirudh Venkataramanan /** 188072adf242SAnirudh Venkataramanan * ice_vsi_cfg_txqs - Configure the VSI for Tx 188172adf242SAnirudh Venkataramanan * @vsi: the VSI being configured 188203f7a986SAnirudh Venkataramanan * @rings: Tx ring array to be configured 18832e84f6b3SMaciej Fijalkowski * @count: number of Tx ring array elements 188472adf242SAnirudh Venkataramanan * 188572adf242SAnirudh Venkataramanan * Return 0 on success and a negative value on error 188672adf242SAnirudh Venkataramanan * Configure the Tx VSI for operation. 188772adf242SAnirudh Venkataramanan */ 188803f7a986SAnirudh Venkataramanan static int 1889e72bba21SMaciej Fijalkowski ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_tx_ring **rings, u16 count) 189072adf242SAnirudh Venkataramanan { 189172adf242SAnirudh Venkataramanan struct ice_aqc_add_tx_qgrp *qg_buf; 1892e75d1b2cSMaciej Fijalkowski u16 q_idx = 0; 1893d02f734cSMaciej Fijalkowski int err = 0; 189472adf242SAnirudh Venkataramanan 189566486d89SBruce Allan qg_buf = kzalloc(struct_size(qg_buf, txqs, 1), GFP_KERNEL); 189672adf242SAnirudh Venkataramanan if (!qg_buf) 189772adf242SAnirudh Venkataramanan return -ENOMEM; 189872adf242SAnirudh Venkataramanan 189972adf242SAnirudh Venkataramanan qg_buf->num_txqs = 1; 190072adf242SAnirudh Venkataramanan 19012e84f6b3SMaciej Fijalkowski for (q_idx = 0; q_idx < count; q_idx++) { 1902e75d1b2cSMaciej Fijalkowski err = ice_vsi_cfg_txq(vsi, rings[q_idx], qg_buf); 1903d02f734cSMaciej Fijalkowski if (err) 190472adf242SAnirudh Venkataramanan goto err_cfg_txqs; 1905e75d1b2cSMaciej Fijalkowski } 1906c5a2a4a3SUsha Ketineni 190772adf242SAnirudh Venkataramanan err_cfg_txqs: 1908e75d1b2cSMaciej Fijalkowski kfree(qg_buf); 190972adf242SAnirudh Venkataramanan return err; 191072adf242SAnirudh Venkataramanan } 191172adf242SAnirudh Venkataramanan 191272adf242SAnirudh Venkataramanan /** 191303f7a986SAnirudh Venkataramanan * ice_vsi_cfg_lan_txqs - Configure the VSI for Tx 191403f7a986SAnirudh Venkataramanan * @vsi: the VSI being configured 191503f7a986SAnirudh Venkataramanan * 191603f7a986SAnirudh Venkataramanan * Return 0 on success and a negative value on error 191703f7a986SAnirudh Venkataramanan * Configure the Tx VSI for operation. 191803f7a986SAnirudh Venkataramanan */ 191903f7a986SAnirudh Venkataramanan int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi) 192003f7a986SAnirudh Venkataramanan { 19212e84f6b3SMaciej Fijalkowski return ice_vsi_cfg_txqs(vsi, vsi->tx_rings, vsi->num_txq); 192203f7a986SAnirudh Venkataramanan } 192303f7a986SAnirudh Venkataramanan 192403f7a986SAnirudh Venkataramanan /** 1925efc2214bSMaciej Fijalkowski * ice_vsi_cfg_xdp_txqs - Configure Tx queues dedicated for XDP in given VSI 1926efc2214bSMaciej Fijalkowski * @vsi: the VSI being configured 1927efc2214bSMaciej Fijalkowski * 1928efc2214bSMaciej Fijalkowski * Return 0 on success and a negative value on error 1929efc2214bSMaciej Fijalkowski * Configure the Tx queues dedicated for XDP in given VSI for operation. 1930efc2214bSMaciej Fijalkowski */ 1931efc2214bSMaciej Fijalkowski int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi) 1932efc2214bSMaciej Fijalkowski { 19332d4238f5SKrzysztof Kazimierczak int ret; 19342d4238f5SKrzysztof Kazimierczak int i; 19352d4238f5SKrzysztof Kazimierczak 19362e84f6b3SMaciej Fijalkowski ret = ice_vsi_cfg_txqs(vsi, vsi->xdp_rings, vsi->num_xdp_txq); 19372d4238f5SKrzysztof Kazimierczak if (ret) 19382d4238f5SKrzysztof Kazimierczak return ret; 19392d4238f5SKrzysztof Kazimierczak 19402faf63b6SMaciej Fijalkowski ice_for_each_xdp_txq(vsi, i) 1941e72bba21SMaciej Fijalkowski vsi->xdp_rings[i]->xsk_pool = ice_tx_xsk_pool(vsi->xdp_rings[i]); 19422d4238f5SKrzysztof Kazimierczak 19432d4238f5SKrzysztof Kazimierczak return ret; 1944efc2214bSMaciej Fijalkowski } 1945efc2214bSMaciej Fijalkowski 1946efc2214bSMaciej Fijalkowski /** 19479e4ab4c2SBrett Creeley * ice_intrl_usec_to_reg - convert interrupt rate limit to register value 19489e4ab4c2SBrett Creeley * @intrl: interrupt rate limit in usecs 19499e4ab4c2SBrett Creeley * @gran: interrupt rate limit granularity in usecs 19509e4ab4c2SBrett Creeley * 19519e4ab4c2SBrett Creeley * This function converts a decimal interrupt rate limit in usecs to the format 19529e4ab4c2SBrett Creeley * expected by firmware. 19539e4ab4c2SBrett Creeley */ 1954b8b47723SJesse Brandeburg static u32 ice_intrl_usec_to_reg(u8 intrl, u8 gran) 19559e4ab4c2SBrett Creeley { 19569e4ab4c2SBrett Creeley u32 val = intrl / gran; 19579e4ab4c2SBrett Creeley 19589e4ab4c2SBrett Creeley if (val) 19599e4ab4c2SBrett Creeley return val | GLINT_RATE_INTRL_ENA_M; 19609e4ab4c2SBrett Creeley return 0; 19619e4ab4c2SBrett Creeley } 19629e4ab4c2SBrett Creeley 19639e4ab4c2SBrett Creeley /** 1964b8b47723SJesse Brandeburg * ice_write_intrl - write throttle rate limit to interrupt specific register 1965b8b47723SJesse Brandeburg * @q_vector: pointer to interrupt specific structure 1966b8b47723SJesse Brandeburg * @intrl: throttle rate limit in microseconds to write 1967b8b47723SJesse Brandeburg */ 1968b8b47723SJesse Brandeburg void ice_write_intrl(struct ice_q_vector *q_vector, u8 intrl) 1969b8b47723SJesse Brandeburg { 1970b8b47723SJesse Brandeburg struct ice_hw *hw = &q_vector->vsi->back->hw; 1971b8b47723SJesse Brandeburg 1972b8b47723SJesse Brandeburg wr32(hw, GLINT_RATE(q_vector->reg_idx), 1973b8b47723SJesse Brandeburg ice_intrl_usec_to_reg(intrl, ICE_INTRL_GRAN_ABOVE_25)); 1974b8b47723SJesse Brandeburg } 1975b8b47723SJesse Brandeburg 1976e72bba21SMaciej Fijalkowski static struct ice_q_vector *ice_pull_qvec_from_rc(struct ice_ring_container *rc) 1977e72bba21SMaciej Fijalkowski { 1978e72bba21SMaciej Fijalkowski switch (rc->type) { 1979e72bba21SMaciej Fijalkowski case ICE_RX_CONTAINER: 1980e72bba21SMaciej Fijalkowski if (rc->rx_ring) 1981e72bba21SMaciej Fijalkowski return rc->rx_ring->q_vector; 1982e72bba21SMaciej Fijalkowski break; 1983e72bba21SMaciej Fijalkowski case ICE_TX_CONTAINER: 1984e72bba21SMaciej Fijalkowski if (rc->tx_ring) 1985e72bba21SMaciej Fijalkowski return rc->tx_ring->q_vector; 1986e72bba21SMaciej Fijalkowski default: 1987e72bba21SMaciej Fijalkowski break; 1988e72bba21SMaciej Fijalkowski } 1989e72bba21SMaciej Fijalkowski 1990e72bba21SMaciej Fijalkowski return NULL; 1991e72bba21SMaciej Fijalkowski } 1992e72bba21SMaciej Fijalkowski 1993b8b47723SJesse Brandeburg /** 1994b8b47723SJesse Brandeburg * __ice_write_itr - write throttle rate to register 1995b8b47723SJesse Brandeburg * @q_vector: pointer to interrupt data structure 1996b8b47723SJesse Brandeburg * @rc: pointer to ring container 1997b8b47723SJesse Brandeburg * @itr: throttle rate in microseconds to write 1998b8b47723SJesse Brandeburg */ 1999b8b47723SJesse Brandeburg static void __ice_write_itr(struct ice_q_vector *q_vector, 2000b8b47723SJesse Brandeburg struct ice_ring_container *rc, u16 itr) 2001b8b47723SJesse Brandeburg { 2002b8b47723SJesse Brandeburg struct ice_hw *hw = &q_vector->vsi->back->hw; 2003b8b47723SJesse Brandeburg 2004b8b47723SJesse Brandeburg wr32(hw, GLINT_ITR(rc->itr_idx, q_vector->reg_idx), 2005b8b47723SJesse Brandeburg ITR_REG_ALIGN(itr) >> ICE_ITR_GRAN_S); 2006b8b47723SJesse Brandeburg } 2007b8b47723SJesse Brandeburg 2008b8b47723SJesse Brandeburg /** 2009b8b47723SJesse Brandeburg * ice_write_itr - write throttle rate to queue specific register 2010b8b47723SJesse Brandeburg * @rc: pointer to ring container 2011b8b47723SJesse Brandeburg * @itr: throttle rate in microseconds to write 2012b8b47723SJesse Brandeburg */ 2013b8b47723SJesse Brandeburg void ice_write_itr(struct ice_ring_container *rc, u16 itr) 2014b8b47723SJesse Brandeburg { 2015b8b47723SJesse Brandeburg struct ice_q_vector *q_vector; 2016b8b47723SJesse Brandeburg 2017e72bba21SMaciej Fijalkowski q_vector = ice_pull_qvec_from_rc(rc); 2018e72bba21SMaciej Fijalkowski if (!q_vector) 2019b8b47723SJesse Brandeburg return; 2020b8b47723SJesse Brandeburg 2021b8b47723SJesse Brandeburg __ice_write_itr(q_vector, rc, itr); 2022b8b47723SJesse Brandeburg } 2023b8b47723SJesse Brandeburg 2024b8b47723SJesse Brandeburg /** 2025d8eb7ad5SJesse Brandeburg * ice_set_q_vector_intrl - set up interrupt rate limiting 2026d8eb7ad5SJesse Brandeburg * @q_vector: the vector to be configured 2027d8eb7ad5SJesse Brandeburg * 2028d8eb7ad5SJesse Brandeburg * Interrupt rate limiting is local to the vector, not per-queue so we must 2029d8eb7ad5SJesse Brandeburg * detect if either ring container has dynamic moderation enabled to decide 2030d8eb7ad5SJesse Brandeburg * what to set the interrupt rate limit to via INTRL settings. In the case that 2031d8eb7ad5SJesse Brandeburg * dynamic moderation is disabled on both, write the value with the cached 2032d8eb7ad5SJesse Brandeburg * setting to make sure INTRL register matches the user visible value. 2033d8eb7ad5SJesse Brandeburg */ 2034d8eb7ad5SJesse Brandeburg void ice_set_q_vector_intrl(struct ice_q_vector *q_vector) 2035d8eb7ad5SJesse Brandeburg { 2036d8eb7ad5SJesse Brandeburg if (ITR_IS_DYNAMIC(&q_vector->tx) || ITR_IS_DYNAMIC(&q_vector->rx)) { 2037d8eb7ad5SJesse Brandeburg /* in the case of dynamic enabled, cap each vector to no more 2038d8eb7ad5SJesse Brandeburg * than (4 us) 250,000 ints/sec, which allows low latency 2039d8eb7ad5SJesse Brandeburg * but still less than 500,000 interrupts per second, which 2040d8eb7ad5SJesse Brandeburg * reduces CPU a bit in the case of the lowest latency 2041d8eb7ad5SJesse Brandeburg * setting. The 4 here is a value in microseconds. 2042d8eb7ad5SJesse Brandeburg */ 2043d8eb7ad5SJesse Brandeburg ice_write_intrl(q_vector, 4); 2044d8eb7ad5SJesse Brandeburg } else { 2045d8eb7ad5SJesse Brandeburg ice_write_intrl(q_vector, q_vector->intrl); 2046d8eb7ad5SJesse Brandeburg } 2047d8eb7ad5SJesse Brandeburg } 2048d8eb7ad5SJesse Brandeburg 2049d8eb7ad5SJesse Brandeburg /** 205072adf242SAnirudh Venkataramanan * ice_vsi_cfg_msix - MSIX mode Interrupt Config in the HW 205172adf242SAnirudh Venkataramanan * @vsi: the VSI being configured 2052047e52c0SAnirudh Venkataramanan * 2053047e52c0SAnirudh Venkataramanan * This configures MSIX mode interrupts for the PF VSI, and should not be used 2054047e52c0SAnirudh Venkataramanan * for the VF VSI. 205572adf242SAnirudh Venkataramanan */ 205672adf242SAnirudh Venkataramanan void ice_vsi_cfg_msix(struct ice_vsi *vsi) 205772adf242SAnirudh Venkataramanan { 205872adf242SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 205972adf242SAnirudh Venkataramanan struct ice_hw *hw = &pf->hw; 206088865fc4SKarol Kolacinski u16 txq = 0, rxq = 0; 2061d2b464a7SBrett Creeley int i, q; 206272adf242SAnirudh Venkataramanan 20632faf63b6SMaciej Fijalkowski ice_for_each_q_vector(vsi, i) { 206472adf242SAnirudh Venkataramanan struct ice_q_vector *q_vector = vsi->q_vectors[i]; 2065b07833a0SBrett Creeley u16 reg_idx = q_vector->reg_idx; 206672adf242SAnirudh Venkataramanan 2067b07833a0SBrett Creeley ice_cfg_itr(hw, q_vector); 20689e4ab4c2SBrett Creeley 206972adf242SAnirudh Venkataramanan /* Both Transmit Queue Interrupt Cause Control register 207072adf242SAnirudh Venkataramanan * and Receive Queue Interrupt Cause control register 207172adf242SAnirudh Venkataramanan * expects MSIX_INDX field to be the vector index 207272adf242SAnirudh Venkataramanan * within the function space and not the absolute 207372adf242SAnirudh Venkataramanan * vector index across PF or across device. 207472adf242SAnirudh Venkataramanan * For SR-IOV VF VSIs queue vector index always starts 207572adf242SAnirudh Venkataramanan * with 1 since first vector index(0) is used for OICR 207672adf242SAnirudh Venkataramanan * in VF space. Since VMDq and other PF VSIs are within 207772adf242SAnirudh Venkataramanan * the PF function space, use the vector index that is 207872adf242SAnirudh Venkataramanan * tracked for this PF. 207972adf242SAnirudh Venkataramanan */ 208072adf242SAnirudh Venkataramanan for (q = 0; q < q_vector->num_ring_tx; q++) { 2081047e52c0SAnirudh Venkataramanan ice_cfg_txq_interrupt(vsi, txq, reg_idx, 2082047e52c0SAnirudh Venkataramanan q_vector->tx.itr_idx); 208372adf242SAnirudh Venkataramanan txq++; 208472adf242SAnirudh Venkataramanan } 208572adf242SAnirudh Venkataramanan 208672adf242SAnirudh Venkataramanan for (q = 0; q < q_vector->num_ring_rx; q++) { 2087047e52c0SAnirudh Venkataramanan ice_cfg_rxq_interrupt(vsi, rxq, reg_idx, 2088047e52c0SAnirudh Venkataramanan q_vector->rx.itr_idx); 208972adf242SAnirudh Venkataramanan rxq++; 209072adf242SAnirudh Venkataramanan } 209172adf242SAnirudh Venkataramanan } 209272adf242SAnirudh Venkataramanan } 209372adf242SAnirudh Venkataramanan 209472adf242SAnirudh Venkataramanan /** 209545d3d428SAnirudh Venkataramanan * ice_vsi_manage_vlan_insertion - Manage VLAN insertion for the VSI for Tx 209645d3d428SAnirudh Venkataramanan * @vsi: the VSI being changed 209745d3d428SAnirudh Venkataramanan */ 209845d3d428SAnirudh Venkataramanan int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi) 209945d3d428SAnirudh Venkataramanan { 210045d3d428SAnirudh Venkataramanan struct ice_hw *hw = &vsi->back->hw; 2101198a666aSBruce Allan struct ice_vsi_ctx *ctxt; 210245d3d428SAnirudh Venkataramanan enum ice_status status; 2103198a666aSBruce Allan int ret = 0; 2104198a666aSBruce Allan 21059efe35d0STony Nguyen ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); 2106198a666aSBruce Allan if (!ctxt) 2107198a666aSBruce Allan return -ENOMEM; 210845d3d428SAnirudh Venkataramanan 210945d3d428SAnirudh Venkataramanan /* Here we are configuring the VSI to let the driver add VLAN tags by 211045d3d428SAnirudh Venkataramanan * setting vlan_flags to ICE_AQ_VSI_VLAN_MODE_ALL. The actual VLAN tag 211145d3d428SAnirudh Venkataramanan * insertion happens in the Tx hot path, in ice_tx_map. 211245d3d428SAnirudh Venkataramanan */ 2113198a666aSBruce Allan ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL; 211445d3d428SAnirudh Venkataramanan 2115e80e76dbSTony Nguyen /* Preserve existing VLAN strip setting */ 2116e80e76dbSTony Nguyen ctxt->info.vlan_flags |= (vsi->info.vlan_flags & 2117e80e76dbSTony Nguyen ICE_AQ_VSI_VLAN_EMOD_M); 2118e80e76dbSTony Nguyen 2119198a666aSBruce Allan ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID); 212045d3d428SAnirudh Venkataramanan 2121198a666aSBruce Allan status = ice_update_vsi(hw, vsi->idx, ctxt, NULL); 212245d3d428SAnirudh Venkataramanan if (status) { 21230fee3577SLihong Yang dev_err(ice_pf_to_dev(vsi->back), "update VSI for VLAN insert failed, err %s aq_err %s\n", 21240fee3577SLihong Yang ice_stat_str(status), 21250fee3577SLihong Yang ice_aq_str(hw->adminq.sq_last_status)); 2126198a666aSBruce Allan ret = -EIO; 2127198a666aSBruce Allan goto out; 212845d3d428SAnirudh Venkataramanan } 212945d3d428SAnirudh Venkataramanan 2130198a666aSBruce Allan vsi->info.vlan_flags = ctxt->info.vlan_flags; 2131198a666aSBruce Allan out: 21329efe35d0STony Nguyen kfree(ctxt); 2133198a666aSBruce Allan return ret; 213445d3d428SAnirudh Venkataramanan } 213545d3d428SAnirudh Venkataramanan 213645d3d428SAnirudh Venkataramanan /** 213745d3d428SAnirudh Venkataramanan * ice_vsi_manage_vlan_stripping - Manage VLAN stripping for the VSI for Rx 213845d3d428SAnirudh Venkataramanan * @vsi: the VSI being changed 213945d3d428SAnirudh Venkataramanan * @ena: boolean value indicating if this is a enable or disable request 214045d3d428SAnirudh Venkataramanan */ 214145d3d428SAnirudh Venkataramanan int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena) 214245d3d428SAnirudh Venkataramanan { 214345d3d428SAnirudh Venkataramanan struct ice_hw *hw = &vsi->back->hw; 2144198a666aSBruce Allan struct ice_vsi_ctx *ctxt; 214545d3d428SAnirudh Venkataramanan enum ice_status status; 2146198a666aSBruce Allan int ret = 0; 2147198a666aSBruce Allan 214819608275SBrett Creeley /* do not allow modifying VLAN stripping when a port VLAN is configured 214919608275SBrett Creeley * on this VSI 215019608275SBrett Creeley */ 215119608275SBrett Creeley if (vsi->info.pvid) 215219608275SBrett Creeley return 0; 215319608275SBrett Creeley 21549efe35d0STony Nguyen ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); 2155198a666aSBruce Allan if (!ctxt) 2156198a666aSBruce Allan return -ENOMEM; 215745d3d428SAnirudh Venkataramanan 215845d3d428SAnirudh Venkataramanan /* Here we are configuring what the VSI should do with the VLAN tag in 215945d3d428SAnirudh Venkataramanan * the Rx packet. We can either leave the tag in the packet or put it in 216045d3d428SAnirudh Venkataramanan * the Rx descriptor. 216145d3d428SAnirudh Venkataramanan */ 2162198a666aSBruce Allan if (ena) 216345d3d428SAnirudh Venkataramanan /* Strip VLAN tag from Rx packet and put it in the desc */ 2164198a666aSBruce Allan ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH; 2165198a666aSBruce Allan else 216645d3d428SAnirudh Venkataramanan /* Disable stripping. Leave tag in packet */ 2167198a666aSBruce Allan ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING; 216845d3d428SAnirudh Venkataramanan 216945d3d428SAnirudh Venkataramanan /* Allow all packets untagged/tagged */ 2170198a666aSBruce Allan ctxt->info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL; 217145d3d428SAnirudh Venkataramanan 2172198a666aSBruce Allan ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID); 217345d3d428SAnirudh Venkataramanan 2174198a666aSBruce Allan status = ice_update_vsi(hw, vsi->idx, ctxt, NULL); 217545d3d428SAnirudh Venkataramanan if (status) { 21760fee3577SLihong Yang dev_err(ice_pf_to_dev(vsi->back), "update VSI for VLAN strip failed, ena = %d err %s aq_err %s\n", 21770fee3577SLihong Yang ena, ice_stat_str(status), 21780fee3577SLihong Yang ice_aq_str(hw->adminq.sq_last_status)); 2179198a666aSBruce Allan ret = -EIO; 2180198a666aSBruce Allan goto out; 218145d3d428SAnirudh Venkataramanan } 218245d3d428SAnirudh Venkataramanan 2183198a666aSBruce Allan vsi->info.vlan_flags = ctxt->info.vlan_flags; 2184198a666aSBruce Allan out: 21859efe35d0STony Nguyen kfree(ctxt); 2186198a666aSBruce Allan return ret; 218745d3d428SAnirudh Venkataramanan } 218872adf242SAnirudh Venkataramanan 218972adf242SAnirudh Venkataramanan /** 219013a6233bSBrett Creeley * ice_vsi_start_all_rx_rings - start/enable all of a VSI's Rx rings 219113a6233bSBrett Creeley * @vsi: the VSI whose rings are to be enabled 219272adf242SAnirudh Venkataramanan * 219372adf242SAnirudh Venkataramanan * Returns 0 on success and a negative value on error 219472adf242SAnirudh Venkataramanan */ 219513a6233bSBrett Creeley int ice_vsi_start_all_rx_rings(struct ice_vsi *vsi) 219672adf242SAnirudh Venkataramanan { 219713a6233bSBrett Creeley return ice_vsi_ctrl_all_rx_rings(vsi, true); 219872adf242SAnirudh Venkataramanan } 219972adf242SAnirudh Venkataramanan 220072adf242SAnirudh Venkataramanan /** 220113a6233bSBrett Creeley * ice_vsi_stop_all_rx_rings - stop/disable all of a VSI's Rx rings 220213a6233bSBrett Creeley * @vsi: the VSI whose rings are to be disabled 220372adf242SAnirudh Venkataramanan * 220472adf242SAnirudh Venkataramanan * Returns 0 on success and a negative value on error 220572adf242SAnirudh Venkataramanan */ 220613a6233bSBrett Creeley int ice_vsi_stop_all_rx_rings(struct ice_vsi *vsi) 220772adf242SAnirudh Venkataramanan { 220813a6233bSBrett Creeley return ice_vsi_ctrl_all_rx_rings(vsi, false); 220972adf242SAnirudh Venkataramanan } 221072adf242SAnirudh Venkataramanan 221172adf242SAnirudh Venkataramanan /** 2212d02f734cSMaciej Fijalkowski * ice_vsi_stop_tx_rings - Disable Tx rings 2213d02f734cSMaciej Fijalkowski * @vsi: the VSI being configured 2214d02f734cSMaciej Fijalkowski * @rst_src: reset source 2215d02f734cSMaciej Fijalkowski * @rel_vmvf_num: Relative ID of VF/VM 2216d02f734cSMaciej Fijalkowski * @rings: Tx ring array to be stopped 22172e84f6b3SMaciej Fijalkowski * @count: number of Tx ring array elements 2218d02f734cSMaciej Fijalkowski */ 2219d02f734cSMaciej Fijalkowski static int 2220d02f734cSMaciej Fijalkowski ice_vsi_stop_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, 2221e72bba21SMaciej Fijalkowski u16 rel_vmvf_num, struct ice_tx_ring **rings, u16 count) 2222d02f734cSMaciej Fijalkowski { 2223e75d1b2cSMaciej Fijalkowski u16 q_idx; 2224d02f734cSMaciej Fijalkowski 2225d02f734cSMaciej Fijalkowski if (vsi->num_txq > ICE_LAN_TXQ_MAX_QDIS) 2226d02f734cSMaciej Fijalkowski return -EINVAL; 2227d02f734cSMaciej Fijalkowski 22282e84f6b3SMaciej Fijalkowski for (q_idx = 0; q_idx < count; q_idx++) { 2229d02f734cSMaciej Fijalkowski struct ice_txq_meta txq_meta = { }; 2230e75d1b2cSMaciej Fijalkowski int status; 2231d02f734cSMaciej Fijalkowski 2232d02f734cSMaciej Fijalkowski if (!rings || !rings[q_idx]) 2233d02f734cSMaciej Fijalkowski return -EINVAL; 2234d02f734cSMaciej Fijalkowski 2235d02f734cSMaciej Fijalkowski ice_fill_txq_meta(vsi, rings[q_idx], &txq_meta); 2236e75d1b2cSMaciej Fijalkowski status = ice_vsi_stop_tx_ring(vsi, rst_src, rel_vmvf_num, 2237d02f734cSMaciej Fijalkowski rings[q_idx], &txq_meta); 2238d02f734cSMaciej Fijalkowski 2239d02f734cSMaciej Fijalkowski if (status) 2240d02f734cSMaciej Fijalkowski return status; 2241bb87ee0eSAnirudh Venkataramanan } 224272adf242SAnirudh Venkataramanan 2243d02f734cSMaciej Fijalkowski return 0; 224472adf242SAnirudh Venkataramanan } 22455153a18eSAnirudh Venkataramanan 22465153a18eSAnirudh Venkataramanan /** 224703f7a986SAnirudh Venkataramanan * ice_vsi_stop_lan_tx_rings - Disable LAN Tx rings 224803f7a986SAnirudh Venkataramanan * @vsi: the VSI being configured 224903f7a986SAnirudh Venkataramanan * @rst_src: reset source 2250f9867df6SAnirudh Venkataramanan * @rel_vmvf_num: Relative ID of VF/VM 225103f7a986SAnirudh Venkataramanan */ 2252c8b7abddSBruce Allan int 2253c8b7abddSBruce Allan ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, 2254c8b7abddSBruce Allan u16 rel_vmvf_num) 225503f7a986SAnirudh Venkataramanan { 22562e84f6b3SMaciej Fijalkowski return ice_vsi_stop_tx_rings(vsi, rst_src, rel_vmvf_num, vsi->tx_rings, vsi->num_txq); 225703f7a986SAnirudh Venkataramanan } 225803f7a986SAnirudh Venkataramanan 225903f7a986SAnirudh Venkataramanan /** 2260efc2214bSMaciej Fijalkowski * ice_vsi_stop_xdp_tx_rings - Disable XDP Tx rings 2261efc2214bSMaciej Fijalkowski * @vsi: the VSI being configured 2262efc2214bSMaciej Fijalkowski */ 2263efc2214bSMaciej Fijalkowski int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi) 2264efc2214bSMaciej Fijalkowski { 22652e84f6b3SMaciej Fijalkowski return ice_vsi_stop_tx_rings(vsi, ICE_NO_RESET, 0, vsi->xdp_rings, vsi->num_xdp_txq); 2266efc2214bSMaciej Fijalkowski } 2267efc2214bSMaciej Fijalkowski 2268efc2214bSMaciej Fijalkowski /** 226942f3efefSBrett Creeley * ice_vsi_is_vlan_pruning_ena - check if VLAN pruning is enabled or not 227042f3efefSBrett Creeley * @vsi: VSI to check whether or not VLAN pruning is enabled. 227142f3efefSBrett Creeley * 2272345be791SBrett Creeley * returns true if Rx VLAN pruning is enabled and false otherwise. 227342f3efefSBrett Creeley */ 227442f3efefSBrett Creeley bool ice_vsi_is_vlan_pruning_ena(struct ice_vsi *vsi) 227542f3efefSBrett Creeley { 227642f3efefSBrett Creeley if (!vsi) 227742f3efefSBrett Creeley return false; 227842f3efefSBrett Creeley 2279345be791SBrett Creeley return (vsi->info.sw_flags2 & ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA); 228042f3efefSBrett Creeley } 228142f3efefSBrett Creeley 228242f3efefSBrett Creeley /** 22835153a18eSAnirudh Venkataramanan * ice_cfg_vlan_pruning - enable or disable VLAN pruning on the VSI 22845153a18eSAnirudh Venkataramanan * @vsi: VSI to enable or disable VLAN pruning on 22855153a18eSAnirudh Venkataramanan * @ena: set to true to enable VLAN pruning and false to disable it 22865eda8afdSAkeem G Abodunrin * @vlan_promisc: enable valid security flags if not in VLAN promiscuous mode 22875153a18eSAnirudh Venkataramanan * 22885153a18eSAnirudh Venkataramanan * returns 0 if VSI is updated, negative otherwise 22895153a18eSAnirudh Venkataramanan */ 22905eda8afdSAkeem G Abodunrin int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc) 22915153a18eSAnirudh Venkataramanan { 22925153a18eSAnirudh Venkataramanan struct ice_vsi_ctx *ctxt; 2293819d8998SJesse Brandeburg struct ice_pf *pf; 22945153a18eSAnirudh Venkataramanan int status; 22955153a18eSAnirudh Venkataramanan 22965153a18eSAnirudh Venkataramanan if (!vsi) 22975153a18eSAnirudh Venkataramanan return -EINVAL; 22985153a18eSAnirudh Venkataramanan 229968d210a6SNick Nunley /* Don't enable VLAN pruning if the netdev is currently in promiscuous 230068d210a6SNick Nunley * mode. VLAN pruning will be enabled when the interface exits 230168d210a6SNick Nunley * promiscuous mode if any VLAN filters are active. 230268d210a6SNick Nunley */ 230368d210a6SNick Nunley if (vsi->netdev && vsi->netdev->flags & IFF_PROMISC && ena) 230468d210a6SNick Nunley return 0; 230568d210a6SNick Nunley 2306819d8998SJesse Brandeburg pf = vsi->back; 23079efe35d0STony Nguyen ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); 23085153a18eSAnirudh Venkataramanan if (!ctxt) 23095153a18eSAnirudh Venkataramanan return -ENOMEM; 23105153a18eSAnirudh Venkataramanan 23115153a18eSAnirudh Venkataramanan ctxt->info = vsi->info; 23125153a18eSAnirudh Venkataramanan 2313cd6d6b83SBrett Creeley if (ena) 23145153a18eSAnirudh Venkataramanan ctxt->info.sw_flags2 |= ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA; 2315cd6d6b83SBrett Creeley else 23165153a18eSAnirudh Venkataramanan ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA; 23175153a18eSAnirudh Venkataramanan 23185eda8afdSAkeem G Abodunrin if (!vlan_promisc) 23195eda8afdSAkeem G Abodunrin ctxt->info.valid_sections = 2320cd6d6b83SBrett Creeley cpu_to_le16(ICE_AQ_VSI_PROP_SW_VALID); 23215726ca0eSAnirudh Venkataramanan 2322819d8998SJesse Brandeburg status = ice_update_vsi(&pf->hw, vsi->idx, ctxt, NULL); 23235153a18eSAnirudh Venkataramanan if (status) { 23240fee3577SLihong Yang netdev_err(vsi->netdev, "%sabling VLAN pruning on VSI handle: %d, VSI HW ID: %d failed, err = %s, aq_err = %s\n", 23250fee3577SLihong Yang ena ? "En" : "Dis", vsi->idx, vsi->vsi_num, 23260fee3577SLihong Yang ice_stat_str(status), 23270fee3577SLihong Yang ice_aq_str(pf->hw.adminq.sq_last_status)); 23285153a18eSAnirudh Venkataramanan goto err_out; 23295153a18eSAnirudh Venkataramanan } 23305153a18eSAnirudh Venkataramanan 23315153a18eSAnirudh Venkataramanan vsi->info.sw_flags2 = ctxt->info.sw_flags2; 23325153a18eSAnirudh Venkataramanan 23339efe35d0STony Nguyen kfree(ctxt); 23345153a18eSAnirudh Venkataramanan return 0; 23355153a18eSAnirudh Venkataramanan 23365153a18eSAnirudh Venkataramanan err_out: 23379efe35d0STony Nguyen kfree(ctxt); 23385153a18eSAnirudh Venkataramanan return -EIO; 23395153a18eSAnirudh Venkataramanan } 23405153a18eSAnirudh Venkataramanan 23417b9ffc76SAnirudh Venkataramanan static void ice_vsi_set_tc_cfg(struct ice_vsi *vsi) 23427b9ffc76SAnirudh Venkataramanan { 2343*0754d65bSKiran Patil if (!test_bit(ICE_FLAG_DCB_ENA, vsi->back->flags)) { 2344*0754d65bSKiran Patil vsi->tc_cfg.ena_tc = ICE_DFLT_TRAFFIC_CLASS; 2345*0754d65bSKiran Patil vsi->tc_cfg.numtc = 1; 2346*0754d65bSKiran Patil return; 2347*0754d65bSKiran Patil } 23487b9ffc76SAnirudh Venkataramanan 2349*0754d65bSKiran Patil /* set VSI TC information based on DCB config */ 2350*0754d65bSKiran Patil ice_vsi_set_dcb_tc_cfg(vsi); 23517b9ffc76SAnirudh Venkataramanan } 23527b9ffc76SAnirudh Venkataramanan 23535153a18eSAnirudh Venkataramanan /** 2354b07833a0SBrett Creeley * ice_vsi_set_q_vectors_reg_idx - set the HW register index for all q_vectors 2355b07833a0SBrett Creeley * @vsi: VSI to set the q_vectors register index on 2356b07833a0SBrett Creeley */ 2357b07833a0SBrett Creeley static int 2358b07833a0SBrett Creeley ice_vsi_set_q_vectors_reg_idx(struct ice_vsi *vsi) 2359b07833a0SBrett Creeley { 2360b07833a0SBrett Creeley u16 i; 2361b07833a0SBrett Creeley 2362b07833a0SBrett Creeley if (!vsi || !vsi->q_vectors) 2363b07833a0SBrett Creeley return -EINVAL; 2364b07833a0SBrett Creeley 2365b07833a0SBrett Creeley ice_for_each_q_vector(vsi, i) { 2366b07833a0SBrett Creeley struct ice_q_vector *q_vector = vsi->q_vectors[i]; 2367b07833a0SBrett Creeley 2368b07833a0SBrett Creeley if (!q_vector) { 236919cce2c6SAnirudh Venkataramanan dev_err(ice_pf_to_dev(vsi->back), "Failed to set reg_idx on q_vector %d VSI %d\n", 2370b07833a0SBrett Creeley i, vsi->vsi_num); 2371b07833a0SBrett Creeley goto clear_reg_idx; 2372b07833a0SBrett Creeley } 2373b07833a0SBrett Creeley 2374cbe66bfeSBrett Creeley if (vsi->type == ICE_VSI_VF) { 2375cbe66bfeSBrett Creeley struct ice_vf *vf = &vsi->back->vf[vsi->vf_id]; 2376cbe66bfeSBrett Creeley 2377cbe66bfeSBrett Creeley q_vector->reg_idx = ice_calc_vf_reg_idx(vf, q_vector); 2378cbe66bfeSBrett Creeley } else { 2379cbe66bfeSBrett Creeley q_vector->reg_idx = 2380cbe66bfeSBrett Creeley q_vector->v_idx + vsi->base_vector; 2381cbe66bfeSBrett Creeley } 2382b07833a0SBrett Creeley } 2383b07833a0SBrett Creeley 2384b07833a0SBrett Creeley return 0; 2385b07833a0SBrett Creeley 2386b07833a0SBrett Creeley clear_reg_idx: 2387b07833a0SBrett Creeley ice_for_each_q_vector(vsi, i) { 2388b07833a0SBrett Creeley struct ice_q_vector *q_vector = vsi->q_vectors[i]; 2389b07833a0SBrett Creeley 2390b07833a0SBrett Creeley if (q_vector) 2391b07833a0SBrett Creeley q_vector->reg_idx = 0; 2392b07833a0SBrett Creeley } 2393b07833a0SBrett Creeley 2394b07833a0SBrett Creeley return -EINVAL; 2395b07833a0SBrett Creeley } 2396b07833a0SBrett Creeley 2397b07833a0SBrett Creeley /** 23982e0e6228SDave Ertman * ice_cfg_sw_lldp - Config switch rules for LLDP packet handling 23992e0e6228SDave Ertman * @vsi: the VSI being configured 24002e0e6228SDave Ertman * @tx: bool to determine Tx or Rx rule 24012e0e6228SDave Ertman * @create: bool to determine create or remove Rule 24022e0e6228SDave Ertman */ 24032e0e6228SDave Ertman void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create) 24042e0e6228SDave Ertman { 24051b8f15b6SMichal Swiatkowski enum ice_status (*eth_fltr)(struct ice_vsi *v, u16 type, u16 flag, 24061b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type act); 24072e0e6228SDave Ertman struct ice_pf *pf = vsi->back; 24082e0e6228SDave Ertman enum ice_status status; 24094015d11eSBrett Creeley struct device *dev; 24102e0e6228SDave Ertman 24114015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 24121b8f15b6SMichal Swiatkowski eth_fltr = create ? ice_fltr_add_eth : ice_fltr_remove_eth; 24132e0e6228SDave Ertman 241434295a36SDave Ertman if (tx) { 24151b8f15b6SMichal Swiatkowski status = eth_fltr(vsi, ETH_P_LLDP, ICE_FLTR_TX, 24161b8f15b6SMichal Swiatkowski ICE_DROP_PACKET); 241734295a36SDave Ertman } else { 241834295a36SDave Ertman if (ice_fw_supports_lldp_fltr_ctrl(&pf->hw)) { 241934295a36SDave Ertman status = ice_lldp_fltr_add_remove(&pf->hw, vsi->vsi_num, 242034295a36SDave Ertman create); 242134295a36SDave Ertman } else { 242234295a36SDave Ertman status = eth_fltr(vsi, ETH_P_LLDP, ICE_FLTR_RX, 242334295a36SDave Ertman ICE_FWD_TO_VSI); 242434295a36SDave Ertman } 242534295a36SDave Ertman } 24262e0e6228SDave Ertman 24272e0e6228SDave Ertman if (status) 2428a69606cdSAnirudh Venkataramanan dev_dbg(dev, "Fail %s %s LLDP rule on VSI %i error: %s\n", 24292e0e6228SDave Ertman create ? "adding" : "removing", tx ? "TX" : "RX", 24300fee3577SLihong Yang vsi->vsi_num, ice_stat_str(status)); 24312e0e6228SDave Ertman } 24322e0e6228SDave Ertman 2433d95276ceSAkeem G Abodunrin /** 2434b126bd6bSKiran Patil * ice_set_agg_vsi - sets up scheduler aggregator node and move VSI into it 2435b126bd6bSKiran Patil * @vsi: pointer to the VSI 2436b126bd6bSKiran Patil * 2437b126bd6bSKiran Patil * This function will allocate new scheduler aggregator now if needed and will 2438b126bd6bSKiran Patil * move specified VSI into it. 2439b126bd6bSKiran Patil */ 2440b126bd6bSKiran Patil static void ice_set_agg_vsi(struct ice_vsi *vsi) 2441b126bd6bSKiran Patil { 2442b126bd6bSKiran Patil struct device *dev = ice_pf_to_dev(vsi->back); 2443b126bd6bSKiran Patil struct ice_agg_node *agg_node_iter = NULL; 2444b126bd6bSKiran Patil u32 agg_id = ICE_INVALID_AGG_NODE_ID; 2445b126bd6bSKiran Patil struct ice_agg_node *agg_node = NULL; 2446b126bd6bSKiran Patil int node_offset, max_agg_nodes = 0; 2447b126bd6bSKiran Patil struct ice_port_info *port_info; 2448b126bd6bSKiran Patil struct ice_pf *pf = vsi->back; 2449b126bd6bSKiran Patil u32 agg_node_id_start = 0; 2450b126bd6bSKiran Patil enum ice_status status; 2451b126bd6bSKiran Patil 2452b126bd6bSKiran Patil /* create (as needed) scheduler aggregator node and move VSI into 2453b126bd6bSKiran Patil * corresponding aggregator node 2454b126bd6bSKiran Patil * - PF aggregator node to contains VSIs of type _PF and _CTRL 2455b126bd6bSKiran Patil * - VF aggregator nodes will contain VF VSI 2456b126bd6bSKiran Patil */ 2457b126bd6bSKiran Patil port_info = pf->hw.port_info; 2458b126bd6bSKiran Patil if (!port_info) 2459b126bd6bSKiran Patil return; 2460b126bd6bSKiran Patil 2461b126bd6bSKiran Patil switch (vsi->type) { 2462b126bd6bSKiran Patil case ICE_VSI_CTRL: 2463*0754d65bSKiran Patil case ICE_VSI_CHNL: 2464b126bd6bSKiran Patil case ICE_VSI_LB: 2465b126bd6bSKiran Patil case ICE_VSI_PF: 2466f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 2467b126bd6bSKiran Patil max_agg_nodes = ICE_MAX_PF_AGG_NODES; 2468b126bd6bSKiran Patil agg_node_id_start = ICE_PF_AGG_NODE_ID_START; 2469b126bd6bSKiran Patil agg_node_iter = &pf->pf_agg_node[0]; 2470b126bd6bSKiran Patil break; 2471b126bd6bSKiran Patil case ICE_VSI_VF: 2472b126bd6bSKiran Patil /* user can create 'n' VFs on a given PF, but since max children 2473b126bd6bSKiran Patil * per aggregator node can be only 64. Following code handles 2474b126bd6bSKiran Patil * aggregator(s) for VF VSIs, either selects a agg_node which 2475b126bd6bSKiran Patil * was already created provided num_vsis < 64, otherwise 2476b126bd6bSKiran Patil * select next available node, which will be created 2477b126bd6bSKiran Patil */ 2478b126bd6bSKiran Patil max_agg_nodes = ICE_MAX_VF_AGG_NODES; 2479b126bd6bSKiran Patil agg_node_id_start = ICE_VF_AGG_NODE_ID_START; 2480b126bd6bSKiran Patil agg_node_iter = &pf->vf_agg_node[0]; 2481b126bd6bSKiran Patil break; 2482b126bd6bSKiran Patil default: 2483b126bd6bSKiran Patil /* other VSI type, handle later if needed */ 2484b126bd6bSKiran Patil dev_dbg(dev, "unexpected VSI type %s\n", 2485b126bd6bSKiran Patil ice_vsi_type_str(vsi->type)); 2486b126bd6bSKiran Patil return; 2487b126bd6bSKiran Patil } 2488b126bd6bSKiran Patil 2489b126bd6bSKiran Patil /* find the appropriate aggregator node */ 2490b126bd6bSKiran Patil for (node_offset = 0; node_offset < max_agg_nodes; node_offset++) { 2491b126bd6bSKiran Patil /* see if we can find space in previously created 2492b126bd6bSKiran Patil * node if num_vsis < 64, otherwise skip 2493b126bd6bSKiran Patil */ 2494b126bd6bSKiran Patil if (agg_node_iter->num_vsis && 2495b126bd6bSKiran Patil agg_node_iter->num_vsis == ICE_MAX_VSIS_IN_AGG_NODE) { 2496b126bd6bSKiran Patil agg_node_iter++; 2497b126bd6bSKiran Patil continue; 2498b126bd6bSKiran Patil } 2499b126bd6bSKiran Patil 2500b126bd6bSKiran Patil if (agg_node_iter->valid && 2501b126bd6bSKiran Patil agg_node_iter->agg_id != ICE_INVALID_AGG_NODE_ID) { 2502b126bd6bSKiran Patil agg_id = agg_node_iter->agg_id; 2503b126bd6bSKiran Patil agg_node = agg_node_iter; 2504b126bd6bSKiran Patil break; 2505b126bd6bSKiran Patil } 2506b126bd6bSKiran Patil 2507b126bd6bSKiran Patil /* find unclaimed agg_id */ 2508b126bd6bSKiran Patil if (agg_node_iter->agg_id == ICE_INVALID_AGG_NODE_ID) { 2509b126bd6bSKiran Patil agg_id = node_offset + agg_node_id_start; 2510b126bd6bSKiran Patil agg_node = agg_node_iter; 2511b126bd6bSKiran Patil break; 2512b126bd6bSKiran Patil } 2513b126bd6bSKiran Patil /* move to next agg_node */ 2514b126bd6bSKiran Patil agg_node_iter++; 2515b126bd6bSKiran Patil } 2516b126bd6bSKiran Patil 2517b126bd6bSKiran Patil if (!agg_node) 2518b126bd6bSKiran Patil return; 2519b126bd6bSKiran Patil 2520b126bd6bSKiran Patil /* if selected aggregator node was not created, create it */ 2521b126bd6bSKiran Patil if (!agg_node->valid) { 2522b126bd6bSKiran Patil status = ice_cfg_agg(port_info, agg_id, ICE_AGG_TYPE_AGG, 2523b126bd6bSKiran Patil (u8)vsi->tc_cfg.ena_tc); 2524b126bd6bSKiran Patil if (status) { 2525b126bd6bSKiran Patil dev_err(dev, "unable to create aggregator node with agg_id %u\n", 2526b126bd6bSKiran Patil agg_id); 2527b126bd6bSKiran Patil return; 2528b126bd6bSKiran Patil } 2529b126bd6bSKiran Patil /* aggregator node is created, store the neeeded info */ 2530b126bd6bSKiran Patil agg_node->valid = true; 2531b126bd6bSKiran Patil agg_node->agg_id = agg_id; 2532b126bd6bSKiran Patil } 2533b126bd6bSKiran Patil 2534b126bd6bSKiran Patil /* move VSI to corresponding aggregator node */ 2535b126bd6bSKiran Patil status = ice_move_vsi_to_agg(port_info, agg_id, vsi->idx, 2536b126bd6bSKiran Patil (u8)vsi->tc_cfg.ena_tc); 2537b126bd6bSKiran Patil if (status) { 2538b126bd6bSKiran Patil dev_err(dev, "unable to move VSI idx %u into aggregator %u node", 2539b126bd6bSKiran Patil vsi->idx, agg_id); 2540b126bd6bSKiran Patil return; 2541b126bd6bSKiran Patil } 2542b126bd6bSKiran Patil 2543b126bd6bSKiran Patil /* keep active children count for aggregator node */ 2544b126bd6bSKiran Patil agg_node->num_vsis++; 2545b126bd6bSKiran Patil 2546b126bd6bSKiran Patil /* cache the 'agg_id' in VSI, so that after reset - VSI will be moved 2547b126bd6bSKiran Patil * to aggregator node 2548b126bd6bSKiran Patil */ 2549b126bd6bSKiran Patil vsi->agg_node = agg_node; 2550b126bd6bSKiran Patil dev_dbg(dev, "successfully moved VSI idx %u tc_bitmap 0x%x) into aggregator node %d which has num_vsis %u\n", 2551b126bd6bSKiran Patil vsi->idx, vsi->tc_cfg.ena_tc, vsi->agg_node->agg_id, 2552b126bd6bSKiran Patil vsi->agg_node->num_vsis); 2553b126bd6bSKiran Patil } 2554b126bd6bSKiran Patil 2555b126bd6bSKiran Patil /** 255637bb8390SAnirudh Venkataramanan * ice_vsi_setup - Set up a VSI by a given type 255737bb8390SAnirudh Venkataramanan * @pf: board private structure 255837bb8390SAnirudh Venkataramanan * @pi: pointer to the port_info instance 25596dae8aa0SBruce Allan * @vsi_type: VSI type 2560f9867df6SAnirudh Venkataramanan * @vf_id: defines VF ID to which this VSI connects. This field is meant to be 256137bb8390SAnirudh Venkataramanan * used only for ICE_VSI_VF VSI type. For other VSI types, should 256237bb8390SAnirudh Venkataramanan * fill-in ICE_INVAL_VFID as input. 2563*0754d65bSKiran Patil * @ch: ptr to channel 256437bb8390SAnirudh Venkataramanan * 256537bb8390SAnirudh Venkataramanan * This allocates the sw VSI structure and its queue resources. 256637bb8390SAnirudh Venkataramanan * 256737bb8390SAnirudh Venkataramanan * Returns pointer to the successfully allocated and configured VSI sw struct on 256837bb8390SAnirudh Venkataramanan * success, NULL on failure. 256937bb8390SAnirudh Venkataramanan */ 257037bb8390SAnirudh Venkataramanan struct ice_vsi * 257137bb8390SAnirudh Venkataramanan ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi, 2572*0754d65bSKiran Patil enum ice_vsi_type vsi_type, u16 vf_id, struct ice_channel *ch) 257337bb8390SAnirudh Venkataramanan { 257437bb8390SAnirudh Venkataramanan u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 }; 25754015d11eSBrett Creeley struct device *dev = ice_pf_to_dev(pf); 2576d31530e8SAkeem G Abodunrin enum ice_status status; 257737bb8390SAnirudh Venkataramanan struct ice_vsi *vsi; 257837bb8390SAnirudh Venkataramanan int ret, i; 257937bb8390SAnirudh Venkataramanan 2580*0754d65bSKiran Patil if (vsi_type == ICE_VSI_CHNL) 2581*0754d65bSKiran Patil vsi = ice_vsi_alloc(pf, vsi_type, ch, ICE_INVAL_VFID); 2582*0754d65bSKiran Patil else if (vsi_type == ICE_VSI_VF || vsi_type == ICE_VSI_CTRL) 2583*0754d65bSKiran Patil vsi = ice_vsi_alloc(pf, vsi_type, NULL, vf_id); 25845743020dSAkeem G Abodunrin else 2585*0754d65bSKiran Patil vsi = ice_vsi_alloc(pf, vsi_type, NULL, ICE_INVAL_VFID); 25865743020dSAkeem G Abodunrin 258737bb8390SAnirudh Venkataramanan if (!vsi) { 258837bb8390SAnirudh Venkataramanan dev_err(dev, "could not allocate VSI\n"); 258937bb8390SAnirudh Venkataramanan return NULL; 259037bb8390SAnirudh Venkataramanan } 259137bb8390SAnirudh Venkataramanan 259237bb8390SAnirudh Venkataramanan vsi->port_info = pi; 259337bb8390SAnirudh Venkataramanan vsi->vsw = pf->first_sw; 2594d95276ceSAkeem G Abodunrin if (vsi->type == ICE_VSI_PF) 2595d95276ceSAkeem G Abodunrin vsi->ethtype = ETH_P_PAUSE; 2596d95276ceSAkeem G Abodunrin 2597da62c5ffSQi Zhang if (vsi->type == ICE_VSI_VF || vsi->type == ICE_VSI_CTRL) 25988ede0178SAnirudh Venkataramanan vsi->vf_id = vf_id; 259937bb8390SAnirudh Venkataramanan 2600148beb61SHenry Tieman ice_alloc_fd_res(vsi); 2601148beb61SHenry Tieman 2602*0754d65bSKiran Patil if (vsi_type != ICE_VSI_CHNL) { 260337bb8390SAnirudh Venkataramanan if (ice_vsi_get_qs(vsi)) { 260437bb8390SAnirudh Venkataramanan dev_err(dev, "Failed to allocate queues. vsi->idx = %d\n", 260537bb8390SAnirudh Venkataramanan vsi->idx); 2606148beb61SHenry Tieman goto unroll_vsi_alloc; 260737bb8390SAnirudh Venkataramanan } 2608*0754d65bSKiran Patil } 260937bb8390SAnirudh Venkataramanan 261037bb8390SAnirudh Venkataramanan /* set RSS capabilities */ 261137bb8390SAnirudh Venkataramanan ice_vsi_set_rss_params(vsi); 261237bb8390SAnirudh Venkataramanan 2613f9867df6SAnirudh Venkataramanan /* set TC configuration */ 2614c5a2a4a3SUsha Ketineni ice_vsi_set_tc_cfg(vsi); 2615c5a2a4a3SUsha Ketineni 261637bb8390SAnirudh Venkataramanan /* create the VSI */ 261787324e74SHenry Tieman ret = ice_vsi_init(vsi, true); 261837bb8390SAnirudh Venkataramanan if (ret) 261937bb8390SAnirudh Venkataramanan goto unroll_get_qs; 262037bb8390SAnirudh Venkataramanan 262137bb8390SAnirudh Venkataramanan switch (vsi->type) { 2622148beb61SHenry Tieman case ICE_VSI_CTRL: 2623f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 262437bb8390SAnirudh Venkataramanan case ICE_VSI_PF: 262537bb8390SAnirudh Venkataramanan ret = ice_vsi_alloc_q_vectors(vsi); 262637bb8390SAnirudh Venkataramanan if (ret) 262737bb8390SAnirudh Venkataramanan goto unroll_vsi_init; 262837bb8390SAnirudh Venkataramanan 262937bb8390SAnirudh Venkataramanan ret = ice_vsi_setup_vector_base(vsi); 263037bb8390SAnirudh Venkataramanan if (ret) 263137bb8390SAnirudh Venkataramanan goto unroll_alloc_q_vector; 263237bb8390SAnirudh Venkataramanan 2633b07833a0SBrett Creeley ret = ice_vsi_set_q_vectors_reg_idx(vsi); 2634b07833a0SBrett Creeley if (ret) 2635b07833a0SBrett Creeley goto unroll_vector_base; 2636b07833a0SBrett Creeley 263737bb8390SAnirudh Venkataramanan ret = ice_vsi_alloc_rings(vsi); 263837bb8390SAnirudh Venkataramanan if (ret) 263937bb8390SAnirudh Venkataramanan goto unroll_vector_base; 264037bb8390SAnirudh Venkataramanan 264142f3efefSBrett Creeley /* Always add VLAN ID 0 switch rule by default. This is needed 264242f3efefSBrett Creeley * in order to allow all untagged and 0 tagged priority traffic 264342f3efefSBrett Creeley * if Rx VLAN pruning is enabled. Also there are cases where we 264442f3efefSBrett Creeley * don't get the call to add VLAN 0 via ice_vlan_rx_add_vid() 264542f3efefSBrett Creeley * so this handles those cases (i.e. adding the PF to a bridge 264642f3efefSBrett Creeley * without the 8021q module loaded). 264742f3efefSBrett Creeley */ 26481b8f15b6SMichal Swiatkowski ret = ice_vsi_add_vlan(vsi, 0, ICE_FWD_TO_VSI); 264942f3efefSBrett Creeley if (ret) 265042f3efefSBrett Creeley goto unroll_clear_rings; 265142f3efefSBrett Creeley 265237bb8390SAnirudh Venkataramanan ice_vsi_map_rings_to_vectors(vsi); 265337bb8390SAnirudh Venkataramanan 2654148beb61SHenry Tieman /* ICE_VSI_CTRL does not need RSS so skip RSS processing */ 2655148beb61SHenry Tieman if (vsi->type != ICE_VSI_CTRL) 2656148beb61SHenry Tieman /* Do not exit if configuring RSS had an issue, at 2657148beb61SHenry Tieman * least receive traffic on first queue. Hence no 2658148beb61SHenry Tieman * need to capture return value 265937bb8390SAnirudh Venkataramanan */ 2660c90ed40cSTony Nguyen if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 266137bb8390SAnirudh Venkataramanan ice_vsi_cfg_rss_lut_key(vsi); 2662c90ed40cSTony Nguyen ice_vsi_set_rss_flow_fld(vsi); 2663c90ed40cSTony Nguyen } 266428bf2672SBrett Creeley ice_init_arfs(vsi); 266537bb8390SAnirudh Venkataramanan break; 2666*0754d65bSKiran Patil case ICE_VSI_CHNL: 2667*0754d65bSKiran Patil if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 2668*0754d65bSKiran Patil ice_vsi_cfg_rss_lut_key(vsi); 2669*0754d65bSKiran Patil ice_vsi_set_rss_flow_fld(vsi); 2670*0754d65bSKiran Patil } 2671*0754d65bSKiran Patil break; 26728ede0178SAnirudh Venkataramanan case ICE_VSI_VF: 26738ede0178SAnirudh Venkataramanan /* VF driver will take care of creating netdev for this type and 26748ede0178SAnirudh Venkataramanan * map queues to vectors through Virtchnl, PF driver only 26758ede0178SAnirudh Venkataramanan * creates a VSI and corresponding structures for bookkeeping 26768ede0178SAnirudh Venkataramanan * purpose 26778ede0178SAnirudh Venkataramanan */ 26788ede0178SAnirudh Venkataramanan ret = ice_vsi_alloc_q_vectors(vsi); 26798ede0178SAnirudh Venkataramanan if (ret) 26808ede0178SAnirudh Venkataramanan goto unroll_vsi_init; 26818ede0178SAnirudh Venkataramanan 26828ede0178SAnirudh Venkataramanan ret = ice_vsi_alloc_rings(vsi); 26838ede0178SAnirudh Venkataramanan if (ret) 26848ede0178SAnirudh Venkataramanan goto unroll_alloc_q_vector; 26858ede0178SAnirudh Venkataramanan 2686b07833a0SBrett Creeley ret = ice_vsi_set_q_vectors_reg_idx(vsi); 2687b07833a0SBrett Creeley if (ret) 2688b07833a0SBrett Creeley goto unroll_vector_base; 2689b07833a0SBrett Creeley 26903a9e32bbSMd Fahad Iqbal Polash /* Do not exit if configuring RSS had an issue, at least 26913a9e32bbSMd Fahad Iqbal Polash * receive traffic on first queue. Hence no need to capture 26923a9e32bbSMd Fahad Iqbal Polash * return value 26933a9e32bbSMd Fahad Iqbal Polash */ 26941c01c8c6SMd Fahad Iqbal Polash if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 26953a9e32bbSMd Fahad Iqbal Polash ice_vsi_cfg_rss_lut_key(vsi); 26961c01c8c6SMd Fahad Iqbal Polash ice_vsi_set_vf_rss_flow_fld(vsi); 26971c01c8c6SMd Fahad Iqbal Polash } 26988ede0178SAnirudh Venkataramanan break; 26990e674aebSAnirudh Venkataramanan case ICE_VSI_LB: 27000e674aebSAnirudh Venkataramanan ret = ice_vsi_alloc_rings(vsi); 27010e674aebSAnirudh Venkataramanan if (ret) 27020e674aebSAnirudh Venkataramanan goto unroll_vsi_init; 27030e674aebSAnirudh Venkataramanan break; 270437bb8390SAnirudh Venkataramanan default: 2705df17b7e0SAnirudh Venkataramanan /* clean up the resources and exit */ 270637bb8390SAnirudh Venkataramanan goto unroll_vsi_init; 270737bb8390SAnirudh Venkataramanan } 270837bb8390SAnirudh Venkataramanan 270937bb8390SAnirudh Venkataramanan /* configure VSI nodes based on number of queues and TC's */ 2710*0754d65bSKiran Patil ice_for_each_traffic_class(i) { 2711*0754d65bSKiran Patil if (!(vsi->tc_cfg.ena_tc & BIT(i))) 2712*0754d65bSKiran Patil continue; 271337bb8390SAnirudh Venkataramanan 2714*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL) { 2715*0754d65bSKiran Patil if (!vsi->alloc_txq && vsi->num_txq) 2716*0754d65bSKiran Patil max_txqs[i] = vsi->num_txq; 2717*0754d65bSKiran Patil else 2718*0754d65bSKiran Patil max_txqs[i] = pf->num_lan_tx; 2719*0754d65bSKiran Patil } else { 2720*0754d65bSKiran Patil max_txqs[i] = vsi->alloc_txq; 2721*0754d65bSKiran Patil } 2722*0754d65bSKiran Patil } 2723*0754d65bSKiran Patil 2724*0754d65bSKiran Patil dev_dbg(dev, "vsi->tc_cfg.ena_tc = %d\n", vsi->tc_cfg.ena_tc); 2725d31530e8SAkeem G Abodunrin status = ice_cfg_vsi_lan(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc, 27264fb33f31SAnirudh Venkataramanan max_txqs); 2727d31530e8SAkeem G Abodunrin if (status) { 27280fee3577SLihong Yang dev_err(dev, "VSI %d failed lan queue config, error %s\n", 27290fee3577SLihong Yang vsi->vsi_num, ice_stat_str(status)); 2730f6a07271SJacob Keller goto unroll_clear_rings; 273137bb8390SAnirudh Venkataramanan } 273237bb8390SAnirudh Venkataramanan 2733d95276ceSAkeem G Abodunrin /* Add switch rule to drop all Tx Flow Control Frames, of look up 2734d95276ceSAkeem G Abodunrin * type ETHERTYPE from VSIs, and restrict malicious VF from sending 2735d95276ceSAkeem G Abodunrin * out PAUSE or PFC frames. If enabled, FW can still send FC frames. 2736d95276ceSAkeem G Abodunrin * The rule is added once for PF VSI in order to create appropriate 2737d95276ceSAkeem G Abodunrin * recipe, since VSI/VSI list is ignored with drop action... 2738241c8cf0SPaul Greenwalt * Also add rules to handle LLDP Tx packets. Tx LLDP packets need to 2739241c8cf0SPaul Greenwalt * be dropped so that VFs cannot send LLDP packets to reconfig DCB 2740241c8cf0SPaul Greenwalt * settings in the HW. 2741d95276ceSAkeem G Abodunrin */ 2742241c8cf0SPaul Greenwalt if (!ice_is_safe_mode(pf)) 27432e0e6228SDave Ertman if (vsi->type == ICE_VSI_PF) { 27441b8f15b6SMichal Swiatkowski ice_fltr_add_eth(vsi, ETH_P_PAUSE, ICE_FLTR_TX, 27451b8f15b6SMichal Swiatkowski ICE_DROP_PACKET); 27462e0e6228SDave Ertman ice_cfg_sw_lldp(vsi, true, true); 2747462acf6aSTony Nguyen } 27482e0e6228SDave Ertman 2749b126bd6bSKiran Patil if (!vsi->agg_node) 2750b126bd6bSKiran Patil ice_set_agg_vsi(vsi); 275137bb8390SAnirudh Venkataramanan return vsi; 275237bb8390SAnirudh Venkataramanan 275342f3efefSBrett Creeley unroll_clear_rings: 275442f3efefSBrett Creeley ice_vsi_clear_rings(vsi); 275537bb8390SAnirudh Venkataramanan unroll_vector_base: 2756eb0208ecSPreethi Banala /* reclaim SW interrupts back to the common pool */ 2757cbe66bfeSBrett Creeley ice_free_res(pf->irq_tracker, vsi->base_vector, vsi->idx); 2758eb0208ecSPreethi Banala pf->num_avail_sw_msix += vsi->num_q_vectors; 275937bb8390SAnirudh Venkataramanan unroll_alloc_q_vector: 276037bb8390SAnirudh Venkataramanan ice_vsi_free_q_vectors(vsi); 276137bb8390SAnirudh Venkataramanan unroll_vsi_init: 276237bb8390SAnirudh Venkataramanan ice_vsi_delete(vsi); 276337bb8390SAnirudh Venkataramanan unroll_get_qs: 276437bb8390SAnirudh Venkataramanan ice_vsi_put_qs(vsi); 2765148beb61SHenry Tieman unroll_vsi_alloc: 2766df006dd4SDave Ertman if (vsi_type == ICE_VSI_VF) 2767df006dd4SDave Ertman ice_enable_lag(pf->lag); 276837bb8390SAnirudh Venkataramanan ice_vsi_clear(vsi); 276937bb8390SAnirudh Venkataramanan 277037bb8390SAnirudh Venkataramanan return NULL; 277137bb8390SAnirudh Venkataramanan } 277237bb8390SAnirudh Venkataramanan 277337bb8390SAnirudh Venkataramanan /** 27745153a18eSAnirudh Venkataramanan * ice_vsi_release_msix - Clear the queue to Interrupt mapping in HW 27755153a18eSAnirudh Venkataramanan * @vsi: the VSI being cleaned up 27765153a18eSAnirudh Venkataramanan */ 27775153a18eSAnirudh Venkataramanan static void ice_vsi_release_msix(struct ice_vsi *vsi) 27785153a18eSAnirudh Venkataramanan { 27795153a18eSAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 27805153a18eSAnirudh Venkataramanan struct ice_hw *hw = &pf->hw; 27815153a18eSAnirudh Venkataramanan u32 txq = 0; 27825153a18eSAnirudh Venkataramanan u32 rxq = 0; 27835153a18eSAnirudh Venkataramanan int i, q; 27845153a18eSAnirudh Venkataramanan 27852faf63b6SMaciej Fijalkowski ice_for_each_q_vector(vsi, i) { 27865153a18eSAnirudh Venkataramanan struct ice_q_vector *q_vector = vsi->q_vectors[i]; 27875153a18eSAnirudh Venkataramanan 2788b8b47723SJesse Brandeburg ice_write_intrl(q_vector, 0); 27895153a18eSAnirudh Venkataramanan for (q = 0; q < q_vector->num_ring_tx; q++) { 2790b8b47723SJesse Brandeburg ice_write_itr(&q_vector->tx, 0); 27915153a18eSAnirudh Venkataramanan wr32(hw, QINT_TQCTL(vsi->txq_map[txq]), 0); 2792efc2214bSMaciej Fijalkowski if (ice_is_xdp_ena_vsi(vsi)) { 2793efc2214bSMaciej Fijalkowski u32 xdp_txq = txq + vsi->num_xdp_txq; 2794efc2214bSMaciej Fijalkowski 2795efc2214bSMaciej Fijalkowski wr32(hw, QINT_TQCTL(vsi->txq_map[xdp_txq]), 0); 2796efc2214bSMaciej Fijalkowski } 27975153a18eSAnirudh Venkataramanan txq++; 27985153a18eSAnirudh Venkataramanan } 27995153a18eSAnirudh Venkataramanan 28005153a18eSAnirudh Venkataramanan for (q = 0; q < q_vector->num_ring_rx; q++) { 2801b8b47723SJesse Brandeburg ice_write_itr(&q_vector->rx, 0); 28025153a18eSAnirudh Venkataramanan wr32(hw, QINT_RQCTL(vsi->rxq_map[rxq]), 0); 28035153a18eSAnirudh Venkataramanan rxq++; 28045153a18eSAnirudh Venkataramanan } 28055153a18eSAnirudh Venkataramanan } 28065153a18eSAnirudh Venkataramanan 28075153a18eSAnirudh Venkataramanan ice_flush(hw); 28085153a18eSAnirudh Venkataramanan } 28095153a18eSAnirudh Venkataramanan 28105153a18eSAnirudh Venkataramanan /** 28115153a18eSAnirudh Venkataramanan * ice_vsi_free_irq - Free the IRQ association with the OS 28125153a18eSAnirudh Venkataramanan * @vsi: the VSI being configured 28135153a18eSAnirudh Venkataramanan */ 28145153a18eSAnirudh Venkataramanan void ice_vsi_free_irq(struct ice_vsi *vsi) 28155153a18eSAnirudh Venkataramanan { 28165153a18eSAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 2817cbe66bfeSBrett Creeley int base = vsi->base_vector; 28185153a18eSAnirudh Venkataramanan int i; 28195153a18eSAnirudh Venkataramanan 28205153a18eSAnirudh Venkataramanan if (!vsi->q_vectors || !vsi->irqs_ready) 28215153a18eSAnirudh Venkataramanan return; 28225153a18eSAnirudh Venkataramanan 2823eb0208ecSPreethi Banala ice_vsi_release_msix(vsi); 28248ede0178SAnirudh Venkataramanan if (vsi->type == ICE_VSI_VF) 28258ede0178SAnirudh Venkataramanan return; 2826eb0208ecSPreethi Banala 28275153a18eSAnirudh Venkataramanan vsi->irqs_ready = false; 28280c2561c8SBrett Creeley ice_for_each_q_vector(vsi, i) { 28295153a18eSAnirudh Venkataramanan u16 vector = i + base; 28305153a18eSAnirudh Venkataramanan int irq_num; 28315153a18eSAnirudh Venkataramanan 28325153a18eSAnirudh Venkataramanan irq_num = pf->msix_entries[vector].vector; 28335153a18eSAnirudh Venkataramanan 28345153a18eSAnirudh Venkataramanan /* free only the irqs that were actually requested */ 28355153a18eSAnirudh Venkataramanan if (!vsi->q_vectors[i] || 28365153a18eSAnirudh Venkataramanan !(vsi->q_vectors[i]->num_ring_tx || 28375153a18eSAnirudh Venkataramanan vsi->q_vectors[i]->num_ring_rx)) 28385153a18eSAnirudh Venkataramanan continue; 28395153a18eSAnirudh Venkataramanan 28405153a18eSAnirudh Venkataramanan /* clear the affinity notifier in the IRQ descriptor */ 28415153a18eSAnirudh Venkataramanan irq_set_affinity_notifier(irq_num, NULL); 28425153a18eSAnirudh Venkataramanan 28435153a18eSAnirudh Venkataramanan /* clear the affinity_mask in the IRQ descriptor */ 28445153a18eSAnirudh Venkataramanan irq_set_affinity_hint(irq_num, NULL); 28455153a18eSAnirudh Venkataramanan synchronize_irq(irq_num); 28464015d11eSBrett Creeley devm_free_irq(ice_pf_to_dev(pf), irq_num, vsi->q_vectors[i]); 28475153a18eSAnirudh Venkataramanan } 28485153a18eSAnirudh Venkataramanan } 28495153a18eSAnirudh Venkataramanan 28505153a18eSAnirudh Venkataramanan /** 28515153a18eSAnirudh Venkataramanan * ice_vsi_free_tx_rings - Free Tx resources for VSI queues 28525153a18eSAnirudh Venkataramanan * @vsi: the VSI having resources freed 28535153a18eSAnirudh Venkataramanan */ 28545153a18eSAnirudh Venkataramanan void ice_vsi_free_tx_rings(struct ice_vsi *vsi) 28555153a18eSAnirudh Venkataramanan { 28565153a18eSAnirudh Venkataramanan int i; 28575153a18eSAnirudh Venkataramanan 28585153a18eSAnirudh Venkataramanan if (!vsi->tx_rings) 28595153a18eSAnirudh Venkataramanan return; 28605153a18eSAnirudh Venkataramanan 28615153a18eSAnirudh Venkataramanan ice_for_each_txq(vsi, i) 28625153a18eSAnirudh Venkataramanan if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc) 28635153a18eSAnirudh Venkataramanan ice_free_tx_ring(vsi->tx_rings[i]); 28645153a18eSAnirudh Venkataramanan } 28655153a18eSAnirudh Venkataramanan 28665153a18eSAnirudh Venkataramanan /** 28675153a18eSAnirudh Venkataramanan * ice_vsi_free_rx_rings - Free Rx resources for VSI queues 28685153a18eSAnirudh Venkataramanan * @vsi: the VSI having resources freed 28695153a18eSAnirudh Venkataramanan */ 28705153a18eSAnirudh Venkataramanan void ice_vsi_free_rx_rings(struct ice_vsi *vsi) 28715153a18eSAnirudh Venkataramanan { 28725153a18eSAnirudh Venkataramanan int i; 28735153a18eSAnirudh Venkataramanan 28745153a18eSAnirudh Venkataramanan if (!vsi->rx_rings) 28755153a18eSAnirudh Venkataramanan return; 28765153a18eSAnirudh Venkataramanan 28775153a18eSAnirudh Venkataramanan ice_for_each_rxq(vsi, i) 28785153a18eSAnirudh Venkataramanan if (vsi->rx_rings[i] && vsi->rx_rings[i]->desc) 28795153a18eSAnirudh Venkataramanan ice_free_rx_ring(vsi->rx_rings[i]); 28805153a18eSAnirudh Venkataramanan } 28815153a18eSAnirudh Venkataramanan 28825153a18eSAnirudh Venkataramanan /** 288307309a0eSAnirudh Venkataramanan * ice_vsi_close - Shut down a VSI 288407309a0eSAnirudh Venkataramanan * @vsi: the VSI being shut down 288507309a0eSAnirudh Venkataramanan */ 288607309a0eSAnirudh Venkataramanan void ice_vsi_close(struct ice_vsi *vsi) 288707309a0eSAnirudh Venkataramanan { 2888e97fb1aeSAnirudh Venkataramanan if (!test_and_set_bit(ICE_VSI_DOWN, vsi->state)) 288907309a0eSAnirudh Venkataramanan ice_down(vsi); 289007309a0eSAnirudh Venkataramanan 289107309a0eSAnirudh Venkataramanan ice_vsi_free_irq(vsi); 289207309a0eSAnirudh Venkataramanan ice_vsi_free_tx_rings(vsi); 289307309a0eSAnirudh Venkataramanan ice_vsi_free_rx_rings(vsi); 289407309a0eSAnirudh Venkataramanan } 289507309a0eSAnirudh Venkataramanan 289607309a0eSAnirudh Venkataramanan /** 28979d614b64SAnirudh Venkataramanan * ice_ena_vsi - resume a VSI 28989d614b64SAnirudh Venkataramanan * @vsi: the VSI being resume 28999d614b64SAnirudh Venkataramanan * @locked: is the rtnl_lock already held 29009d614b64SAnirudh Venkataramanan */ 29019d614b64SAnirudh Venkataramanan int ice_ena_vsi(struct ice_vsi *vsi, bool locked) 29029d614b64SAnirudh Venkataramanan { 29039d614b64SAnirudh Venkataramanan int err = 0; 29049d614b64SAnirudh Venkataramanan 2905e97fb1aeSAnirudh Venkataramanan if (!test_bit(ICE_VSI_NEEDS_RESTART, vsi->state)) 29069d614b64SAnirudh Venkataramanan return 0; 29079d614b64SAnirudh Venkataramanan 2908e97fb1aeSAnirudh Venkataramanan clear_bit(ICE_VSI_NEEDS_RESTART, vsi->state); 29099d614b64SAnirudh Venkataramanan 29109d614b64SAnirudh Venkataramanan if (vsi->netdev && vsi->type == ICE_VSI_PF) { 29119d614b64SAnirudh Venkataramanan if (netif_running(vsi->netdev)) { 29129d614b64SAnirudh Venkataramanan if (!locked) 29139d614b64SAnirudh Venkataramanan rtnl_lock(); 29149d614b64SAnirudh Venkataramanan 2915e95fc857SKrzysztof Goreczny err = ice_open_internal(vsi->netdev); 29169d614b64SAnirudh Venkataramanan 29179d614b64SAnirudh Venkataramanan if (!locked) 29189d614b64SAnirudh Venkataramanan rtnl_unlock(); 29199d614b64SAnirudh Venkataramanan } 2920148beb61SHenry Tieman } else if (vsi->type == ICE_VSI_CTRL) { 2921148beb61SHenry Tieman err = ice_vsi_open_ctrl(vsi); 29229d614b64SAnirudh Venkataramanan } 29239d614b64SAnirudh Venkataramanan 29249d614b64SAnirudh Venkataramanan return err; 29259d614b64SAnirudh Venkataramanan } 29269d614b64SAnirudh Venkataramanan 29279d614b64SAnirudh Venkataramanan /** 29289d614b64SAnirudh Venkataramanan * ice_dis_vsi - pause a VSI 29299d614b64SAnirudh Venkataramanan * @vsi: the VSI being paused 29309d614b64SAnirudh Venkataramanan * @locked: is the rtnl_lock already held 29319d614b64SAnirudh Venkataramanan */ 29329d614b64SAnirudh Venkataramanan void ice_dis_vsi(struct ice_vsi *vsi, bool locked) 29339d614b64SAnirudh Venkataramanan { 2934e97fb1aeSAnirudh Venkataramanan if (test_bit(ICE_VSI_DOWN, vsi->state)) 29359d614b64SAnirudh Venkataramanan return; 29369d614b64SAnirudh Venkataramanan 2937e97fb1aeSAnirudh Venkataramanan set_bit(ICE_VSI_NEEDS_RESTART, vsi->state); 29389d614b64SAnirudh Venkataramanan 29399d614b64SAnirudh Venkataramanan if (vsi->type == ICE_VSI_PF && vsi->netdev) { 29409d614b64SAnirudh Venkataramanan if (netif_running(vsi->netdev)) { 29419d614b64SAnirudh Venkataramanan if (!locked) 29429d614b64SAnirudh Venkataramanan rtnl_lock(); 29439d614b64SAnirudh Venkataramanan 2944e95fc857SKrzysztof Goreczny ice_vsi_close(vsi); 29459d614b64SAnirudh Venkataramanan 29469d614b64SAnirudh Venkataramanan if (!locked) 29479d614b64SAnirudh Venkataramanan rtnl_unlock(); 29489d614b64SAnirudh Venkataramanan } else { 29499d614b64SAnirudh Venkataramanan ice_vsi_close(vsi); 29509d614b64SAnirudh Venkataramanan } 2951f66756e0SGrzegorz Nitka } else if (vsi->type == ICE_VSI_CTRL || 2952f66756e0SGrzegorz Nitka vsi->type == ICE_VSI_SWITCHDEV_CTRL) { 2953148beb61SHenry Tieman ice_vsi_close(vsi); 29549d614b64SAnirudh Venkataramanan } 29559d614b64SAnirudh Venkataramanan } 29569d614b64SAnirudh Venkataramanan 29579d614b64SAnirudh Venkataramanan /** 29585153a18eSAnirudh Venkataramanan * ice_vsi_dis_irq - Mask off queue interrupt generation on the VSI 29595153a18eSAnirudh Venkataramanan * @vsi: the VSI being un-configured 29605153a18eSAnirudh Venkataramanan */ 29615153a18eSAnirudh Venkataramanan void ice_vsi_dis_irq(struct ice_vsi *vsi) 29625153a18eSAnirudh Venkataramanan { 2963cbe66bfeSBrett Creeley int base = vsi->base_vector; 29645153a18eSAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 29655153a18eSAnirudh Venkataramanan struct ice_hw *hw = &pf->hw; 29665153a18eSAnirudh Venkataramanan u32 val; 29675153a18eSAnirudh Venkataramanan int i; 29685153a18eSAnirudh Venkataramanan 29695153a18eSAnirudh Venkataramanan /* disable interrupt causation from each queue */ 29705153a18eSAnirudh Venkataramanan if (vsi->tx_rings) { 29715153a18eSAnirudh Venkataramanan ice_for_each_txq(vsi, i) { 29725153a18eSAnirudh Venkataramanan if (vsi->tx_rings[i]) { 29735153a18eSAnirudh Venkataramanan u16 reg; 29745153a18eSAnirudh Venkataramanan 29755153a18eSAnirudh Venkataramanan reg = vsi->tx_rings[i]->reg_idx; 29765153a18eSAnirudh Venkataramanan val = rd32(hw, QINT_TQCTL(reg)); 29775153a18eSAnirudh Venkataramanan val &= ~QINT_TQCTL_CAUSE_ENA_M; 29785153a18eSAnirudh Venkataramanan wr32(hw, QINT_TQCTL(reg), val); 29795153a18eSAnirudh Venkataramanan } 29805153a18eSAnirudh Venkataramanan } 29815153a18eSAnirudh Venkataramanan } 29825153a18eSAnirudh Venkataramanan 29835153a18eSAnirudh Venkataramanan if (vsi->rx_rings) { 29845153a18eSAnirudh Venkataramanan ice_for_each_rxq(vsi, i) { 29855153a18eSAnirudh Venkataramanan if (vsi->rx_rings[i]) { 29865153a18eSAnirudh Venkataramanan u16 reg; 29875153a18eSAnirudh Venkataramanan 29885153a18eSAnirudh Venkataramanan reg = vsi->rx_rings[i]->reg_idx; 29895153a18eSAnirudh Venkataramanan val = rd32(hw, QINT_RQCTL(reg)); 29905153a18eSAnirudh Venkataramanan val &= ~QINT_RQCTL_CAUSE_ENA_M; 29915153a18eSAnirudh Venkataramanan wr32(hw, QINT_RQCTL(reg), val); 29925153a18eSAnirudh Venkataramanan } 29935153a18eSAnirudh Venkataramanan } 29945153a18eSAnirudh Venkataramanan } 29955153a18eSAnirudh Venkataramanan 29965153a18eSAnirudh Venkataramanan /* disable each interrupt */ 2997462acf6aSTony Nguyen ice_for_each_q_vector(vsi, i) { 2998462acf6aSTony Nguyen if (!vsi->q_vectors[i]) 2999462acf6aSTony Nguyen continue; 3000b07833a0SBrett Creeley wr32(hw, GLINT_DYN_CTL(vsi->q_vectors[i]->reg_idx), 0); 3001462acf6aSTony Nguyen } 30025153a18eSAnirudh Venkataramanan 30035153a18eSAnirudh Venkataramanan ice_flush(hw); 3004b07833a0SBrett Creeley 3005da4a9e73SBrett Creeley /* don't call synchronize_irq() for VF's from the host */ 3006da4a9e73SBrett Creeley if (vsi->type == ICE_VSI_VF) 3007da4a9e73SBrett Creeley return; 3008da4a9e73SBrett Creeley 30090c2561c8SBrett Creeley ice_for_each_q_vector(vsi, i) 30105153a18eSAnirudh Venkataramanan synchronize_irq(pf->msix_entries[i + base].vector); 30115153a18eSAnirudh Venkataramanan } 30125153a18eSAnirudh Venkataramanan 30135153a18eSAnirudh Venkataramanan /** 3014561f4379STony Nguyen * ice_napi_del - Remove NAPI handler for the VSI 3015561f4379STony Nguyen * @vsi: VSI for which NAPI handler is to be removed 3016561f4379STony Nguyen */ 3017561f4379STony Nguyen void ice_napi_del(struct ice_vsi *vsi) 3018561f4379STony Nguyen { 3019561f4379STony Nguyen int v_idx; 3020561f4379STony Nguyen 3021561f4379STony Nguyen if (!vsi->netdev) 3022561f4379STony Nguyen return; 3023561f4379STony Nguyen 3024561f4379STony Nguyen ice_for_each_q_vector(vsi, v_idx) 3025561f4379STony Nguyen netif_napi_del(&vsi->q_vectors[v_idx]->napi); 3026561f4379STony Nguyen } 3027561f4379STony Nguyen 3028561f4379STony Nguyen /** 3029df0f8479SAnirudh Venkataramanan * ice_vsi_release - Delete a VSI and free its resources 3030df0f8479SAnirudh Venkataramanan * @vsi: the VSI being removed 3031df0f8479SAnirudh Venkataramanan * 3032df0f8479SAnirudh Venkataramanan * Returns 0 on success or < 0 on error 3033df0f8479SAnirudh Venkataramanan */ 3034df0f8479SAnirudh Venkataramanan int ice_vsi_release(struct ice_vsi *vsi) 3035df0f8479SAnirudh Venkataramanan { 3036df0f8479SAnirudh Venkataramanan struct ice_pf *pf; 3037df0f8479SAnirudh Venkataramanan 3038df0f8479SAnirudh Venkataramanan if (!vsi->back) 3039df0f8479SAnirudh Venkataramanan return -ENODEV; 3040df0f8479SAnirudh Venkataramanan pf = vsi->back; 3041b751930cSBrett Creeley 3042aa6ccf3fSBrett Creeley /* do not unregister while driver is in the reset recovery pending 3043aa6ccf3fSBrett Creeley * state. Since reset/rebuild happens through PF service task workqueue, 3044aa6ccf3fSBrett Creeley * it's not a good idea to unregister netdev that is associated to the 3045aa6ccf3fSBrett Creeley * PF that is running the work queue items currently. This is done to 3046aa6ccf3fSBrett Creeley * avoid check_flush_dependency() warning on this wq 3047df0f8479SAnirudh Venkataramanan */ 3048a476d72aSAnirudh Venkataramanan if (vsi->netdev && !ice_is_reset_in_progress(pf->state) && 3049a476d72aSAnirudh Venkataramanan (test_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state))) { 3050df0f8479SAnirudh Venkataramanan unregister_netdev(vsi->netdev); 3051a476d72aSAnirudh Venkataramanan clear_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state); 305248d40025SJacob Keller } 3053df0f8479SAnirudh Venkataramanan 30542ae0aa47SWojciech Drewek if (vsi->type == ICE_VSI_PF) 30552ae0aa47SWojciech Drewek ice_devlink_destroy_pf_port(pf); 3056a476d72aSAnirudh Venkataramanan 3057df0f8479SAnirudh Venkataramanan if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) 3058df0f8479SAnirudh Venkataramanan ice_rss_clean(vsi); 3059df0f8479SAnirudh Venkataramanan 3060df0f8479SAnirudh Venkataramanan /* Disable VSI and free resources */ 30610e674aebSAnirudh Venkataramanan if (vsi->type != ICE_VSI_LB) 3062df0f8479SAnirudh Venkataramanan ice_vsi_dis_irq(vsi); 3063df0f8479SAnirudh Venkataramanan ice_vsi_close(vsi); 3064df0f8479SAnirudh Venkataramanan 3065cbe66bfeSBrett Creeley /* SR-IOV determines needed MSIX resources all at once instead of per 3066cbe66bfeSBrett Creeley * VSI since when VFs are spawned we know how many VFs there are and how 3067cbe66bfeSBrett Creeley * many interrupts each VF needs. SR-IOV MSIX resources are also 3068cbe66bfeSBrett Creeley * cleared in the same manner. 3069cbe66bfeSBrett Creeley */ 3070da62c5ffSQi Zhang if (vsi->type == ICE_VSI_CTRL && vsi->vf_id != ICE_INVAL_VFID) { 3071da62c5ffSQi Zhang int i; 3072da62c5ffSQi Zhang 3073da62c5ffSQi Zhang ice_for_each_vf(pf, i) { 3074b6b0501dSPaul M Stillwell Jr struct ice_vf *vf = &pf->vf[i]; 3075b6b0501dSPaul M Stillwell Jr 3076da62c5ffSQi Zhang if (i != vsi->vf_id && vf->ctrl_vsi_idx != ICE_NO_VSI) 3077da62c5ffSQi Zhang break; 3078da62c5ffSQi Zhang } 3079da62c5ffSQi Zhang if (i == pf->num_alloc_vfs) { 3080da62c5ffSQi Zhang /* No other VFs left that have control VSI, reclaim SW 3081da62c5ffSQi Zhang * interrupts back to the common pool 3082da62c5ffSQi Zhang */ 3083da62c5ffSQi Zhang ice_free_res(pf->irq_tracker, vsi->base_vector, 3084da62c5ffSQi Zhang ICE_RES_VF_CTRL_VEC_ID); 3085da62c5ffSQi Zhang pf->num_avail_sw_msix += vsi->num_q_vectors; 3086da62c5ffSQi Zhang } 3087da62c5ffSQi Zhang } else if (vsi->type != ICE_VSI_VF) { 30888ede0178SAnirudh Venkataramanan /* reclaim SW interrupts back to the common pool */ 3089cbe66bfeSBrett Creeley ice_free_res(pf->irq_tracker, vsi->base_vector, vsi->idx); 3090eb0208ecSPreethi Banala pf->num_avail_sw_msix += vsi->num_q_vectors; 30918ede0178SAnirudh Venkataramanan } 3092df0f8479SAnirudh Venkataramanan 3093462acf6aSTony Nguyen if (!ice_is_safe_mode(pf)) { 30942e0e6228SDave Ertman if (vsi->type == ICE_VSI_PF) { 30951b8f15b6SMichal Swiatkowski ice_fltr_remove_eth(vsi, ETH_P_PAUSE, ICE_FLTR_TX, 30961b8f15b6SMichal Swiatkowski ICE_DROP_PACKET); 30972e0e6228SDave Ertman ice_cfg_sw_lldp(vsi, true, false); 30982e0e6228SDave Ertman /* The Rx rule will only exist to remove if the LLDP FW 30992e0e6228SDave Ertman * engine is currently stopped 31002e0e6228SDave Ertman */ 310184a118abSDave Ertman if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags)) 31022e0e6228SDave Ertman ice_cfg_sw_lldp(vsi, false, false); 31032e0e6228SDave Ertman } 3104462acf6aSTony Nguyen } 3105d95276ceSAkeem G Abodunrin 31061b8f15b6SMichal Swiatkowski ice_fltr_remove_all(vsi); 310710e03a22SAnirudh Venkataramanan ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx); 3108df0f8479SAnirudh Venkataramanan ice_vsi_delete(vsi); 3109df0f8479SAnirudh Venkataramanan ice_vsi_free_q_vectors(vsi); 3110aa6ccf3fSBrett Creeley 3111a476d72aSAnirudh Venkataramanan if (vsi->netdev) { 3112a476d72aSAnirudh Venkataramanan if (test_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state)) { 3113a476d72aSAnirudh Venkataramanan unregister_netdev(vsi->netdev); 3114a476d72aSAnirudh Venkataramanan clear_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state); 3115a476d72aSAnirudh Venkataramanan } 3116a476d72aSAnirudh Venkataramanan if (test_bit(ICE_VSI_NETDEV_ALLOCD, vsi->state)) { 3117aa6ccf3fSBrett Creeley free_netdev(vsi->netdev); 3118aa6ccf3fSBrett Creeley vsi->netdev = NULL; 3119a476d72aSAnirudh Venkataramanan clear_bit(ICE_VSI_NETDEV_ALLOCD, vsi->state); 3120a476d72aSAnirudh Venkataramanan } 3121aa6ccf3fSBrett Creeley } 3122aa6ccf3fSBrett Creeley 3123b126bd6bSKiran Patil if (vsi->type == ICE_VSI_VF && 3124b126bd6bSKiran Patil vsi->agg_node && vsi->agg_node->valid) 3125b126bd6bSKiran Patil vsi->agg_node->num_vsis--; 3126df0f8479SAnirudh Venkataramanan ice_vsi_clear_rings(vsi); 3127df0f8479SAnirudh Venkataramanan 3128df0f8479SAnirudh Venkataramanan ice_vsi_put_qs(vsi); 3129df0f8479SAnirudh Venkataramanan 3130df0f8479SAnirudh Venkataramanan /* retain SW VSI data structure since it is needed to unregister and 3131df0f8479SAnirudh Venkataramanan * free VSI netdev when PF is not in reset recovery pending state,\ 3132df0f8479SAnirudh Venkataramanan * for ex: during rmmod. 3133df0f8479SAnirudh Venkataramanan */ 31345df7e45dSDave Ertman if (!ice_is_reset_in_progress(pf->state)) 3135df0f8479SAnirudh Venkataramanan ice_vsi_clear(vsi); 3136df0f8479SAnirudh Venkataramanan 3137df0f8479SAnirudh Venkataramanan return 0; 3138df0f8479SAnirudh Venkataramanan } 3139df0f8479SAnirudh Venkataramanan 3140df0f8479SAnirudh Venkataramanan /** 314161dc79ceSMichal Swiatkowski * ice_vsi_rebuild_get_coalesce - get coalesce from all q_vectors 314261dc79ceSMichal Swiatkowski * @vsi: VSI connected with q_vectors 314361dc79ceSMichal Swiatkowski * @coalesce: array of struct with stored coalesce 314461dc79ceSMichal Swiatkowski * 314561dc79ceSMichal Swiatkowski * Returns array size. 314661dc79ceSMichal Swiatkowski */ 314761dc79ceSMichal Swiatkowski static int 314861dc79ceSMichal Swiatkowski ice_vsi_rebuild_get_coalesce(struct ice_vsi *vsi, 314961dc79ceSMichal Swiatkowski struct ice_coalesce_stored *coalesce) 315061dc79ceSMichal Swiatkowski { 315161dc79ceSMichal Swiatkowski int i; 315261dc79ceSMichal Swiatkowski 315361dc79ceSMichal Swiatkowski ice_for_each_q_vector(vsi, i) { 315461dc79ceSMichal Swiatkowski struct ice_q_vector *q_vector = vsi->q_vectors[i]; 315561dc79ceSMichal Swiatkowski 315661dc79ceSMichal Swiatkowski coalesce[i].itr_tx = q_vector->tx.itr_setting; 315761dc79ceSMichal Swiatkowski coalesce[i].itr_rx = q_vector->rx.itr_setting; 315861dc79ceSMichal Swiatkowski coalesce[i].intrl = q_vector->intrl; 31592ec56385SPaul M Stillwell Jr 31602ec56385SPaul M Stillwell Jr if (i < vsi->num_txq) 31612ec56385SPaul M Stillwell Jr coalesce[i].tx_valid = true; 31622ec56385SPaul M Stillwell Jr if (i < vsi->num_rxq) 31632ec56385SPaul M Stillwell Jr coalesce[i].rx_valid = true; 316461dc79ceSMichal Swiatkowski } 316561dc79ceSMichal Swiatkowski 316661dc79ceSMichal Swiatkowski return vsi->num_q_vectors; 316761dc79ceSMichal Swiatkowski } 316861dc79ceSMichal Swiatkowski 316961dc79ceSMichal Swiatkowski /** 317061dc79ceSMichal Swiatkowski * ice_vsi_rebuild_set_coalesce - set coalesce from earlier saved arrays 317161dc79ceSMichal Swiatkowski * @vsi: VSI connected with q_vectors 317261dc79ceSMichal Swiatkowski * @coalesce: pointer to array of struct with stored coalesce 317361dc79ceSMichal Swiatkowski * @size: size of coalesce array 317461dc79ceSMichal Swiatkowski * 317561dc79ceSMichal Swiatkowski * Before this function, ice_vsi_rebuild_get_coalesce should be called to save 317661dc79ceSMichal Swiatkowski * ITR params in arrays. If size is 0 or coalesce wasn't stored set coalesce 317761dc79ceSMichal Swiatkowski * to default value. 317861dc79ceSMichal Swiatkowski */ 317961dc79ceSMichal Swiatkowski static void 318061dc79ceSMichal Swiatkowski ice_vsi_rebuild_set_coalesce(struct ice_vsi *vsi, 318161dc79ceSMichal Swiatkowski struct ice_coalesce_stored *coalesce, int size) 318261dc79ceSMichal Swiatkowski { 3183b8b47723SJesse Brandeburg struct ice_ring_container *rc; 318461dc79ceSMichal Swiatkowski int i; 318561dc79ceSMichal Swiatkowski 318661dc79ceSMichal Swiatkowski if ((size && !coalesce) || !vsi) 318761dc79ceSMichal Swiatkowski return; 318861dc79ceSMichal Swiatkowski 31892ec56385SPaul M Stillwell Jr /* There are a couple of cases that have to be handled here: 31902ec56385SPaul M Stillwell Jr * 1. The case where the number of queue vectors stays the same, but 31912ec56385SPaul M Stillwell Jr * the number of Tx or Rx rings changes (the first for loop) 31922ec56385SPaul M Stillwell Jr * 2. The case where the number of queue vectors increased (the 31932ec56385SPaul M Stillwell Jr * second for loop) 3194a039f6fcSBrett Creeley */ 31952ec56385SPaul M Stillwell Jr for (i = 0; i < size && i < vsi->num_q_vectors; i++) { 31962ec56385SPaul M Stillwell Jr /* There are 2 cases to handle here and they are the same for 31972ec56385SPaul M Stillwell Jr * both Tx and Rx: 31982ec56385SPaul M Stillwell Jr * if the entry was valid previously (coalesce[i].[tr]x_valid 31992ec56385SPaul M Stillwell Jr * and the loop variable is less than the number of rings 32002ec56385SPaul M Stillwell Jr * allocated, then write the previous values 32012ec56385SPaul M Stillwell Jr * 32022ec56385SPaul M Stillwell Jr * if the entry was not valid previously, but the number of 32032ec56385SPaul M Stillwell Jr * rings is less than are allocated (this means the number of 32042ec56385SPaul M Stillwell Jr * rings increased from previously), then write out the 32052ec56385SPaul M Stillwell Jr * values in the first element 3206b8b47723SJesse Brandeburg * 3207b8b47723SJesse Brandeburg * Also, always write the ITR, even if in ITR_IS_DYNAMIC 3208b8b47723SJesse Brandeburg * as there is no harm because the dynamic algorithm 3209b8b47723SJesse Brandeburg * will just overwrite. 32102ec56385SPaul M Stillwell Jr */ 3211b8b47723SJesse Brandeburg if (i < vsi->alloc_rxq && coalesce[i].rx_valid) { 3212b8b47723SJesse Brandeburg rc = &vsi->q_vectors[i]->rx; 3213b8b47723SJesse Brandeburg rc->itr_setting = coalesce[i].itr_rx; 3214b8b47723SJesse Brandeburg ice_write_itr(rc, rc->itr_setting); 3215b8b47723SJesse Brandeburg } else if (i < vsi->alloc_rxq) { 3216b8b47723SJesse Brandeburg rc = &vsi->q_vectors[i]->rx; 3217b8b47723SJesse Brandeburg rc->itr_setting = coalesce[0].itr_rx; 3218b8b47723SJesse Brandeburg ice_write_itr(rc, rc->itr_setting); 3219b8b47723SJesse Brandeburg } 32202ec56385SPaul M Stillwell Jr 3221b8b47723SJesse Brandeburg if (i < vsi->alloc_txq && coalesce[i].tx_valid) { 3222b8b47723SJesse Brandeburg rc = &vsi->q_vectors[i]->tx; 3223b8b47723SJesse Brandeburg rc->itr_setting = coalesce[i].itr_tx; 3224b8b47723SJesse Brandeburg ice_write_itr(rc, rc->itr_setting); 3225b8b47723SJesse Brandeburg } else if (i < vsi->alloc_txq) { 3226b8b47723SJesse Brandeburg rc = &vsi->q_vectors[i]->tx; 3227b8b47723SJesse Brandeburg rc->itr_setting = coalesce[0].itr_tx; 3228b8b47723SJesse Brandeburg ice_write_itr(rc, rc->itr_setting); 3229b8b47723SJesse Brandeburg } 32302ec56385SPaul M Stillwell Jr 3231b8b47723SJesse Brandeburg vsi->q_vectors[i]->intrl = coalesce[i].intrl; 3232d16a4f45SJesse Brandeburg ice_set_q_vector_intrl(vsi->q_vectors[i]); 32332ec56385SPaul M Stillwell Jr } 32342ec56385SPaul M Stillwell Jr 32352ec56385SPaul M Stillwell Jr /* the number of queue vectors increased so write whatever is in 32362ec56385SPaul M Stillwell Jr * the first element 32372ec56385SPaul M Stillwell Jr */ 32382ec56385SPaul M Stillwell Jr for (; i < vsi->num_q_vectors; i++) { 3239b8b47723SJesse Brandeburg /* transmit */ 3240b8b47723SJesse Brandeburg rc = &vsi->q_vectors[i]->tx; 3241b8b47723SJesse Brandeburg rc->itr_setting = coalesce[0].itr_tx; 3242b8b47723SJesse Brandeburg ice_write_itr(rc, rc->itr_setting); 3243b8b47723SJesse Brandeburg 3244b8b47723SJesse Brandeburg /* receive */ 3245b8b47723SJesse Brandeburg rc = &vsi->q_vectors[i]->rx; 3246b8b47723SJesse Brandeburg rc->itr_setting = coalesce[0].itr_rx; 3247b8b47723SJesse Brandeburg ice_write_itr(rc, rc->itr_setting); 3248b8b47723SJesse Brandeburg 3249b8b47723SJesse Brandeburg vsi->q_vectors[i]->intrl = coalesce[0].intrl; 3250d16a4f45SJesse Brandeburg ice_set_q_vector_intrl(vsi->q_vectors[i]); 32512ec56385SPaul M Stillwell Jr } 325261dc79ceSMichal Swiatkowski } 325361dc79ceSMichal Swiatkowski 325461dc79ceSMichal Swiatkowski /** 3255df0f8479SAnirudh Venkataramanan * ice_vsi_rebuild - Rebuild VSI after reset 3256df0f8479SAnirudh Venkataramanan * @vsi: VSI to be rebuild 325787324e74SHenry Tieman * @init_vsi: is this an initialization or a reconfigure of the VSI 3258df0f8479SAnirudh Venkataramanan * 3259df0f8479SAnirudh Venkataramanan * Returns 0 on success and negative value on failure 3260df0f8479SAnirudh Venkataramanan */ 326187324e74SHenry Tieman int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi) 3262df0f8479SAnirudh Venkataramanan { 3263df0f8479SAnirudh Venkataramanan u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 }; 326461dc79ceSMichal Swiatkowski struct ice_coalesce_stored *coalesce; 326561dc79ceSMichal Swiatkowski int prev_num_q_vectors = 0; 32667eeac889SAkeem G Abodunrin struct ice_vf *vf = NULL; 326758623c52SJesse Brandeburg enum ice_vsi_type vtype; 3268d31530e8SAkeem G Abodunrin enum ice_status status; 3269c5a2a4a3SUsha Ketineni struct ice_pf *pf; 3270df0f8479SAnirudh Venkataramanan int ret, i; 3271df0f8479SAnirudh Venkataramanan 3272df0f8479SAnirudh Venkataramanan if (!vsi) 3273df0f8479SAnirudh Venkataramanan return -EINVAL; 3274df0f8479SAnirudh Venkataramanan 3275c5a2a4a3SUsha Ketineni pf = vsi->back; 327658623c52SJesse Brandeburg vtype = vsi->type; 327758623c52SJesse Brandeburg if (vtype == ICE_VSI_VF) 32787eeac889SAkeem G Abodunrin vf = &pf->vf[vsi->vf_id]; 32797eeac889SAkeem G Abodunrin 328061dc79ceSMichal Swiatkowski coalesce = kcalloc(vsi->num_q_vectors, 328161dc79ceSMichal Swiatkowski sizeof(struct ice_coalesce_stored), GFP_KERNEL); 32822ec56385SPaul M Stillwell Jr if (!coalesce) 32832ec56385SPaul M Stillwell Jr return -ENOMEM; 32842ec56385SPaul M Stillwell Jr 32852ec56385SPaul M Stillwell Jr prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi, coalesce); 32862ec56385SPaul M Stillwell Jr 328747e3e53cSHenry Tieman ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx); 3288df0f8479SAnirudh Venkataramanan ice_vsi_free_q_vectors(vsi); 32897eeac889SAkeem G Abodunrin 3290cbe66bfeSBrett Creeley /* SR-IOV determines needed MSIX resources all at once instead of per 3291cbe66bfeSBrett Creeley * VSI since when VFs are spawned we know how many VFs there are and how 3292cbe66bfeSBrett Creeley * many interrupts each VF needs. SR-IOV MSIX resources are also 3293cbe66bfeSBrett Creeley * cleared in the same manner. 3294cbe66bfeSBrett Creeley */ 329558623c52SJesse Brandeburg if (vtype != ICE_VSI_VF) { 32967eeac889SAkeem G Abodunrin /* reclaim SW interrupts back to the common pool */ 3297cbe66bfeSBrett Creeley ice_free_res(pf->irq_tracker, vsi->base_vector, vsi->idx); 32987eeac889SAkeem G Abodunrin pf->num_avail_sw_msix += vsi->num_q_vectors; 3299cbe66bfeSBrett Creeley vsi->base_vector = 0; 33007eeac889SAkeem G Abodunrin } 33017eeac889SAkeem G Abodunrin 3302efc2214bSMaciej Fijalkowski if (ice_is_xdp_ena_vsi(vsi)) 3303efc2214bSMaciej Fijalkowski /* return value check can be skipped here, it always returns 3304efc2214bSMaciej Fijalkowski * 0 if reset is in progress 3305efc2214bSMaciej Fijalkowski */ 3306efc2214bSMaciej Fijalkowski ice_destroy_xdp_rings(vsi); 330778b5713aSAnirudh Venkataramanan ice_vsi_put_qs(vsi); 3308df0f8479SAnirudh Venkataramanan ice_vsi_clear_rings(vsi); 3309a85a3847SBrett Creeley ice_vsi_free_arrays(vsi); 331058623c52SJesse Brandeburg if (vtype == ICE_VSI_VF) 33115743020dSAkeem G Abodunrin ice_vsi_set_num_qs(vsi, vf->vf_id); 33125743020dSAkeem G Abodunrin else 33135743020dSAkeem G Abodunrin ice_vsi_set_num_qs(vsi, ICE_INVAL_VFID); 331478b5713aSAnirudh Venkataramanan 331578b5713aSAnirudh Venkataramanan ret = ice_vsi_alloc_arrays(vsi); 331678b5713aSAnirudh Venkataramanan if (ret < 0) 331778b5713aSAnirudh Venkataramanan goto err_vsi; 331878b5713aSAnirudh Venkataramanan 331978b5713aSAnirudh Venkataramanan ice_vsi_get_qs(vsi); 332083af0039SHenry Tieman 332183af0039SHenry Tieman ice_alloc_fd_res(vsi); 3322c5a2a4a3SUsha Ketineni ice_vsi_set_tc_cfg(vsi); 3323df0f8479SAnirudh Venkataramanan 3324df0f8479SAnirudh Venkataramanan /* Initialize VSI struct elements and create VSI in FW */ 332587324e74SHenry Tieman ret = ice_vsi_init(vsi, init_vsi); 3326df0f8479SAnirudh Venkataramanan if (ret < 0) 3327df0f8479SAnirudh Venkataramanan goto err_vsi; 3328df0f8479SAnirudh Venkataramanan 332958623c52SJesse Brandeburg switch (vtype) { 333083af0039SHenry Tieman case ICE_VSI_CTRL: 3331f66756e0SGrzegorz Nitka case ICE_VSI_SWITCHDEV_CTRL: 3332df0f8479SAnirudh Venkataramanan case ICE_VSI_PF: 3333df0f8479SAnirudh Venkataramanan ret = ice_vsi_alloc_q_vectors(vsi); 3334df0f8479SAnirudh Venkataramanan if (ret) 3335df0f8479SAnirudh Venkataramanan goto err_rings; 3336df0f8479SAnirudh Venkataramanan 333717bc6d07STony Nguyen ret = ice_vsi_setup_vector_base(vsi); 333817bc6d07STony Nguyen if (ret) 333917bc6d07STony Nguyen goto err_vectors; 334017bc6d07STony Nguyen 3341b07833a0SBrett Creeley ret = ice_vsi_set_q_vectors_reg_idx(vsi); 3342b07833a0SBrett Creeley if (ret) 3343b07833a0SBrett Creeley goto err_vectors; 3344b07833a0SBrett Creeley 3345df0f8479SAnirudh Venkataramanan ret = ice_vsi_alloc_rings(vsi); 3346df0f8479SAnirudh Venkataramanan if (ret) 3347df0f8479SAnirudh Venkataramanan goto err_vectors; 3348df0f8479SAnirudh Venkataramanan 3349df0f8479SAnirudh Venkataramanan ice_vsi_map_rings_to_vectors(vsi); 3350efc2214bSMaciej Fijalkowski if (ice_is_xdp_ena_vsi(vsi)) { 335122bf877eSMaciej Fijalkowski ret = ice_vsi_determine_xdp_res(vsi); 335222bf877eSMaciej Fijalkowski if (ret) 335322bf877eSMaciej Fijalkowski goto err_vectors; 3354efc2214bSMaciej Fijalkowski ret = ice_prepare_xdp_rings(vsi, vsi->xdp_prog); 3355efc2214bSMaciej Fijalkowski if (ret) 3356efc2214bSMaciej Fijalkowski goto err_vectors; 3357efc2214bSMaciej Fijalkowski } 335883af0039SHenry Tieman /* ICE_VSI_CTRL does not need RSS so skip RSS processing */ 335958623c52SJesse Brandeburg if (vtype != ICE_VSI_CTRL) 336083af0039SHenry Tieman /* Do not exit if configuring RSS had an issue, at 336183af0039SHenry Tieman * least receive traffic on first queue. Hence no 336283af0039SHenry Tieman * need to capture return value 336327a98affSMd Fahad Iqbal Polash */ 3364819d8998SJesse Brandeburg if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) 336527a98affSMd Fahad Iqbal Polash ice_vsi_cfg_rss_lut_key(vsi); 3366df0f8479SAnirudh Venkataramanan break; 33678ede0178SAnirudh Venkataramanan case ICE_VSI_VF: 33688ede0178SAnirudh Venkataramanan ret = ice_vsi_alloc_q_vectors(vsi); 33698ede0178SAnirudh Venkataramanan if (ret) 33708ede0178SAnirudh Venkataramanan goto err_rings; 33718ede0178SAnirudh Venkataramanan 3372b07833a0SBrett Creeley ret = ice_vsi_set_q_vectors_reg_idx(vsi); 3373b07833a0SBrett Creeley if (ret) 3374b07833a0SBrett Creeley goto err_vectors; 3375b07833a0SBrett Creeley 33768ede0178SAnirudh Venkataramanan ret = ice_vsi_alloc_rings(vsi); 33778ede0178SAnirudh Venkataramanan if (ret) 33788ede0178SAnirudh Venkataramanan goto err_vectors; 33798ede0178SAnirudh Venkataramanan 33808ede0178SAnirudh Venkataramanan break; 3381*0754d65bSKiran Patil case ICE_VSI_CHNL: 3382*0754d65bSKiran Patil if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 3383*0754d65bSKiran Patil ice_vsi_cfg_rss_lut_key(vsi); 3384*0754d65bSKiran Patil ice_vsi_set_rss_flow_fld(vsi); 3385*0754d65bSKiran Patil } 3386*0754d65bSKiran Patil break; 3387df0f8479SAnirudh Venkataramanan default: 3388df0f8479SAnirudh Venkataramanan break; 3389df0f8479SAnirudh Venkataramanan } 3390df0f8479SAnirudh Venkataramanan 3391df0f8479SAnirudh Venkataramanan /* configure VSI nodes based on number of queues and TC's */ 3392efc2214bSMaciej Fijalkowski for (i = 0; i < vsi->tc_cfg.numtc; i++) { 3393*0754d65bSKiran Patil /* configure VSI nodes based on number of queues and TC's. 3394*0754d65bSKiran Patil * ADQ creates VSIs for each TC/Channel but doesn't 3395*0754d65bSKiran Patil * allocate queues instead it reconfigures the PF queues 3396*0754d65bSKiran Patil * as per the TC command. So max_txqs should point to the 3397*0754d65bSKiran Patil * PF Tx queues. 3398*0754d65bSKiran Patil */ 3399*0754d65bSKiran Patil if (vtype == ICE_VSI_CHNL) 3400*0754d65bSKiran Patil max_txqs[i] = pf->num_lan_tx; 3401*0754d65bSKiran Patil else 3402d5a46359SAkeem G Abodunrin max_txqs[i] = vsi->alloc_txq; 3403df0f8479SAnirudh Venkataramanan 3404efc2214bSMaciej Fijalkowski if (ice_is_xdp_ena_vsi(vsi)) 3405efc2214bSMaciej Fijalkowski max_txqs[i] += vsi->num_xdp_txq; 3406efc2214bSMaciej Fijalkowski } 3407efc2214bSMaciej Fijalkowski 3408*0754d65bSKiran Patil if (test_bit(ICE_FLAG_TC_MQPRIO, pf->flags)) 3409*0754d65bSKiran Patil /* If MQPRIO is set, means channel code path, hence for main 3410*0754d65bSKiran Patil * VSI's, use TC as 1 3411*0754d65bSKiran Patil */ 3412*0754d65bSKiran Patil status = ice_cfg_vsi_lan(vsi->port_info, vsi->idx, 1, max_txqs); 3413*0754d65bSKiran Patil else 3414*0754d65bSKiran Patil status = ice_cfg_vsi_lan(vsi->port_info, vsi->idx, 3415*0754d65bSKiran Patil vsi->tc_cfg.ena_tc, max_txqs); 3416*0754d65bSKiran Patil 3417d31530e8SAkeem G Abodunrin if (status) { 34180fee3577SLihong Yang dev_err(ice_pf_to_dev(pf), "VSI %d failed lan queue config, error %s\n", 34190fee3577SLihong Yang vsi->vsi_num, ice_stat_str(status)); 342087324e74SHenry Tieman if (init_vsi) { 342187324e74SHenry Tieman ret = -EIO; 3422df0f8479SAnirudh Venkataramanan goto err_vectors; 342387324e74SHenry Tieman } else { 342487324e74SHenry Tieman return ice_schedule_reset(pf, ICE_RESET_PFR); 342587324e74SHenry Tieman } 3426df0f8479SAnirudh Venkataramanan } 342761dc79ceSMichal Swiatkowski ice_vsi_rebuild_set_coalesce(vsi, coalesce, prev_num_q_vectors); 342861dc79ceSMichal Swiatkowski kfree(coalesce); 342961dc79ceSMichal Swiatkowski 3430df0f8479SAnirudh Venkataramanan return 0; 3431df0f8479SAnirudh Venkataramanan 3432df0f8479SAnirudh Venkataramanan err_vectors: 3433df0f8479SAnirudh Venkataramanan ice_vsi_free_q_vectors(vsi); 3434df0f8479SAnirudh Venkataramanan err_rings: 3435df0f8479SAnirudh Venkataramanan if (vsi->netdev) { 3436df0f8479SAnirudh Venkataramanan vsi->current_netdev_flags = 0; 3437df0f8479SAnirudh Venkataramanan unregister_netdev(vsi->netdev); 3438df0f8479SAnirudh Venkataramanan free_netdev(vsi->netdev); 3439df0f8479SAnirudh Venkataramanan vsi->netdev = NULL; 3440df0f8479SAnirudh Venkataramanan } 3441df0f8479SAnirudh Venkataramanan err_vsi: 3442df0f8479SAnirudh Venkataramanan ice_vsi_clear(vsi); 34437e408e07SAnirudh Venkataramanan set_bit(ICE_RESET_FAILED, pf->state); 344461dc79ceSMichal Swiatkowski kfree(coalesce); 3445df0f8479SAnirudh Venkataramanan return ret; 3446df0f8479SAnirudh Venkataramanan } 3447df0f8479SAnirudh Venkataramanan 3448df0f8479SAnirudh Venkataramanan /** 34495df7e45dSDave Ertman * ice_is_reset_in_progress - check for a reset in progress 34502f2da36eSAnirudh Venkataramanan * @state: PF state field 34515153a18eSAnirudh Venkataramanan */ 34525df7e45dSDave Ertman bool ice_is_reset_in_progress(unsigned long *state) 34535153a18eSAnirudh Venkataramanan { 34547e408e07SAnirudh Venkataramanan return test_bit(ICE_RESET_OICR_RECV, state) || 34557e408e07SAnirudh Venkataramanan test_bit(ICE_PFR_REQ, state) || 34567e408e07SAnirudh Venkataramanan test_bit(ICE_CORER_REQ, state) || 34577e408e07SAnirudh Venkataramanan test_bit(ICE_GLOBR_REQ, state); 34585153a18eSAnirudh Venkataramanan } 34597b9ffc76SAnirudh Venkataramanan 34601c08052eSJacob Keller /** 34611c08052eSJacob Keller * ice_wait_for_reset - Wait for driver to finish reset and rebuild 34621c08052eSJacob Keller * @pf: pointer to the PF structure 34631c08052eSJacob Keller * @timeout: length of time to wait, in jiffies 34641c08052eSJacob Keller * 34651c08052eSJacob Keller * Wait (sleep) for a short time until the driver finishes cleaning up from 34661c08052eSJacob Keller * a device reset. The caller must be able to sleep. Use this to delay 34671c08052eSJacob Keller * operations that could fail while the driver is cleaning up after a device 34681c08052eSJacob Keller * reset. 34691c08052eSJacob Keller * 34701c08052eSJacob Keller * Returns 0 on success, -EBUSY if the reset is not finished within the 34711c08052eSJacob Keller * timeout, and -ERESTARTSYS if the thread was interrupted. 34721c08052eSJacob Keller */ 34731c08052eSJacob Keller int ice_wait_for_reset(struct ice_pf *pf, unsigned long timeout) 34741c08052eSJacob Keller { 34751c08052eSJacob Keller long ret; 34761c08052eSJacob Keller 34771c08052eSJacob Keller ret = wait_event_interruptible_timeout(pf->reset_wait_queue, 34781c08052eSJacob Keller !ice_is_reset_in_progress(pf->state), 34791c08052eSJacob Keller timeout); 34801c08052eSJacob Keller if (ret < 0) 34811c08052eSJacob Keller return ret; 34821c08052eSJacob Keller else if (!ret) 34831c08052eSJacob Keller return -EBUSY; 34841c08052eSJacob Keller else 34851c08052eSJacob Keller return 0; 34861c08052eSJacob Keller } 34871c08052eSJacob Keller 34887b9ffc76SAnirudh Venkataramanan /** 34897b9ffc76SAnirudh Venkataramanan * ice_vsi_update_q_map - update our copy of the VSI info with new queue map 34907b9ffc76SAnirudh Venkataramanan * @vsi: VSI being configured 34917b9ffc76SAnirudh Venkataramanan * @ctx: the context buffer returned from AQ VSI update command 34927b9ffc76SAnirudh Venkataramanan */ 34937b9ffc76SAnirudh Venkataramanan static void ice_vsi_update_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctx) 34947b9ffc76SAnirudh Venkataramanan { 34957b9ffc76SAnirudh Venkataramanan vsi->info.mapping_flags = ctx->info.mapping_flags; 34967b9ffc76SAnirudh Venkataramanan memcpy(&vsi->info.q_mapping, &ctx->info.q_mapping, 34977b9ffc76SAnirudh Venkataramanan sizeof(vsi->info.q_mapping)); 34987b9ffc76SAnirudh Venkataramanan memcpy(&vsi->info.tc_mapping, ctx->info.tc_mapping, 34997b9ffc76SAnirudh Venkataramanan sizeof(vsi->info.tc_mapping)); 35007b9ffc76SAnirudh Venkataramanan } 35017b9ffc76SAnirudh Venkataramanan 35027b9ffc76SAnirudh Venkataramanan /** 3503*0754d65bSKiran Patil * ice_vsi_cfg_netdev_tc - Setup the netdev TC configuration 3504*0754d65bSKiran Patil * @vsi: the VSI being configured 3505*0754d65bSKiran Patil * @ena_tc: TC map to be enabled 3506*0754d65bSKiran Patil */ 3507*0754d65bSKiran Patil void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc) 3508*0754d65bSKiran Patil { 3509*0754d65bSKiran Patil struct net_device *netdev = vsi->netdev; 3510*0754d65bSKiran Patil struct ice_pf *pf = vsi->back; 3511*0754d65bSKiran Patil int numtc = vsi->tc_cfg.numtc; 3512*0754d65bSKiran Patil struct ice_dcbx_cfg *dcbcfg; 3513*0754d65bSKiran Patil u8 netdev_tc; 3514*0754d65bSKiran Patil int i; 3515*0754d65bSKiran Patil 3516*0754d65bSKiran Patil if (!netdev) 3517*0754d65bSKiran Patil return; 3518*0754d65bSKiran Patil 3519*0754d65bSKiran Patil /* CHNL VSI doesn't have it's own netdev, hence, no netdev_tc */ 3520*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL) 3521*0754d65bSKiran Patil return; 3522*0754d65bSKiran Patil 3523*0754d65bSKiran Patil if (!ena_tc) { 3524*0754d65bSKiran Patil netdev_reset_tc(netdev); 3525*0754d65bSKiran Patil return; 3526*0754d65bSKiran Patil } 3527*0754d65bSKiran Patil 3528*0754d65bSKiran Patil if (vsi->type == ICE_VSI_PF && ice_is_adq_active(pf)) 3529*0754d65bSKiran Patil numtc = vsi->all_numtc; 3530*0754d65bSKiran Patil 3531*0754d65bSKiran Patil if (netdev_set_num_tc(netdev, numtc)) 3532*0754d65bSKiran Patil return; 3533*0754d65bSKiran Patil 3534*0754d65bSKiran Patil dcbcfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; 3535*0754d65bSKiran Patil 3536*0754d65bSKiran Patil ice_for_each_traffic_class(i) 3537*0754d65bSKiran Patil if (vsi->tc_cfg.ena_tc & BIT(i)) 3538*0754d65bSKiran Patil netdev_set_tc_queue(netdev, 3539*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].netdev_tc, 3540*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].qcount_tx, 3541*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].qoffset); 3542*0754d65bSKiran Patil /* setup TC queue map for CHNL TCs */ 3543*0754d65bSKiran Patil ice_for_each_chnl_tc(i) { 3544*0754d65bSKiran Patil if (!(vsi->all_enatc & BIT(i))) 3545*0754d65bSKiran Patil break; 3546*0754d65bSKiran Patil if (!vsi->mqprio_qopt.qopt.count[i]) 3547*0754d65bSKiran Patil break; 3548*0754d65bSKiran Patil netdev_set_tc_queue(netdev, i, 3549*0754d65bSKiran Patil vsi->mqprio_qopt.qopt.count[i], 3550*0754d65bSKiran Patil vsi->mqprio_qopt.qopt.offset[i]); 3551*0754d65bSKiran Patil } 3552*0754d65bSKiran Patil 3553*0754d65bSKiran Patil if (test_bit(ICE_FLAG_TC_MQPRIO, pf->flags)) 3554*0754d65bSKiran Patil return; 3555*0754d65bSKiran Patil 3556*0754d65bSKiran Patil for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) { 3557*0754d65bSKiran Patil u8 ets_tc = dcbcfg->etscfg.prio_table[i]; 3558*0754d65bSKiran Patil 3559*0754d65bSKiran Patil /* Get the mapped netdev TC# for the UP */ 3560*0754d65bSKiran Patil netdev_tc = vsi->tc_cfg.tc_info[ets_tc].netdev_tc; 3561*0754d65bSKiran Patil netdev_set_prio_tc_map(netdev, i, netdev_tc); 3562*0754d65bSKiran Patil } 3563*0754d65bSKiran Patil } 3564*0754d65bSKiran Patil 3565*0754d65bSKiran Patil /** 3566*0754d65bSKiran Patil * ice_vsi_setup_q_map_mqprio - Prepares mqprio based tc_config 3567*0754d65bSKiran Patil * @vsi: the VSI being configured, 3568*0754d65bSKiran Patil * @ctxt: VSI context structure 3569*0754d65bSKiran Patil * @ena_tc: number of traffic classes to enable 3570*0754d65bSKiran Patil * 3571*0754d65bSKiran Patil * Prepares VSI tc_config to have queue configurations based on MQPRIO options. 3572*0754d65bSKiran Patil */ 3573*0754d65bSKiran Patil static void 3574*0754d65bSKiran Patil ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt, 3575*0754d65bSKiran Patil u8 ena_tc) 3576*0754d65bSKiran Patil { 3577*0754d65bSKiran Patil u16 pow, offset = 0, qcount_tx = 0, qcount_rx = 0, qmap; 3578*0754d65bSKiran Patil u16 tc0_offset = vsi->mqprio_qopt.qopt.offset[0]; 3579*0754d65bSKiran Patil int tc0_qcount = vsi->mqprio_qopt.qopt.count[0]; 3580*0754d65bSKiran Patil u8 netdev_tc = 0; 3581*0754d65bSKiran Patil int i; 3582*0754d65bSKiran Patil 3583*0754d65bSKiran Patil vsi->tc_cfg.ena_tc = ena_tc ? ena_tc : 1; 3584*0754d65bSKiran Patil 3585*0754d65bSKiran Patil pow = order_base_2(tc0_qcount); 3586*0754d65bSKiran Patil qmap = ((tc0_offset << ICE_AQ_VSI_TC_Q_OFFSET_S) & 3587*0754d65bSKiran Patil ICE_AQ_VSI_TC_Q_OFFSET_M) | 3588*0754d65bSKiran Patil ((pow << ICE_AQ_VSI_TC_Q_NUM_S) & ICE_AQ_VSI_TC_Q_NUM_M); 3589*0754d65bSKiran Patil 3590*0754d65bSKiran Patil ice_for_each_traffic_class(i) { 3591*0754d65bSKiran Patil if (!(vsi->tc_cfg.ena_tc & BIT(i))) { 3592*0754d65bSKiran Patil /* TC is not enabled */ 3593*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].qoffset = 0; 3594*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].qcount_rx = 1; 3595*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].qcount_tx = 1; 3596*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].netdev_tc = 0; 3597*0754d65bSKiran Patil ctxt->info.tc_mapping[i] = 0; 3598*0754d65bSKiran Patil continue; 3599*0754d65bSKiran Patil } 3600*0754d65bSKiran Patil 3601*0754d65bSKiran Patil offset = vsi->mqprio_qopt.qopt.offset[i]; 3602*0754d65bSKiran Patil qcount_rx = vsi->mqprio_qopt.qopt.count[i]; 3603*0754d65bSKiran Patil qcount_tx = vsi->mqprio_qopt.qopt.count[i]; 3604*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].qoffset = offset; 3605*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].qcount_rx = qcount_rx; 3606*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].qcount_tx = qcount_tx; 3607*0754d65bSKiran Patil vsi->tc_cfg.tc_info[i].netdev_tc = netdev_tc++; 3608*0754d65bSKiran Patil } 3609*0754d65bSKiran Patil 3610*0754d65bSKiran Patil if (vsi->all_numtc && vsi->all_numtc != vsi->tc_cfg.numtc) { 3611*0754d65bSKiran Patil ice_for_each_chnl_tc(i) { 3612*0754d65bSKiran Patil if (!(vsi->all_enatc & BIT(i))) 3613*0754d65bSKiran Patil continue; 3614*0754d65bSKiran Patil offset = vsi->mqprio_qopt.qopt.offset[i]; 3615*0754d65bSKiran Patil qcount_rx = vsi->mqprio_qopt.qopt.count[i]; 3616*0754d65bSKiran Patil qcount_tx = vsi->mqprio_qopt.qopt.count[i]; 3617*0754d65bSKiran Patil } 3618*0754d65bSKiran Patil } 3619*0754d65bSKiran Patil 3620*0754d65bSKiran Patil /* Set actual Tx/Rx queue pairs */ 3621*0754d65bSKiran Patil vsi->num_txq = offset + qcount_tx; 3622*0754d65bSKiran Patil vsi->num_rxq = offset + qcount_rx; 3623*0754d65bSKiran Patil 3624*0754d65bSKiran Patil /* Setup queue TC[0].qmap for given VSI context */ 3625*0754d65bSKiran Patil ctxt->info.tc_mapping[0] = cpu_to_le16(qmap); 3626*0754d65bSKiran Patil ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]); 3627*0754d65bSKiran Patil ctxt->info.q_mapping[1] = cpu_to_le16(tc0_qcount); 3628*0754d65bSKiran Patil 3629*0754d65bSKiran Patil /* Find queue count available for channel VSIs and starting offset 3630*0754d65bSKiran Patil * for channel VSIs 3631*0754d65bSKiran Patil */ 3632*0754d65bSKiran Patil if (tc0_qcount && tc0_qcount < vsi->num_rxq) { 3633*0754d65bSKiran Patil vsi->cnt_q_avail = vsi->num_rxq - tc0_qcount; 3634*0754d65bSKiran Patil vsi->next_base_q = tc0_qcount; 3635*0754d65bSKiran Patil } 3636*0754d65bSKiran Patil dev_dbg(ice_pf_to_dev(vsi->back), "vsi->num_txq = %d\n", vsi->num_txq); 3637*0754d65bSKiran Patil dev_dbg(ice_pf_to_dev(vsi->back), "vsi->num_rxq = %d\n", vsi->num_rxq); 3638*0754d65bSKiran Patil dev_dbg(ice_pf_to_dev(vsi->back), "all_numtc %u, all_enatc: 0x%04x, tc_cfg.numtc %u\n", 3639*0754d65bSKiran Patil vsi->all_numtc, vsi->all_enatc, vsi->tc_cfg.numtc); 3640*0754d65bSKiran Patil } 3641*0754d65bSKiran Patil 3642*0754d65bSKiran Patil /** 36437b9ffc76SAnirudh Venkataramanan * ice_vsi_cfg_tc - Configure VSI Tx Sched for given TC map 36447b9ffc76SAnirudh Venkataramanan * @vsi: VSI to be configured 36457b9ffc76SAnirudh Venkataramanan * @ena_tc: TC bitmap 36467b9ffc76SAnirudh Venkataramanan * 36477b9ffc76SAnirudh Venkataramanan * VSI queues expected to be quiesced before calling this function 36487b9ffc76SAnirudh Venkataramanan */ 36497b9ffc76SAnirudh Venkataramanan int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc) 36507b9ffc76SAnirudh Venkataramanan { 36517b9ffc76SAnirudh Venkataramanan u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 }; 36527b9ffc76SAnirudh Venkataramanan struct ice_pf *pf = vsi->back; 36534ee656bbSTony Nguyen struct ice_vsi_ctx *ctx; 36547b9ffc76SAnirudh Venkataramanan enum ice_status status; 36554015d11eSBrett Creeley struct device *dev; 36567b9ffc76SAnirudh Venkataramanan int i, ret = 0; 36577b9ffc76SAnirudh Venkataramanan u8 num_tc = 0; 36587b9ffc76SAnirudh Venkataramanan 36594015d11eSBrett Creeley dev = ice_pf_to_dev(pf); 3660*0754d65bSKiran Patil if (vsi->tc_cfg.ena_tc == ena_tc && 3661*0754d65bSKiran Patil vsi->mqprio_qopt.mode != TC_MQPRIO_MODE_CHANNEL) 3662*0754d65bSKiran Patil return ret; 36634015d11eSBrett Creeley 36647b9ffc76SAnirudh Venkataramanan ice_for_each_traffic_class(i) { 36657b9ffc76SAnirudh Venkataramanan /* build bitmap of enabled TCs */ 36667b9ffc76SAnirudh Venkataramanan if (ena_tc & BIT(i)) 36677b9ffc76SAnirudh Venkataramanan num_tc++; 36687b9ffc76SAnirudh Venkataramanan /* populate max_txqs per TC */ 3669d5a46359SAkeem G Abodunrin max_txqs[i] = vsi->alloc_txq; 3670*0754d65bSKiran Patil /* Update max_txqs if it is CHNL VSI, because alloc_t[r]xq are 3671*0754d65bSKiran Patil * zero for CHNL VSI, hence use num_txq instead as max_txqs 3672*0754d65bSKiran Patil */ 3673*0754d65bSKiran Patil if (vsi->type == ICE_VSI_CHNL && 3674*0754d65bSKiran Patil test_bit(ICE_FLAG_TC_MQPRIO, pf->flags)) 3675*0754d65bSKiran Patil max_txqs[i] = vsi->num_txq; 36767b9ffc76SAnirudh Venkataramanan } 36777b9ffc76SAnirudh Venkataramanan 36787b9ffc76SAnirudh Venkataramanan vsi->tc_cfg.ena_tc = ena_tc; 36797b9ffc76SAnirudh Venkataramanan vsi->tc_cfg.numtc = num_tc; 36807b9ffc76SAnirudh Venkataramanan 36819efe35d0STony Nguyen ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 36827b9ffc76SAnirudh Venkataramanan if (!ctx) 36837b9ffc76SAnirudh Venkataramanan return -ENOMEM; 36847b9ffc76SAnirudh Venkataramanan 36857b9ffc76SAnirudh Venkataramanan ctx->vf_num = 0; 36867b9ffc76SAnirudh Venkataramanan ctx->info = vsi->info; 36877b9ffc76SAnirudh Venkataramanan 3688*0754d65bSKiran Patil if (vsi->type == ICE_VSI_PF && 3689*0754d65bSKiran Patil test_bit(ICE_FLAG_TC_MQPRIO, pf->flags)) 3690*0754d65bSKiran Patil ice_vsi_setup_q_map_mqprio(vsi, ctx, ena_tc); 3691*0754d65bSKiran Patil else 36927b9ffc76SAnirudh Venkataramanan ice_vsi_setup_q_map(vsi, ctx); 36937b9ffc76SAnirudh Venkataramanan 36947b9ffc76SAnirudh Venkataramanan /* must to indicate which section of VSI context are being modified */ 36957b9ffc76SAnirudh Venkataramanan ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID); 36967b9ffc76SAnirudh Venkataramanan status = ice_update_vsi(&pf->hw, vsi->idx, ctx, NULL); 36977b9ffc76SAnirudh Venkataramanan if (status) { 36984015d11eSBrett Creeley dev_info(dev, "Failed VSI Update\n"); 36997b9ffc76SAnirudh Venkataramanan ret = -EIO; 37007b9ffc76SAnirudh Venkataramanan goto out; 37017b9ffc76SAnirudh Venkataramanan } 37027b9ffc76SAnirudh Venkataramanan 3703*0754d65bSKiran Patil if (vsi->type == ICE_VSI_PF && 3704*0754d65bSKiran Patil test_bit(ICE_FLAG_TC_MQPRIO, pf->flags)) 3705*0754d65bSKiran Patil status = ice_cfg_vsi_lan(vsi->port_info, vsi->idx, 1, 37067b9ffc76SAnirudh Venkataramanan max_txqs); 3707*0754d65bSKiran Patil else 3708*0754d65bSKiran Patil status = ice_cfg_vsi_lan(vsi->port_info, vsi->idx, 3709*0754d65bSKiran Patil vsi->tc_cfg.ena_tc, max_txqs); 37107b9ffc76SAnirudh Venkataramanan 37117b9ffc76SAnirudh Venkataramanan if (status) { 37120fee3577SLihong Yang dev_err(dev, "VSI %d failed TC config, error %s\n", 37130fee3577SLihong Yang vsi->vsi_num, ice_stat_str(status)); 37147b9ffc76SAnirudh Venkataramanan ret = -EIO; 37157b9ffc76SAnirudh Venkataramanan goto out; 37167b9ffc76SAnirudh Venkataramanan } 37177b9ffc76SAnirudh Venkataramanan ice_vsi_update_q_map(vsi, ctx); 37187b9ffc76SAnirudh Venkataramanan vsi->info.valid_sections = 0; 37197b9ffc76SAnirudh Venkataramanan 37207b9ffc76SAnirudh Venkataramanan ice_vsi_cfg_netdev_tc(vsi, ena_tc); 37217b9ffc76SAnirudh Venkataramanan out: 37229efe35d0STony Nguyen kfree(ctx); 37237b9ffc76SAnirudh Venkataramanan return ret; 37247b9ffc76SAnirudh Venkataramanan } 3725bbb968e8SAkeem G Abodunrin 3726bbb968e8SAkeem G Abodunrin /** 37272d4238f5SKrzysztof Kazimierczak * ice_update_ring_stats - Update ring statistics 3728e72bba21SMaciej Fijalkowski * @stats: stats to be updated 37292d4238f5SKrzysztof Kazimierczak * @pkts: number of processed packets 37302d4238f5SKrzysztof Kazimierczak * @bytes: number of processed bytes 37312d4238f5SKrzysztof Kazimierczak * 37322d4238f5SKrzysztof Kazimierczak * This function assumes that caller has acquired a u64_stats_sync lock. 37332d4238f5SKrzysztof Kazimierczak */ 3734e72bba21SMaciej Fijalkowski static void ice_update_ring_stats(struct ice_q_stats *stats, u64 pkts, u64 bytes) 37352d4238f5SKrzysztof Kazimierczak { 3736e72bba21SMaciej Fijalkowski stats->bytes += bytes; 3737e72bba21SMaciej Fijalkowski stats->pkts += pkts; 37382d4238f5SKrzysztof Kazimierczak } 37392d4238f5SKrzysztof Kazimierczak 37402d4238f5SKrzysztof Kazimierczak /** 37412d4238f5SKrzysztof Kazimierczak * ice_update_tx_ring_stats - Update Tx ring specific counters 37422d4238f5SKrzysztof Kazimierczak * @tx_ring: ring to update 37432d4238f5SKrzysztof Kazimierczak * @pkts: number of processed packets 37442d4238f5SKrzysztof Kazimierczak * @bytes: number of processed bytes 37452d4238f5SKrzysztof Kazimierczak */ 3746e72bba21SMaciej Fijalkowski void ice_update_tx_ring_stats(struct ice_tx_ring *tx_ring, u64 pkts, u64 bytes) 37472d4238f5SKrzysztof Kazimierczak { 37482d4238f5SKrzysztof Kazimierczak u64_stats_update_begin(&tx_ring->syncp); 3749e72bba21SMaciej Fijalkowski ice_update_ring_stats(&tx_ring->stats, pkts, bytes); 37502d4238f5SKrzysztof Kazimierczak u64_stats_update_end(&tx_ring->syncp); 37512d4238f5SKrzysztof Kazimierczak } 37522d4238f5SKrzysztof Kazimierczak 37532d4238f5SKrzysztof Kazimierczak /** 37542d4238f5SKrzysztof Kazimierczak * ice_update_rx_ring_stats - Update Rx ring specific counters 37552d4238f5SKrzysztof Kazimierczak * @rx_ring: ring to update 37562d4238f5SKrzysztof Kazimierczak * @pkts: number of processed packets 37572d4238f5SKrzysztof Kazimierczak * @bytes: number of processed bytes 37582d4238f5SKrzysztof Kazimierczak */ 3759e72bba21SMaciej Fijalkowski void ice_update_rx_ring_stats(struct ice_rx_ring *rx_ring, u64 pkts, u64 bytes) 37602d4238f5SKrzysztof Kazimierczak { 37612d4238f5SKrzysztof Kazimierczak u64_stats_update_begin(&rx_ring->syncp); 3762e72bba21SMaciej Fijalkowski ice_update_ring_stats(&rx_ring->stats, pkts, bytes); 37632d4238f5SKrzysztof Kazimierczak u64_stats_update_end(&rx_ring->syncp); 37642d4238f5SKrzysztof Kazimierczak } 37652d4238f5SKrzysztof Kazimierczak 37662d4238f5SKrzysztof Kazimierczak /** 3767148beb61SHenry Tieman * ice_status_to_errno - convert from enum ice_status to Linux errno 3768148beb61SHenry Tieman * @err: ice_status value to convert 3769148beb61SHenry Tieman */ 3770148beb61SHenry Tieman int ice_status_to_errno(enum ice_status err) 3771148beb61SHenry Tieman { 3772148beb61SHenry Tieman switch (err) { 3773148beb61SHenry Tieman case ICE_SUCCESS: 3774148beb61SHenry Tieman return 0; 3775148beb61SHenry Tieman case ICE_ERR_DOES_NOT_EXIST: 3776148beb61SHenry Tieman return -ENOENT; 3777148beb61SHenry Tieman case ICE_ERR_OUT_OF_RANGE: 37788f5ee3c4SJacob Keller case ICE_ERR_AQ_ERROR: 37798f5ee3c4SJacob Keller case ICE_ERR_AQ_TIMEOUT: 37808f5ee3c4SJacob Keller case ICE_ERR_AQ_EMPTY: 37818f5ee3c4SJacob Keller case ICE_ERR_AQ_FW_CRITICAL: 37828f5ee3c4SJacob Keller return -EIO; 3783148beb61SHenry Tieman case ICE_ERR_PARAM: 37848f5ee3c4SJacob Keller case ICE_ERR_INVAL_SIZE: 3785148beb61SHenry Tieman return -EINVAL; 3786148beb61SHenry Tieman case ICE_ERR_NO_MEMORY: 3787148beb61SHenry Tieman return -ENOMEM; 3788148beb61SHenry Tieman case ICE_ERR_MAX_LIMIT: 3789148beb61SHenry Tieman return -EAGAIN; 37908f5ee3c4SJacob Keller case ICE_ERR_RESET_ONGOING: 37918f5ee3c4SJacob Keller return -EBUSY; 37928f5ee3c4SJacob Keller case ICE_ERR_AQ_FULL: 37938f5ee3c4SJacob Keller return -ENOSPC; 3794148beb61SHenry Tieman default: 3795148beb61SHenry Tieman return -EINVAL; 3796148beb61SHenry Tieman } 3797148beb61SHenry Tieman } 3798148beb61SHenry Tieman 3799148beb61SHenry Tieman /** 3800fc0f39bcSBrett Creeley * ice_is_dflt_vsi_in_use - check if the default forwarding VSI is being used 3801fc0f39bcSBrett Creeley * @sw: switch to check if its default forwarding VSI is free 3802fc0f39bcSBrett Creeley * 3803fc0f39bcSBrett Creeley * Return true if the default forwarding VSI is already being used, else returns 3804fc0f39bcSBrett Creeley * false signalling that it's available to use. 3805fc0f39bcSBrett Creeley */ 3806fc0f39bcSBrett Creeley bool ice_is_dflt_vsi_in_use(struct ice_sw *sw) 3807fc0f39bcSBrett Creeley { 3808fc0f39bcSBrett Creeley return (sw->dflt_vsi && sw->dflt_vsi_ena); 3809fc0f39bcSBrett Creeley } 3810fc0f39bcSBrett Creeley 3811fc0f39bcSBrett Creeley /** 3812fc0f39bcSBrett Creeley * ice_is_vsi_dflt_vsi - check if the VSI passed in is the default VSI 3813fc0f39bcSBrett Creeley * @sw: switch for the default forwarding VSI to compare against 3814fc0f39bcSBrett Creeley * @vsi: VSI to compare against default forwarding VSI 3815fc0f39bcSBrett Creeley * 3816fc0f39bcSBrett Creeley * If this VSI passed in is the default forwarding VSI then return true, else 3817fc0f39bcSBrett Creeley * return false 3818fc0f39bcSBrett Creeley */ 3819fc0f39bcSBrett Creeley bool ice_is_vsi_dflt_vsi(struct ice_sw *sw, struct ice_vsi *vsi) 3820fc0f39bcSBrett Creeley { 3821fc0f39bcSBrett Creeley return (sw->dflt_vsi == vsi && sw->dflt_vsi_ena); 3822fc0f39bcSBrett Creeley } 3823fc0f39bcSBrett Creeley 3824fc0f39bcSBrett Creeley /** 3825fc0f39bcSBrett Creeley * ice_set_dflt_vsi - set the default forwarding VSI 3826fc0f39bcSBrett Creeley * @sw: switch used to assign the default forwarding VSI 3827fc0f39bcSBrett Creeley * @vsi: VSI getting set as the default forwarding VSI on the switch 3828fc0f39bcSBrett Creeley * 3829fc0f39bcSBrett Creeley * If the VSI passed in is already the default VSI and it's enabled just return 3830fc0f39bcSBrett Creeley * success. 3831fc0f39bcSBrett Creeley * 3832fc0f39bcSBrett Creeley * If there is already a default VSI on the switch and it's enabled then return 3833fc0f39bcSBrett Creeley * -EEXIST since there can only be one default VSI per switch. 3834fc0f39bcSBrett Creeley * 3835fc0f39bcSBrett Creeley * Otherwise try to set the VSI passed in as the switch's default VSI and 3836fc0f39bcSBrett Creeley * return the result. 3837fc0f39bcSBrett Creeley */ 3838fc0f39bcSBrett Creeley int ice_set_dflt_vsi(struct ice_sw *sw, struct ice_vsi *vsi) 3839fc0f39bcSBrett Creeley { 3840fc0f39bcSBrett Creeley enum ice_status status; 3841fc0f39bcSBrett Creeley struct device *dev; 3842fc0f39bcSBrett Creeley 3843fc0f39bcSBrett Creeley if (!sw || !vsi) 3844fc0f39bcSBrett Creeley return -EINVAL; 3845fc0f39bcSBrett Creeley 3846fc0f39bcSBrett Creeley dev = ice_pf_to_dev(vsi->back); 3847fc0f39bcSBrett Creeley 3848fc0f39bcSBrett Creeley /* the VSI passed in is already the default VSI */ 3849fc0f39bcSBrett Creeley if (ice_is_vsi_dflt_vsi(sw, vsi)) { 3850fc0f39bcSBrett Creeley dev_dbg(dev, "VSI %d passed in is already the default forwarding VSI, nothing to do\n", 3851fc0f39bcSBrett Creeley vsi->vsi_num); 3852fc0f39bcSBrett Creeley return 0; 3853fc0f39bcSBrett Creeley } 3854fc0f39bcSBrett Creeley 3855fc0f39bcSBrett Creeley /* another VSI is already the default VSI for this switch */ 3856fc0f39bcSBrett Creeley if (ice_is_dflt_vsi_in_use(sw)) { 385719cce2c6SAnirudh Venkataramanan dev_err(dev, "Default forwarding VSI %d already in use, disable it and try again\n", 3858fc0f39bcSBrett Creeley sw->dflt_vsi->vsi_num); 3859fc0f39bcSBrett Creeley return -EEXIST; 3860fc0f39bcSBrett Creeley } 3861fc0f39bcSBrett Creeley 3862fc0f39bcSBrett Creeley status = ice_cfg_dflt_vsi(&vsi->back->hw, vsi->idx, true, ICE_FLTR_RX); 3863fc0f39bcSBrett Creeley if (status) { 38640fee3577SLihong Yang dev_err(dev, "Failed to set VSI %d as the default forwarding VSI, error %s\n", 38650fee3577SLihong Yang vsi->vsi_num, ice_stat_str(status)); 3866fc0f39bcSBrett Creeley return -EIO; 3867fc0f39bcSBrett Creeley } 3868fc0f39bcSBrett Creeley 3869fc0f39bcSBrett Creeley sw->dflt_vsi = vsi; 3870fc0f39bcSBrett Creeley sw->dflt_vsi_ena = true; 3871fc0f39bcSBrett Creeley 3872fc0f39bcSBrett Creeley return 0; 3873fc0f39bcSBrett Creeley } 3874fc0f39bcSBrett Creeley 3875fc0f39bcSBrett Creeley /** 3876fc0f39bcSBrett Creeley * ice_clear_dflt_vsi - clear the default forwarding VSI 3877fc0f39bcSBrett Creeley * @sw: switch used to clear the default VSI 3878fc0f39bcSBrett Creeley * 3879fc0f39bcSBrett Creeley * If the switch has no default VSI or it's not enabled then return error. 3880fc0f39bcSBrett Creeley * 3881fc0f39bcSBrett Creeley * Otherwise try to clear the default VSI and return the result. 3882fc0f39bcSBrett Creeley */ 3883fc0f39bcSBrett Creeley int ice_clear_dflt_vsi(struct ice_sw *sw) 3884fc0f39bcSBrett Creeley { 3885fc0f39bcSBrett Creeley struct ice_vsi *dflt_vsi; 3886fc0f39bcSBrett Creeley enum ice_status status; 3887fc0f39bcSBrett Creeley struct device *dev; 3888fc0f39bcSBrett Creeley 3889fc0f39bcSBrett Creeley if (!sw) 3890fc0f39bcSBrett Creeley return -EINVAL; 3891fc0f39bcSBrett Creeley 3892fc0f39bcSBrett Creeley dev = ice_pf_to_dev(sw->pf); 3893fc0f39bcSBrett Creeley 3894fc0f39bcSBrett Creeley dflt_vsi = sw->dflt_vsi; 3895fc0f39bcSBrett Creeley 3896fc0f39bcSBrett Creeley /* there is no default VSI configured */ 3897fc0f39bcSBrett Creeley if (!ice_is_dflt_vsi_in_use(sw)) 3898fc0f39bcSBrett Creeley return -ENODEV; 3899fc0f39bcSBrett Creeley 3900fc0f39bcSBrett Creeley status = ice_cfg_dflt_vsi(&dflt_vsi->back->hw, dflt_vsi->idx, false, 3901fc0f39bcSBrett Creeley ICE_FLTR_RX); 3902fc0f39bcSBrett Creeley if (status) { 39030fee3577SLihong Yang dev_err(dev, "Failed to clear the default forwarding VSI %d, error %s\n", 39040fee3577SLihong Yang dflt_vsi->vsi_num, ice_stat_str(status)); 3905fc0f39bcSBrett Creeley return -EIO; 3906fc0f39bcSBrett Creeley } 3907fc0f39bcSBrett Creeley 3908fc0f39bcSBrett Creeley sw->dflt_vsi = NULL; 3909fc0f39bcSBrett Creeley sw->dflt_vsi_ena = false; 3910fc0f39bcSBrett Creeley 3911fc0f39bcSBrett Creeley return 0; 3912fc0f39bcSBrett Creeley } 3913d348d517SAnirudh Venkataramanan 3914d348d517SAnirudh Venkataramanan /** 39154ecc8633SBrett Creeley * ice_get_link_speed_mbps - get link speed in Mbps 39164ecc8633SBrett Creeley * @vsi: the VSI whose link speed is being queried 39174ecc8633SBrett Creeley * 39184ecc8633SBrett Creeley * Return current VSI link speed and 0 if the speed is unknown. 39194ecc8633SBrett Creeley */ 39204ecc8633SBrett Creeley int ice_get_link_speed_mbps(struct ice_vsi *vsi) 39214ecc8633SBrett Creeley { 39224ecc8633SBrett Creeley switch (vsi->port_info->phy.link_info.link_speed) { 39234ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_100GB: 39244ecc8633SBrett Creeley return SPEED_100000; 39254ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_50GB: 39264ecc8633SBrett Creeley return SPEED_50000; 39274ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_40GB: 39284ecc8633SBrett Creeley return SPEED_40000; 39294ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_25GB: 39304ecc8633SBrett Creeley return SPEED_25000; 39314ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_20GB: 39324ecc8633SBrett Creeley return SPEED_20000; 39334ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_10GB: 39344ecc8633SBrett Creeley return SPEED_10000; 39354ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_5GB: 39364ecc8633SBrett Creeley return SPEED_5000; 39374ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_2500MB: 39384ecc8633SBrett Creeley return SPEED_2500; 39394ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_1000MB: 39404ecc8633SBrett Creeley return SPEED_1000; 39414ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_100MB: 39424ecc8633SBrett Creeley return SPEED_100; 39434ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_10MB: 39444ecc8633SBrett Creeley return SPEED_10; 39454ecc8633SBrett Creeley case ICE_AQ_LINK_SPEED_UNKNOWN: 39464ecc8633SBrett Creeley default: 39474ecc8633SBrett Creeley return 0; 39484ecc8633SBrett Creeley } 39494ecc8633SBrett Creeley } 39504ecc8633SBrett Creeley 39514ecc8633SBrett Creeley /** 39524ecc8633SBrett Creeley * ice_get_link_speed_kbps - get link speed in Kbps 39534ecc8633SBrett Creeley * @vsi: the VSI whose link speed is being queried 39544ecc8633SBrett Creeley * 39554ecc8633SBrett Creeley * Return current VSI link speed and 0 if the speed is unknown. 39564ecc8633SBrett Creeley */ 39574ecc8633SBrett Creeley static int ice_get_link_speed_kbps(struct ice_vsi *vsi) 39584ecc8633SBrett Creeley { 39594ecc8633SBrett Creeley int speed_mbps; 39604ecc8633SBrett Creeley 39614ecc8633SBrett Creeley speed_mbps = ice_get_link_speed_mbps(vsi); 39624ecc8633SBrett Creeley 39634ecc8633SBrett Creeley return speed_mbps * 1000; 39644ecc8633SBrett Creeley } 39654ecc8633SBrett Creeley 39664ecc8633SBrett Creeley /** 39674ecc8633SBrett Creeley * ice_set_min_bw_limit - setup minimum BW limit for Tx based on min_tx_rate 39684ecc8633SBrett Creeley * @vsi: VSI to be configured 39694ecc8633SBrett Creeley * @min_tx_rate: min Tx rate in Kbps to be configured as BW limit 39704ecc8633SBrett Creeley * 39714ecc8633SBrett Creeley * If the min_tx_rate is specified as 0 that means to clear the minimum BW limit 39724ecc8633SBrett Creeley * profile, otherwise a non-zero value will force a minimum BW limit for the VSI 39734ecc8633SBrett Creeley * on TC 0. 39744ecc8633SBrett Creeley */ 39754ecc8633SBrett Creeley int ice_set_min_bw_limit(struct ice_vsi *vsi, u64 min_tx_rate) 39764ecc8633SBrett Creeley { 39774ecc8633SBrett Creeley struct ice_pf *pf = vsi->back; 39784ecc8633SBrett Creeley enum ice_status status; 39794ecc8633SBrett Creeley struct device *dev; 39804ecc8633SBrett Creeley int speed; 39814ecc8633SBrett Creeley 39824ecc8633SBrett Creeley dev = ice_pf_to_dev(pf); 39834ecc8633SBrett Creeley if (!vsi->port_info) { 39844ecc8633SBrett Creeley dev_dbg(dev, "VSI %d, type %u specified doesn't have valid port_info\n", 39854ecc8633SBrett Creeley vsi->idx, vsi->type); 39864ecc8633SBrett Creeley return -EINVAL; 39874ecc8633SBrett Creeley } 39884ecc8633SBrett Creeley 39894ecc8633SBrett Creeley speed = ice_get_link_speed_kbps(vsi); 39904ecc8633SBrett Creeley if (min_tx_rate > (u64)speed) { 39914ecc8633SBrett Creeley dev_err(dev, "invalid min Tx rate %llu Kbps specified for %s %d is greater than current link speed %u Kbps\n", 39924ecc8633SBrett Creeley min_tx_rate, ice_vsi_type_str(vsi->type), vsi->idx, 39934ecc8633SBrett Creeley speed); 39944ecc8633SBrett Creeley return -EINVAL; 39954ecc8633SBrett Creeley } 39964ecc8633SBrett Creeley 39974ecc8633SBrett Creeley /* Configure min BW for VSI limit */ 39984ecc8633SBrett Creeley if (min_tx_rate) { 39994ecc8633SBrett Creeley status = ice_cfg_vsi_bw_lmt_per_tc(vsi->port_info, vsi->idx, 0, 40004ecc8633SBrett Creeley ICE_MIN_BW, min_tx_rate); 40014ecc8633SBrett Creeley if (status) { 40024ecc8633SBrett Creeley dev_err(dev, "failed to set min Tx rate(%llu Kbps) for %s %d\n", 40034ecc8633SBrett Creeley min_tx_rate, ice_vsi_type_str(vsi->type), 40044ecc8633SBrett Creeley vsi->idx); 40054ecc8633SBrett Creeley return -EIO; 40064ecc8633SBrett Creeley } 40074ecc8633SBrett Creeley 40084ecc8633SBrett Creeley dev_dbg(dev, "set min Tx rate(%llu Kbps) for %s\n", 40094ecc8633SBrett Creeley min_tx_rate, ice_vsi_type_str(vsi->type)); 40104ecc8633SBrett Creeley } else { 40114ecc8633SBrett Creeley status = ice_cfg_vsi_bw_dflt_lmt_per_tc(vsi->port_info, 40124ecc8633SBrett Creeley vsi->idx, 0, 40134ecc8633SBrett Creeley ICE_MIN_BW); 40144ecc8633SBrett Creeley if (status) { 40154ecc8633SBrett Creeley dev_err(dev, "failed to clear min Tx rate configuration for %s %d\n", 40164ecc8633SBrett Creeley ice_vsi_type_str(vsi->type), vsi->idx); 40174ecc8633SBrett Creeley return -EIO; 40184ecc8633SBrett Creeley } 40194ecc8633SBrett Creeley 40204ecc8633SBrett Creeley dev_dbg(dev, "cleared min Tx rate configuration for %s %d\n", 40214ecc8633SBrett Creeley ice_vsi_type_str(vsi->type), vsi->idx); 40224ecc8633SBrett Creeley } 40234ecc8633SBrett Creeley 40244ecc8633SBrett Creeley return 0; 40254ecc8633SBrett Creeley } 40264ecc8633SBrett Creeley 40274ecc8633SBrett Creeley /** 40284ecc8633SBrett Creeley * ice_set_max_bw_limit - setup maximum BW limit for Tx based on max_tx_rate 40294ecc8633SBrett Creeley * @vsi: VSI to be configured 40304ecc8633SBrett Creeley * @max_tx_rate: max Tx rate in Kbps to be configured as BW limit 40314ecc8633SBrett Creeley * 40324ecc8633SBrett Creeley * If the max_tx_rate is specified as 0 that means to clear the maximum BW limit 40334ecc8633SBrett Creeley * profile, otherwise a non-zero value will force a maximum BW limit for the VSI 40344ecc8633SBrett Creeley * on TC 0. 40354ecc8633SBrett Creeley */ 40364ecc8633SBrett Creeley int ice_set_max_bw_limit(struct ice_vsi *vsi, u64 max_tx_rate) 40374ecc8633SBrett Creeley { 40384ecc8633SBrett Creeley struct ice_pf *pf = vsi->back; 40394ecc8633SBrett Creeley enum ice_status status; 40404ecc8633SBrett Creeley struct device *dev; 40414ecc8633SBrett Creeley int speed; 40424ecc8633SBrett Creeley 40434ecc8633SBrett Creeley dev = ice_pf_to_dev(pf); 40444ecc8633SBrett Creeley if (!vsi->port_info) { 40454ecc8633SBrett Creeley dev_dbg(dev, "VSI %d, type %u specified doesn't have valid port_info\n", 40464ecc8633SBrett Creeley vsi->idx, vsi->type); 40474ecc8633SBrett Creeley return -EINVAL; 40484ecc8633SBrett Creeley } 40494ecc8633SBrett Creeley 40504ecc8633SBrett Creeley speed = ice_get_link_speed_kbps(vsi); 40514ecc8633SBrett Creeley if (max_tx_rate > (u64)speed) { 40524ecc8633SBrett Creeley dev_err(dev, "invalid max Tx rate %llu Kbps specified for %s %d is greater than current link speed %u Kbps\n", 40534ecc8633SBrett Creeley max_tx_rate, ice_vsi_type_str(vsi->type), vsi->idx, 40544ecc8633SBrett Creeley speed); 40554ecc8633SBrett Creeley return -EINVAL; 40564ecc8633SBrett Creeley } 40574ecc8633SBrett Creeley 40584ecc8633SBrett Creeley /* Configure max BW for VSI limit */ 40594ecc8633SBrett Creeley if (max_tx_rate) { 40604ecc8633SBrett Creeley status = ice_cfg_vsi_bw_lmt_per_tc(vsi->port_info, vsi->idx, 0, 40614ecc8633SBrett Creeley ICE_MAX_BW, max_tx_rate); 40624ecc8633SBrett Creeley if (status) { 40634ecc8633SBrett Creeley dev_err(dev, "failed setting max Tx rate(%llu Kbps) for %s %d\n", 40644ecc8633SBrett Creeley max_tx_rate, ice_vsi_type_str(vsi->type), 40654ecc8633SBrett Creeley vsi->idx); 40664ecc8633SBrett Creeley return -EIO; 40674ecc8633SBrett Creeley } 40684ecc8633SBrett Creeley 40694ecc8633SBrett Creeley dev_dbg(dev, "set max Tx rate(%llu Kbps) for %s %d\n", 40704ecc8633SBrett Creeley max_tx_rate, ice_vsi_type_str(vsi->type), vsi->idx); 40714ecc8633SBrett Creeley } else { 40724ecc8633SBrett Creeley status = ice_cfg_vsi_bw_dflt_lmt_per_tc(vsi->port_info, 40734ecc8633SBrett Creeley vsi->idx, 0, 40744ecc8633SBrett Creeley ICE_MAX_BW); 40754ecc8633SBrett Creeley if (status) { 40764ecc8633SBrett Creeley dev_err(dev, "failed clearing max Tx rate configuration for %s %d\n", 40774ecc8633SBrett Creeley ice_vsi_type_str(vsi->type), vsi->idx); 40784ecc8633SBrett Creeley return -EIO; 40794ecc8633SBrett Creeley } 40804ecc8633SBrett Creeley 40814ecc8633SBrett Creeley dev_dbg(dev, "cleared max Tx rate configuration for %s %d\n", 40824ecc8633SBrett Creeley ice_vsi_type_str(vsi->type), vsi->idx); 40834ecc8633SBrett Creeley } 40844ecc8633SBrett Creeley 40854ecc8633SBrett Creeley return 0; 40864ecc8633SBrett Creeley } 40874ecc8633SBrett Creeley 40884ecc8633SBrett Creeley /** 4089d348d517SAnirudh Venkataramanan * ice_set_link - turn on/off physical link 4090d348d517SAnirudh Venkataramanan * @vsi: VSI to modify physical link on 4091d348d517SAnirudh Venkataramanan * @ena: turn on/off physical link 4092d348d517SAnirudh Venkataramanan */ 4093d348d517SAnirudh Venkataramanan int ice_set_link(struct ice_vsi *vsi, bool ena) 4094d348d517SAnirudh Venkataramanan { 4095d348d517SAnirudh Venkataramanan struct device *dev = ice_pf_to_dev(vsi->back); 4096d348d517SAnirudh Venkataramanan struct ice_port_info *pi = vsi->port_info; 4097d348d517SAnirudh Venkataramanan struct ice_hw *hw = pi->hw; 4098d348d517SAnirudh Venkataramanan enum ice_status status; 4099d348d517SAnirudh Venkataramanan 4100d348d517SAnirudh Venkataramanan if (vsi->type != ICE_VSI_PF) 4101d348d517SAnirudh Venkataramanan return -EINVAL; 4102d348d517SAnirudh Venkataramanan 4103d348d517SAnirudh Venkataramanan status = ice_aq_set_link_restart_an(pi, ena, NULL); 4104d348d517SAnirudh Venkataramanan 4105d348d517SAnirudh Venkataramanan /* if link is owned by manageability, FW will return ICE_AQ_RC_EMODE. 4106d348d517SAnirudh Venkataramanan * this is not a fatal error, so print a warning message and return 4107d348d517SAnirudh Venkataramanan * a success code. Return an error if FW returns an error code other 4108d348d517SAnirudh Venkataramanan * than ICE_AQ_RC_EMODE 4109d348d517SAnirudh Venkataramanan */ 4110d348d517SAnirudh Venkataramanan if (status == ICE_ERR_AQ_ERROR) { 4111d348d517SAnirudh Venkataramanan if (hw->adminq.sq_last_status == ICE_AQ_RC_EMODE) 4112d348d517SAnirudh Venkataramanan dev_warn(dev, "can't set link to %s, err %s aq_err %s. not fatal, continuing\n", 4113d348d517SAnirudh Venkataramanan (ena ? "ON" : "OFF"), ice_stat_str(status), 4114d348d517SAnirudh Venkataramanan ice_aq_str(hw->adminq.sq_last_status)); 4115d348d517SAnirudh Venkataramanan } else if (status) { 4116d348d517SAnirudh Venkataramanan dev_err(dev, "can't set link to %s, err %s aq_err %s\n", 4117d348d517SAnirudh Venkataramanan (ena ? "ON" : "OFF"), ice_stat_str(status), 4118d348d517SAnirudh Venkataramanan ice_aq_str(hw->adminq.sq_last_status)); 4119d348d517SAnirudh Venkataramanan return -EIO; 4120d348d517SAnirudh Venkataramanan } 4121d348d517SAnirudh Venkataramanan 4122d348d517SAnirudh Venkataramanan return 0; 4123d348d517SAnirudh Venkataramanan } 412440b24760SAnirudh Venkataramanan 412540b24760SAnirudh Venkataramanan /** 412640b24760SAnirudh Venkataramanan * ice_is_feature_supported 412740b24760SAnirudh Venkataramanan * @pf: pointer to the struct ice_pf instance 412840b24760SAnirudh Venkataramanan * @f: feature enum to be checked 412940b24760SAnirudh Venkataramanan * 413040b24760SAnirudh Venkataramanan * returns true if feature is supported, false otherwise 413140b24760SAnirudh Venkataramanan */ 413240b24760SAnirudh Venkataramanan bool ice_is_feature_supported(struct ice_pf *pf, enum ice_feature f) 413340b24760SAnirudh Venkataramanan { 413440b24760SAnirudh Venkataramanan if (f < 0 || f >= ICE_F_MAX) 413540b24760SAnirudh Venkataramanan return false; 413640b24760SAnirudh Venkataramanan 413740b24760SAnirudh Venkataramanan return test_bit(f, pf->features); 413840b24760SAnirudh Venkataramanan } 413940b24760SAnirudh Venkataramanan 414040b24760SAnirudh Venkataramanan /** 414140b24760SAnirudh Venkataramanan * ice_set_feature_support 414240b24760SAnirudh Venkataramanan * @pf: pointer to the struct ice_pf instance 414340b24760SAnirudh Venkataramanan * @f: feature enum to set 414440b24760SAnirudh Venkataramanan */ 414540b24760SAnirudh Venkataramanan static void ice_set_feature_support(struct ice_pf *pf, enum ice_feature f) 414640b24760SAnirudh Venkataramanan { 414740b24760SAnirudh Venkataramanan if (f < 0 || f >= ICE_F_MAX) 414840b24760SAnirudh Venkataramanan return; 414940b24760SAnirudh Venkataramanan 415040b24760SAnirudh Venkataramanan set_bit(f, pf->features); 415140b24760SAnirudh Venkataramanan } 415240b24760SAnirudh Venkataramanan 415340b24760SAnirudh Venkataramanan /** 4154325b2064SMaciej Machnikowski * ice_clear_feature_support 4155325b2064SMaciej Machnikowski * @pf: pointer to the struct ice_pf instance 4156325b2064SMaciej Machnikowski * @f: feature enum to clear 4157325b2064SMaciej Machnikowski */ 4158325b2064SMaciej Machnikowski void ice_clear_feature_support(struct ice_pf *pf, enum ice_feature f) 4159325b2064SMaciej Machnikowski { 4160325b2064SMaciej Machnikowski if (f < 0 || f >= ICE_F_MAX) 4161325b2064SMaciej Machnikowski return; 4162325b2064SMaciej Machnikowski 4163325b2064SMaciej Machnikowski clear_bit(f, pf->features); 4164325b2064SMaciej Machnikowski } 4165325b2064SMaciej Machnikowski 4166325b2064SMaciej Machnikowski /** 416740b24760SAnirudh Venkataramanan * ice_init_feature_support 416840b24760SAnirudh Venkataramanan * @pf: pointer to the struct ice_pf instance 416940b24760SAnirudh Venkataramanan * 417040b24760SAnirudh Venkataramanan * called during init to setup supported feature 417140b24760SAnirudh Venkataramanan */ 417240b24760SAnirudh Venkataramanan void ice_init_feature_support(struct ice_pf *pf) 417340b24760SAnirudh Venkataramanan { 417440b24760SAnirudh Venkataramanan switch (pf->hw.device_id) { 417540b24760SAnirudh Venkataramanan case ICE_DEV_ID_E810C_BACKPLANE: 417640b24760SAnirudh Venkataramanan case ICE_DEV_ID_E810C_QSFP: 417740b24760SAnirudh Venkataramanan case ICE_DEV_ID_E810C_SFP: 417840b24760SAnirudh Venkataramanan ice_set_feature_support(pf, ICE_F_DSCP); 4179325b2064SMaciej Machnikowski if (ice_is_e810t(&pf->hw)) 4180325b2064SMaciej Machnikowski ice_set_feature_support(pf, ICE_F_SMA_CTRL); 418140b24760SAnirudh Venkataramanan break; 418240b24760SAnirudh Venkataramanan default: 418340b24760SAnirudh Venkataramanan break; 418440b24760SAnirudh Venkataramanan } 418540b24760SAnirudh Venkataramanan } 4186ff5411efSMichal Swiatkowski 4187ff5411efSMichal Swiatkowski /** 4188ff5411efSMichal Swiatkowski * ice_vsi_update_security - update security block in VSI 4189ff5411efSMichal Swiatkowski * @vsi: pointer to VSI structure 4190ff5411efSMichal Swiatkowski * @fill: function pointer to fill ctx 4191ff5411efSMichal Swiatkowski */ 4192ff5411efSMichal Swiatkowski int 4193ff5411efSMichal Swiatkowski ice_vsi_update_security(struct ice_vsi *vsi, void (*fill)(struct ice_vsi_ctx *)) 4194ff5411efSMichal Swiatkowski { 4195ff5411efSMichal Swiatkowski struct ice_vsi_ctx ctx = { 0 }; 4196ff5411efSMichal Swiatkowski 4197ff5411efSMichal Swiatkowski ctx.info = vsi->info; 4198ff5411efSMichal Swiatkowski ctx.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID); 4199ff5411efSMichal Swiatkowski fill(&ctx); 4200ff5411efSMichal Swiatkowski 4201ff5411efSMichal Swiatkowski if (ice_update_vsi(&vsi->back->hw, vsi->idx, &ctx, NULL)) 4202ff5411efSMichal Swiatkowski return -ENODEV; 4203ff5411efSMichal Swiatkowski 4204ff5411efSMichal Swiatkowski vsi->info = ctx.info; 4205ff5411efSMichal Swiatkowski return 0; 4206ff5411efSMichal Swiatkowski } 4207ff5411efSMichal Swiatkowski 4208ff5411efSMichal Swiatkowski /** 4209ff5411efSMichal Swiatkowski * ice_vsi_ctx_set_antispoof - set antispoof function in VSI ctx 4210ff5411efSMichal Swiatkowski * @ctx: pointer to VSI ctx structure 4211ff5411efSMichal Swiatkowski */ 4212ff5411efSMichal Swiatkowski void ice_vsi_ctx_set_antispoof(struct ice_vsi_ctx *ctx) 4213ff5411efSMichal Swiatkowski { 4214ff5411efSMichal Swiatkowski ctx->info.sec_flags |= ICE_AQ_VSI_SEC_FLAG_ENA_MAC_ANTI_SPOOF | 4215ff5411efSMichal Swiatkowski (ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA << 4216ff5411efSMichal Swiatkowski ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S); 4217ff5411efSMichal Swiatkowski } 4218ff5411efSMichal Swiatkowski 4219ff5411efSMichal Swiatkowski /** 4220ff5411efSMichal Swiatkowski * ice_vsi_ctx_clear_antispoof - clear antispoof function in VSI ctx 4221ff5411efSMichal Swiatkowski * @ctx: pointer to VSI ctx structure 4222ff5411efSMichal Swiatkowski */ 4223ff5411efSMichal Swiatkowski void ice_vsi_ctx_clear_antispoof(struct ice_vsi_ctx *ctx) 4224ff5411efSMichal Swiatkowski { 4225ff5411efSMichal Swiatkowski ctx->info.sec_flags &= ~ICE_AQ_VSI_SEC_FLAG_ENA_MAC_ANTI_SPOOF & 4226ff5411efSMichal Swiatkowski ~(ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA << 4227ff5411efSMichal Swiatkowski ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S); 4228ff5411efSMichal Swiatkowski } 4229ff5411efSMichal Swiatkowski 4230ff5411efSMichal Swiatkowski /** 4231ff5411efSMichal Swiatkowski * ice_vsi_ctx_set_allow_override - allow destination override on VSI 4232ff5411efSMichal Swiatkowski * @ctx: pointer to VSI ctx structure 4233ff5411efSMichal Swiatkowski */ 4234ff5411efSMichal Swiatkowski void ice_vsi_ctx_set_allow_override(struct ice_vsi_ctx *ctx) 4235ff5411efSMichal Swiatkowski { 4236ff5411efSMichal Swiatkowski ctx->info.sec_flags |= ICE_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD; 4237ff5411efSMichal Swiatkowski } 4238ff5411efSMichal Swiatkowski 4239ff5411efSMichal Swiatkowski /** 4240ff5411efSMichal Swiatkowski * ice_vsi_ctx_clear_allow_override - turn off destination override on VSI 4241ff5411efSMichal Swiatkowski * @ctx: pointer to VSI ctx structure 4242ff5411efSMichal Swiatkowski */ 4243ff5411efSMichal Swiatkowski void ice_vsi_ctx_clear_allow_override(struct ice_vsi_ctx *ctx) 4244ff5411efSMichal Swiatkowski { 4245ff5411efSMichal Swiatkowski ctx->info.sec_flags &= ~ICE_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD; 4246ff5411efSMichal Swiatkowski } 4247