Commit 57701171 authored by David S. Miller's avatar David S. Miller

Merge branch 'bnxt_en-Update-for-net-next'

Michael Chan says:

====================
bnxt_en: Update for net-next.

This series includes the usual firmware spec. update, a PCI ID addition,
enhancements for VF trust, MDIO read/write for external PHY, and
fixing the return code when TC flow offload fails.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4509de14 b2d69122
/* 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-2018 Broadcom Limited * Copyright (c) 2016-2019 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
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <asm/page.h> #include <asm/page.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/mdio.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/if_bridge.h> #include <linux/if_bridge.h>
...@@ -112,6 +113,7 @@ enum board_idx { ...@@ -112,6 +113,7 @@ enum board_idx {
BCM57454, BCM57454,
BCM5745x_NPAR, BCM5745x_NPAR,
BCM57508, BCM57508,
BCM57504,
BCM58802, BCM58802,
BCM58804, BCM58804,
BCM58808, BCM58808,
...@@ -155,6 +157,7 @@ static const struct { ...@@ -155,6 +157,7 @@ static const struct {
[BCM57454] = { "Broadcom BCM57454 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" }, [BCM57454] = { "Broadcom BCM57454 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
[BCM5745x_NPAR] = { "Broadcom BCM5745x NetXtreme-E Ethernet Partition" }, [BCM5745x_NPAR] = { "Broadcom BCM5745x NetXtreme-E Ethernet Partition" },
[BCM57508] = { "Broadcom BCM57508 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet" }, [BCM57508] = { "Broadcom BCM57508 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet" },
[BCM57504] = { "Broadcom BCM57504 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet" },
[BCM58802] = { "Broadcom BCM58802 NetXtreme-S 10Gb/25Gb/40Gb/50Gb Ethernet" }, [BCM58802] = { "Broadcom BCM58802 NetXtreme-S 10Gb/25Gb/40Gb/50Gb Ethernet" },
[BCM58804] = { "Broadcom BCM58804 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" }, [BCM58804] = { "Broadcom BCM58804 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
[BCM58808] = { "Broadcom BCM58808 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" }, [BCM58808] = { "Broadcom BCM58808 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
...@@ -201,6 +204,7 @@ static const struct pci_device_id bnxt_pci_tbl[] = { ...@@ -201,6 +204,7 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
{ PCI_VDEVICE(BROADCOM, 0x16f0), .driver_data = BCM58808 }, { PCI_VDEVICE(BROADCOM, 0x16f0), .driver_data = BCM58808 },
{ PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 }, { PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 },
{ PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 }, { PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 },
{ PCI_VDEVICE(BROADCOM, 0x1751), .driver_data = BCM57504 },
{ PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 }, { PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 },
{ PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 }, { PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 },
#ifdef CONFIG_BNXT_SRIOV #ifdef CONFIG_BNXT_SRIOV
...@@ -6680,6 +6684,10 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp) ...@@ -6680,6 +6684,10 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
VER_GET_RESP_DEV_CAPS_CFG_FLOW_HANDLE_64BIT_SUPPORTED) VER_GET_RESP_DEV_CAPS_CFG_FLOW_HANDLE_64BIT_SUPPORTED)
bp->fw_cap |= BNXT_FW_CAP_OVS_64BIT_HANDLE; bp->fw_cap |= BNXT_FW_CAP_OVS_64BIT_HANDLE;
if (dev_caps_cfg &
VER_GET_RESP_DEV_CAPS_CFG_TRUSTED_VF_SUPPORTED)
bp->fw_cap |= BNXT_FW_CAP_TRUSTED_VF;
hwrm_ver_get_exit: hwrm_ver_get_exit:
mutex_unlock(&bp->hwrm_cmd_lock); mutex_unlock(&bp->hwrm_cmd_lock);
return rc; return rc;
...@@ -8614,24 +8622,88 @@ static int bnxt_close(struct net_device *dev) ...@@ -8614,24 +8622,88 @@ static int bnxt_close(struct net_device *dev)
return 0; return 0;
} }
static int bnxt_hwrm_port_phy_read(struct bnxt *bp, u16 phy_addr, u16 reg,
u16 *val)
{
struct hwrm_port_phy_mdio_read_output *resp = bp->hwrm_cmd_resp_addr;
struct hwrm_port_phy_mdio_read_input req = {0};
int rc;
if (bp->hwrm_spec_code < 0x10a00)
return -EOPNOTSUPP;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_MDIO_READ, -1, -1);
req.port_id = cpu_to_le16(bp->pf.port_id);
req.phy_addr = phy_addr;
req.reg_addr = cpu_to_le16(reg & 0x1f);
if (bp->link_info.support_speeds & BNXT_LINK_SPEED_MSK_10GB) {
req.cl45_mdio = 1;
req.phy_addr = mdio_phy_id_prtad(phy_addr);
req.dev_addr = mdio_phy_id_devad(phy_addr);
req.reg_addr = cpu_to_le16(reg);
}
mutex_lock(&bp->hwrm_cmd_lock);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (!rc)
*val = le16_to_cpu(resp->reg_data);
mutex_unlock(&bp->hwrm_cmd_lock);
return rc;
}
static int bnxt_hwrm_port_phy_write(struct bnxt *bp, u16 phy_addr, u16 reg,
u16 val)
{
struct hwrm_port_phy_mdio_write_input req = {0};
if (bp->hwrm_spec_code < 0x10a00)
return -EOPNOTSUPP;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_MDIO_WRITE, -1, -1);
req.port_id = cpu_to_le16(bp->pf.port_id);
req.phy_addr = phy_addr;
req.reg_addr = cpu_to_le16(reg & 0x1f);
if (bp->link_info.support_speeds & BNXT_LINK_SPEED_MSK_10GB) {
req.cl45_mdio = 1;
req.phy_addr = mdio_phy_id_prtad(phy_addr);
req.dev_addr = mdio_phy_id_devad(phy_addr);
req.reg_addr = cpu_to_le16(reg);
}
req.reg_data = cpu_to_le16(val);
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
}
/* rtnl_lock held */ /* rtnl_lock held */
static int bnxt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int bnxt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{ {
struct mii_ioctl_data *mdio = if_mii(ifr);
struct bnxt *bp = netdev_priv(dev);
int rc;
switch (cmd) { switch (cmd) {
case SIOCGMIIPHY: case SIOCGMIIPHY:
mdio->phy_id = bp->link_info.phy_addr;
/* fallthru */ /* fallthru */
case SIOCGMIIREG: { case SIOCGMIIREG: {
u16 mii_regval = 0;
if (!netif_running(dev)) if (!netif_running(dev))
return -EAGAIN; return -EAGAIN;
return 0; rc = bnxt_hwrm_port_phy_read(bp, mdio->phy_id, mdio->reg_num,
&mii_regval);
mdio->val_out = mii_regval;
return rc;
} }
case SIOCSMIIREG: case SIOCSMIIREG:
if (!netif_running(dev)) if (!netif_running(dev))
return -EAGAIN; return -EAGAIN;
return 0; return bnxt_hwrm_port_phy_write(bp, mdio->phy_id, mdio->reg_num,
mdio->val_in);
default: default:
/* do nothing */ /* do nothing */
......
...@@ -945,6 +945,7 @@ struct bnxt_vf_info { ...@@ -945,6 +945,7 @@ struct bnxt_vf_info {
* stored by PF. * stored by PF.
*/ */
u16 vlan; u16 vlan;
u16 func_qcfg_flags;
u32 flags; u32 flags;
#define BNXT_VF_QOS 0x1 #define BNXT_VF_QOS 0x1
#define BNXT_VF_SPOOFCHK 0x2 #define BNXT_VF_SPOOFCHK 0x2
...@@ -1478,6 +1479,7 @@ struct bnxt { ...@@ -1478,6 +1479,7 @@ struct bnxt {
#define BNXT_FW_CAP_IF_CHANGE 0x00000010 #define BNXT_FW_CAP_IF_CHANGE 0x00000010
#define BNXT_FW_CAP_KONG_MB_CHNL 0x00000080 #define BNXT_FW_CAP_KONG_MB_CHNL 0x00000080
#define BNXT_FW_CAP_OVS_64BIT_HANDLE 0x00000400 #define BNXT_FW_CAP_OVS_64BIT_HANDLE 0x00000400
#define BNXT_FW_CAP_TRUSTED_VF 0x00000800
#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM) #define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
u32 hwrm_spec_code; u32 hwrm_spec_code;
......
...@@ -121,6 +121,54 @@ int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting) ...@@ -121,6 +121,54 @@ int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting)
return rc; return rc;
} }
static int bnxt_hwrm_func_qcfg_flags(struct bnxt *bp, struct bnxt_vf_info *vf)
{
struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
struct hwrm_func_qcfg_input req = {0};
int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QCFG, -1, -1);
req.fid = cpu_to_le16(vf->fw_fid);
mutex_lock(&bp->hwrm_cmd_lock);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc) {
mutex_unlock(&bp->hwrm_cmd_lock);
return -EIO;
}
vf->func_qcfg_flags = le16_to_cpu(resp->flags);
mutex_unlock(&bp->hwrm_cmd_lock);
return 0;
}
static bool bnxt_is_trusted_vf(struct bnxt *bp, struct bnxt_vf_info *vf)
{
if (!(bp->fw_cap & BNXT_FW_CAP_TRUSTED_VF))
return !!(vf->flags & BNXT_VF_TRUST);
bnxt_hwrm_func_qcfg_flags(bp, vf);
return !!(vf->func_qcfg_flags & FUNC_QCFG_RESP_FLAGS_TRUSTED_VF);
}
static int bnxt_hwrm_set_trusted_vf(struct bnxt *bp, struct bnxt_vf_info *vf)
{
struct hwrm_func_cfg_input req = {0};
int rc;
if (!(bp->fw_cap & BNXT_FW_CAP_TRUSTED_VF))
return 0;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
req.fid = cpu_to_le16(vf->fw_fid);
if (vf->flags & BNXT_VF_TRUST)
req.flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_TRUSTED_VF_ENABLE);
else
req.flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_TRUSTED_VF_DISABLE);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
return -EIO;
return 0;
}
int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted) int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted)
{ {
struct bnxt *bp = netdev_priv(dev); struct bnxt *bp = netdev_priv(dev);
...@@ -135,6 +183,7 @@ int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted) ...@@ -135,6 +183,7 @@ int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted)
else else
vf->flags &= ~BNXT_VF_TRUST; vf->flags &= ~BNXT_VF_TRUST;
bnxt_hwrm_set_trusted_vf(bp, vf);
return 0; return 0;
} }
...@@ -164,7 +213,7 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id, ...@@ -164,7 +213,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); ivi->trusted = bnxt_is_trusted_vf(bp, vf);
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)
...@@ -935,9 +984,10 @@ static int bnxt_vf_configure_mac(struct bnxt *bp, struct bnxt_vf_info *vf) ...@@ -935,9 +984,10 @@ static int bnxt_vf_configure_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
* if the PF assigned MAC 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)) {
bool trust = bnxt_is_trusted_vf(bp, vf);
if (is_valid_ether_addr(req->dflt_mac_addr) && if (is_valid_ether_addr(req->dflt_mac_addr) &&
((vf->flags & BNXT_VF_TRUST) || (trust || !is_valid_ether_addr(vf->mac_addr) ||
!is_valid_ether_addr(vf->mac_addr) ||
ether_addr_equal(req->dflt_mac_addr, vf->mac_addr))) { ether_addr_equal(req->dflt_mac_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);
...@@ -962,7 +1012,7 @@ static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf) ...@@ -962,7 +1012,7 @@ static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
* 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 (vf->flags & BNXT_VF_TRUST) { if (bnxt_is_trusted_vf(bp, vf)) {
mac_ok = true; mac_ok = true;
} else if (is_valid_ether_addr(vf->mac_addr)) { } 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))
......
...@@ -1290,7 +1290,7 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, ...@@ -1290,7 +1290,7 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid,
bnxt_tc_set_flow_dir(bp, flow, src_fid); bnxt_tc_set_flow_dir(bp, flow, src_fid);
if (!bnxt_tc_can_offload(bp, flow)) { if (!bnxt_tc_can_offload(bp, flow)) {
rc = -ENOSPC; rc = -EOPNOTSUPP;
goto free_node; goto free_node;
} }
......
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