Commit 28ea334b authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

bnxt_en: Fix VF mac address regression.

The recent commit to always forward the VF MAC address to the PF for
approval may not work if the PF driver or the firmware is older.  This
will cause the VF driver to fail during probe:

  bnxt_en 0000:00:03.0 (unnamed net_device) (uninitialized): hwrm req_type 0xf seq id 0x5 error 0xffff
  bnxt_en 0000:00:03.0 (unnamed net_device) (uninitialized): VF MAC address 00:00:17:02:05:d0 not approved by the PF
  bnxt_en 0000:00:03.0: Unable to initialize mac address.
  bnxt_en: probe of 0000:00:03.0 failed with error -99

We fix it by treating the error as fatal only if the VF MAC address is
locally generated by the VF.

Fixes: 707e7e96 ("bnxt_en: Always forward VF MAC address to the PF.")
Reported-by: default avatarSeth Forshee <seth.forshee@canonical.com>
Reported-by: default avatarSiwei Liu <loseweigh@gmail.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bbd6528d
...@@ -8027,7 +8027,7 @@ static int bnxt_change_mac_addr(struct net_device *dev, void *p) ...@@ -8027,7 +8027,7 @@ static int bnxt_change_mac_addr(struct net_device *dev, void *p)
if (ether_addr_equal(addr->sa_data, dev->dev_addr)) if (ether_addr_equal(addr->sa_data, dev->dev_addr))
return 0; return 0;
rc = bnxt_approve_mac(bp, addr->sa_data); rc = bnxt_approve_mac(bp, addr->sa_data, true);
if (rc) if (rc)
return rc; return rc;
...@@ -8827,14 +8827,19 @@ static int bnxt_init_mac_addr(struct bnxt *bp) ...@@ -8827,14 +8827,19 @@ static int bnxt_init_mac_addr(struct bnxt *bp)
} else { } else {
#ifdef CONFIG_BNXT_SRIOV #ifdef CONFIG_BNXT_SRIOV
struct bnxt_vf_info *vf = &bp->vf; struct bnxt_vf_info *vf = &bp->vf;
bool strict_approval = true;
if (is_valid_ether_addr(vf->mac_addr)) { if (is_valid_ether_addr(vf->mac_addr)) {
/* overwrite netdev dev_addr with admin VF MAC */ /* overwrite netdev dev_addr with admin VF MAC */
memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN); memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
/* Older PF driver or firmware may not approve this
* correctly.
*/
strict_approval = false;
} else { } else {
eth_hw_addr_random(bp->dev); eth_hw_addr_random(bp->dev);
} }
rc = bnxt_approve_mac(bp, bp->dev->dev_addr); rc = bnxt_approve_mac(bp, bp->dev->dev_addr, strict_approval);
#endif #endif
} }
return rc; return rc;
......
...@@ -1104,7 +1104,7 @@ void bnxt_update_vf_mac(struct bnxt *bp) ...@@ -1104,7 +1104,7 @@ void bnxt_update_vf_mac(struct bnxt *bp)
mutex_unlock(&bp->hwrm_cmd_lock); mutex_unlock(&bp->hwrm_cmd_lock);
} }
int bnxt_approve_mac(struct bnxt *bp, u8 *mac) int bnxt_approve_mac(struct bnxt *bp, u8 *mac, bool strict)
{ {
struct hwrm_func_vf_cfg_input req = {0}; struct hwrm_func_vf_cfg_input req = {0};
int rc = 0; int rc = 0;
...@@ -1122,12 +1122,13 @@ int bnxt_approve_mac(struct bnxt *bp, u8 *mac) ...@@ -1122,12 +1122,13 @@ int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
memcpy(req.dflt_mac_addr, mac, ETH_ALEN); memcpy(req.dflt_mac_addr, mac, ETH_ALEN);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
mac_done: mac_done:
if (rc) { if (rc && strict) {
rc = -EADDRNOTAVAIL; rc = -EADDRNOTAVAIL;
netdev_warn(bp->dev, "VF MAC address %pM not approved by the PF\n", netdev_warn(bp->dev, "VF MAC address %pM not approved by the PF\n",
mac); mac);
return rc;
} }
return rc; return 0;
} }
#else #else
...@@ -1144,7 +1145,7 @@ void bnxt_update_vf_mac(struct bnxt *bp) ...@@ -1144,7 +1145,7 @@ void bnxt_update_vf_mac(struct bnxt *bp)
{ {
} }
int bnxt_approve_mac(struct bnxt *bp, u8 *mac) int bnxt_approve_mac(struct bnxt *bp, u8 *mac, bool strict)
{ {
return 0; return 0;
} }
......
...@@ -39,5 +39,5 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs); ...@@ -39,5 +39,5 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs);
void bnxt_sriov_disable(struct bnxt *); void bnxt_sriov_disable(struct bnxt *);
void bnxt_hwrm_exec_fwd_req(struct bnxt *); void bnxt_hwrm_exec_fwd_req(struct bnxt *);
void bnxt_update_vf_mac(struct bnxt *); void bnxt_update_vf_mac(struct bnxt *);
int bnxt_approve_mac(struct bnxt *, u8 *); int bnxt_approve_mac(struct bnxt *, u8 *, bool);
#endif #endif
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