From 3874d6a8b61966a77aa743b4160ba96bf3081ce5 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Fri, 26 Feb 2016 03:59:59 -0500 Subject: bnxt_en: Improve bnxt_vf_update_mac(). Allow the VF to setup its own MAC address if the PF has not administratively set it for the VF. To do that, we should always store the MAC address from the firmware. There are 2 cases: 1. The MAC address is valid. This MAC address is assigned by the PF and it needs to override the current VF MAC address. 2. The MAC address is zero. The VF will use a random MAC address by default. By storing this 0 MAC address in the VF structure, it will allow the VF user to change the MAC address later using ndo_set_mac_address() when it sees that the stored MAC address is 0. v2: Expanded descriptions and added more comments. Signed-off-by: Jeffrey Huang Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index c1cc83d7e38c..0b4ca35cee9b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -809,13 +809,19 @@ void bnxt_update_vf_mac(struct bnxt *bp) if (_hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT)) goto update_vf_mac_exit; - if (!is_valid_ether_addr(resp->perm_mac_address)) - goto update_vf_mac_exit; - + /* Store MAC address from the firmware. There are 2 cases: + * 1. MAC address is valid. It is assigned from the PF and we + * need to override the current VF MAC address with it. + * 2. MAC address is zero. The VF will use a random MAC address by + * default but the stored zero MAC will allow the VF user to change + * the random MAC address using ndo_set_mac_address() if he wants. + */ if (!ether_addr_equal(resp->perm_mac_address, bp->vf.mac_addr)) memcpy(bp->vf.mac_addr, resp->perm_mac_address, ETH_ALEN); - /* overwrite netdev dev_adr with admin VF MAC */ - memcpy(bp->dev->dev_addr, bp->vf.mac_addr, ETH_ALEN); + + /* overwrite netdev dev_addr with admin VF MAC */ + if (is_valid_ether_addr(bp->vf.mac_addr)) + memcpy(bp->dev->dev_addr, bp->vf.mac_addr, ETH_ALEN); update_vf_mac_exit: mutex_unlock(&bp->hwrm_cmd_lock); } -- cgit v1.2.3 From 19241368443ff976b1924019d29eef8e972158e7 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Fri, 26 Feb 2016 04:00:00 -0500 Subject: bnxt_en: Send PF driver unload notification to all VFs. During remove_one() when SRIOV is enabled, the PF driver should broadcast PF driver unload notification to all VFs that are attached to VMs. Upon receiving the PF driver unload notification, the VF driver should print a warning message to message log. Certain operations on the VF may not succeed after the PF has unloaded. Signed-off-by: Jeffrey Huang Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 10 ++++-- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 43 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index ff1507f3e226..80c441298e16 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1239,13 +1239,17 @@ static int bnxt_async_event_process(struct bnxt *bp, switch (event_id) { case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE: set_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event); - schedule_work(&bp->sp_task); + break; + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD: + set_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event); break; default: netdev_err(bp->dev, "unhandled ASYNC event (id 0x%x)\n", event_id); - break; + goto async_event_process_exit; } + schedule_work(&bp->sp_task); +async_event_process_exit: return 0; } @@ -5559,6 +5563,8 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp) } } } + if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) + netdev_info(bp->dev, "Receive PF driver unload event!"); } #else diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 2be51b332652..cc798d5a3527 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -986,6 +986,7 @@ struct bnxt { #define BNXT_VXLAN_DEL_PORT_SP_EVENT 5 #define BNXT_RESET_TASK_SP_EVENT 6 #define BNXT_RST_RING_SP_EVENT 7 +#define BNXT_HWRM_PF_UNLOAD_SP_EVENT 8 struct bnxt_pf_info pf; #ifdef CONFIG_BNXT_SRIOV diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 0b4ca35cee9b..9f6b4cc6bd0e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -522,6 +522,46 @@ 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); @@ -530,6 +570,9 @@ void bnxt_sriov_disable(struct bnxt *bp) return; if (pci_vfs_assigned(bp->pdev)) { + bnxt_hwrm_fwd_async_event_cmpl( + bp, NULL, + HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD); netdev_warn(bp->dev, "Unable to free %d VFs because some are assigned to VMs.\n", num_vfs); } else { -- cgit v1.2.3 From dfb5b894f87cb78168e04283e8d15626dc3e6d5a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:01 -0500 Subject: bnxt_en: Store irq coalescing timer values in micro seconds. Don't convert these to internal hardware tick values before storing them. This avoids the confusion of ethtool -c returning slightly different values than the ones set using ethtool -C when we convert hardware tick values back to micro seconds. Add better comments for the hardware settings. Also, rename the current set of coalescing fields with rx_ prefix. The next patch will add support of tx coalescing values. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 33 ++++++++++++++--------- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 9 +++---- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 21 +++++++-------- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 80c441298e16..a7103b5cde1c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -3532,20 +3532,25 @@ int bnxt_hwrm_set_coal(struct bnxt *bp) bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1); - /* Each rx completion (2 records) should be DMAed immediately */ - max_buf = min_t(u16, bp->coal_bufs / 4, 2); + /* Each rx completion (2 records) should be DMAed immediately. + * DMA 1/4 of the completion buffers at a time. + */ + max_buf = min_t(u16, bp->rx_coal_bufs / 4, 2); /* max_buf must not be zero */ max_buf = clamp_t(u16, max_buf, 1, 63); - max_buf_irq = clamp_t(u16, bp->coal_bufs_irq, 1, 63); - buf_tmr = max_t(u16, bp->coal_ticks / 4, 1); - buf_tmr_irq = max_t(u16, bp->coal_ticks_irq, 1); + max_buf_irq = clamp_t(u16, bp->rx_coal_bufs_irq, 1, 63); + buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal_ticks); + /* buf timer set to 1/4 of interrupt timer */ + buf_tmr = max_t(u16, buf_tmr / 4, 1); + buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal_ticks_irq); + buf_tmr_irq = max_t(u16, buf_tmr_irq, 1); flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET; /* RING_IDLE generates more IRQs for lower latency. Enable it only * if coal_ticks is less than 25 us. */ - if (BNXT_COAL_TIMER_TO_USEC(bp->coal_ticks) < 25) + if (bp->rx_coal_ticks < 25) flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE; req.flags = cpu_to_le16(flags); @@ -3553,9 +3558,10 @@ int bnxt_hwrm_set_coal(struct bnxt *bp) req.num_cmpl_dma_aggr_during_int = cpu_to_le16(max_buf_irq); req.cmpl_aggr_dma_tmr = cpu_to_le16(buf_tmr); req.cmpl_aggr_dma_tmr_during_int = cpu_to_le16(buf_tmr_irq); - req.int_lat_tmr_min = cpu_to_le16(buf_tmr); - req.int_lat_tmr_max = cpu_to_le16(bp->coal_ticks); - req.num_cmpl_aggr_int = cpu_to_le16(bp->coal_bufs); + /* Minimum time between 2 interrupts set to buf_tmr x 2 */ + req.int_lat_tmr_min = cpu_to_le16(buf_tmr * 2); + req.int_lat_tmr_max = cpu_to_le16(buf_tmr * 4); + req.num_cmpl_aggr_int = cpu_to_le16(max_buf * 4); mutex_lock(&bp->hwrm_cmd_lock); for (i = 0; i < bp->cp_nr_rings; i++) { @@ -5295,10 +5301,11 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) bp->rx_ring_size = BNXT_DEFAULT_RX_RING_SIZE; bp->tx_ring_size = BNXT_DEFAULT_TX_RING_SIZE; - bp->coal_ticks = BNXT_USEC_TO_COAL_TIMER(4); - bp->coal_bufs = 20; - bp->coal_ticks_irq = BNXT_USEC_TO_COAL_TIMER(1); - bp->coal_bufs_irq = 2; + /* tick values in micro seconds */ + bp->rx_coal_ticks = 4; + bp->rx_coal_bufs = 20; + bp->rx_coal_ticks_irq = 1; + bp->rx_coal_bufs_irq = 2; init_timer(&bp->timer); bp->timer.data = (unsigned long)bp; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index cc798d5a3527..6913307e7612 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -968,13 +968,12 @@ struct bnxt { __le16 vxlan_fw_dst_port_id; u8 nge_port_cnt; __le16 nge_fw_dst_port_id; - u16 coal_ticks; - u16 coal_ticks_irq; - u16 coal_bufs; - u16 coal_bufs_irq; + u16 rx_coal_ticks; + u16 rx_coal_ticks_irq; + u16 rx_coal_bufs; + u16 rx_coal_bufs_irq; #define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2) -#define BNXT_COAL_TIMER_TO_USEC(x) ((x) * 2 / 25) struct work_struct sp_task; unsigned long sp_event; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 3238817dfd5f..d18a97727394 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -41,12 +41,11 @@ static int bnxt_get_coalesce(struct net_device *dev, memset(coal, 0, sizeof(*coal)); - coal->rx_coalesce_usecs = - max_t(u16, BNXT_COAL_TIMER_TO_USEC(bp->coal_ticks), 1); - coal->rx_max_coalesced_frames = bp->coal_bufs / 2; - coal->rx_coalesce_usecs_irq = - max_t(u16, BNXT_COAL_TIMER_TO_USEC(bp->coal_ticks_irq), 1); - coal->rx_max_coalesced_frames_irq = bp->coal_bufs_irq / 2; + coal->rx_coalesce_usecs = bp->rx_coal_ticks; + /* 2 completion records per rx packet */ + coal->rx_max_coalesced_frames = bp->rx_coal_bufs / 2; + coal->rx_coalesce_usecs_irq = bp->rx_coal_ticks_irq; + coal->rx_max_coalesced_frames_irq = bp->rx_coal_bufs_irq / 2; return 0; } @@ -57,11 +56,11 @@ static int bnxt_set_coalesce(struct net_device *dev, struct bnxt *bp = netdev_priv(dev); int rc = 0; - bp->coal_ticks = BNXT_USEC_TO_COAL_TIMER(coal->rx_coalesce_usecs); - bp->coal_bufs = coal->rx_max_coalesced_frames * 2; - bp->coal_ticks_irq = - BNXT_USEC_TO_COAL_TIMER(coal->rx_coalesce_usecs_irq); - bp->coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2; + bp->rx_coal_ticks = coal->rx_coalesce_usecs; + /* 2 completion records per rx packet */ + bp->rx_coal_bufs = coal->rx_max_coalesced_frames * 2; + bp->rx_coal_ticks_irq = coal->rx_coalesce_usecs_irq; + bp->rx_coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2; if (netif_running(dev)) rc = bnxt_hwrm_set_coal(bp); -- cgit v1.2.3 From bb053f52a54d66a6057c2220458349f7d39ce0d2 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:02 -0500 Subject: bnxt_en: Refactor bnxt_hwrm_set_coal(). Add a function to set all the coalescing parameters. The function can be used later to set both rx and tx coalescing parameters. v2: Fixed function parameters formatting requested by DaveM. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index a7103b5cde1c..a391c9c9ab68 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -3521,6 +3521,21 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path) } } +static void bnxt_hwrm_set_coal_params(struct bnxt *bp, u32 max_bufs, + u32 buf_tmrs, u16 flags, + struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req) +{ + req->flags = cpu_to_le16(flags); + req->num_cmpl_dma_aggr = cpu_to_le16((u16)max_bufs); + req->num_cmpl_dma_aggr_during_int = cpu_to_le16(max_bufs >> 16); + req->cmpl_aggr_dma_tmr = cpu_to_le16((u16)buf_tmrs); + req->cmpl_aggr_dma_tmr_during_int = cpu_to_le16(buf_tmrs >> 16); + /* Minimum time between 2 interrupts set to buf_tmr x 2 */ + req->int_lat_tmr_min = cpu_to_le16((u16)buf_tmrs * 2); + req->int_lat_tmr_max = cpu_to_le16((u16)buf_tmrs * 4); + req->num_cmpl_aggr_int = cpu_to_le16((u16)max_bufs * 4); +} + int bnxt_hwrm_set_coal(struct bnxt *bp) { int i, rc = 0; @@ -3553,15 +3568,8 @@ int bnxt_hwrm_set_coal(struct bnxt *bp) if (bp->rx_coal_ticks < 25) flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE; - req.flags = cpu_to_le16(flags); - req.num_cmpl_dma_aggr = cpu_to_le16(max_buf); - req.num_cmpl_dma_aggr_during_int = cpu_to_le16(max_buf_irq); - req.cmpl_aggr_dma_tmr = cpu_to_le16(buf_tmr); - req.cmpl_aggr_dma_tmr_during_int = cpu_to_le16(buf_tmr_irq); - /* Minimum time between 2 interrupts set to buf_tmr x 2 */ - req.int_lat_tmr_min = cpu_to_le16(buf_tmr * 2); - req.int_lat_tmr_max = cpu_to_le16(buf_tmr * 4); - req.num_cmpl_aggr_int = cpu_to_le16(max_buf * 4); + bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf, + buf_tmr_irq << 16 | buf_tmr, flags, &req); mutex_lock(&bp->hwrm_cmd_lock); for (i = 0; i < bp->cp_nr_rings; i++) { -- cgit v1.2.3 From dfc9c94a83909f4be80e5d0c67e79793830aa312 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:03 -0500 Subject: bnxt_en: Add coalescing support for tx rings. When tx and rx rings don't share the same completion ring, tx coalescing parameters can be set differently from the rx coalescing parameters. Otherwise, use rx coalescing parameters on shared completion rings. Adjust rx coalescing default values to lower interrupt rate. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 42 ++++++++++++++++++----- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 5 +++ drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 10 ++++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index a391c9c9ab68..198c69d49556 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -3539,13 +3539,16 @@ static void bnxt_hwrm_set_coal_params(struct bnxt *bp, u32 max_bufs, int bnxt_hwrm_set_coal(struct bnxt *bp) { int i, rc = 0; - struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req = {0}; + struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0}, + req_tx = {0}, *req; u16 max_buf, max_buf_irq; u16 buf_tmr, buf_tmr_irq; u32 flags; - bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, - -1, -1); + bnxt_hwrm_cmd_hdr_init(bp, &req_rx, + HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1); + bnxt_hwrm_cmd_hdr_init(bp, &req_tx, + HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1); /* Each rx completion (2 records) should be DMAed immediately. * DMA 1/4 of the completion buffers at a time. @@ -3569,13 +3572,31 @@ int bnxt_hwrm_set_coal(struct bnxt *bp) flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE; bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf, - buf_tmr_irq << 16 | buf_tmr, flags, &req); + buf_tmr_irq << 16 | buf_tmr, flags, &req_rx); + + /* max_buf must not be zero */ + max_buf = clamp_t(u16, bp->tx_coal_bufs, 1, 63); + max_buf_irq = clamp_t(u16, bp->tx_coal_bufs_irq, 1, 63); + buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal_ticks); + /* buf timer set to 1/4 of interrupt timer */ + buf_tmr = max_t(u16, buf_tmr / 4, 1); + buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal_ticks_irq); + buf_tmr_irq = max_t(u16, buf_tmr_irq, 1); + + flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET; + bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf, + buf_tmr_irq << 16 | buf_tmr, flags, &req_tx); mutex_lock(&bp->hwrm_cmd_lock); for (i = 0; i < bp->cp_nr_rings; i++) { - req.ring_id = cpu_to_le16(bp->grp_info[i].cp_fw_ring_id); + struct bnxt_napi *bnapi = bp->bnapi[i]; - rc = _hwrm_send_message(bp, &req, sizeof(req), + req = &req_rx; + if (!bnapi->rx_ring) + req = &req_tx; + req->ring_id = cpu_to_le16(bp->grp_info[i].cp_fw_ring_id); + + rc = _hwrm_send_message(bp, req, sizeof(*req), HWRM_CMD_TIMEOUT); if (rc) break; @@ -5310,11 +5331,16 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) bp->tx_ring_size = BNXT_DEFAULT_TX_RING_SIZE; /* tick values in micro seconds */ - bp->rx_coal_ticks = 4; - bp->rx_coal_bufs = 20; + bp->rx_coal_ticks = 12; + bp->rx_coal_bufs = 30; bp->rx_coal_ticks_irq = 1; bp->rx_coal_bufs_irq = 2; + bp->tx_coal_ticks = 25; + bp->tx_coal_bufs = 30; + bp->tx_coal_ticks_irq = 2; + bp->tx_coal_bufs_irq = 2; + init_timer(&bp->timer); bp->timer.data = (unsigned long)bp; bp->timer.function = bnxt_timer; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 6913307e7612..ba67c4a66ef3 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -968,10 +968,15 @@ struct bnxt { __le16 vxlan_fw_dst_port_id; u8 nge_port_cnt; __le16 nge_fw_dst_port_id; + u16 rx_coal_ticks; u16 rx_coal_ticks_irq; u16 rx_coal_bufs; u16 rx_coal_bufs_irq; + u16 tx_coal_ticks; + u16 tx_coal_ticks_irq; + u16 tx_coal_bufs; + u16 tx_coal_bufs_irq; #define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index d18a97727394..a2d25499a73c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -47,6 +47,11 @@ static int bnxt_get_coalesce(struct net_device *dev, coal->rx_coalesce_usecs_irq = bp->rx_coal_ticks_irq; coal->rx_max_coalesced_frames_irq = bp->rx_coal_bufs_irq / 2; + coal->tx_coalesce_usecs = bp->tx_coal_ticks; + coal->tx_max_coalesced_frames = bp->tx_coal_bufs; + coal->tx_coalesce_usecs_irq = bp->tx_coal_ticks_irq; + coal->tx_max_coalesced_frames_irq = bp->tx_coal_bufs_irq; + return 0; } @@ -62,6 +67,11 @@ static int bnxt_set_coalesce(struct net_device *dev, bp->rx_coal_ticks_irq = coal->rx_coalesce_usecs_irq; bp->rx_coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2; + bp->tx_coal_ticks = coal->tx_coalesce_usecs; + bp->tx_coal_bufs = coal->tx_max_coalesced_frames; + bp->tx_coal_ticks_irq = coal->tx_coalesce_usecs_irq; + bp->tx_coal_bufs_irq = coal->tx_max_coalesced_frames_irq; + if (netif_running(dev)) rc = bnxt_hwrm_set_coal(bp); -- cgit v1.2.3 From ff4fe81d2d49e3cad3bb45c8c5b9a49ca90ee10b Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:04 -0500 Subject: bnxt_en: Use firmware provided message timeout value. Before this patch, we used a hardcoded value of 500 msec as the default value for firmware message response timeout. For better portability with future hardware or debug platforms, use the value provided by firmware in the first response and store it for all susequent messages. Redefine the macro HWRM_CMD_TIMEOUT to the stored value. Since we don't have the value yet in the first message, use the 500 ms default if the stored value is zero. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 7 +++++++ drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 198c69d49556..05a93a7efd8c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2638,6 +2638,9 @@ int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) /* Ring channel doorbell */ writel(1, bp->bar0 + 0x100); + if (!timeout) + timeout = DFLT_HWRM_CMD_TIMEOUT; + i = 0; if (intr_process) { /* Wait until hwrm response cmpl interrupt is processed */ @@ -3809,6 +3812,10 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp) resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld, resp->hwrm_intf_maj, resp->hwrm_intf_min, resp->hwrm_intf_upd); + bp->hwrm_cmd_timeout = le16_to_cpu(resp->def_req_timeout); + if (!bp->hwrm_cmd_timeout) + bp->hwrm_cmd_timeout = DFLT_HWRM_CMD_TIMEOUT; + hwrm_ver_get_exit: mutex_unlock(&bp->hwrm_cmd_lock); return rc; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index ba67c4a66ef3..a3d49406c9c3 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -477,7 +477,8 @@ struct rx_tpa_end_cmp_ext { #define RING_CMP(idx) ((idx) & bp->cp_ring_mask) #define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1)) -#define HWRM_CMD_TIMEOUT 500 +#define DFLT_HWRM_CMD_TIMEOUT 500 +#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout) #define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4) #define HWRM_RESP_ERR_CODE_MASK 0xffff #define HWRM_RESP_LEN_MASK 0xffff0000 @@ -957,6 +958,7 @@ struct bnxt { void *hwrm_dbg_resp_addr; dma_addr_t hwrm_dbg_resp_dma_addr; #define HWRM_DBG_REG_BUF_SIZE 128 + int hwrm_cmd_timeout; struct mutex hwrm_cmd_lock; /* serialize hwrm messages */ struct hwrm_ver_get_output ver_resp; #define FW_VER_STR_LEN 32 -- cgit v1.2.3 From a8643e1604c1f39a675c6b10a7f84260fa13590c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:05 -0500 Subject: bnxt_en: Fix dmesg log firmware error messages. Use appropriate firmware request header structure to prepare the firmware messages. This avoids the unnecessary conversion of the fields to 32-bit fields. Add appropriate endian conversion when printing out the message fields in dmesg so that they appear correct in the log. Reported-by: Rob Swindell Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 29 +++++++++++-------------- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 15 ++----------- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 4 ++-- 3 files changed, 17 insertions(+), 31 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 05a93a7efd8c..9ff498e32743 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2600,28 +2600,26 @@ alloc_mem_err: void bnxt_hwrm_cmd_hdr_init(struct bnxt *bp, void *request, u16 req_type, u16 cmpl_ring, u16 target_id) { - struct hwrm_cmd_req_hdr *req = request; + struct input *req = request; - req->cmpl_ring_req_type = - cpu_to_le32(req_type | (cmpl_ring << HWRM_CMPL_RING_SFT)); - req->target_id_seq_id = cpu_to_le32(target_id << HWRM_TARGET_FID_SFT); + req->req_type = cpu_to_le16(req_type); + req->cmpl_ring = cpu_to_le16(cmpl_ring); + req->target_id = cpu_to_le16(target_id); req->resp_addr = cpu_to_le64(bp->hwrm_cmd_resp_dma_addr); } int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) { int i, intr_process, rc; - struct hwrm_cmd_req_hdr *req = msg; + struct input *req = msg; u32 *data = msg; __le32 *resp_len, *valid; u16 cp_ring_id, len = 0; struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr; - req->target_id_seq_id |= cpu_to_le32(bp->hwrm_cmd_seq++); + req->seq_id = cpu_to_le16(bp->hwrm_cmd_seq++); memset(resp, 0, PAGE_SIZE); - cp_ring_id = (le32_to_cpu(req->cmpl_ring_req_type) & - HWRM_CMPL_RING_MASK) >> - HWRM_CMPL_RING_SFT; + cp_ring_id = le16_to_cpu(req->cmpl_ring); intr_process = (cp_ring_id == INVALID_HW_RING_ID) ? 0 : 1; /* Write request msg to hwrm channel */ @@ -2632,8 +2630,7 @@ int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) /* currently supports only one outstanding message */ if (intr_process) - bp->hwrm_intr_seq_id = le32_to_cpu(req->target_id_seq_id) & - HWRM_SEQ_ID_MASK; + bp->hwrm_intr_seq_id = le16_to_cpu(req->seq_id); /* Ring channel doorbell */ writel(1, bp->bar0 + 0x100); @@ -2651,7 +2648,7 @@ int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) if (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID) { netdev_err(bp->dev, "Resp cmpl intr err msg: 0x%x\n", - req->cmpl_ring_req_type); + le16_to_cpu(req->req_type)); return -1; } } else { @@ -2667,8 +2664,8 @@ int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) if (i >= timeout) { netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d\n", - timeout, req->cmpl_ring_req_type, - req->target_id_seq_id, *resp_len); + timeout, le16_to_cpu(req->req_type), + le16_to_cpu(req->seq_id), *resp_len); return -1; } @@ -2682,8 +2679,8 @@ int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) if (i >= timeout) { netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d v:%d\n", - timeout, req->cmpl_ring_req_type, - req->target_id_seq_id, len, *valid); + timeout, le16_to_cpu(req->req_type), + le16_to_cpu(req->seq_id), len, *valid); return -1; } } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index a3d49406c9c3..3936e966595e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -481,9 +481,11 @@ struct rx_tpa_end_cmp_ext { #define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout) #define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4) #define HWRM_RESP_ERR_CODE_MASK 0xffff +#define HWRM_RESP_LEN_OFFSET 4 #define HWRM_RESP_LEN_MASK 0xffff0000 #define HWRM_RESP_LEN_SFT 16 #define HWRM_RESP_VALID_MASK 0xff000000 +#define HWRM_SEQ_ID_INVALID -1 #define BNXT_HWRM_REQ_MAX_SIZE 128 #define BNXT_HWRM_REQS_PER_PAGE (BNXT_PAGE_SIZE / \ BNXT_HWRM_REQ_MAX_SIZE) @@ -645,19 +647,6 @@ struct bnxt_irq { #define INVALID_STATS_CTX_ID -1 -struct hwrm_cmd_req_hdr { -#define HWRM_CMPL_RING_MASK 0xffff0000 -#define HWRM_CMPL_RING_SFT 16 - __le32 cmpl_ring_req_type; -#define HWRM_SEQ_ID_MASK 0xffff -#define HWRM_SEQ_ID_INVALID -1 -#define HWRM_RESP_LEN_OFFSET 4 -#define HWRM_TARGET_FID_MASK 0xffff0000 -#define HWRM_TARGET_FID_SFT 16 - __le32 target_id_seq_id; - __le64 resp_addr; -}; - struct bnxt_ring_grp_info { u16 fw_stats_ctx; u16 fw_grp_id; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 9f6b4cc6bd0e..0c5f510492f1 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -801,8 +801,8 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf) static int bnxt_vf_req_validate_snd(struct bnxt *bp, struct bnxt_vf_info *vf) { int rc = 0; - struct hwrm_cmd_req_hdr *encap_req = vf->hwrm_cmd_req_addr; - u32 req_type = le32_to_cpu(encap_req->cmpl_ring_req_type) & 0xffff; + struct input *encap_req = vf->hwrm_cmd_req_addr; + u32 req_type = le16_to_cpu(encap_req->req_type); switch (req_type) { case HWRM_CFA_L2_FILTER_ALLOC: -- cgit v1.2.3 From 3ebf6f0a09a284adef62111c7cfca29f56d6cce7 Mon Sep 17 00:00:00 2001 From: Rob Swindell Date: Fri, 26 Feb 2016 04:00:06 -0500 Subject: bnxt_en: Add installed-package firmware version reporting via Ethtool GDRVINFO For everything to fit, we remove the PHY microcode version and replace it with the firmware package version in the fw_version string. Signed-off-by: Rob Swindell Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 +- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 95 +++++++++++++++++++++- drivers/net/ethernet/broadcom/bnxt/bnxt_nvm_defs.h | 14 ++++ 3 files changed, 109 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 9ff498e32743..6e45a00905b9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -3805,7 +3805,7 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp) resp->hwrm_intf_upd); netdev_warn(bp->dev, "Please update firmware with HWRM interface 1.0.0 or newer.\n"); } - snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "bc %d.%d.%d rm %d.%d.%d", + snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d/%d.%d.%d", resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld, resp->hwrm_intf_maj, resp->hwrm_intf_min, resp->hwrm_intf_upd); @@ -5725,7 +5725,6 @@ static int bnxt_probe_phy(struct bnxt *bp) { int rc = 0; struct bnxt_link_info *link_info = &bp->link_info; - char phy_ver[PHY_VER_STR_LEN]; rc = bnxt_update_link(bp, false); if (rc) { @@ -5745,11 +5744,6 @@ static int bnxt_probe_phy(struct bnxt *bp) link_info->req_duplex = link_info->duplex_setting; link_info->req_flow_ctrl = link_info->force_pause_setting; } - snprintf(phy_ver, PHY_VER_STR_LEN, " ph %d.%d.%d", - link_info->phy_ver[0], - link_info->phy_ver[1], - link_info->phy_ver[2]); - strcat(bp->fw_ver_str, phy_ver); return rc; } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index a2d25499a73c..bfda92ef1778 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -7,6 +7,7 @@ * the Free Software Foundation. */ +#include #include #include #include @@ -20,6 +21,8 @@ #include "bnxt_fw_hdr.h" /* Firmware hdr constant and structure defs */ #define FLASH_NVRAM_TIMEOUT ((HWRM_CMD_TIMEOUT) * 100) +static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen); + static u32 bnxt_get_msglevel(struct net_device *dev) { struct bnxt *bp = netdev_priv(dev); @@ -469,10 +472,20 @@ static void bnxt_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct bnxt *bp = netdev_priv(dev); + char *pkglog; + char *pkgver = NULL; + pkglog = kmalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL); + if (pkglog) + pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH); strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); - strlcpy(info->fw_version, bp->fw_ver_str, sizeof(info->fw_version)); + if (pkgver && *pkgver != 0 && isdigit(*pkgver)) + snprintf(info->fw_version, sizeof(info->fw_version) - 1, + "%s pkg %s", bp->fw_ver_str, pkgver); + else + strlcpy(info->fw_version, bp->fw_ver_str, + sizeof(info->fw_version)); strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); info->n_stats = BNXT_NUM_STATS * bp->cp_nr_rings; info->testinfo_len = BNXT_NUM_TESTS(bp); @@ -480,6 +493,7 @@ static void bnxt_get_drvinfo(struct net_device *dev, info->eedump_len = 0; /* TODO CHIMP FW: reg dump details */ info->regdump_len = 0; + kfree(pkglog); } static u32 bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info) @@ -1111,6 +1125,85 @@ static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset, return rc; } +static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal, + u16 ext, u16 *index, u32 *item_length, + u32 *data_length) +{ + struct bnxt *bp = netdev_priv(dev); + int rc; + struct hwrm_nvm_find_dir_entry_input req = {0}; + struct hwrm_nvm_find_dir_entry_output *output = bp->hwrm_cmd_resp_addr; + + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_FIND_DIR_ENTRY, -1, -1); + req.enables = 0; + req.dir_idx = 0; + req.dir_type = cpu_to_le16(type); + req.dir_ordinal = cpu_to_le16(ordinal); + req.dir_ext = cpu_to_le16(ext); + req.opt_ordinal = NVM_FIND_DIR_ENTRY_REQ_OPT_ORDINAL_EQ; + rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (rc == 0) { + if (index) + *index = le16_to_cpu(output->dir_idx); + if (item_length) + *item_length = le32_to_cpu(output->dir_item_length); + if (data_length) + *data_length = le32_to_cpu(output->dir_data_length); + } + return rc; +} + +static char *bnxt_parse_pkglog(int desired_field, u8 *data, size_t datalen) +{ + char *retval = NULL; + char *p; + char *value; + int field = 0; + + if (datalen < 1) + return NULL; + /* null-terminate the log data (removing last '\n'): */ + data[datalen - 1] = 0; + for (p = data; *p != 0; p++) { + field = 0; + retval = NULL; + while (*p != 0 && *p != '\n') { + value = p; + while (*p != 0 && *p != '\t' && *p != '\n') + p++; + if (field == desired_field) + retval = value; + if (*p != '\t') + break; + *p = 0; + field++; + p++; + } + if (*p == 0) + break; + *p = 0; + } + return retval; +} + +static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen) +{ + u16 index = 0; + u32 datalen; + + if (bnxt_find_nvram_item(dev, BNX_DIR_TYPE_PKG_LOG, + BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE, + &index, NULL, &datalen) != 0) + return NULL; + + memset(buf, 0, buflen); + if (bnxt_get_nvram_item(dev, index, 0, datalen, buf) != 0) + return NULL; + + return bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, buf, + datalen); +} + static int bnxt_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_nvm_defs.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_nvm_defs.h index 3cf3e1b70b64..43ef392c8588 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_nvm_defs.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_nvm_defs.h @@ -50,10 +50,24 @@ enum bnxt_nvm_directory_type { #define BNX_DIR_ORDINAL_FIRST 0 +#define BNX_DIR_EXT_NONE 0 #define BNX_DIR_EXT_INACTIVE (1 << 0) #define BNX_DIR_EXT_UPDATE (1 << 1) +#define BNX_DIR_ATTR_NONE 0 #define BNX_DIR_ATTR_NO_CHKSUM (1 << 0) #define BNX_DIR_ATTR_PROP_STREAM (1 << 1) +#define BNX_PKG_LOG_MAX_LENGTH 4096 + +enum bnxnvm_pkglog_field_index { + BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP = 0, + BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION = 1, + BNX_PKG_LOG_FIELD_IDX_PKG_VERSION = 2, + BNX_PKG_LOG_FIELD_IDX_PKG_TIMESTAMP = 3, + BNX_PKG_LOG_FIELD_IDX_PKG_CHECKSUM = 4, + BNX_PKG_LOG_FIELD_IDX_INSTALLED_ITEMS = 5, + BNX_PKG_LOG_FIELD_IDX_INSTALLED_MASK = 6 +}; + #endif /* Don't add anything after this line */ -- cgit v1.2.3 From fbfbc4851dd709cf1327afc283f9cca00235dcb3 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:07 -0500 Subject: bnxt_en: Refactor _hwrm_send_message(). Add a new function bnxt_do_send_msg() to do essentially the same thing with an additional paramter to silence error response messages. All current callers will set silent to false. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 6e45a00905b9..48a7bbc7cc25 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2608,7 +2608,8 @@ void bnxt_hwrm_cmd_hdr_init(struct bnxt *bp, void *request, u16 req_type, req->resp_addr = cpu_to_le64(bp->hwrm_cmd_resp_dma_addr); } -int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) +static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len, + int timeout, bool silent) { int i, intr_process, rc; struct input *req = msg; @@ -2686,13 +2687,16 @@ int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) } rc = le16_to_cpu(resp->error_code); - if (rc) { + if (rc && !silent) netdev_err(bp->dev, "hwrm req_type 0x%x seq id 0x%x error 0x%x\n", le16_to_cpu(resp->req_type), le16_to_cpu(resp->seq_id), rc); - return rc; - } - return 0; + return rc; +} + +int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) +{ + return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, false); } int hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) -- cgit v1.2.3 From 90e209213096110bce06ef580e1c73702fe4a288 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:08 -0500 Subject: bnxt_en: Add hwrm_send_message_silent(). This is used to send NVM_FIND_DIR_ENTRY messages which can return error if the entry is not found. This is normal and the error message will cause unnecessary alarm, so silence it. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 11 +++++++++++ drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 48a7bbc7cc25..aa6a3189caca 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2709,6 +2709,17 @@ int hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) return rc; } +int hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 msg_len, + int timeout) +{ + int rc; + + mutex_lock(&bp->hwrm_cmd_lock); + rc = bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, true); + mutex_unlock(&bp->hwrm_cmd_lock); + return rc; +} + static int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp) { struct hwrm_func_drv_rgtr_input req = {0}; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 3936e966595e..9aa38f57601b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1095,6 +1095,7 @@ 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); int hwrm_send_message(struct bnxt *, void *, u32, int); +int hwrm_send_message_silent(struct bnxt *, void *, u32, int); int bnxt_hwrm_set_coal(struct bnxt *); int bnxt_hwrm_func_qcaps(struct bnxt *); int bnxt_hwrm_set_pause(struct bnxt *); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index bfda92ef1778..84ea26d6f3ff 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1141,7 +1141,7 @@ static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal, req.dir_ordinal = cpu_to_le16(ordinal); req.dir_ext = cpu_to_le16(ext); req.opt_ordinal = NVM_FIND_DIR_ENTRY_REQ_OPT_ORDINAL_EQ; - rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); if (rc == 0) { if (index) *index = le16_to_cpu(output->dir_idx); -- cgit v1.2.3