Skip to content

Commit

Permalink
be2net: create optimal number of queues on SR-IOV config
Browse files Browse the repository at this point in the history
If SR-IOV is enabled in the adapter, the FW distributes queue resources
evenly across the PF and it's VFs. If the user is not interested in enabling
VFs, the queues set aside for VFs are wasted.
This patch adds support for the PF driver to re-configure the resource
distribution in FW based on the number of VFs enabled by the user.
This also allows for supporting RSS queues on VFs, when less number of VFs
are enabled per PF. When maximum number of VFs are enabled, each VF typically
gets only one RXQ.

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>
  • Loading branch information
Vasundhara Volam authored and David S. Miller committed Jul 3, 2014
1 parent 10cccf6 commit bec84e6
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 75 deletions.
8 changes: 4 additions & 4 deletions drivers/net/ethernet/emulex/benet/be.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ struct be_adapter {
u32 flash_status;
struct completion et_cmd_compl;

struct be_resources pool_res; /* resources available for the port */
struct be_resources res; /* resources available for the func */
u16 num_vfs; /* Number of VFs provisioned by PF */
u8 virtfn;
Expand All @@ -524,9 +525,8 @@ struct be_adapter {

#define be_physfn(adapter) (!adapter->virtfn)
#define be_virtfn(adapter) (adapter->virtfn)
#define sriov_enabled(adapter) (adapter->num_vfs > 0)
#define sriov_want(adapter) (be_physfn(adapter) && \
(num_vfs || pci_num_vf(adapter->pdev)))
#define sriov_enabled(adapter) (adapter->num_vfs > 0)

#define for_all_vfs(adapter, vf_cfg, i) \
for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
i++, vf_cfg++)
Expand All @@ -537,7 +537,7 @@ struct be_adapter {
#define be_max_vlans(adapter) (adapter->res.max_vlans)
#define be_max_uc(adapter) (adapter->res.max_uc_mac)
#define be_max_mc(adapter) (adapter->res.max_mcast_mac)
#define be_max_vfs(adapter) (adapter->res.max_vfs)
#define be_max_vfs(adapter) (adapter->pool_res.max_vfs)
#define be_max_rss(adapter) (adapter->res.max_rss_qs)
#define be_max_txqs(adapter) (adapter->res.max_tx_qs)
#define be_max_prio_txqs(adapter) (adapter->res.max_prio_tx_qs)
Expand Down
108 changes: 88 additions & 20 deletions drivers/net/ethernet/emulex/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -3523,38 +3523,39 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
return status;
}

int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
int size, u8 version, u8 domain)
/* Will use MBOX only if MCCQ has not been created */
static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
int size, int count, u8 version, u8 domain)
{
struct be_cmd_req_set_profile_config *req;
struct be_mcc_wrb *wrb;
struct be_mcc_wrb wrb = {0};
struct be_dma_mem cmd;
int status;

spin_lock_bh(&adapter->mcc_lock);

wrb = wrb_from_mccq(adapter);
if (!wrb) {
status = -EBUSY;
goto err;
}
memset(&cmd, 0, sizeof(struct be_dma_mem));
cmd.size = sizeof(struct be_cmd_req_set_profile_config);
cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
if (!cmd.va)
return -ENOMEM;

req = embedded_payload(wrb);
req = cmd.va;
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req),
wrb, NULL);
OPCODE_COMMON_SET_PROFILE_CONFIG, cmd.size,
&wrb, &cmd);
req->hdr.version = version;
req->hdr.domain = domain;
req->desc_count = cpu_to_le32(1);
req->desc_count = cpu_to_le32(count);
memcpy(req->desc, desc, size);

status = be_mcc_notify_wait(adapter);
err:
spin_unlock_bh(&adapter->mcc_lock);
status = be_cmd_notify_wait(adapter, &wrb);

if (cmd.va)
pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
return status;
}

/* Mark all fields invalid */
void be_reset_nic_desc(struct be_nic_res_desc *nic)
static void be_reset_nic_desc(struct be_nic_res_desc *nic)
{
memset(nic, 0, sizeof(*nic));
nic->unicast_mac_count = 0xFFFF;
Expand All @@ -3575,9 +3576,20 @@ void be_reset_nic_desc(struct be_nic_res_desc *nic)
nic->wol_param = 0x0F;
nic->tunnel_iface_count = 0xFFFF;
nic->direct_tenant_iface_count = 0xFFFF;
nic->bw_min = 0xFFFFFFFF;
nic->bw_max = 0xFFFFFFFF;
}

/* Mark all fields invalid */
static void be_reset_pcie_desc(struct be_pcie_res_desc *pcie)
{
memset(pcie, 0, sizeof(*pcie));
pcie->sriov_state = 0xFF;
pcie->pf_state = 0xFF;
pcie->pf_type = 0xFF;
pcie->num_vfs = 0xFFFF;
}

int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
u8 domain)
{
Expand Down Expand Up @@ -3608,7 +3620,63 @@ int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,

return be_cmd_set_profile_config(adapter, &nic_desc,
nic_desc.hdr.desc_len,
version, domain);
1, version, domain);
}

int be_cmd_set_sriov_config(struct be_adapter *adapter,
struct be_resources res, u16 num_vfs)
{
struct {
struct be_pcie_res_desc pcie;
struct be_nic_res_desc nic_vft;
} __packed desc;
u16 vf_q_count;

if (BEx_chip(adapter) || lancer_chip(adapter))
return 0;

/* PF PCIE descriptor */
be_reset_pcie_desc(&desc.pcie);
desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1;
desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
desc.pcie.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
desc.pcie.pf_num = adapter->pdev->devfn;
desc.pcie.sriov_state = num_vfs ? 1 : 0;
desc.pcie.num_vfs = cpu_to_le16(num_vfs);

/* VF NIC Template descriptor */
be_reset_nic_desc(&desc.nic_vft);
desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
desc.nic_vft.flags = (1 << VFT_SHIFT) | (1 << IMM_SHIFT) |
(1 << NOSV_SHIFT);
desc.nic_vft.pf_num = adapter->pdev->devfn;
desc.nic_vft.vf_num = 0;

if (num_vfs && res.vf_if_cap_flags & BE_IF_FLAGS_RSS) {
/* If number of VFs requested is 8 less than max supported,
* 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,
2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0);
}

int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
Expand Down Expand Up @@ -3660,7 +3728,7 @@ int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port)
}

return be_cmd_set_profile_config(adapter, &port_desc,
RESOURCE_DESC_SIZE_V1, 1, 0);
RESOURCE_DESC_SIZE_V1, 1, 1, 0);
}

int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/ethernet/emulex/benet/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -1963,8 +1963,8 @@ struct be_cmd_req_set_profile_config {
struct be_cmd_req_hdr hdr;
u32 rsvd;
u32 desc_count;
u8 desc[RESOURCE_DESC_SIZE_V1];
};
u8 desc[2 * RESOURCE_DESC_SIZE_V1];
} __packed;

struct be_cmd_resp_set_profile_config {
struct be_cmd_resp_hdr hdr;
Expand Down Expand Up @@ -2158,8 +2158,6 @@ int be_cmd_get_func_config(struct be_adapter *adapter,
struct be_resources *res);
int be_cmd_get_profile_config(struct be_adapter *adapter,
struct be_resources *res, u8 domain);
int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
int size, u8 version, u8 domain);
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 vf_num);
Expand All @@ -2169,3 +2167,5 @@ int be_cmd_set_logical_link_config(struct be_adapter *adapter,
int link_state, u8 domain);
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_set_sriov_config(struct be_adapter *adapter,
struct be_resources res, u16 num_vfs);
Loading

0 comments on commit bec84e6

Please sign in to comment.