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 LIST_HEAD(i40e_devices); 12e3219ce6SAnjali Singhai Jain static DEFINE_MUTEX(i40e_device_mutex); 13f4370a85SShiraz Saleem DEFINE_IDA(i40e_client_ida); 14e3219ce6SAnjali Singhai Jain 15e3219ce6SAnjali Singhai Jain static int i40e_client_virtchnl_send(struct i40e_info *ldev, 16e3219ce6SAnjali Singhai Jain struct i40e_client *client, 17e3219ce6SAnjali Singhai Jain u32 vf_id, u8 *msg, u16 len); 18e3219ce6SAnjali Singhai Jain 19e3219ce6SAnjali Singhai Jain static int i40e_client_setup_qvlist(struct i40e_info *ldev, 20e3219ce6SAnjali Singhai Jain struct i40e_client *client, 21e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info); 22e3219ce6SAnjali Singhai Jain 23e3219ce6SAnjali Singhai Jain static void i40e_client_request_reset(struct i40e_info *ldev, 24e3219ce6SAnjali Singhai Jain struct i40e_client *client, 25e3219ce6SAnjali Singhai Jain u32 reset_level); 26e3219ce6SAnjali Singhai Jain 27e3219ce6SAnjali Singhai Jain static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, 28e3219ce6SAnjali Singhai Jain struct i40e_client *client, 29e3219ce6SAnjali Singhai Jain bool is_vf, u32 vf_id, 30e3219ce6SAnjali Singhai Jain u32 flag, u32 valid_flag); 31e3219ce6SAnjali Singhai Jain 32e3219ce6SAnjali Singhai Jain static struct i40e_ops i40e_lan_ops = { 33e3219ce6SAnjali Singhai Jain .virtchnl_send = i40e_client_virtchnl_send, 34e3219ce6SAnjali Singhai Jain .setup_qvlist = i40e_client_setup_qvlist, 35e3219ce6SAnjali Singhai Jain .request_reset = i40e_client_request_reset, 36e3219ce6SAnjali Singhai Jain .update_vsi_ctxt = i40e_client_update_vsi_ctxt, 37e3219ce6SAnjali Singhai Jain }; 38e3219ce6SAnjali Singhai Jain 39e3219ce6SAnjali Singhai Jain /** 40e3219ce6SAnjali Singhai Jain * i40e_client_get_params - Get the params that can change at runtime 41e3219ce6SAnjali Singhai Jain * @vsi: the VSI with the message 42f5254429SJacob Keller * @params: client param struct 43e3219ce6SAnjali Singhai Jain * 44e3219ce6SAnjali Singhai Jain **/ 45e3219ce6SAnjali Singhai Jain static 46e3219ce6SAnjali Singhai Jain int i40e_client_get_params(struct i40e_vsi *vsi, struct i40e_params *params) 47e3219ce6SAnjali Singhai Jain { 48e3219ce6SAnjali Singhai Jain struct i40e_dcbx_config *dcb_cfg = &vsi->back->hw.local_dcbx_config; 49e3219ce6SAnjali Singhai Jain int i = 0; 50e3219ce6SAnjali Singhai Jain 51e3219ce6SAnjali Singhai Jain for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { 52e3219ce6SAnjali Singhai Jain u8 tc = dcb_cfg->etscfg.prioritytable[i]; 53e3219ce6SAnjali Singhai Jain u16 qs_handle; 54e3219ce6SAnjali Singhai Jain 55e3219ce6SAnjali Singhai Jain /* If TC is not enabled for VSI use TC0 for UP */ 56e3219ce6SAnjali Singhai Jain if (!(vsi->tc_config.enabled_tc & BIT(tc))) 57e3219ce6SAnjali Singhai Jain tc = 0; 58e3219ce6SAnjali Singhai Jain 59e3219ce6SAnjali Singhai Jain qs_handle = le16_to_cpu(vsi->info.qs_handle[tc]); 60e3219ce6SAnjali Singhai Jain params->qos.prio_qos[i].tc = tc; 61e3219ce6SAnjali Singhai Jain params->qos.prio_qos[i].qs_handle = qs_handle; 62e3219ce6SAnjali Singhai Jain if (qs_handle == I40E_AQ_VSI_QS_HANDLE_INVALID) { 63e3219ce6SAnjali Singhai Jain dev_err(&vsi->back->pdev->dev, "Invalid queue set handle for TC = %d, vsi id = %d\n", 64e3219ce6SAnjali Singhai Jain tc, vsi->id); 65e3219ce6SAnjali Singhai Jain return -EINVAL; 66e3219ce6SAnjali Singhai Jain } 67e3219ce6SAnjali Singhai Jain } 68e3219ce6SAnjali Singhai Jain 69e3219ce6SAnjali Singhai Jain params->mtu = vsi->netdev->mtu; 70e3219ce6SAnjali Singhai Jain return 0; 71e3219ce6SAnjali Singhai Jain } 72e3219ce6SAnjali Singhai Jain 73e3219ce6SAnjali Singhai Jain /** 74e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_msg - call the client vf message callback 75e3219ce6SAnjali Singhai Jain * @vsi: the VSI with the message 76e3219ce6SAnjali Singhai Jain * @vf_id: the absolute VF id that sent the message 77e3219ce6SAnjali Singhai Jain * @msg: message buffer 78e3219ce6SAnjali Singhai Jain * @len: length of the message 79e3219ce6SAnjali Singhai Jain * 80e3219ce6SAnjali Singhai Jain * If there is a client to this VSI, call the client 81e3219ce6SAnjali Singhai Jain **/ 82e3219ce6SAnjali Singhai Jain void 83e3219ce6SAnjali Singhai Jain i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id, u8 *msg, u16 len) 84e3219ce6SAnjali Singhai Jain { 850ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 860ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 87e3219ce6SAnjali Singhai Jain 880ef2d5afSMitch Williams if (!cdev || !cdev->client) 89e3219ce6SAnjali Singhai Jain return; 900ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->virtchnl_receive) { 910ef2d5afSMitch Williams dev_dbg(&pf->pdev->dev, 92e3219ce6SAnjali Singhai Jain "Cannot locate client instance virtual channel receive routine\n"); 930ef2d5afSMitch Williams return; 94e3219ce6SAnjali Singhai Jain } 950ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 960ef2d5afSMitch Williams dev_dbg(&pf->pdev->dev, "Client is not open, abort virtchnl_receive\n"); 970ef2d5afSMitch Williams return; 9891cdca4fSCatherine Sullivan } 990ef2d5afSMitch Williams cdev->client->ops->virtchnl_receive(&cdev->lan_info, cdev->client, 100e3219ce6SAnjali Singhai Jain vf_id, msg, len); 101e3219ce6SAnjali Singhai Jain } 102e3219ce6SAnjali Singhai Jain 103e3219ce6SAnjali Singhai Jain /** 104e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_l2_param_changes - call the client notify callback 105e3219ce6SAnjali Singhai Jain * @vsi: the VSI with l2 param changes 106e3219ce6SAnjali Singhai Jain * 107e3219ce6SAnjali Singhai Jain * If there is a client to this VSI, call the client 108e3219ce6SAnjali Singhai Jain **/ 109e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi) 110e3219ce6SAnjali Singhai Jain { 1110ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 1120ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 113e3219ce6SAnjali Singhai Jain struct i40e_params params; 114e3219ce6SAnjali Singhai Jain 1150ef2d5afSMitch Williams if (!cdev || !cdev->client) 116e3219ce6SAnjali Singhai Jain return; 1170ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->l2_param_change) { 118e3219ce6SAnjali Singhai Jain dev_dbg(&vsi->back->pdev->dev, 119e3219ce6SAnjali Singhai Jain "Cannot locate client instance l2_param_change routine\n"); 1200ef2d5afSMitch Williams return; 121e3219ce6SAnjali Singhai Jain } 1220ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 12391cdca4fSCatherine Sullivan dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort l2 param change\n"); 1240ef2d5afSMitch Williams return; 12591cdca4fSCatherine Sullivan } 1267be147dcSJacob Keller memset(¶ms, 0, sizeof(params)); 1277be147dcSJacob Keller i40e_client_get_params(vsi, ¶ms); 1280ef2d5afSMitch Williams memcpy(&cdev->lan_info.params, ¶ms, sizeof(struct i40e_params)); 1290ef2d5afSMitch Williams cdev->client->ops->l2_param_change(&cdev->lan_info, cdev->client, 130e3219ce6SAnjali Singhai Jain ¶ms); 131e3219ce6SAnjali Singhai Jain } 132e3219ce6SAnjali Singhai Jain 133e3219ce6SAnjali Singhai Jain /** 1340ef2d5afSMitch Williams * i40e_client_release_qvlist - release MSI-X vector mapping for client 135e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 136e3219ce6SAnjali Singhai Jain * 137e3219ce6SAnjali Singhai Jain **/ 138e3219ce6SAnjali Singhai Jain static void i40e_client_release_qvlist(struct i40e_info *ldev) 139e3219ce6SAnjali Singhai Jain { 140e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info = ldev->qvlist_info; 141e3219ce6SAnjali Singhai Jain u32 i; 142e3219ce6SAnjali Singhai Jain 143e3219ce6SAnjali Singhai Jain if (!ldev->qvlist_info) 144e3219ce6SAnjali Singhai Jain return; 145e3219ce6SAnjali Singhai Jain 146e3219ce6SAnjali Singhai Jain for (i = 0; i < qvlist_info->num_vectors; i++) { 147e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 148e3219ce6SAnjali Singhai Jain struct i40e_qv_info *qv_info; 149e3219ce6SAnjali Singhai Jain u32 reg_idx; 150e3219ce6SAnjali Singhai Jain 151e3219ce6SAnjali Singhai Jain qv_info = &qvlist_info->qv_info[i]; 152e3219ce6SAnjali Singhai Jain if (!qv_info) 153e3219ce6SAnjali Singhai Jain continue; 154e3219ce6SAnjali Singhai Jain reg_idx = I40E_PFINT_LNKLSTN(qv_info->v_idx - 1); 155e3219ce6SAnjali Singhai Jain wr32(&pf->hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK); 156e3219ce6SAnjali Singhai Jain } 157e3219ce6SAnjali Singhai Jain kfree(ldev->qvlist_info); 158e3219ce6SAnjali Singhai Jain ldev->qvlist_info = NULL; 159e3219ce6SAnjali Singhai Jain } 160e3219ce6SAnjali Singhai Jain 161e3219ce6SAnjali Singhai Jain /** 162e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_netdev_close - call the client close callback 163e3219ce6SAnjali Singhai Jain * @vsi: the VSI with netdev closed 164e3219ce6SAnjali Singhai Jain * @reset: true when close called due to a reset pending 165e3219ce6SAnjali Singhai Jain * 166e3219ce6SAnjali Singhai Jain * If there is a client to this netdev, call the client with close 167e3219ce6SAnjali Singhai Jain **/ 168e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset) 169e3219ce6SAnjali Singhai Jain { 1700ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 1710ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 172e3219ce6SAnjali Singhai Jain 1730ef2d5afSMitch Williams if (!cdev || !cdev->client) 174e3219ce6SAnjali Singhai Jain return; 1750ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->close) { 176e3219ce6SAnjali Singhai Jain dev_dbg(&vsi->back->pdev->dev, 177e3219ce6SAnjali Singhai Jain "Cannot locate client instance close routine\n"); 1780ef2d5afSMitch Williams return; 179e3219ce6SAnjali Singhai Jain } 180*fb8396aeSIvan Vecera if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 181*fb8396aeSIvan Vecera dev_dbg(&pf->pdev->dev, "Client is not open, abort close\n"); 182*fb8396aeSIvan Vecera return; 183*fb8396aeSIvan Vecera } 1840ef2d5afSMitch Williams cdev->client->ops->close(&cdev->lan_info, cdev->client, reset); 1857be96322SMitch Williams clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 186e3219ce6SAnjali Singhai Jain i40e_client_release_qvlist(&cdev->lan_info); 187e3219ce6SAnjali Singhai Jain } 188e3219ce6SAnjali Singhai Jain 189e3219ce6SAnjali Singhai Jain /** 190e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_reset - call the client vf reset callback 191e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 192e3219ce6SAnjali Singhai Jain * @vf_id: asolute id of VF being reset 193e3219ce6SAnjali Singhai Jain * 194e3219ce6SAnjali Singhai Jain * If there is a client attached to this PF, notify when a VF is reset 195e3219ce6SAnjali Singhai Jain **/ 196e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id) 197e3219ce6SAnjali Singhai Jain { 1980ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 199e3219ce6SAnjali Singhai Jain 2000ef2d5afSMitch Williams if (!cdev || !cdev->client) 201e3219ce6SAnjali Singhai Jain return; 2020ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_reset) { 203e3219ce6SAnjali Singhai Jain dev_dbg(&pf->pdev->dev, 204e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF reset routine\n"); 2050ef2d5afSMitch Williams return; 206e3219ce6SAnjali Singhai Jain } 2070ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 20891cdca4fSCatherine Sullivan dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-reset\n"); 2090ef2d5afSMitch Williams return; 21091cdca4fSCatherine Sullivan } 2110ef2d5afSMitch Williams cdev->client->ops->vf_reset(&cdev->lan_info, cdev->client, vf_id); 212e3219ce6SAnjali Singhai Jain } 213e3219ce6SAnjali Singhai Jain 214e3219ce6SAnjali Singhai Jain /** 215e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_enable - call the client vf notification callback 216e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 217e3219ce6SAnjali Singhai Jain * @num_vfs: the number of VFs currently enabled, 0 for disable 218e3219ce6SAnjali Singhai Jain * 219e3219ce6SAnjali Singhai Jain * If there is a client attached to this PF, call its VF notification routine 220e3219ce6SAnjali Singhai Jain **/ 221e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs) 222e3219ce6SAnjali Singhai Jain { 2230ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 224e3219ce6SAnjali Singhai Jain 2250ef2d5afSMitch Williams if (!cdev || !cdev->client) 226e3219ce6SAnjali Singhai Jain return; 2270ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_enable) { 228e3219ce6SAnjali Singhai Jain dev_dbg(&pf->pdev->dev, 229e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF enable routine\n"); 2300ef2d5afSMitch Williams return; 231e3219ce6SAnjali Singhai Jain } 23291cdca4fSCatherine Sullivan if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, 23391cdca4fSCatherine Sullivan &cdev->state)) { 23491cdca4fSCatherine Sullivan dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-enable\n"); 2350ef2d5afSMitch Williams return; 23691cdca4fSCatherine Sullivan } 2370ef2d5afSMitch Williams cdev->client->ops->vf_enable(&cdev->lan_info, cdev->client, num_vfs); 238e3219ce6SAnjali Singhai Jain } 239e3219ce6SAnjali Singhai Jain 240e3219ce6SAnjali Singhai Jain /** 241e3219ce6SAnjali Singhai Jain * i40e_vf_client_capable - ask the client if it likes the specified VF 242e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 243e3219ce6SAnjali Singhai Jain * @vf_id: the VF in question 244e3219ce6SAnjali Singhai Jain * 245e3219ce6SAnjali Singhai Jain * If there is a client of the specified type attached to this PF, call 246e3219ce6SAnjali Singhai Jain * its vf_capable routine 247e3219ce6SAnjali Singhai Jain **/ 2480ef2d5afSMitch Williams int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id) 249e3219ce6SAnjali Singhai Jain { 2500ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 251e3219ce6SAnjali Singhai Jain int capable = false; 252e3219ce6SAnjali Singhai Jain 2530ef2d5afSMitch Williams if (!cdev || !cdev->client) 2540ef2d5afSMitch Williams goto out; 2550ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_capable) { 25659e331e3SJacob Keller dev_dbg(&pf->pdev->dev, 257e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF capability routine\n"); 2580ef2d5afSMitch Williams goto out; 259e3219ce6SAnjali Singhai Jain } 2600ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) 2610ef2d5afSMitch Williams goto out; 2620ef2d5afSMitch Williams 263e3219ce6SAnjali Singhai Jain capable = cdev->client->ops->vf_capable(&cdev->lan_info, 264e3219ce6SAnjali Singhai Jain cdev->client, 265e3219ce6SAnjali Singhai Jain vf_id); 2660ef2d5afSMitch Williams out: 267e3219ce6SAnjali Singhai Jain return capable; 268e3219ce6SAnjali Singhai Jain } 269e3219ce6SAnjali Singhai Jain 270ddbb8d5dSShiraz Saleem void i40e_client_update_msix_info(struct i40e_pf *pf) 271ddbb8d5dSShiraz Saleem { 272ddbb8d5dSShiraz Saleem struct i40e_client_instance *cdev = pf->cinst; 273ddbb8d5dSShiraz Saleem 274ddbb8d5dSShiraz Saleem if (!cdev || !cdev->client) 275ddbb8d5dSShiraz Saleem return; 276ddbb8d5dSShiraz Saleem 277ddbb8d5dSShiraz Saleem cdev->lan_info.msix_count = pf->num_iwarp_msix; 278ddbb8d5dSShiraz Saleem cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector]; 279ddbb8d5dSShiraz Saleem } 280ddbb8d5dSShiraz Saleem 281f4370a85SShiraz Saleem static void i40e_auxiliary_dev_release(struct device *dev) 282f4370a85SShiraz Saleem { 283f4370a85SShiraz Saleem struct i40e_auxiliary_device *i40e_aux_dev = 284f4370a85SShiraz Saleem container_of(dev, struct i40e_auxiliary_device, aux_dev.dev); 285f4370a85SShiraz Saleem 286f4370a85SShiraz Saleem ida_free(&i40e_client_ida, i40e_aux_dev->aux_dev.id); 287f4370a85SShiraz Saleem kfree(i40e_aux_dev); 288f4370a85SShiraz Saleem } 289f4370a85SShiraz Saleem 290f4370a85SShiraz Saleem static int i40e_register_auxiliary_dev(struct i40e_info *ldev, const char *name) 291f4370a85SShiraz Saleem { 292f4370a85SShiraz Saleem struct i40e_auxiliary_device *i40e_aux_dev; 293f4370a85SShiraz Saleem struct pci_dev *pdev = ldev->pcidev; 294f4370a85SShiraz Saleem struct auxiliary_device *aux_dev; 295f4370a85SShiraz Saleem int ret; 296f4370a85SShiraz Saleem 297f4370a85SShiraz Saleem i40e_aux_dev = kzalloc(sizeof(*i40e_aux_dev), GFP_KERNEL); 298f4370a85SShiraz Saleem if (!i40e_aux_dev) 299f4370a85SShiraz Saleem return -ENOMEM; 300f4370a85SShiraz Saleem 301f4370a85SShiraz Saleem i40e_aux_dev->ldev = ldev; 302f4370a85SShiraz Saleem 303f4370a85SShiraz Saleem aux_dev = &i40e_aux_dev->aux_dev; 304f4370a85SShiraz Saleem aux_dev->name = name; 305f4370a85SShiraz Saleem aux_dev->dev.parent = &pdev->dev; 306f4370a85SShiraz Saleem aux_dev->dev.release = i40e_auxiliary_dev_release; 307f4370a85SShiraz Saleem ldev->aux_dev = aux_dev; 308f4370a85SShiraz Saleem 309f4370a85SShiraz Saleem ret = ida_alloc(&i40e_client_ida, GFP_KERNEL); 310f4370a85SShiraz Saleem if (ret < 0) { 311f4370a85SShiraz Saleem kfree(i40e_aux_dev); 312f4370a85SShiraz Saleem return ret; 313f4370a85SShiraz Saleem } 314f4370a85SShiraz Saleem aux_dev->id = ret; 315f4370a85SShiraz Saleem 316f4370a85SShiraz Saleem ret = auxiliary_device_init(aux_dev); 317f4370a85SShiraz Saleem if (ret < 0) { 318f4370a85SShiraz Saleem ida_free(&i40e_client_ida, aux_dev->id); 319f4370a85SShiraz Saleem kfree(i40e_aux_dev); 320f4370a85SShiraz Saleem return ret; 321f4370a85SShiraz Saleem } 322f4370a85SShiraz Saleem 323f4370a85SShiraz Saleem ret = auxiliary_device_add(aux_dev); 324f4370a85SShiraz Saleem if (ret) { 325f4370a85SShiraz Saleem auxiliary_device_uninit(aux_dev); 326f4370a85SShiraz Saleem return ret; 327f4370a85SShiraz Saleem } 328f4370a85SShiraz Saleem 329f4370a85SShiraz Saleem return ret; 330f4370a85SShiraz Saleem } 331f4370a85SShiraz Saleem 332e3219ce6SAnjali Singhai Jain /** 333e3219ce6SAnjali Singhai Jain * i40e_client_add_instance - add a client instance struct to the instance list 334e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 335e3219ce6SAnjali Singhai Jain * 336e3219ce6SAnjali Singhai Jain **/ 3370ef2d5afSMitch Williams static void i40e_client_add_instance(struct i40e_pf *pf) 338e3219ce6SAnjali Singhai Jain { 3390ef2d5afSMitch Williams struct i40e_client_instance *cdev = NULL; 340e3219ce6SAnjali Singhai Jain struct netdev_hw_addr *mac = NULL; 341e3219ce6SAnjali Singhai Jain struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 342e3219ce6SAnjali Singhai Jain 343e3219ce6SAnjali Singhai Jain cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 344e3219ce6SAnjali Singhai Jain if (!cdev) 3450ef2d5afSMitch Williams return; 346e3219ce6SAnjali Singhai Jain 347e3219ce6SAnjali Singhai Jain cdev->lan_info.pf = (void *)pf; 348e3219ce6SAnjali Singhai Jain cdev->lan_info.netdev = vsi->netdev; 349e3219ce6SAnjali Singhai Jain cdev->lan_info.pcidev = pf->pdev; 350e3219ce6SAnjali Singhai Jain cdev->lan_info.fid = pf->hw.pf_id; 351e3219ce6SAnjali Singhai Jain cdev->lan_info.ftype = I40E_CLIENT_FTYPE_PF; 352e3219ce6SAnjali Singhai Jain cdev->lan_info.hw_addr = pf->hw.hw_addr; 353e3219ce6SAnjali Singhai Jain cdev->lan_info.ops = &i40e_lan_ops; 354e3219ce6SAnjali Singhai Jain cdev->lan_info.version.major = I40E_CLIENT_VERSION_MAJOR; 355e3219ce6SAnjali Singhai Jain cdev->lan_info.version.minor = I40E_CLIENT_VERSION_MINOR; 356e3219ce6SAnjali Singhai Jain cdev->lan_info.version.build = I40E_CLIENT_VERSION_BUILD; 357e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_maj_ver = pf->hw.aq.fw_maj_ver; 358e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_min_ver = pf->hw.aq.fw_min_ver; 359e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_build = pf->hw.aq.fw_build; 360e3219ce6SAnjali Singhai Jain set_bit(__I40E_CLIENT_INSTANCE_NONE, &cdev->state); 361e3219ce6SAnjali Singhai Jain 362f4370a85SShiraz Saleem if (i40e_client_get_params(vsi, &cdev->lan_info.params)) 363f4370a85SShiraz Saleem goto free_cdev; 364e3219ce6SAnjali Singhai Jain 365e3219ce6SAnjali Singhai Jain mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list, 366e3219ce6SAnjali Singhai Jain struct netdev_hw_addr, list); 367e3219ce6SAnjali Singhai Jain if (mac) 368e3219ce6SAnjali Singhai Jain ether_addr_copy(cdev->lan_info.lanmac, mac->addr); 369e3219ce6SAnjali Singhai Jain else 370e3219ce6SAnjali Singhai Jain dev_err(&pf->pdev->dev, "MAC address list is empty!\n"); 371e3219ce6SAnjali Singhai Jain 3720ef2d5afSMitch Williams pf->cinst = cdev; 373ddbb8d5dSShiraz Saleem 374f4370a85SShiraz Saleem cdev->lan_info.msix_count = pf->num_iwarp_msix; 375f4370a85SShiraz Saleem cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector]; 376f4370a85SShiraz Saleem 377f4370a85SShiraz Saleem if (i40e_register_auxiliary_dev(&cdev->lan_info, "iwarp")) 378f4370a85SShiraz Saleem goto free_cdev; 379f4370a85SShiraz Saleem 380f4370a85SShiraz Saleem return; 381f4370a85SShiraz Saleem 382f4370a85SShiraz Saleem free_cdev: 383f4370a85SShiraz Saleem kfree(cdev); 384f4370a85SShiraz Saleem pf->cinst = NULL; 385e3219ce6SAnjali Singhai Jain } 386e3219ce6SAnjali Singhai Jain 387e3219ce6SAnjali Singhai Jain /** 388e3219ce6SAnjali Singhai Jain * i40e_client_del_instance - removes a client instance from the list 389e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 390e3219ce6SAnjali Singhai Jain * 391e3219ce6SAnjali Singhai Jain **/ 392e3219ce6SAnjali Singhai Jain static 3930ef2d5afSMitch Williams void i40e_client_del_instance(struct i40e_pf *pf) 394e3219ce6SAnjali Singhai Jain { 3950ef2d5afSMitch Williams kfree(pf->cinst); 3960ef2d5afSMitch Williams pf->cinst = NULL; 397e3219ce6SAnjali Singhai Jain } 398e3219ce6SAnjali Singhai Jain 399e3219ce6SAnjali Singhai Jain /** 400e3219ce6SAnjali Singhai Jain * i40e_client_subtask - client maintenance work 401e3219ce6SAnjali Singhai Jain * @pf: board private structure 402e3219ce6SAnjali Singhai Jain **/ 403e3219ce6SAnjali Singhai Jain void i40e_client_subtask(struct i40e_pf *pf) 404e3219ce6SAnjali Singhai Jain { 405f4370a85SShiraz Saleem struct i40e_client *client; 406e3219ce6SAnjali Singhai Jain struct i40e_client_instance *cdev; 4070ef2d5afSMitch Williams struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 408e3219ce6SAnjali Singhai Jain int ret = 0; 409e3219ce6SAnjali Singhai Jain 4105f76a704SJacob Keller if (!test_and_clear_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state)) 411e3219ce6SAnjali Singhai Jain return; 4120ef2d5afSMitch Williams cdev = pf->cinst; 413e3219ce6SAnjali Singhai Jain 414e3219ce6SAnjali Singhai Jain /* If we're down or resetting, just bail */ 4150da36b97SJacob Keller if (test_bit(__I40E_DOWN, pf->state) || 4160da36b97SJacob Keller test_bit(__I40E_CONFIG_BUSY, pf->state)) 417e3219ce6SAnjali Singhai Jain return; 418e3219ce6SAnjali Singhai Jain 419f4370a85SShiraz Saleem if (!cdev || !cdev->client) 4200ef2d5afSMitch Williams return; 421e3219ce6SAnjali Singhai Jain 422f4370a85SShiraz Saleem client = cdev->client; 423f4370a85SShiraz Saleem 4247b0b1a6dSShiraz Saleem /* Here we handle client opens. If the client is down, and 4257b0b1a6dSShiraz Saleem * the netdev is registered, then open the client. 4260ef2d5afSMitch Williams */ 4270ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 4287b0b1a6dSShiraz Saleem if (vsi->netdev_registered && 4290ef2d5afSMitch Williams client->ops && client->ops->open) { 4300ef2d5afSMitch Williams set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 4310ef2d5afSMitch Williams ret = client->ops->open(&cdev->lan_info, client); 4320ef2d5afSMitch Williams if (ret) { 4330ef2d5afSMitch Williams /* Remove failed client instance */ 4340ef2d5afSMitch Williams clear_bit(__I40E_CLIENT_INSTANCE_OPENED, 4357be96322SMitch Williams &cdev->state); 43638318f23SYunjian Wang return; 4370ef2d5afSMitch Williams } 4380ef2d5afSMitch Williams } 4397b0b1a6dSShiraz Saleem } 4407b0b1a6dSShiraz Saleem 4417b0b1a6dSShiraz Saleem /* enable/disable PE TCP_ENA flag based on netdev down/up 4420ef2d5afSMitch Williams */ 4437b0b1a6dSShiraz Saleem if (test_bit(__I40E_VSI_DOWN, vsi->state)) 4447b0b1a6dSShiraz Saleem i40e_client_update_vsi_ctxt(&cdev->lan_info, client, 4457b0b1a6dSShiraz Saleem 0, 0, 0, 4467b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE); 4477b0b1a6dSShiraz Saleem else 4487b0b1a6dSShiraz Saleem i40e_client_update_vsi_ctxt(&cdev->lan_info, client, 4497b0b1a6dSShiraz Saleem 0, 0, 4507b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE, 4517b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE); 452e3219ce6SAnjali Singhai Jain } 453e3219ce6SAnjali Singhai Jain 454e3219ce6SAnjali Singhai Jain /** 455e3219ce6SAnjali Singhai Jain * i40e_lan_add_device - add a lan device struct to the list of lan devices 456e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 457e3219ce6SAnjali Singhai Jain * 458e3219ce6SAnjali Singhai Jain * Returns 0 on success or none 0 on error 459e3219ce6SAnjali Singhai Jain **/ 460e3219ce6SAnjali Singhai Jain int i40e_lan_add_device(struct i40e_pf *pf) 461e3219ce6SAnjali Singhai Jain { 462e3219ce6SAnjali Singhai Jain struct i40e_device *ldev; 463e3219ce6SAnjali Singhai Jain int ret = 0; 464e3219ce6SAnjali Singhai Jain 465e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 466e3219ce6SAnjali Singhai Jain list_for_each_entry(ldev, &i40e_devices, list) { 467e3219ce6SAnjali Singhai Jain if (ldev->pf == pf) { 468e3219ce6SAnjali Singhai Jain ret = -EEXIST; 469e3219ce6SAnjali Singhai Jain goto out; 470e3219ce6SAnjali Singhai Jain } 471e3219ce6SAnjali Singhai Jain } 472e3219ce6SAnjali Singhai Jain ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); 473e3219ce6SAnjali Singhai Jain if (!ldev) { 474e3219ce6SAnjali Singhai Jain ret = -ENOMEM; 475e3219ce6SAnjali Singhai Jain goto out; 476e3219ce6SAnjali Singhai Jain } 477e3219ce6SAnjali Singhai Jain ldev->pf = pf; 478e3219ce6SAnjali Singhai Jain INIT_LIST_HEAD(&ldev->list); 479e3219ce6SAnjali Singhai Jain list_add(&ldev->list, &i40e_devices); 480b3f028fcSSudheer Mogilappagari dev_info(&pf->pdev->dev, "Added LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n", 481b3f028fcSSudheer Mogilappagari pf->hw.pf_id, pf->hw.bus.bus_id, 482b3f028fcSSudheer Mogilappagari pf->hw.bus.device, pf->hw.bus.func); 483e3219ce6SAnjali Singhai Jain 4848090f618SMitch Williams i40e_client_add_instance(pf); 4858090f618SMitch Williams 4865f76a704SJacob Keller set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state); 487e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 488e3219ce6SAnjali Singhai Jain 489e3219ce6SAnjali Singhai Jain out: 490e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 491e3219ce6SAnjali Singhai Jain return ret; 492e3219ce6SAnjali Singhai Jain } 493e3219ce6SAnjali Singhai Jain 494e3219ce6SAnjali Singhai Jain /** 495e3219ce6SAnjali Singhai Jain * i40e_lan_del_device - removes a lan device from the device list 496e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 497e3219ce6SAnjali Singhai Jain * 498e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 499e3219ce6SAnjali Singhai Jain **/ 500e3219ce6SAnjali Singhai Jain int i40e_lan_del_device(struct i40e_pf *pf) 501e3219ce6SAnjali Singhai Jain { 502f4370a85SShiraz Saleem struct auxiliary_device *aux_dev = pf->cinst->lan_info.aux_dev; 503e3219ce6SAnjali Singhai Jain struct i40e_device *ldev, *tmp; 504e3219ce6SAnjali Singhai Jain int ret = -ENODEV; 505e3219ce6SAnjali Singhai Jain 506f4370a85SShiraz Saleem auxiliary_device_delete(aux_dev); 507f4370a85SShiraz Saleem auxiliary_device_uninit(aux_dev); 508f4370a85SShiraz Saleem 509295c0a55SMitch Williams /* First, remove any client instance. */ 510295c0a55SMitch Williams i40e_client_del_instance(pf); 511295c0a55SMitch Williams 512e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 513e3219ce6SAnjali Singhai Jain list_for_each_entry_safe(ldev, tmp, &i40e_devices, list) { 514e3219ce6SAnjali Singhai Jain if (ldev->pf == pf) { 515b3f028fcSSudheer Mogilappagari dev_info(&pf->pdev->dev, "Deleted LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n", 516b3f028fcSSudheer Mogilappagari pf->hw.pf_id, pf->hw.bus.bus_id, 517b3f028fcSSudheer Mogilappagari pf->hw.bus.device, pf->hw.bus.func); 518e3219ce6SAnjali Singhai Jain list_del(&ldev->list); 519e3219ce6SAnjali Singhai Jain kfree(ldev); 520e3219ce6SAnjali Singhai Jain ret = 0; 521e3219ce6SAnjali Singhai Jain break; 522e3219ce6SAnjali Singhai Jain } 523e3219ce6SAnjali Singhai Jain } 524e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 525e3219ce6SAnjali Singhai Jain return ret; 526e3219ce6SAnjali Singhai Jain } 527e3219ce6SAnjali Singhai Jain 528e3219ce6SAnjali Singhai Jain /** 529e3219ce6SAnjali Singhai Jain * i40e_client_virtchnl_send - TBD 530e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context 531e3219ce6SAnjali Singhai Jain * @client: Client pointer 532e3219ce6SAnjali Singhai Jain * @vf_id: absolute VF identifier 533e3219ce6SAnjali Singhai Jain * @msg: message buffer 534e3219ce6SAnjali Singhai Jain * @len: length of message buffer 535e3219ce6SAnjali Singhai Jain * 536e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 537e3219ce6SAnjali Singhai Jain **/ 538e3219ce6SAnjali Singhai Jain static int i40e_client_virtchnl_send(struct i40e_info *ldev, 539e3219ce6SAnjali Singhai Jain struct i40e_client *client, 540e3219ce6SAnjali Singhai Jain u32 vf_id, u8 *msg, u16 len) 541e3219ce6SAnjali Singhai Jain { 542e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 543e3219ce6SAnjali Singhai Jain struct i40e_hw *hw = &pf->hw; 544e3219ce6SAnjali Singhai Jain i40e_status err; 545e3219ce6SAnjali Singhai Jain 546310a2ad9SJesse Brandeburg err = i40e_aq_send_msg_to_vf(hw, vf_id, VIRTCHNL_OP_IWARP, 547e3219ce6SAnjali Singhai Jain 0, msg, len, NULL); 548e3219ce6SAnjali Singhai Jain if (err) 549e3219ce6SAnjali Singhai Jain dev_err(&pf->pdev->dev, "Unable to send iWarp message to VF, error %d, aq status %d\n", 550e3219ce6SAnjali Singhai Jain err, hw->aq.asq_last_status); 551e3219ce6SAnjali Singhai Jain 552e3219ce6SAnjali Singhai Jain return err; 553e3219ce6SAnjali Singhai Jain } 554e3219ce6SAnjali Singhai Jain 555e3219ce6SAnjali Singhai Jain /** 556e3219ce6SAnjali Singhai Jain * i40e_client_setup_qvlist 557e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 558e3219ce6SAnjali Singhai Jain * @client: Client pointer. 559f5254429SJacob Keller * @qvlist_info: queue and vector list 560e3219ce6SAnjali Singhai Jain * 561e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 562e3219ce6SAnjali Singhai Jain **/ 563e3219ce6SAnjali Singhai Jain static int i40e_client_setup_qvlist(struct i40e_info *ldev, 564e3219ce6SAnjali Singhai Jain struct i40e_client *client, 565e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info) 566e3219ce6SAnjali Singhai Jain { 567e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 568e3219ce6SAnjali Singhai Jain struct i40e_hw *hw = &pf->hw; 569e3219ce6SAnjali Singhai Jain struct i40e_qv_info *qv_info; 570e3219ce6SAnjali Singhai Jain u32 v_idx, i, reg_idx, reg; 571e3219ce6SAnjali Singhai Jain 572825f0a4eSGustavo A. R. Silva ldev->qvlist_info = kzalloc(struct_size(ldev->qvlist_info, qv_info, 573125217e0SGustavo A. R. Silva qvlist_info->num_vectors), GFP_KERNEL); 5740a4ecc2cSChristophe Jaillet if (!ldev->qvlist_info) 5750a4ecc2cSChristophe Jaillet return -ENOMEM; 576e3219ce6SAnjali Singhai Jain ldev->qvlist_info->num_vectors = qvlist_info->num_vectors; 577e3219ce6SAnjali Singhai Jain 578e3219ce6SAnjali Singhai Jain for (i = 0; i < qvlist_info->num_vectors; i++) { 579e3219ce6SAnjali Singhai Jain qv_info = &qvlist_info->qv_info[i]; 580e3219ce6SAnjali Singhai Jain if (!qv_info) 581e3219ce6SAnjali Singhai Jain continue; 582e3219ce6SAnjali Singhai Jain v_idx = qv_info->v_idx; 583e3219ce6SAnjali Singhai Jain 584e3219ce6SAnjali Singhai Jain /* Validate vector id belongs to this client */ 585e3219ce6SAnjali Singhai Jain if ((v_idx >= (pf->iwarp_base_vector + pf->num_iwarp_msix)) || 586e3219ce6SAnjali Singhai Jain (v_idx < pf->iwarp_base_vector)) 587e3219ce6SAnjali Singhai Jain goto err; 588e3219ce6SAnjali Singhai Jain 589e3219ce6SAnjali Singhai Jain ldev->qvlist_info->qv_info[i] = *qv_info; 590e3219ce6SAnjali Singhai Jain reg_idx = I40E_PFINT_LNKLSTN(v_idx - 1); 591e3219ce6SAnjali Singhai Jain 592e3219ce6SAnjali Singhai Jain if (qv_info->ceq_idx == I40E_QUEUE_INVALID_IDX) { 593e3219ce6SAnjali Singhai Jain /* Special case - No CEQ mapped on this vector */ 594e3219ce6SAnjali Singhai Jain wr32(hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK); 595e3219ce6SAnjali Singhai Jain } else { 596e3219ce6SAnjali Singhai Jain reg = (qv_info->ceq_idx & 597e3219ce6SAnjali Singhai Jain I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK) | 598e3219ce6SAnjali Singhai Jain (I40E_QUEUE_TYPE_PE_CEQ << 599e3219ce6SAnjali Singhai Jain I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT); 600e3219ce6SAnjali Singhai Jain wr32(hw, reg_idx, reg); 601e3219ce6SAnjali Singhai Jain 602e3219ce6SAnjali Singhai Jain reg = (I40E_PFINT_CEQCTL_CAUSE_ENA_MASK | 603e3219ce6SAnjali Singhai Jain (v_idx << I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT) | 604e3219ce6SAnjali Singhai Jain (qv_info->itr_idx << 605e3219ce6SAnjali Singhai Jain I40E_PFINT_CEQCTL_ITR_INDX_SHIFT) | 606e3219ce6SAnjali Singhai Jain (I40E_QUEUE_END_OF_LIST << 607e3219ce6SAnjali Singhai Jain I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)); 608e3219ce6SAnjali Singhai Jain wr32(hw, I40E_PFINT_CEQCTL(qv_info->ceq_idx), reg); 609e3219ce6SAnjali Singhai Jain } 610e3219ce6SAnjali Singhai Jain if (qv_info->aeq_idx != I40E_QUEUE_INVALID_IDX) { 611e3219ce6SAnjali Singhai Jain reg = (I40E_PFINT_AEQCTL_CAUSE_ENA_MASK | 612e3219ce6SAnjali Singhai Jain (v_idx << I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT) | 613e3219ce6SAnjali Singhai Jain (qv_info->itr_idx << 614e3219ce6SAnjali Singhai Jain I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)); 615e3219ce6SAnjali Singhai Jain 616e3219ce6SAnjali Singhai Jain wr32(hw, I40E_PFINT_AEQCTL, reg); 617e3219ce6SAnjali Singhai Jain } 618e3219ce6SAnjali Singhai Jain } 61970df973bSAvinash Dayanand /* Mitigate sync problems with iwarp VF driver */ 62070df973bSAvinash Dayanand i40e_flush(hw); 621e3219ce6SAnjali Singhai Jain return 0; 622e3219ce6SAnjali Singhai Jain err: 623e3219ce6SAnjali Singhai Jain kfree(ldev->qvlist_info); 624e3219ce6SAnjali Singhai Jain ldev->qvlist_info = NULL; 625e3219ce6SAnjali Singhai Jain return -EINVAL; 626e3219ce6SAnjali Singhai Jain } 627e3219ce6SAnjali Singhai Jain 628e3219ce6SAnjali Singhai Jain /** 629e3219ce6SAnjali Singhai Jain * i40e_client_request_reset 630e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 631e3219ce6SAnjali Singhai Jain * @client: Client pointer. 632f5254429SJacob Keller * @reset_level: reset level 633e3219ce6SAnjali Singhai Jain **/ 634e3219ce6SAnjali Singhai Jain static void i40e_client_request_reset(struct i40e_info *ldev, 635e3219ce6SAnjali Singhai Jain struct i40e_client *client, 636e3219ce6SAnjali Singhai Jain u32 reset_level) 637e3219ce6SAnjali Singhai Jain { 638e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 639e3219ce6SAnjali Singhai Jain 640e3219ce6SAnjali Singhai Jain switch (reset_level) { 641e3219ce6SAnjali Singhai Jain case I40E_CLIENT_RESET_LEVEL_PF: 6420da36b97SJacob Keller set_bit(__I40E_PF_RESET_REQUESTED, pf->state); 643e3219ce6SAnjali Singhai Jain break; 644e3219ce6SAnjali Singhai Jain case I40E_CLIENT_RESET_LEVEL_CORE: 6450da36b97SJacob Keller set_bit(__I40E_PF_RESET_REQUESTED, pf->state); 646e3219ce6SAnjali Singhai Jain break; 647e3219ce6SAnjali Singhai Jain default: 648e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 6490ef2d5afSMitch Williams "Client for PF id %d requested an unsupported reset: %d.\n", 6500ef2d5afSMitch Williams pf->hw.pf_id, reset_level); 651e3219ce6SAnjali Singhai Jain break; 652e3219ce6SAnjali Singhai Jain } 653e3219ce6SAnjali Singhai Jain 654e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 655e3219ce6SAnjali Singhai Jain } 656e3219ce6SAnjali Singhai Jain 657e3219ce6SAnjali Singhai Jain /** 658e3219ce6SAnjali Singhai Jain * i40e_client_update_vsi_ctxt 659e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 660e3219ce6SAnjali Singhai Jain * @client: Client pointer. 661e3219ce6SAnjali Singhai Jain * @is_vf: if this for the VF 662e3219ce6SAnjali Singhai Jain * @vf_id: if is_vf true this carries the vf_id 663e3219ce6SAnjali Singhai Jain * @flag: Any device level setting that needs to be done for PE 664e3219ce6SAnjali Singhai Jain * @valid_flag: Bits in this match up and enable changing of flag bits 665e3219ce6SAnjali Singhai Jain * 666e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 667e3219ce6SAnjali Singhai Jain **/ 668e3219ce6SAnjali Singhai Jain static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, 669e3219ce6SAnjali Singhai Jain struct i40e_client *client, 670e3219ce6SAnjali Singhai Jain bool is_vf, u32 vf_id, 671e3219ce6SAnjali Singhai Jain u32 flag, u32 valid_flag) 672e3219ce6SAnjali Singhai Jain { 673e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 674e3219ce6SAnjali Singhai Jain struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 675e3219ce6SAnjali Singhai Jain struct i40e_vsi_context ctxt; 676e3219ce6SAnjali Singhai Jain bool update = true; 677e3219ce6SAnjali Singhai Jain i40e_status err; 678e3219ce6SAnjali Singhai Jain 679e3219ce6SAnjali Singhai Jain /* TODO: for now do not allow setting VF's VSI setting */ 680e3219ce6SAnjali Singhai Jain if (is_vf) 681e3219ce6SAnjali Singhai Jain return -EINVAL; 682e3219ce6SAnjali Singhai Jain 683e3219ce6SAnjali Singhai Jain ctxt.seid = pf->main_vsi_seid; 684e3219ce6SAnjali Singhai Jain ctxt.pf_num = pf->hw.pf_id; 685e3219ce6SAnjali Singhai Jain err = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); 686e3219ce6SAnjali Singhai Jain ctxt.flags = I40E_AQ_VSI_TYPE_PF; 687e3219ce6SAnjali Singhai Jain if (err) { 688e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, 689e3219ce6SAnjali Singhai Jain "couldn't get PF vsi config, err %s aq_err %s\n", 690e3219ce6SAnjali Singhai Jain i40e_stat_str(&pf->hw, err), 691e3219ce6SAnjali Singhai Jain i40e_aq_str(&pf->hw, 692e3219ce6SAnjali Singhai Jain pf->hw.aq.asq_last_status)); 693e3219ce6SAnjali Singhai Jain return -ENOENT; 694e3219ce6SAnjali Singhai Jain } 695e3219ce6SAnjali Singhai Jain 6967b0b1a6dSShiraz Saleem if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) && 6977b0b1a6dSShiraz Saleem (flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) { 698e3219ce6SAnjali Singhai Jain ctxt.info.valid_sections = 699e3219ce6SAnjali Singhai Jain cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID); 700e3219ce6SAnjali Singhai Jain ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA; 7017b0b1a6dSShiraz Saleem } else if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) && 7027b0b1a6dSShiraz Saleem !(flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) { 703e3219ce6SAnjali Singhai Jain ctxt.info.valid_sections = 704e3219ce6SAnjali Singhai Jain cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID); 705e3219ce6SAnjali Singhai Jain ctxt.info.queueing_opt_flags &= ~I40E_AQ_VSI_QUE_OPT_TCP_ENA; 706e3219ce6SAnjali Singhai Jain } else { 707e3219ce6SAnjali Singhai Jain update = false; 708e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 7090ef2d5afSMitch Williams "Client for PF id %d request an unsupported Config: %x.\n", 7100ef2d5afSMitch Williams pf->hw.pf_id, flag); 711e3219ce6SAnjali Singhai Jain } 712e3219ce6SAnjali Singhai Jain 713e3219ce6SAnjali Singhai Jain if (update) { 714e3219ce6SAnjali Singhai Jain err = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); 715e3219ce6SAnjali Singhai Jain if (err) { 716e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, 717e3219ce6SAnjali Singhai Jain "update VSI ctxt for PE failed, err %s aq_err %s\n", 718e3219ce6SAnjali Singhai Jain i40e_stat_str(&pf->hw, err), 719e3219ce6SAnjali Singhai Jain i40e_aq_str(&pf->hw, 720e3219ce6SAnjali Singhai Jain pf->hw.aq.asq_last_status)); 721e3219ce6SAnjali Singhai Jain } 722e3219ce6SAnjali Singhai Jain } 723e3219ce6SAnjali Singhai Jain return err; 724e3219ce6SAnjali Singhai Jain } 725e3219ce6SAnjali Singhai Jain 726f4370a85SShiraz Saleem void i40e_client_device_register(struct i40e_info *ldev, struct i40e_client *client) 727f4370a85SShiraz Saleem { 728f4370a85SShiraz Saleem struct i40e_pf *pf = ldev->pf; 729f4370a85SShiraz Saleem 730f4370a85SShiraz Saleem pf->cinst->client = client; 731f4370a85SShiraz Saleem set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state); 732f4370a85SShiraz Saleem i40e_service_event_schedule(pf); 733f4370a85SShiraz Saleem } 734f4370a85SShiraz Saleem EXPORT_SYMBOL_GPL(i40e_client_device_register); 735f4370a85SShiraz Saleem 736f4370a85SShiraz Saleem void i40e_client_device_unregister(struct i40e_info *ldev) 737f4370a85SShiraz Saleem { 738f4370a85SShiraz Saleem struct i40e_pf *pf = ldev->pf; 739f4370a85SShiraz Saleem struct i40e_client_instance *cdev = pf->cinst; 740f4370a85SShiraz Saleem 741f4370a85SShiraz Saleem if (!cdev) 742f4370a85SShiraz Saleem return; 743f4370a85SShiraz Saleem 744f4370a85SShiraz Saleem while (test_and_set_bit(__I40E_SERVICE_SCHED, pf->state)) 745f4370a85SShiraz Saleem usleep_range(500, 1000); 746f4370a85SShiraz Saleem 747f4370a85SShiraz Saleem if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 748f4370a85SShiraz Saleem cdev->client->ops->close(&cdev->lan_info, cdev->client, false); 749f4370a85SShiraz Saleem clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 750f4370a85SShiraz Saleem i40e_client_release_qvlist(&cdev->lan_info); 751f4370a85SShiraz Saleem } 752f4370a85SShiraz Saleem 753f4370a85SShiraz Saleem pf->cinst->client = NULL; 754f4370a85SShiraz Saleem clear_bit(__I40E_SERVICE_SCHED, pf->state); 755f4370a85SShiraz Saleem } 756f4370a85SShiraz Saleem EXPORT_SYMBOL_GPL(i40e_client_device_unregister); 757