linux/drivers/net/ethernet/intel/i40e/i40e_client.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2013 - 2018 Intel Corporation. */
   3
   4#include <linux/list.h>
   5#include <linux/errno.h>
   6#include <linux/net/intel/i40e_client.h>
   7
   8#include "i40e.h"
   9#include "i40e_prototype.h"
  10
  11static LIST_HEAD(i40e_devices);
  12static DEFINE_MUTEX(i40e_device_mutex);
  13DEFINE_IDA(i40e_client_ida);
  14
  15static int i40e_client_virtchnl_send(struct i40e_info *ldev,
  16                                     struct i40e_client *client,
  17                                     u32 vf_id, u8 *msg, u16 len);
  18
  19static int i40e_client_setup_qvlist(struct i40e_info *ldev,
  20                                    struct i40e_client *client,
  21                                    struct i40e_qvlist_info *qvlist_info);
  22
  23static void i40e_client_request_reset(struct i40e_info *ldev,
  24                                      struct i40e_client *client,
  25                                      u32 reset_level);
  26
  27static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev,
  28                                       struct i40e_client *client,
  29                                       bool is_vf, u32 vf_id,
  30                                       u32 flag, u32 valid_flag);
  31
  32static struct i40e_ops i40e_lan_ops = {
  33        .virtchnl_send = i40e_client_virtchnl_send,
  34        .setup_qvlist = i40e_client_setup_qvlist,
  35        .request_reset = i40e_client_request_reset,
  36        .update_vsi_ctxt = i40e_client_update_vsi_ctxt,
  37};
  38
  39/**
  40 * i40e_client_get_params - Get the params that can change at runtime
  41 * @vsi: the VSI with the message
  42 * @params: client param struct
  43 *
  44 **/
  45static
  46int i40e_client_get_params(struct i40e_vsi *vsi, struct i40e_params *params)
  47{
  48        struct i40e_dcbx_config *dcb_cfg = &vsi->back->hw.local_dcbx_config;
  49        int i = 0;
  50
  51        for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
  52                u8 tc = dcb_cfg->etscfg.prioritytable[i];
  53                u16 qs_handle;
  54
  55                /* If TC is not enabled for VSI use TC0 for UP */
  56                if (!(vsi->tc_config.enabled_tc & BIT(tc)))
  57                        tc = 0;
  58
  59                qs_handle = le16_to_cpu(vsi->info.qs_handle[tc]);
  60                params->qos.prio_qos[i].tc = tc;
  61                params->qos.prio_qos[i].qs_handle = qs_handle;
  62                if (qs_handle == I40E_AQ_VSI_QS_HANDLE_INVALID) {
  63                        dev_err(&vsi->back->pdev->dev, "Invalid queue set handle for TC = %d, vsi id = %d\n",
  64                                tc, vsi->id);
  65                        return -EINVAL;
  66                }
  67        }
  68
  69        params->mtu = vsi->netdev->mtu;
  70        return 0;
  71}
  72
  73/**
  74 * i40e_notify_client_of_vf_msg - call the client vf message callback
  75 * @vsi: the VSI with the message
  76 * @vf_id: the absolute VF id that sent the message
  77 * @msg: message buffer
  78 * @len: length of the message
  79 *
  80 * If there is a client to this VSI, call the client
  81 **/
  82void
  83i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id, u8 *msg, u16 len)
  84{
  85        struct i40e_pf *pf = vsi->back;
  86        struct i40e_client_instance *cdev = pf->cinst;
  87
  88        if (!cdev || !cdev->client)
  89                return;
  90        if (!cdev->client->ops || !cdev->client->ops->virtchnl_receive) {
  91                dev_dbg(&pf->pdev->dev,
  92                        "Cannot locate client instance virtual channel receive routine\n");
  93                return;
  94        }
  95        if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
  96                dev_dbg(&pf->pdev->dev, "Client is not open, abort virtchnl_receive\n");
  97                return;
  98        }
  99        cdev->client->ops->virtchnl_receive(&cdev->lan_info, cdev->client,
 100                                            vf_id, msg, len);
 101}
 102
 103/**
 104 * i40e_notify_client_of_l2_param_changes - call the client notify callback
 105 * @vsi: the VSI with l2 param changes
 106 *
 107 * If there is a client to this VSI, call the client
 108 **/
 109void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi)
 110{
 111        struct i40e_pf *pf = vsi->back;
 112        struct i40e_client_instance *cdev = pf->cinst;
 113        struct i40e_params params;
 114
 115        if (!cdev || !cdev->client)
 116                return;
 117        if (!cdev->client->ops || !cdev->client->ops->l2_param_change) {
 118                dev_dbg(&vsi->back->pdev->dev,
 119                        "Cannot locate client instance l2_param_change routine\n");
 120                return;
 121        }
 122        if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
 123                dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort l2 param change\n");
 124                return;
 125        }
 126        memset(&params, 0, sizeof(params));
 127        i40e_client_get_params(vsi, &params);
 128        memcpy(&cdev->lan_info.params, &params, sizeof(struct i40e_params));
 129        cdev->client->ops->l2_param_change(&cdev->lan_info, cdev->client,
 130                                           &params);
 131}
 132
 133/**
 134 * i40e_client_release_qvlist - release MSI-X vector mapping for client
 135 * @ldev: pointer to L2 context.
 136 *
 137 **/
 138static void i40e_client_release_qvlist(struct i40e_info *ldev)
 139{
 140        struct i40e_qvlist_info *qvlist_info = ldev->qvlist_info;
 141        u32 i;
 142
 143        if (!ldev->qvlist_info)
 144                return;
 145
 146        for (i = 0; i < qvlist_info->num_vectors; i++) {
 147                struct i40e_pf *pf = ldev->pf;
 148                struct i40e_qv_info *qv_info;
 149                u32 reg_idx;
 150
 151                qv_info = &qvlist_info->qv_info[i];
 152                if (!qv_info)
 153                        continue;
 154                reg_idx = I40E_PFINT_LNKLSTN(qv_info->v_idx - 1);
 155                wr32(&pf->hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK);
 156        }
 157        kfree(ldev->qvlist_info);
 158        ldev->qvlist_info = NULL;
 159}
 160
 161/**
 162 * i40e_notify_client_of_netdev_close - call the client close callback
 163 * @vsi: the VSI with netdev closed
 164 * @reset: true when close called due to a reset pending
 165 *
 166 * If there is a client to this netdev, call the client with close
 167 **/
 168void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset)
 169{
 170        struct i40e_pf *pf = vsi->back;
 171        struct i40e_client_instance *cdev = pf->cinst;
 172
 173        if (!cdev || !cdev->client)
 174                return;
 175        if (!cdev->client->ops || !cdev->client->ops->close) {
 176                dev_dbg(&vsi->back->pdev->dev,
 177                        "Cannot locate client instance close routine\n");
 178                return;
 179        }
 180        cdev->client->ops->close(&cdev->lan_info, cdev->client, reset);
 181        clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
 182        i40e_client_release_qvlist(&cdev->lan_info);
 183}
 184
 185/**
 186 * i40e_notify_client_of_vf_reset - call the client vf reset callback
 187 * @pf: PF device pointer
 188 * @vf_id: asolute id of VF being reset
 189 *
 190 * If there is a client attached to this PF, notify when a VF is reset
 191 **/
 192void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id)
 193{
 194        struct i40e_client_instance *cdev = pf->cinst;
 195
 196        if (!cdev || !cdev->client)
 197                return;
 198        if (!cdev->client->ops || !cdev->client->ops->vf_reset) {
 199                dev_dbg(&pf->pdev->dev,
 200                        "Cannot locate client instance VF reset routine\n");
 201                return;
 202        }
 203        if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,  &cdev->state)) {
 204                dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-reset\n");
 205                return;
 206        }
 207        cdev->client->ops->vf_reset(&cdev->lan_info, cdev->client, vf_id);
 208}
 209
 210/**
 211 * i40e_notify_client_of_vf_enable - call the client vf notification callback
 212 * @pf: PF device pointer
 213 * @num_vfs: the number of VFs currently enabled, 0 for disable
 214 *
 215 * If there is a client attached to this PF, call its VF notification routine
 216 **/
 217void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs)
 218{
 219        struct i40e_client_instance *cdev = pf->cinst;
 220
 221        if (!cdev || !cdev->client)
 222                return;
 223        if (!cdev->client->ops || !cdev->client->ops->vf_enable) {
 224                dev_dbg(&pf->pdev->dev,
 225                        "Cannot locate client instance VF enable routine\n");
 226                return;
 227        }
 228        if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
 229                      &cdev->state)) {
 230                dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-enable\n");
 231                return;
 232        }
 233        cdev->client->ops->vf_enable(&cdev->lan_info, cdev->client, num_vfs);
 234}
 235
 236/**
 237 * i40e_vf_client_capable - ask the client if it likes the specified VF
 238 * @pf: PF device pointer
 239 * @vf_id: the VF in question
 240 *
 241 * If there is a client of the specified type attached to this PF, call
 242 * its vf_capable routine
 243 **/
 244int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id)
 245{
 246        struct i40e_client_instance *cdev = pf->cinst;
 247        int capable = false;
 248
 249        if (!cdev || !cdev->client)
 250                goto out;
 251        if (!cdev->client->ops || !cdev->client->ops->vf_capable) {
 252                dev_dbg(&pf->pdev->dev,
 253                        "Cannot locate client instance VF capability routine\n");
 254                goto out;
 255        }
 256        if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state))
 257                goto out;
 258
 259        capable = cdev->client->ops->vf_capable(&cdev->lan_info,
 260                                                cdev->client,
 261                                                vf_id);
 262out:
 263        return capable;
 264}
 265
 266void i40e_client_update_msix_info(struct i40e_pf *pf)
 267{
 268        struct i40e_client_instance *cdev = pf->cinst;
 269
 270        if (!cdev || !cdev->client)
 271                return;
 272
 273        cdev->lan_info.msix_count = pf->num_iwarp_msix;
 274        cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
 275}
 276
 277static void i40e_auxiliary_dev_release(struct device *dev)
 278{
 279        struct i40e_auxiliary_device *i40e_aux_dev =
 280                        container_of(dev, struct i40e_auxiliary_device, aux_dev.dev);
 281
 282        ida_free(&i40e_client_ida, i40e_aux_dev->aux_dev.id);
 283        kfree(i40e_aux_dev);
 284}
 285
 286static int i40e_register_auxiliary_dev(struct i40e_info *ldev, const char *name)
 287{
 288        struct i40e_auxiliary_device *i40e_aux_dev;
 289        struct pci_dev *pdev = ldev->pcidev;
 290        struct auxiliary_device *aux_dev;
 291        int ret;
 292
 293        i40e_aux_dev = kzalloc(sizeof(*i40e_aux_dev), GFP_KERNEL);
 294        if (!i40e_aux_dev)
 295                return -ENOMEM;
 296
 297        i40e_aux_dev->ldev = ldev;
 298
 299        aux_dev = &i40e_aux_dev->aux_dev;
 300        aux_dev->name = name;
 301        aux_dev->dev.parent = &pdev->dev;
 302        aux_dev->dev.release = i40e_auxiliary_dev_release;
 303        ldev->aux_dev = aux_dev;
 304
 305        ret = ida_alloc(&i40e_client_ida, GFP_KERNEL);
 306        if (ret < 0) {
 307                kfree(i40e_aux_dev);
 308                return ret;
 309        }
 310        aux_dev->id = ret;
 311
 312        ret = auxiliary_device_init(aux_dev);
 313        if (ret < 0) {
 314                ida_free(&i40e_client_ida, aux_dev->id);
 315                kfree(i40e_aux_dev);
 316                return ret;
 317        }
 318
 319        ret = auxiliary_device_add(aux_dev);
 320        if (ret) {
 321                auxiliary_device_uninit(aux_dev);
 322                return ret;
 323        }
 324
 325        return ret;
 326}
 327
 328/**
 329 * i40e_client_add_instance - add a client instance struct to the instance list
 330 * @pf: pointer to the board struct
 331 *
 332 **/
 333static void i40e_client_add_instance(struct i40e_pf *pf)
 334{
 335        struct i40e_client_instance *cdev = NULL;
 336        struct netdev_hw_addr *mac = NULL;
 337        struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
 338
 339        cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
 340        if (!cdev)
 341                return;
 342
 343        cdev->lan_info.pf = (void *)pf;
 344        cdev->lan_info.netdev = vsi->netdev;
 345        cdev->lan_info.pcidev = pf->pdev;
 346        cdev->lan_info.fid = pf->hw.pf_id;
 347        cdev->lan_info.ftype = I40E_CLIENT_FTYPE_PF;
 348        cdev->lan_info.hw_addr = pf->hw.hw_addr;
 349        cdev->lan_info.ops = &i40e_lan_ops;
 350        cdev->lan_info.version.major = I40E_CLIENT_VERSION_MAJOR;
 351        cdev->lan_info.version.minor = I40E_CLIENT_VERSION_MINOR;
 352        cdev->lan_info.version.build = I40E_CLIENT_VERSION_BUILD;
 353        cdev->lan_info.fw_maj_ver = pf->hw.aq.fw_maj_ver;
 354        cdev->lan_info.fw_min_ver = pf->hw.aq.fw_min_ver;
 355        cdev->lan_info.fw_build = pf->hw.aq.fw_build;
 356        set_bit(__I40E_CLIENT_INSTANCE_NONE, &cdev->state);
 357
 358        if (i40e_client_get_params(vsi, &cdev->lan_info.params))
 359                goto free_cdev;
 360
 361        mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list,
 362                               struct netdev_hw_addr, list);
 363        if (mac)
 364                ether_addr_copy(cdev->lan_info.lanmac, mac->addr);
 365        else
 366                dev_err(&pf->pdev->dev, "MAC address list is empty!\n");
 367
 368        pf->cinst = cdev;
 369
 370        cdev->lan_info.msix_count = pf->num_iwarp_msix;
 371        cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
 372
 373        if (i40e_register_auxiliary_dev(&cdev->lan_info, "iwarp"))
 374                goto free_cdev;
 375
 376        return;
 377
 378free_cdev:
 379        kfree(cdev);
 380        pf->cinst = NULL;
 381}
 382
 383/**
 384 * i40e_client_del_instance - removes a client instance from the list
 385 * @pf: pointer to the board struct
 386 *
 387 **/
 388static
 389void i40e_client_del_instance(struct i40e_pf *pf)
 390{
 391        kfree(pf->cinst);
 392        pf->cinst = NULL;
 393}
 394
 395/**
 396 * i40e_client_subtask - client maintenance work
 397 * @pf: board private structure
 398 **/
 399void i40e_client_subtask(struct i40e_pf *pf)
 400{
 401        struct i40e_client *client;
 402        struct i40e_client_instance *cdev;
 403        struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
 404        int ret = 0;
 405
 406        if (!test_and_clear_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state))
 407                return;
 408        cdev = pf->cinst;
 409
 410        /* If we're down or resetting, just bail */
 411        if (test_bit(__I40E_DOWN, pf->state) ||
 412            test_bit(__I40E_CONFIG_BUSY, pf->state))
 413                return;
 414
 415        if (!cdev || !cdev->client)
 416                return;
 417
 418        client = cdev->client;
 419
 420        /* Here we handle client opens. If the client is down, and
 421         * the netdev is registered, then open the client.
 422         */
 423        if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
 424                if (vsi->netdev_registered &&
 425                    client->ops && client->ops->open) {
 426                        set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
 427                        ret = client->ops->open(&cdev->lan_info, client);
 428                        if (ret) {
 429                                /* Remove failed client instance */
 430                                clear_bit(__I40E_CLIENT_INSTANCE_OPENED,
 431                                          &cdev->state);
 432                                i40e_client_del_instance(pf);
 433                                return;
 434                        }
 435                }
 436        }
 437
 438        /* enable/disable PE TCP_ENA flag based on netdev down/up
 439         */
 440        if (test_bit(__I40E_VSI_DOWN, vsi->state))
 441                i40e_client_update_vsi_ctxt(&cdev->lan_info, client,
 442                                            0, 0, 0,
 443                                            I40E_CLIENT_VSI_FLAG_TCP_ENABLE);
 444        else
 445                i40e_client_update_vsi_ctxt(&cdev->lan_info, client,
 446                                            0, 0,
 447                                            I40E_CLIENT_VSI_FLAG_TCP_ENABLE,
 448                                            I40E_CLIENT_VSI_FLAG_TCP_ENABLE);
 449}
 450
 451/**
 452 * i40e_lan_add_device - add a lan device struct to the list of lan devices
 453 * @pf: pointer to the board struct
 454 *
 455 * Returns 0 on success or none 0 on error
 456 **/
 457int i40e_lan_add_device(struct i40e_pf *pf)
 458{
 459        struct i40e_device *ldev;
 460        int ret = 0;
 461
 462        mutex_lock(&i40e_device_mutex);
 463        list_for_each_entry(ldev, &i40e_devices, list) {
 464                if (ldev->pf == pf) {
 465                        ret = -EEXIST;
 466                        goto out;
 467                }
 468        }
 469        ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
 470        if (!ldev) {
 471                ret = -ENOMEM;
 472                goto out;
 473        }
 474        ldev->pf = pf;
 475        INIT_LIST_HEAD(&ldev->list);
 476        list_add(&ldev->list, &i40e_devices);
 477        dev_info(&pf->pdev->dev, "Added LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n",
 478                 pf->hw.pf_id, pf->hw.bus.bus_id,
 479                 pf->hw.bus.device, pf->hw.bus.func);
 480
 481        i40e_client_add_instance(pf);
 482
 483        set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state);
 484        i40e_service_event_schedule(pf);
 485
 486out:
 487        mutex_unlock(&i40e_device_mutex);
 488        return ret;
 489}
 490
 491/**
 492 * i40e_lan_del_device - removes a lan device from the device list
 493 * @pf: pointer to the board struct
 494 *
 495 * Returns 0 on success or non-0 on error
 496 **/
 497int i40e_lan_del_device(struct i40e_pf *pf)
 498{
 499        struct auxiliary_device *aux_dev = pf->cinst->lan_info.aux_dev;
 500        struct i40e_device *ldev, *tmp;
 501        int ret = -ENODEV;
 502
 503        auxiliary_device_delete(aux_dev);
 504        auxiliary_device_uninit(aux_dev);
 505
 506        /* First, remove any client instance. */
 507        i40e_client_del_instance(pf);
 508
 509        mutex_lock(&i40e_device_mutex);
 510        list_for_each_entry_safe(ldev, tmp, &i40e_devices, list) {
 511                if (ldev->pf == pf) {
 512                        dev_info(&pf->pdev->dev, "Deleted LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n",
 513                                 pf->hw.pf_id, pf->hw.bus.bus_id,
 514                                 pf->hw.bus.device, pf->hw.bus.func);
 515                        list_del(&ldev->list);
 516                        kfree(ldev);
 517                        ret = 0;
 518                        break;
 519                }
 520        }
 521        mutex_unlock(&i40e_device_mutex);
 522        return ret;
 523}
 524
 525/**
 526 * i40e_client_virtchnl_send - TBD
 527 * @ldev: pointer to L2 context
 528 * @client: Client pointer
 529 * @vf_id: absolute VF identifier
 530 * @msg: message buffer
 531 * @len: length of message buffer
 532 *
 533 * Return 0 on success or < 0 on error
 534 **/
 535static int i40e_client_virtchnl_send(struct i40e_info *ldev,
 536                                     struct i40e_client *client,
 537                                     u32 vf_id, u8 *msg, u16 len)
 538{
 539        struct i40e_pf *pf = ldev->pf;
 540        struct i40e_hw *hw = &pf->hw;
 541        i40e_status err;
 542
 543        err = i40e_aq_send_msg_to_vf(hw, vf_id, VIRTCHNL_OP_IWARP,
 544                                     0, msg, len, NULL);
 545        if (err)
 546                dev_err(&pf->pdev->dev, "Unable to send iWarp message to VF, error %d, aq status %d\n",
 547                        err, hw->aq.asq_last_status);
 548
 549        return err;
 550}
 551
 552/**
 553 * i40e_client_setup_qvlist
 554 * @ldev: pointer to L2 context.
 555 * @client: Client pointer.
 556 * @qvlist_info: queue and vector list
 557 *
 558 * Return 0 on success or < 0 on error
 559 **/
 560static int i40e_client_setup_qvlist(struct i40e_info *ldev,
 561                                    struct i40e_client *client,
 562                                    struct i40e_qvlist_info *qvlist_info)
 563{
 564        struct i40e_pf *pf = ldev->pf;
 565        struct i40e_hw *hw = &pf->hw;
 566        struct i40e_qv_info *qv_info;
 567        u32 v_idx, i, reg_idx, reg;
 568
 569        ldev->qvlist_info = kzalloc(struct_size(ldev->qvlist_info, qv_info,
 570                                    qvlist_info->num_vectors), GFP_KERNEL);
 571        if (!ldev->qvlist_info)
 572                return -ENOMEM;
 573        ldev->qvlist_info->num_vectors = qvlist_info->num_vectors;
 574
 575        for (i = 0; i < qvlist_info->num_vectors; i++) {
 576                qv_info = &qvlist_info->qv_info[i];
 577                if (!qv_info)
 578                        continue;
 579                v_idx = qv_info->v_idx;
 580
 581                /* Validate vector id belongs to this client */
 582                if ((v_idx >= (pf->iwarp_base_vector + pf->num_iwarp_msix)) ||
 583                    (v_idx < pf->iwarp_base_vector))
 584                        goto err;
 585
 586                ldev->qvlist_info->qv_info[i] = *qv_info;
 587                reg_idx = I40E_PFINT_LNKLSTN(v_idx - 1);
 588
 589                if (qv_info->ceq_idx == I40E_QUEUE_INVALID_IDX) {
 590                        /* Special case - No CEQ mapped on this vector */
 591                        wr32(hw, reg_idx, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK);
 592                } else {
 593                        reg = (qv_info->ceq_idx &
 594                               I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK) |
 595                               (I40E_QUEUE_TYPE_PE_CEQ <<
 596                               I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT);
 597                        wr32(hw, reg_idx, reg);
 598
 599                        reg = (I40E_PFINT_CEQCTL_CAUSE_ENA_MASK |
 600                               (v_idx << I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT) |
 601                               (qv_info->itr_idx <<
 602                                I40E_PFINT_CEQCTL_ITR_INDX_SHIFT) |
 603                               (I40E_QUEUE_END_OF_LIST <<
 604                                I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT));
 605                        wr32(hw, I40E_PFINT_CEQCTL(qv_info->ceq_idx), reg);
 606                }
 607                if (qv_info->aeq_idx != I40E_QUEUE_INVALID_IDX) {
 608                        reg = (I40E_PFINT_AEQCTL_CAUSE_ENA_MASK |
 609                               (v_idx << I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT) |
 610                               (qv_info->itr_idx <<
 611                                I40E_PFINT_AEQCTL_ITR_INDX_SHIFT));
 612
 613                        wr32(hw, I40E_PFINT_AEQCTL, reg);
 614                }
 615        }
 616        /* Mitigate sync problems with iwarp VF driver */
 617        i40e_flush(hw);
 618        return 0;
 619err:
 620        kfree(ldev->qvlist_info);
 621        ldev->qvlist_info = NULL;
 622        return -EINVAL;
 623}
 624
 625/**
 626 * i40e_client_request_reset
 627 * @ldev: pointer to L2 context.
 628 * @client: Client pointer.
 629 * @reset_level: reset level
 630 **/
 631static void i40e_client_request_reset(struct i40e_info *ldev,
 632                                      struct i40e_client *client,
 633                                      u32 reset_level)
 634{
 635        struct i40e_pf *pf = ldev->pf;
 636
 637        switch (reset_level) {
 638        case I40E_CLIENT_RESET_LEVEL_PF:
 639                set_bit(__I40E_PF_RESET_REQUESTED, pf->state);
 640                break;
 641        case I40E_CLIENT_RESET_LEVEL_CORE:
 642                set_bit(__I40E_PF_RESET_REQUESTED, pf->state);
 643                break;
 644        default:
 645                dev_warn(&pf->pdev->dev,
 646                         "Client for PF id %d requested an unsupported reset: %d.\n",
 647                         pf->hw.pf_id, reset_level);
 648                break;
 649        }
 650
 651        i40e_service_event_schedule(pf);
 652}
 653
 654/**
 655 * i40e_client_update_vsi_ctxt
 656 * @ldev: pointer to L2 context.
 657 * @client: Client pointer.
 658 * @is_vf: if this for the VF
 659 * @vf_id: if is_vf true this carries the vf_id
 660 * @flag: Any device level setting that needs to be done for PE
 661 * @valid_flag: Bits in this match up and enable changing of flag bits
 662 *
 663 * Return 0 on success or < 0 on error
 664 **/
 665static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev,
 666                                       struct i40e_client *client,
 667                                       bool is_vf, u32 vf_id,
 668                                       u32 flag, u32 valid_flag)
 669{
 670        struct i40e_pf *pf = ldev->pf;
 671        struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
 672        struct i40e_vsi_context ctxt;
 673        bool update = true;
 674        i40e_status err;
 675
 676        /* TODO: for now do not allow setting VF's VSI setting */
 677        if (is_vf)
 678                return -EINVAL;
 679
 680        ctxt.seid = pf->main_vsi_seid;
 681        ctxt.pf_num = pf->hw.pf_id;
 682        err = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
 683        ctxt.flags = I40E_AQ_VSI_TYPE_PF;
 684        if (err) {
 685                dev_info(&pf->pdev->dev,
 686                         "couldn't get PF vsi config, err %s aq_err %s\n",
 687                         i40e_stat_str(&pf->hw, err),
 688                         i40e_aq_str(&pf->hw,
 689                                     pf->hw.aq.asq_last_status));
 690                return -ENOENT;
 691        }
 692
 693        if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) &&
 694            (flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) {
 695                ctxt.info.valid_sections =
 696                        cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
 697                ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA;
 698        } else if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) &&
 699                  !(flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) {
 700                ctxt.info.valid_sections =
 701                        cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
 702                ctxt.info.queueing_opt_flags &= ~I40E_AQ_VSI_QUE_OPT_TCP_ENA;
 703        } else {
 704                update = false;
 705                dev_warn(&pf->pdev->dev,
 706                         "Client for PF id %d request an unsupported Config: %x.\n",
 707                         pf->hw.pf_id, flag);
 708        }
 709
 710        if (update) {
 711                err = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
 712                if (err) {
 713                        dev_info(&pf->pdev->dev,
 714                                 "update VSI ctxt for PE failed, err %s aq_err %s\n",
 715                                 i40e_stat_str(&pf->hw, err),
 716                                 i40e_aq_str(&pf->hw,
 717                                             pf->hw.aq.asq_last_status));
 718                }
 719        }
 720        return err;
 721}
 722
 723void i40e_client_device_register(struct i40e_info *ldev, struct i40e_client *client)
 724{
 725        struct i40e_pf *pf = ldev->pf;
 726
 727        pf->cinst->client = client;
 728        set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state);
 729        i40e_service_event_schedule(pf);
 730}
 731EXPORT_SYMBOL_GPL(i40e_client_device_register);
 732
 733void i40e_client_device_unregister(struct i40e_info *ldev)
 734{
 735        struct i40e_pf *pf = ldev->pf;
 736        struct i40e_client_instance *cdev = pf->cinst;
 737
 738        if (!cdev)
 739                return;
 740
 741        while (test_and_set_bit(__I40E_SERVICE_SCHED, pf->state))
 742                usleep_range(500, 1000);
 743
 744        if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
 745                cdev->client->ops->close(&cdev->lan_info, cdev->client, false);
 746                clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
 747                i40e_client_release_qvlist(&cdev->lan_info);
 748        }
 749
 750        pf->cinst->client = NULL;
 751        clear_bit(__I40E_SERVICE_SCHED, pf->state);
 752}
 753EXPORT_SYMBOL_GPL(i40e_client_device_unregister);
 754