Commit 64151ae3 authored by David S. Miller's avatar David S. Miller

Merge branch 'be2net-noncrit-fixes'

Sathya Perla says:

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

Hi David, the following patch set contains three non-critical fixes that
can go into the net-next tree.

Patch 1 fixes the logic for provisioning queue pairs on VFs to take into
account the limit on number of TXQs too as in some profiles the number
of TXQs is less than that of RXQs.

Patch 2 enables WoL support from shutdown on Skyhawk.

Patch 3 enhances the logic for provisioning queue pairs on VFs on
SR-IOV over multi-partition configs. Each PF (partition) on a port has to
compute the number of RSS tables it's VFs can use.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c19b6d24 de2b1e03
......@@ -97,7 +97,8 @@
* SURF/DPDK
*/
#define MAX_RSS_IFACES 15
#define MAX_PORT_RSS_TABLES 15
#define MAX_NIC_FUNCS 16
#define MAX_RX_QS 32
#define MAX_EVT_QS 32
#define MAX_TX_QS 32
......@@ -444,6 +445,17 @@ struct be_resources {
u16 max_evt_qs;
u32 if_cap_flags;
u32 vf_if_cap_flags; /* VF if capability flags */
u32 flags;
/* Calculated PF Pool's share of RSS Tables. This is not enforced by
* the FW, but is a self-imposed driver limitation.
*/
u16 max_rss_tables;
};
/* These are port-wide values */
struct be_port_resources {
u16 max_vfs;
u16 nic_pfs;
};
#define be_is_os2bmc_enabled(adapter) (adapter->flags & BE_FLAGS_OS2BMC)
......@@ -634,6 +646,8 @@ struct be_adapter {
#define be_max_rxqs(adapter) (adapter->res.max_rx_qs)
#define be_max_eqs(adapter) (adapter->res.max_evt_qs)
#define be_if_cap_flags(adapter) (adapter->res.if_cap_flags)
#define be_max_pf_pool_rss_tables(adapter) \
(adapter->pool_res.max_rss_tables)
static inline u16 be_max_qs(struct be_adapter *adapter)
{
......
......@@ -4023,7 +4023,10 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *)cmd.va;
adapter->wol_cap = resp->wol_settings;
if (adapter->wol_cap & BE_WOL_CAP)
/* Non-zero macaddr indicates WOL is enabled */
if (adapter->wol_cap & BE_WOL_CAP &&
!is_zero_ether_addr(resp->magic_mac))
adapter->wol_en = true;
}
err:
......@@ -4360,9 +4363,35 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
return status;
}
/* This routine returns a list of all the NIC PF_nums in the adapter */
u16 be_get_nic_pf_num_list(u8 *buf, u32 desc_count, u16 *nic_pf_nums)
{
struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
struct be_pcie_res_desc *pcie = NULL;
int i;
u16 nic_pf_count = 0;
for (i = 0; i < desc_count; i++) {
if (hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V0 ||
hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V1) {
pcie = (struct be_pcie_res_desc *)hdr;
if (pcie->pf_state && (pcie->pf_type == MISSION_NIC ||
pcie->pf_type == MISSION_RDMA)) {
nic_pf_nums[nic_pf_count++] = pcie->pf_num;
}
}
hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
hdr = (void *)hdr + hdr->desc_len;
}
return nic_pf_count;
}
/* 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 query, u8 domain)
struct be_resources *res,
struct be_port_resources *port_res,
u8 profile_type, u8 query, u8 domain)
{
struct be_cmd_resp_get_profile_config *resp;
struct be_cmd_req_get_profile_config *req;
......@@ -4389,7 +4418,7 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
if (!lancer_chip(adapter))
req->hdr.version = 1;
req->type = ACTIVE_PROFILE_TYPE;
req->type = profile_type;
req->hdr.domain = domain;
/* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
......@@ -4406,6 +4435,28 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
resp = cmd.va;
desc_count = le16_to_cpu(resp->desc_count);
if (port_res) {
u16 nic_pf_cnt = 0, i;
u16 nic_pf_num_list[MAX_NIC_FUNCS];
nic_pf_cnt = be_get_nic_pf_num_list(resp->func_param,
desc_count,
nic_pf_num_list);
for (i = 0; i < nic_pf_cnt; i++) {
nic = be_get_func_nic_desc(resp->func_param, desc_count,
nic_pf_num_list[i]);
if (nic->link_param == adapter->port_num) {
port_res->nic_pfs++;
pcie = be_get_pcie_desc(resp->func_param,
desc_count,
nic_pf_num_list[i]);
port_res->max_vfs += le16_to_cpu(pcie->num_vfs);
}
}
return status;
}
pcie = be_get_pcie_desc(resp->func_param, desc_count,
adapter->pf_num);
if (pcie)
......@@ -4465,7 +4516,7 @@ static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
}
/* Mark all fields invalid */
static void be_reset_nic_desc(struct be_nic_res_desc *nic)
void be_reset_nic_desc(struct be_nic_res_desc *nic)
{
memset(nic, 0, sizeof(*nic));
nic->unicast_mac_count = 0xFFFF;
......@@ -4534,73 +4585,9 @@ int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
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);
}
} else {
num_vf_qs = 1;
}
if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_VLAN_PROMISCUOUS) {
nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT);
vf_if_cap_flags &= ~BE_IF_FLAGS_VLAN_PROMISCUOUS;
}
nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
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,
struct be_resources pool_res, u16 num_vfs,
u16 num_vf_qs)
struct be_resources *vft_res)
{
struct {
struct be_pcie_res_desc pcie;
......@@ -4620,12 +4607,26 @@ int be_cmd_set_sriov_config(struct be_adapter *adapter,
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 = BIT(VFT_SHIFT) | BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
desc.nic_vft.flags = vft_res->flags | BIT(VFT_SHIFT) |
BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
desc.nic_vft.pf_num = adapter->pdev->devfn;
desc.nic_vft.vf_num = 0;
be_fill_vf_res_template(adapter, pool_res, num_vfs, num_vf_qs,
&desc.nic_vft);
desc.nic_vft.cap_flags = cpu_to_le32(vft_res->vf_if_cap_flags);
desc.nic_vft.rq_count = cpu_to_le16(vft_res->max_rx_qs);
desc.nic_vft.txq_count = cpu_to_le16(vft_res->max_tx_qs);
desc.nic_vft.rssq_count = cpu_to_le16(vft_res->max_rss_qs);
desc.nic_vft.cq_count = cpu_to_le16(vft_res->max_cq_count);
if (vft_res->max_uc_mac)
desc.nic_vft.unicast_mac_count =
cpu_to_le16(vft_res->max_uc_mac);
if (vft_res->max_vlans)
desc.nic_vft.vlan_count = cpu_to_le16(vft_res->max_vlans);
if (vft_res->max_iface_count)
desc.nic_vft.iface_count =
cpu_to_le16(vft_res->max_iface_count);
if (vft_res->max_mcc_count)
desc.nic_vft.mcc_count = cpu_to_le16(vft_res->max_mcc_count);
return be_cmd_set_profile_config(adapter, &desc,
2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0);
......
......@@ -1556,7 +1556,9 @@ struct be_cmd_resp_acpi_wol_magic_config_v1 {
u8 rsvd0[2];
u8 wol_settings;
u8 rsvd1[5];
u32 rsvd2[295];
u32 rsvd2[288];
u8 magic_mac[6];
u8 rsvd3[22];
} __packed;
#define BE_GET_WOL_CAP 2
......@@ -2128,6 +2130,9 @@ struct be_cmd_req_set_ext_fat_caps {
#define IMM_SHIFT 6 /* Immediate */
#define NOSV_SHIFT 7 /* No save */
#define MISSION_NIC 1
#define MISSION_RDMA 8
struct be_res_desc_hdr {
u8 desc_type;
u8 desc_len;
......@@ -2244,6 +2249,7 @@ struct be_cmd_req_get_profile_config {
struct be_cmd_req_hdr hdr;
u8 rsvd;
#define ACTIVE_PROFILE_TYPE 0x2
#define SAVED_PROFILE_TYPE 0x0
#define QUERY_MODIFIABLE_FIELDS_TYPE BIT(3)
u8 type;
u16 rsvd1;
......@@ -2449,7 +2455,9 @@ int be_cmd_query_port_name(struct be_adapter *adapter);
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 query, u8 domain);
struct be_resources *res,
struct be_port_resources *port_res,
u8 profile_type, u8 query, 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);
......@@ -2461,4 +2469,4 @@ 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,
u16 num_vf_qs);
struct be_resources *vft_res);
......@@ -793,6 +793,11 @@ static void be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
static int be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct be_adapter *adapter = netdev_priv(netdev);
struct device *dev = &adapter->pdev->dev;
struct be_dma_mem cmd;
u8 mac[ETH_ALEN];
bool enable;
int status;
if (wol->wolopts & ~WAKE_MAGIC)
return -EOPNOTSUPP;
......@@ -802,12 +807,32 @@ static int be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return -EOPNOTSUPP;
}
if (wol->wolopts & WAKE_MAGIC)
adapter->wol_en = true;
else
adapter->wol_en = false;
cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
cmd.va = dma_zalloc_coherent(dev, cmd.size, &cmd.dma, GFP_KERNEL);
if (!cmd.va)
return -ENOMEM;
return 0;
eth_zero_addr(mac);
enable = wol->wolopts & WAKE_MAGIC;
if (enable)
ether_addr_copy(mac, adapter->netdev->dev_addr);
status = be_cmd_enable_magic_wol(adapter, mac, &cmd);
if (status) {
dev_err(dev, "Could not set Wake-on-lan mac address\n");
status = be_cmd_status(status);
goto err;
}
pci_enable_wake(adapter->pdev, PCI_D3hot, enable);
pci_enable_wake(adapter->pdev, PCI_D3cold, enable);
adapter->wol_en = enable ? true : false;
err:
dma_free_coherent(dev, cmd.size, cmd.va, cmd.dma);
return status;
}
static int be_test_ddr_dma(struct be_adapter *adapter)
......
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