1e3219ce6SAnjali Singhai Jain /******************************************************************************* 2e3219ce6SAnjali Singhai Jain * 3e3219ce6SAnjali Singhai Jain * Intel Ethernet Controller XL710 Family Linux Driver 4e3219ce6SAnjali Singhai Jain * Copyright(c) 2013 - 2015 Intel Corporation. 5e3219ce6SAnjali Singhai Jain * 6e3219ce6SAnjali Singhai Jain * This program is free software; you can redistribute it and/or modify it 7e3219ce6SAnjali Singhai Jain * under the terms and conditions of the GNU General Public License, 8e3219ce6SAnjali Singhai Jain * version 2, as published by the Free Software Foundation. 9e3219ce6SAnjali Singhai Jain * 10e3219ce6SAnjali Singhai Jain * This program is distributed in the hope it will be useful, but WITHOUT 11e3219ce6SAnjali Singhai Jain * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12e3219ce6SAnjali Singhai Jain * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13e3219ce6SAnjali Singhai Jain * more details. 14e3219ce6SAnjali Singhai Jain * 15e3219ce6SAnjali Singhai Jain * You should have received a copy of the GNU General Public License along 16e3219ce6SAnjali Singhai Jain * with this program. If not, see <http://www.gnu.org/licenses/>. 17e3219ce6SAnjali Singhai Jain * 18e3219ce6SAnjali Singhai Jain * The full GNU General Public License is included in this distribution in 19e3219ce6SAnjali Singhai Jain * the file called "COPYING". 20e3219ce6SAnjali Singhai Jain * 21e3219ce6SAnjali Singhai Jain * Contact Information: 22e3219ce6SAnjali Singhai Jain * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 23e3219ce6SAnjali Singhai Jain * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 24e3219ce6SAnjali Singhai Jain * 25e3219ce6SAnjali Singhai Jain ******************************************************************************/ 26e3219ce6SAnjali Singhai Jain 27e3219ce6SAnjali Singhai Jain #include <linux/list.h> 28e3219ce6SAnjali Singhai Jain #include <linux/errno.h> 29e3219ce6SAnjali Singhai Jain 30e3219ce6SAnjali Singhai Jain #include "i40e.h" 31e3219ce6SAnjali Singhai Jain #include "i40e_prototype.h" 32e3219ce6SAnjali Singhai Jain #include "i40e_client.h" 33e3219ce6SAnjali Singhai Jain 34e3219ce6SAnjali Singhai Jain static const char i40e_client_interface_version_str[] = I40E_CLIENT_VERSION_STR; 350ef2d5afSMitch Williams static struct i40e_client *registered_client; 36e3219ce6SAnjali Singhai Jain static LIST_HEAD(i40e_devices); 37e3219ce6SAnjali Singhai Jain static DEFINE_MUTEX(i40e_device_mutex); 38e3219ce6SAnjali Singhai Jain 39e3219ce6SAnjali Singhai Jain static int i40e_client_virtchnl_send(struct i40e_info *ldev, 40e3219ce6SAnjali Singhai Jain struct i40e_client *client, 41e3219ce6SAnjali Singhai Jain u32 vf_id, u8 *msg, u16 len); 42e3219ce6SAnjali Singhai Jain 43e3219ce6SAnjali Singhai Jain static int i40e_client_setup_qvlist(struct i40e_info *ldev, 44e3219ce6SAnjali Singhai Jain struct i40e_client *client, 45e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info); 46e3219ce6SAnjali Singhai Jain 47e3219ce6SAnjali Singhai Jain static void i40e_client_request_reset(struct i40e_info *ldev, 48e3219ce6SAnjali Singhai Jain struct i40e_client *client, 49e3219ce6SAnjali Singhai Jain u32 reset_level); 50e3219ce6SAnjali Singhai Jain 51e3219ce6SAnjali Singhai Jain static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, 52e3219ce6SAnjali Singhai Jain struct i40e_client *client, 53e3219ce6SAnjali Singhai Jain bool is_vf, u32 vf_id, 54e3219ce6SAnjali Singhai Jain u32 flag, u32 valid_flag); 55e3219ce6SAnjali Singhai Jain 56e3219ce6SAnjali Singhai Jain static struct i40e_ops i40e_lan_ops = { 57e3219ce6SAnjali Singhai Jain .virtchnl_send = i40e_client_virtchnl_send, 58e3219ce6SAnjali Singhai Jain .setup_qvlist = i40e_client_setup_qvlist, 59e3219ce6SAnjali Singhai Jain .request_reset = i40e_client_request_reset, 60e3219ce6SAnjali Singhai Jain .update_vsi_ctxt = i40e_client_update_vsi_ctxt, 61e3219ce6SAnjali Singhai Jain }; 62e3219ce6SAnjali Singhai Jain 63e3219ce6SAnjali Singhai Jain /** 64e3219ce6SAnjali Singhai Jain * i40e_client_get_params - Get the params that can change at runtime 65e3219ce6SAnjali Singhai Jain * @vsi: the VSI with the message 66e3219ce6SAnjali Singhai Jain * @param: clinet param struct 67e3219ce6SAnjali Singhai Jain * 68e3219ce6SAnjali Singhai Jain **/ 69e3219ce6SAnjali Singhai Jain static 70e3219ce6SAnjali Singhai Jain int i40e_client_get_params(struct i40e_vsi *vsi, struct i40e_params *params) 71e3219ce6SAnjali Singhai Jain { 72e3219ce6SAnjali Singhai Jain struct i40e_dcbx_config *dcb_cfg = &vsi->back->hw.local_dcbx_config; 73e3219ce6SAnjali Singhai Jain int i = 0; 74e3219ce6SAnjali Singhai Jain 75e3219ce6SAnjali Singhai Jain for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { 76e3219ce6SAnjali Singhai Jain u8 tc = dcb_cfg->etscfg.prioritytable[i]; 77e3219ce6SAnjali Singhai Jain u16 qs_handle; 78e3219ce6SAnjali Singhai Jain 79e3219ce6SAnjali Singhai Jain /* If TC is not enabled for VSI use TC0 for UP */ 80e3219ce6SAnjali Singhai Jain if (!(vsi->tc_config.enabled_tc & BIT(tc))) 81e3219ce6SAnjali Singhai Jain tc = 0; 82e3219ce6SAnjali Singhai Jain 83e3219ce6SAnjali Singhai Jain qs_handle = le16_to_cpu(vsi->info.qs_handle[tc]); 84e3219ce6SAnjali Singhai Jain params->qos.prio_qos[i].tc = tc; 85e3219ce6SAnjali Singhai Jain params->qos.prio_qos[i].qs_handle = qs_handle; 86e3219ce6SAnjali Singhai Jain if (qs_handle == I40E_AQ_VSI_QS_HANDLE_INVALID) { 87e3219ce6SAnjali Singhai Jain dev_err(&vsi->back->pdev->dev, "Invalid queue set handle for TC = %d, vsi id = %d\n", 88e3219ce6SAnjali Singhai Jain tc, vsi->id); 89e3219ce6SAnjali Singhai Jain return -EINVAL; 90e3219ce6SAnjali Singhai Jain } 91e3219ce6SAnjali Singhai Jain } 92e3219ce6SAnjali Singhai Jain 93e3219ce6SAnjali Singhai Jain params->mtu = vsi->netdev->mtu; 94e3219ce6SAnjali Singhai Jain return 0; 95e3219ce6SAnjali Singhai Jain } 96e3219ce6SAnjali Singhai Jain 97e3219ce6SAnjali Singhai Jain /** 98e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_msg - call the client vf message callback 99e3219ce6SAnjali Singhai Jain * @vsi: the VSI with the message 100e3219ce6SAnjali Singhai Jain * @vf_id: the absolute VF id that sent the message 101e3219ce6SAnjali Singhai Jain * @msg: message buffer 102e3219ce6SAnjali Singhai Jain * @len: length of the message 103e3219ce6SAnjali Singhai Jain * 104e3219ce6SAnjali Singhai Jain * If there is a client to this VSI, call the client 105e3219ce6SAnjali Singhai Jain **/ 106e3219ce6SAnjali Singhai Jain void 107e3219ce6SAnjali Singhai Jain i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id, u8 *msg, u16 len) 108e3219ce6SAnjali Singhai Jain { 1090ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 1100ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 111e3219ce6SAnjali Singhai Jain 1120ef2d5afSMitch Williams if (!cdev || !cdev->client) 113e3219ce6SAnjali Singhai Jain return; 1140ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->virtchnl_receive) { 1150ef2d5afSMitch Williams dev_dbg(&pf->pdev->dev, 116e3219ce6SAnjali Singhai Jain "Cannot locate client instance virtual channel receive routine\n"); 1170ef2d5afSMitch Williams return; 118e3219ce6SAnjali Singhai Jain } 1190ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 1200ef2d5afSMitch Williams dev_dbg(&pf->pdev->dev, "Client is not open, abort virtchnl_receive\n"); 1210ef2d5afSMitch Williams return; 12291cdca4fSCatherine Sullivan } 1230ef2d5afSMitch Williams cdev->client->ops->virtchnl_receive(&cdev->lan_info, cdev->client, 124e3219ce6SAnjali Singhai Jain vf_id, msg, len); 125e3219ce6SAnjali Singhai Jain } 126e3219ce6SAnjali Singhai Jain 127e3219ce6SAnjali Singhai Jain /** 128e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_l2_param_changes - call the client notify callback 129e3219ce6SAnjali Singhai Jain * @vsi: the VSI with l2 param changes 130e3219ce6SAnjali Singhai Jain * 131e3219ce6SAnjali Singhai Jain * If there is a client to this VSI, call the client 132e3219ce6SAnjali Singhai Jain **/ 133e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi) 134e3219ce6SAnjali Singhai Jain { 1350ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 1360ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 137e3219ce6SAnjali Singhai Jain struct i40e_params params; 138e3219ce6SAnjali Singhai Jain 1390ef2d5afSMitch Williams if (!cdev || !cdev->client) 140e3219ce6SAnjali Singhai Jain return; 1410ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->l2_param_change) { 142e3219ce6SAnjali Singhai Jain dev_dbg(&vsi->back->pdev->dev, 143e3219ce6SAnjali Singhai Jain "Cannot locate client instance l2_param_change routine\n"); 1440ef2d5afSMitch Williams return; 145e3219ce6SAnjali Singhai Jain } 1460ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 14791cdca4fSCatherine Sullivan dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort l2 param change\n"); 1480ef2d5afSMitch Williams return; 14991cdca4fSCatherine Sullivan } 1507be147dcSJacob Keller memset(¶ms, 0, sizeof(params)); 1517be147dcSJacob Keller i40e_client_get_params(vsi, ¶ms); 1520ef2d5afSMitch Williams memcpy(&cdev->lan_info.params, ¶ms, sizeof(struct i40e_params)); 1530ef2d5afSMitch Williams cdev->client->ops->l2_param_change(&cdev->lan_info, cdev->client, 154e3219ce6SAnjali Singhai Jain ¶ms); 155e3219ce6SAnjali Singhai Jain } 156e3219ce6SAnjali Singhai Jain 157e3219ce6SAnjali Singhai Jain /** 1580ef2d5afSMitch Williams * i40e_client_release_qvlist - release MSI-X vector mapping for client 159e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 160e3219ce6SAnjali Singhai Jain * 161e3219ce6SAnjali Singhai Jain **/ 162e3219ce6SAnjali Singhai Jain static void i40e_client_release_qvlist(struct i40e_info *ldev) 163e3219ce6SAnjali Singhai Jain { 164e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info = ldev->qvlist_info; 165e3219ce6SAnjali Singhai Jain u32 i; 166e3219ce6SAnjali Singhai Jain 167e3219ce6SAnjali Singhai Jain if (!ldev->qvlist_info) 168e3219ce6SAnjali Singhai Jain return; 169e3219ce6SAnjali Singhai Jain 170e3219ce6SAnjali Singhai Jain for (i = 0; i < qvlist_info->num_vectors; i++) { 171e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 172e3219ce6SAnjali Singhai Jain struct i40e_qv_info *qv_info; 173e3219ce6SAnjali Singhai Jain u32 reg_idx; 174e3219ce6SAnjali Singhai Jain 175e3219ce6SAnjali Singhai Jain qv_info = &qvlist_info->qv_info[i]; 176e3219ce6SAnjali Singhai Jain if (!qv_info) 177e3219ce6SAnjali Singhai Jain continue; 178e3219ce6SAnjali Singhai Jain reg_idx = I40E_PFINT_LNKLSTN(qv_info->v_idx - 1); 179e3219ce6SAnjali Singhai Jain wr32(&pf->hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK); 180e3219ce6SAnjali Singhai Jain } 181e3219ce6SAnjali Singhai Jain kfree(ldev->qvlist_info); 182e3219ce6SAnjali Singhai Jain ldev->qvlist_info = NULL; 183e3219ce6SAnjali Singhai Jain } 184e3219ce6SAnjali Singhai Jain 185e3219ce6SAnjali Singhai Jain /** 186e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_netdev_close - call the client close callback 187e3219ce6SAnjali Singhai Jain * @vsi: the VSI with netdev closed 188e3219ce6SAnjali Singhai Jain * @reset: true when close called due to a reset pending 189e3219ce6SAnjali Singhai Jain * 190e3219ce6SAnjali Singhai Jain * If there is a client to this netdev, call the client with close 191e3219ce6SAnjali Singhai Jain **/ 192e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset) 193e3219ce6SAnjali Singhai Jain { 1940ef2d5afSMitch Williams struct i40e_pf *pf = vsi->back; 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->close) { 200e3219ce6SAnjali Singhai Jain dev_dbg(&vsi->back->pdev->dev, 201e3219ce6SAnjali Singhai Jain "Cannot locate client instance close routine\n"); 2020ef2d5afSMitch Williams return; 203e3219ce6SAnjali Singhai Jain } 2040ef2d5afSMitch Williams cdev->client->ops->close(&cdev->lan_info, cdev->client, reset); 2057be96322SMitch Williams clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 206e3219ce6SAnjali Singhai Jain i40e_client_release_qvlist(&cdev->lan_info); 207e3219ce6SAnjali Singhai Jain } 208e3219ce6SAnjali Singhai Jain 209e3219ce6SAnjali Singhai Jain /** 210e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_reset - call the client vf reset callback 211e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 212e3219ce6SAnjali Singhai Jain * @vf_id: asolute id of VF being reset 213e3219ce6SAnjali Singhai Jain * 214e3219ce6SAnjali Singhai Jain * If there is a client attached to this PF, notify when a VF is reset 215e3219ce6SAnjali Singhai Jain **/ 216e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id) 217e3219ce6SAnjali Singhai Jain { 2180ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 219e3219ce6SAnjali Singhai Jain 2200ef2d5afSMitch Williams if (!cdev || !cdev->client) 221e3219ce6SAnjali Singhai Jain return; 2220ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_reset) { 223e3219ce6SAnjali Singhai Jain dev_dbg(&pf->pdev->dev, 224e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF reset routine\n"); 2250ef2d5afSMitch Williams return; 226e3219ce6SAnjali Singhai Jain } 2270ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 22891cdca4fSCatherine Sullivan dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-reset\n"); 2290ef2d5afSMitch Williams return; 23091cdca4fSCatherine Sullivan } 2310ef2d5afSMitch Williams cdev->client->ops->vf_reset(&cdev->lan_info, cdev->client, vf_id); 232e3219ce6SAnjali Singhai Jain } 233e3219ce6SAnjali Singhai Jain 234e3219ce6SAnjali Singhai Jain /** 235e3219ce6SAnjali Singhai Jain * i40e_notify_client_of_vf_enable - call the client vf notification callback 236e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 237e3219ce6SAnjali Singhai Jain * @num_vfs: the number of VFs currently enabled, 0 for disable 238e3219ce6SAnjali Singhai Jain * 239e3219ce6SAnjali Singhai Jain * If there is a client attached to this PF, call its VF notification routine 240e3219ce6SAnjali Singhai Jain **/ 241e3219ce6SAnjali Singhai Jain void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs) 242e3219ce6SAnjali Singhai Jain { 2430ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 244e3219ce6SAnjali Singhai Jain 2450ef2d5afSMitch Williams if (!cdev || !cdev->client) 246e3219ce6SAnjali Singhai Jain return; 2470ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_enable) { 248e3219ce6SAnjali Singhai Jain dev_dbg(&pf->pdev->dev, 249e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF enable routine\n"); 2500ef2d5afSMitch Williams return; 251e3219ce6SAnjali Singhai Jain } 25291cdca4fSCatherine Sullivan if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, 25391cdca4fSCatherine Sullivan &cdev->state)) { 25491cdca4fSCatherine Sullivan dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-enable\n"); 2550ef2d5afSMitch Williams return; 25691cdca4fSCatherine Sullivan } 2570ef2d5afSMitch Williams cdev->client->ops->vf_enable(&cdev->lan_info, cdev->client, num_vfs); 258e3219ce6SAnjali Singhai Jain } 259e3219ce6SAnjali Singhai Jain 260e3219ce6SAnjali Singhai Jain /** 261e3219ce6SAnjali Singhai Jain * i40e_vf_client_capable - ask the client if it likes the specified VF 262e3219ce6SAnjali Singhai Jain * @pf: PF device pointer 263e3219ce6SAnjali Singhai Jain * @vf_id: the VF in question 264e3219ce6SAnjali Singhai Jain * 265e3219ce6SAnjali Singhai Jain * If there is a client of the specified type attached to this PF, call 266e3219ce6SAnjali Singhai Jain * its vf_capable routine 267e3219ce6SAnjali Singhai Jain **/ 2680ef2d5afSMitch Williams int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id) 269e3219ce6SAnjali Singhai Jain { 2700ef2d5afSMitch Williams struct i40e_client_instance *cdev = pf->cinst; 271e3219ce6SAnjali Singhai Jain int capable = false; 272e3219ce6SAnjali Singhai Jain 2730ef2d5afSMitch Williams if (!cdev || !cdev->client) 2740ef2d5afSMitch Williams goto out; 2750ef2d5afSMitch Williams if (!cdev->client->ops || !cdev->client->ops->vf_capable) { 2760ef2d5afSMitch Williams dev_info(&pf->pdev->dev, 277e3219ce6SAnjali Singhai Jain "Cannot locate client instance VF capability routine\n"); 2780ef2d5afSMitch Williams goto out; 279e3219ce6SAnjali Singhai Jain } 2800ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) 2810ef2d5afSMitch Williams goto out; 2820ef2d5afSMitch Williams 283e3219ce6SAnjali Singhai Jain capable = cdev->client->ops->vf_capable(&cdev->lan_info, 284e3219ce6SAnjali Singhai Jain cdev->client, 285e3219ce6SAnjali Singhai Jain vf_id); 2860ef2d5afSMitch Williams out: 287e3219ce6SAnjali Singhai Jain return capable; 288e3219ce6SAnjali Singhai Jain } 289e3219ce6SAnjali Singhai Jain 290e3219ce6SAnjali Singhai Jain /** 291e3219ce6SAnjali Singhai Jain * i40e_client_add_instance - add a client instance struct to the instance list 292e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 293e3219ce6SAnjali Singhai Jain * @client: pointer to a client struct in the client list. 294f38ff2eeSAnjali Singhai Jain * @existing: if there was already an existing instance 295e3219ce6SAnjali Singhai Jain * 296e3219ce6SAnjali Singhai Jain **/ 2970ef2d5afSMitch Williams static void i40e_client_add_instance(struct i40e_pf *pf) 298e3219ce6SAnjali Singhai Jain { 2990ef2d5afSMitch Williams struct i40e_client_instance *cdev = NULL; 300e3219ce6SAnjali Singhai Jain struct netdev_hw_addr *mac = NULL; 301e3219ce6SAnjali Singhai Jain struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 302e3219ce6SAnjali Singhai Jain 3030ef2d5afSMitch Williams if (!registered_client || pf->cinst) 3040ef2d5afSMitch Williams return; 3050ef2d5afSMitch Williams 306e3219ce6SAnjali Singhai Jain cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 307e3219ce6SAnjali Singhai Jain if (!cdev) 3080ef2d5afSMitch Williams return; 309e3219ce6SAnjali Singhai Jain 310e3219ce6SAnjali Singhai Jain cdev->lan_info.pf = (void *)pf; 311e3219ce6SAnjali Singhai Jain cdev->lan_info.netdev = vsi->netdev; 312e3219ce6SAnjali Singhai Jain cdev->lan_info.pcidev = pf->pdev; 313e3219ce6SAnjali Singhai Jain cdev->lan_info.fid = pf->hw.pf_id; 314e3219ce6SAnjali Singhai Jain cdev->lan_info.ftype = I40E_CLIENT_FTYPE_PF; 315e3219ce6SAnjali Singhai Jain cdev->lan_info.hw_addr = pf->hw.hw_addr; 316e3219ce6SAnjali Singhai Jain cdev->lan_info.ops = &i40e_lan_ops; 317e3219ce6SAnjali Singhai Jain cdev->lan_info.version.major = I40E_CLIENT_VERSION_MAJOR; 318e3219ce6SAnjali Singhai Jain cdev->lan_info.version.minor = I40E_CLIENT_VERSION_MINOR; 319e3219ce6SAnjali Singhai Jain cdev->lan_info.version.build = I40E_CLIENT_VERSION_BUILD; 320e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_maj_ver = pf->hw.aq.fw_maj_ver; 321e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_min_ver = pf->hw.aq.fw_min_ver; 322e3219ce6SAnjali Singhai Jain cdev->lan_info.fw_build = pf->hw.aq.fw_build; 323e3219ce6SAnjali Singhai Jain set_bit(__I40E_CLIENT_INSTANCE_NONE, &cdev->state); 324e3219ce6SAnjali Singhai Jain 325e3219ce6SAnjali Singhai Jain if (i40e_client_get_params(vsi, &cdev->lan_info.params)) { 326e3219ce6SAnjali Singhai Jain kfree(cdev); 327e3219ce6SAnjali Singhai Jain cdev = NULL; 3280ef2d5afSMitch Williams return; 329e3219ce6SAnjali Singhai Jain } 330e3219ce6SAnjali Singhai Jain 331e3219ce6SAnjali Singhai Jain cdev->lan_info.msix_count = pf->num_iwarp_msix; 332e3219ce6SAnjali Singhai Jain cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector]; 333e3219ce6SAnjali Singhai Jain 334e3219ce6SAnjali Singhai Jain mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list, 335e3219ce6SAnjali Singhai Jain struct netdev_hw_addr, list); 336e3219ce6SAnjali Singhai Jain if (mac) 337e3219ce6SAnjali Singhai Jain ether_addr_copy(cdev->lan_info.lanmac, mac->addr); 338e3219ce6SAnjali Singhai Jain else 339e3219ce6SAnjali Singhai Jain dev_err(&pf->pdev->dev, "MAC address list is empty!\n"); 340e3219ce6SAnjali Singhai Jain 3410ef2d5afSMitch Williams cdev->client = registered_client; 3420ef2d5afSMitch Williams pf->cinst = cdev; 343e3219ce6SAnjali Singhai Jain } 344e3219ce6SAnjali Singhai Jain 345e3219ce6SAnjali Singhai Jain /** 346e3219ce6SAnjali Singhai Jain * i40e_client_del_instance - removes a client instance from the list 347e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 348e3219ce6SAnjali Singhai Jain * 349e3219ce6SAnjali Singhai Jain **/ 350e3219ce6SAnjali Singhai Jain static 3510ef2d5afSMitch Williams void i40e_client_del_instance(struct i40e_pf *pf) 352e3219ce6SAnjali Singhai Jain { 3530ef2d5afSMitch Williams kfree(pf->cinst); 3540ef2d5afSMitch Williams pf->cinst = NULL; 355e3219ce6SAnjali Singhai Jain } 356e3219ce6SAnjali Singhai Jain 357e3219ce6SAnjali Singhai Jain /** 358e3219ce6SAnjali Singhai Jain * i40e_client_subtask - client maintenance work 359e3219ce6SAnjali Singhai Jain * @pf: board private structure 360e3219ce6SAnjali Singhai Jain **/ 361e3219ce6SAnjali Singhai Jain void i40e_client_subtask(struct i40e_pf *pf) 362e3219ce6SAnjali Singhai Jain { 3630ef2d5afSMitch Williams struct i40e_client *client = registered_client; 364e3219ce6SAnjali Singhai Jain struct i40e_client_instance *cdev; 3650ef2d5afSMitch Williams struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 366e3219ce6SAnjali Singhai Jain int ret = 0; 367e3219ce6SAnjali Singhai Jain 368e3219ce6SAnjali Singhai Jain if (!(pf->flags & I40E_FLAG_SERVICE_CLIENT_REQUESTED)) 369e3219ce6SAnjali Singhai Jain return; 370e3219ce6SAnjali Singhai Jain pf->flags &= ~I40E_FLAG_SERVICE_CLIENT_REQUESTED; 3710ef2d5afSMitch Williams cdev = pf->cinst; 372e3219ce6SAnjali Singhai Jain 373e3219ce6SAnjali Singhai Jain /* If we're down or resetting, just bail */ 374e3219ce6SAnjali Singhai Jain if (test_bit(__I40E_DOWN, &pf->state) || 375e3219ce6SAnjali Singhai Jain test_bit(__I40E_CONFIG_BUSY, &pf->state)) 376e3219ce6SAnjali Singhai Jain return; 377e3219ce6SAnjali Singhai Jain 3780ef2d5afSMitch Williams if (!client || !cdev) 3790ef2d5afSMitch Williams return; 380e3219ce6SAnjali Singhai Jain 3810ef2d5afSMitch Williams /* Here we handle client opens. If the client is down, but 3820ef2d5afSMitch Williams * the netdev is up, then open the client. 3830ef2d5afSMitch Williams */ 3840ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 3850ef2d5afSMitch Williams if (!test_bit(__I40E_DOWN, &vsi->state) && 3860ef2d5afSMitch Williams client->ops && client->ops->open) { 3870ef2d5afSMitch Williams set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 3880ef2d5afSMitch Williams ret = client->ops->open(&cdev->lan_info, client); 3890ef2d5afSMitch Williams if (ret) { 3900ef2d5afSMitch Williams /* Remove failed client instance */ 3910ef2d5afSMitch Williams clear_bit(__I40E_CLIENT_INSTANCE_OPENED, 3927be96322SMitch Williams &cdev->state); 3930ef2d5afSMitch Williams i40e_client_del_instance(pf); 3940ef2d5afSMitch Williams } 3950ef2d5afSMitch Williams } 3967be96322SMitch Williams } else { 3970ef2d5afSMitch Williams /* Likewise for client close. If the client is up, but the netdev 3980ef2d5afSMitch Williams * is down, then close the client. 3990ef2d5afSMitch Williams */ 4000ef2d5afSMitch Williams if (test_bit(__I40E_DOWN, &vsi->state) && 4010ef2d5afSMitch Williams client->ops && client->ops->close) { 4020ef2d5afSMitch Williams clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 4030ef2d5afSMitch Williams client->ops->close(&cdev->lan_info, client, false); 4040ef2d5afSMitch Williams i40e_client_release_qvlist(&cdev->lan_info); 405e3219ce6SAnjali Singhai Jain } 4067be96322SMitch Williams } 407e3219ce6SAnjali Singhai Jain } 408e3219ce6SAnjali Singhai Jain 409e3219ce6SAnjali Singhai Jain /** 410e3219ce6SAnjali Singhai Jain * i40e_lan_add_device - add a lan device struct to the list of lan devices 411e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 412e3219ce6SAnjali Singhai Jain * 413e3219ce6SAnjali Singhai Jain * Returns 0 on success or none 0 on error 414e3219ce6SAnjali Singhai Jain **/ 415e3219ce6SAnjali Singhai Jain int i40e_lan_add_device(struct i40e_pf *pf) 416e3219ce6SAnjali Singhai Jain { 417e3219ce6SAnjali Singhai Jain struct i40e_device *ldev; 418e3219ce6SAnjali Singhai Jain int ret = 0; 419e3219ce6SAnjali Singhai Jain 420e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 421e3219ce6SAnjali Singhai Jain list_for_each_entry(ldev, &i40e_devices, list) { 422e3219ce6SAnjali Singhai Jain if (ldev->pf == pf) { 423e3219ce6SAnjali Singhai Jain ret = -EEXIST; 424e3219ce6SAnjali Singhai Jain goto out; 425e3219ce6SAnjali Singhai Jain } 426e3219ce6SAnjali Singhai Jain } 427e3219ce6SAnjali Singhai Jain ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); 428e3219ce6SAnjali Singhai Jain if (!ldev) { 429e3219ce6SAnjali Singhai Jain ret = -ENOMEM; 430e3219ce6SAnjali Singhai Jain goto out; 431e3219ce6SAnjali Singhai Jain } 432e3219ce6SAnjali Singhai Jain ldev->pf = pf; 433e3219ce6SAnjali Singhai Jain INIT_LIST_HEAD(&ldev->list); 434e3219ce6SAnjali Singhai Jain list_add(&ldev->list, &i40e_devices); 435b3f028fcSSudheer Mogilappagari dev_info(&pf->pdev->dev, "Added LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n", 436b3f028fcSSudheer Mogilappagari pf->hw.pf_id, pf->hw.bus.bus_id, 437b3f028fcSSudheer Mogilappagari pf->hw.bus.device, pf->hw.bus.func); 438e3219ce6SAnjali Singhai Jain 439e3219ce6SAnjali Singhai Jain /* Since in some cases register may have happened before a device gets 440f38ff2eeSAnjali Singhai Jain * added, we can schedule a subtask to go initiate the clients if 441f38ff2eeSAnjali Singhai Jain * they can be launched at probe time. 442e3219ce6SAnjali Singhai Jain */ 443e3219ce6SAnjali Singhai Jain pf->flags |= I40E_FLAG_SERVICE_CLIENT_REQUESTED; 444e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 445e3219ce6SAnjali Singhai Jain 446e3219ce6SAnjali Singhai Jain out: 447e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 448e3219ce6SAnjali Singhai Jain return ret; 449e3219ce6SAnjali Singhai Jain } 450e3219ce6SAnjali Singhai Jain 451e3219ce6SAnjali Singhai Jain /** 452e3219ce6SAnjali Singhai Jain * i40e_lan_del_device - removes a lan device from the device list 453e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 454e3219ce6SAnjali Singhai Jain * 455e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 456e3219ce6SAnjali Singhai Jain **/ 457e3219ce6SAnjali Singhai Jain int i40e_lan_del_device(struct i40e_pf *pf) 458e3219ce6SAnjali Singhai Jain { 459e3219ce6SAnjali Singhai Jain struct i40e_device *ldev, *tmp; 460e3219ce6SAnjali Singhai Jain int ret = -ENODEV; 461e3219ce6SAnjali Singhai Jain 462*295c0a55SMitch Williams /* First, remove any client instance. */ 463*295c0a55SMitch Williams i40e_client_del_instance(pf); 464*295c0a55SMitch Williams 465e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 466e3219ce6SAnjali Singhai Jain list_for_each_entry_safe(ldev, tmp, &i40e_devices, list) { 467e3219ce6SAnjali Singhai Jain if (ldev->pf == pf) { 468b3f028fcSSudheer Mogilappagari dev_info(&pf->pdev->dev, "Deleted LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n", 469b3f028fcSSudheer Mogilappagari pf->hw.pf_id, pf->hw.bus.bus_id, 470b3f028fcSSudheer Mogilappagari pf->hw.bus.device, pf->hw.bus.func); 471e3219ce6SAnjali Singhai Jain list_del(&ldev->list); 472e3219ce6SAnjali Singhai Jain kfree(ldev); 473e3219ce6SAnjali Singhai Jain ret = 0; 474e3219ce6SAnjali Singhai Jain break; 475e3219ce6SAnjali Singhai Jain } 476e3219ce6SAnjali Singhai Jain } 477e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 478e3219ce6SAnjali Singhai Jain return ret; 479e3219ce6SAnjali Singhai Jain } 480e3219ce6SAnjali Singhai Jain 481e3219ce6SAnjali Singhai Jain /** 482e3219ce6SAnjali Singhai Jain * i40e_client_release - release client specific resources 483e3219ce6SAnjali Singhai Jain * @client: pointer to the registered client 484e3219ce6SAnjali Singhai Jain * 485e3219ce6SAnjali Singhai Jain **/ 4860ef2d5afSMitch Williams static void i40e_client_release(struct i40e_client *client) 487e3219ce6SAnjali Singhai Jain { 4880ef2d5afSMitch Williams struct i40e_client_instance *cdev; 4890ef2d5afSMitch Williams struct i40e_device *ldev; 490682d11d7SHarshitha Ramamurthy struct i40e_pf *pf; 491e3219ce6SAnjali Singhai Jain 4920ef2d5afSMitch Williams mutex_lock(&i40e_device_mutex); 4930ef2d5afSMitch Williams list_for_each_entry(ldev, &i40e_devices, list) { 4940ef2d5afSMitch Williams pf = ldev->pf; 4950ef2d5afSMitch Williams cdev = pf->cinst; 4960ef2d5afSMitch Williams if (!cdev) 497e3219ce6SAnjali Singhai Jain continue; 4980ef2d5afSMitch Williams 4990ef2d5afSMitch Williams while (test_and_set_bit(__I40E_SERVICE_SCHED, 5000ef2d5afSMitch Williams &pf->state)) 5010ef2d5afSMitch Williams usleep_range(500, 1000); 5020ef2d5afSMitch Williams 503e3219ce6SAnjali Singhai Jain if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 504e3219ce6SAnjali Singhai Jain if (client->ops && client->ops->close) 505e3219ce6SAnjali Singhai Jain client->ops->close(&cdev->lan_info, client, 506e3219ce6SAnjali Singhai Jain false); 507e3219ce6SAnjali Singhai Jain i40e_client_release_qvlist(&cdev->lan_info); 508e3219ce6SAnjali Singhai Jain clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 509e3219ce6SAnjali Singhai Jain 510e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 511e3219ce6SAnjali Singhai Jain "Client %s instance for PF id %d closed\n", 512e3219ce6SAnjali Singhai Jain client->name, pf->hw.pf_id); 513e3219ce6SAnjali Singhai Jain } 5140ef2d5afSMitch Williams /* delete the client instance */ 5150ef2d5afSMitch Williams i40e_client_del_instance(pf); 516e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, "Deleted client instance of Client %s\n", 517e3219ce6SAnjali Singhai Jain client->name); 5180ef2d5afSMitch Williams clear_bit(__I40E_SERVICE_SCHED, &pf->state); 519e3219ce6SAnjali Singhai Jain } 5200ef2d5afSMitch Williams mutex_unlock(&i40e_device_mutex); 521e3219ce6SAnjali Singhai Jain } 522e3219ce6SAnjali Singhai Jain 523e3219ce6SAnjali Singhai Jain /** 524e3219ce6SAnjali Singhai Jain * i40e_client_prepare - prepare client specific resources 525e3219ce6SAnjali Singhai Jain * @client: pointer to the registered client 526e3219ce6SAnjali Singhai Jain * 527e3219ce6SAnjali Singhai Jain **/ 5283bb83bafSMitch Williams static void i40e_client_prepare(struct i40e_client *client) 529e3219ce6SAnjali Singhai Jain { 530e3219ce6SAnjali Singhai Jain struct i40e_device *ldev; 531e3219ce6SAnjali Singhai Jain struct i40e_pf *pf; 532e3219ce6SAnjali Singhai Jain 533e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 534e3219ce6SAnjali Singhai Jain list_for_each_entry(ldev, &i40e_devices, list) { 535e3219ce6SAnjali Singhai Jain pf = ldev->pf; 5360ef2d5afSMitch Williams i40e_client_add_instance(pf); 537e3219ce6SAnjali Singhai Jain /* Start the client subtask */ 538e3219ce6SAnjali Singhai Jain pf->flags |= I40E_FLAG_SERVICE_CLIENT_REQUESTED; 539e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 540e3219ce6SAnjali Singhai Jain } 541e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 542e3219ce6SAnjali Singhai Jain } 543e3219ce6SAnjali Singhai Jain 544e3219ce6SAnjali Singhai Jain /** 545e3219ce6SAnjali Singhai Jain * i40e_client_virtchnl_send - TBD 546e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context 547e3219ce6SAnjali Singhai Jain * @client: Client pointer 548e3219ce6SAnjali Singhai Jain * @vf_id: absolute VF identifier 549e3219ce6SAnjali Singhai Jain * @msg: message buffer 550e3219ce6SAnjali Singhai Jain * @len: length of message buffer 551e3219ce6SAnjali Singhai Jain * 552e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 553e3219ce6SAnjali Singhai Jain **/ 554e3219ce6SAnjali Singhai Jain static int i40e_client_virtchnl_send(struct i40e_info *ldev, 555e3219ce6SAnjali Singhai Jain struct i40e_client *client, 556e3219ce6SAnjali Singhai Jain u32 vf_id, u8 *msg, u16 len) 557e3219ce6SAnjali Singhai Jain { 558e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 559e3219ce6SAnjali Singhai Jain struct i40e_hw *hw = &pf->hw; 560e3219ce6SAnjali Singhai Jain i40e_status err; 561e3219ce6SAnjali Singhai Jain 562e3219ce6SAnjali Singhai Jain err = i40e_aq_send_msg_to_vf(hw, vf_id, I40E_VIRTCHNL_OP_IWARP, 563e3219ce6SAnjali Singhai Jain 0, msg, len, NULL); 564e3219ce6SAnjali Singhai Jain if (err) 565e3219ce6SAnjali Singhai Jain dev_err(&pf->pdev->dev, "Unable to send iWarp message to VF, error %d, aq status %d\n", 566e3219ce6SAnjali Singhai Jain err, hw->aq.asq_last_status); 567e3219ce6SAnjali Singhai Jain 568e3219ce6SAnjali Singhai Jain return err; 569e3219ce6SAnjali Singhai Jain } 570e3219ce6SAnjali Singhai Jain 571e3219ce6SAnjali Singhai Jain /** 572e3219ce6SAnjali Singhai Jain * i40e_client_setup_qvlist 573e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 574e3219ce6SAnjali Singhai Jain * @client: Client pointer. 575e3219ce6SAnjali Singhai Jain * @qv_info: queue and vector list 576e3219ce6SAnjali Singhai Jain * 577e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 578e3219ce6SAnjali Singhai Jain **/ 579e3219ce6SAnjali Singhai Jain static int i40e_client_setup_qvlist(struct i40e_info *ldev, 580e3219ce6SAnjali Singhai Jain struct i40e_client *client, 581e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info) 582e3219ce6SAnjali Singhai Jain { 583e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 584e3219ce6SAnjali Singhai Jain struct i40e_hw *hw = &pf->hw; 585e3219ce6SAnjali Singhai Jain struct i40e_qv_info *qv_info; 586e3219ce6SAnjali Singhai Jain u32 v_idx, i, reg_idx, reg; 587e3219ce6SAnjali Singhai Jain u32 size; 588e3219ce6SAnjali Singhai Jain 589e3219ce6SAnjali Singhai Jain size = sizeof(struct i40e_qvlist_info) + 590e3219ce6SAnjali Singhai Jain (sizeof(struct i40e_qv_info) * (qvlist_info->num_vectors - 1)); 591e3219ce6SAnjali Singhai Jain ldev->qvlist_info = kzalloc(size, GFP_KERNEL); 592e3219ce6SAnjali Singhai Jain ldev->qvlist_info->num_vectors = qvlist_info->num_vectors; 593e3219ce6SAnjali Singhai Jain 594e3219ce6SAnjali Singhai Jain for (i = 0; i < qvlist_info->num_vectors; i++) { 595e3219ce6SAnjali Singhai Jain qv_info = &qvlist_info->qv_info[i]; 596e3219ce6SAnjali Singhai Jain if (!qv_info) 597e3219ce6SAnjali Singhai Jain continue; 598e3219ce6SAnjali Singhai Jain v_idx = qv_info->v_idx; 599e3219ce6SAnjali Singhai Jain 600e3219ce6SAnjali Singhai Jain /* Validate vector id belongs to this client */ 601e3219ce6SAnjali Singhai Jain if ((v_idx >= (pf->iwarp_base_vector + pf->num_iwarp_msix)) || 602e3219ce6SAnjali Singhai Jain (v_idx < pf->iwarp_base_vector)) 603e3219ce6SAnjali Singhai Jain goto err; 604e3219ce6SAnjali Singhai Jain 605e3219ce6SAnjali Singhai Jain ldev->qvlist_info->qv_info[i] = *qv_info; 606e3219ce6SAnjali Singhai Jain reg_idx = I40E_PFINT_LNKLSTN(v_idx - 1); 607e3219ce6SAnjali Singhai Jain 608e3219ce6SAnjali Singhai Jain if (qv_info->ceq_idx == I40E_QUEUE_INVALID_IDX) { 609e3219ce6SAnjali Singhai Jain /* Special case - No CEQ mapped on this vector */ 610e3219ce6SAnjali Singhai Jain wr32(hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK); 611e3219ce6SAnjali Singhai Jain } else { 612e3219ce6SAnjali Singhai Jain reg = (qv_info->ceq_idx & 613e3219ce6SAnjali Singhai Jain I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK) | 614e3219ce6SAnjali Singhai Jain (I40E_QUEUE_TYPE_PE_CEQ << 615e3219ce6SAnjali Singhai Jain I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT); 616e3219ce6SAnjali Singhai Jain wr32(hw, reg_idx, reg); 617e3219ce6SAnjali Singhai Jain 618e3219ce6SAnjali Singhai Jain reg = (I40E_PFINT_CEQCTL_CAUSE_ENA_MASK | 619e3219ce6SAnjali Singhai Jain (v_idx << I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT) | 620e3219ce6SAnjali Singhai Jain (qv_info->itr_idx << 621e3219ce6SAnjali Singhai Jain I40E_PFINT_CEQCTL_ITR_INDX_SHIFT) | 622e3219ce6SAnjali Singhai Jain (I40E_QUEUE_END_OF_LIST << 623e3219ce6SAnjali Singhai Jain I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)); 624e3219ce6SAnjali Singhai Jain wr32(hw, I40E_PFINT_CEQCTL(qv_info->ceq_idx), reg); 625e3219ce6SAnjali Singhai Jain } 626e3219ce6SAnjali Singhai Jain if (qv_info->aeq_idx != I40E_QUEUE_INVALID_IDX) { 627e3219ce6SAnjali Singhai Jain reg = (I40E_PFINT_AEQCTL_CAUSE_ENA_MASK | 628e3219ce6SAnjali Singhai Jain (v_idx << I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT) | 629e3219ce6SAnjali Singhai Jain (qv_info->itr_idx << 630e3219ce6SAnjali Singhai Jain I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)); 631e3219ce6SAnjali Singhai Jain 632e3219ce6SAnjali Singhai Jain wr32(hw, I40E_PFINT_AEQCTL, reg); 633e3219ce6SAnjali Singhai Jain } 634e3219ce6SAnjali Singhai Jain } 63570df973bSAvinash Dayanand /* Mitigate sync problems with iwarp VF driver */ 63670df973bSAvinash Dayanand i40e_flush(hw); 637e3219ce6SAnjali Singhai Jain return 0; 638e3219ce6SAnjali Singhai Jain err: 639e3219ce6SAnjali Singhai Jain kfree(ldev->qvlist_info); 640e3219ce6SAnjali Singhai Jain ldev->qvlist_info = NULL; 641e3219ce6SAnjali Singhai Jain return -EINVAL; 642e3219ce6SAnjali Singhai Jain } 643e3219ce6SAnjali Singhai Jain 644e3219ce6SAnjali Singhai Jain /** 645e3219ce6SAnjali Singhai Jain * i40e_client_request_reset 646e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 647e3219ce6SAnjali Singhai Jain * @client: Client pointer. 648e3219ce6SAnjali Singhai Jain * @level: reset level 649e3219ce6SAnjali Singhai Jain **/ 650e3219ce6SAnjali Singhai Jain static void i40e_client_request_reset(struct i40e_info *ldev, 651e3219ce6SAnjali Singhai Jain struct i40e_client *client, 652e3219ce6SAnjali Singhai Jain u32 reset_level) 653e3219ce6SAnjali Singhai Jain { 654e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 655e3219ce6SAnjali Singhai Jain 656e3219ce6SAnjali Singhai Jain switch (reset_level) { 657e3219ce6SAnjali Singhai Jain case I40E_CLIENT_RESET_LEVEL_PF: 658e3219ce6SAnjali Singhai Jain set_bit(__I40E_PF_RESET_REQUESTED, &pf->state); 659e3219ce6SAnjali Singhai Jain break; 660e3219ce6SAnjali Singhai Jain case I40E_CLIENT_RESET_LEVEL_CORE: 661e3219ce6SAnjali Singhai Jain set_bit(__I40E_PF_RESET_REQUESTED, &pf->state); 662e3219ce6SAnjali Singhai Jain break; 663e3219ce6SAnjali Singhai Jain default: 664e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 6650ef2d5afSMitch Williams "Client for PF id %d requested an unsupported reset: %d.\n", 6660ef2d5afSMitch Williams pf->hw.pf_id, reset_level); 667e3219ce6SAnjali Singhai Jain break; 668e3219ce6SAnjali Singhai Jain } 669e3219ce6SAnjali Singhai Jain 670e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 671e3219ce6SAnjali Singhai Jain } 672e3219ce6SAnjali Singhai Jain 673e3219ce6SAnjali Singhai Jain /** 674e3219ce6SAnjali Singhai Jain * i40e_client_update_vsi_ctxt 675e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 676e3219ce6SAnjali Singhai Jain * @client: Client pointer. 677e3219ce6SAnjali Singhai Jain * @is_vf: if this for the VF 678e3219ce6SAnjali Singhai Jain * @vf_id: if is_vf true this carries the vf_id 679e3219ce6SAnjali Singhai Jain * @flag: Any device level setting that needs to be done for PE 680e3219ce6SAnjali Singhai Jain * @valid_flag: Bits in this match up and enable changing of flag bits 681e3219ce6SAnjali Singhai Jain * 682e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 683e3219ce6SAnjali Singhai Jain **/ 684e3219ce6SAnjali Singhai Jain static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, 685e3219ce6SAnjali Singhai Jain struct i40e_client *client, 686e3219ce6SAnjali Singhai Jain bool is_vf, u32 vf_id, 687e3219ce6SAnjali Singhai Jain u32 flag, u32 valid_flag) 688e3219ce6SAnjali Singhai Jain { 689e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 690e3219ce6SAnjali Singhai Jain struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 691e3219ce6SAnjali Singhai Jain struct i40e_vsi_context ctxt; 692e3219ce6SAnjali Singhai Jain bool update = true; 693e3219ce6SAnjali Singhai Jain i40e_status err; 694e3219ce6SAnjali Singhai Jain 695e3219ce6SAnjali Singhai Jain /* TODO: for now do not allow setting VF's VSI setting */ 696e3219ce6SAnjali Singhai Jain if (is_vf) 697e3219ce6SAnjali Singhai Jain return -EINVAL; 698e3219ce6SAnjali Singhai Jain 699e3219ce6SAnjali Singhai Jain ctxt.seid = pf->main_vsi_seid; 700e3219ce6SAnjali Singhai Jain ctxt.pf_num = pf->hw.pf_id; 701e3219ce6SAnjali Singhai Jain err = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); 702e3219ce6SAnjali Singhai Jain ctxt.flags = I40E_AQ_VSI_TYPE_PF; 703e3219ce6SAnjali Singhai Jain if (err) { 704e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, 705e3219ce6SAnjali Singhai Jain "couldn't get PF vsi config, err %s aq_err %s\n", 706e3219ce6SAnjali Singhai Jain i40e_stat_str(&pf->hw, err), 707e3219ce6SAnjali Singhai Jain i40e_aq_str(&pf->hw, 708e3219ce6SAnjali Singhai Jain pf->hw.aq.asq_last_status)); 709e3219ce6SAnjali Singhai Jain return -ENOENT; 710e3219ce6SAnjali Singhai Jain } 711e3219ce6SAnjali Singhai Jain 712e3219ce6SAnjali Singhai Jain if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE) && 713e3219ce6SAnjali Singhai Jain (flag & I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE)) { 714e3219ce6SAnjali Singhai Jain ctxt.info.valid_sections = 715e3219ce6SAnjali Singhai Jain cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID); 716e3219ce6SAnjali Singhai Jain ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA; 717e3219ce6SAnjali Singhai Jain } else if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE) && 718e3219ce6SAnjali Singhai Jain !(flag & I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE)) { 719e3219ce6SAnjali Singhai Jain ctxt.info.valid_sections = 720e3219ce6SAnjali Singhai Jain cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID); 721e3219ce6SAnjali Singhai Jain ctxt.info.queueing_opt_flags &= ~I40E_AQ_VSI_QUE_OPT_TCP_ENA; 722e3219ce6SAnjali Singhai Jain } else { 723e3219ce6SAnjali Singhai Jain update = false; 724e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 7250ef2d5afSMitch Williams "Client for PF id %d request an unsupported Config: %x.\n", 7260ef2d5afSMitch Williams pf->hw.pf_id, flag); 727e3219ce6SAnjali Singhai Jain } 728e3219ce6SAnjali Singhai Jain 729e3219ce6SAnjali Singhai Jain if (update) { 730e3219ce6SAnjali Singhai Jain err = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); 731e3219ce6SAnjali Singhai Jain if (err) { 732e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, 733e3219ce6SAnjali Singhai Jain "update VSI ctxt for PE failed, err %s aq_err %s\n", 734e3219ce6SAnjali Singhai Jain i40e_stat_str(&pf->hw, err), 735e3219ce6SAnjali Singhai Jain i40e_aq_str(&pf->hw, 736e3219ce6SAnjali Singhai Jain pf->hw.aq.asq_last_status)); 737e3219ce6SAnjali Singhai Jain } 738e3219ce6SAnjali Singhai Jain } 739e3219ce6SAnjali Singhai Jain return err; 740e3219ce6SAnjali Singhai Jain } 741e3219ce6SAnjali Singhai Jain 742e3219ce6SAnjali Singhai Jain /** 743e3219ce6SAnjali Singhai Jain * i40e_register_client - Register a i40e client driver with the L2 driver 744e3219ce6SAnjali Singhai Jain * @client: pointer to the i40e_client struct 745e3219ce6SAnjali Singhai Jain * 746e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 747e3219ce6SAnjali Singhai Jain **/ 748e3219ce6SAnjali Singhai Jain int i40e_register_client(struct i40e_client *client) 749e3219ce6SAnjali Singhai Jain { 750e3219ce6SAnjali Singhai Jain int ret = 0; 751e3219ce6SAnjali Singhai Jain 752e3219ce6SAnjali Singhai Jain if (!client) { 753e3219ce6SAnjali Singhai Jain ret = -EIO; 754e3219ce6SAnjali Singhai Jain goto out; 755e3219ce6SAnjali Singhai Jain } 756e3219ce6SAnjali Singhai Jain 757e3219ce6SAnjali Singhai Jain if (strlen(client->name) == 0) { 758e3219ce6SAnjali Singhai Jain pr_info("i40e: Failed to register client with no name\n"); 759e3219ce6SAnjali Singhai Jain ret = -EIO; 760e3219ce6SAnjali Singhai Jain goto out; 761e3219ce6SAnjali Singhai Jain } 762e3219ce6SAnjali Singhai Jain 7630ef2d5afSMitch Williams if (registered_client) { 764e3219ce6SAnjali Singhai Jain pr_info("i40e: Client %s has already been registered!\n", 765e3219ce6SAnjali Singhai Jain client->name); 766e3219ce6SAnjali Singhai Jain ret = -EEXIST; 767e3219ce6SAnjali Singhai Jain goto out; 768e3219ce6SAnjali Singhai Jain } 769e3219ce6SAnjali Singhai Jain 770e3219ce6SAnjali Singhai Jain if ((client->version.major != I40E_CLIENT_VERSION_MAJOR) || 771e3219ce6SAnjali Singhai Jain (client->version.minor != I40E_CLIENT_VERSION_MINOR)) { 772e3219ce6SAnjali Singhai Jain pr_info("i40e: Failed to register client %s due to mismatched client interface version\n", 773e3219ce6SAnjali Singhai Jain client->name); 774e3219ce6SAnjali Singhai Jain pr_info("Client is using version: %02d.%02d.%02d while LAN driver supports %s\n", 775e3219ce6SAnjali Singhai Jain client->version.major, client->version.minor, 776e3219ce6SAnjali Singhai Jain client->version.build, 777e3219ce6SAnjali Singhai Jain i40e_client_interface_version_str); 778e3219ce6SAnjali Singhai Jain ret = -EIO; 779e3219ce6SAnjali Singhai Jain goto out; 780e3219ce6SAnjali Singhai Jain } 781e3219ce6SAnjali Singhai Jain 7820ef2d5afSMitch Williams registered_client = client; 783e3219ce6SAnjali Singhai Jain 7843bb83bafSMitch Williams i40e_client_prepare(client); 785e3219ce6SAnjali Singhai Jain 7863bb83bafSMitch Williams pr_info("i40e: Registered client %s\n", client->name); 787e3219ce6SAnjali Singhai Jain out: 788e3219ce6SAnjali Singhai Jain return ret; 789e3219ce6SAnjali Singhai Jain } 790e3219ce6SAnjali Singhai Jain EXPORT_SYMBOL(i40e_register_client); 791e3219ce6SAnjali Singhai Jain 792e3219ce6SAnjali Singhai Jain /** 793e3219ce6SAnjali Singhai Jain * i40e_unregister_client - Unregister a i40e client driver with the L2 driver 794e3219ce6SAnjali Singhai Jain * @client: pointer to the i40e_client struct 795e3219ce6SAnjali Singhai Jain * 796e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 797e3219ce6SAnjali Singhai Jain **/ 798e3219ce6SAnjali Singhai Jain int i40e_unregister_client(struct i40e_client *client) 799e3219ce6SAnjali Singhai Jain { 800e3219ce6SAnjali Singhai Jain int ret = 0; 801e3219ce6SAnjali Singhai Jain 8020ef2d5afSMitch Williams if (registered_client != client) { 803e3219ce6SAnjali Singhai Jain pr_info("i40e: Client %s has not been registered\n", 804e3219ce6SAnjali Singhai Jain client->name); 805e3219ce6SAnjali Singhai Jain ret = -ENODEV; 806e3219ce6SAnjali Singhai Jain goto out; 807e3219ce6SAnjali Singhai Jain } 8080ef2d5afSMitch Williams registered_client = NULL; 8090ef2d5afSMitch Williams /* When a unregister request comes through we would have to send 8100ef2d5afSMitch Williams * a close for each of the client instances that were opened. 8110ef2d5afSMitch Williams * client_release function is called to handle this. 8120ef2d5afSMitch Williams */ 8130ef2d5afSMitch Williams i40e_client_release(client); 8140ef2d5afSMitch Williams 8150ef2d5afSMitch Williams pr_info("i40e: Unregistered client %s\n", client->name); 816e3219ce6SAnjali Singhai Jain out: 817e3219ce6SAnjali Singhai Jain return ret; 818e3219ce6SAnjali Singhai Jain } 819e3219ce6SAnjali Singhai Jain EXPORT_SYMBOL(i40e_unregister_client); 820