forked from Minki/linux
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>
This commit is contained in:
commit
eb1ac820c6
@ -411,6 +411,7 @@ struct be_resources {
|
||||
u16 max_vlans; /* Number of vlans supported */
|
||||
u16 max_evt_qs;
|
||||
u32 if_cap_flags;
|
||||
u32 vf_if_cap_flags; /* VF if capability flags */
|
||||
};
|
||||
|
||||
struct rss_info {
|
||||
@ -500,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;
|
||||
@ -523,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++)
|
||||
@ -536,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)
|
||||
|
@ -3313,15 +3313,28 @@ err:
|
||||
return status;
|
||||
}
|
||||
|
||||
static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count)
|
||||
/* Descriptor type */
|
||||
enum {
|
||||
FUNC_DESC = 1,
|
||||
VFT_DESC = 2
|
||||
};
|
||||
|
||||
static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count,
|
||||
int desc_type)
|
||||
{
|
||||
struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
|
||||
struct be_nic_res_desc *nic;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < desc_count; i++) {
|
||||
if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
|
||||
hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1)
|
||||
return (struct be_nic_res_desc *)hdr;
|
||||
hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1) {
|
||||
nic = (struct be_nic_res_desc *)hdr;
|
||||
if (desc_type == FUNC_DESC ||
|
||||
(desc_type == VFT_DESC &&
|
||||
nic->flags & (1 << VFT_SHIFT)))
|
||||
return nic;
|
||||
}
|
||||
|
||||
hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
|
||||
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)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct be_nic_res_desc *be_get_vft_desc(u8 *buf, u32 desc_count)
|
||||
{
|
||||
return be_get_nic_desc(buf, desc_count, VFT_DESC);
|
||||
}
|
||||
|
||||
static struct be_nic_res_desc *be_get_func_nic_desc(u8 *buf, u32 desc_count)
|
||||
{
|
||||
return be_get_nic_desc(buf, desc_count, FUNC_DESC);
|
||||
}
|
||||
|
||||
static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
|
||||
u32 desc_count)
|
||||
{
|
||||
@ -3424,7 +3447,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
|
||||
u32 desc_count = le32_to_cpu(resp->desc_count);
|
||||
struct be_nic_res_desc *desc;
|
||||
|
||||
desc = be_get_nic_desc(resp->func_param, desc_count);
|
||||
desc = be_get_func_nic_desc(resp->func_param, desc_count);
|
||||
if (!desc) {
|
||||
status = -EINVAL;
|
||||
goto err;
|
||||
@ -3440,76 +3463,17 @@ err:
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Uses mbox */
|
||||
static int be_cmd_get_profile_config_mbox(struct be_adapter *adapter,
|
||||
u8 domain, struct be_dma_mem *cmd)
|
||||
{
|
||||
struct be_mcc_wrb *wrb;
|
||||
struct be_cmd_req_get_profile_config *req;
|
||||
int status;
|
||||
|
||||
if (mutex_lock_interruptible(&adapter->mbox_lock))
|
||||
return -1;
|
||||
wrb = wrb_from_mbox(adapter);
|
||||
|
||||
req = cmd->va;
|
||||
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
||||
OPCODE_COMMON_GET_PROFILE_CONFIG,
|
||||
cmd->size, wrb, cmd);
|
||||
|
||||
req->type = ACTIVE_PROFILE_TYPE;
|
||||
req->hdr.domain = domain;
|
||||
if (!lancer_chip(adapter))
|
||||
req->hdr.version = 1;
|
||||
|
||||
status = be_mbox_notify_wait(adapter);
|
||||
|
||||
mutex_unlock(&adapter->mbox_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Uses sync mcc */
|
||||
static int be_cmd_get_profile_config_mccq(struct be_adapter *adapter,
|
||||
u8 domain, struct be_dma_mem *cmd)
|
||||
{
|
||||
struct be_mcc_wrb *wrb;
|
||||
struct be_cmd_req_get_profile_config *req;
|
||||
int status;
|
||||
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
status = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
req = cmd->va;
|
||||
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
||||
OPCODE_COMMON_GET_PROFILE_CONFIG,
|
||||
cmd->size, wrb, cmd);
|
||||
|
||||
req->type = ACTIVE_PROFILE_TYPE;
|
||||
req->hdr.domain = domain;
|
||||
if (!lancer_chip(adapter))
|
||||
req->hdr.version = 1;
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
|
||||
err:
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Uses sync mcc, if MCCQ is already created otherwise mbox */
|
||||
/* Will use MBOX only if MCCQ has not been created */
|
||||
int be_cmd_get_profile_config(struct be_adapter *adapter,
|
||||
struct be_resources *res, u8 domain)
|
||||
{
|
||||
struct be_cmd_resp_get_profile_config *resp;
|
||||
struct be_cmd_req_get_profile_config *req;
|
||||
struct be_nic_res_desc *vf_res;
|
||||
struct be_pcie_res_desc *pcie;
|
||||
struct be_port_res_desc *port;
|
||||
struct be_nic_res_desc *nic;
|
||||
struct be_queue_info *mccq = &adapter->mcc_obj.q;
|
||||
struct be_mcc_wrb wrb = {0};
|
||||
struct be_dma_mem cmd;
|
||||
u32 desc_count;
|
||||
int status;
|
||||
@ -3520,10 +3484,17 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
|
||||
if (!cmd.va)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!mccq->created)
|
||||
status = be_cmd_get_profile_config_mbox(adapter, domain, &cmd);
|
||||
else
|
||||
status = be_cmd_get_profile_config_mccq(adapter, domain, &cmd);
|
||||
req = cmd.va;
|
||||
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
||||
OPCODE_COMMON_GET_PROFILE_CONFIG,
|
||||
cmd.size, &wrb, &cmd);
|
||||
|
||||
req->hdr.domain = domain;
|
||||
if (!lancer_chip(adapter))
|
||||
req->hdr.version = 1;
|
||||
req->type = ACTIVE_PROFILE_TYPE;
|
||||
|
||||
status = be_cmd_notify_wait(adapter, &wrb);
|
||||
if (status)
|
||||
goto err;
|
||||
|
||||
@ -3539,48 +3510,52 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
|
||||
if (port)
|
||||
adapter->mc_type = port->mc_type;
|
||||
|
||||
nic = be_get_nic_desc(resp->func_param, desc_count);
|
||||
nic = be_get_func_nic_desc(resp->func_param, desc_count);
|
||||
if (nic)
|
||||
be_copy_nic_desc(res, nic);
|
||||
|
||||
vf_res = be_get_vft_desc(resp->func_param, desc_count);
|
||||
if (vf_res)
|
||||
res->vf_if_cap_flags = vf_res->cap_flags;
|
||||
err:
|
||||
if (cmd.va)
|
||||
pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
|
||||
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);
|
||||
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;
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
status = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -3601,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)
|
||||
{
|
||||
@ -3634,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)
|
||||
@ -3686,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,
|
||||
|
@ -1835,6 +1835,7 @@ struct be_cmd_req_set_ext_fat_caps {
|
||||
#define PORT_RESOURCE_DESC_TYPE_V1 0x55
|
||||
#define MAX_RESOURCE_DESC 264
|
||||
|
||||
#define VFT_SHIFT 3 /* VF template */
|
||||
#define IMM_SHIFT 6 /* Immediate */
|
||||
#define NOSV_SHIFT 7 /* No save */
|
||||
|
||||
@ -1962,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;
|
||||
@ -2157,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);
|
||||
@ -2168,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);
|
||||
|
@ -1172,20 +1172,15 @@ static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
|
||||
static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
int status = 0;
|
||||
|
||||
/* Packets with VID 0 are always received by Lancer by default */
|
||||
if (lancer_chip(adapter) && vid == 0)
|
||||
goto ret;
|
||||
return 0;
|
||||
|
||||
clear_bit(vid, adapter->vids);
|
||||
status = be_vid_config(adapter);
|
||||
if (!status)
|
||||
adapter->vlans_added--;
|
||||
else
|
||||
set_bit(vid, adapter->vids);
|
||||
ret:
|
||||
return status;
|
||||
adapter->vlans_added--;
|
||||
|
||||
return be_vid_config(adapter);
|
||||
}
|
||||
|
||||
static void be_clear_promisc(struct be_adapter *adapter)
|
||||
@ -3098,6 +3093,13 @@ static int be_clear(struct be_adapter *adapter)
|
||||
if (sriov_enabled(adapter))
|
||||
be_vf_clear(adapter);
|
||||
|
||||
/* Re-configure FW to distribute resources evenly across max-supported
|
||||
* number of VFs, only when VFs are not already enabled.
|
||||
*/
|
||||
if (be_physfn(adapter) && !pci_vfs_assigned(adapter->pdev))
|
||||
be_cmd_set_sriov_config(adapter, adapter->pool_res,
|
||||
pci_sriov_get_totalvfs(adapter->pdev));
|
||||
|
||||
#ifdef CONFIG_BE2NET_VXLAN
|
||||
be_disable_vxlan_offloads(adapter);
|
||||
#endif
|
||||
@ -3170,19 +3172,6 @@ static int be_vf_setup(struct be_adapter *adapter)
|
||||
u32 privileges;
|
||||
|
||||
old_vfs = pci_num_vf(adapter->pdev);
|
||||
if (old_vfs) {
|
||||
dev_info(dev, "%d VFs are already enabled\n", old_vfs);
|
||||
if (old_vfs != num_vfs)
|
||||
dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
|
||||
adapter->num_vfs = old_vfs;
|
||||
} else {
|
||||
if (num_vfs > be_max_vfs(adapter))
|
||||
dev_info(dev, "Device supports %d VFs and not %d\n",
|
||||
be_max_vfs(adapter), num_vfs);
|
||||
adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
|
||||
if (!adapter->num_vfs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = be_vf_setup_init(adapter);
|
||||
if (status)
|
||||
@ -3194,17 +3183,15 @@ static int be_vf_setup(struct be_adapter *adapter)
|
||||
if (status)
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
status = be_vfs_if_create(adapter);
|
||||
if (status)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (old_vfs) {
|
||||
status = be_vfs_mac_query(adapter);
|
||||
if (status)
|
||||
goto err;
|
||||
} else {
|
||||
status = be_vfs_if_create(adapter);
|
||||
if (status)
|
||||
goto err;
|
||||
|
||||
status = be_vf_eth_addr_config(adapter);
|
||||
if (status)
|
||||
goto err;
|
||||
@ -3270,19 +3257,7 @@ static u8 be_convert_mc_type(u32 function_mode)
|
||||
static void BEx_get_resources(struct be_adapter *adapter,
|
||||
struct be_resources *res)
|
||||
{
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
bool use_sriov = false;
|
||||
int max_vfs = 0;
|
||||
|
||||
if (be_physfn(adapter) && BE3_chip(adapter)) {
|
||||
be_cmd_get_profile_config(adapter, res, 0);
|
||||
/* Some old versions of BE3 FW don't report max_vfs value */
|
||||
if (res->max_vfs == 0) {
|
||||
max_vfs = pci_sriov_get_totalvfs(pdev);
|
||||
res->max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0;
|
||||
}
|
||||
use_sriov = res->max_vfs && sriov_want(adapter);
|
||||
}
|
||||
bool use_sriov = adapter->num_vfs ? 1 : 0;
|
||||
|
||||
if (be_physfn(adapter))
|
||||
res->max_uc_mac = BE_UC_PMAC_COUNT;
|
||||
@ -3349,6 +3324,54 @@ static void be_setup_init(struct be_adapter *adapter)
|
||||
adapter->cmd_privileges = MIN_PRIVILEGES;
|
||||
}
|
||||
|
||||
static int be_get_sriov_config(struct be_adapter *adapter)
|
||||
{
|
||||
struct device *dev = &adapter->pdev->dev;
|
||||
struct be_resources res = {0};
|
||||
int status, max_vfs, old_vfs;
|
||||
|
||||
status = be_cmd_get_profile_config(adapter, &res, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
adapter->pool_res = res;
|
||||
|
||||
/* Some old versions of BE3 FW don't report max_vfs value */
|
||||
if (BE3_chip(adapter) && !res.max_vfs) {
|
||||
max_vfs = pci_sriov_get_totalvfs(adapter->pdev);
|
||||
res.max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0;
|
||||
}
|
||||
|
||||
adapter->pool_res.max_vfs = res.max_vfs;
|
||||
pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter));
|
||||
|
||||
if (!be_max_vfs(adapter)) {
|
||||
if (num_vfs)
|
||||
dev_warn(dev, "device doesn't support SRIOV\n");
|
||||
adapter->num_vfs = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* validate num_vfs module param */
|
||||
old_vfs = pci_num_vf(adapter->pdev);
|
||||
if (old_vfs) {
|
||||
dev_info(dev, "%d VFs are already enabled\n", old_vfs);
|
||||
if (old_vfs != num_vfs)
|
||||
dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
|
||||
adapter->num_vfs = old_vfs;
|
||||
} else {
|
||||
if (num_vfs > be_max_vfs(adapter)) {
|
||||
dev_info(dev, "Resources unavailable to init %d VFs\n",
|
||||
num_vfs);
|
||||
dev_info(dev, "Limiting to %d VFs\n",
|
||||
be_max_vfs(adapter));
|
||||
}
|
||||
adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int be_get_resources(struct be_adapter *adapter)
|
||||
{
|
||||
struct device *dev = &adapter->pdev->dev;
|
||||
@ -3374,13 +3397,6 @@ static int be_get_resources(struct be_adapter *adapter)
|
||||
res.max_evt_qs /= 2;
|
||||
adapter->res = res;
|
||||
|
||||
if (be_physfn(adapter)) {
|
||||
status = be_cmd_get_profile_config(adapter, &res, 0);
|
||||
if (status)
|
||||
return status;
|
||||
adapter->res.max_vfs = res.max_vfs;
|
||||
}
|
||||
|
||||
dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n",
|
||||
be_max_txqs(adapter), be_max_rxqs(adapter),
|
||||
be_max_rss(adapter), be_max_eqs(adapter),
|
||||
@ -3393,7 +3409,6 @@ static int be_get_resources(struct be_adapter *adapter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Routine to query per function resource limits */
|
||||
static int be_get_config(struct be_adapter *adapter)
|
||||
{
|
||||
u16 profile_id;
|
||||
@ -3411,6 +3426,26 @@ static int be_get_config(struct be_adapter *adapter)
|
||||
if (!status)
|
||||
dev_info(&adapter->pdev->dev,
|
||||
"Using profile 0x%x\n", profile_id);
|
||||
|
||||
status = be_get_sriov_config(adapter);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* When the HW is in SRIOV capable configuration, the PF-pool
|
||||
* resources are equally distributed across the max-number of
|
||||
* VFs. The user may request only a subset of the max-vfs to be
|
||||
* enabled. Based on num_vfs, redistribute the resources across
|
||||
* num_vfs so that each VF will have access to more number of
|
||||
* resources. This facility is not available in BE3 FW.
|
||||
* Also, this is done by FW in Lancer chip.
|
||||
*/
|
||||
if (!pci_num_vf(adapter->pdev)) {
|
||||
status = be_cmd_set_sriov_config(adapter,
|
||||
adapter->pool_res,
|
||||
adapter->num_vfs);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = be_get_resources(adapter);
|
||||
@ -3596,12 +3631,8 @@ static int be_setup(struct be_adapter *adapter)
|
||||
be_cmd_set_logical_link_config(adapter,
|
||||
IFLA_VF_LINK_STATE_AUTO, 0);
|
||||
|
||||
if (sriov_want(adapter)) {
|
||||
if (be_max_vfs(adapter))
|
||||
be_vf_setup(adapter);
|
||||
else
|
||||
dev_warn(dev, "device doesn't support SRIOV\n");
|
||||
}
|
||||
if (adapter->num_vfs)
|
||||
be_vf_setup(adapter);
|
||||
|
||||
status = be_cmd_get_phy_info(adapter);
|
||||
if (!status && be_pause_supported(adapter))
|
||||
|
Loading…
Reference in New Issue
Block a user