1e3219ce6SAnjali Singhai Jain /******************************************************************************* 2e3219ce6SAnjali Singhai Jain * 3e3219ce6SAnjali Singhai Jain * Intel Ethernet Controller XL710 Family Linux Driver 459e331e3SJacob Keller * Copyright(c) 2013 - 2017 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) { 27659e331e3SJacob Keller dev_dbg(&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 */ 3740da36b97SJacob Keller if (test_bit(__I40E_DOWN, pf->state) || 3750da36b97SJacob Keller 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 381*7b0b1a6dSShiraz Saleem /* Here we handle client opens. If the client is down, and 382*7b0b1a6dSShiraz Saleem * the netdev is registered, then open the client. 3830ef2d5afSMitch Williams */ 3840ef2d5afSMitch Williams if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 385*7b0b1a6dSShiraz Saleem if (vsi->netdev_registered && 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 } 396*7b0b1a6dSShiraz Saleem } 397*7b0b1a6dSShiraz Saleem 398*7b0b1a6dSShiraz Saleem /* enable/disable PE TCP_ENA flag based on netdev down/up 3990ef2d5afSMitch Williams */ 400*7b0b1a6dSShiraz Saleem if (test_bit(__I40E_VSI_DOWN, vsi->state)) 401*7b0b1a6dSShiraz Saleem i40e_client_update_vsi_ctxt(&cdev->lan_info, client, 402*7b0b1a6dSShiraz Saleem 0, 0, 0, 403*7b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE); 404*7b0b1a6dSShiraz Saleem else 405*7b0b1a6dSShiraz Saleem i40e_client_update_vsi_ctxt(&cdev->lan_info, client, 406*7b0b1a6dSShiraz Saleem 0, 0, 407*7b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE, 408*7b0b1a6dSShiraz Saleem I40E_CLIENT_VSI_FLAG_TCP_ENABLE); 409e3219ce6SAnjali Singhai Jain } 410e3219ce6SAnjali Singhai Jain 411e3219ce6SAnjali Singhai Jain /** 412e3219ce6SAnjali Singhai Jain * i40e_lan_add_device - add a lan device struct to the list of lan devices 413e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 414e3219ce6SAnjali Singhai Jain * 415e3219ce6SAnjali Singhai Jain * Returns 0 on success or none 0 on error 416e3219ce6SAnjali Singhai Jain **/ 417e3219ce6SAnjali Singhai Jain int i40e_lan_add_device(struct i40e_pf *pf) 418e3219ce6SAnjali Singhai Jain { 419e3219ce6SAnjali Singhai Jain struct i40e_device *ldev; 420e3219ce6SAnjali Singhai Jain int ret = 0; 421e3219ce6SAnjali Singhai Jain 422e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 423e3219ce6SAnjali Singhai Jain list_for_each_entry(ldev, &i40e_devices, list) { 424e3219ce6SAnjali Singhai Jain if (ldev->pf == pf) { 425e3219ce6SAnjali Singhai Jain ret = -EEXIST; 426e3219ce6SAnjali Singhai Jain goto out; 427e3219ce6SAnjali Singhai Jain } 428e3219ce6SAnjali Singhai Jain } 429e3219ce6SAnjali Singhai Jain ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); 430e3219ce6SAnjali Singhai Jain if (!ldev) { 431e3219ce6SAnjali Singhai Jain ret = -ENOMEM; 432e3219ce6SAnjali Singhai Jain goto out; 433e3219ce6SAnjali Singhai Jain } 434e3219ce6SAnjali Singhai Jain ldev->pf = pf; 435e3219ce6SAnjali Singhai Jain INIT_LIST_HEAD(&ldev->list); 436e3219ce6SAnjali Singhai Jain list_add(&ldev->list, &i40e_devices); 437b3f028fcSSudheer Mogilappagari dev_info(&pf->pdev->dev, "Added LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n", 438b3f028fcSSudheer Mogilappagari pf->hw.pf_id, pf->hw.bus.bus_id, 439b3f028fcSSudheer Mogilappagari pf->hw.bus.device, pf->hw.bus.func); 440e3219ce6SAnjali Singhai Jain 4418090f618SMitch Williams /* If a client has already been registered, we need to add an instance 4428090f618SMitch Williams * of it to our new LAN device. 4438090f618SMitch Williams */ 4448090f618SMitch Williams if (registered_client) 4458090f618SMitch Williams i40e_client_add_instance(pf); 4468090f618SMitch Williams 447e3219ce6SAnjali Singhai Jain /* Since in some cases register may have happened before a device gets 448f38ff2eeSAnjali Singhai Jain * added, we can schedule a subtask to go initiate the clients if 449f38ff2eeSAnjali Singhai Jain * they can be launched at probe time. 450e3219ce6SAnjali Singhai Jain */ 451e3219ce6SAnjali Singhai Jain pf->flags |= I40E_FLAG_SERVICE_CLIENT_REQUESTED; 452e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 453e3219ce6SAnjali Singhai Jain 454e3219ce6SAnjali Singhai Jain out: 455e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 456e3219ce6SAnjali Singhai Jain return ret; 457e3219ce6SAnjali Singhai Jain } 458e3219ce6SAnjali Singhai Jain 459e3219ce6SAnjali Singhai Jain /** 460e3219ce6SAnjali Singhai Jain * i40e_lan_del_device - removes a lan device from the device list 461e3219ce6SAnjali Singhai Jain * @pf: pointer to the board struct 462e3219ce6SAnjali Singhai Jain * 463e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 464e3219ce6SAnjali Singhai Jain **/ 465e3219ce6SAnjali Singhai Jain int i40e_lan_del_device(struct i40e_pf *pf) 466e3219ce6SAnjali Singhai Jain { 467e3219ce6SAnjali Singhai Jain struct i40e_device *ldev, *tmp; 468e3219ce6SAnjali Singhai Jain int ret = -ENODEV; 469e3219ce6SAnjali Singhai Jain 470295c0a55SMitch Williams /* First, remove any client instance. */ 471295c0a55SMitch Williams i40e_client_del_instance(pf); 472295c0a55SMitch Williams 473e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 474e3219ce6SAnjali Singhai Jain list_for_each_entry_safe(ldev, tmp, &i40e_devices, list) { 475e3219ce6SAnjali Singhai Jain if (ldev->pf == pf) { 476b3f028fcSSudheer Mogilappagari dev_info(&pf->pdev->dev, "Deleted LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n", 477b3f028fcSSudheer Mogilappagari pf->hw.pf_id, pf->hw.bus.bus_id, 478b3f028fcSSudheer Mogilappagari pf->hw.bus.device, pf->hw.bus.func); 479e3219ce6SAnjali Singhai Jain list_del(&ldev->list); 480e3219ce6SAnjali Singhai Jain kfree(ldev); 481e3219ce6SAnjali Singhai Jain ret = 0; 482e3219ce6SAnjali Singhai Jain break; 483e3219ce6SAnjali Singhai Jain } 484e3219ce6SAnjali Singhai Jain } 485e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 486e3219ce6SAnjali Singhai Jain return ret; 487e3219ce6SAnjali Singhai Jain } 488e3219ce6SAnjali Singhai Jain 489e3219ce6SAnjali Singhai Jain /** 490e3219ce6SAnjali Singhai Jain * i40e_client_release - release client specific resources 491e3219ce6SAnjali Singhai Jain * @client: pointer to the registered client 492e3219ce6SAnjali Singhai Jain * 493e3219ce6SAnjali Singhai Jain **/ 4940ef2d5afSMitch Williams static void i40e_client_release(struct i40e_client *client) 495e3219ce6SAnjali Singhai Jain { 4960ef2d5afSMitch Williams struct i40e_client_instance *cdev; 4970ef2d5afSMitch Williams struct i40e_device *ldev; 498682d11d7SHarshitha Ramamurthy struct i40e_pf *pf; 499e3219ce6SAnjali Singhai Jain 5000ef2d5afSMitch Williams mutex_lock(&i40e_device_mutex); 5010ef2d5afSMitch Williams list_for_each_entry(ldev, &i40e_devices, list) { 5020ef2d5afSMitch Williams pf = ldev->pf; 5030ef2d5afSMitch Williams cdev = pf->cinst; 5040ef2d5afSMitch Williams if (!cdev) 505e3219ce6SAnjali Singhai Jain continue; 5060ef2d5afSMitch Williams 5070ef2d5afSMitch Williams while (test_and_set_bit(__I40E_SERVICE_SCHED, 5080da36b97SJacob Keller pf->state)) 5090ef2d5afSMitch Williams usleep_range(500, 1000); 5100ef2d5afSMitch Williams 511e3219ce6SAnjali Singhai Jain if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { 512e3219ce6SAnjali Singhai Jain if (client->ops && client->ops->close) 513e3219ce6SAnjali Singhai Jain client->ops->close(&cdev->lan_info, client, 514e3219ce6SAnjali Singhai Jain false); 515e3219ce6SAnjali Singhai Jain i40e_client_release_qvlist(&cdev->lan_info); 516e3219ce6SAnjali Singhai Jain clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); 517e3219ce6SAnjali Singhai Jain 518e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 519e3219ce6SAnjali Singhai Jain "Client %s instance for PF id %d closed\n", 520e3219ce6SAnjali Singhai Jain client->name, pf->hw.pf_id); 521e3219ce6SAnjali Singhai Jain } 5220ef2d5afSMitch Williams /* delete the client instance */ 5230ef2d5afSMitch Williams i40e_client_del_instance(pf); 524e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, "Deleted client instance of Client %s\n", 525e3219ce6SAnjali Singhai Jain client->name); 5260da36b97SJacob Keller clear_bit(__I40E_SERVICE_SCHED, pf->state); 527e3219ce6SAnjali Singhai Jain } 5280ef2d5afSMitch Williams mutex_unlock(&i40e_device_mutex); 529e3219ce6SAnjali Singhai Jain } 530e3219ce6SAnjali Singhai Jain 531e3219ce6SAnjali Singhai Jain /** 532e3219ce6SAnjali Singhai Jain * i40e_client_prepare - prepare client specific resources 533e3219ce6SAnjali Singhai Jain * @client: pointer to the registered client 534e3219ce6SAnjali Singhai Jain * 535e3219ce6SAnjali Singhai Jain **/ 5363bb83bafSMitch Williams static void i40e_client_prepare(struct i40e_client *client) 537e3219ce6SAnjali Singhai Jain { 538e3219ce6SAnjali Singhai Jain struct i40e_device *ldev; 539e3219ce6SAnjali Singhai Jain struct i40e_pf *pf; 540e3219ce6SAnjali Singhai Jain 541e3219ce6SAnjali Singhai Jain mutex_lock(&i40e_device_mutex); 542e3219ce6SAnjali Singhai Jain list_for_each_entry(ldev, &i40e_devices, list) { 543e3219ce6SAnjali Singhai Jain pf = ldev->pf; 5440ef2d5afSMitch Williams i40e_client_add_instance(pf); 545e3219ce6SAnjali Singhai Jain /* Start the client subtask */ 546e3219ce6SAnjali Singhai Jain pf->flags |= I40E_FLAG_SERVICE_CLIENT_REQUESTED; 547e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 548e3219ce6SAnjali Singhai Jain } 549e3219ce6SAnjali Singhai Jain mutex_unlock(&i40e_device_mutex); 550e3219ce6SAnjali Singhai Jain } 551e3219ce6SAnjali Singhai Jain 552e3219ce6SAnjali Singhai Jain /** 553e3219ce6SAnjali Singhai Jain * i40e_client_virtchnl_send - TBD 554e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context 555e3219ce6SAnjali Singhai Jain * @client: Client pointer 556e3219ce6SAnjali Singhai Jain * @vf_id: absolute VF identifier 557e3219ce6SAnjali Singhai Jain * @msg: message buffer 558e3219ce6SAnjali Singhai Jain * @len: length of message buffer 559e3219ce6SAnjali Singhai Jain * 560e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 561e3219ce6SAnjali Singhai Jain **/ 562e3219ce6SAnjali Singhai Jain static int i40e_client_virtchnl_send(struct i40e_info *ldev, 563e3219ce6SAnjali Singhai Jain struct i40e_client *client, 564e3219ce6SAnjali Singhai Jain u32 vf_id, u8 *msg, u16 len) 565e3219ce6SAnjali Singhai Jain { 566e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 567e3219ce6SAnjali Singhai Jain struct i40e_hw *hw = &pf->hw; 568e3219ce6SAnjali Singhai Jain i40e_status err; 569e3219ce6SAnjali Singhai Jain 570310a2ad9SJesse Brandeburg err = i40e_aq_send_msg_to_vf(hw, vf_id, VIRTCHNL_OP_IWARP, 571e3219ce6SAnjali Singhai Jain 0, msg, len, NULL); 572e3219ce6SAnjali Singhai Jain if (err) 573e3219ce6SAnjali Singhai Jain dev_err(&pf->pdev->dev, "Unable to send iWarp message to VF, error %d, aq status %d\n", 574e3219ce6SAnjali Singhai Jain err, hw->aq.asq_last_status); 575e3219ce6SAnjali Singhai Jain 576e3219ce6SAnjali Singhai Jain return err; 577e3219ce6SAnjali Singhai Jain } 578e3219ce6SAnjali Singhai Jain 579e3219ce6SAnjali Singhai Jain /** 580e3219ce6SAnjali Singhai Jain * i40e_client_setup_qvlist 581e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 582e3219ce6SAnjali Singhai Jain * @client: Client pointer. 583e3219ce6SAnjali Singhai Jain * @qv_info: queue and vector list 584e3219ce6SAnjali Singhai Jain * 585e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 586e3219ce6SAnjali Singhai Jain **/ 587e3219ce6SAnjali Singhai Jain static int i40e_client_setup_qvlist(struct i40e_info *ldev, 588e3219ce6SAnjali Singhai Jain struct i40e_client *client, 589e3219ce6SAnjali Singhai Jain struct i40e_qvlist_info *qvlist_info) 590e3219ce6SAnjali Singhai Jain { 591e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 592e3219ce6SAnjali Singhai Jain struct i40e_hw *hw = &pf->hw; 593e3219ce6SAnjali Singhai Jain struct i40e_qv_info *qv_info; 594e3219ce6SAnjali Singhai Jain u32 v_idx, i, reg_idx, reg; 595e3219ce6SAnjali Singhai Jain u32 size; 596e3219ce6SAnjali Singhai Jain 597e3219ce6SAnjali Singhai Jain size = sizeof(struct i40e_qvlist_info) + 598e3219ce6SAnjali Singhai Jain (sizeof(struct i40e_qv_info) * (qvlist_info->num_vectors - 1)); 599e3219ce6SAnjali Singhai Jain ldev->qvlist_info = kzalloc(size, GFP_KERNEL); 6000a4ecc2cSChristophe Jaillet if (!ldev->qvlist_info) 6010a4ecc2cSChristophe Jaillet return -ENOMEM; 602e3219ce6SAnjali Singhai Jain ldev->qvlist_info->num_vectors = qvlist_info->num_vectors; 603e3219ce6SAnjali Singhai Jain 604e3219ce6SAnjali Singhai Jain for (i = 0; i < qvlist_info->num_vectors; i++) { 605e3219ce6SAnjali Singhai Jain qv_info = &qvlist_info->qv_info[i]; 606e3219ce6SAnjali Singhai Jain if (!qv_info) 607e3219ce6SAnjali Singhai Jain continue; 608e3219ce6SAnjali Singhai Jain v_idx = qv_info->v_idx; 609e3219ce6SAnjali Singhai Jain 610e3219ce6SAnjali Singhai Jain /* Validate vector id belongs to this client */ 611e3219ce6SAnjali Singhai Jain if ((v_idx >= (pf->iwarp_base_vector + pf->num_iwarp_msix)) || 612e3219ce6SAnjali Singhai Jain (v_idx < pf->iwarp_base_vector)) 613e3219ce6SAnjali Singhai Jain goto err; 614e3219ce6SAnjali Singhai Jain 615e3219ce6SAnjali Singhai Jain ldev->qvlist_info->qv_info[i] = *qv_info; 616e3219ce6SAnjali Singhai Jain reg_idx = I40E_PFINT_LNKLSTN(v_idx - 1); 617e3219ce6SAnjali Singhai Jain 618e3219ce6SAnjali Singhai Jain if (qv_info->ceq_idx == I40E_QUEUE_INVALID_IDX) { 619e3219ce6SAnjali Singhai Jain /* Special case - No CEQ mapped on this vector */ 620e3219ce6SAnjali Singhai Jain wr32(hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK); 621e3219ce6SAnjali Singhai Jain } else { 622e3219ce6SAnjali Singhai Jain reg = (qv_info->ceq_idx & 623e3219ce6SAnjali Singhai Jain I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK) | 624e3219ce6SAnjali Singhai Jain (I40E_QUEUE_TYPE_PE_CEQ << 625e3219ce6SAnjali Singhai Jain I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT); 626e3219ce6SAnjali Singhai Jain wr32(hw, reg_idx, reg); 627e3219ce6SAnjali Singhai Jain 628e3219ce6SAnjali Singhai Jain reg = (I40E_PFINT_CEQCTL_CAUSE_ENA_MASK | 629e3219ce6SAnjali Singhai Jain (v_idx << I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT) | 630e3219ce6SAnjali Singhai Jain (qv_info->itr_idx << 631e3219ce6SAnjali Singhai Jain I40E_PFINT_CEQCTL_ITR_INDX_SHIFT) | 632e3219ce6SAnjali Singhai Jain (I40E_QUEUE_END_OF_LIST << 633e3219ce6SAnjali Singhai Jain I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)); 634e3219ce6SAnjali Singhai Jain wr32(hw, I40E_PFINT_CEQCTL(qv_info->ceq_idx), reg); 635e3219ce6SAnjali Singhai Jain } 636e3219ce6SAnjali Singhai Jain if (qv_info->aeq_idx != I40E_QUEUE_INVALID_IDX) { 637e3219ce6SAnjali Singhai Jain reg = (I40E_PFINT_AEQCTL_CAUSE_ENA_MASK | 638e3219ce6SAnjali Singhai Jain (v_idx << I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT) | 639e3219ce6SAnjali Singhai Jain (qv_info->itr_idx << 640e3219ce6SAnjali Singhai Jain I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)); 641e3219ce6SAnjali Singhai Jain 642e3219ce6SAnjali Singhai Jain wr32(hw, I40E_PFINT_AEQCTL, reg); 643e3219ce6SAnjali Singhai Jain } 644e3219ce6SAnjali Singhai Jain } 64570df973bSAvinash Dayanand /* Mitigate sync problems with iwarp VF driver */ 64670df973bSAvinash Dayanand i40e_flush(hw); 647e3219ce6SAnjali Singhai Jain return 0; 648e3219ce6SAnjali Singhai Jain err: 649e3219ce6SAnjali Singhai Jain kfree(ldev->qvlist_info); 650e3219ce6SAnjali Singhai Jain ldev->qvlist_info = NULL; 651e3219ce6SAnjali Singhai Jain return -EINVAL; 652e3219ce6SAnjali Singhai Jain } 653e3219ce6SAnjali Singhai Jain 654e3219ce6SAnjali Singhai Jain /** 655e3219ce6SAnjali Singhai Jain * i40e_client_request_reset 656e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 657e3219ce6SAnjali Singhai Jain * @client: Client pointer. 658e3219ce6SAnjali Singhai Jain * @level: reset level 659e3219ce6SAnjali Singhai Jain **/ 660e3219ce6SAnjali Singhai Jain static void i40e_client_request_reset(struct i40e_info *ldev, 661e3219ce6SAnjali Singhai Jain struct i40e_client *client, 662e3219ce6SAnjali Singhai Jain u32 reset_level) 663e3219ce6SAnjali Singhai Jain { 664e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 665e3219ce6SAnjali Singhai Jain 666e3219ce6SAnjali Singhai Jain switch (reset_level) { 667e3219ce6SAnjali Singhai Jain case I40E_CLIENT_RESET_LEVEL_PF: 6680da36b97SJacob Keller set_bit(__I40E_PF_RESET_REQUESTED, pf->state); 669e3219ce6SAnjali Singhai Jain break; 670e3219ce6SAnjali Singhai Jain case I40E_CLIENT_RESET_LEVEL_CORE: 6710da36b97SJacob Keller set_bit(__I40E_PF_RESET_REQUESTED, pf->state); 672e3219ce6SAnjali Singhai Jain break; 673e3219ce6SAnjali Singhai Jain default: 674e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 6750ef2d5afSMitch Williams "Client for PF id %d requested an unsupported reset: %d.\n", 6760ef2d5afSMitch Williams pf->hw.pf_id, reset_level); 677e3219ce6SAnjali Singhai Jain break; 678e3219ce6SAnjali Singhai Jain } 679e3219ce6SAnjali Singhai Jain 680e3219ce6SAnjali Singhai Jain i40e_service_event_schedule(pf); 681e3219ce6SAnjali Singhai Jain } 682e3219ce6SAnjali Singhai Jain 683e3219ce6SAnjali Singhai Jain /** 684e3219ce6SAnjali Singhai Jain * i40e_client_update_vsi_ctxt 685e3219ce6SAnjali Singhai Jain * @ldev: pointer to L2 context. 686e3219ce6SAnjali Singhai Jain * @client: Client pointer. 687e3219ce6SAnjali Singhai Jain * @is_vf: if this for the VF 688e3219ce6SAnjali Singhai Jain * @vf_id: if is_vf true this carries the vf_id 689e3219ce6SAnjali Singhai Jain * @flag: Any device level setting that needs to be done for PE 690e3219ce6SAnjali Singhai Jain * @valid_flag: Bits in this match up and enable changing of flag bits 691e3219ce6SAnjali Singhai Jain * 692e3219ce6SAnjali Singhai Jain * Return 0 on success or < 0 on error 693e3219ce6SAnjali Singhai Jain **/ 694e3219ce6SAnjali Singhai Jain static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, 695e3219ce6SAnjali Singhai Jain struct i40e_client *client, 696e3219ce6SAnjali Singhai Jain bool is_vf, u32 vf_id, 697e3219ce6SAnjali Singhai Jain u32 flag, u32 valid_flag) 698e3219ce6SAnjali Singhai Jain { 699e3219ce6SAnjali Singhai Jain struct i40e_pf *pf = ldev->pf; 700e3219ce6SAnjali Singhai Jain struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 701e3219ce6SAnjali Singhai Jain struct i40e_vsi_context ctxt; 702e3219ce6SAnjali Singhai Jain bool update = true; 703e3219ce6SAnjali Singhai Jain i40e_status err; 704e3219ce6SAnjali Singhai Jain 705e3219ce6SAnjali Singhai Jain /* TODO: for now do not allow setting VF's VSI setting */ 706e3219ce6SAnjali Singhai Jain if (is_vf) 707e3219ce6SAnjali Singhai Jain return -EINVAL; 708e3219ce6SAnjali Singhai Jain 709e3219ce6SAnjali Singhai Jain ctxt.seid = pf->main_vsi_seid; 710e3219ce6SAnjali Singhai Jain ctxt.pf_num = pf->hw.pf_id; 711e3219ce6SAnjali Singhai Jain err = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); 712e3219ce6SAnjali Singhai Jain ctxt.flags = I40E_AQ_VSI_TYPE_PF; 713e3219ce6SAnjali Singhai Jain if (err) { 714e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, 715e3219ce6SAnjali Singhai Jain "couldn't get PF vsi config, err %s aq_err %s\n", 716e3219ce6SAnjali Singhai Jain i40e_stat_str(&pf->hw, err), 717e3219ce6SAnjali Singhai Jain i40e_aq_str(&pf->hw, 718e3219ce6SAnjali Singhai Jain pf->hw.aq.asq_last_status)); 719e3219ce6SAnjali Singhai Jain return -ENOENT; 720e3219ce6SAnjali Singhai Jain } 721e3219ce6SAnjali Singhai Jain 722*7b0b1a6dSShiraz Saleem if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) && 723*7b0b1a6dSShiraz Saleem (flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) { 724e3219ce6SAnjali Singhai Jain ctxt.info.valid_sections = 725e3219ce6SAnjali Singhai Jain cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID); 726e3219ce6SAnjali Singhai Jain ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA; 727*7b0b1a6dSShiraz Saleem } else if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) && 728*7b0b1a6dSShiraz Saleem !(flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) { 729e3219ce6SAnjali Singhai Jain ctxt.info.valid_sections = 730e3219ce6SAnjali Singhai Jain cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID); 731e3219ce6SAnjali Singhai Jain ctxt.info.queueing_opt_flags &= ~I40E_AQ_VSI_QUE_OPT_TCP_ENA; 732e3219ce6SAnjali Singhai Jain } else { 733e3219ce6SAnjali Singhai Jain update = false; 734e3219ce6SAnjali Singhai Jain dev_warn(&pf->pdev->dev, 7350ef2d5afSMitch Williams "Client for PF id %d request an unsupported Config: %x.\n", 7360ef2d5afSMitch Williams pf->hw.pf_id, flag); 737e3219ce6SAnjali Singhai Jain } 738e3219ce6SAnjali Singhai Jain 739e3219ce6SAnjali Singhai Jain if (update) { 740e3219ce6SAnjali Singhai Jain err = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); 741e3219ce6SAnjali Singhai Jain if (err) { 742e3219ce6SAnjali Singhai Jain dev_info(&pf->pdev->dev, 743e3219ce6SAnjali Singhai Jain "update VSI ctxt for PE failed, err %s aq_err %s\n", 744e3219ce6SAnjali Singhai Jain i40e_stat_str(&pf->hw, err), 745e3219ce6SAnjali Singhai Jain i40e_aq_str(&pf->hw, 746e3219ce6SAnjali Singhai Jain pf->hw.aq.asq_last_status)); 747e3219ce6SAnjali Singhai Jain } 748e3219ce6SAnjali Singhai Jain } 749e3219ce6SAnjali Singhai Jain return err; 750e3219ce6SAnjali Singhai Jain } 751e3219ce6SAnjali Singhai Jain 752e3219ce6SAnjali Singhai Jain /** 753e3219ce6SAnjali Singhai Jain * i40e_register_client - Register a i40e client driver with the L2 driver 754e3219ce6SAnjali Singhai Jain * @client: pointer to the i40e_client struct 755e3219ce6SAnjali Singhai Jain * 756e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 757e3219ce6SAnjali Singhai Jain **/ 758e3219ce6SAnjali Singhai Jain int i40e_register_client(struct i40e_client *client) 759e3219ce6SAnjali Singhai Jain { 760e3219ce6SAnjali Singhai Jain int ret = 0; 761e3219ce6SAnjali Singhai Jain 762e3219ce6SAnjali Singhai Jain if (!client) { 763e3219ce6SAnjali Singhai Jain ret = -EIO; 764e3219ce6SAnjali Singhai Jain goto out; 765e3219ce6SAnjali Singhai Jain } 766e3219ce6SAnjali Singhai Jain 767e3219ce6SAnjali Singhai Jain if (strlen(client->name) == 0) { 768e3219ce6SAnjali Singhai Jain pr_info("i40e: Failed to register client with no name\n"); 769e3219ce6SAnjali Singhai Jain ret = -EIO; 770e3219ce6SAnjali Singhai Jain goto out; 771e3219ce6SAnjali Singhai Jain } 772e3219ce6SAnjali Singhai Jain 7730ef2d5afSMitch Williams if (registered_client) { 774e3219ce6SAnjali Singhai Jain pr_info("i40e: Client %s has already been registered!\n", 775e3219ce6SAnjali Singhai Jain client->name); 776e3219ce6SAnjali Singhai Jain ret = -EEXIST; 777e3219ce6SAnjali Singhai Jain goto out; 778e3219ce6SAnjali Singhai Jain } 779e3219ce6SAnjali Singhai Jain 780e3219ce6SAnjali Singhai Jain if ((client->version.major != I40E_CLIENT_VERSION_MAJOR) || 781e3219ce6SAnjali Singhai Jain (client->version.minor != I40E_CLIENT_VERSION_MINOR)) { 782e3219ce6SAnjali Singhai Jain pr_info("i40e: Failed to register client %s due to mismatched client interface version\n", 783e3219ce6SAnjali Singhai Jain client->name); 784e3219ce6SAnjali Singhai Jain pr_info("Client is using version: %02d.%02d.%02d while LAN driver supports %s\n", 785e3219ce6SAnjali Singhai Jain client->version.major, client->version.minor, 786e3219ce6SAnjali Singhai Jain client->version.build, 787e3219ce6SAnjali Singhai Jain i40e_client_interface_version_str); 788e3219ce6SAnjali Singhai Jain ret = -EIO; 789e3219ce6SAnjali Singhai Jain goto out; 790e3219ce6SAnjali Singhai Jain } 791e3219ce6SAnjali Singhai Jain 7920ef2d5afSMitch Williams registered_client = client; 793e3219ce6SAnjali Singhai Jain 7943bb83bafSMitch Williams i40e_client_prepare(client); 795e3219ce6SAnjali Singhai Jain 7963bb83bafSMitch Williams pr_info("i40e: Registered client %s\n", client->name); 797e3219ce6SAnjali Singhai Jain out: 798e3219ce6SAnjali Singhai Jain return ret; 799e3219ce6SAnjali Singhai Jain } 800e3219ce6SAnjali Singhai Jain EXPORT_SYMBOL(i40e_register_client); 801e3219ce6SAnjali Singhai Jain 802e3219ce6SAnjali Singhai Jain /** 803e3219ce6SAnjali Singhai Jain * i40e_unregister_client - Unregister a i40e client driver with the L2 driver 804e3219ce6SAnjali Singhai Jain * @client: pointer to the i40e_client struct 805e3219ce6SAnjali Singhai Jain * 806e3219ce6SAnjali Singhai Jain * Returns 0 on success or non-0 on error 807e3219ce6SAnjali Singhai Jain **/ 808e3219ce6SAnjali Singhai Jain int i40e_unregister_client(struct i40e_client *client) 809e3219ce6SAnjali Singhai Jain { 810e3219ce6SAnjali Singhai Jain int ret = 0; 811e3219ce6SAnjali Singhai Jain 8120ef2d5afSMitch Williams if (registered_client != client) { 813e3219ce6SAnjali Singhai Jain pr_info("i40e: Client %s has not been registered\n", 814e3219ce6SAnjali Singhai Jain client->name); 815e3219ce6SAnjali Singhai Jain ret = -ENODEV; 816e3219ce6SAnjali Singhai Jain goto out; 817e3219ce6SAnjali Singhai Jain } 8180ef2d5afSMitch Williams registered_client = NULL; 8190ef2d5afSMitch Williams /* When a unregister request comes through we would have to send 8200ef2d5afSMitch Williams * a close for each of the client instances that were opened. 8210ef2d5afSMitch Williams * client_release function is called to handle this. 8220ef2d5afSMitch Williams */ 8230ef2d5afSMitch Williams i40e_client_release(client); 8240ef2d5afSMitch Williams 8250ef2d5afSMitch Williams pr_info("i40e: Unregistered client %s\n", client->name); 826e3219ce6SAnjali Singhai Jain out: 827e3219ce6SAnjali Singhai Jain return ret; 828e3219ce6SAnjali Singhai Jain } 829e3219ce6SAnjali Singhai Jain EXPORT_SYMBOL(i40e_unregister_client); 830