Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 2013 - 2018 Intel Corporation. */
0003 
0004 #include <linux/list.h>
0005 #include <linux/errno.h>
0006 #include <linux/net/intel/i40e_client.h>
0007 
0008 #include "i40e.h"
0009 #include "i40e_prototype.h"
0010 
0011 static LIST_HEAD(i40e_devices);
0012 static DEFINE_MUTEX(i40e_device_mutex);
0013 DEFINE_IDA(i40e_client_ida);
0014 
0015 static int i40e_client_virtchnl_send(struct i40e_info *ldev,
0016                      struct i40e_client *client,
0017                      u32 vf_id, u8 *msg, u16 len);
0018 
0019 static int i40e_client_setup_qvlist(struct i40e_info *ldev,
0020                     struct i40e_client *client,
0021                     struct i40e_qvlist_info *qvlist_info);
0022 
0023 static void i40e_client_request_reset(struct i40e_info *ldev,
0024                       struct i40e_client *client,
0025                       u32 reset_level);
0026 
0027 static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev,
0028                        struct i40e_client *client,
0029                        bool is_vf, u32 vf_id,
0030                        u32 flag, u32 valid_flag);
0031 
0032 static struct i40e_ops i40e_lan_ops = {
0033     .virtchnl_send = i40e_client_virtchnl_send,
0034     .setup_qvlist = i40e_client_setup_qvlist,
0035     .request_reset = i40e_client_request_reset,
0036     .update_vsi_ctxt = i40e_client_update_vsi_ctxt,
0037 };
0038 
0039 /**
0040  * i40e_client_get_params - Get the params that can change at runtime
0041  * @vsi: the VSI with the message
0042  * @params: client param struct
0043  *
0044  **/
0045 static
0046 int i40e_client_get_params(struct i40e_vsi *vsi, struct i40e_params *params)
0047 {
0048     struct i40e_dcbx_config *dcb_cfg = &vsi->back->hw.local_dcbx_config;
0049     int i = 0;
0050 
0051     for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
0052         u8 tc = dcb_cfg->etscfg.prioritytable[i];
0053         u16 qs_handle;
0054 
0055         /* If TC is not enabled for VSI use TC0 for UP */
0056         if (!(vsi->tc_config.enabled_tc & BIT(tc)))
0057             tc = 0;
0058 
0059         qs_handle = le16_to_cpu(vsi->info.qs_handle[tc]);
0060         params->qos.prio_qos[i].tc = tc;
0061         params->qos.prio_qos[i].qs_handle = qs_handle;
0062         if (qs_handle == I40E_AQ_VSI_QS_HANDLE_INVALID) {
0063             dev_err(&vsi->back->pdev->dev, "Invalid queue set handle for TC = %d, vsi id = %d\n",
0064                 tc, vsi->id);
0065             return -EINVAL;
0066         }
0067     }
0068 
0069     params->mtu = vsi->netdev->mtu;
0070     return 0;
0071 }
0072 
0073 /**
0074  * i40e_notify_client_of_vf_msg - call the client vf message callback
0075  * @vsi: the VSI with the message
0076  * @vf_id: the absolute VF id that sent the message
0077  * @msg: message buffer
0078  * @len: length of the message
0079  *
0080  * If there is a client to this VSI, call the client
0081  **/
0082 void
0083 i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id, u8 *msg, u16 len)
0084 {
0085     struct i40e_pf *pf = vsi->back;
0086     struct i40e_client_instance *cdev = pf->cinst;
0087 
0088     if (!cdev || !cdev->client)
0089         return;
0090     if (!cdev->client->ops || !cdev->client->ops->virtchnl_receive) {
0091         dev_dbg(&pf->pdev->dev,
0092             "Cannot locate client instance virtual channel receive routine\n");
0093         return;
0094     }
0095     if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
0096         dev_dbg(&pf->pdev->dev, "Client is not open, abort virtchnl_receive\n");
0097         return;
0098     }
0099     cdev->client->ops->virtchnl_receive(&cdev->lan_info, cdev->client,
0100                         vf_id, msg, len);
0101 }
0102 
0103 /**
0104  * i40e_notify_client_of_l2_param_changes - call the client notify callback
0105  * @vsi: the VSI with l2 param changes
0106  *
0107  * If there is a client to this VSI, call the client
0108  **/
0109 void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi)
0110 {
0111     struct i40e_pf *pf = vsi->back;
0112     struct i40e_client_instance *cdev = pf->cinst;
0113     struct i40e_params params;
0114 
0115     if (!cdev || !cdev->client)
0116         return;
0117     if (!cdev->client->ops || !cdev->client->ops->l2_param_change) {
0118         dev_dbg(&vsi->back->pdev->dev,
0119             "Cannot locate client instance l2_param_change routine\n");
0120         return;
0121     }
0122     if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
0123         dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort l2 param change\n");
0124         return;
0125     }
0126     memset(&params, 0, sizeof(params));
0127     i40e_client_get_params(vsi, &params);
0128     memcpy(&cdev->lan_info.params, &params, sizeof(struct i40e_params));
0129     cdev->client->ops->l2_param_change(&cdev->lan_info, cdev->client,
0130                        &params);
0131 }
0132 
0133 /**
0134  * i40e_client_release_qvlist - release MSI-X vector mapping for client
0135  * @ldev: pointer to L2 context.
0136  *
0137  **/
0138 static void i40e_client_release_qvlist(struct i40e_info *ldev)
0139 {
0140     struct i40e_qvlist_info *qvlist_info = ldev->qvlist_info;
0141     u32 i;
0142 
0143     if (!ldev->qvlist_info)
0144         return;
0145 
0146     for (i = 0; i < qvlist_info->num_vectors; i++) {
0147         struct i40e_pf *pf = ldev->pf;
0148         struct i40e_qv_info *qv_info;
0149         u32 reg_idx;
0150 
0151         qv_info = &qvlist_info->qv_info[i];
0152         if (!qv_info)
0153             continue;
0154         reg_idx = I40E_PFINT_LNKLSTN(qv_info->v_idx - 1);
0155         wr32(&pf->hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK);
0156     }
0157     kfree(ldev->qvlist_info);
0158     ldev->qvlist_info = NULL;
0159 }
0160 
0161 /**
0162  * i40e_notify_client_of_netdev_close - call the client close callback
0163  * @vsi: the VSI with netdev closed
0164  * @reset: true when close called due to a reset pending
0165  *
0166  * If there is a client to this netdev, call the client with close
0167  **/
0168 void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset)
0169 {
0170     struct i40e_pf *pf = vsi->back;
0171     struct i40e_client_instance *cdev = pf->cinst;
0172 
0173     if (!cdev || !cdev->client)
0174         return;
0175     if (!cdev->client->ops || !cdev->client->ops->close) {
0176         dev_dbg(&vsi->back->pdev->dev,
0177             "Cannot locate client instance close routine\n");
0178         return;
0179     }
0180     if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
0181         dev_dbg(&pf->pdev->dev, "Client is not open, abort close\n");
0182         return;
0183     }
0184     cdev->client->ops->close(&cdev->lan_info, cdev->client, reset);
0185     clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
0186     i40e_client_release_qvlist(&cdev->lan_info);
0187 }
0188 
0189 /**
0190  * i40e_notify_client_of_vf_reset - call the client vf reset callback
0191  * @pf: PF device pointer
0192  * @vf_id: asolute id of VF being reset
0193  *
0194  * If there is a client attached to this PF, notify when a VF is reset
0195  **/
0196 void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id)
0197 {
0198     struct i40e_client_instance *cdev = pf->cinst;
0199 
0200     if (!cdev || !cdev->client)
0201         return;
0202     if (!cdev->client->ops || !cdev->client->ops->vf_reset) {
0203         dev_dbg(&pf->pdev->dev,
0204             "Cannot locate client instance VF reset routine\n");
0205         return;
0206     }
0207     if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,  &cdev->state)) {
0208         dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-reset\n");
0209         return;
0210     }
0211     cdev->client->ops->vf_reset(&cdev->lan_info, cdev->client, vf_id);
0212 }
0213 
0214 /**
0215  * i40e_notify_client_of_vf_enable - call the client vf notification callback
0216  * @pf: PF device pointer
0217  * @num_vfs: the number of VFs currently enabled, 0 for disable
0218  *
0219  * If there is a client attached to this PF, call its VF notification routine
0220  **/
0221 void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs)
0222 {
0223     struct i40e_client_instance *cdev = pf->cinst;
0224 
0225     if (!cdev || !cdev->client)
0226         return;
0227     if (!cdev->client->ops || !cdev->client->ops->vf_enable) {
0228         dev_dbg(&pf->pdev->dev,
0229             "Cannot locate client instance VF enable routine\n");
0230         return;
0231     }
0232     if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
0233               &cdev->state)) {
0234         dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-enable\n");
0235         return;
0236     }
0237     cdev->client->ops->vf_enable(&cdev->lan_info, cdev->client, num_vfs);
0238 }
0239 
0240 /**
0241  * i40e_vf_client_capable - ask the client if it likes the specified VF
0242  * @pf: PF device pointer
0243  * @vf_id: the VF in question
0244  *
0245  * If there is a client of the specified type attached to this PF, call
0246  * its vf_capable routine
0247  **/
0248 int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id)
0249 {
0250     struct i40e_client_instance *cdev = pf->cinst;
0251     int capable = false;
0252 
0253     if (!cdev || !cdev->client)
0254         goto out;
0255     if (!cdev->client->ops || !cdev->client->ops->vf_capable) {
0256         dev_dbg(&pf->pdev->dev,
0257             "Cannot locate client instance VF capability routine\n");
0258         goto out;
0259     }
0260     if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state))
0261         goto out;
0262 
0263     capable = cdev->client->ops->vf_capable(&cdev->lan_info,
0264                         cdev->client,
0265                         vf_id);
0266 out:
0267     return capable;
0268 }
0269 
0270 void i40e_client_update_msix_info(struct i40e_pf *pf)
0271 {
0272     struct i40e_client_instance *cdev = pf->cinst;
0273 
0274     if (!cdev || !cdev->client)
0275         return;
0276 
0277     cdev->lan_info.msix_count = pf->num_iwarp_msix;
0278     cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
0279 }
0280 
0281 static void i40e_auxiliary_dev_release(struct device *dev)
0282 {
0283     struct i40e_auxiliary_device *i40e_aux_dev =
0284             container_of(dev, struct i40e_auxiliary_device, aux_dev.dev);
0285 
0286     ida_free(&i40e_client_ida, i40e_aux_dev->aux_dev.id);
0287     kfree(i40e_aux_dev);
0288 }
0289 
0290 static int i40e_register_auxiliary_dev(struct i40e_info *ldev, const char *name)
0291 {
0292     struct i40e_auxiliary_device *i40e_aux_dev;
0293     struct pci_dev *pdev = ldev->pcidev;
0294     struct auxiliary_device *aux_dev;
0295     int ret;
0296 
0297     i40e_aux_dev = kzalloc(sizeof(*i40e_aux_dev), GFP_KERNEL);
0298     if (!i40e_aux_dev)
0299         return -ENOMEM;
0300 
0301     i40e_aux_dev->ldev = ldev;
0302 
0303     aux_dev = &i40e_aux_dev->aux_dev;
0304     aux_dev->name = name;
0305     aux_dev->dev.parent = &pdev->dev;
0306     aux_dev->dev.release = i40e_auxiliary_dev_release;
0307     ldev->aux_dev = aux_dev;
0308 
0309     ret = ida_alloc(&i40e_client_ida, GFP_KERNEL);
0310     if (ret < 0) {
0311         kfree(i40e_aux_dev);
0312         return ret;
0313     }
0314     aux_dev->id = ret;
0315 
0316     ret = auxiliary_device_init(aux_dev);
0317     if (ret < 0) {
0318         ida_free(&i40e_client_ida, aux_dev->id);
0319         kfree(i40e_aux_dev);
0320         return ret;
0321     }
0322 
0323     ret = auxiliary_device_add(aux_dev);
0324     if (ret) {
0325         auxiliary_device_uninit(aux_dev);
0326         return ret;
0327     }
0328 
0329     return ret;
0330 }
0331 
0332 /**
0333  * i40e_client_add_instance - add a client instance struct to the instance list
0334  * @pf: pointer to the board struct
0335  *
0336  **/
0337 static void i40e_client_add_instance(struct i40e_pf *pf)
0338 {
0339     struct i40e_client_instance *cdev = NULL;
0340     struct netdev_hw_addr *mac = NULL;
0341     struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
0342 
0343     cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
0344     if (!cdev)
0345         return;
0346 
0347     cdev->lan_info.pf = (void *)pf;
0348     cdev->lan_info.netdev = vsi->netdev;
0349     cdev->lan_info.pcidev = pf->pdev;
0350     cdev->lan_info.fid = pf->hw.pf_id;
0351     cdev->lan_info.ftype = I40E_CLIENT_FTYPE_PF;
0352     cdev->lan_info.hw_addr = pf->hw.hw_addr;
0353     cdev->lan_info.ops = &i40e_lan_ops;
0354     cdev->lan_info.version.major = I40E_CLIENT_VERSION_MAJOR;
0355     cdev->lan_info.version.minor = I40E_CLIENT_VERSION_MINOR;
0356     cdev->lan_info.version.build = I40E_CLIENT_VERSION_BUILD;
0357     cdev->lan_info.fw_maj_ver = pf->hw.aq.fw_maj_ver;
0358     cdev->lan_info.fw_min_ver = pf->hw.aq.fw_min_ver;
0359     cdev->lan_info.fw_build = pf->hw.aq.fw_build;
0360     set_bit(__I40E_CLIENT_INSTANCE_NONE, &cdev->state);
0361 
0362     if (i40e_client_get_params(vsi, &cdev->lan_info.params))
0363         goto free_cdev;
0364 
0365     mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list,
0366                    struct netdev_hw_addr, list);
0367     if (mac)
0368         ether_addr_copy(cdev->lan_info.lanmac, mac->addr);
0369     else
0370         dev_err(&pf->pdev->dev, "MAC address list is empty!\n");
0371 
0372     pf->cinst = cdev;
0373 
0374     cdev->lan_info.msix_count = pf->num_iwarp_msix;
0375     cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
0376 
0377     if (i40e_register_auxiliary_dev(&cdev->lan_info, "iwarp"))
0378         goto free_cdev;
0379 
0380     return;
0381 
0382 free_cdev:
0383     kfree(cdev);
0384     pf->cinst = NULL;
0385 }
0386 
0387 /**
0388  * i40e_client_del_instance - removes a client instance from the list
0389  * @pf: pointer to the board struct
0390  *
0391  **/
0392 static
0393 void i40e_client_del_instance(struct i40e_pf *pf)
0394 {
0395     kfree(pf->cinst);
0396     pf->cinst = NULL;
0397 }
0398 
0399 /**
0400  * i40e_client_subtask - client maintenance work
0401  * @pf: board private structure
0402  **/
0403 void i40e_client_subtask(struct i40e_pf *pf)
0404 {
0405     struct i40e_client *client;
0406     struct i40e_client_instance *cdev;
0407     struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
0408     int ret = 0;
0409 
0410     if (!test_and_clear_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state))
0411         return;
0412     cdev = pf->cinst;
0413 
0414     /* If we're down or resetting, just bail */
0415     if (test_bit(__I40E_DOWN, pf->state) ||
0416         test_bit(__I40E_CONFIG_BUSY, pf->state))
0417         return;
0418 
0419     if (!cdev || !cdev->client)
0420         return;
0421 
0422     client = cdev->client;
0423 
0424     /* Here we handle client opens. If the client is down, and
0425      * the netdev is registered, then open the client.
0426      */
0427     if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
0428         if (vsi->netdev_registered &&
0429             client->ops && client->ops->open) {
0430             set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
0431             ret = client->ops->open(&cdev->lan_info, client);
0432             if (ret) {
0433                 /* Remove failed client instance */
0434                 clear_bit(__I40E_CLIENT_INSTANCE_OPENED,
0435                       &cdev->state);
0436                 return;
0437             }
0438         }
0439     }
0440 
0441     /* enable/disable PE TCP_ENA flag based on netdev down/up
0442      */
0443     if (test_bit(__I40E_VSI_DOWN, vsi->state))
0444         i40e_client_update_vsi_ctxt(&cdev->lan_info, client,
0445                         0, 0, 0,
0446                         I40E_CLIENT_VSI_FLAG_TCP_ENABLE);
0447     else
0448         i40e_client_update_vsi_ctxt(&cdev->lan_info, client,
0449                         0, 0,
0450                         I40E_CLIENT_VSI_FLAG_TCP_ENABLE,
0451                         I40E_CLIENT_VSI_FLAG_TCP_ENABLE);
0452 }
0453 
0454 /**
0455  * i40e_lan_add_device - add a lan device struct to the list of lan devices
0456  * @pf: pointer to the board struct
0457  *
0458  * Returns 0 on success or none 0 on error
0459  **/
0460 int i40e_lan_add_device(struct i40e_pf *pf)
0461 {
0462     struct i40e_device *ldev;
0463     int ret = 0;
0464 
0465     mutex_lock(&i40e_device_mutex);
0466     list_for_each_entry(ldev, &i40e_devices, list) {
0467         if (ldev->pf == pf) {
0468             ret = -EEXIST;
0469             goto out;
0470         }
0471     }
0472     ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
0473     if (!ldev) {
0474         ret = -ENOMEM;
0475         goto out;
0476     }
0477     ldev->pf = pf;
0478     INIT_LIST_HEAD(&ldev->list);
0479     list_add(&ldev->list, &i40e_devices);
0480     dev_info(&pf->pdev->dev, "Added LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n",
0481          pf->hw.pf_id, pf->hw.bus.bus_id,
0482          pf->hw.bus.device, pf->hw.bus.func);
0483 
0484     i40e_client_add_instance(pf);
0485 
0486     set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state);
0487     i40e_service_event_schedule(pf);
0488 
0489 out:
0490     mutex_unlock(&i40e_device_mutex);
0491     return ret;
0492 }
0493 
0494 /**
0495  * i40e_lan_del_device - removes a lan device from the device list
0496  * @pf: pointer to the board struct
0497  *
0498  * Returns 0 on success or non-0 on error
0499  **/
0500 int i40e_lan_del_device(struct i40e_pf *pf)
0501 {
0502     struct auxiliary_device *aux_dev = pf->cinst->lan_info.aux_dev;
0503     struct i40e_device *ldev, *tmp;
0504     int ret = -ENODEV;
0505 
0506     auxiliary_device_delete(aux_dev);
0507     auxiliary_device_uninit(aux_dev);
0508 
0509     /* First, remove any client instance. */
0510     i40e_client_del_instance(pf);
0511 
0512     mutex_lock(&i40e_device_mutex);
0513     list_for_each_entry_safe(ldev, tmp, &i40e_devices, list) {
0514         if (ldev->pf == pf) {
0515             dev_info(&pf->pdev->dev, "Deleted LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n",
0516                  pf->hw.pf_id, pf->hw.bus.bus_id,
0517                  pf->hw.bus.device, pf->hw.bus.func);
0518             list_del(&ldev->list);
0519             kfree(ldev);
0520             ret = 0;
0521             break;
0522         }
0523     }
0524     mutex_unlock(&i40e_device_mutex);
0525     return ret;
0526 }
0527 
0528 /**
0529  * i40e_client_virtchnl_send - TBD
0530  * @ldev: pointer to L2 context
0531  * @client: Client pointer
0532  * @vf_id: absolute VF identifier
0533  * @msg: message buffer
0534  * @len: length of message buffer
0535  *
0536  * Return 0 on success or < 0 on error
0537  **/
0538 static int i40e_client_virtchnl_send(struct i40e_info *ldev,
0539                      struct i40e_client *client,
0540                      u32 vf_id, u8 *msg, u16 len)
0541 {
0542     struct i40e_pf *pf = ldev->pf;
0543     struct i40e_hw *hw = &pf->hw;
0544     i40e_status err;
0545 
0546     err = i40e_aq_send_msg_to_vf(hw, vf_id, VIRTCHNL_OP_IWARP,
0547                      0, msg, len, NULL);
0548     if (err)
0549         dev_err(&pf->pdev->dev, "Unable to send iWarp message to VF, error %d, aq status %d\n",
0550             err, hw->aq.asq_last_status);
0551 
0552     return err;
0553 }
0554 
0555 /**
0556  * i40e_client_setup_qvlist
0557  * @ldev: pointer to L2 context.
0558  * @client: Client pointer.
0559  * @qvlist_info: queue and vector list
0560  *
0561  * Return 0 on success or < 0 on error
0562  **/
0563 static int i40e_client_setup_qvlist(struct i40e_info *ldev,
0564                     struct i40e_client *client,
0565                     struct i40e_qvlist_info *qvlist_info)
0566 {
0567     struct i40e_pf *pf = ldev->pf;
0568     struct i40e_hw *hw = &pf->hw;
0569     struct i40e_qv_info *qv_info;
0570     u32 v_idx, i, reg_idx, reg;
0571 
0572     ldev->qvlist_info = kzalloc(struct_size(ldev->qvlist_info, qv_info,
0573                     qvlist_info->num_vectors), GFP_KERNEL);
0574     if (!ldev->qvlist_info)
0575         return -ENOMEM;
0576     ldev->qvlist_info->num_vectors = qvlist_info->num_vectors;
0577 
0578     for (i = 0; i < qvlist_info->num_vectors; i++) {
0579         qv_info = &qvlist_info->qv_info[i];
0580         if (!qv_info)
0581             continue;
0582         v_idx = qv_info->v_idx;
0583 
0584         /* Validate vector id belongs to this client */
0585         if ((v_idx >= (pf->iwarp_base_vector + pf->num_iwarp_msix)) ||
0586             (v_idx < pf->iwarp_base_vector))
0587             goto err;
0588 
0589         ldev->qvlist_info->qv_info[i] = *qv_info;
0590         reg_idx = I40E_PFINT_LNKLSTN(v_idx - 1);
0591 
0592         if (qv_info->ceq_idx == I40E_QUEUE_INVALID_IDX) {
0593             /* Special case - No CEQ mapped on this vector */
0594             wr32(hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK);
0595         } else {
0596             reg = (qv_info->ceq_idx &
0597                    I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK) |
0598                    (I40E_QUEUE_TYPE_PE_CEQ <<
0599                    I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT);
0600             wr32(hw, reg_idx, reg);
0601 
0602             reg = (I40E_PFINT_CEQCTL_CAUSE_ENA_MASK |
0603                    (v_idx << I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT) |
0604                    (qv_info->itr_idx <<
0605                 I40E_PFINT_CEQCTL_ITR_INDX_SHIFT) |
0606                    (I40E_QUEUE_END_OF_LIST <<
0607                 I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT));
0608             wr32(hw, I40E_PFINT_CEQCTL(qv_info->ceq_idx), reg);
0609         }
0610         if (qv_info->aeq_idx != I40E_QUEUE_INVALID_IDX) {
0611             reg = (I40E_PFINT_AEQCTL_CAUSE_ENA_MASK |
0612                    (v_idx << I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT) |
0613                    (qv_info->itr_idx <<
0614                 I40E_PFINT_AEQCTL_ITR_INDX_SHIFT));
0615 
0616             wr32(hw, I40E_PFINT_AEQCTL, reg);
0617         }
0618     }
0619     /* Mitigate sync problems with iwarp VF driver */
0620     i40e_flush(hw);
0621     return 0;
0622 err:
0623     kfree(ldev->qvlist_info);
0624     ldev->qvlist_info = NULL;
0625     return -EINVAL;
0626 }
0627 
0628 /**
0629  * i40e_client_request_reset
0630  * @ldev: pointer to L2 context.
0631  * @client: Client pointer.
0632  * @reset_level: reset level
0633  **/
0634 static void i40e_client_request_reset(struct i40e_info *ldev,
0635                       struct i40e_client *client,
0636                       u32 reset_level)
0637 {
0638     struct i40e_pf *pf = ldev->pf;
0639 
0640     switch (reset_level) {
0641     case I40E_CLIENT_RESET_LEVEL_PF:
0642         set_bit(__I40E_PF_RESET_REQUESTED, pf->state);
0643         break;
0644     case I40E_CLIENT_RESET_LEVEL_CORE:
0645         set_bit(__I40E_PF_RESET_REQUESTED, pf->state);
0646         break;
0647     default:
0648         dev_warn(&pf->pdev->dev,
0649              "Client for PF id %d requested an unsupported reset: %d.\n",
0650              pf->hw.pf_id, reset_level);
0651         break;
0652     }
0653 
0654     i40e_service_event_schedule(pf);
0655 }
0656 
0657 /**
0658  * i40e_client_update_vsi_ctxt
0659  * @ldev: pointer to L2 context.
0660  * @client: Client pointer.
0661  * @is_vf: if this for the VF
0662  * @vf_id: if is_vf true this carries the vf_id
0663  * @flag: Any device level setting that needs to be done for PE
0664  * @valid_flag: Bits in this match up and enable changing of flag bits
0665  *
0666  * Return 0 on success or < 0 on error
0667  **/
0668 static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev,
0669                        struct i40e_client *client,
0670                        bool is_vf, u32 vf_id,
0671                        u32 flag, u32 valid_flag)
0672 {
0673     struct i40e_pf *pf = ldev->pf;
0674     struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
0675     struct i40e_vsi_context ctxt;
0676     bool update = true;
0677     i40e_status err;
0678 
0679     /* TODO: for now do not allow setting VF's VSI setting */
0680     if (is_vf)
0681         return -EINVAL;
0682 
0683     ctxt.seid = pf->main_vsi_seid;
0684     ctxt.pf_num = pf->hw.pf_id;
0685     err = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
0686     ctxt.flags = I40E_AQ_VSI_TYPE_PF;
0687     if (err) {
0688         dev_info(&pf->pdev->dev,
0689              "couldn't get PF vsi config, err %s aq_err %s\n",
0690              i40e_stat_str(&pf->hw, err),
0691              i40e_aq_str(&pf->hw,
0692                      pf->hw.aq.asq_last_status));
0693         return -ENOENT;
0694     }
0695 
0696     if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) &&
0697         (flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) {
0698         ctxt.info.valid_sections =
0699             cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
0700         ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA;
0701     } else if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) &&
0702           !(flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) {
0703         ctxt.info.valid_sections =
0704             cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
0705         ctxt.info.queueing_opt_flags &= ~I40E_AQ_VSI_QUE_OPT_TCP_ENA;
0706     } else {
0707         update = false;
0708         dev_warn(&pf->pdev->dev,
0709              "Client for PF id %d request an unsupported Config: %x.\n",
0710              pf->hw.pf_id, flag);
0711     }
0712 
0713     if (update) {
0714         err = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
0715         if (err) {
0716             dev_info(&pf->pdev->dev,
0717                  "update VSI ctxt for PE failed, err %s aq_err %s\n",
0718                  i40e_stat_str(&pf->hw, err),
0719                  i40e_aq_str(&pf->hw,
0720                          pf->hw.aq.asq_last_status));
0721         }
0722     }
0723     return err;
0724 }
0725 
0726 void i40e_client_device_register(struct i40e_info *ldev, struct i40e_client *client)
0727 {
0728     struct i40e_pf *pf = ldev->pf;
0729 
0730     pf->cinst->client = client;
0731     set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state);
0732     i40e_service_event_schedule(pf);
0733 }
0734 EXPORT_SYMBOL_GPL(i40e_client_device_register);
0735 
0736 void i40e_client_device_unregister(struct i40e_info *ldev)
0737 {
0738     struct i40e_pf *pf = ldev->pf;
0739     struct i40e_client_instance *cdev = pf->cinst;
0740 
0741     if (!cdev)
0742         return;
0743 
0744     while (test_and_set_bit(__I40E_SERVICE_SCHED, pf->state))
0745         usleep_range(500, 1000);
0746 
0747     if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
0748         cdev->client->ops->close(&cdev->lan_info, cdev->client, false);
0749         clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
0750         i40e_client_release_qvlist(&cdev->lan_info);
0751     }
0752 
0753     pf->cinst->client = NULL;
0754     clear_bit(__I40E_SERVICE_SCHED, pf->state);
0755 }
0756 EXPORT_SYMBOL_GPL(i40e_client_device_unregister);