1ae06c70bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0 251dce24bSJeff Kirsher /* Copyright(c) 2013 - 2018 Intel Corporation. */ 3e3219ce6SAnjali Singhai Jain 4e3219ce6SAnjali Singhai Jain #include <linux/list.h> 5e3219ce6SAnjali Singhai Jain #include <linux/errno.h> 6fe21b6c3SShiraz Saleem #include <linux/net/intel/i40e_client.h> 7e3219ce6SAnjali Singhai Jain 8e3219ce6SAnjali Singhai Jain #include "i40e.h" 9e3219ce6SAnjali Singhai Jain #include "i40e_prototype.h" 10e3219ce6SAnjali Singhai Jain 11e3219ce6SAnjali Singhai Jain static const char i40e_client_interface_version_str[] = I40E_CLIENT_VERSION_STR; 120ef2d5afSMitch Williams static struct i40e_client *registered_client; 13e3219ce6SAnjali Singhai Jain static LIST_HEAD(i40e_devices); 14e3219ce6SAnjali Singhai Jain static DEFINE_MUTEX(i40e_device_mutex); 15e3219ce6SAnjali Singhai Jain 16e3219ce6SAnjali Singhai Jain static int i40e_client_virtchnl_send(struct i40e_info *ldev, 17e3219ce6SAnjali Singhai Jain struct i40e_client *client, 18e3219ce6SAnjali Singhai Jain u32 vf_id, u8 *msg, u16 len); 19e3219ce6SAnjali Singhai Jain 20e3219ce6SAnjali Singhai Jain static int i40e_client_setup_qvlist(struct i40e_info *ldev, 21e3219ce6SAnjali Singhai Jain struct i40e_client *client, 22e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info); 23e3219ce6SAnjali Singhai Jain 24e3219ce6SAnjali Singhai Jain static void i40e_client_request_reset(struct i40e_info *ldev, 25e3219ce6SAnjali Singhai Jain struct i40e_client *client, 26e3219ce6SAnjali Singhai Jain u32 reset_level); 27e3219ce6SAnjali Singhai Jain 28e3219ce6SAnjali Singhai Jain static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, 29e3219ce6SAnjali Singhai Jain struct i40e_client *client, 30e3219ce6SAnjali Singhai Jain bool is_vf, u32 vf_id, 31e3219ce6SAnjali Singhai Jain u32 flag, u32 valid_flag); 32e3219ce6SAnjali Singhai Jain 33e3219ce6SAnjali Singhai Jain static struct i40e_ops i40e_lan_ops = { 34e3219ce6SAnjali Singhai Jain .virtchnl_send = i40e_client_virtchnl_send, 35e3219ce6SAnjali Singhai Jain .setup_qvlist = i40e_client_setup_qvlist, 36e3219ce6SAnjali Singhai Jain .request_reset = i40e_client_request_reset, 37e3219ce6SAnjali Singhai Jain .update_vsi_ctxt = i40e_client_update_vsi_ctxt, 38e3219ce6SAnjali Singhai Jain }; 39e3219ce6SAnjali Singhai Jain 40e3219ce6SAnjali Singhai Jain /** 41e3219ce6SAnjali Singhai Jain * i40e_client_get_params - Get the params that can change at runtime 42e3219ce6SAnjali Singhai Jain * @vsi: the VSI with the message 43f5254429SJacob Keller * @params: client param struct 44e3219ce6SAnjali Singhai Jain * 45e3219ce6SAnjali Singhai Jain **/ 46e3219ce6SAnjali Singhai Jain static 47e3219ce6SAnjali Singhai Jain int i40e_client_get_params(struct i40e_vsi *vsi, struct i40e_params *params) 48e3219ce6SAnjali Singhai Jain { 49e3219ce6SAnjali Singhai Jain struct i40e_dcbx_config *dcb_cfg = &vsi->back->hw.local_dcbx_config; 50e3219ce6SAnjali Singhai Jain int i = 0; 51e3219ce6SAnjali Singhai Jain 52e3219ce6SAnjali Singhai Jain for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { 53e3219ce6SAnjali Singhai Jain u8 tc = dcb_cfg->etscfg.prioritytable[i]; 54e3219ce6SAnjali Singhai Jain u16 qs_handle; 55e3219ce6SAnjali Singhai Jain 56e3219ce6SAnjali Singhai Jain /* If TC is not enabled for VSI use TC0 for UP */ 57e3219ce6SAnjali Singhai Jain if (!(vsi->tc_config.enabled_tc & BIT(tc))) 58e3219ce6SAnjali Singhai Jain tc = 0; 59e3219ce6SAnjali Singhai Jain 60e3219ce6SAnjali Singhai Jain qs_handle = le16_to_cpu(vsi->info.qs_handle[tc]); 61e3219ce6SAnjali Singhai Jain params->qos.prio_qos[i].tc = tc; 62e3219ce6SAnjali Singhai Jain params->qos.prio_qos[i].qs_handle = qs_handle; 63e3219ce6SAnjali Singhai Jain if (qs_handle == I40E_AQ_VSI_QS_HANDLE_INVALID) { 64e3219ce6SAnjali Singhai Jain dev_err(&vsi->back->pdev->dev, "Invalid queue set handle for TC = %d, vsi id = %d\n", 65e3219ce6SAnjali Singhai Jain tc, vsi->id); 66e3219ce6SAnjali Singhai Jain return -EINVAL; 67e3219ce6SAnjali Singhai Jain } 68e3219ce6SAnjali Singhai Jain } 69e3219ce6SAnjali Singhai Jain 70e3219ce6SAnjali Singhai Jain params->mtu = vsi->netdev->mtu; 71e3219ce6SAnjali Singhai Jain return 0; 72e3219ce6SAnjali Singhai Jain } 73e3219ce6SAnjali Singhai Jain 74e3219ce6SAnjali Singhai Jain /** 75e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_msg - call the client vf message callback 76e3219ce6SAnjali Singhai Jain * @vsi: the VSI with the message 77e3219ce6SAnjali Singhai Jain * @vf_id: the absolute VF id that sent the message 78e3219ce6SAnjali Singhai Jain * @msg: message buffer 79e3219ce6SAnjali Singhai Jain * @len: length of the message 80e3219ce6SAnjali Singhai Jain * 81e3219ce6SAnjali Singhai Jain * If there is a client to this VSI, call the client 82e3219ce6SAnjali Singhai Jain **/ 83e3219ce6SAnjali Singhai Jain void 84e3219ce6SAnjali Singhai Jain i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id, u8 *msg, u16 len) 85e3219ce6SAnjali Singhai Jain { 860ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 870ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 88e3219ce6SAnjali Singhai Jain 890ef2d5afSMitch Williams if (!cdev || !cdev->client) 90e3219ce6SAnjali Singhai Jain return; 910ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->virtchnl_receive) { 920ef2d5afSMitch Williams dev_dbg(&pf->pdev->dev, 93e3219ce6SAnjali Singhai Jain "Cannot locate client instance virtual channel receive routine\n"); 940ef2d5afSMitch Williams return; 95e3219ce6SAnjali Singhai Jain } 960ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 970ef2d5afSMitch Williams dev_dbg(&pf->pdev->dev, "Client is not open, abort virtchnl_receive\n"); 980ef2d5afSMitch Williams return; 9991cdca4fSCatherine Sullivan } 1000ef2d5afSMitch Williams cdev->client->ops->virtchnl_receive(&cdev->lan_info, cdev->client, 101e3219ce6SAnjali Singhai Jain vf_id, msg, len); 102e3219ce6SAnjali Singhai Jain } 103e3219ce6SAnjali Singhai Jain 104e3219ce6SAnjali Singhai Jain /** 105e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_l2_param_changes - call the client notify callback 106e3219ce6SAnjali Singhai Jain * @vsi: the VSI with l2 param changes 107e3219ce6SAnjali Singhai Jain * 108e3219ce6SAnjali Singhai Jain * If there is a client to this VSI, call the client 109e3219ce6SAnjali Singhai Jain **/ 110e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi) 111e3219ce6SAnjali Singhai Jain { 1120ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 1130ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 114e3219ce6SAnjali Singhai Jain struct i40e_params params; 115e3219ce6SAnjali Singhai Jain 1160ef2d5afSMitch Williams if (!cdev || !cdev->client) 117e3219ce6SAnjali Singhai Jain return; 1180ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->l2_param_change) { 119e3219ce6SAnjali Singhai Jain dev_dbg(&vsi->back->pdev->dev, 120e3219ce6SAnjali Singhai Jain "Cannot locate client instance l2_param_change routine\n"); 1210ef2d5afSMitch Williams return; 122e3219ce6SAnjali Singhai Jain } 1230ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 12491cdca4fSCatherine Sullivan dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort l2 param change\n"); 1250ef2d5afSMitch Williams return; 12691cdca4fSCatherine Sullivan } 1277be147dcSJacob Keller memset(¶ms, 0, sizeof(params)); 1287be147dcSJacob Keller i40e_client_get_params(vsi, ¶ms); 1290ef2d5afSMitch Williams memcpy(&cdev->lan_info.params, ¶ms, sizeof(struct i40e_params)); 1300ef2d5afSMitch Williams cdev->client->ops->l2_param_change(&cdev->lan_info, cdev->client, 131e3219ce6SAnjali Singhai Jain ¶ms); 132e3219ce6SAnjali Singhai Jain } 133e3219ce6SAnjali Singhai Jain 134e3219ce6SAnjali Singhai Jain /** 1350ef2d5afSMitch Williams * i40e_client_release_qvlist - release MSI-X vector mapping for client 136e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 137e3219ce6SAnjali Singhai Jain * 138e3219ce6SAnjali Singhai Jain **/ 139e3219ce6SAnjali Singhai Jain static void i40e_client_release_qvlist(struct i40e_info *ldev) 140e3219ce6SAnjali Singhai Jain { 141e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info = ldev->qvlist_info; 142e3219ce6SAnjali Singhai Jain u32 i; 143e3219ce6SAnjali Singhai Jain 144e3219ce6SAnjali Singhai Jain if (!ldev->qvlist_info) 145e3219ce6SAnjali Singhai Jain return; 146e3219ce6SAnjali Singhai Jain 147e3219ce6SAnjali Singhai Jain for (i = 0; i < qvlist_info->num_vectors; i++) { 148e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 149e3219ce6SAnjali Singhai Jain struct i40e_qv_info *qv_info; 150e3219ce6SAnjali Singhai Jain u32 reg_idx; 151e3219ce6SAnjali Singhai Jain 152e3219ce6SAnjali Singhai Jain qv_info = &qvlist_info->qv_info[i]; 153e3219ce6SAnjali Singhai Jain if (!qv_info) 154e3219ce6SAnjali Singhai Jain continue; 155e3219ce6SAnjali Singhai Jain reg_idx = I40E_PFINT_LNKLSTN(qv_info->v_idx - 1); 156e3219ce6SAnjali Singhai Jain wr32(&pf->hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK); 157e3219ce6SAnjali Singhai Jain } 158e3219ce6SAnjali Singhai Jain kfree(ldev->qvlist_info); 159e3219ce6SAnjali Singhai Jain ldev->qvlist_info = NULL; 160e3219ce6SAnjali Singhai Jain } 161e3219ce6SAnjali Singhai Jain 162e3219ce6SAnjali Singhai Jain /** 163e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_netdev_close - call the client close callback 164e3219ce6SAnjali Singhai Jain * @vsi: the VSI with netdev closed 165e3219ce6SAnjali Singhai Jain * @reset: true when close called due to a reset pending 166e3219ce6SAnjali Singhai Jain * 167e3219ce6SAnjali Singhai Jain * If there is a client to this netdev, call the client with close 168e3219ce6SAnjali Singhai Jain **/ 169e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset) 170e3219ce6SAnjali Singhai Jain { 1710ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 1720ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 173e3219ce6SAnjali Singhai Jain 1740ef2d5afSMitch Williams if (!cdev || !cdev->client) 175e3219ce6SAnjali Singhai Jain return; 1760ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->close) { 177e3219ce6SAnjali Singhai Jain dev_dbg(&vsi->back->pdev->dev, 178e3219ce6SAnjali Singhai Jain "Cannot locate client instance close routine\n"); 1790ef2d5afSMitch Williams return; 180e3219ce6SAnjali Singhai Jain } 1810ef2d5afSMitch Williams cdev->client->ops->close(&cdev->lan_info, cdev->client, reset); 1827be96322SMitch Williams clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 183e3219ce6SAnjali Singhai Jain i40e_client_release_qvlist(&cdev->lan_info); 184e3219ce6SAnjali Singhai Jain } 185e3219ce6SAnjali Singhai Jain 186e3219ce6SAnjali Singhai Jain /** 187e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_reset - call the client vf reset callback 188e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 189e3219ce6SAnjali Singhai Jain * @vf_id: asolute id of VF being reset 190e3219ce6SAnjali Singhai Jain * 191e3219ce6SAnjali Singhai Jain * If there is a client attached to this PF, notify when a VF is reset 192e3219ce6SAnjali Singhai Jain **/ 193e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id) 194e3219ce6SAnjali Singhai Jain { 1950ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 196e3219ce6SAnjali Singhai Jain 1970ef2d5afSMitch Williams if (!cdev || !cdev->client) 198e3219ce6SAnjali Singhai Jain return; 1990ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_reset) { 200e3219ce6SAnjali Singhai Jain dev_dbg(&pf->pdev->dev, 201e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF reset routine\n"); 2020ef2d5afSMitch Williams return; 203e3219ce6SAnjali Singhai Jain } 2040ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 20591cdca4fSCatherine Sullivan dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-reset\n"); 2060ef2d5afSMitch Williams return; 20791cdca4fSCatherine Sullivan } 2080ef2d5afSMitch Williams cdev->client->ops->vf_reset(&cdev->lan_info, cdev->client, vf_id); 209e3219ce6SAnjali Singhai Jain } 210e3219ce6SAnjali Singhai Jain 211e3219ce6SAnjali Singhai Jain /** 212e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_enable - call the client vf notification callback 213e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 214e3219ce6SAnjali Singhai Jain * @num_vfs: the number of VFs currently enabled, 0 for disable 215e3219ce6SAnjali Singhai Jain * 216e3219ce6SAnjali Singhai Jain * If there is a client attached to this PF, call its VF notification routine 217e3219ce6SAnjali Singhai Jain **/ 218e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs) 219e3219ce6SAnjali Singhai Jain { 2200ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 221e3219ce6SAnjali Singhai Jain 2220ef2d5afSMitch Williams if (!cdev || !cdev->client) 223e3219ce6SAnjali Singhai Jain return; 2240ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_enable) { 225e3219ce6SAnjali Singhai Jain dev_dbg(&pf->pdev->dev, 226e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF enable routine\n"); 2270ef2d5afSMitch Williams return; 228e3219ce6SAnjali Singhai Jain } 22991cdca4fSCatherine Sullivan if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, 23091cdca4fSCatherine Sullivan &cdev->state)) { 23191cdca4fSCatherine Sullivan dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-enable\n"); 2320ef2d5afSMitch Williams return; 23391cdca4fSCatherine Sullivan } 2340ef2d5afSMitch Williams cdev->client->ops->vf_enable(&cdev->lan_info, cdev->client, num_vfs); 235e3219ce6SAnjali Singhai Jain } 236e3219ce6SAnjali Singhai Jain 237e3219ce6SAnjali Singhai Jain /** 238e3219ce6SAnjali Singhai Jain * i40e_vf_client_capable - ask the client if it likes the specified VF 239e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 240e3219ce6SAnjali Singhai Jain * @vf_id: the VF in question 241e3219ce6SAnjali Singhai Jain * 242e3219ce6SAnjali Singhai Jain * If there is a client of the specified type attached to this PF, call 243e3219ce6SAnjali Singhai Jain * its vf_capable routine 244e3219ce6SAnjali Singhai Jain **/ 2450ef2d5afSMitch Williams int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id) 246e3219ce6SAnjali Singhai Jain { 2470ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 248e3219ce6SAnjali Singhai Jain int capable = false; 249e3219ce6SAnjali Singhai Jain 2500ef2d5afSMitch Williams if (!cdev || !cdev->client) 2510ef2d5afSMitch Williams goto out; 2520ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_capable) { 25359e331e3SJacob Keller dev_dbg(&pf->pdev->dev, 254e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF capability routine\n"); 2550ef2d5afSMitch Williams goto out; 256e3219ce6SAnjali Singhai Jain } 2570ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) 2580ef2d5afSMitch Williams goto out; 2590ef2d5afSMitch Williams 260e3219ce6SAnjali Singhai Jain capable = cdev->client->ops->vf_capable(&cdev->lan_info, 261e3219ce6SAnjali Singhai Jain cdev->client, 262e3219ce6SAnjali Singhai Jain vf_id); 2630ef2d5afSMitch Williams out: 264e3219ce6SAnjali Singhai Jain return capable; 265e3219ce6SAnjali Singhai Jain } 266e3219ce6SAnjali Singhai Jain 267ddbb8d5dSShiraz Saleem void i40e_client_update_msix_info(struct i40e_pf *pf) 268ddbb8d5dSShiraz Saleem { 269ddbb8d5dSShiraz Saleem struct i40e_client_instance *cdev = pf->cinst; 270ddbb8d5dSShiraz Saleem 271ddbb8d5dSShiraz Saleem if (!cdev || !cdev->client) 272ddbb8d5dSShiraz Saleem return; 273ddbb8d5dSShiraz Saleem 274ddbb8d5dSShiraz Saleem cdev->lan_info.msix_count = pf->num_iwarp_msix; 275ddbb8d5dSShiraz Saleem cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector]; 276ddbb8d5dSShiraz Saleem } 277ddbb8d5dSShiraz Saleem 278e3219ce6SAnjali Singhai Jain /** 279e3219ce6SAnjali Singhai Jain * i40e_client_add_instance - add a client instance struct to the instance list 280e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 281e3219ce6SAnjali Singhai Jain * 282e3219ce6SAnjali Singhai Jain **/ 2830ef2d5afSMitch Williams static void i40e_client_add_instance(struct i40e_pf *pf) 284e3219ce6SAnjali Singhai Jain { 2850ef2d5afSMitch Williams struct i40e_client_instance *cdev = NULL; 286e3219ce6SAnjali Singhai Jain struct netdev_hw_addr *mac = NULL; 287e3219ce6SAnjali Singhai Jain struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 288e3219ce6SAnjali Singhai Jain 2890ef2d5afSMitch Williams if (!registered_client || pf->cinst) 2900ef2d5afSMitch Williams return; 2910ef2d5afSMitch Williams 292e3219ce6SAnjali Singhai Jain cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 293e3219ce6SAnjali Singhai Jain if (!cdev) 2940ef2d5afSMitch Williams return; 295e3219ce6SAnjali Singhai Jain 296e3219ce6SAnjali Singhai Jain cdev->lan_info.pf = (void *)pf; 297e3219ce6SAnjali Singhai Jain cdev->lan_info.netdev = vsi->netdev; 298e3219ce6SAnjali Singhai Jain cdev->lan_info.pcidev = pf->pdev; 299e3219ce6SAnjali Singhai Jain cdev->lan_info.fid = pf->hw.pf_id; 300e3219ce6SAnjali Singhai Jain cdev->lan_info.ftype = I40E_CLIENT_FTYPE_PF; 301e3219ce6SAnjali Singhai Jain cdev->lan_info.hw_addr = pf->hw.hw_addr; 302e3219ce6SAnjali Singhai Jain cdev->lan_info.ops = &i40e_lan_ops; 303e3219ce6SAnjali Singhai Jain cdev->lan_info.version.major = I40E_CLIENT_VERSION_MAJOR; 304e3219ce6SAnjali Singhai Jain cdev->lan_info.version.minor = I40E_CLIENT_VERSION_MINOR; 305e3219ce6SAnjali Singhai Jain cdev->lan_info.version.build = I40E_CLIENT_VERSION_BUILD; 306e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_maj_ver = pf->hw.aq.fw_maj_ver; 307e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_min_ver = pf->hw.aq.fw_min_ver; 308e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_build = pf->hw.aq.fw_build; 309e3219ce6SAnjali Singhai Jain set_bit(__I40E_CLIENT_INSTANCE_NONE, &cdev->state); 310e3219ce6SAnjali Singhai Jain 311e3219ce6SAnjali Singhai Jain if (i40e_client_get_params(vsi, &cdev->lan_info.params)) { 312e3219ce6SAnjali Singhai Jain kfree(cdev); 313e3219ce6SAnjali Singhai Jain cdev = NULL; 3140ef2d5afSMitch Williams return; 315e3219ce6SAnjali Singhai Jain } 316e3219ce6SAnjali Singhai Jain 317e3219ce6SAnjali Singhai Jain mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list, 318e3219ce6SAnjali Singhai Jain struct netdev_hw_addr, list); 319e3219ce6SAnjali Singhai Jain if (mac) 320e3219ce6SAnjali Singhai Jain ether_addr_copy(cdev->lan_info.lanmac, mac->addr); 321e3219ce6SAnjali Singhai Jain else 322e3219ce6SAnjali Singhai Jain dev_err(&pf->pdev->dev, "MAC address list is empty!\n"); 323e3219ce6SAnjali Singhai Jain 3240ef2d5afSMitch Williams cdev->client = registered_client; 3250ef2d5afSMitch Williams pf->cinst = cdev; 326ddbb8d5dSShiraz Saleem 327ddbb8d5dSShiraz Saleem i40e_client_update_msix_info(pf); 328e3219ce6SAnjali Singhai Jain } 329e3219ce6SAnjali Singhai Jain 330e3219ce6SAnjali Singhai Jain /** 331e3219ce6SAnjali Singhai Jain * i40e_client_del_instance - removes a client instance from the list 332e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 333e3219ce6SAnjali Singhai Jain * 334e3219ce6SAnjali Singhai Jain **/ 335e3219ce6SAnjali Singhai Jain static 3360ef2d5afSMitch Williams void i40e_client_del_instance(struct i40e_pf *pf) 337e3219ce6SAnjali Singhai Jain { 3380ef2d5afSMitch Williams kfree(pf->cinst); 3390ef2d5afSMitch Williams pf->cinst = NULL; 340e3219ce6SAnjali Singhai Jain } 341e3219ce6SAnjali Singhai Jain 342e3219ce6SAnjali Singhai Jain /** 343e3219ce6SAnjali Singhai Jain * i40e_client_subtask - client maintenance work 344e3219ce6SAnjali Singhai Jain * @pf: board private structure 345e3219ce6SAnjali Singhai Jain **/ 346e3219ce6SAnjali Singhai Jain void i40e_client_subtask(struct i40e_pf *pf) 347e3219ce6SAnjali Singhai Jain { 3480ef2d5afSMitch Williams struct i40e_client *client = registered_client; 349e3219ce6SAnjali Singhai Jain struct i40e_client_instance *cdev; 3500ef2d5afSMitch Williams struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 351e3219ce6SAnjali Singhai Jain int ret = 0; 352e3219ce6SAnjali Singhai Jain 3535f76a704SJacob Keller if (!test_and_clear_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state)) 354e3219ce6SAnjali Singhai Jain return; 3550ef2d5afSMitch Williams cdev = pf->cinst; 356e3219ce6SAnjali Singhai Jain 357e3219ce6SAnjali Singhai Jain /* If we're down or resetting, just bail */ 3580da36b97SJacob Keller if (test_bit(__I40E_DOWN, pf->state) || 3590da36b97SJacob Keller test_bit(__I40E_CONFIG_BUSY, pf->state)) 360e3219ce6SAnjali Singhai Jain return; 361e3219ce6SAnjali Singhai Jain 3620ef2d5afSMitch Williams if (!client || !cdev) 3630ef2d5afSMitch Williams return; 364e3219ce6SAnjali Singhai Jain 3657b0b1a6dSShiraz Saleem /* Here we handle client opens. If the client is down, and 3667b0b1a6dSShiraz Saleem * the netdev is registered, then open the client. 3670ef2d5afSMitch Williams */ 3680ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 3697b0b1a6dSShiraz Saleem if (vsi->netdev_registered && 3700ef2d5afSMitch Williams client->ops && client->ops->open) { 3710ef2d5afSMitch Williams set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 3720ef2d5afSMitch Williams ret = client->ops->open(&cdev->lan_info, client); 3730ef2d5afSMitch Williams if (ret) { 3740ef2d5afSMitch Williams /* Remove failed client instance */ 3750ef2d5afSMitch Williams clear_bit(__I40E_CLIENT_INSTANCE_OPENED, 3767be96322SMitch Williams &cdev->state); 3770ef2d5afSMitch Williams i40e_client_del_instance(pf); 37838318f23SYunjian Wang return; 3790ef2d5afSMitch Williams } 3800ef2d5afSMitch Williams } 3817b0b1a6dSShiraz Saleem } 3827b0b1a6dSShiraz Saleem 3837b0b1a6dSShiraz Saleem /* enable/disable PE TCP_ENA flag based on netdev down/up 3840ef2d5afSMitch Williams */ 3857b0b1a6dSShiraz Saleem if (test_bit(__I40E_VSI_DOWN, vsi->state)) 3867b0b1a6dSShiraz Saleem i40e_client_update_vsi_ctxt(&cdev->lan_info, client, 3877b0b1a6dSShiraz Saleem 0, 0, 0, 3887b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE); 3897b0b1a6dSShiraz Saleem else 3907b0b1a6dSShiraz Saleem i40e_client_update_vsi_ctxt(&cdev->lan_info, client, 3917b0b1a6dSShiraz Saleem 0, 0, 3927b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE, 3937b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE); 394e3219ce6SAnjali Singhai Jain } 395e3219ce6SAnjali Singhai Jain 396e3219ce6SAnjali Singhai Jain /** 397e3219ce6SAnjali Singhai Jain * i40e_lan_add_device - add a lan device struct to the list of lan devices 398e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 399e3219ce6SAnjali Singhai Jain * 400e3219ce6SAnjali Singhai Jain * Returns 0 on success or none 0 on error 401e3219ce6SAnjali Singhai Jain **/ 402e3219ce6SAnjali Singhai Jain int i40e_lan_add_device(struct i40e_pf *pf) 403e3219ce6SAnjali Singhai Jain { 404e3219ce6SAnjali Singhai Jain struct i40e_device *ldev; 405e3219ce6SAnjali Singhai Jain int ret = 0; 406e3219ce6SAnjali Singhai Jain 407e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 408e3219ce6SAnjali Singhai Jain list_for_each_entry(ldev, &i40e_devices, list) { 409e3219ce6SAnjali Singhai Jain if (ldev->pf == pf) { 410e3219ce6SAnjali Singhai Jain ret = -EEXIST; 411e3219ce6SAnjali Singhai Jain goto out; 412e3219ce6SAnjali Singhai Jain } 413e3219ce6SAnjali Singhai Jain } 414e3219ce6SAnjali Singhai Jain ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); 415e3219ce6SAnjali Singhai Jain if (!ldev) { 416e3219ce6SAnjali Singhai Jain ret = -ENOMEM; 417e3219ce6SAnjali Singhai Jain goto out; 418e3219ce6SAnjali Singhai Jain } 419e3219ce6SAnjali Singhai Jain ldev->pf = pf; 420e3219ce6SAnjali Singhai Jain INIT_LIST_HEAD(&ldev->list); 421e3219ce6SAnjali Singhai Jain list_add(&ldev->list, &i40e_devices); 422b3f028fcSSudheer Mogilappagari dev_info(&pf->pdev->dev, "Added LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n", 423b3f028fcSSudheer Mogilappagari pf->hw.pf_id, pf->hw.bus.bus_id, 424b3f028fcSSudheer Mogilappagari pf->hw.bus.device, pf->hw.bus.func); 425e3219ce6SAnjali Singhai Jain 4268090f618SMitch Williams /* If a client has already been registered, we need to add an instance 4278090f618SMitch Williams * of it to our new LAN device. 4288090f618SMitch Williams */ 4298090f618SMitch Williams if (registered_client) 4308090f618SMitch Williams i40e_client_add_instance(pf); 4318090f618SMitch Williams 432e3219ce6SAnjali Singhai Jain /* Since in some cases register may have happened before a device gets 433f38ff2eeSAnjali Singhai Jain * added, we can schedule a subtask to go initiate the clients if 434f38ff2eeSAnjali Singhai Jain * they can be launched at probe time. 435e3219ce6SAnjali Singhai Jain */ 4365f76a704SJacob Keller set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state); 437e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 438e3219ce6SAnjali Singhai Jain 439e3219ce6SAnjali Singhai Jain out: 440e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 441e3219ce6SAnjali Singhai Jain return ret; 442e3219ce6SAnjali Singhai Jain } 443e3219ce6SAnjali Singhai Jain 444e3219ce6SAnjali Singhai Jain /** 445e3219ce6SAnjali Singhai Jain * i40e_lan_del_device - removes a lan device from the device list 446e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 447e3219ce6SAnjali Singhai Jain * 448e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 449e3219ce6SAnjali Singhai Jain **/ 450e3219ce6SAnjali Singhai Jain int i40e_lan_del_device(struct i40e_pf *pf) 451e3219ce6SAnjali Singhai Jain { 452e3219ce6SAnjali Singhai Jain struct i40e_device *ldev, *tmp; 453e3219ce6SAnjali Singhai Jain int ret = -ENODEV; 454e3219ce6SAnjali Singhai Jain 455295c0a55SMitch Williams /* First, remove any client instance. */ 456295c0a55SMitch Williams i40e_client_del_instance(pf); 457295c0a55SMitch Williams 458e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 459e3219ce6SAnjali Singhai Jain list_for_each_entry_safe(ldev, tmp, &i40e_devices, list) { 460e3219ce6SAnjali Singhai Jain if (ldev->pf == pf) { 461b3f028fcSSudheer Mogilappagari dev_info(&pf->pdev->dev, "Deleted LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n", 462b3f028fcSSudheer Mogilappagari pf->hw.pf_id, pf->hw.bus.bus_id, 463b3f028fcSSudheer Mogilappagari pf->hw.bus.device, pf->hw.bus.func); 464e3219ce6SAnjali Singhai Jain list_del(&ldev->list); 465e3219ce6SAnjali Singhai Jain kfree(ldev); 466e3219ce6SAnjali Singhai Jain ret = 0; 467e3219ce6SAnjali Singhai Jain break; 468e3219ce6SAnjali Singhai Jain } 469e3219ce6SAnjali Singhai Jain } 470e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 471e3219ce6SAnjali Singhai Jain return ret; 472e3219ce6SAnjali Singhai Jain } 473e3219ce6SAnjali Singhai Jain 474e3219ce6SAnjali Singhai Jain /** 475e3219ce6SAnjali Singhai Jain * i40e_client_release - release client specific resources 476e3219ce6SAnjali Singhai Jain * @client: pointer to the registered client 477e3219ce6SAnjali Singhai Jain * 478e3219ce6SAnjali Singhai Jain **/ 4790ef2d5afSMitch Williams static void i40e_client_release(struct i40e_client *client) 480e3219ce6SAnjali Singhai Jain { 4810ef2d5afSMitch Williams struct i40e_client_instance *cdev; 4820ef2d5afSMitch Williams struct i40e_device *ldev; 483682d11d7SHarshitha Ramamurthy struct i40e_pf *pf; 484e3219ce6SAnjali Singhai Jain 4850ef2d5afSMitch Williams mutex_lock(&i40e_device_mutex); 4860ef2d5afSMitch Williams list_for_each_entry(ldev, &i40e_devices, list) { 4870ef2d5afSMitch Williams pf = ldev->pf; 4880ef2d5afSMitch Williams cdev = pf->cinst; 4890ef2d5afSMitch Williams if (!cdev) 490e3219ce6SAnjali Singhai Jain continue; 4910ef2d5afSMitch Williams 4920ef2d5afSMitch Williams while (test_and_set_bit(__I40E_SERVICE_SCHED, 4930da36b97SJacob Keller pf->state)) 4940ef2d5afSMitch Williams usleep_range(500, 1000); 4950ef2d5afSMitch Williams 496e3219ce6SAnjali Singhai Jain if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 497e3219ce6SAnjali Singhai Jain if (client->ops && client->ops->close) 498e3219ce6SAnjali Singhai Jain client->ops->close(&cdev->lan_info, client, 499e3219ce6SAnjali Singhai Jain false); 500e3219ce6SAnjali Singhai Jain i40e_client_release_qvlist(&cdev->lan_info); 501e3219ce6SAnjali Singhai Jain clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 502e3219ce6SAnjali Singhai Jain 503e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 504e3219ce6SAnjali Singhai Jain "Client %s instance for PF id %d closed\n", 505e3219ce6SAnjali Singhai Jain client->name, pf->hw.pf_id); 506e3219ce6SAnjali Singhai Jain } 5070ef2d5afSMitch Williams /* delete the client instance */ 5080ef2d5afSMitch Williams i40e_client_del_instance(pf); 509e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, "Deleted client instance of Client %s\n", 510e3219ce6SAnjali Singhai Jain client->name); 5110da36b97SJacob Keller clear_bit(__I40E_SERVICE_SCHED, pf->state); 512e3219ce6SAnjali Singhai Jain } 5130ef2d5afSMitch Williams mutex_unlock(&i40e_device_mutex); 514e3219ce6SAnjali Singhai Jain } 515e3219ce6SAnjali Singhai Jain 516e3219ce6SAnjali Singhai Jain /** 517e3219ce6SAnjali Singhai Jain * i40e_client_prepare - prepare client specific resources 518e3219ce6SAnjali Singhai Jain * @client: pointer to the registered client 519e3219ce6SAnjali Singhai Jain * 520e3219ce6SAnjali Singhai Jain **/ 5213bb83bafSMitch Williams static void i40e_client_prepare(struct i40e_client *client) 522e3219ce6SAnjali Singhai Jain { 523e3219ce6SAnjali Singhai Jain struct i40e_device *ldev; 524e3219ce6SAnjali Singhai Jain struct i40e_pf *pf; 525e3219ce6SAnjali Singhai Jain 526e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 527e3219ce6SAnjali Singhai Jain list_for_each_entry(ldev, &i40e_devices, list) { 528e3219ce6SAnjali Singhai Jain pf = ldev->pf; 5290ef2d5afSMitch Williams i40e_client_add_instance(pf); 530e3219ce6SAnjali Singhai Jain /* Start the client subtask */ 5315f76a704SJacob Keller set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state); 532e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 533e3219ce6SAnjali Singhai Jain } 534e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 535e3219ce6SAnjali Singhai Jain } 536e3219ce6SAnjali Singhai Jain 537e3219ce6SAnjali Singhai Jain /** 538e3219ce6SAnjali Singhai Jain * i40e_client_virtchnl_send - TBD 539e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context 540e3219ce6SAnjali Singhai Jain * @client: Client pointer 541e3219ce6SAnjali Singhai Jain * @vf_id: absolute VF identifier 542e3219ce6SAnjali Singhai Jain * @msg: message buffer 543e3219ce6SAnjali Singhai Jain * @len: length of message buffer 544e3219ce6SAnjali Singhai Jain * 545e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 546e3219ce6SAnjali Singhai Jain **/ 547e3219ce6SAnjali Singhai Jain static int i40e_client_virtchnl_send(struct i40e_info *ldev, 548e3219ce6SAnjali Singhai Jain struct i40e_client *client, 549e3219ce6SAnjali Singhai Jain u32 vf_id, u8 *msg, u16 len) 550e3219ce6SAnjali Singhai Jain { 551e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 552e3219ce6SAnjali Singhai Jain struct i40e_hw *hw = &pf->hw; 553e3219ce6SAnjali Singhai Jain i40e_status err; 554e3219ce6SAnjali Singhai Jain 555310a2ad9SJesse Brandeburg err = i40e_aq_send_msg_to_vf(hw, vf_id, VIRTCHNL_OP_IWARP, 556e3219ce6SAnjali Singhai Jain 0, msg, len, NULL); 557e3219ce6SAnjali Singhai Jain if (err) 558e3219ce6SAnjali Singhai Jain dev_err(&pf->pdev->dev, "Unable to send iWarp message to VF, error %d, aq status %d\n", 559e3219ce6SAnjali Singhai Jain err, hw->aq.asq_last_status); 560e3219ce6SAnjali Singhai Jain 561e3219ce6SAnjali Singhai Jain return err; 562e3219ce6SAnjali Singhai Jain } 563e3219ce6SAnjali Singhai Jain 564e3219ce6SAnjali Singhai Jain /** 565e3219ce6SAnjali Singhai Jain * i40e_client_setup_qvlist 566e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 567e3219ce6SAnjali Singhai Jain * @client: Client pointer. 568f5254429SJacob Keller * @qvlist_info: queue and vector list 569e3219ce6SAnjali Singhai Jain * 570e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 571e3219ce6SAnjali Singhai Jain **/ 572e3219ce6SAnjali Singhai Jain static int i40e_client_setup_qvlist(struct i40e_info *ldev, 573e3219ce6SAnjali Singhai Jain struct i40e_client *client, 574e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info) 575e3219ce6SAnjali Singhai Jain { 576e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 577e3219ce6SAnjali Singhai Jain struct i40e_hw *hw = &pf->hw; 578e3219ce6SAnjali Singhai Jain struct i40e_qv_info *qv_info; 579e3219ce6SAnjali Singhai Jain u32 v_idx, i, reg_idx, reg; 580e3219ce6SAnjali Singhai Jain 581825f0a4eSGustavo A. R. Silva ldev->qvlist_info = kzalloc(struct_size(ldev->qvlist_info, qv_info, 582*125217e0SGustavo A. R. Silva qvlist_info->num_vectors), GFP_KERNEL); 5830a4ecc2cSChristophe Jaillet if (!ldev->qvlist_info) 5840a4ecc2cSChristophe Jaillet return -ENOMEM; 585e3219ce6SAnjali Singhai Jain ldev->qvlist_info->num_vectors = qvlist_info->num_vectors; 586e3219ce6SAnjali Singhai Jain 587e3219ce6SAnjali Singhai Jain for (i = 0; i < qvlist_info->num_vectors; i++) { 588e3219ce6SAnjali Singhai Jain qv_info = &qvlist_info->qv_info[i]; 589e3219ce6SAnjali Singhai Jain if (!qv_info) 590e3219ce6SAnjali Singhai Jain continue; 591e3219ce6SAnjali Singhai Jain v_idx = qv_info->v_idx; 592e3219ce6SAnjali Singhai Jain 593e3219ce6SAnjali Singhai Jain /* Validate vector id belongs to this client */ 594e3219ce6SAnjali Singhai Jain if ((v_idx >= (pf->iwarp_base_vector + pf->num_iwarp_msix)) || 595e3219ce6SAnjali Singhai Jain (v_idx < pf->iwarp_base_vector)) 596e3219ce6SAnjali Singhai Jain goto err; 597e3219ce6SAnjali Singhai Jain 598e3219ce6SAnjali Singhai Jain ldev->qvlist_info->qv_info[i] = *qv_info; 599e3219ce6SAnjali Singhai Jain reg_idx = I40E_PFINT_LNKLSTN(v_idx - 1); 600e3219ce6SAnjali Singhai Jain 601e3219ce6SAnjali Singhai Jain if (qv_info->ceq_idx == I40E_QUEUE_INVALID_IDX) { 602e3219ce6SAnjali Singhai Jain /* Special case - No CEQ mapped on this vector */ 603e3219ce6SAnjali Singhai Jain wr32(hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK); 604e3219ce6SAnjali Singhai Jain } else { 605e3219ce6SAnjali Singhai Jain reg = (qv_info->ceq_idx & 606e3219ce6SAnjali Singhai Jain I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK) | 607e3219ce6SAnjali Singhai Jain (I40E_QUEUE_TYPE_PE_CEQ << 608e3219ce6SAnjali Singhai Jain I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT); 609e3219ce6SAnjali Singhai Jain wr32(hw, reg_idx, reg); 610e3219ce6SAnjali Singhai Jain 611e3219ce6SAnjali Singhai Jain reg = (I40E_PFINT_CEQCTL_CAUSE_ENA_MASK | 612e3219ce6SAnjali Singhai Jain (v_idx << I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT) | 613e3219ce6SAnjali Singhai Jain (qv_info->itr_idx << 614e3219ce6SAnjali Singhai Jain I40E_PFINT_CEQCTL_ITR_INDX_SHIFT) | 615e3219ce6SAnjali Singhai Jain (I40E_QUEUE_END_OF_LIST << 616e3219ce6SAnjali Singhai Jain I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)); 617e3219ce6SAnjali Singhai Jain wr32(hw, I40E_PFINT_CEQCTL(qv_info->ceq_idx), reg); 618e3219ce6SAnjali Singhai Jain } 619e3219ce6SAnjali Singhai Jain if (qv_info->aeq_idx != I40E_QUEUE_INVALID_IDX) { 620e3219ce6SAnjali Singhai Jain reg = (I40E_PFINT_AEQCTL_CAUSE_ENA_MASK | 621e3219ce6SAnjali Singhai Jain (v_idx << I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT) | 622e3219ce6SAnjali Singhai Jain (qv_info->itr_idx << 623e3219ce6SAnjali Singhai Jain I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)); 624e3219ce6SAnjali Singhai Jain 625e3219ce6SAnjali Singhai Jain wr32(hw, I40E_PFINT_AEQCTL, reg); 626e3219ce6SAnjali Singhai Jain } 627e3219ce6SAnjali Singhai Jain } 62870df973bSAvinash Dayanand /* Mitigate sync problems with iwarp VF driver */ 62970df973bSAvinash Dayanand i40e_flush(hw); 630e3219ce6SAnjali Singhai Jain return 0; 631e3219ce6SAnjali Singhai Jain err: 632e3219ce6SAnjali Singhai Jain kfree(ldev->qvlist_info); 633e3219ce6SAnjali Singhai Jain ldev->qvlist_info = NULL; 634e3219ce6SAnjali Singhai Jain return -EINVAL; 635e3219ce6SAnjali Singhai Jain } 636e3219ce6SAnjali Singhai Jain 637e3219ce6SAnjali Singhai Jain /** 638e3219ce6SAnjali Singhai Jain * i40e_client_request_reset 639e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 640e3219ce6SAnjali Singhai Jain * @client: Client pointer. 641f5254429SJacob Keller * @reset_level: reset level 642e3219ce6SAnjali Singhai Jain **/ 643e3219ce6SAnjali Singhai Jain static void i40e_client_request_reset(struct i40e_info *ldev, 644e3219ce6SAnjali Singhai Jain struct i40e_client *client, 645e3219ce6SAnjali Singhai Jain u32 reset_level) 646e3219ce6SAnjali Singhai Jain { 647e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 648e3219ce6SAnjali Singhai Jain 649e3219ce6SAnjali Singhai Jain switch (reset_level) { 650e3219ce6SAnjali Singhai Jain case I40E_CLIENT_RESET_LEVEL_PF: 6510da36b97SJacob Keller set_bit(__I40E_PF_RESET_REQUESTED, pf->state); 652e3219ce6SAnjali Singhai Jain break; 653e3219ce6SAnjali Singhai Jain case I40E_CLIENT_RESET_LEVEL_CORE: 6540da36b97SJacob Keller set_bit(__I40E_PF_RESET_REQUESTED, pf->state); 655e3219ce6SAnjali Singhai Jain break; 656e3219ce6SAnjali Singhai Jain default: 657e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 6580ef2d5afSMitch Williams "Client for PF id %d requested an unsupported reset: %d.\n", 6590ef2d5afSMitch Williams pf->hw.pf_id, reset_level); 660e3219ce6SAnjali Singhai Jain break; 661e3219ce6SAnjali Singhai Jain } 662e3219ce6SAnjali Singhai Jain 663e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 664e3219ce6SAnjali Singhai Jain } 665e3219ce6SAnjali Singhai Jain 666e3219ce6SAnjali Singhai Jain /** 667e3219ce6SAnjali Singhai Jain * i40e_client_update_vsi_ctxt 668e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 669e3219ce6SAnjali Singhai Jain * @client: Client pointer. 670e3219ce6SAnjali Singhai Jain * @is_vf: if this for the VF 671e3219ce6SAnjali Singhai Jain * @vf_id: if is_vf true this carries the vf_id 672e3219ce6SAnjali Singhai Jain * @flag: Any device level setting that needs to be done for PE 673e3219ce6SAnjali Singhai Jain * @valid_flag: Bits in this match up and enable changing of flag bits 674e3219ce6SAnjali Singhai Jain * 675e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 676e3219ce6SAnjali Singhai Jain **/ 677e3219ce6SAnjali Singhai Jain static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, 678e3219ce6SAnjali Singhai Jain struct i40e_client *client, 679e3219ce6SAnjali Singhai Jain bool is_vf, u32 vf_id, 680e3219ce6SAnjali Singhai Jain u32 flag, u32 valid_flag) 681e3219ce6SAnjali Singhai Jain { 682e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 683e3219ce6SAnjali Singhai Jain struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 684e3219ce6SAnjali Singhai Jain struct i40e_vsi_context ctxt; 685e3219ce6SAnjali Singhai Jain bool update = true; 686e3219ce6SAnjali Singhai Jain i40e_status err; 687e3219ce6SAnjali Singhai Jain 688e3219ce6SAnjali Singhai Jain /* TODO: for now do not allow setting VF's VSI setting */ 689e3219ce6SAnjali Singhai Jain if (is_vf) 690e3219ce6SAnjali Singhai Jain return -EINVAL; 691e3219ce6SAnjali Singhai Jain 692e3219ce6SAnjali Singhai Jain ctxt.seid = pf->main_vsi_seid; 693e3219ce6SAnjali Singhai Jain ctxt.pf_num = pf->hw.pf_id; 694e3219ce6SAnjali Singhai Jain err = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); 695e3219ce6SAnjali Singhai Jain ctxt.flags = I40E_AQ_VSI_TYPE_PF; 696e3219ce6SAnjali Singhai Jain if (err) { 697e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, 698e3219ce6SAnjali Singhai Jain "couldn't get PF vsi config, err %s aq_err %s\n", 699e3219ce6SAnjali Singhai Jain i40e_stat_str(&pf->hw, err), 700e3219ce6SAnjali Singhai Jain i40e_aq_str(&pf->hw, 701e3219ce6SAnjali Singhai Jain pf->hw.aq.asq_last_status)); 702e3219ce6SAnjali Singhai Jain return -ENOENT; 703e3219ce6SAnjali Singhai Jain } 704e3219ce6SAnjali Singhai Jain 7057b0b1a6dSShiraz Saleem if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) && 7067b0b1a6dSShiraz Saleem (flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) { 707e3219ce6SAnjali Singhai Jain ctxt.info.valid_sections = 708e3219ce6SAnjali Singhai Jain cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID); 709e3219ce6SAnjali Singhai Jain ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA; 7107b0b1a6dSShiraz Saleem } else if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) && 7117b0b1a6dSShiraz Saleem !(flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) { 712e3219ce6SAnjali Singhai Jain ctxt.info.valid_sections = 713e3219ce6SAnjali Singhai Jain cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID); 714e3219ce6SAnjali Singhai Jain ctxt.info.queueing_opt_flags &= ~I40E_AQ_VSI_QUE_OPT_TCP_ENA; 715e3219ce6SAnjali Singhai Jain } else { 716e3219ce6SAnjali Singhai Jain update = false; 717e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 7180ef2d5afSMitch Williams "Client for PF id %d request an unsupported Config: %x.\n", 7190ef2d5afSMitch Williams pf->hw.pf_id, flag); 720e3219ce6SAnjali Singhai Jain } 721e3219ce6SAnjali Singhai Jain 722e3219ce6SAnjali Singhai Jain if (update) { 723e3219ce6SAnjali Singhai Jain err = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); 724e3219ce6SAnjali Singhai Jain if (err) { 725e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, 726e3219ce6SAnjali Singhai Jain "update VSI ctxt for PE failed, err %s aq_err %s\n", 727e3219ce6SAnjali Singhai Jain i40e_stat_str(&pf->hw, err), 728e3219ce6SAnjali Singhai Jain i40e_aq_str(&pf->hw, 729e3219ce6SAnjali Singhai Jain pf->hw.aq.asq_last_status)); 730e3219ce6SAnjali Singhai Jain } 731e3219ce6SAnjali Singhai Jain } 732e3219ce6SAnjali Singhai Jain return err; 733e3219ce6SAnjali Singhai Jain } 734e3219ce6SAnjali Singhai Jain 735e3219ce6SAnjali Singhai Jain /** 736e3219ce6SAnjali Singhai Jain * i40e_register_client - Register a i40e client driver with the L2 driver 737e3219ce6SAnjali Singhai Jain * @client: pointer to the i40e_client struct 738e3219ce6SAnjali Singhai Jain * 739e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 740e3219ce6SAnjali Singhai Jain **/ 741e3219ce6SAnjali Singhai Jain int i40e_register_client(struct i40e_client *client) 742e3219ce6SAnjali Singhai Jain { 743e3219ce6SAnjali Singhai Jain int ret = 0; 744e3219ce6SAnjali Singhai Jain 745e3219ce6SAnjali Singhai Jain if (!client) { 746e3219ce6SAnjali Singhai Jain ret = -EIO; 747e3219ce6SAnjali Singhai Jain goto out; 748e3219ce6SAnjali Singhai Jain } 749e3219ce6SAnjali Singhai Jain 750e3219ce6SAnjali Singhai Jain if (strlen(client->name) == 0) { 751e3219ce6SAnjali Singhai Jain pr_info("i40e: Failed to register client with no name\n"); 752e3219ce6SAnjali Singhai Jain ret = -EIO; 753e3219ce6SAnjali Singhai Jain goto out; 754e3219ce6SAnjali Singhai Jain } 755e3219ce6SAnjali Singhai Jain 7560ef2d5afSMitch Williams if (registered_client) { 757e3219ce6SAnjali Singhai Jain pr_info("i40e: Client %s has already been registered!\n", 758e3219ce6SAnjali Singhai Jain client->name); 759e3219ce6SAnjali Singhai Jain ret = -EEXIST; 760e3219ce6SAnjali Singhai Jain goto out; 761e3219ce6SAnjali Singhai Jain } 762e3219ce6SAnjali Singhai Jain 763e3219ce6SAnjali Singhai Jain if ((client->version.major != I40E_CLIENT_VERSION_MAJOR) || 764e3219ce6SAnjali Singhai Jain (client->version.minor != I40E_CLIENT_VERSION_MINOR)) { 765e3219ce6SAnjali Singhai Jain pr_info("i40e: Failed to register client %s due to mismatched client interface version\n", 766e3219ce6SAnjali Singhai Jain client->name); 767e3219ce6SAnjali Singhai Jain pr_info("Client is using version: %02d.%02d.%02d while LAN driver supports %s\n", 768e3219ce6SAnjali Singhai Jain client->version.major, client->version.minor, 769e3219ce6SAnjali Singhai Jain client->version.build, 770e3219ce6SAnjali Singhai Jain i40e_client_interface_version_str); 771e3219ce6SAnjali Singhai Jain ret = -EIO; 772e3219ce6SAnjali Singhai Jain goto out; 773e3219ce6SAnjali Singhai Jain } 774e3219ce6SAnjali Singhai Jain 7750ef2d5afSMitch Williams registered_client = client; 776e3219ce6SAnjali Singhai Jain 7773bb83bafSMitch Williams i40e_client_prepare(client); 778e3219ce6SAnjali Singhai Jain 7793bb83bafSMitch Williams pr_info("i40e: Registered client %s\n", client->name); 780e3219ce6SAnjali Singhai Jain out: 781e3219ce6SAnjali Singhai Jain return ret; 782e3219ce6SAnjali Singhai Jain } 783e3219ce6SAnjali Singhai Jain EXPORT_SYMBOL(i40e_register_client); 784e3219ce6SAnjali Singhai Jain 785e3219ce6SAnjali Singhai Jain /** 786e3219ce6SAnjali Singhai Jain * i40e_unregister_client - Unregister a i40e client driver with the L2 driver 787e3219ce6SAnjali Singhai Jain * @client: pointer to the i40e_client struct 788e3219ce6SAnjali Singhai Jain * 789e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 790e3219ce6SAnjali Singhai Jain **/ 791e3219ce6SAnjali Singhai Jain int i40e_unregister_client(struct i40e_client *client) 792e3219ce6SAnjali Singhai Jain { 793e3219ce6SAnjali Singhai Jain int ret = 0; 794e3219ce6SAnjali Singhai Jain 7950ef2d5afSMitch Williams if (registered_client != client) { 796e3219ce6SAnjali Singhai Jain pr_info("i40e: Client %s has not been registered\n", 797e3219ce6SAnjali Singhai Jain client->name); 798e3219ce6SAnjali Singhai Jain ret = -ENODEV; 799e3219ce6SAnjali Singhai Jain goto out; 800e3219ce6SAnjali Singhai Jain } 8010ef2d5afSMitch Williams registered_client = NULL; 8020ef2d5afSMitch Williams /* When a unregister request comes through we would have to send 8030ef2d5afSMitch Williams * a close for each of the client instances that were opened. 8040ef2d5afSMitch Williams * client_release function is called to handle this. 8050ef2d5afSMitch Williams */ 8060ef2d5afSMitch Williams i40e_client_release(client); 8070ef2d5afSMitch Williams 8080ef2d5afSMitch Williams pr_info("i40e: Unregistered client %s\n", client->name); 809e3219ce6SAnjali Singhai Jain out: 810e3219ce6SAnjali Singhai Jain return ret; 811e3219ce6SAnjali Singhai Jain } 812e3219ce6SAnjali Singhai Jain EXPORT_SYMBOL(i40e_unregister_client); 813