Skip to content

Commit

Permalink
Merge branch 'bnxt_en-next'
Browse files Browse the repository at this point in the history
Michael Chan says:

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

Non-critical bug fixes, improvements, a new ethtool feature, and a new
device ID.

v2: Fixed a bug in bnxt_get_module_eeprom() found by Ben Hutchings.

Ajit Khaparde (2):
  bnxt_en: Add Support for ETHTOOL_GMODULEINFO and ETHTOOL_GMODULEEEPRO
  bnxt_en: Report PCIe link speed and width during driver load

Michael Chan (6):
  bnxt_en: Reduce maximum ring pages if page size is 64K.
  bnxt_en: Improve the delay logic for firmware response.
  bnxt_en: Fix length value in dmesg log firmware error message.
  bnxt_en: Simplify and improve unsupported SFP+ module reporting.
  bnxt_en: Add BCM57314 device ID.
  bnxt_en: Use dma_rmb() instead of rmb().

Satish Baddipadige (1):
  bnxt_en: Fix invalid max channel parameter in ethtool -l.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 15, 2016
2 parents 909b27f + b67daab commit bf14e9e
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 49 deletions.
111 changes: 64 additions & 47 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ enum board_idx {
BCM57402,
BCM57404,
BCM57406,
BCM57314,
BCM57304_VF,
BCM57404_VF,
};
Expand All @@ -92,6 +93,7 @@ static const struct {
{ "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 BCM57314 NetXtreme-C Dual-port 10Gb/25Gb/40Gb/50Gb Ethernet" },
{ "Broadcom BCM57304 NetXtreme-C Ethernet Virtual Function" },
{ "Broadcom BCM57404 NetXtreme-E Ethernet Virtual Function" },
};
Expand All @@ -103,6 +105,7 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
{ PCI_VDEVICE(BROADCOM, 0x16d0), .driver_data = BCM57402 },
{ PCI_VDEVICE(BROADCOM, 0x16d1), .driver_data = BCM57404 },
{ PCI_VDEVICE(BROADCOM, 0x16d2), .driver_data = BCM57406 },
{ PCI_VDEVICE(BROADCOM, 0x16df), .driver_data = BCM57314 },
#ifdef CONFIG_BNXT_SRIOV
{ PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = BCM57304_VF },
{ PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = BCM57404_VF },
Expand Down Expand Up @@ -1324,15 +1327,6 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons,
((data) & \
HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_PORT_ID_MASK)

#define BNXT_EVENT_POLICY_MASK \
HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_MASK

#define BNXT_EVENT_POLICY_SFT \
HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_SFT

#define BNXT_GET_EVENT_POLICY(data) \
(((data) & BNXT_EVENT_POLICY_MASK) >> BNXT_EVENT_POLICY_SFT)

static int bnxt_async_event_process(struct bnxt *bp,
struct hwrm_async_event_cmpl *cmpl)
{
Expand Down Expand Up @@ -1371,9 +1365,6 @@ static int bnxt_async_event_process(struct bnxt *bp,
if (bp->pf.port_id != port_id)
break;

bp->link_info.last_port_module_event =
BNXT_GET_EVENT_POLICY(data1);

set_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event);
break;
}
Expand Down Expand Up @@ -1503,7 +1494,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
/* The valid test of the entry must be done first before
* reading any further.
*/
rmb();
dma_rmb();
if (TX_CMP_TYPE(txcmp) == CMP_TYPE_TX_L2_CMP) {
tx_pkts++;
/* return full budget so NAPI will complete. */
Expand Down Expand Up @@ -2780,7 +2771,7 @@ void bnxt_hwrm_cmd_hdr_init(struct bnxt *bp, void *request, u16 req_type,
static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
int timeout, bool silent)
{
int i, intr_process, rc;
int i, intr_process, rc, tmo_count;
struct input *req = msg;
u32 *data = msg;
__le32 *resp_len, *valid;
Expand Down Expand Up @@ -2809,11 +2800,12 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
timeout = DFLT_HWRM_CMD_TIMEOUT;

i = 0;
tmo_count = timeout * 40;
if (intr_process) {
/* Wait until hwrm response cmpl interrupt is processed */
while (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID &&
i++ < timeout) {
usleep_range(600, 800);
i++ < tmo_count) {
usleep_range(25, 40);
}

if (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID) {
Expand All @@ -2824,30 +2816,30 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
} else {
/* Check if response len is updated */
resp_len = bp->hwrm_cmd_resp_addr + HWRM_RESP_LEN_OFFSET;
for (i = 0; i < timeout; i++) {
for (i = 0; i < tmo_count; i++) {
len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >>
HWRM_RESP_LEN_SFT;
if (len)
break;
usleep_range(600, 800);
usleep_range(25, 40);
}

if (i >= timeout) {
if (i >= tmo_count) {
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d\n",
timeout, le16_to_cpu(req->req_type),
le16_to_cpu(req->seq_id), *resp_len);
le16_to_cpu(req->seq_id), len);
return -1;
}

/* Last word of resp contains valid bit */
valid = bp->hwrm_cmd_resp_addr + len - 4;
for (i = 0; i < timeout; i++) {
for (i = 0; i < 5; i++) {
if (le32_to_cpu(*valid) & HWRM_RESP_VALID_MASK)
break;
usleep_range(600, 800);
udelay(1);
}

if (i >= timeout) {
if (i >= 5) {
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d v:%d\n",
timeout, le16_to_cpu(req->req_type),
le16_to_cpu(req->seq_id), len, *valid);
Expand Down Expand Up @@ -4734,6 +4726,7 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
link_info->transceiver = resp->xcvr_pkg_type;
link_info->phy_addr = resp->eee_config_phy_addr &
PORT_PHY_QCFG_RESP_PHY_ADDR_MASK;
link_info->module_status = resp->module_status;

if (bp->flags & BNXT_FLAG_EEE_CAP) {
struct ethtool_eee *eee = &bp->eee;
Expand Down Expand Up @@ -4786,6 +4779,33 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
return 0;
}

static void bnxt_get_port_module_status(struct bnxt *bp)
{
struct bnxt_link_info *link_info = &bp->link_info;
struct hwrm_port_phy_qcfg_output *resp = &link_info->phy_qcfg_resp;
u8 module_status;

if (bnxt_update_link(bp, true))
return;

module_status = link_info->module_status;
switch (module_status) {
case PORT_PHY_QCFG_RESP_MODULE_STATUS_DISABLETX:
case PORT_PHY_QCFG_RESP_MODULE_STATUS_PWRDOWN:
case PORT_PHY_QCFG_RESP_MODULE_STATUS_WARNINGMSG:
netdev_warn(bp->dev, "Unqualified SFP+ module detected on port %d\n",
bp->pf.port_id);
if (bp->hwrm_spec_code >= 0x10201) {
netdev_warn(bp->dev, "Module part number %s\n",
resp->phy_vendor_partnumber);
}
if (module_status == PORT_PHY_QCFG_RESP_MODULE_STATUS_DISABLETX)
netdev_warn(bp->dev, "TX is disabled\n");
if (module_status == PORT_PHY_QCFG_RESP_MODULE_STATUS_PWRDOWN)
netdev_warn(bp->dev, "SFP+ module is shutdown\n");
}
}

static void
bnxt_hwrm_set_pause_common(struct bnxt *bp, struct hwrm_port_phy_cfg_input *req)
{
Expand Down Expand Up @@ -5078,7 +5098,8 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
/* Enable TX queues */
bnxt_tx_enable(bp);
mod_timer(&bp->timer, jiffies + bp->current_interval);
bnxt_update_link(bp, true);
/* Poll link status and check for SFP+ module status */
bnxt_get_port_module_status(bp);

return 0;

Expand Down Expand Up @@ -5613,28 +5634,6 @@ static void bnxt_timer(unsigned long data)
mod_timer(&bp->timer, jiffies + bp->current_interval);
}

static void bnxt_port_module_event(struct bnxt *bp)
{
struct bnxt_link_info *link_info = &bp->link_info;
struct hwrm_port_phy_qcfg_output *resp = &link_info->phy_qcfg_resp;

if (bnxt_update_link(bp, true))
return;

if (link_info->last_port_module_event != 0) {
netdev_warn(bp->dev, "Unqualified SFP+ module detected on port %d\n",
bp->pf.port_id);
if (bp->hwrm_spec_code >= 0x10201) {
netdev_warn(bp->dev, "Module part number %s\n",
resp->phy_vendor_partnumber);
}
}
if (link_info->last_port_module_event == 1)
netdev_warn(bp->dev, "TX is disabled\n");
if (link_info->last_port_module_event == 3)
netdev_warn(bp->dev, "Shutdown SFP+ module\n");
}

static void bnxt_cfg_ntp_filters(struct bnxt *);

static void bnxt_sp_task(struct work_struct *work)
Expand Down Expand Up @@ -5683,7 +5682,7 @@ static void bnxt_sp_task(struct work_struct *work)
}

if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event))
bnxt_port_module_event(bp);
bnxt_get_port_module_status(bp);

if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event))
bnxt_hwrm_port_qstats(bp);
Expand Down Expand Up @@ -6260,6 +6259,22 @@ static int bnxt_set_dflt_rings(struct bnxt *bp)
return rc;
}

static void bnxt_parse_log_pcie_link(struct bnxt *bp)
{
enum pcie_link_width width = PCIE_LNK_WIDTH_UNKNOWN;
enum pci_bus_speed speed = PCI_SPEED_UNKNOWN;

if (pcie_get_minimum_link(bp->pdev, &speed, &width) ||
speed == PCI_SPEED_UNKNOWN || width == PCIE_LNK_WIDTH_UNKNOWN)
netdev_info(bp->dev, "Failed to determine PCIe Link Info\n");
else
netdev_info(bp->dev, "PCIe: Speed %s Width x%d\n",
speed == PCIE_SPEED_2_5GT ? "2.5GT/s" :
speed == PCIE_SPEED_5_0GT ? "5.0GT/s" :
speed == PCIE_SPEED_8_0GT ? "8.0GT/s" :
"Unknown", width);
}

static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int version_printed;
Expand Down Expand Up @@ -6380,6 +6395,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
board_info[ent->driver_data].name,
(long)pci_resource_start(pdev, 0), dev->dev_addr);

bnxt_parse_log_pcie_link(bp);

return 0;

init_err:
Expand Down
19 changes: 18 additions & 1 deletion drivers/net/ethernet/broadcom/bnxt/bnxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,10 +425,17 @@ struct rx_tpa_end_cmp_ext {

#define MAX_TPA 64

#if (BNXT_PAGE_SHIFT == 16)
#define MAX_RX_PAGES 1
#define MAX_RX_AGG_PAGES 4
#define MAX_TX_PAGES 1
#define MAX_CP_PAGES 8
#else
#define MAX_RX_PAGES 8
#define MAX_RX_AGG_PAGES 32
#define MAX_TX_PAGES 8
#define MAX_CP_PAGES 64
#endif

#define RX_DESC_CNT (BNXT_PAGE_SIZE / sizeof(struct rx_bd))
#define TX_DESC_CNT (BNXT_PAGE_SIZE / sizeof(struct tx_bd))
Expand Down Expand Up @@ -831,6 +838,7 @@ struct bnxt_link_info {
u16 lp_auto_link_speeds;
u16 force_link_speed;
u32 preemphasis;
u8 module_status;

/* copy of requested setting from ethtool cmd */
u8 autoneg;
Expand All @@ -842,7 +850,6 @@ struct bnxt_link_info {
u32 advertising;
bool force_link_chng;

u8 last_port_module_event;
/* a copy of phy_qcfg output used to report link
* info to VF
*/
Expand Down Expand Up @@ -1123,6 +1130,16 @@ static inline void bnxt_disable_poll(struct bnxt_napi *bnapi)

#endif

#define I2C_DEV_ADDR_A0 0xa0
#define I2C_DEV_ADDR_A2 0xa2
#define SFP_EEPROM_SFF_8472_COMP_ADDR 0x5e
#define SFP_EEPROM_SFF_8472_COMP_SIZE 1
#define SFF_MODULE_ID_SFP 0x3
#define SFF_MODULE_ID_QSFP 0xc
#define SFF_MODULE_ID_QSFP_PLUS 0xd
#define SFF_MODULE_ID_QSFP28 0x11
#define BNXT_MAX_PHY_I2C_RESP_SIZE 64

void bnxt_set_ring_params(struct bnxt *);
void bnxt_hwrm_cmd_hdr_init(struct bnxt *, void *, u16, u16, u16);
int _hwrm_send_message(struct bnxt *, void *, u32, int);
Expand Down
Loading

0 comments on commit bf14e9e

Please sign in to comment.