Commit 91cdda40 authored by Vasundhara Volam's avatar Vasundhara Volam Committed by David S. Miller

bnxt_en: Forward VF MAC address to the PF.

Forward hwrm_func_vf_cfg command from VF to PF driver, to store
VF MAC address in PF's context.  This will allow "ip link show"
to display all VF MAC addresses.

Maintain 2 locations of MAC address in VF info structure, one for
a PF assigned MAC and one for VF assigned MAC.

Display VF assigned MAC in "ip link show", only if PF assigned MAC is
not valid.
Signed-off-by: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 92abef36
...@@ -213,6 +213,7 @@ MODULE_DEVICE_TABLE(pci, bnxt_pci_tbl); ...@@ -213,6 +213,7 @@ MODULE_DEVICE_TABLE(pci, bnxt_pci_tbl);
static const u16 bnxt_vf_req_snif[] = { static const u16 bnxt_vf_req_snif[] = {
HWRM_FUNC_CFG, HWRM_FUNC_CFG,
HWRM_FUNC_VF_CFG,
HWRM_PORT_PHY_QCFG, HWRM_PORT_PHY_QCFG,
HWRM_CFA_L2_FILTER_ALLOC, HWRM_CFA_L2_FILTER_ALLOC,
}; };
...@@ -8432,7 +8433,7 @@ static int bnxt_init_mac_addr(struct bnxt *bp) ...@@ -8432,7 +8433,7 @@ static int bnxt_init_mac_addr(struct bnxt *bp)
struct bnxt_vf_info *vf = &bp->vf; struct bnxt_vf_info *vf = &bp->vf;
if (is_valid_ether_addr(vf->mac_addr)) { if (is_valid_ether_addr(vf->mac_addr)) {
/* overwrite netdev dev_adr 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);
} else { } else {
eth_hw_addr_random(bp->dev); eth_hw_addr_random(bp->dev);
......
...@@ -804,7 +804,10 @@ struct bnxt_hw_resc { ...@@ -804,7 +804,10 @@ struct bnxt_hw_resc {
#if defined(CONFIG_BNXT_SRIOV) #if defined(CONFIG_BNXT_SRIOV)
struct bnxt_vf_info { struct bnxt_vf_info {
u16 fw_fid; u16 fw_fid;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN]; /* PF assigned MAC Address */
u8 vf_mac_addr[ETH_ALEN]; /* VF assigned MAC address, only
* stored by PF.
*/
u16 vlan; u16 vlan;
u32 flags; u32 flags;
#define BNXT_VF_QOS 0x1 #define BNXT_VF_QOS 0x1
......
...@@ -135,7 +135,10 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id, ...@@ -135,7 +135,10 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id,
ivi->vf = vf_id; ivi->vf = vf_id;
vf = &bp->pf.vf[vf_id]; vf = &bp->pf.vf[vf_id];
if (is_valid_ether_addr(vf->mac_addr))
memcpy(&ivi->mac, vf->mac_addr, ETH_ALEN); memcpy(&ivi->mac, vf->mac_addr, ETH_ALEN);
else
memcpy(&ivi->mac, vf->vf_mac_addr, ETH_ALEN);
ivi->max_tx_rate = vf->max_tx_rate; ivi->max_tx_rate = vf->max_tx_rate;
ivi->min_tx_rate = vf->min_tx_rate; ivi->min_tx_rate = vf->min_tx_rate;
ivi->vlan = vf->vlan; ivi->vlan = vf->vlan;
...@@ -883,16 +886,50 @@ static int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, struct bnxt_vf_info *vf, ...@@ -883,16 +886,50 @@ static int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, struct bnxt_vf_info *vf,
return rc; return rc;
} }
static int bnxt_vf_store_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
{
u32 msg_size = sizeof(struct hwrm_func_vf_cfg_input);
struct hwrm_func_vf_cfg_input *req =
(struct hwrm_func_vf_cfg_input *)vf->hwrm_cmd_req_addr;
/* Only allow VF to set a valid MAC address if the PF assigned MAC
* address is zero
*/
if (req->enables & cpu_to_le32(FUNC_VF_CFG_REQ_ENABLES_DFLT_MAC_ADDR)) {
if (is_valid_ether_addr(req->dflt_mac_addr) &&
!is_valid_ether_addr(vf->mac_addr)) {
ether_addr_copy(vf->vf_mac_addr, req->dflt_mac_addr);
return bnxt_hwrm_exec_fwd_resp(bp, vf, msg_size);
}
return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size);
}
return bnxt_hwrm_exec_fwd_resp(bp, vf, msg_size);
}
static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf) static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
{ {
u32 msg_size = sizeof(struct hwrm_cfa_l2_filter_alloc_input); u32 msg_size = sizeof(struct hwrm_cfa_l2_filter_alloc_input);
struct hwrm_cfa_l2_filter_alloc_input *req = struct hwrm_cfa_l2_filter_alloc_input *req =
(struct hwrm_cfa_l2_filter_alloc_input *)vf->hwrm_cmd_req_addr; (struct hwrm_cfa_l2_filter_alloc_input *)vf->hwrm_cmd_req_addr;
bool mac_ok = false;
if (!is_valid_ether_addr(vf->mac_addr) || /* VF MAC address must first match PF MAC address, if it is valid.
ether_addr_equal((const u8 *)req->l2_addr, vf->mac_addr)) * Otherwise, it must match the VF MAC address if firmware spec >=
* 1.2.2
*/
if (is_valid_ether_addr(vf->mac_addr)) {
if (ether_addr_equal((const u8 *)req->l2_addr, vf->mac_addr))
mac_ok = true;
} else if (is_valid_ether_addr(vf->vf_mac_addr)) {
if (ether_addr_equal((const u8 *)req->l2_addr, vf->vf_mac_addr))
mac_ok = true;
} else if (bp->hwrm_spec_code < 0x10202) {
mac_ok = true;
} else {
mac_ok = true;
}
if (mac_ok)
return bnxt_hwrm_exec_fwd_resp(bp, vf, msg_size); return bnxt_hwrm_exec_fwd_resp(bp, vf, msg_size);
else
return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size); return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size);
} }
...@@ -955,6 +992,9 @@ static int bnxt_vf_req_validate_snd(struct bnxt *bp, struct bnxt_vf_info *vf) ...@@ -955,6 +992,9 @@ static int bnxt_vf_req_validate_snd(struct bnxt *bp, struct bnxt_vf_info *vf)
u32 req_type = le16_to_cpu(encap_req->req_type); u32 req_type = le16_to_cpu(encap_req->req_type);
switch (req_type) { switch (req_type) {
case HWRM_FUNC_VF_CFG:
rc = bnxt_vf_store_mac(bp, vf);
break;
case HWRM_CFA_L2_FILTER_ALLOC: case HWRM_CFA_L2_FILTER_ALLOC:
rc = bnxt_vf_validate_set_mac(bp, vf); rc = bnxt_vf_validate_set_mac(bp, vf);
break; break;
......
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