Commit 1f225031 authored by David S. Miller's avatar David S. Miller

Merge branch 'be2net-fixes'

Sathya Perla says:

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

Patch 1 fixes a FW image compatibility check in the driver that
prevents certain FW images from being flashed on BE3 (not BE3-R)
adapters.

Patch 2 fixes a spin_lock not being released in a failure case in
be_cmd_notify_wait().

Patch 3 includes a workaround to pad packets that are only 32b long or less
to be applicabe to BE3 too. This workaround was currently applied only to
Skyhawk and Lancer chips. Such packets are causing BE3's TX path to stall
on a SR-IOV config.

Patch 4 fixes the be_cmd_get_profile_config() routine to set the pf_num
field in the cmd request. The FW requires this field to be set for it to
return the specific function's descriptors. If not set, the FW returns
the descriptors of all the functions on the device. If the first descriptor
is not what is being queried for, the driver will read wrong data.
This patch fixes this issue by using the GET_CNTL_ATTRIB cmd to query the
real pci_func_num of a function and then uses it in the GET_PROFILE_CONFIG
cmd.

Patch 5 completes an earlier fix that removed the vlan promisc capability
for VFs. The earlier fix did not update the removal of this capability from
the profile descriptor of the VF. This causes the VF driver to request this
capability when it tries to create it's interface at probe time. This could
potentailly cause the VF probe to fail if the FW enforces strict checking of
the flags based on what was provisoned by the PF.  This strict checking is
not being done by FW currently but will be fixed in a future version. This
patch fixes this issue by updating the VF's profile descriptor so that they
match the interface capability flags provisioned by the PF.

Pls consider adding these patches to the net tree. Thanks!
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3bb35ac4 196e3735
...@@ -592,6 +592,7 @@ struct be_adapter { ...@@ -592,6 +592,7 @@ struct be_adapter {
int be_get_temp_freq; int be_get_temp_freq;
struct be_hwmon hwmon_info; struct be_hwmon hwmon_info;
u8 pf_number; u8 pf_number;
u8 pci_func_num;
struct rss_info rss_info; struct rss_info rss_info;
/* Filters for packets that need to be sent to BMC */ /* Filters for packets that need to be sent to BMC */
u32 bmc_filt_mask; u32 bmc_filt_mask;
......
...@@ -851,8 +851,10 @@ static int be_cmd_notify_wait(struct be_adapter *adapter, ...@@ -851,8 +851,10 @@ static int be_cmd_notify_wait(struct be_adapter *adapter,
return status; return status;
dest_wrb = be_cmd_copy(adapter, wrb); dest_wrb = be_cmd_copy(adapter, wrb);
if (!dest_wrb) if (!dest_wrb) {
return -EBUSY; status = -EBUSY;
goto unlock;
}
if (use_mcc(adapter)) if (use_mcc(adapter))
status = be_mcc_notify_wait(adapter); status = be_mcc_notify_wait(adapter);
...@@ -862,6 +864,7 @@ static int be_cmd_notify_wait(struct be_adapter *adapter, ...@@ -862,6 +864,7 @@ static int be_cmd_notify_wait(struct be_adapter *adapter,
if (!status) if (!status)
memcpy(wrb, dest_wrb, sizeof(*wrb)); memcpy(wrb, dest_wrb, sizeof(*wrb));
unlock:
be_cmd_unlock(adapter); be_cmd_unlock(adapter);
return status; return status;
} }
...@@ -1984,6 +1987,8 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value) ...@@ -1984,6 +1987,8 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
be_if_cap_flags(adapter)); be_if_cap_flags(adapter));
} }
flags &= be_if_cap_flags(adapter); flags &= be_if_cap_flags(adapter);
if (!flags)
return -ENOTSUPP;
return __be_cmd_rx_filter(adapter, flags, value); return __be_cmd_rx_filter(adapter, flags, value);
} }
...@@ -2887,6 +2892,7 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter) ...@@ -2887,6 +2892,7 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
if (!status) { if (!status) {
attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr); attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr);
adapter->hba_port_num = attribs->hba_attribs.phy_port; adapter->hba_port_num = attribs->hba_attribs.phy_port;
adapter->pci_func_num = attribs->pci_func_num;
serial_num = attribs->hba_attribs.controller_serial_number; serial_num = attribs->hba_attribs.controller_serial_number;
for (i = 0; i < CNTL_SERIAL_NUM_WORDS; i++) for (i = 0; i < CNTL_SERIAL_NUM_WORDS; i++)
adapter->serial_num[i] = le32_to_cpu(serial_num[i]) & adapter->serial_num[i] = le32_to_cpu(serial_num[i]) &
...@@ -3709,7 +3715,6 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res) ...@@ -3709,7 +3715,6 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
status = -EINVAL; status = -EINVAL;
goto err; goto err;
} }
adapter->pf_number = desc->pf_num; adapter->pf_number = desc->pf_num;
be_copy_nic_desc(res, desc); be_copy_nic_desc(res, desc);
} }
...@@ -3721,7 +3726,10 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res) ...@@ -3721,7 +3726,10 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
return status; return status;
} }
/* Will use MBOX only if MCCQ has not been created */ /* Will use MBOX only if MCCQ has not been created
* non-zero domain => a PF is querying this on behalf of a VF
* zero domain => a PF or a VF is querying this for itself
*/
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 query, u8 domain) struct be_resources *res, u8 query, u8 domain)
{ {
...@@ -3748,10 +3756,15 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, ...@@ -3748,10 +3756,15 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
OPCODE_COMMON_GET_PROFILE_CONFIG, OPCODE_COMMON_GET_PROFILE_CONFIG,
cmd.size, &wrb, &cmd); cmd.size, &wrb, &cmd);
req->hdr.domain = domain;
if (!lancer_chip(adapter)) if (!lancer_chip(adapter))
req->hdr.version = 1; req->hdr.version = 1;
req->type = ACTIVE_PROFILE_TYPE; req->type = ACTIVE_PROFILE_TYPE;
/* When a function is querying profile information relating to
* itself hdr.pf_number must be set to it's pci_func_num + 1
*/
req->hdr.domain = domain;
if (domain == 0)
req->hdr.pf_num = adapter->pci_func_num + 1;
/* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the /* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
* descriptors with all bits set to "1" for the fields which can be * descriptors with all bits set to "1" for the fields which can be
...@@ -3921,12 +3934,16 @@ static void be_fill_vf_res_template(struct be_adapter *adapter, ...@@ -3921,12 +3934,16 @@ static void be_fill_vf_res_template(struct be_adapter *adapter,
vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS | vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS |
BE_IF_FLAGS_DEFQ_RSS); BE_IF_FLAGS_DEFQ_RSS);
} }
nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
} else { } else {
num_vf_qs = 1; 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->rq_count = cpu_to_le16(num_vf_qs);
nic_vft->txq_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->rssq_count = cpu_to_le16(num_vf_qs);
......
...@@ -289,7 +289,9 @@ struct be_cmd_req_hdr { ...@@ -289,7 +289,9 @@ struct be_cmd_req_hdr {
u32 timeout; /* dword 1 */ u32 timeout; /* dword 1 */
u32 request_length; /* dword 2 */ u32 request_length; /* dword 2 */
u8 version; /* dword 3 */ u8 version; /* dword 3 */
u8 rsvd[3]; /* dword 3 */ u8 rsvd1; /* dword 3 */
u8 pf_num; /* dword 3 */
u8 rsvd2; /* dword 3 */
}; };
#define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */ #define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */
...@@ -1652,7 +1654,11 @@ struct mgmt_hba_attribs { ...@@ -1652,7 +1654,11 @@ struct mgmt_hba_attribs {
struct mgmt_controller_attrib { struct mgmt_controller_attrib {
struct mgmt_hba_attribs hba_attribs; struct mgmt_hba_attribs hba_attribs;
u32 rsvd0[10]; u32 rsvd0[2];
u16 rsvd1;
u8 pci_func_num;
u8 rsvd2;
u32 rsvd3[7];
} __packed; } __packed;
struct be_cmd_req_cntl_attribs { struct be_cmd_req_cntl_attribs {
......
...@@ -1123,11 +1123,12 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, ...@@ -1123,11 +1123,12 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
struct sk_buff *skb, struct sk_buff *skb,
struct be_wrb_params *wrb_params) struct be_wrb_params *wrb_params)
{ {
/* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or /* Lancer, SH and BE3 in SRIOV mode have a bug wherein
* less may cause a transmit stall on that port. So the work-around is * packets that are 32b or less may cause a transmit stall
* to pad short packets (<= 32 bytes) to a 36-byte length. * on that port. The workaround is to pad such packets
* (len <= 32 bytes) to a minimum length of 36b.
*/ */
if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) { if (skb->len <= 32) {
if (skb_put_padto(skb, 36)) if (skb_put_padto(skb, 36))
return NULL; return NULL;
} }
...@@ -4205,10 +4206,6 @@ static int be_get_config(struct be_adapter *adapter) ...@@ -4205,10 +4206,6 @@ static int be_get_config(struct be_adapter *adapter)
int status, level; int status, level;
u16 profile_id; u16 profile_id;
status = be_cmd_get_cntl_attributes(adapter);
if (status)
return status;
status = be_cmd_query_fw_cfg(adapter); status = be_cmd_query_fw_cfg(adapter);
if (status) if (status)
return status; return status;
...@@ -4407,6 +4404,11 @@ static int be_setup(struct be_adapter *adapter) ...@@ -4407,6 +4404,11 @@ static int be_setup(struct be_adapter *adapter)
if (!lancer_chip(adapter)) if (!lancer_chip(adapter))
be_cmd_req_native_mode(adapter); be_cmd_req_native_mode(adapter);
/* Need to invoke this cmd first to get the PCI Function Number */
status = be_cmd_get_cntl_attributes(adapter);
if (status)
return status;
if (!BE2_chip(adapter) && be_physfn(adapter)) if (!BE2_chip(adapter) && be_physfn(adapter))
be_alloc_sriov_res(adapter); be_alloc_sriov_res(adapter);
...@@ -4999,7 +5001,15 @@ static bool be_check_ufi_compatibility(struct be_adapter *adapter, ...@@ -4999,7 +5001,15 @@ static bool be_check_ufi_compatibility(struct be_adapter *adapter,
return false; return false;
} }
return (fhdr->asic_type_rev >= adapter->asic_rev); /* In BE3 FW images the "asic_type_rev" field doesn't track the
* asic_rev of the chips it is compatible with.
* When asic_type_rev is 0 the image is compatible only with
* pre-BE3-R chips (asic_rev < 0x10)
*/
if (BEx_chip(adapter) && fhdr->asic_type_rev == 0)
return adapter->asic_rev < 0x10;
else
return (fhdr->asic_type_rev >= adapter->asic_rev);
} }
static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
......
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