summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
diff options
context:
space:
mode:
authorVasundhara Volam <vasundhara-v.volam@broadcom.com>2018-01-17 03:21:14 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-17 14:48:27 -0500
commit91cdda40714178497cbd182261b2ea6ec5cb9276 (patch)
tree94cfc2ec88565a81682cec57d5ff4710d68454d5 /drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
parent92abef361bd233ea2a99db9e9a637626f523f82e (diff)
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: Vasundhara Volam <vasundhara-v.volam@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
index 508e917c7adc..d87faad901fe 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
@@ -135,7 +135,10 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id,
ivi->vf = vf_id;
vf = &bp->pf.vf[vf_id];
- memcpy(&ivi->mac, vf->mac_addr, ETH_ALEN);
+ if (is_valid_ether_addr(vf->mac_addr))
+ 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->min_tx_rate = vf->min_tx_rate;
ivi->vlan = vf->vlan;
@@ -883,17 +886,51 @@ exec_fwd_resp_exit:
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)
{
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 *)vf->hwrm_cmd_req_addr;
+ bool mac_ok = false;
- if (!is_valid_ether_addr(vf->mac_addr) ||
- ether_addr_equal((const u8 *)req->l2_addr, vf->mac_addr))
+ /* VF MAC address must first match PF MAC address, if it is valid.
+ * 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);
- else
- return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size);
+ return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size);
}
static int bnxt_vf_set_link(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);
switch (req_type) {
+ case HWRM_FUNC_VF_CFG:
+ rc = bnxt_vf_store_mac(bp, vf);
+ break;
case HWRM_CFA_L2_FILTER_ALLOC:
rc = bnxt_vf_validate_set_mac(bp, vf);
break;