From a0eaf75c03712b491b7a840b5836c8f1e2a09277 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Mon, 4 Aug 2014 11:51:16 -0400 Subject: [PATCH 1/3] qlcnic: Fix update of ethtool stats. o Aggregating tx stats in adapter variable was resulting in an increase in stats even after no traffic was run and user runs ifconfig/ethtool command. o qlcnic_update_stats used to accumulate stats in adapter struct at each function call, instead accumulate tx stats in local variable and then assign it to adapter structure. Reported-by: Holger Kiehl Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- .../ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 1b7f3dbae289..141f116eb868 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1290,17 +1290,25 @@ static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type) void qlcnic_update_stats(struct qlcnic_adapter *adapter) { + struct qlcnic_tx_queue_stats tx_stats; struct qlcnic_host_tx_ring *tx_ring; int ring; + memset(&tx_stats, 0, sizeof(tx_stats)); for (ring = 0; ring < adapter->drv_tx_rings; ring++) { tx_ring = &adapter->tx_ring[ring]; - adapter->stats.xmit_on += tx_ring->tx_stats.xmit_on; - adapter->stats.xmit_off += tx_ring->tx_stats.xmit_off; - adapter->stats.xmitcalled += tx_ring->tx_stats.xmit_called; - adapter->stats.xmitfinished += tx_ring->tx_stats.xmit_finished; - adapter->stats.txbytes += tx_ring->tx_stats.tx_bytes; + tx_stats.xmit_on += tx_ring->tx_stats.xmit_on; + tx_stats.xmit_off += tx_ring->tx_stats.xmit_off; + tx_stats.xmit_called += tx_ring->tx_stats.xmit_called; + tx_stats.xmit_finished += tx_ring->tx_stats.xmit_finished; + tx_stats.tx_bytes += tx_ring->tx_stats.tx_bytes; } + + adapter->stats.xmit_on = tx_stats.xmit_on; + adapter->stats.xmit_off = tx_stats.xmit_off; + adapter->stats.xmitcalled = tx_stats.xmit_called; + adapter->stats.xmitfinished = tx_stats.xmit_finished; + adapter->stats.txbytes = tx_stats.tx_bytes; } static u64 *qlcnic_fill_tx_queue_stats(u64 *data, void *stats) From bf63014f108aaff49e4382b7adc7d0a2b6365744 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Mon, 4 Aug 2014 11:51:17 -0400 Subject: [PATCH 2/3] qlcnic: Set driver version before registering netdev o Earlier, set_drv_version was getting called after register_netdev. This was resulting in a race between set_drv_version and FLR called from open(). Moving set_drv_version before register_netdev avoids the race. o Log response code in error message on CDRP failure. Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 304e247bdf33..ffbae293cef5 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -136,7 +136,7 @@ int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter, rsp = qlcnic_poll_rsp(adapter); if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) { - dev_err(&pdev->dev, "card response timeout.\n"); + dev_err(&pdev->dev, "command timeout, response = 0x%x\n", rsp); cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT; } else if (rsp == QLCNIC_CDRP_RSP_FAIL) { cmd->rsp.arg[0] = QLCRD32(adapter, QLCNIC_CDRP_ARG(1), &err); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 4fc186713b66..158e1d9f255f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2623,13 +2623,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_out_disable_mbx_intr; + if (adapter->portnum == 0) + qlcnic_set_drv_version(adapter); + err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); if (err) goto err_out_disable_mbx_intr; - if (adapter->portnum == 0) - qlcnic_set_drv_version(adapter); - pci_set_drvdata(pdev, adapter); if (qlcnic_82xx_check(adapter)) From cd1560e2b60fc2fbfadb9200c366eb59fe04f10d Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Mon, 4 Aug 2014 11:51:18 -0400 Subject: [PATCH 3/3] qlcnic: Initialize dcbnl_ops before register_netdev o Initialization of dcbnl_ops after register netdev may result in dcbnl_ops not getting set before it is being accessed from open. So, moving it before register_netdev. Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 158e1d9f255f..3187bc0c471b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2323,14 +2323,14 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, if (err) return err; + qlcnic_dcb_init_dcbnl_ops(adapter->dcb); + err = register_netdev(netdev); if (err) { dev_err(&pdev->dev, "failed to register net device\n"); return err; } - qlcnic_dcb_init_dcbnl_ops(adapter->dcb); - return 0; }