Skip to content

Commit

Permalink
bnxt_en: Implement ndo_bridge_{get|set}link methods.
Browse files Browse the repository at this point in the history
To allow users to set the hardware bridging mode to VEB or VEPA.  Only
single function PF can change the bridging mode.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michael Chan authored and David S. Miller committed Jul 25, 2017
1 parent 32e8239 commit 39d8ba2
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4919,6 +4919,26 @@ static void bnxt_hwrm_resource_free(struct bnxt *bp, bool close_path,
}
}

static int bnxt_hwrm_set_br_mode(struct bnxt *bp, u16 br_mode)
{
struct hwrm_func_cfg_input req = {0};
int rc;

bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
req.fid = cpu_to_le16(0xffff);
req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_EVB_MODE);
if (br_mode == BRIDGE_MODE_VEB)
req.evb_mode = FUNC_CFG_REQ_EVB_MODE_VEB;
else if (br_mode == BRIDGE_MODE_VEPA)
req.evb_mode = FUNC_CFG_REQ_EVB_MODE_VEPA;
else
return -EINVAL;
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
rc = -EIO;
return rc;
}

static int bnxt_setup_vnic(struct bnxt *bp, u16 vnic_id)
{
struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
Expand Down Expand Up @@ -7432,6 +7452,51 @@ static void bnxt_udp_tunnel_del(struct net_device *dev,
schedule_work(&bp->sp_task);
}

static int bnxt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
struct net_device *dev, u32 filter_mask,
int nlflags)
{
struct bnxt *bp = netdev_priv(dev);

return ndo_dflt_bridge_getlink(skb, pid, seq, dev, bp->br_mode, 0, 0,
nlflags, filter_mask, NULL);
}

static int bnxt_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
u16 flags)
{
struct bnxt *bp = netdev_priv(dev);
struct nlattr *attr, *br_spec;
int rem, rc = 0;

if (bp->hwrm_spec_code < 0x10708 || !BNXT_SINGLE_PF(bp))
return -EOPNOTSUPP;

br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
if (!br_spec)
return -EINVAL;

nla_for_each_nested(attr, br_spec, rem) {
u16 mode;

if (nla_type(attr) != IFLA_BRIDGE_MODE)
continue;

if (nla_len(attr) < sizeof(mode))
return -EINVAL;

mode = nla_get_u16(attr);
if (mode == bp->br_mode)
break;

rc = bnxt_hwrm_set_br_mode(bp, mode);
if (!rc)
bp->br_mode = mode;
break;
}
return rc;
}

static const struct net_device_ops bnxt_netdev_ops = {
.ndo_open = bnxt_open,
.ndo_start_xmit = bnxt_start_xmit,
Expand Down Expand Up @@ -7463,6 +7528,8 @@ static const struct net_device_ops bnxt_netdev_ops = {
.ndo_udp_tunnel_add = bnxt_udp_tunnel_add,
.ndo_udp_tunnel_del = bnxt_udp_tunnel_del,
.ndo_xdp = bnxt_xdp,
.ndo_bridge_getlink = bnxt_bridge_getlink,
.ndo_bridge_setlink = bnxt_bridge_setlink,
};

static void bnxt_remove_one(struct pci_dev *pdev)
Expand Down

0 comments on commit 39d8ba2

Please sign in to comment.