diff options
author | David S. Miller <davem@davemloft.net> | 2014-07-02 21:41:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-02 21:41:05 -0400 |
commit | eb1ac820c61d0d83747f2575092451efc2be09e4 (patch) | |
tree | b681e5092ce68fc3c8cb6ea0f5de61fa218fe7f7 | |
parent | bd4578bc84a8c8a390cf6002539e75447e78e935 (diff) | |
parent | 9d4dfe4ae370747bcab66531482013d7ff6857f1 (diff) |
Merge branch 'be2net'
Sathya Perla says:
====================
be2net: patch set
v2 change: merged 2 lines into one in patch 4
Patch 1 refactors be_cmd_get_profile_config() routine to reduce
code duplication by using the be_cmd_notify_wait() routine, instead
of using a separate variant of the code for MBOX and MCCQ.
Patch 2 introduces the required FW-cmd code in the PF to query
RSS support on a VF. This is in preparation for patch 3.
Patch 3 adds support for the PF driver to re-configure the resource
distribution in FW based on the number of VFs enabled by the user. When
the user is not interested in enabling VFs, all resources of a port are
set-aside for the PF. If less than maximum number of VFs are enabled, then
each VF gets a better share of the resources and can now enable RSS (if
the interface supports it.)
Patch 4 is a minor fix to re-enable HW vlan filtering as soon as the number
of vlans programmed is within the HW limit.
Please consider applying to net-next tree. Thanks!
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 226 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 141 |
4 files changed, 230 insertions, 155 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index c2f5d2d3b932..d3d871b28cad 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -411,6 +411,7 @@ struct be_resources { | |||
411 | u16 max_vlans; /* Number of vlans supported */ | 411 | u16 max_vlans; /* Number of vlans supported */ |
412 | u16 max_evt_qs; | 412 | u16 max_evt_qs; |
413 | u32 if_cap_flags; | 413 | u32 if_cap_flags; |
414 | u32 vf_if_cap_flags; /* VF if capability flags */ | ||
414 | }; | 415 | }; |
415 | 416 | ||
416 | struct rss_info { | 417 | struct rss_info { |
@@ -500,6 +501,7 @@ struct be_adapter { | |||
500 | u32 flash_status; | 501 | u32 flash_status; |
501 | struct completion et_cmd_compl; | 502 | struct completion et_cmd_compl; |
502 | 503 | ||
504 | struct be_resources pool_res; /* resources available for the port */ | ||
503 | struct be_resources res; /* resources available for the func */ | 505 | struct be_resources res; /* resources available for the func */ |
504 | u16 num_vfs; /* Number of VFs provisioned by PF */ | 506 | u16 num_vfs; /* Number of VFs provisioned by PF */ |
505 | u8 virtfn; | 507 | u8 virtfn; |
@@ -523,9 +525,8 @@ struct be_adapter { | |||
523 | 525 | ||
524 | #define be_physfn(adapter) (!adapter->virtfn) | 526 | #define be_physfn(adapter) (!adapter->virtfn) |
525 | #define be_virtfn(adapter) (adapter->virtfn) | 527 | #define be_virtfn(adapter) (adapter->virtfn) |
526 | #define sriov_enabled(adapter) (adapter->num_vfs > 0) | 528 | #define sriov_enabled(adapter) (adapter->num_vfs > 0) |
527 | #define sriov_want(adapter) (be_physfn(adapter) && \ | 529 | |
528 | (num_vfs || pci_num_vf(adapter->pdev))) | ||
529 | #define for_all_vfs(adapter, vf_cfg, i) \ | 530 | #define for_all_vfs(adapter, vf_cfg, i) \ |
530 | for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \ | 531 | for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \ |
531 | i++, vf_cfg++) | 532 | i++, vf_cfg++) |
@@ -536,7 +537,7 @@ struct be_adapter { | |||
536 | #define be_max_vlans(adapter) (adapter->res.max_vlans) | 537 | #define be_max_vlans(adapter) (adapter->res.max_vlans) |
537 | #define be_max_uc(adapter) (adapter->res.max_uc_mac) | 538 | #define be_max_uc(adapter) (adapter->res.max_uc_mac) |
538 | #define be_max_mc(adapter) (adapter->res.max_mcast_mac) | 539 | #define be_max_mc(adapter) (adapter->res.max_mcast_mac) |
539 | #define be_max_vfs(adapter) (adapter->res.max_vfs) | 540 | #define be_max_vfs(adapter) (adapter->pool_res.max_vfs) |
540 | #define be_max_rss(adapter) (adapter->res.max_rss_qs) | 541 | #define be_max_rss(adapter) (adapter->res.max_rss_qs) |
541 | #define be_max_txqs(adapter) (adapter->res.max_tx_qs) | 542 | #define be_max_txqs(adapter) (adapter->res.max_tx_qs) |
542 | #define be_max_prio_txqs(adapter) (adapter->res.max_prio_tx_qs) | 543 | #define be_max_prio_txqs(adapter) (adapter->res.max_prio_tx_qs) |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index f4ea3490f446..9904bbfd4e93 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -3313,15 +3313,28 @@ err: | |||
3313 | return status; | 3313 | return status; |
3314 | } | 3314 | } |
3315 | 3315 | ||
3316 | static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count) | 3316 | /* Descriptor type */ |
3317 | enum { | ||
3318 | FUNC_DESC = 1, | ||
3319 | VFT_DESC = 2 | ||
3320 | }; | ||
3321 | |||
3322 | static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count, | ||
3323 | int desc_type) | ||
3317 | { | 3324 | { |
3318 | struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf; | 3325 | struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf; |
3326 | struct be_nic_res_desc *nic; | ||
3319 | int i; | 3327 | int i; |
3320 | 3328 | ||
3321 | for (i = 0; i < desc_count; i++) { | 3329 | for (i = 0; i < desc_count; i++) { |
3322 | if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || | 3330 | if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || |
3323 | hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1) | 3331 | hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1) { |
3324 | return (struct be_nic_res_desc *)hdr; | 3332 | nic = (struct be_nic_res_desc *)hdr; |
3333 | if (desc_type == FUNC_DESC || | ||
3334 | (desc_type == VFT_DESC && | ||
3335 | nic->flags & (1 << VFT_SHIFT))) | ||
3336 | return nic; | ||
3337 | } | ||
3325 | 3338 | ||
3326 | hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0; | 3339 | hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0; |
3327 | hdr = (void *)hdr + hdr->desc_len; | 3340 | hdr = (void *)hdr + hdr->desc_len; |
@@ -3329,6 +3342,16 @@ static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count) | |||
3329 | return NULL; | 3342 | return NULL; |
3330 | } | 3343 | } |
3331 | 3344 | ||
3345 | static struct be_nic_res_desc *be_get_vft_desc(u8 *buf, u32 desc_count) | ||
3346 | { | ||
3347 | return be_get_nic_desc(buf, desc_count, VFT_DESC); | ||
3348 | } | ||
3349 | |||
3350 | static struct be_nic_res_desc *be_get_func_nic_desc(u8 *buf, u32 desc_count) | ||
3351 | { | ||
3352 | return be_get_nic_desc(buf, desc_count, FUNC_DESC); | ||
3353 | } | ||
3354 | |||
3332 | static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf, | 3355 | static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf, |
3333 | u32 desc_count) | 3356 | u32 desc_count) |
3334 | { | 3357 | { |
@@ -3424,7 +3447,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res) | |||
3424 | u32 desc_count = le32_to_cpu(resp->desc_count); | 3447 | u32 desc_count = le32_to_cpu(resp->desc_count); |
3425 | struct be_nic_res_desc *desc; | 3448 | struct be_nic_res_desc *desc; |
3426 | 3449 | ||
3427 | desc = be_get_nic_desc(resp->func_param, desc_count); | 3450 | desc = be_get_func_nic_desc(resp->func_param, desc_count); |
3428 | if (!desc) { | 3451 | if (!desc) { |
3429 | status = -EINVAL; | 3452 | status = -EINVAL; |
3430 | goto err; | 3453 | goto err; |
@@ -3440,76 +3463,17 @@ err: | |||
3440 | return status; | 3463 | return status; |
3441 | } | 3464 | } |
3442 | 3465 | ||
3443 | /* Uses mbox */ | 3466 | /* Will use MBOX only if MCCQ has not been created */ |
3444 | static int be_cmd_get_profile_config_mbox(struct be_adapter *adapter, | ||
3445 | u8 domain, struct be_dma_mem *cmd) | ||
3446 | { | ||
3447 | struct be_mcc_wrb *wrb; | ||
3448 | struct be_cmd_req_get_profile_config *req; | ||
3449 | int status; | ||
3450 | |||
3451 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | ||
3452 | return -1; | ||
3453 | wrb = wrb_from_mbox(adapter); | ||
3454 | |||
3455 | req = cmd->va; | ||
3456 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
3457 | OPCODE_COMMON_GET_PROFILE_CONFIG, | ||
3458 | cmd->size, wrb, cmd); | ||
3459 | |||
3460 | req->type = ACTIVE_PROFILE_TYPE; | ||
3461 | req->hdr.domain = domain; | ||
3462 | if (!lancer_chip(adapter)) | ||
3463 | req->hdr.version = 1; | ||
3464 | |||
3465 | status = be_mbox_notify_wait(adapter); | ||
3466 | |||
3467 | mutex_unlock(&adapter->mbox_lock); | ||
3468 | return status; | ||
3469 | } | ||
3470 | |||
3471 | /* Uses sync mcc */ | ||
3472 | static int be_cmd_get_profile_config_mccq(struct be_adapter *adapter, | ||
3473 | u8 domain, struct be_dma_mem *cmd) | ||
3474 | { | ||
3475 | struct be_mcc_wrb *wrb; | ||
3476 | struct be_cmd_req_get_profile_config *req; | ||
3477 | int status; | ||
3478 | |||
3479 | spin_lock_bh(&adapter->mcc_lock); | ||
3480 | |||
3481 | wrb = wrb_from_mccq(adapter); | ||
3482 | if (!wrb) { | ||
3483 | status = -EBUSY; | ||
3484 | goto err; | ||
3485 | } | ||
3486 | |||
3487 | req = cmd->va; | ||
3488 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
3489 | OPCODE_COMMON_GET_PROFILE_CONFIG, | ||
3490 | cmd->size, wrb, cmd); | ||
3491 | |||
3492 | req->type = ACTIVE_PROFILE_TYPE; | ||
3493 | req->hdr.domain = domain; | ||
3494 | if (!lancer_chip(adapter)) | ||
3495 | req->hdr.version = 1; | ||
3496 | |||
3497 | status = be_mcc_notify_wait(adapter); | ||
3498 | |||
3499 | err: | ||
3500 | spin_unlock_bh(&adapter->mcc_lock); | ||
3501 | return status; | ||
3502 | } | ||
3503 | |||
3504 | /* Uses sync mcc, if MCCQ is already created otherwise mbox */ | ||
3505 | int be_cmd_get_profile_config(struct be_adapter *adapter, | 3467 | int be_cmd_get_profile_config(struct be_adapter *adapter, |
3506 | struct be_resources *res, u8 domain) | 3468 | struct be_resources *res, u8 domain) |
3507 | { | 3469 | { |
3508 | struct be_cmd_resp_get_profile_config *resp; | 3470 | struct be_cmd_resp_get_profile_config *resp; |
3471 | struct be_cmd_req_get_profile_config *req; | ||
3472 | struct be_nic_res_desc *vf_res; | ||
3509 | struct be_pcie_res_desc *pcie; | 3473 | struct be_pcie_res_desc *pcie; |
3510 | struct be_port_res_desc *port; | 3474 | struct be_port_res_desc *port; |
3511 | struct be_nic_res_desc *nic; | 3475 | struct be_nic_res_desc *nic; |
3512 | struct be_queue_info *mccq = &adapter->mcc_obj.q; | 3476 | struct be_mcc_wrb wrb = {0}; |
3513 | struct be_dma_mem cmd; | 3477 | struct be_dma_mem cmd; |
3514 | u32 desc_count; | 3478 | u32 desc_count; |
3515 | int status; | 3479 | int status; |
@@ -3520,10 +3484,17 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, | |||
3520 | if (!cmd.va) | 3484 | if (!cmd.va) |
3521 | return -ENOMEM; | 3485 | return -ENOMEM; |
3522 | 3486 | ||
3523 | if (!mccq->created) | 3487 | req = cmd.va; |
3524 | status = be_cmd_get_profile_config_mbox(adapter, domain, &cmd); | 3488 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
3525 | else | 3489 | OPCODE_COMMON_GET_PROFILE_CONFIG, |
3526 | status = be_cmd_get_profile_config_mccq(adapter, domain, &cmd); | 3490 | cmd.size, &wrb, &cmd); |
3491 | |||
3492 | req->hdr.domain = domain; | ||
3493 | if (!lancer_chip(adapter)) | ||
3494 | req->hdr.version = 1; | ||
3495 | req->type = ACTIVE_PROFILE_TYPE; | ||
3496 | |||
3497 | status = be_cmd_notify_wait(adapter, &wrb); | ||
3527 | if (status) | 3498 | if (status) |
3528 | goto err; | 3499 | goto err; |
3529 | 3500 | ||
@@ -3539,48 +3510,52 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, | |||
3539 | if (port) | 3510 | if (port) |
3540 | adapter->mc_type = port->mc_type; | 3511 | adapter->mc_type = port->mc_type; |
3541 | 3512 | ||
3542 | nic = be_get_nic_desc(resp->func_param, desc_count); | 3513 | nic = be_get_func_nic_desc(resp->func_param, desc_count); |
3543 | if (nic) | 3514 | if (nic) |
3544 | be_copy_nic_desc(res, nic); | 3515 | be_copy_nic_desc(res, nic); |
3545 | 3516 | ||
3517 | vf_res = be_get_vft_desc(resp->func_param, desc_count); | ||
3518 | if (vf_res) | ||
3519 | res->vf_if_cap_flags = vf_res->cap_flags; | ||
3546 | err: | 3520 | err: |
3547 | if (cmd.va) | 3521 | if (cmd.va) |
3548 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | 3522 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); |
3549 | return status; | 3523 | return status; |
3550 | } | 3524 | } |
3551 | 3525 | ||
3552 | int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc, | 3526 | /* Will use MBOX only if MCCQ has not been created */ |
3553 | int size, u8 version, u8 domain) | 3527 | static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc, |
3528 | int size, int count, u8 version, u8 domain) | ||
3554 | { | 3529 | { |
3555 | struct be_cmd_req_set_profile_config *req; | 3530 | struct be_cmd_req_set_profile_config *req; |
3556 | struct be_mcc_wrb *wrb; | 3531 | struct be_mcc_wrb wrb = {0}; |
3532 | struct be_dma_mem cmd; | ||
3557 | int status; | 3533 | int status; |
3558 | 3534 | ||
3559 | spin_lock_bh(&adapter->mcc_lock); | 3535 | memset(&cmd, 0, sizeof(struct be_dma_mem)); |
3560 | 3536 | cmd.size = sizeof(struct be_cmd_req_set_profile_config); | |
3561 | wrb = wrb_from_mccq(adapter); | 3537 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); |
3562 | if (!wrb) { | 3538 | if (!cmd.va) |
3563 | status = -EBUSY; | 3539 | return -ENOMEM; |
3564 | goto err; | ||
3565 | } | ||
3566 | 3540 | ||
3567 | req = embedded_payload(wrb); | 3541 | req = cmd.va; |
3568 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 3542 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
3569 | OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req), | 3543 | OPCODE_COMMON_SET_PROFILE_CONFIG, cmd.size, |
3570 | wrb, NULL); | 3544 | &wrb, &cmd); |
3571 | req->hdr.version = version; | 3545 | req->hdr.version = version; |
3572 | req->hdr.domain = domain; | 3546 | req->hdr.domain = domain; |
3573 | req->desc_count = cpu_to_le32(1); | 3547 | req->desc_count = cpu_to_le32(count); |
3574 | memcpy(req->desc, desc, size); | 3548 | memcpy(req->desc, desc, size); |
3575 | 3549 | ||
3576 | status = be_mcc_notify_wait(adapter); | 3550 | status = be_cmd_notify_wait(adapter, &wrb); |
3577 | err: | 3551 | |
3578 | spin_unlock_bh(&adapter->mcc_lock); | 3552 | if (cmd.va) |
3553 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | ||
3579 | return status; | 3554 | return status; |
3580 | } | 3555 | } |
3581 | 3556 | ||
3582 | /* Mark all fields invalid */ | 3557 | /* Mark all fields invalid */ |
3583 | void be_reset_nic_desc(struct be_nic_res_desc *nic) | 3558 | static void be_reset_nic_desc(struct be_nic_res_desc *nic) |
3584 | { | 3559 | { |
3585 | memset(nic, 0, sizeof(*nic)); | 3560 | memset(nic, 0, sizeof(*nic)); |
3586 | nic->unicast_mac_count = 0xFFFF; | 3561 | nic->unicast_mac_count = 0xFFFF; |
@@ -3601,9 +3576,20 @@ void be_reset_nic_desc(struct be_nic_res_desc *nic) | |||
3601 | nic->wol_param = 0x0F; | 3576 | nic->wol_param = 0x0F; |
3602 | nic->tunnel_iface_count = 0xFFFF; | 3577 | nic->tunnel_iface_count = 0xFFFF; |
3603 | nic->direct_tenant_iface_count = 0xFFFF; | 3578 | nic->direct_tenant_iface_count = 0xFFFF; |
3579 | nic->bw_min = 0xFFFFFFFF; | ||
3604 | nic->bw_max = 0xFFFFFFFF; | 3580 | nic->bw_max = 0xFFFFFFFF; |
3605 | } | 3581 | } |
3606 | 3582 | ||
3583 | /* Mark all fields invalid */ | ||
3584 | static void be_reset_pcie_desc(struct be_pcie_res_desc *pcie) | ||
3585 | { | ||
3586 | memset(pcie, 0, sizeof(*pcie)); | ||
3587 | pcie->sriov_state = 0xFF; | ||
3588 | pcie->pf_state = 0xFF; | ||
3589 | pcie->pf_type = 0xFF; | ||
3590 | pcie->num_vfs = 0xFFFF; | ||
3591 | } | ||
3592 | |||
3607 | int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed, | 3593 | int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed, |
3608 | u8 domain) | 3594 | u8 domain) |
3609 | { | 3595 | { |
@@ -3634,7 +3620,63 @@ int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed, | |||
3634 | 3620 | ||
3635 | return be_cmd_set_profile_config(adapter, &nic_desc, | 3621 | return be_cmd_set_profile_config(adapter, &nic_desc, |
3636 | nic_desc.hdr.desc_len, | 3622 | nic_desc.hdr.desc_len, |
3637 | version, domain); | 3623 | 1, version, domain); |
3624 | } | ||
3625 | |||
3626 | int be_cmd_set_sriov_config(struct be_adapter *adapter, | ||
3627 | struct be_resources res, u16 num_vfs) | ||
3628 | { | ||
3629 | struct { | ||
3630 | struct be_pcie_res_desc pcie; | ||
3631 | struct be_nic_res_desc nic_vft; | ||
3632 | } __packed desc; | ||
3633 | u16 vf_q_count; | ||
3634 | |||
3635 | if (BEx_chip(adapter) || lancer_chip(adapter)) | ||
3636 | return 0; | ||
3637 | |||
3638 | /* PF PCIE descriptor */ | ||
3639 | be_reset_pcie_desc(&desc.pcie); | ||
3640 | desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1; | ||
3641 | desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1; | ||
3642 | desc.pcie.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT); | ||
3643 | desc.pcie.pf_num = adapter->pdev->devfn; | ||
3644 | desc.pcie.sriov_state = num_vfs ? 1 : 0; | ||
3645 | desc.pcie.num_vfs = cpu_to_le16(num_vfs); | ||
3646 | |||
3647 | /* VF NIC Template descriptor */ | ||
3648 | be_reset_nic_desc(&desc.nic_vft); | ||
3649 | desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1; | ||
3650 | desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1; | ||
3651 | desc.nic_vft.flags = (1 << VFT_SHIFT) | (1 << IMM_SHIFT) | | ||
3652 | (1 << NOSV_SHIFT); | ||
3653 | desc.nic_vft.pf_num = adapter->pdev->devfn; | ||
3654 | desc.nic_vft.vf_num = 0; | ||
3655 | |||
3656 | if (num_vfs && res.vf_if_cap_flags & BE_IF_FLAGS_RSS) { | ||
3657 | /* If number of VFs requested is 8 less than max supported, | ||
3658 | * assign 8 queue pairs to the PF and divide the remaining | ||
3659 | * resources evenly among the VFs | ||
3660 | */ | ||
3661 | if (num_vfs < (be_max_vfs(adapter) - 8)) | ||
3662 | vf_q_count = (res.max_rss_qs - 8) / num_vfs; | ||
3663 | else | ||
3664 | vf_q_count = res.max_rss_qs / num_vfs; | ||
3665 | |||
3666 | desc.nic_vft.rq_count = cpu_to_le16(vf_q_count); | ||
3667 | desc.nic_vft.txq_count = cpu_to_le16(vf_q_count); | ||
3668 | desc.nic_vft.rssq_count = cpu_to_le16(vf_q_count - 1); | ||
3669 | desc.nic_vft.cq_count = cpu_to_le16(3 * vf_q_count); | ||
3670 | } else { | ||
3671 | desc.nic_vft.txq_count = cpu_to_le16(1); | ||
3672 | desc.nic_vft.rq_count = cpu_to_le16(1); | ||
3673 | desc.nic_vft.rssq_count = cpu_to_le16(0); | ||
3674 | /* One CQ for each TX, RX and MCCQ */ | ||
3675 | desc.nic_vft.cq_count = cpu_to_le16(3); | ||
3676 | } | ||
3677 | |||
3678 | return be_cmd_set_profile_config(adapter, &desc, | ||
3679 | 2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0); | ||
3638 | } | 3680 | } |
3639 | 3681 | ||
3640 | int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op) | 3682 | int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op) |
@@ -3686,7 +3728,7 @@ int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port) | |||
3686 | } | 3728 | } |
3687 | 3729 | ||
3688 | return be_cmd_set_profile_config(adapter, &port_desc, | 3730 | return be_cmd_set_profile_config(adapter, &port_desc, |
3689 | RESOURCE_DESC_SIZE_V1, 1, 0); | 3731 | RESOURCE_DESC_SIZE_V1, 1, 1, 0); |
3690 | } | 3732 | } |
3691 | 3733 | ||
3692 | int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, | 3734 | int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 59b3c056f329..c0f7167049b7 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -1835,6 +1835,7 @@ struct be_cmd_req_set_ext_fat_caps { | |||
1835 | #define PORT_RESOURCE_DESC_TYPE_V1 0x55 | 1835 | #define PORT_RESOURCE_DESC_TYPE_V1 0x55 |
1836 | #define MAX_RESOURCE_DESC 264 | 1836 | #define MAX_RESOURCE_DESC 264 |
1837 | 1837 | ||
1838 | #define VFT_SHIFT 3 /* VF template */ | ||
1838 | #define IMM_SHIFT 6 /* Immediate */ | 1839 | #define IMM_SHIFT 6 /* Immediate */ |
1839 | #define NOSV_SHIFT 7 /* No save */ | 1840 | #define NOSV_SHIFT 7 /* No save */ |
1840 | 1841 | ||
@@ -1962,8 +1963,8 @@ struct be_cmd_req_set_profile_config { | |||
1962 | struct be_cmd_req_hdr hdr; | 1963 | struct be_cmd_req_hdr hdr; |
1963 | u32 rsvd; | 1964 | u32 rsvd; |
1964 | u32 desc_count; | 1965 | u32 desc_count; |
1965 | u8 desc[RESOURCE_DESC_SIZE_V1]; | 1966 | u8 desc[2 * RESOURCE_DESC_SIZE_V1]; |
1966 | }; | 1967 | } __packed; |
1967 | 1968 | ||
1968 | struct be_cmd_resp_set_profile_config { | 1969 | struct be_cmd_resp_set_profile_config { |
1969 | struct be_cmd_resp_hdr hdr; | 1970 | struct be_cmd_resp_hdr hdr; |
@@ -2157,8 +2158,6 @@ int be_cmd_get_func_config(struct be_adapter *adapter, | |||
2157 | struct be_resources *res); | 2158 | struct be_resources *res); |
2158 | int be_cmd_get_profile_config(struct be_adapter *adapter, | 2159 | int be_cmd_get_profile_config(struct be_adapter *adapter, |
2159 | struct be_resources *res, u8 domain); | 2160 | struct be_resources *res, u8 domain); |
2160 | int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc, | ||
2161 | int size, u8 version, u8 domain); | ||
2162 | int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile); | 2161 | int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile); |
2163 | int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, | 2162 | int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, |
2164 | int vf_num); | 2163 | int vf_num); |
@@ -2168,3 +2167,5 @@ int be_cmd_set_logical_link_config(struct be_adapter *adapter, | |||
2168 | int link_state, u8 domain); | 2167 | int link_state, u8 domain); |
2169 | int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port); | 2168 | int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port); |
2170 | int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op); | 2169 | int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op); |
2170 | int be_cmd_set_sriov_config(struct be_adapter *adapter, | ||
2171 | struct be_resources res, u16 num_vfs); | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 34a26e42f19d..6297e72b77e2 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -1172,20 +1172,15 @@ static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid) | |||
1172 | static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid) | 1172 | static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid) |
1173 | { | 1173 | { |
1174 | struct be_adapter *adapter = netdev_priv(netdev); | 1174 | struct be_adapter *adapter = netdev_priv(netdev); |
1175 | int status = 0; | ||
1176 | 1175 | ||
1177 | /* Packets with VID 0 are always received by Lancer by default */ | 1176 | /* Packets with VID 0 are always received by Lancer by default */ |
1178 | if (lancer_chip(adapter) && vid == 0) | 1177 | if (lancer_chip(adapter) && vid == 0) |
1179 | goto ret; | 1178 | return 0; |
1180 | 1179 | ||
1181 | clear_bit(vid, adapter->vids); | 1180 | clear_bit(vid, adapter->vids); |
1182 | status = be_vid_config(adapter); | 1181 | adapter->vlans_added--; |
1183 | if (!status) | 1182 | |
1184 | adapter->vlans_added--; | 1183 | return be_vid_config(adapter); |
1185 | else | ||
1186 | set_bit(vid, adapter->vids); | ||
1187 | ret: | ||
1188 | return status; | ||
1189 | } | 1184 | } |
1190 | 1185 | ||
1191 | static void be_clear_promisc(struct be_adapter *adapter) | 1186 | static void be_clear_promisc(struct be_adapter *adapter) |
@@ -3098,6 +3093,13 @@ static int be_clear(struct be_adapter *adapter) | |||
3098 | if (sriov_enabled(adapter)) | 3093 | if (sriov_enabled(adapter)) |
3099 | be_vf_clear(adapter); | 3094 | be_vf_clear(adapter); |
3100 | 3095 | ||
3096 | /* Re-configure FW to distribute resources evenly across max-supported | ||
3097 | * number of VFs, only when VFs are not already enabled. | ||
3098 | */ | ||
3099 | if (be_physfn(adapter) && !pci_vfs_assigned(adapter->pdev)) | ||
3100 | be_cmd_set_sriov_config(adapter, adapter->pool_res, | ||
3101 | pci_sriov_get_totalvfs(adapter->pdev)); | ||
3102 | |||
3101 | #ifdef CONFIG_BE2NET_VXLAN | 3103 | #ifdef CONFIG_BE2NET_VXLAN |
3102 | be_disable_vxlan_offloads(adapter); | 3104 | be_disable_vxlan_offloads(adapter); |
3103 | #endif | 3105 | #endif |
@@ -3170,19 +3172,6 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
3170 | u32 privileges; | 3172 | u32 privileges; |
3171 | 3173 | ||
3172 | old_vfs = pci_num_vf(adapter->pdev); | 3174 | old_vfs = pci_num_vf(adapter->pdev); |
3173 | if (old_vfs) { | ||
3174 | dev_info(dev, "%d VFs are already enabled\n", old_vfs); | ||
3175 | if (old_vfs != num_vfs) | ||
3176 | dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs); | ||
3177 | adapter->num_vfs = old_vfs; | ||
3178 | } else { | ||
3179 | if (num_vfs > be_max_vfs(adapter)) | ||
3180 | dev_info(dev, "Device supports %d VFs and not %d\n", | ||
3181 | be_max_vfs(adapter), num_vfs); | ||
3182 | adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter)); | ||
3183 | if (!adapter->num_vfs) | ||
3184 | return 0; | ||
3185 | } | ||
3186 | 3175 | ||
3187 | status = be_vf_setup_init(adapter); | 3176 | status = be_vf_setup_init(adapter); |
3188 | if (status) | 3177 | if (status) |
@@ -3194,17 +3183,15 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
3194 | if (status) | 3183 | if (status) |
3195 | goto err; | 3184 | goto err; |
3196 | } | 3185 | } |
3197 | } else { | ||
3198 | status = be_vfs_if_create(adapter); | ||
3199 | if (status) | ||
3200 | goto err; | ||
3201 | } | ||
3202 | 3186 | ||
3203 | if (old_vfs) { | ||
3204 | status = be_vfs_mac_query(adapter); | 3187 | status = be_vfs_mac_query(adapter); |
3205 | if (status) | 3188 | if (status) |
3206 | goto err; | 3189 | goto err; |
3207 | } else { | 3190 | } else { |
3191 | status = be_vfs_if_create(adapter); | ||
3192 | if (status) | ||
3193 | goto err; | ||
3194 | |||
3208 | status = be_vf_eth_addr_config(adapter); | 3195 | status = be_vf_eth_addr_config(adapter); |
3209 | if (status) | 3196 | if (status) |
3210 | goto err; | 3197 | goto err; |
@@ -3270,19 +3257,7 @@ static u8 be_convert_mc_type(u32 function_mode) | |||
3270 | static void BEx_get_resources(struct be_adapter *adapter, | 3257 | static void BEx_get_resources(struct be_adapter *adapter, |
3271 | struct be_resources *res) | 3258 | struct be_resources *res) |
3272 | { | 3259 | { |
3273 | struct pci_dev *pdev = adapter->pdev; | 3260 | bool use_sriov = adapter->num_vfs ? 1 : 0; |
3274 | bool use_sriov = false; | ||
3275 | int max_vfs = 0; | ||
3276 | |||
3277 | if (be_physfn(adapter) && BE3_chip(adapter)) { | ||
3278 | be_cmd_get_profile_config(adapter, res, 0); | ||
3279 | /* Some old versions of BE3 FW don't report max_vfs value */ | ||
3280 | if (res->max_vfs == 0) { | ||
3281 | max_vfs = pci_sriov_get_totalvfs(pdev); | ||
3282 | res->max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0; | ||
3283 | } | ||
3284 | use_sriov = res->max_vfs && sriov_want(adapter); | ||
3285 | } | ||
3286 | 3261 | ||
3287 | if (be_physfn(adapter)) | 3262 | if (be_physfn(adapter)) |
3288 | res->max_uc_mac = BE_UC_PMAC_COUNT; | 3263 | res->max_uc_mac = BE_UC_PMAC_COUNT; |
@@ -3349,6 +3324,54 @@ static void be_setup_init(struct be_adapter *adapter) | |||
3349 | adapter->cmd_privileges = MIN_PRIVILEGES; | 3324 | adapter->cmd_privileges = MIN_PRIVILEGES; |
3350 | } | 3325 | } |
3351 | 3326 | ||
3327 | static int be_get_sriov_config(struct be_adapter *adapter) | ||
3328 | { | ||
3329 | struct device *dev = &adapter->pdev->dev; | ||
3330 | struct be_resources res = {0}; | ||
3331 | int status, max_vfs, old_vfs; | ||
3332 | |||
3333 | status = be_cmd_get_profile_config(adapter, &res, 0); | ||
3334 | if (status) | ||
3335 | return status; | ||
3336 | |||
3337 | adapter->pool_res = res; | ||
3338 | |||
3339 | /* Some old versions of BE3 FW don't report max_vfs value */ | ||
3340 | if (BE3_chip(adapter) && !res.max_vfs) { | ||
3341 | max_vfs = pci_sriov_get_totalvfs(adapter->pdev); | ||
3342 | res.max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0; | ||
3343 | } | ||
3344 | |||
3345 | adapter->pool_res.max_vfs = res.max_vfs; | ||
3346 | pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter)); | ||
3347 | |||
3348 | if (!be_max_vfs(adapter)) { | ||
3349 | if (num_vfs) | ||
3350 | dev_warn(dev, "device doesn't support SRIOV\n"); | ||
3351 | adapter->num_vfs = 0; | ||
3352 | return 0; | ||
3353 | } | ||
3354 | |||
3355 | /* validate num_vfs module param */ | ||
3356 | old_vfs = pci_num_vf(adapter->pdev); | ||
3357 | if (old_vfs) { | ||
3358 | dev_info(dev, "%d VFs are already enabled\n", old_vfs); | ||
3359 | if (old_vfs != num_vfs) | ||
3360 | dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs); | ||
3361 | adapter->num_vfs = old_vfs; | ||
3362 | } else { | ||
3363 | if (num_vfs > be_max_vfs(adapter)) { | ||
3364 | dev_info(dev, "Resources unavailable to init %d VFs\n", | ||
3365 | num_vfs); | ||
3366 | dev_info(dev, "Limiting to %d VFs\n", | ||
3367 | be_max_vfs(adapter)); | ||
3368 | } | ||
3369 | adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter)); | ||
3370 | } | ||
3371 | |||
3372 | return 0; | ||
3373 | } | ||
3374 | |||
3352 | static int be_get_resources(struct be_adapter *adapter) | 3375 | static int be_get_resources(struct be_adapter *adapter) |
3353 | { | 3376 | { |
3354 | struct device *dev = &adapter->pdev->dev; | 3377 | struct device *dev = &adapter->pdev->dev; |
@@ -3374,13 +3397,6 @@ static int be_get_resources(struct be_adapter *adapter) | |||
3374 | res.max_evt_qs /= 2; | 3397 | res.max_evt_qs /= 2; |
3375 | adapter->res = res; | 3398 | adapter->res = res; |
3376 | 3399 | ||
3377 | if (be_physfn(adapter)) { | ||
3378 | status = be_cmd_get_profile_config(adapter, &res, 0); | ||
3379 | if (status) | ||
3380 | return status; | ||
3381 | adapter->res.max_vfs = res.max_vfs; | ||
3382 | } | ||
3383 | |||
3384 | dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n", | 3400 | dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n", |
3385 | be_max_txqs(adapter), be_max_rxqs(adapter), | 3401 | be_max_txqs(adapter), be_max_rxqs(adapter), |
3386 | be_max_rss(adapter), be_max_eqs(adapter), | 3402 | be_max_rss(adapter), be_max_eqs(adapter), |
@@ -3393,7 +3409,6 @@ static int be_get_resources(struct be_adapter *adapter) | |||
3393 | return 0; | 3409 | return 0; |
3394 | } | 3410 | } |
3395 | 3411 | ||
3396 | /* Routine to query per function resource limits */ | ||
3397 | static int be_get_config(struct be_adapter *adapter) | 3412 | static int be_get_config(struct be_adapter *adapter) |
3398 | { | 3413 | { |
3399 | u16 profile_id; | 3414 | u16 profile_id; |
@@ -3411,6 +3426,26 @@ static int be_get_config(struct be_adapter *adapter) | |||
3411 | if (!status) | 3426 | if (!status) |
3412 | dev_info(&adapter->pdev->dev, | 3427 | dev_info(&adapter->pdev->dev, |
3413 | "Using profile 0x%x\n", profile_id); | 3428 | "Using profile 0x%x\n", profile_id); |
3429 | |||
3430 | status = be_get_sriov_config(adapter); | ||
3431 | if (status) | ||
3432 | return status; | ||
3433 | |||
3434 | /* When the HW is in SRIOV capable configuration, the PF-pool | ||
3435 | * resources are equally distributed across the max-number of | ||
3436 | * VFs. The user may request only a subset of the max-vfs to be | ||
3437 | * enabled. Based on num_vfs, redistribute the resources across | ||
3438 | * num_vfs so that each VF will have access to more number of | ||
3439 | * resources. This facility is not available in BE3 FW. | ||
3440 | * Also, this is done by FW in Lancer chip. | ||
3441 | */ | ||
3442 | if (!pci_num_vf(adapter->pdev)) { | ||
3443 | status = be_cmd_set_sriov_config(adapter, | ||
3444 | adapter->pool_res, | ||
3445 | adapter->num_vfs); | ||
3446 | if (status) | ||
3447 | return status; | ||
3448 | } | ||
3414 | } | 3449 | } |
3415 | 3450 | ||
3416 | status = be_get_resources(adapter); | 3451 | status = be_get_resources(adapter); |
@@ -3596,12 +3631,8 @@ static int be_setup(struct be_adapter *adapter) | |||
3596 | be_cmd_set_logical_link_config(adapter, | 3631 | be_cmd_set_logical_link_config(adapter, |
3597 | IFLA_VF_LINK_STATE_AUTO, 0); | 3632 | IFLA_VF_LINK_STATE_AUTO, 0); |
3598 | 3633 | ||
3599 | if (sriov_want(adapter)) { | 3634 | if (adapter->num_vfs) |
3600 | if (be_max_vfs(adapter)) | 3635 | be_vf_setup(adapter); |
3601 | be_vf_setup(adapter); | ||
3602 | else | ||
3603 | dev_warn(dev, "device doesn't support SRIOV\n"); | ||
3604 | } | ||
3605 | 3636 | ||
3606 | status = be_cmd_get_phy_info(adapter); | 3637 | status = be_cmd_get_phy_info(adapter); |
3607 | if (!status && be_pause_supported(adapter)) | 3638 | if (!status && be_pause_supported(adapter)) |