Commit c473463c authored by David S. Miller's avatar David S. Miller

Merge branch 'be2net-next'

Sathya Perla says:

====================
be2net: patch set

Hi Dave, the following patch set includes three feature additions relating
to SR-IOV to be2net.

Patch 1 avoid creating a non-RSS default RXQ when FW allows it.
This prevents wasting one RXQ for each VF.

Patch 2 adds support for evenly distributing all queue & filter resources
across VFs. The FW informs the driver as to which resources are distributable.

Patch 3 implements the sriov_configure PCI method to allow runtime
enablement of VFs via sysfs.

Pls consider applying this patch-set to the net-next tree. Thanks!
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 28811a8c ace40aff
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
#define BE3_MAX_EVT_QS 16 #define BE3_MAX_EVT_QS 16
#define BE3_SRIOV_MAX_EVT_QS 8 #define BE3_SRIOV_MAX_EVT_QS 8
#define MAX_RSS_IFACES 15
#define MAX_RX_QS 32 #define MAX_RX_QS 32
#define MAX_EVT_QS 32 #define MAX_EVT_QS 32
#define MAX_TX_QS 32 #define MAX_TX_QS 32
...@@ -411,8 +412,11 @@ struct be_resources { ...@@ -411,8 +412,11 @@ struct be_resources {
u16 max_tx_qs; u16 max_tx_qs;
u16 max_rss_qs; u16 max_rss_qs;
u16 max_rx_qs; u16 max_rx_qs;
u16 max_cq_count;
u16 max_uc_mac; /* Max UC MACs programmable */ u16 max_uc_mac; /* Max UC MACs programmable */
u16 max_vlans; /* Number of vlans supported */ u16 max_vlans; /* Number of vlans supported */
u16 max_iface_count;
u16 max_mcc_count;
u16 max_evt_qs; u16 max_evt_qs;
u32 if_cap_flags; u32 if_cap_flags;
u32 vf_if_cap_flags; /* VF if capability flags */ u32 vf_if_cap_flags; /* VF if capability flags */
...@@ -488,6 +492,8 @@ struct be_adapter { ...@@ -488,6 +492,8 @@ struct be_adapter {
/* Rx rings */ /* Rx rings */
u16 num_rx_qs; u16 num_rx_qs;
u16 num_rss_qs;
u16 need_def_rxq;
struct be_rx_obj rx_obj[MAX_RX_QS]; struct be_rx_obj rx_obj[MAX_RX_QS];
u32 big_page_size; /* Compounded page size shared by rx wrbs */ u32 big_page_size; /* Compounded page size shared by rx wrbs */
...@@ -635,9 +641,8 @@ extern const struct ethtool_ops be_ethtool_ops; ...@@ -635,9 +641,8 @@ extern const struct ethtool_ops be_ethtool_ops;
for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \ for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \
i++, rxo++) i++, rxo++)
/* Skip the default non-rss queue (last one)*/
#define for_all_rss_queues(adapter, rxo, i) \ #define for_all_rss_queues(adapter, rxo, i) \
for (i = 0, rxo = &adapter->rx_obj[i]; i < (adapter->num_rx_qs - 1);\ for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rss_qs; \
i++, rxo++) i++, rxo++)
#define for_all_tx_queues(adapter, txo, i) \ #define for_all_tx_queues(adapter, txo, i) \
......
...@@ -3577,12 +3577,12 @@ static void be_copy_nic_desc(struct be_resources *res, ...@@ -3577,12 +3577,12 @@ static void be_copy_nic_desc(struct be_resources *res,
res->max_rss_qs = le16_to_cpu(desc->rssq_count); res->max_rss_qs = le16_to_cpu(desc->rssq_count);
res->max_rx_qs = le16_to_cpu(desc->rq_count); res->max_rx_qs = le16_to_cpu(desc->rq_count);
res->max_evt_qs = le16_to_cpu(desc->eq_count); res->max_evt_qs = le16_to_cpu(desc->eq_count);
res->max_cq_count = le16_to_cpu(desc->cq_count);
res->max_iface_count = le16_to_cpu(desc->iface_count);
res->max_mcc_count = le16_to_cpu(desc->mcc_count);
/* Clear flags that driver is not interested in */ /* Clear flags that driver is not interested in */
res->if_cap_flags = le32_to_cpu(desc->cap_flags) & res->if_cap_flags = le32_to_cpu(desc->cap_flags) &
BE_IF_CAP_FLAGS_WANT; BE_IF_CAP_FLAGS_WANT;
/* Need 1 RXQ as the default RXQ */
if (res->max_rss_qs && res->max_rss_qs == res->max_rx_qs)
res->max_rss_qs -= 1;
} }
/* Uses Mbox */ /* Uses Mbox */
...@@ -3644,7 +3644,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res) ...@@ -3644,7 +3644,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
/* Will use MBOX only if MCCQ has not been created */ /* Will use MBOX only if MCCQ has not been created */
int be_cmd_get_profile_config(struct be_adapter *adapter, int be_cmd_get_profile_config(struct be_adapter *adapter,
struct be_resources *res, u8 domain) struct be_resources *res, u8 query, u8 domain)
{ {
struct be_cmd_resp_get_profile_config *resp; struct be_cmd_resp_get_profile_config *resp;
struct be_cmd_req_get_profile_config *req; struct be_cmd_req_get_profile_config *req;
...@@ -3654,7 +3654,7 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, ...@@ -3654,7 +3654,7 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
struct be_nic_res_desc *nic; struct be_nic_res_desc *nic;
struct be_mcc_wrb wrb = {0}; struct be_mcc_wrb wrb = {0};
struct be_dma_mem cmd; struct be_dma_mem cmd;
u32 desc_count; u16 desc_count;
int status; int status;
memset(&cmd, 0, sizeof(struct be_dma_mem)); memset(&cmd, 0, sizeof(struct be_dma_mem));
...@@ -3673,12 +3673,19 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, ...@@ -3673,12 +3673,19 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
req->hdr.version = 1; req->hdr.version = 1;
req->type = ACTIVE_PROFILE_TYPE; req->type = ACTIVE_PROFILE_TYPE;
/* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
* descriptors with all bits set to "1" for the fields which can be
* modified using SET_PROFILE_CONFIG cmd.
*/
if (query == RESOURCE_MODIFIABLE)
req->type |= QUERY_MODIFIABLE_FIELDS_TYPE;
status = be_cmd_notify_wait(adapter, &wrb); status = be_cmd_notify_wait(adapter, &wrb);
if (status) if (status)
goto err; goto err;
resp = cmd.va; resp = cmd.va;
desc_count = le32_to_cpu(resp->desc_count); desc_count = le16_to_cpu(resp->desc_count);
pcie = be_get_pcie_desc(adapter->pdev->devfn, resp->func_param, pcie = be_get_pcie_desc(adapter->pdev->devfn, resp->func_param,
desc_count); desc_count);
...@@ -3803,23 +3810,80 @@ int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed, ...@@ -3803,23 +3810,80 @@ int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
1, version, domain); 1, version, domain);
} }
static void be_fill_vf_res_template(struct be_adapter *adapter,
struct be_resources pool_res,
u16 num_vfs, u16 num_vf_qs,
struct be_nic_res_desc *nic_vft)
{
u32 vf_if_cap_flags = pool_res.vf_if_cap_flags;
struct be_resources res_mod = {0};
/* Resource with fields set to all '1's by GET_PROFILE_CONFIG cmd,
* which are modifiable using SET_PROFILE_CONFIG cmd.
*/
be_cmd_get_profile_config(adapter, &res_mod, RESOURCE_MODIFIABLE, 0);
/* If RSS IFACE capability flags are modifiable for a VF, set the
* capability flag as valid and set RSS and DEFQ_RSS IFACE flags if
* more than 1 RSSQ is available for a VF.
* Otherwise, provision only 1 queue pair for VF.
*/
if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_RSS) {
nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT);
if (num_vf_qs > 1) {
vf_if_cap_flags |= BE_IF_FLAGS_RSS;
if (pool_res.if_cap_flags & BE_IF_FLAGS_DEFQ_RSS)
vf_if_cap_flags |= BE_IF_FLAGS_DEFQ_RSS;
} else {
vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS |
BE_IF_FLAGS_DEFQ_RSS);
}
nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
} else {
num_vf_qs = 1;
}
nic_vft->rq_count = cpu_to_le16(num_vf_qs);
nic_vft->txq_count = cpu_to_le16(num_vf_qs);
nic_vft->rssq_count = cpu_to_le16(num_vf_qs);
nic_vft->cq_count = cpu_to_le16(pool_res.max_cq_count /
(num_vfs + 1));
/* Distribute unicast MACs, VLANs, IFACE count and MCCQ count equally
* among the PF and it's VFs, if the fields are changeable
*/
if (res_mod.max_uc_mac == FIELD_MODIFIABLE)
nic_vft->unicast_mac_count = cpu_to_le16(pool_res.max_uc_mac /
(num_vfs + 1));
if (res_mod.max_vlans == FIELD_MODIFIABLE)
nic_vft->vlan_count = cpu_to_le16(pool_res.max_vlans /
(num_vfs + 1));
if (res_mod.max_iface_count == FIELD_MODIFIABLE)
nic_vft->iface_count = cpu_to_le16(pool_res.max_iface_count /
(num_vfs + 1));
if (res_mod.max_mcc_count == FIELD_MODIFIABLE)
nic_vft->mcc_count = cpu_to_le16(pool_res.max_mcc_count /
(num_vfs + 1));
}
int be_cmd_set_sriov_config(struct be_adapter *adapter, int be_cmd_set_sriov_config(struct be_adapter *adapter,
struct be_resources res, u16 num_vfs) struct be_resources pool_res, u16 num_vfs,
u16 num_vf_qs)
{ {
struct { struct {
struct be_pcie_res_desc pcie; struct be_pcie_res_desc pcie;
struct be_nic_res_desc nic_vft; struct be_nic_res_desc nic_vft;
} __packed desc; } __packed desc;
u16 vf_q_count;
if (BEx_chip(adapter) || lancer_chip(adapter))
return 0;
/* PF PCIE descriptor */ /* PF PCIE descriptor */
be_reset_pcie_desc(&desc.pcie); be_reset_pcie_desc(&desc.pcie);
desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1; desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1;
desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1; desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
desc.pcie.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT); desc.pcie.flags = BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
desc.pcie.pf_num = adapter->pdev->devfn; desc.pcie.pf_num = adapter->pdev->devfn;
desc.pcie.sriov_state = num_vfs ? 1 : 0; desc.pcie.sriov_state = num_vfs ? 1 : 0;
desc.pcie.num_vfs = cpu_to_le16(num_vfs); desc.pcie.num_vfs = cpu_to_le16(num_vfs);
...@@ -3828,32 +3892,12 @@ int be_cmd_set_sriov_config(struct be_adapter *adapter, ...@@ -3828,32 +3892,12 @@ int be_cmd_set_sriov_config(struct be_adapter *adapter,
be_reset_nic_desc(&desc.nic_vft); be_reset_nic_desc(&desc.nic_vft);
desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1; desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1; desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
desc.nic_vft.flags = (1 << VFT_SHIFT) | (1 << IMM_SHIFT) | desc.nic_vft.flags = BIT(VFT_SHIFT) | BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
(1 << NOSV_SHIFT);
desc.nic_vft.pf_num = adapter->pdev->devfn; desc.nic_vft.pf_num = adapter->pdev->devfn;
desc.nic_vft.vf_num = 0; desc.nic_vft.vf_num = 0;
if (num_vfs && res.vf_if_cap_flags & BE_IF_FLAGS_RSS) { be_fill_vf_res_template(adapter, pool_res, num_vfs, num_vf_qs,
/* If number of VFs requested is 8 less than max supported, &desc.nic_vft);
* assign 8 queue pairs to the PF and divide the remaining
* resources evenly among the VFs
*/
if (num_vfs < (be_max_vfs(adapter) - 8))
vf_q_count = (res.max_rss_qs - 8) / num_vfs;
else
vf_q_count = res.max_rss_qs / num_vfs;
desc.nic_vft.rq_count = cpu_to_le16(vf_q_count);
desc.nic_vft.txq_count = cpu_to_le16(vf_q_count);
desc.nic_vft.rssq_count = cpu_to_le16(vf_q_count - 1);
desc.nic_vft.cq_count = cpu_to_le16(3 * vf_q_count);
} else {
desc.nic_vft.txq_count = cpu_to_le16(1);
desc.nic_vft.rq_count = cpu_to_le16(1);
desc.nic_vft.rssq_count = cpu_to_le16(0);
/* One CQ for each TX, RX and MCCQ */
desc.nic_vft.cq_count = cpu_to_le16(3);
}
return be_cmd_set_profile_config(adapter, &desc, return be_cmd_set_profile_config(adapter, &desc,
2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0); 2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0);
......
...@@ -588,14 +588,15 @@ enum be_if_flags { ...@@ -588,14 +588,15 @@ enum be_if_flags {
BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200,
BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, BE_IF_FLAGS_PASS_L2_ERRORS = 0x400,
BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800, BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800,
BE_IF_FLAGS_MULTICAST = 0x1000 BE_IF_FLAGS_MULTICAST = 0x1000,
BE_IF_FLAGS_DEFQ_RSS = 0x1000000
}; };
#define BE_IF_CAP_FLAGS_WANT (BE_IF_FLAGS_RSS | BE_IF_FLAGS_PROMISCUOUS |\ #define BE_IF_CAP_FLAGS_WANT (BE_IF_FLAGS_RSS | BE_IF_FLAGS_PROMISCUOUS |\
BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_VLAN_PROMISCUOUS |\ BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_VLAN_PROMISCUOUS |\
BE_IF_FLAGS_VLAN | BE_IF_FLAGS_MCAST_PROMISCUOUS |\ BE_IF_FLAGS_VLAN | BE_IF_FLAGS_MCAST_PROMISCUOUS |\
BE_IF_FLAGS_PASS_L3L4_ERRORS | BE_IF_FLAGS_MULTICAST |\ BE_IF_FLAGS_PASS_L3L4_ERRORS | BE_IF_FLAGS_MULTICAST |\
BE_IF_FLAGS_UNTAGGED) BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_DEFQ_RSS)
#define BE_IF_FLAGS_ALL_PROMISCUOUS (BE_IF_FLAGS_PROMISCUOUS | \ #define BE_IF_FLAGS_ALL_PROMISCUOUS (BE_IF_FLAGS_PROMISCUOUS | \
BE_IF_FLAGS_VLAN_PROMISCUOUS |\ BE_IF_FLAGS_VLAN_PROMISCUOUS |\
...@@ -2021,6 +2022,7 @@ struct be_cmd_req_set_ext_fat_caps { ...@@ -2021,6 +2022,7 @@ struct be_cmd_req_set_ext_fat_caps {
#define PORT_RESOURCE_DESC_TYPE_V1 0x55 #define PORT_RESOURCE_DESC_TYPE_V1 0x55
#define MAX_RESOURCE_DESC 264 #define MAX_RESOURCE_DESC 264
#define IF_CAPS_FLAGS_VALID_SHIFT 0 /* IF caps valid */
#define VFT_SHIFT 3 /* VF template */ #define VFT_SHIFT 3 /* VF template */
#define IMM_SHIFT 6 /* Immediate */ #define IMM_SHIFT 6 /* Immediate */
#define NOSV_SHIFT 7 /* No save */ #define NOSV_SHIFT 7 /* No save */
...@@ -2131,20 +2133,28 @@ struct be_cmd_resp_get_func_config { ...@@ -2131,20 +2133,28 @@ struct be_cmd_resp_get_func_config {
u8 func_param[MAX_RESOURCE_DESC * RESOURCE_DESC_SIZE_V1]; u8 func_param[MAX_RESOURCE_DESC * RESOURCE_DESC_SIZE_V1];
}; };
#define ACTIVE_PROFILE_TYPE 0x2 enum {
RESOURCE_LIMITS,
RESOURCE_MODIFIABLE
};
struct be_cmd_req_get_profile_config { struct be_cmd_req_get_profile_config {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
u8 rsvd; u8 rsvd;
#define ACTIVE_PROFILE_TYPE 0x2
#define QUERY_MODIFIABLE_FIELDS_TYPE BIT(3)
u8 type; u8 type;
u16 rsvd1; u16 rsvd1;
}; };
struct be_cmd_resp_get_profile_config { struct be_cmd_resp_get_profile_config {
struct be_cmd_resp_hdr hdr; struct be_cmd_resp_hdr hdr;
u32 desc_count; __le16 desc_count;
u16 rsvd;
u8 func_param[MAX_RESOURCE_DESC * RESOURCE_DESC_SIZE_V1]; u8 func_param[MAX_RESOURCE_DESC * RESOURCE_DESC_SIZE_V1];
}; };
#define FIELD_MODIFIABLE 0xFFFF
struct be_cmd_req_set_profile_config { struct be_cmd_req_set_profile_config {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
u32 rsvd; u32 rsvd;
...@@ -2344,7 +2354,7 @@ int be_cmd_query_port_name(struct be_adapter *adapter); ...@@ -2344,7 +2354,7 @@ int be_cmd_query_port_name(struct be_adapter *adapter);
int be_cmd_get_func_config(struct be_adapter *adapter, int be_cmd_get_func_config(struct be_adapter *adapter,
struct be_resources *res); struct be_resources *res);
int be_cmd_get_profile_config(struct be_adapter *adapter, int be_cmd_get_profile_config(struct be_adapter *adapter,
struct be_resources *res, u8 domain); struct be_resources *res, u8 query, u8 domain);
int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile); int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile);
int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
int vf_num); int vf_num);
...@@ -2355,4 +2365,5 @@ int be_cmd_set_logical_link_config(struct be_adapter *adapter, ...@@ -2355,4 +2365,5 @@ int be_cmd_set_logical_link_config(struct be_adapter *adapter,
int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port); int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port);
int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op); int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op);
int be_cmd_set_sriov_config(struct be_adapter *adapter, int be_cmd_set_sriov_config(struct be_adapter *adapter,
struct be_resources res, u16 num_vfs); struct be_resources res, u16 num_vfs,
u16 num_vf_qs);
...@@ -1097,7 +1097,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter, ...@@ -1097,7 +1097,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter,
return status; return status;
if (be_multi_rxq(adapter)) { if (be_multi_rxq(adapter)) {
for (j = 0; j < 128; j += adapter->num_rx_qs - 1) { for (j = 0; j < 128; j += adapter->num_rss_qs) {
for_all_rss_queues(adapter, rxo, i) { for_all_rss_queues(adapter, rxo, i) {
if ((j + i) >= 128) if ((j + i) >= 128)
break; break;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment