mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 15:11:31 +00:00
Merge branch 'bnxt_en-next'
Michael Chan says: ==================== bnxt: update for net-next. Misc. changes and minor bug fixes for net-next. Please review. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
583c139c71
@ -32,6 +32,7 @@
|
||||
#include <linux/mii.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/udp.h>
|
||||
@ -93,50 +94,49 @@ enum board_idx {
|
||||
BCM57404_NPAR,
|
||||
BCM57406_NPAR,
|
||||
BCM57407_SFP,
|
||||
BCM57407_NPAR,
|
||||
BCM57414_NPAR,
|
||||
BCM57416_NPAR,
|
||||
BCM57304_VF,
|
||||
BCM57404_VF,
|
||||
BCM57414_VF,
|
||||
BCM57314_VF,
|
||||
NETXTREME_E_VF,
|
||||
NETXTREME_C_VF,
|
||||
};
|
||||
|
||||
/* indexed by enum above */
|
||||
static const struct {
|
||||
char *name;
|
||||
} board_info[] = {
|
||||
{ "Broadcom BCM57301 NetXtreme-C Single-port 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57302 NetXtreme-C Dual-port 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57304 NetXtreme-C Dual-port 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
||||
{ "Broadcom BCM57301 NetXtreme-C 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57302 NetXtreme-C 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57304 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
||||
{ "Broadcom BCM57417 NetXtreme-E Ethernet Partition" },
|
||||
{ "Broadcom BCM58700 Nitro 4-port 1Gb/2.5Gb/10Gb Ethernet" },
|
||||
{ "Broadcom BCM57311 NetXtreme-C Single-port 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57312 NetXtreme-C Dual-port 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57402 NetXtreme-E Dual-port 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57404 NetXtreme-E Dual-port 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57406 NetXtreme-E Dual-port 10GBase-T Ethernet" },
|
||||
{ "Broadcom BCM58700 Nitro 1Gb/2.5Gb/10Gb Ethernet" },
|
||||
{ "Broadcom BCM57311 NetXtreme-C 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57312 NetXtreme-C 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57402 NetXtreme-E 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57404 NetXtreme-E 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57406 NetXtreme-E 10GBase-T Ethernet" },
|
||||
{ "Broadcom BCM57402 NetXtreme-E Ethernet Partition" },
|
||||
{ "Broadcom BCM57407 NetXtreme-E Dual-port 10GBase-T Ethernet" },
|
||||
{ "Broadcom BCM57412 NetXtreme-E Dual-port 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57414 NetXtreme-E Dual-port 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57416 NetXtreme-E Dual-port 10GBase-T Ethernet" },
|
||||
{ "Broadcom BCM57417 NetXtreme-E Dual-port 10GBase-T Ethernet" },
|
||||
{ "Broadcom BCM57407 NetXtreme-E 10GBase-T Ethernet" },
|
||||
{ "Broadcom BCM57412 NetXtreme-E 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57414 NetXtreme-E 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57416 NetXtreme-E 10GBase-T Ethernet" },
|
||||
{ "Broadcom BCM57417 NetXtreme-E 10GBase-T Ethernet" },
|
||||
{ "Broadcom BCM57412 NetXtreme-E Ethernet Partition" },
|
||||
{ "Broadcom BCM57314 NetXtreme-C Dual-port 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
||||
{ "Broadcom BCM57417 NetXtreme-E Dual-port 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57416 NetXtreme-E Dual-port 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57314 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
||||
{ "Broadcom BCM57417 NetXtreme-E 10Gb/25Gb Ethernet" },
|
||||
{ "Broadcom BCM57416 NetXtreme-E 10Gb Ethernet" },
|
||||
{ "Broadcom BCM57404 NetXtreme-E Ethernet Partition" },
|
||||
{ "Broadcom BCM57406 NetXtreme-E Ethernet Partition" },
|
||||
{ "Broadcom BCM57407 NetXtreme-E Dual-port 25Gb Ethernet" },
|
||||
{ "Broadcom BCM57407 NetXtreme-E 25Gb Ethernet" },
|
||||
{ "Broadcom BCM57407 NetXtreme-E Ethernet Partition" },
|
||||
{ "Broadcom BCM57414 NetXtreme-E Ethernet Partition" },
|
||||
{ "Broadcom BCM57416 NetXtreme-E Ethernet Partition" },
|
||||
{ "Broadcom BCM57304 NetXtreme-C Ethernet Virtual Function" },
|
||||
{ "Broadcom BCM57404 NetXtreme-E Ethernet Virtual Function" },
|
||||
{ "Broadcom BCM57414 NetXtreme-E Ethernet Virtual Function" },
|
||||
{ "Broadcom BCM57314 NetXtreme-E Ethernet Virtual Function" },
|
||||
{ "Broadcom NetXtreme-E Ethernet Virtual Function" },
|
||||
{ "Broadcom NetXtreme-C Ethernet Virtual Function" },
|
||||
};
|
||||
|
||||
static const struct pci_device_id bnxt_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16c0), .driver_data = BCM57417_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16c8), .driver_data = BCM57301 },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16c9), .driver_data = BCM57302 },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16ca), .driver_data = BCM57304 },
|
||||
@ -160,13 +160,19 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16e7), .driver_data = BCM57404_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16e8), .driver_data = BCM57406_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16e9), .driver_data = BCM57407_SFP },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16ea), .driver_data = BCM57407_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16eb), .driver_data = BCM57412_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16ec), .driver_data = BCM57414_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16ed), .driver_data = BCM57414_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16ee), .driver_data = BCM57416_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16ef), .driver_data = BCM57416_NPAR },
|
||||
#ifdef CONFIG_BNXT_SRIOV
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = BCM57304_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = BCM57404_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16dc), .driver_data = BCM57414_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16e1), .driver_data = BCM57314_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16c1), .driver_data = NETXTREME_E_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = NETXTREME_C_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = NETXTREME_E_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16dc), .driver_data = NETXTREME_E_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16e1), .driver_data = NETXTREME_C_VF },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x16e5), .driver_data = NETXTREME_C_VF },
|
||||
#endif
|
||||
{ 0 }
|
||||
};
|
||||
@ -189,8 +195,7 @@ static const u16 bnxt_async_events_arr[] = {
|
||||
|
||||
static bool bnxt_vf_pciid(enum board_idx idx)
|
||||
{
|
||||
return (idx == BCM57304_VF || idx == BCM57404_VF ||
|
||||
idx == BCM57314_VF || idx == BCM57414_VF);
|
||||
return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF);
|
||||
}
|
||||
|
||||
#define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID)
|
||||
@ -3419,10 +3424,10 @@ static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, u16 vnic_id, bool set_rss)
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_RSS_CFG, -1, -1);
|
||||
if (set_rss) {
|
||||
vnic->hash_type = BNXT_RSS_HASH_TYPE_FLAG_IPV4 |
|
||||
BNXT_RSS_HASH_TYPE_FLAG_TCP_IPV4 |
|
||||
BNXT_RSS_HASH_TYPE_FLAG_IPV6 |
|
||||
BNXT_RSS_HASH_TYPE_FLAG_TCP_IPV6;
|
||||
vnic->hash_type = VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4 |
|
||||
VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4 |
|
||||
VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6 |
|
||||
VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6;
|
||||
|
||||
req.hash_type = cpu_to_le32(vnic->hash_type);
|
||||
|
||||
@ -4156,6 +4161,11 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
|
||||
if (rc)
|
||||
goto hwrm_func_qcaps_exit;
|
||||
|
||||
bp->tx_push_thresh = 0;
|
||||
if (resp->flags &
|
||||
cpu_to_le32(FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED))
|
||||
bp->tx_push_thresh = BNXT_TX_PUSH_THRESH;
|
||||
|
||||
if (BNXT_PF(bp)) {
|
||||
struct bnxt_pf_info *pf = &bp->pf;
|
||||
|
||||
@ -4187,12 +4197,6 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
|
||||
struct bnxt_vf_info *vf = &bp->vf;
|
||||
|
||||
vf->fw_fid = le16_to_cpu(resp->fid);
|
||||
memcpy(vf->mac_addr, resp->mac_address, ETH_ALEN);
|
||||
if (is_valid_ether_addr(vf->mac_addr))
|
||||
/* overwrite netdev dev_adr with admin VF MAC */
|
||||
memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
|
||||
else
|
||||
random_ether_addr(bp->dev->dev_addr);
|
||||
|
||||
vf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx);
|
||||
vf->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings);
|
||||
@ -4204,14 +4208,21 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
|
||||
vf->max_l2_ctxs = le16_to_cpu(resp->max_l2_ctxs);
|
||||
vf->max_vnics = le16_to_cpu(resp->max_vnics);
|
||||
vf->max_stat_ctxs = le16_to_cpu(resp->max_stat_ctx);
|
||||
|
||||
memcpy(vf->mac_addr, resp->mac_address, ETH_ALEN);
|
||||
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||
|
||||
if (is_valid_ether_addr(vf->mac_addr)) {
|
||||
/* overwrite netdev dev_adr with admin VF MAC */
|
||||
memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
|
||||
} else {
|
||||
random_ether_addr(bp->dev->dev_addr);
|
||||
rc = bnxt_approve_mac(bp, bp->dev->dev_addr);
|
||||
}
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
|
||||
bp->tx_push_thresh = 0;
|
||||
if (resp->flags &
|
||||
cpu_to_le32(FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED))
|
||||
bp->tx_push_thresh = BNXT_TX_PUSH_THRESH;
|
||||
|
||||
hwrm_func_qcaps_exit:
|
||||
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||
return rc;
|
||||
@ -4249,6 +4260,9 @@ static int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
|
||||
if (bp->max_tc > BNXT_MAX_QUEUE)
|
||||
bp->max_tc = BNXT_MAX_QUEUE;
|
||||
|
||||
if (resp->queue_cfg_info & QUEUE_QPORTCFG_RESP_QUEUE_CFG_INFO_ASYM_CFG)
|
||||
bp->max_tc = 1;
|
||||
|
||||
qptr = &resp->queue_id0;
|
||||
for (i = 0; i < bp->max_tc; i++) {
|
||||
bp->q_info[i].queue_id = *qptr++;
|
||||
@ -4307,6 +4321,27 @@ hwrm_ver_get_exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int bnxt_hwrm_fw_set_time(struct bnxt *bp)
|
||||
{
|
||||
struct hwrm_fw_set_time_input req = {0};
|
||||
struct rtc_time tm;
|
||||
struct timeval tv;
|
||||
|
||||
if (bp->hwrm_spec_code < 0x10400)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
do_gettimeofday(&tv);
|
||||
rtc_time_to_tm(tv.tv_sec, &tm);
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FW_SET_TIME, -1, -1);
|
||||
req.year = cpu_to_le16(1900 + tm.tm_year);
|
||||
req.month = 1 + tm.tm_mon;
|
||||
req.day = tm.tm_mday;
|
||||
req.hour = tm.tm_hour;
|
||||
req.minute = tm.tm_min;
|
||||
req.second = tm.tm_sec;
|
||||
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
}
|
||||
|
||||
static int bnxt_hwrm_port_qstats(struct bnxt *bp)
|
||||
{
|
||||
int rc;
|
||||
@ -6804,6 +6839,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (rc)
|
||||
goto init_err;
|
||||
|
||||
bnxt_hwrm_fw_set_time(bp);
|
||||
|
||||
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
|
||||
NETIF_F_TSO | NETIF_F_TSO6 |
|
||||
NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
|
||||
|
@ -11,10 +11,10 @@
|
||||
#define BNXT_H
|
||||
|
||||
#define DRV_MODULE_NAME "bnxt_en"
|
||||
#define DRV_MODULE_VERSION "1.3.0"
|
||||
#define DRV_MODULE_VERSION "1.5.0"
|
||||
|
||||
#define DRV_VER_MAJ 1
|
||||
#define DRV_VER_MIN 3
|
||||
#define DRV_VER_MIN 5
|
||||
#define DRV_VER_UPD 0
|
||||
|
||||
struct tx_bd {
|
||||
@ -106,11 +106,11 @@ struct tx_cmp {
|
||||
#define CMP_TYPE_REMOTE_DRIVER_REQ 34
|
||||
#define CMP_TYPE_REMOTE_DRIVER_RESP 36
|
||||
#define CMP_TYPE_ERROR_STATUS 48
|
||||
#define CMPL_BASE_TYPE_STAT_EJECT (0x1aUL << 0)
|
||||
#define CMPL_BASE_TYPE_HWRM_DONE (0x20UL << 0)
|
||||
#define CMPL_BASE_TYPE_HWRM_FWD_REQ (0x22UL << 0)
|
||||
#define CMPL_BASE_TYPE_HWRM_FWD_RESP (0x24UL << 0)
|
||||
#define CMPL_BASE_TYPE_HWRM_ASYNC_EVENT (0x2eUL << 0)
|
||||
#define CMPL_BASE_TYPE_STAT_EJECT 0x1aUL
|
||||
#define CMPL_BASE_TYPE_HWRM_DONE 0x20UL
|
||||
#define CMPL_BASE_TYPE_HWRM_FWD_REQ 0x22UL
|
||||
#define CMPL_BASE_TYPE_HWRM_FWD_RESP 0x24UL
|
||||
#define CMPL_BASE_TYPE_HWRM_ASYNC_EVENT 0x2eUL
|
||||
|
||||
#define TX_CMP_FLAGS_ERROR (1 << 6)
|
||||
#define TX_CMP_FLAGS_PUSH (1 << 7)
|
||||
@ -389,11 +389,6 @@ struct rx_tpa_end_cmp_ext {
|
||||
|
||||
#define INVALID_HW_RING_ID ((u16)-1)
|
||||
|
||||
#define BNXT_RSS_HASH_TYPE_FLAG_IPV4 0x01
|
||||
#define BNXT_RSS_HASH_TYPE_FLAG_TCP_IPV4 0x02
|
||||
#define BNXT_RSS_HASH_TYPE_FLAG_IPV6 0x04
|
||||
#define BNXT_RSS_HASH_TYPE_FLAG_TCP_IPV6 0x08
|
||||
|
||||
/* The hardware supports certain page sizes. Use the supported page sizes
|
||||
* to allocate the rings.
|
||||
*/
|
||||
@ -418,7 +413,7 @@ struct rx_tpa_end_cmp_ext {
|
||||
|
||||
#define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT)
|
||||
|
||||
#define BNXT_MIN_PKT_SIZE 45
|
||||
#define BNXT_MIN_PKT_SIZE 52
|
||||
|
||||
#define BNXT_NUM_TESTS(bp) 0
|
||||
|
||||
@ -1225,6 +1220,7 @@ int bnxt_hwrm_set_coal(struct bnxt *);
|
||||
int bnxt_hwrm_func_qcaps(struct bnxt *);
|
||||
int bnxt_hwrm_set_pause(struct bnxt *);
|
||||
int bnxt_hwrm_set_link_setting(struct bnxt *, bool, bool);
|
||||
int bnxt_hwrm_fw_set_time(struct bnxt *);
|
||||
int bnxt_open_nic(struct bnxt *, bool, bool);
|
||||
int bnxt_close_nic(struct bnxt *, bool, bool);
|
||||
int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "bnxt_nvm_defs.h" /* NVRAM content constant and structure defs */
|
||||
#include "bnxt_fw_hdr.h" /* Firmware hdr constant and structure defs */
|
||||
#define FLASH_NVRAM_TIMEOUT ((HWRM_CMD_TIMEOUT) * 100)
|
||||
#define FLASH_PACKAGE_TIMEOUT ((HWRM_CMD_TIMEOUT) * 200)
|
||||
#define INSTALL_PACKAGE_TIMEOUT ((HWRM_CMD_TIMEOUT) * 200)
|
||||
|
||||
static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen);
|
||||
|
||||
@ -346,7 +348,7 @@ static void bnxt_get_channels(struct net_device *dev,
|
||||
int max_rx_rings, max_tx_rings, tcs;
|
||||
|
||||
bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, true);
|
||||
channel->max_combined = max_rx_rings;
|
||||
channel->max_combined = max_t(int, max_rx_rings, max_tx_rings);
|
||||
|
||||
if (bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, false)) {
|
||||
max_rx_rings = 0;
|
||||
@ -404,8 +406,8 @@ static int bnxt_set_channels(struct net_device *dev,
|
||||
if (tcs > 1)
|
||||
max_tx_rings /= tcs;
|
||||
|
||||
if (sh && (channel->combined_count > max_rx_rings ||
|
||||
channel->combined_count > max_tx_rings))
|
||||
if (sh &&
|
||||
channel->combined_count > max_t(int, max_rx_rings, max_tx_rings))
|
||||
return -ENOMEM;
|
||||
|
||||
if (!sh && (channel->rx_count > max_rx_rings ||
|
||||
@ -428,8 +430,10 @@ static int bnxt_set_channels(struct net_device *dev,
|
||||
|
||||
if (sh) {
|
||||
bp->flags |= BNXT_FLAG_SHARED_RINGS;
|
||||
bp->rx_nr_rings = channel->combined_count;
|
||||
bp->tx_nr_rings_per_tc = channel->combined_count;
|
||||
bp->rx_nr_rings = min_t(int, channel->combined_count,
|
||||
max_rx_rings);
|
||||
bp->tx_nr_rings_per_tc = min_t(int, channel->combined_count,
|
||||
max_tx_rings);
|
||||
} else {
|
||||
bp->flags &= ~BNXT_FLAG_SHARED_RINGS;
|
||||
bp->rx_nr_rings = channel->rx_count;
|
||||
@ -1028,6 +1032,10 @@ static u32 bnxt_get_link(struct net_device *dev)
|
||||
return bp->link_info.link_up;
|
||||
}
|
||||
|
||||
static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
|
||||
u16 ext, u16 *index, u32 *item_length,
|
||||
u32 *data_length);
|
||||
|
||||
static int bnxt_flash_nvram(struct net_device *dev,
|
||||
u16 dir_type,
|
||||
u16 dir_ordinal,
|
||||
@ -1179,7 +1187,6 @@ static int bnxt_flash_firmware(struct net_device *dev,
|
||||
(unsigned long)calculated_crc);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* TODO: Validate digital signature (RSA-encrypted SHA-256 hash) here */
|
||||
rc = bnxt_flash_nvram(dev, dir_type, BNX_DIR_ORDINAL_FIRST,
|
||||
0, 0, fw_data, fw_size);
|
||||
if (rc == 0) /* Firmware update successful */
|
||||
@ -1188,6 +1195,57 @@ static int bnxt_flash_firmware(struct net_device *dev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnxt_flash_microcode(struct net_device *dev,
|
||||
u16 dir_type,
|
||||
const u8 *fw_data,
|
||||
size_t fw_size)
|
||||
{
|
||||
struct bnxt_ucode_trailer *trailer;
|
||||
u32 calculated_crc;
|
||||
u32 stored_crc;
|
||||
int rc = 0;
|
||||
|
||||
if (fw_size < sizeof(struct bnxt_ucode_trailer)) {
|
||||
netdev_err(dev, "Invalid microcode file size: %u\n",
|
||||
(unsigned int)fw_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
trailer = (struct bnxt_ucode_trailer *)(fw_data + (fw_size -
|
||||
sizeof(*trailer)));
|
||||
if (trailer->sig != cpu_to_le32(BNXT_UCODE_TRAILER_SIGNATURE)) {
|
||||
netdev_err(dev, "Invalid microcode trailer signature: %08X\n",
|
||||
le32_to_cpu(trailer->sig));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (le16_to_cpu(trailer->dir_type) != dir_type) {
|
||||
netdev_err(dev, "Expected microcode type: %d, read: %d\n",
|
||||
dir_type, le16_to_cpu(trailer->dir_type));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (le16_to_cpu(trailer->trailer_length) <
|
||||
sizeof(struct bnxt_ucode_trailer)) {
|
||||
netdev_err(dev, "Invalid microcode trailer length: %d\n",
|
||||
le16_to_cpu(trailer->trailer_length));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Confirm the CRC32 checksum of the file: */
|
||||
stored_crc = le32_to_cpu(*(__le32 *)(fw_data + fw_size -
|
||||
sizeof(stored_crc)));
|
||||
calculated_crc = ~crc32(~0, fw_data, fw_size - sizeof(stored_crc));
|
||||
if (calculated_crc != stored_crc) {
|
||||
netdev_err(dev,
|
||||
"CRC32 (%08lX) does not match calculated: %08lX\n",
|
||||
(unsigned long)stored_crc,
|
||||
(unsigned long)calculated_crc);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = bnxt_flash_nvram(dev, dir_type, BNX_DIR_ORDINAL_FIRST,
|
||||
0, 0, fw_data, fw_size);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool bnxt_dir_type_is_ape_bin_format(u16 dir_type)
|
||||
{
|
||||
switch (dir_type) {
|
||||
@ -1206,7 +1264,7 @@ static bool bnxt_dir_type_is_ape_bin_format(u16 dir_type)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool bnxt_dir_type_is_unprotected_exec_format(u16 dir_type)
|
||||
static bool bnxt_dir_type_is_other_exec_format(u16 dir_type)
|
||||
{
|
||||
switch (dir_type) {
|
||||
case BNX_DIR_TYPE_AVS:
|
||||
@ -1227,7 +1285,7 @@ static bool bnxt_dir_type_is_unprotected_exec_format(u16 dir_type)
|
||||
static bool bnxt_dir_type_is_executable(u16 dir_type)
|
||||
{
|
||||
return bnxt_dir_type_is_ape_bin_format(dir_type) ||
|
||||
bnxt_dir_type_is_unprotected_exec_format(dir_type);
|
||||
bnxt_dir_type_is_other_exec_format(dir_type);
|
||||
}
|
||||
|
||||
static int bnxt_flash_firmware_from_file(struct net_device *dev,
|
||||
@ -1237,10 +1295,6 @@ static int bnxt_flash_firmware_from_file(struct net_device *dev,
|
||||
const struct firmware *fw;
|
||||
int rc;
|
||||
|
||||
if (dir_type != BNX_DIR_TYPE_UPDATE &&
|
||||
bnxt_dir_type_is_executable(dir_type) == false)
|
||||
return -EINVAL;
|
||||
|
||||
rc = request_firmware(&fw, filename, &dev->dev);
|
||||
if (rc != 0) {
|
||||
netdev_err(dev, "Error %d requesting firmware file: %s\n",
|
||||
@ -1249,6 +1303,8 @@ static int bnxt_flash_firmware_from_file(struct net_device *dev,
|
||||
}
|
||||
if (bnxt_dir_type_is_ape_bin_format(dir_type) == true)
|
||||
rc = bnxt_flash_firmware(dev, dir_type, fw->data, fw->size);
|
||||
else if (bnxt_dir_type_is_other_exec_format(dir_type) == true)
|
||||
rc = bnxt_flash_microcode(dev, dir_type, fw->data, fw->size);
|
||||
else
|
||||
rc = bnxt_flash_nvram(dev, dir_type, BNX_DIR_ORDINAL_FIRST,
|
||||
0, 0, fw->data, fw->size);
|
||||
@ -1257,10 +1313,83 @@ static int bnxt_flash_firmware_from_file(struct net_device *dev,
|
||||
}
|
||||
|
||||
static int bnxt_flash_package_from_file(struct net_device *dev,
|
||||
char *filename)
|
||||
char *filename, u32 install_type)
|
||||
{
|
||||
netdev_err(dev, "packages are not yet supported\n");
|
||||
return -EINVAL;
|
||||
struct bnxt *bp = netdev_priv(dev);
|
||||
struct hwrm_nvm_install_update_output *resp = bp->hwrm_cmd_resp_addr;
|
||||
struct hwrm_nvm_install_update_input install = {0};
|
||||
const struct firmware *fw;
|
||||
u32 item_len;
|
||||
u16 index;
|
||||
int rc;
|
||||
|
||||
bnxt_hwrm_fw_set_time(bp);
|
||||
|
||||
if (bnxt_find_nvram_item(dev, BNX_DIR_TYPE_UPDATE,
|
||||
BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
|
||||
&index, &item_len, NULL) != 0) {
|
||||
netdev_err(dev, "PKG update area not created in nvram\n");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
rc = request_firmware(&fw, filename, &dev->dev);
|
||||
if (rc != 0) {
|
||||
netdev_err(dev, "PKG error %d requesting file: %s\n",
|
||||
rc, filename);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (fw->size > item_len) {
|
||||
netdev_err(dev, "PKG insufficient update area in nvram: %lu",
|
||||
(unsigned long)fw->size);
|
||||
rc = -EFBIG;
|
||||
} else {
|
||||
dma_addr_t dma_handle;
|
||||
u8 *kmem;
|
||||
struct hwrm_nvm_modify_input modify = {0};
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &modify, HWRM_NVM_MODIFY, -1, -1);
|
||||
|
||||
modify.dir_idx = cpu_to_le16(index);
|
||||
modify.len = cpu_to_le32(fw->size);
|
||||
|
||||
kmem = dma_alloc_coherent(&bp->pdev->dev, fw->size,
|
||||
&dma_handle, GFP_KERNEL);
|
||||
if (!kmem) {
|
||||
netdev_err(dev,
|
||||
"dma_alloc_coherent failure, length = %u\n",
|
||||
(unsigned int)fw->size);
|
||||
rc = -ENOMEM;
|
||||
} else {
|
||||
memcpy(kmem, fw->data, fw->size);
|
||||
modify.host_src_addr = cpu_to_le64(dma_handle);
|
||||
|
||||
rc = hwrm_send_message(bp, &modify, sizeof(modify),
|
||||
FLASH_PACKAGE_TIMEOUT);
|
||||
dma_free_coherent(&bp->pdev->dev, fw->size, kmem,
|
||||
dma_handle);
|
||||
}
|
||||
}
|
||||
release_firmware(fw);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if ((install_type & 0xffff) == 0)
|
||||
install_type >>= 16;
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &install, HWRM_NVM_INSTALL_UPDATE, -1, -1);
|
||||
install.install_type = cpu_to_le32(install_type);
|
||||
|
||||
rc = hwrm_send_message(bp, &install, sizeof(install),
|
||||
INSTALL_PACKAGE_TIMEOUT);
|
||||
if (rc)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (resp->result) {
|
||||
netdev_err(dev, "PKG install error = %d, problem_item = %d\n",
|
||||
(s8)resp->result, (int)resp->problem_item);
|
||||
return -ENOPKG;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bnxt_flash_device(struct net_device *dev,
|
||||
@ -1271,8 +1400,10 @@ static int bnxt_flash_device(struct net_device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (flash->region == ETHTOOL_FLASH_ALL_REGIONS)
|
||||
return bnxt_flash_package_from_file(dev, flash->data);
|
||||
if (flash->region == ETHTOOL_FLASH_ALL_REGIONS ||
|
||||
flash->region > 0xffff)
|
||||
return bnxt_flash_package_from_file(dev, flash->data,
|
||||
flash->region);
|
||||
|
||||
return bnxt_flash_firmware_from_file(dev, flash->region, flash->data);
|
||||
}
|
||||
@ -1516,7 +1647,7 @@ static int bnxt_set_eeprom(struct net_device *dev,
|
||||
|
||||
/* Create or re-write an NVM item: */
|
||||
if (bnxt_dir_type_is_executable(type) == true)
|
||||
return -EINVAL;
|
||||
return -EOPNOTSUPP;
|
||||
ext = eeprom->magic & 0xffff;
|
||||
ordinal = eeprom->offset >> 16;
|
||||
attr = eeprom->offset & 0xffff;
|
||||
@ -1718,6 +1849,25 @@ static int bnxt_get_module_eeprom(struct net_device *dev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnxt_nway_reset(struct net_device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
struct bnxt *bp = netdev_priv(dev);
|
||||
struct bnxt_link_info *link_info = &bp->link_info;
|
||||
|
||||
if (!BNXT_SINGLE_PF(bp))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!(link_info->autoneg & BNXT_AUTONEG_SPEED))
|
||||
return -EINVAL;
|
||||
|
||||
if (netif_running(dev))
|
||||
rc = bnxt_hwrm_set_link_setting(bp, true, false);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
const struct ethtool_ops bnxt_ethtool_ops = {
|
||||
.get_link_ksettings = bnxt_get_link_ksettings,
|
||||
.set_link_ksettings = bnxt_set_link_ksettings,
|
||||
@ -1750,4 +1900,5 @@ const struct ethtool_ops bnxt_ethtool_ops = {
|
||||
.set_eee = bnxt_set_eee,
|
||||
.get_module_info = bnxt_get_module_info,
|
||||
.get_module_eeprom = bnxt_get_module_eeprom,
|
||||
.nway_reset = bnxt_nway_reset
|
||||
};
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define __BNXT_FW_HDR_H__
|
||||
|
||||
#define BNXT_FIRMWARE_BIN_SIGNATURE 0x1a4d4342 /* "BCM"+0x1a */
|
||||
#define BNXT_UCODE_TRAILER_SIGNATURE 0x726c7254 /* "Trlr" */
|
||||
|
||||
enum SUPPORTED_FAMILY {
|
||||
DEVICE_5702_3_4_FAMILY, /* 0 - Denali, Vinson, K2 */
|
||||
@ -85,7 +86,7 @@ enum SUPPORTED_MEDIA {
|
||||
|
||||
struct bnxt_fw_header {
|
||||
__le32 signature; /* constains the constant value of
|
||||
* BNXT_Firmware_Bin_Signatures
|
||||
* BNXT_FIRMWARE_BIN_SIGNATURE
|
||||
*/
|
||||
u8 flags; /* reserved for ChiMP use */
|
||||
u8 code_type; /* enum SUPPORTED_CODE */
|
||||
@ -102,4 +103,17 @@ struct bnxt_fw_header {
|
||||
u8 major_ver;
|
||||
};
|
||||
|
||||
/* Microcode and pre-boot software/firmware trailer: */
|
||||
struct bnxt_ucode_trailer {
|
||||
u8 rsa_sig[256];
|
||||
__le16 flags;
|
||||
u8 version_format;
|
||||
u8 version_length;
|
||||
u8 version[16];
|
||||
__le16 dir_type;
|
||||
__le16 trailer_length;
|
||||
__le32 sig; /* BNXT_UCODE_TRAILER_SIGNATURE */
|
||||
__le32 chksum; /* CRC-32 */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,45 @@
|
||||
#include "bnxt_ethtool.h"
|
||||
|
||||
#ifdef CONFIG_BNXT_SRIOV
|
||||
static int bnxt_hwrm_fwd_async_event_cmpl(struct bnxt *bp,
|
||||
struct bnxt_vf_info *vf, u16 event_id)
|
||||
{
|
||||
struct hwrm_fwd_async_event_cmpl_output *resp = bp->hwrm_cmd_resp_addr;
|
||||
struct hwrm_fwd_async_event_cmpl_input req = {0};
|
||||
struct hwrm_async_event_cmpl *async_cmpl;
|
||||
int rc = 0;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FWD_ASYNC_EVENT_CMPL, -1, -1);
|
||||
if (vf)
|
||||
req.encap_async_event_target_id = cpu_to_le16(vf->fw_fid);
|
||||
else
|
||||
/* broadcast this async event to all VFs */
|
||||
req.encap_async_event_target_id = cpu_to_le16(0xffff);
|
||||
async_cmpl = (struct hwrm_async_event_cmpl *)req.encap_async_event_cmpl;
|
||||
async_cmpl->type =
|
||||
cpu_to_le16(HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT);
|
||||
async_cmpl->event_id = cpu_to_le16(event_id);
|
||||
|
||||
mutex_lock(&bp->hwrm_cmd_lock);
|
||||
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
|
||||
if (rc) {
|
||||
netdev_err(bp->dev, "hwrm_fwd_async_event_cmpl failed. rc:%d\n",
|
||||
rc);
|
||||
goto fwd_async_event_cmpl_exit;
|
||||
}
|
||||
|
||||
if (resp->error_code) {
|
||||
netdev_err(bp->dev, "hwrm_fwd_async_event_cmpl error %d\n",
|
||||
resp->error_code);
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
fwd_async_event_cmpl_exit:
|
||||
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnxt_vf_ndo_prep(struct bnxt *bp, int vf_id)
|
||||
{
|
||||
if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
|
||||
@ -243,8 +282,9 @@ int bnxt_set_vf_link_state(struct net_device *dev, int vf_id, int link)
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
/* CHIMP TODO: send msg to VF to update new link state */
|
||||
|
||||
if (vf->flags & (BNXT_VF_LINK_UP | BNXT_VF_LINK_FORCED))
|
||||
rc = bnxt_hwrm_fwd_async_event_cmpl(bp, vf,
|
||||
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -525,46 +565,6 @@ err_out1:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnxt_hwrm_fwd_async_event_cmpl(struct bnxt *bp,
|
||||
struct bnxt_vf_info *vf,
|
||||
u16 event_id)
|
||||
{
|
||||
int rc = 0;
|
||||
struct hwrm_fwd_async_event_cmpl_input req = {0};
|
||||
struct hwrm_fwd_async_event_cmpl_output *resp = bp->hwrm_cmd_resp_addr;
|
||||
struct hwrm_async_event_cmpl *async_cmpl;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FWD_ASYNC_EVENT_CMPL, -1, -1);
|
||||
if (vf)
|
||||
req.encap_async_event_target_id = cpu_to_le16(vf->fw_fid);
|
||||
else
|
||||
/* broadcast this async event to all VFs */
|
||||
req.encap_async_event_target_id = cpu_to_le16(0xffff);
|
||||
async_cmpl = (struct hwrm_async_event_cmpl *)req.encap_async_event_cmpl;
|
||||
async_cmpl->type =
|
||||
cpu_to_le16(HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT);
|
||||
async_cmpl->event_id = cpu_to_le16(event_id);
|
||||
|
||||
mutex_lock(&bp->hwrm_cmd_lock);
|
||||
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
|
||||
if (rc) {
|
||||
netdev_err(bp->dev, "hwrm_fwd_async_event_cmpl failed. rc:%d\n",
|
||||
rc);
|
||||
goto fwd_async_event_cmpl_exit;
|
||||
}
|
||||
|
||||
if (resp->error_code) {
|
||||
netdev_err(bp->dev, "hwrm_fwd_async_event_cmpl error %d\n",
|
||||
resp->error_code);
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
fwd_async_event_cmpl_exit:
|
||||
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void bnxt_sriov_disable(struct bnxt *bp)
|
||||
{
|
||||
u16 num_vfs = pci_num_vf(bp->pdev);
|
||||
|
Loading…
Reference in New Issue
Block a user