diff options
author | Vasundhara Volam <vasundhara.volam@emulex.com> | 2015-03-04 00:44:32 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-04 15:58:37 -0500 |
commit | 71bb8bd08ca61c8cd8b07ff13d3cca40b7272769 (patch) | |
tree | 6139e707f0e0d4655103d8f7d49e4f2befd8c081 /drivers/net/ethernet/emulex | |
parent | 28811a8c00fe0d899b8a544421f3b4947425d5e8 (diff) |
be2net: avoid creating the non-RSS default RXQ if FW allows to
On BE2, BE3 and Skhawk-R chips one non-RSS (called "default") RXQ was
needed to receive non-IP traffic. Some FW versions now export a
capability called IFACE_FLAGS_DEFQ_RSS where this requirement doesn't hold.
On such FWs the driver now does not create the non-RSS default queue.
This prevents wasting one RXQ per VF.
Signed-off-by: Vasundhara Volam <vasundhara.volam@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 50 |
5 files changed, 41 insertions, 24 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index fac806a15a61..7e13faba03bd 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -488,6 +488,8 @@ struct be_adapter { | |||
488 | 488 | ||
489 | /* Rx rings */ | 489 | /* Rx rings */ |
490 | u16 num_rx_qs; | 490 | u16 num_rx_qs; |
491 | u16 num_rss_qs; | ||
492 | u16 need_def_rxq; | ||
491 | struct be_rx_obj rx_obj[MAX_RX_QS]; | 493 | struct be_rx_obj rx_obj[MAX_RX_QS]; |
492 | u32 big_page_size; /* Compounded page size shared by rx wrbs */ | 494 | u32 big_page_size; /* Compounded page size shared by rx wrbs */ |
493 | 495 | ||
@@ -635,9 +637,8 @@ extern const struct ethtool_ops be_ethtool_ops; | |||
635 | for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \ | 637 | for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \ |
636 | i++, rxo++) | 638 | i++, rxo++) |
637 | 639 | ||
638 | /* Skip the default non-rss queue (last one)*/ | ||
639 | #define for_all_rss_queues(adapter, rxo, i) \ | 640 | #define for_all_rss_queues(adapter, rxo, i) \ |
640 | for (i = 0, rxo = &adapter->rx_obj[i]; i < (adapter->num_rx_qs - 1);\ | 641 | for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rss_qs; \ |
641 | i++, rxo++) | 642 | i++, rxo++) |
642 | 643 | ||
643 | #define for_all_tx_queues(adapter, txo, i) \ | 644 | #define for_all_tx_queues(adapter, txo, i) \ |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index be00695b3be7..e1fa1d4c55d4 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -3580,9 +3580,6 @@ static void be_copy_nic_desc(struct be_resources *res, | |||
3580 | /* Clear flags that driver is not interested in */ | 3580 | /* Clear flags that driver is not interested in */ |
3581 | res->if_cap_flags = le32_to_cpu(desc->cap_flags) & | 3581 | res->if_cap_flags = le32_to_cpu(desc->cap_flags) & |
3582 | BE_IF_CAP_FLAGS_WANT; | 3582 | BE_IF_CAP_FLAGS_WANT; |
3583 | /* Need 1 RXQ as the default RXQ */ | ||
3584 | if (res->max_rss_qs && res->max_rss_qs == res->max_rx_qs) | ||
3585 | res->max_rss_qs -= 1; | ||
3586 | } | 3583 | } |
3587 | 3584 | ||
3588 | /* Uses Mbox */ | 3585 | /* Uses Mbox */ |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index db761e8e42a3..49514821d0df 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -588,14 +588,15 @@ enum be_if_flags { | |||
588 | BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, | 588 | BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, |
589 | BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, | 589 | BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, |
590 | BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800, | 590 | BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800, |
591 | BE_IF_FLAGS_MULTICAST = 0x1000 | 591 | BE_IF_FLAGS_MULTICAST = 0x1000, |
592 | BE_IF_FLAGS_DEFQ_RSS = 0x1000000 | ||
592 | }; | 593 | }; |
593 | 594 | ||
594 | #define BE_IF_CAP_FLAGS_WANT (BE_IF_FLAGS_RSS | BE_IF_FLAGS_PROMISCUOUS |\ | 595 | #define BE_IF_CAP_FLAGS_WANT (BE_IF_FLAGS_RSS | BE_IF_FLAGS_PROMISCUOUS |\ |
595 | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_VLAN_PROMISCUOUS |\ | 596 | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_VLAN_PROMISCUOUS |\ |
596 | BE_IF_FLAGS_VLAN | BE_IF_FLAGS_MCAST_PROMISCUOUS |\ | 597 | BE_IF_FLAGS_VLAN | BE_IF_FLAGS_MCAST_PROMISCUOUS |\ |
597 | BE_IF_FLAGS_PASS_L3L4_ERRORS | BE_IF_FLAGS_MULTICAST |\ | 598 | BE_IF_FLAGS_PASS_L3L4_ERRORS | BE_IF_FLAGS_MULTICAST |\ |
598 | BE_IF_FLAGS_UNTAGGED) | 599 | BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_DEFQ_RSS) |
599 | 600 | ||
600 | #define BE_IF_FLAGS_ALL_PROMISCUOUS (BE_IF_FLAGS_PROMISCUOUS | \ | 601 | #define BE_IF_FLAGS_ALL_PROMISCUOUS (BE_IF_FLAGS_PROMISCUOUS | \ |
601 | BE_IF_FLAGS_VLAN_PROMISCUOUS |\ | 602 | BE_IF_FLAGS_VLAN_PROMISCUOUS |\ |
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 4d2de4700769..b765c24625bf 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c | |||
@@ -1097,7 +1097,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter, | |||
1097 | return status; | 1097 | return status; |
1098 | 1098 | ||
1099 | if (be_multi_rxq(adapter)) { | 1099 | if (be_multi_rxq(adapter)) { |
1100 | for (j = 0; j < 128; j += adapter->num_rx_qs - 1) { | 1100 | for (j = 0; j < 128; j += adapter->num_rss_qs) { |
1101 | for_all_rss_queues(adapter, rxo, i) { | 1101 | for_all_rss_queues(adapter, rxo, i) { |
1102 | if ((j + i) >= 128) | 1102 | if ((j + i) >= 128) |
1103 | break; | 1103 | break; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 7eccebc676e2..c4c3a93cac99 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -2454,13 +2454,19 @@ static int be_rx_cqs_create(struct be_adapter *adapter) | |||
2454 | int rc, i; | 2454 | int rc, i; |
2455 | 2455 | ||
2456 | /* We can create as many RSS rings as there are EQs. */ | 2456 | /* We can create as many RSS rings as there are EQs. */ |
2457 | adapter->num_rx_qs = adapter->num_evt_qs; | 2457 | adapter->num_rss_qs = adapter->num_evt_qs; |
2458 | 2458 | ||
2459 | /* We'll use RSS only if atleast 2 RSS rings are supported. | 2459 | /* We'll use RSS only if atleast 2 RSS rings are supported. */ |
2460 | * When RSS is used, we'll need a default RXQ for non-IP traffic. | 2460 | if (adapter->num_rss_qs <= 1) |
2461 | adapter->num_rss_qs = 0; | ||
2462 | |||
2463 | adapter->num_rx_qs = adapter->num_rss_qs + adapter->need_def_rxq; | ||
2464 | |||
2465 | /* When the interface is not capable of RSS rings (and there is no | ||
2466 | * need to create a default RXQ) we'll still need one RXQ | ||
2461 | */ | 2467 | */ |
2462 | if (adapter->num_rx_qs > 1) | 2468 | if (adapter->num_rx_qs == 0) |
2463 | adapter->num_rx_qs++; | 2469 | adapter->num_rx_qs = 1; |
2464 | 2470 | ||
2465 | adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; | 2471 | adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; |
2466 | for_all_rx_queues(adapter, rxo, i) { | 2472 | for_all_rx_queues(adapter, rxo, i) { |
@@ -2479,8 +2485,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter) | |||
2479 | } | 2485 | } |
2480 | 2486 | ||
2481 | dev_info(&adapter->pdev->dev, | 2487 | dev_info(&adapter->pdev->dev, |
2482 | "created %d RSS queue(s) and 1 default RX queue\n", | 2488 | "created %d RX queue(s)\n", adapter->num_rx_qs); |
2483 | adapter->num_rx_qs - 1); | ||
2484 | return 0; | 2489 | return 0; |
2485 | } | 2490 | } |
2486 | 2491 | ||
@@ -3110,12 +3115,14 @@ static int be_rx_qs_create(struct be_adapter *adapter) | |||
3110 | return rc; | 3115 | return rc; |
3111 | } | 3116 | } |
3112 | 3117 | ||
3113 | /* The FW would like the default RXQ to be created first */ | 3118 | if (adapter->need_def_rxq || !adapter->num_rss_qs) { |
3114 | rxo = default_rxo(adapter); | 3119 | rxo = default_rxo(adapter); |
3115 | rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, rx_frag_size, | 3120 | rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, |
3116 | adapter->if_handle, false, &rxo->rss_id); | 3121 | rx_frag_size, adapter->if_handle, |
3117 | if (rc) | 3122 | false, &rxo->rss_id); |
3118 | return rc; | 3123 | if (rc) |
3124 | return rc; | ||
3125 | } | ||
3119 | 3126 | ||
3120 | for_all_rss_queues(adapter, rxo, i) { | 3127 | for_all_rss_queues(adapter, rxo, i) { |
3121 | rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, | 3128 | rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, |
@@ -3126,8 +3133,7 @@ static int be_rx_qs_create(struct be_adapter *adapter) | |||
3126 | } | 3133 | } |
3127 | 3134 | ||
3128 | if (be_multi_rxq(adapter)) { | 3135 | if (be_multi_rxq(adapter)) { |
3129 | for (j = 0; j < RSS_INDIR_TABLE_LEN; | 3136 | for (j = 0; j < RSS_INDIR_TABLE_LEN; j += adapter->num_rss_qs) { |
3130 | j += adapter->num_rx_qs - 1) { | ||
3131 | for_all_rss_queues(adapter, rxo, i) { | 3137 | for_all_rss_queues(adapter, rxo, i) { |
3132 | if ((j + i) >= RSS_INDIR_TABLE_LEN) | 3138 | if ((j + i) >= RSS_INDIR_TABLE_LEN) |
3133 | break; | 3139 | break; |
@@ -3439,7 +3445,7 @@ static int be_if_create(struct be_adapter *adapter, u32 *if_handle, | |||
3439 | 3445 | ||
3440 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 3446 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | |
3441 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS | | 3447 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS | |
3442 | BE_IF_FLAGS_RSS; | 3448 | BE_IF_FLAGS_RSS | BE_IF_FLAGS_DEFQ_RSS; |
3443 | 3449 | ||
3444 | en_flags &= cap_flags; | 3450 | en_flags &= cap_flags; |
3445 | 3451 | ||
@@ -3649,6 +3655,7 @@ static void BEx_get_resources(struct be_adapter *adapter, | |||
3649 | res->max_evt_qs = 1; | 3655 | res->max_evt_qs = 1; |
3650 | 3656 | ||
3651 | res->if_cap_flags = BE_IF_CAP_FLAGS_WANT; | 3657 | res->if_cap_flags = BE_IF_CAP_FLAGS_WANT; |
3658 | res->if_cap_flags &= ~BE_IF_FLAGS_DEFQ_RSS; | ||
3652 | if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS)) | 3659 | if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS)) |
3653 | res->if_cap_flags &= ~BE_IF_FLAGS_RSS; | 3660 | res->if_cap_flags &= ~BE_IF_FLAGS_RSS; |
3654 | } | 3661 | } |
@@ -3731,12 +3738,23 @@ static int be_get_resources(struct be_adapter *adapter) | |||
3731 | if (status) | 3738 | if (status) |
3732 | return status; | 3739 | return status; |
3733 | 3740 | ||
3741 | /* If a deafault RXQ must be created, we'll use up one RSSQ*/ | ||
3742 | if (res.max_rss_qs && res.max_rss_qs == res.max_rx_qs && | ||
3743 | !(res.if_cap_flags & BE_IF_FLAGS_DEFQ_RSS)) | ||
3744 | res.max_rss_qs -= 1; | ||
3745 | |||
3734 | /* If RoCE may be enabled stash away half the EQs for RoCE */ | 3746 | /* If RoCE may be enabled stash away half the EQs for RoCE */ |
3735 | if (be_roce_supported(adapter)) | 3747 | if (be_roce_supported(adapter)) |
3736 | res.max_evt_qs /= 2; | 3748 | res.max_evt_qs /= 2; |
3737 | adapter->res = res; | 3749 | adapter->res = res; |
3738 | } | 3750 | } |
3739 | 3751 | ||
3752 | /* If FW supports RSS default queue, then skip creating non-RSS | ||
3753 | * queue for non-IP traffic. | ||
3754 | */ | ||
3755 | adapter->need_def_rxq = (be_if_cap_flags(adapter) & | ||
3756 | BE_IF_FLAGS_DEFQ_RSS) ? 0 : 1; | ||
3757 | |||
3740 | dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n", | 3758 | dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n", |
3741 | be_max_txqs(adapter), be_max_rxqs(adapter), | 3759 | be_max_txqs(adapter), be_max_rxqs(adapter), |
3742 | be_max_rss(adapter), be_max_eqs(adapter), | 3760 | be_max_rss(adapter), be_max_eqs(adapter), |