Commit 746df139 authored by Vasundhara Volam's avatar Vasundhara Volam Committed by David S. Miller

bnxt_en: Add support for ndo_set_vf_trust

Trusted VFs are allowed to modify MAC address, even when PF
has assigned one.
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 2373d8d6
...@@ -8206,6 +8206,7 @@ static const struct net_device_ops bnxt_netdev_ops = { ...@@ -8206,6 +8206,7 @@ static const struct net_device_ops bnxt_netdev_ops = {
.ndo_set_vf_rate = bnxt_set_vf_bw, .ndo_set_vf_rate = bnxt_set_vf_bw,
.ndo_set_vf_link_state = bnxt_set_vf_link_state, .ndo_set_vf_link_state = bnxt_set_vf_link_state,
.ndo_set_vf_spoofchk = bnxt_set_vf_spoofchk, .ndo_set_vf_spoofchk = bnxt_set_vf_spoofchk,
.ndo_set_vf_trust = bnxt_set_vf_trust,
#endif #endif
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = bnxt_poll_controller, .ndo_poll_controller = bnxt_poll_controller,
......
...@@ -815,6 +815,7 @@ struct bnxt_vf_info { ...@@ -815,6 +815,7 @@ struct bnxt_vf_info {
#define BNXT_VF_SPOOFCHK 0x2 #define BNXT_VF_SPOOFCHK 0x2
#define BNXT_VF_LINK_FORCED 0x4 #define BNXT_VF_LINK_FORCED 0x4
#define BNXT_VF_LINK_UP 0x8 #define BNXT_VF_LINK_UP 0x8
#define BNXT_VF_TRUST 0x10
u32 func_flags; /* func cfg flags */ u32 func_flags; /* func cfg flags */
u32 min_tx_rate; u32 min_tx_rate;
u32 max_tx_rate; u32 max_tx_rate;
......
/* Broadcom NetXtreme-C/E network driver. /* Broadcom NetXtreme-C/E network driver.
* *
* Copyright (c) 2014-2016 Broadcom Corporation * Copyright (c) 2014-2016 Broadcom Corporation
* Copyright (c) 2016-2017 Broadcom Limited * Copyright (c) 2016-2018 Broadcom Limited
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -121,6 +121,23 @@ int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting) ...@@ -121,6 +121,23 @@ int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting)
return rc; return rc;
} }
int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted)
{
struct bnxt *bp = netdev_priv(dev);
struct bnxt_vf_info *vf;
if (bnxt_vf_ndo_prep(bp, vf_id))
return -EINVAL;
vf = &bp->pf.vf[vf_id];
if (trusted)
vf->flags |= BNXT_VF_TRUST;
else
vf->flags &= ~BNXT_VF_TRUST;
return 0;
}
int bnxt_get_vf_config(struct net_device *dev, int vf_id, int bnxt_get_vf_config(struct net_device *dev, int vf_id,
struct ifla_vf_info *ivi) struct ifla_vf_info *ivi)
{ {
...@@ -147,6 +164,7 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id, ...@@ -147,6 +164,7 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id,
else else
ivi->qos = 0; ivi->qos = 0;
ivi->spoofchk = !!(vf->flags & BNXT_VF_SPOOFCHK); ivi->spoofchk = !!(vf->flags & BNXT_VF_SPOOFCHK);
ivi->trusted = !!(vf->flags & BNXT_VF_TRUST);
if (!(vf->flags & BNXT_VF_LINK_FORCED)) if (!(vf->flags & BNXT_VF_LINK_FORCED))
ivi->linkstate = IFLA_VF_LINK_STATE_AUTO; ivi->linkstate = IFLA_VF_LINK_STATE_AUTO;
else if (vf->flags & BNXT_VF_LINK_UP) else if (vf->flags & BNXT_VF_LINK_UP)
...@@ -886,18 +904,19 @@ static int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, struct bnxt_vf_info *vf, ...@@ -886,18 +904,19 @@ 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) static int bnxt_vf_configure_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
{ {
u32 msg_size = sizeof(struct hwrm_func_vf_cfg_input); u32 msg_size = sizeof(struct hwrm_func_vf_cfg_input);
struct hwrm_func_vf_cfg_input *req = struct hwrm_func_vf_cfg_input *req =
(struct hwrm_func_vf_cfg_input *)vf->hwrm_cmd_req_addr; (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 /* Allow VF to set a valid MAC address, if trust is set to on or
* address is zero * if the PF assigned MAC address is zero
*/ */
if (req->enables & cpu_to_le32(FUNC_VF_CFG_REQ_ENABLES_DFLT_MAC_ADDR)) { if (req->enables & cpu_to_le32(FUNC_VF_CFG_REQ_ENABLES_DFLT_MAC_ADDR)) {
if (is_valid_ether_addr(req->dflt_mac_addr) && if (is_valid_ether_addr(req->dflt_mac_addr) &&
!is_valid_ether_addr(vf->mac_addr)) { ((vf->flags & BNXT_VF_TRUST) ||
(!is_valid_ether_addr(vf->mac_addr)))) {
ether_addr_copy(vf->vf_mac_addr, req->dflt_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_exec_fwd_resp(bp, vf, msg_size);
} }
...@@ -913,11 +932,17 @@ static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf) ...@@ -913,11 +932,17 @@ static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
(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; bool mac_ok = false;
/* VF MAC address must first match PF MAC address, if it is valid. if (!is_valid_ether_addr((const u8 *)req->l2_addr))
return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size);
/* Allow VF to set a valid MAC address, if trust is set to on.
* Or VF MAC address must first match MAC address in PF's context.
* Otherwise, it must match the VF MAC address if firmware spec >= * Otherwise, it must match the VF MAC address if firmware spec >=
* 1.2.2 * 1.2.2
*/ */
if (is_valid_ether_addr(vf->mac_addr)) { if (vf->flags & BNXT_VF_TRUST) {
mac_ok = true;
} else if (is_valid_ether_addr(vf->mac_addr)) {
if (ether_addr_equal((const u8 *)req->l2_addr, vf->mac_addr)) if (ether_addr_equal((const u8 *)req->l2_addr, vf->mac_addr))
mac_ok = true; mac_ok = true;
} else if (is_valid_ether_addr(vf->vf_mac_addr)) { } else if (is_valid_ether_addr(vf->vf_mac_addr)) {
...@@ -993,7 +1018,7 @@ static int bnxt_vf_req_validate_snd(struct bnxt *bp, struct bnxt_vf_info *vf) ...@@ -993,7 +1018,7 @@ static int bnxt_vf_req_validate_snd(struct bnxt *bp, struct bnxt_vf_info *vf)
switch (req_type) { switch (req_type) {
case HWRM_FUNC_VF_CFG: case HWRM_FUNC_VF_CFG:
rc = bnxt_vf_store_mac(bp, vf); rc = bnxt_vf_configure_mac(bp, vf);
break; 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);
......
/* Broadcom NetXtreme-C/E network driver. /* Broadcom NetXtreme-C/E network driver.
* *
* Copyright (c) 2014-2016 Broadcom Corporation * Copyright (c) 2014-2016 Broadcom Corporation
* Copyright (c) 2016-2017 Broadcom Limited * Copyright (c) 2016-2018 Broadcom Limited
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -17,6 +17,7 @@ int bnxt_set_vf_vlan(struct net_device *, int, u16, u8, __be16); ...@@ -17,6 +17,7 @@ int bnxt_set_vf_vlan(struct net_device *, int, u16, u8, __be16);
int bnxt_set_vf_bw(struct net_device *, int, int, int); int bnxt_set_vf_bw(struct net_device *, int, int, int);
int bnxt_set_vf_link_state(struct net_device *, int, int); int bnxt_set_vf_link_state(struct net_device *, int, int);
int bnxt_set_vf_spoofchk(struct net_device *, int, bool); int bnxt_set_vf_spoofchk(struct net_device *, int, bool);
int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trust);
int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs); 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 *);
......
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