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