From 4da005cf1e30897520106114a8ce11a5aa558497 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Wed, 11 Jun 2014 14:09:11 -0400 Subject: [PATCH 1/3] qlcnic: Pre-allocate DMA buffer used for minidump collection Pre-allocate the physically contiguous DMA buffer used for minidump collection at driver load time, rather than at run time, to minimize allocation failures. Driver will allocate the buffer at load time if PEX DMA support capability is indicated by the adapter. Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 2 ++ .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 14 ++++++-- .../ethernet/qlogic/qlcnic/qlcnic_minidump.c | 32 +++++++++---------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 41abe6070466..d85f7e1e117f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -441,6 +441,8 @@ struct qlcnic_82xx_dump_template_hdr { u32 rsvd1[0]; }; +#define QLC_PEX_DMA_READ_SIZE (PAGE_SIZE * 16) + struct qlcnic_fw_dump { u8 clr; /* flag to indicate if dump is cleared */ bool enable; /* enable/disable dump */ diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index f06ba90b4282..1c188919cdda 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2087,12 +2087,20 @@ err_out: static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter) { + struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; + kfree(adapter->recv_ctx); adapter->recv_ctx = NULL; - if (adapter->ahw->fw_dump.tmpl_hdr) { - vfree(adapter->ahw->fw_dump.tmpl_hdr); - adapter->ahw->fw_dump.tmpl_hdr = NULL; + if (fw_dump->tmpl_hdr) { + vfree(fw_dump->tmpl_hdr); + fw_dump->tmpl_hdr = NULL; + } + + if (fw_dump->dma_buffer) { + dma_free_coherent(&adapter->pdev->dev, QLC_PEX_DMA_READ_SIZE, + fw_dump->dma_buffer, fw_dump->phys_addr); + fw_dump->dma_buffer = NULL; } kfree(adapter->ahw->reset.buff); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c index f7694da8ed5d..e46fc39d425d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c @@ -660,8 +660,6 @@ out: #define QLC_DMA_CMD_BUFF_ADDR_HI 4 #define QLC_DMA_CMD_STATUS_CTRL 8 -#define QLC_PEX_DMA_READ_SIZE (PAGE_SIZE * 16) - static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter, struct __mem *mem) { @@ -1155,6 +1153,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) u32 version, csum, *tmp_buf; u8 use_flash_temp = 0; u32 temp_size = 0; + void *temp_buffer; int err; ahw = adapter->ahw; @@ -1204,6 +1203,19 @@ flash_temp: qlcnic_cache_tmpl_hdr_values(adapter, fw_dump); + if (fw_dump->use_pex_dma) { + fw_dump->dma_buffer = NULL; + temp_buffer = dma_alloc_coherent(&adapter->pdev->dev, + QLC_PEX_DMA_READ_SIZE, + &fw_dump->phys_addr, + GFP_KERNEL); + if (!temp_buffer) + fw_dump->use_pex_dma = false; + else + fw_dump->dma_buffer = temp_buffer; + } + + dev_info(&adapter->pdev->dev, "Default minidump capture mask 0x%x\n", fw_dump->cap_mask); @@ -1223,7 +1235,7 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter) struct device *dev = &adapter->pdev->dev; struct qlcnic_hardware_context *ahw; struct qlcnic_dump_entry *entry; - void *temp_buffer, *tmpl_hdr; + void *tmpl_hdr; u32 ocm_window; __le32 *buffer; char mesg[64]; @@ -1267,16 +1279,6 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter) qlcnic_set_sys_info(adapter, tmpl_hdr, 0, QLCNIC_DRIVER_VERSION); qlcnic_set_sys_info(adapter, tmpl_hdr, 1, adapter->fw_version); - if (fw_dump->use_pex_dma) { - temp_buffer = dma_alloc_coherent(dev, QLC_PEX_DMA_READ_SIZE, - &fw_dump->phys_addr, - GFP_KERNEL); - if (!temp_buffer) - fw_dump->use_pex_dma = false; - else - fw_dump->dma_buffer = temp_buffer; - } - if (qlcnic_82xx_check(adapter)) { ops_cnt = ARRAY_SIZE(qlcnic_fw_dump_ops); fw_dump_ops = qlcnic_fw_dump_ops; @@ -1334,10 +1336,6 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter) /* Send a udev event to notify availability of FW dump */ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, msg); - if (fw_dump->use_pex_dma) - dma_free_coherent(dev, QLC_PEX_DMA_READ_SIZE, - fw_dump->dma_buffer, fw_dump->phys_addr); - return 0; } From 18e0d625336a7690dcb358e2f4157becfa65183b Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Wed, 11 Jun 2014 14:09:12 -0400 Subject: [PATCH 2/3] qlcnic: Optimize ring count validations - Check interrupt mode at the start of qlcnic_set_channels(). - Do not validate ring count if they are not going to change. Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 9 +++++++-- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 10 ---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 5bacf5210aed..1b7f3dbae289 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -726,6 +726,11 @@ static int qlcnic_set_channels(struct net_device *dev, struct qlcnic_adapter *adapter = netdev_priv(dev); int err; + if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { + netdev_err(dev, "No RSS/TSS support in non MSI-X mode\n"); + return -EINVAL; + } + if (channel->other_count || channel->combined_count) return -EINVAL; @@ -734,7 +739,7 @@ static int qlcnic_set_channels(struct net_device *dev, if (err) return err; - if (channel->rx_count) { + if (adapter->drv_sds_rings != channel->rx_count) { err = qlcnic_validate_rings(adapter, channel->rx_count, QLCNIC_RX_QUEUE); if (err) { @@ -745,7 +750,7 @@ static int qlcnic_set_channels(struct net_device *dev, adapter->drv_rss_rings = channel->rx_count; } - if (channel->tx_count) { + if (adapter->drv_tx_rings != channel->tx_count) { err = qlcnic_validate_rings(adapter, channel->tx_count, QLCNIC_TX_QUEUE); if (err) { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 1c188919cdda..4fc186713b66 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -4003,16 +4003,6 @@ int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt, strcpy(buf, "Tx"); } - if (!QLCNIC_IS_MSI_FAMILY(adapter)) { - netdev_err(netdev, "No RSS/TSS support in INT-x mode\n"); - return -EINVAL; - } - - if (adapter->flags & QLCNIC_MSI_ENABLED) { - netdev_err(netdev, "No RSS/TSS support in MSI mode\n"); - return -EINVAL; - } - if (!is_power_of_2(ring_cnt)) { netdev_err(netdev, "%s rings value should be a power of 2\n", buf); From 038782d6d0d92c3cc98ffc08cd78cfe46a2eca41 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Wed, 11 Jun 2014 14:09:13 -0400 Subject: [PATCH 3/3] qlcnic: Update version to 5.3.60 Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index d85f7e1e117f..be618b9e874f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -39,8 +39,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 3 -#define _QLCNIC_LINUX_SUBVERSION 59 -#define QLCNIC_LINUX_VERSIONID "5.3.59" +#define _QLCNIC_LINUX_SUBVERSION 60 +#define QLCNIC_LINUX_VERSIONID "5.3.60" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))