From f716775026707113496cbd9961882de91ab88b07 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Fri, 25 Apr 2014 11:43:50 +0200 Subject: qlcnic: Use pci_enable_msix_exact() instead of pci_enable_msix() As result of deprecation of MSI-X/MSI enablement functions pci_enable_msix() and pci_enable_msi_block() all drivers using these two interfaces need to be updated to use the new pci_enable_msi_range() or pci_enable_msi_exact() and pci_enable_msix_range() or pci_enable_msix_exact() interfaces. Cc: Shahed Shaikh Cc: Dept-HSGLinuxNICDev@qlogic.com Cc: netdev@vger.kernel.org Cc: linux-pci@vger.kernel.org Signed-off-by: Alexander Gordeev Acked-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index dbf75393f758..73f908a000e9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -690,10 +690,10 @@ int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *adapter) adapter->msix_entries[vector].entry = vector; restore: - err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); - if (err > 0) { + err = pci_enable_msix_exact(pdev, adapter->msix_entries, num_msix); + if (err == -ENOSPC) { if (!adapter->drv_tss_rings && !adapter->drv_rss_rings) - return -ENOSPC; + return err; netdev_info(adapter->netdev, "Unable to allocate %d MSI-X vectors, Available vectors %d\n", -- cgit v1.2.1 From ddfbac07c0e87e221596a439e8fb3937b95db228 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Fri, 25 Apr 2014 17:43:56 -0400 Subject: qlcnic: Optimize MAC learning code * Use rx_mac_learn instead of mac_learn and eSwitch flag check in Rx path of 82xx adapter. * Check for MAC filter overrun only after driver scans through cached MAC address list. This will help to update the time stamp of cached MAC addresses even if adapter runs out of MAC address filter limit. * Remove expensive log thrown by driver when MAC address filters are exhausted Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 173b3d12991f..deb2278b48d5 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -305,7 +305,6 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, { struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data); struct ethhdr *phdr = (struct ethhdr *)(skb->data); - struct net_device *netdev = adapter->netdev; u16 protocol = ntohs(skb->protocol); struct qlcnic_filter *fil, *tmp_fil; struct hlist_head *head; @@ -330,13 +329,6 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, return; } - if (adapter->fhash.fnum >= adapter->fhash.fmax) { - adapter->stats.mac_filter_limit_overrun++; - netdev_info(netdev, "Can not add more than %d mac-vlan filters, configured %d\n", - adapter->fhash.fmax, adapter->fhash.fnum); - return; - } - memcpy(&src_addr, phdr->h_source, ETH_ALEN); hval = qlcnic_mac_hash(src_addr, vlan_id); hindex = hval & (adapter->fhash.fbucket_size - 1); @@ -353,6 +345,11 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, } } + if (unlikely(adapter->fhash.fnum >= adapter->fhash.fmax)) { + adapter->stats.mac_filter_limit_overrun++; + return; + } + fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); if (!fil) return; @@ -1216,8 +1213,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, if (!skb) return buffer; - if (adapter->drv_mac_learn && - (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { + if (adapter->rx_mac_learn) { t_vid = 0; is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0); qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); @@ -1293,8 +1289,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, if (!skb) return buffer; - if (adapter->drv_mac_learn && - (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { + if (adapter->rx_mac_learn) { t_vid = 0; is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0); qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); -- cgit v1.2.1 From 1f0f467b670eec101419a2a1235e315e4324ea07 Mon Sep 17 00:00:00 2001 From: Harish Patil Date: Fri, 25 Apr 2014 17:43:57 -0400 Subject: qlcnic: Add hwmon interface to export board temperature. Signed-off-by: Harish Patil Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 15 ++++++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 4 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 66 +++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 7b52a88923ef..381da04f1b71 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -537,6 +537,7 @@ struct qlcnic_hardware_context { u8 phys_port_id[ETH_ALEN]; u8 lb_mode; u16 vxlan_port; + struct device *hwmon_dev; }; struct qlcnic_adapter_stats { @@ -2361,4 +2362,18 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) else return QLC_DEFAULT_VNIC_COUNT; } + +#ifdef CONFIG_QLCNIC_HWMON +void qlcnic_register_hwmon_dev(struct qlcnic_adapter *); +void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *); +#else +static inline void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter) +{ + return; +} +static inline void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter) +{ + return; +} +#endif #endif /* __QLCNIC_H_ */ diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 73f908a000e9..19878fb393d0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2593,7 +2593,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) qlcnic_alloc_lb_filters_mem(adapter); qlcnic_add_sysfs(adapter); - + qlcnic_register_hwmon_dev(adapter); return 0; err_out_disable_mbx_intr: @@ -2700,6 +2700,8 @@ static void qlcnic_remove(struct pci_dev *pdev) qlcnic_remove_sysfs(adapter); + qlcnic_unregister_hwmon_dev(adapter); + qlcnic_cleanup_pci_map(adapter->ahw); qlcnic_release_firmware(adapter); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index cd346e27f2e1..eee5fc9dd56e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -19,6 +19,10 @@ #include #include #include +#ifdef CONFIG_QLCNIC_HWMON +#include +#include +#endif #define QLC_STATUS_UNSUPPORTED_CMD -2 @@ -1243,6 +1247,68 @@ static struct bin_attribute bin_attr_flash = { .write = qlcnic_83xx_sysfs_flash_write_handler, }; +#ifdef CONFIG_QLCNIC_HWMON + +static ssize_t qlcnic_hwmon_show_temp(struct device *dev, + struct device_attribute *dev_attr, + char *buf) +{ + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + unsigned int temperature = 0, value = 0; + + if (qlcnic_83xx_check(adapter)) + value = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP); + else if (qlcnic_82xx_check(adapter)) + value = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP); + + temperature = qlcnic_get_temp_val(value); + /* display millidegree celcius */ + temperature *= 1000; + return sprintf(buf, "%u\n", temperature); +} + +/* hwmon-sysfs attributes */ +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, + qlcnic_hwmon_show_temp, NULL, 1); + +static struct attribute *qlcnic_hwmon_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + NULL +}; + +ATTRIBUTE_GROUPS(qlcnic_hwmon); + +void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter) +{ + struct device *dev = &adapter->pdev->dev; + struct device *hwmon_dev; + + /* Skip hwmon registration for a VF device */ + if (qlcnic_sriov_vf_check(adapter)) { + adapter->ahw->hwmon_dev = NULL; + return; + } + hwmon_dev = hwmon_device_register_with_groups(dev, qlcnic_driver_name, + adapter, + qlcnic_hwmon_groups); + if (IS_ERR(hwmon_dev)) { + dev_err(dev, "Cannot register with hwmon, err=%ld\n", + PTR_ERR(hwmon_dev)); + hwmon_dev = NULL; + } + adapter->ahw->hwmon_dev = hwmon_dev; +} + +void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter) +{ + struct device *hwmon_dev = adapter->ahw->hwmon_dev; + if (hwmon_dev) { + hwmon_device_unregister(hwmon_dev); + adapter->ahw->hwmon_dev = NULL; + } +} +#endif + void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter) { struct device *dev = &adapter->pdev->dev; -- cgit v1.2.1 From 868e9144314a00f04ee30ab1288338e510b4cf3a Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Fri, 25 Apr 2014 17:43:58 -0400 Subject: qlcnic: Allow setting TX interrupt coalescing parameters from VF. o Tx interrupt coalescing parameters can now be set from VF. o Added validation code in PF to validate the parameters. Signed-off-by: Sucheta Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 13 ++++++++ .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 35 ++++++++++++++++++---- 2 files changed, 42 insertions(+), 6 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 19878fb393d0..5ceff4796df6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2052,6 +2052,7 @@ out: static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) { + struct qlcnic_hardware_context *ahw = adapter->ahw; int err = 0; adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), @@ -2061,6 +2062,18 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) goto err_out; } + if (qlcnic_83xx_check(adapter)) { + ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX_TX; + ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; + ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; + ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; + ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; + } else { + ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; + ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; + ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; + } + /* clear stats */ memset(&adapter->stats, 0, sizeof(adapter->stats)); err_out: diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 280137991544..c7926ce85fec 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -16,6 +16,7 @@ #define QLC_VF_FLOOD_BIT BIT_16 #define QLC_FLOOD_MODE 0x5 #define QLC_SRIOV_ALLOW_VLAN0 BIT_19 +#define QLC_INTR_COAL_TYPE_MASK 0x7 static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8); @@ -1178,19 +1179,41 @@ static int qlcnic_sriov_validate_cfg_intrcoal(struct qlcnic_adapter *adapter, { struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal; u16 ctx_id, pkts, time; + int err = -EINVAL; + u8 type; + type = cmd->req.arg[1] & QLC_INTR_COAL_TYPE_MASK; ctx_id = cmd->req.arg[1] >> 16; pkts = cmd->req.arg[2] & 0xffff; time = cmd->req.arg[2] >> 16; - if (ctx_id != vf->rx_ctx_id) - return -EINVAL; - if (pkts > coal->rx_packets) - return -EINVAL; - if (time < coal->rx_time_us) - return -EINVAL; + switch (type) { + case QLCNIC_INTR_COAL_TYPE_RX: + if (ctx_id != vf->rx_ctx_id || pkts > coal->rx_packets || + time < coal->rx_time_us) + goto err_label; + break; + case QLCNIC_INTR_COAL_TYPE_TX: + if (ctx_id != vf->tx_ctx_id || pkts > coal->tx_packets || + time < coal->tx_time_us) + goto err_label; + break; + default: + netdev_err(adapter->netdev, "Invalid coalescing type 0x%x received\n", + type); + return err; + } return 0; + +err_label: + netdev_err(adapter->netdev, "Expected: rx_ctx_id 0x%x rx_packets 0x%x rx_time_us 0x%x tx_ctx_id 0x%x tx_packets 0x%x tx_time_us 0x%x\n", + vf->rx_ctx_id, coal->rx_packets, coal->rx_time_us, + vf->tx_ctx_id, coal->tx_packets, coal->tx_time_us); + netdev_err(adapter->netdev, "Received: ctx_id 0x%x packets 0x%x time_us 0x%x type 0x%x\n", + ctx_id, pkts, time, type); + + return err; } static int qlcnic_sriov_pf_cfg_intrcoal_cmd(struct qlcnic_bc_trans *tran, -- cgit v1.2.1 From c65762fc2fc8a85c3d8a2024c17815e1a0f5dff0 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Fri, 25 Apr 2014 17:43:59 -0400 Subject: qlcnic: Add driver logs in error path. Signed-off-by: Sucheta Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 3 +++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 2 ++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 13 +++++++++++-- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 +++-- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 2 ++ 5 files changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index b7cffb46a75d..4ea15bafe53f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -879,6 +879,9 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx, return 0; } } + + dev_err(&adapter->pdev->dev, "%s: Invalid mailbox command opcode 0x%x\n", + __func__, type); return -EINVAL; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index ba20c721ee97..34d273794e96 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -2181,6 +2181,8 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) max_sds_rings = QLCNIC_MAX_SDS_RINGS; max_tx_rings = QLCNIC_MAX_TX_RINGS; } else { + dev_err(&adapter->pdev->dev, "%s: Invalid opmode %d\n", + __func__, ret); return -EIO; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index c1e11f5715b0..304e247bdf33 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -1027,8 +1027,11 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, u32 arg1; if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC || - !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) + !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) { + dev_err(&adapter->pdev->dev, "%s: Not a management function\n", + __func__); return err; + } arg1 = id | (enable_mirroring ? BIT_4 : 0); arg1 |= pci_func << 8; @@ -1318,8 +1321,12 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u32 arg1, arg2 = 0; u8 pci_func; - if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) + if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) { + dev_err(&adapter->pdev->dev, "%s: Not a management function\n", + __func__); return err; + } + pci_func = esw_cfg->pci_func; index = qlcnic_is_valid_nic_func(adapter, pci_func); if (index < 0) @@ -1363,6 +1370,8 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, arg1 &= ~(0x0ffff << 16); break; default: + dev_err(&adapter->pdev->dev, "%s: Invalid opmode 0x%x\n", + __func__, esw_cfg->op_mode); return err; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 5ceff4796df6..f2c9a199295d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -1014,6 +1014,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) if (pfn >= ahw->max_vnic_func) { ret = QL_STATUS_INVALID_PARAM; + dev_err(&adapter->pdev->dev, "%s: Invalid function 0x%x, max 0x%x\n", + __func__, pfn, ahw->max_vnic_func); goto err_eswitch; } @@ -2531,8 +2533,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); goto err_out_free_hw; default: - dev_err(&pdev->dev, "Adapter initialization failed. A reboot may be required to recover from this failure\n"); - dev_err(&pdev->dev, "If reboot does not help to recover from this failure, try a flash update of the adapter\n"); + dev_err(&pdev->dev, "Adapter initialization failed. Driver will load in maintenance mode to recover the adapter using the application\n"); goto err_out_maintenance_mode; } } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index eee5fc9dd56e..f5786d5792df 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -362,6 +362,8 @@ int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) if (adapter->npars[i].pci_func == pci_func) return i; } + + dev_err(&adapter->pdev->dev, "%s: Invalid nic function\n", __func__); return -EINVAL; } -- cgit v1.2.1 From aaecf51cf31160262b29a6d50f364f4a76c7ed1e Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Fri, 25 Apr 2014 17:44:00 -0400 Subject: qlcnic: Limit vNIC support in legacy interrupt mode o When the driver loads in legacy interrupt mode, only vNICs with PCI function number 0-7 are supported. Signed-off-by: Sucheta Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 10 +++++++++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 4ea15bafe53f..7c125d7fb547 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -33,6 +33,7 @@ static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *); #define RSS_HASHTYPE_IP_TCP 0x3 #define QLC_83XX_FW_MBX_CMD 0 #define QLC_SKIP_INACTIVE_PCI_REGS 7 +#define QLC_MAX_LEGACY_FUNC_SUPP 8 static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1}, @@ -357,8 +358,15 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter) if (!ahw->intr_tbl) return -ENOMEM; - if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) + if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { + if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) { + dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n", + ahw->pci_func); + return -EOPNOTSUPP; + } + qlcnic_83xx_enable_legacy(adapter); + } for (i = 0; i < num_msix; i++) { if (adapter->flags & QLCNIC_MSIX_ENABLED) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index f2c9a199295d..7023d358baa9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2532,6 +2532,9 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case -ENOMEM: dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); goto err_out_free_hw; + case -EOPNOTSUPP: + dev_err(&pdev->dev, "Adapter initialization failed\n"); + goto err_out_free_hw; default: dev_err(&pdev->dev, "Adapter initialization failed. Driver will load in maintenance mode to recover the adapter using the application\n"); goto err_out_maintenance_mode; -- cgit v1.2.1 From d73657440976f908f71f2a1f8bfd03990a2acb66 Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Fri, 25 Apr 2014 17:44:01 -0400 Subject: qlcnic: Update version to 5.3.58 Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 381da04f1b71..09fe9c276f1c 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 57 -#define QLCNIC_LINUX_VERSIONID "5.3.57" +#define _QLCNIC_LINUX_SUBVERSION 58 +#define QLCNIC_LINUX_VERSIONID "5.3.58" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit v1.2.1 From 132a3f2bee7600366244097658c4c89ac99a8981 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Fri, 9 May 2014 02:51:29 -0400 Subject: qlcnic: Allow SR-IOV VF probe in hypervisor. o Add support for SR-IOV VF probe in hypervisor to enable assignment of VFs within hypervisor. o SR-IOV VF can be uplinked to bridge/macvtap device with this change. o Refactor SR-IOV enable/disable code. We cannot take rtnl lock while enabling/disabling SR-IOV as VF probe will take an rtnl lock. o Disable spoofchk by default. Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 +--- .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 2 +- .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 34 ++++++++++++++-------- 3 files changed, 24 insertions(+), 17 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 7023d358baa9..28ebe1ba5a0b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2398,9 +2398,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int err, pci_using_dac = -1; char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ - if (pdev->is_virtfn) - return -ENODEV; - err = pci_enable_device(pdev); if (err) return err; @@ -2680,9 +2677,9 @@ static void qlcnic_remove(struct pci_dev *pdev) return; netdev = adapter->netdev; - qlcnic_sriov_pf_disable(adapter); qlcnic_cancel_idc_work(adapter); + qlcnic_sriov_pf_disable(adapter); ahw = adapter->ahw; unregister_netdev(netdev); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 0638c1810d54..4eccc2b74f67 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -198,7 +198,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) } sriov->vf_info[i].vp = vp; vp->max_tx_bw = MAX_BW; - vp->spoofchk = true; + vp->spoofchk = false; random_ether_addr(vp->mac); dev_info(&adapter->pdev->dev, "MAC Address %pM is configured for VF %d\n", diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index c7926ce85fec..df409086e4d3 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -472,12 +472,12 @@ static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter) return -EPERM; } + qlcnic_sriov_pf_disable(adapter); + rtnl_lock(); if (netif_running(netdev)) __qlcnic_down(adapter, netdev); - qlcnic_sriov_pf_disable(adapter); - qlcnic_sriov_free_vlans(adapter); qlcnic_sriov_pf_cleanup(adapter); @@ -596,7 +596,6 @@ static int __qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, qlcnic_sriov_alloc_vlans(adapter); - err = qlcnic_sriov_pf_enable(adapter, num_vfs); return err; del_flr_queue: @@ -627,25 +626,36 @@ static int qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, int num_vfs) __qlcnic_down(adapter, netdev); err = __qlcnic_pci_sriov_enable(adapter, num_vfs); - if (err) { - netdev_info(netdev, "Failed to enable SR-IOV on port %d\n", - adapter->portnum); + if (err) + goto error; - err = -EIO; - if (qlcnic_83xx_configure_opmode(adapter)) - goto error; - } else { + if (netif_running(netdev)) + __qlcnic_up(adapter, netdev); + + rtnl_unlock(); + err = qlcnic_sriov_pf_enable(adapter, num_vfs); + if (!err) { netdev_info(netdev, "SR-IOV is enabled successfully on port %d\n", adapter->portnum); /* Return number of vfs enabled */ - err = num_vfs; + return num_vfs; } + + rtnl_lock(); if (netif_running(netdev)) - __qlcnic_up(adapter, netdev); + __qlcnic_down(adapter, netdev); error: + if (!qlcnic_83xx_configure_opmode(adapter)) { + if (netif_running(netdev)) + __qlcnic_up(adapter, netdev); + } + rtnl_unlock(); + netdev_info(netdev, "Failed to enable SR-IOV on port %d\n", + adapter->portnum); + return err; } -- cgit v1.2.1 From 74b7ba1a8bc994f92cfe4716d80c17f90df5eba3 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Fri, 9 May 2014 02:51:30 -0400 Subject: qlcnic: Add support to process commands in atomic context o Commands from VF may sleep during PF-VF communication. Earlier we use to process qlcnic_sriov_vf_set_multi function in process context. Now individual commands that are called in atomic context are processed in process context without waiting for completion of command. Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 24 +--- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 4 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | 3 +- .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 137 ++++++++++----------- .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 36 +++--- 6 files changed, 99 insertions(+), 107 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 09fe9c276f1c..7bad613becba 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -1693,7 +1693,7 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *); int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); void qlcnic_set_netdev_features(struct qlcnic_adapter *, struct qlcnic_esw_func_cfg *); -void qlcnic_sriov_vf_schedule_multi(struct net_device *); +void qlcnic_sriov_vf_set_multi(struct net_device *); int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8); int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *, u16 *); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 9f3adf4e70b5..e5352b70314a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -567,28 +567,14 @@ static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan) void qlcnic_set_multi(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); - struct qlcnic_mac_vlan_list *cur; - struct netdev_hw_addr *ha; - size_t temp; if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) return; - if (qlcnic_sriov_vf_check(adapter)) { - if (!netdev_mc_empty(netdev)) { - netdev_for_each_mc_addr(ha, netdev) { - temp = sizeof(struct qlcnic_mac_vlan_list); - cur = kzalloc(temp, GFP_ATOMIC); - if (cur == NULL) - break; - memcpy(cur->mac_addr, - ha->addr, ETH_ALEN); - list_add_tail(&cur->list, &adapter->vf_mc_list); - } - } - qlcnic_sriov_vf_schedule_multi(adapter->netdev); - return; - } - __qlcnic_set_multi(netdev, 0); + + if (qlcnic_sriov_vf_check(adapter)) + qlcnic_sriov_vf_set_multi(netdev); + else + __qlcnic_set_multi(netdev, 0); } int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 28ebe1ba5a0b..1a52a781401f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -1917,8 +1917,6 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) return; - if (qlcnic_sriov_vf_check(adapter)) - qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); smp_mb(); netif_carrier_off(netdev); adapter->ahw->linkup = 0; @@ -1930,6 +1928,8 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) qlcnic_delete_lb_filters(adapter); qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); + if (qlcnic_sriov_vf_check(adapter)) + qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); qlcnic_napi_disable(adapter); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h index 396bd1fd1d27..54159bde2bc7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h @@ -151,13 +151,14 @@ struct qlcnic_vf_info { struct qlcnic_trans_list rcv_pend; struct qlcnic_adapter *adapter; struct qlcnic_vport *vp; - struct mutex vlan_list_lock; /* Lock for VLAN list */ + spinlock_t vlan_list_lock; /* Lock for VLAN list */ }; struct qlcnic_async_work_list { struct list_head list; struct work_struct work; void *ptr; + struct qlcnic_cmd_args *cmd; }; struct qlcnic_back_channel { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 4eccc2b74f67..44cd5bd03744 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -39,6 +39,8 @@ static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *, u8); static void qlcnic_sriov_process_bc_cmd(struct work_struct *); static int qlcnic_sriov_vf_shutdown(struct pci_dev *); static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *); +static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *, + struct qlcnic_cmd_args *); static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = { .read_crb = qlcnic_83xx_read_crb, @@ -181,7 +183,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) vf->adapter = adapter; vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i); mutex_init(&vf->send_cmd_lock); - mutex_init(&vf->vlan_list_lock); + spin_lock_init(&vf->vlan_list_lock); INIT_LIST_HEAD(&vf->rcv_act.wait_list); INIT_LIST_HEAD(&vf->rcv_pend.wait_list); spin_lock_init(&vf->rcv_act.lock); @@ -1356,7 +1358,7 @@ static int qlcnic_sriov_retry_bc_cmd(struct qlcnic_adapter *adapter, return -EIO; } -static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, +static int __qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd) { struct qlcnic_hardware_context *ahw = adapter->ahw; @@ -1428,6 +1430,16 @@ cleanup_transaction: return rsp; } + +static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, + struct qlcnic_cmd_args *cmd) +{ + if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) + return qlcnic_sriov_async_issue_cmd(adapter, cmd); + else + return __qlcnic_sriov_issue_cmd(adapter, cmd); +} + static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_op) { struct qlcnic_cmd_args cmd; @@ -1458,58 +1470,28 @@ out: return ret; } -static void qlcnic_vf_add_mc_list(struct net_device *netdev) +static void qlcnic_vf_add_mc_list(struct net_device *netdev, const u8 *mac) { struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_sriov *sriov = adapter->ahw->sriov; - struct qlcnic_mac_vlan_list *cur; - struct list_head *head, tmp_list; struct qlcnic_vf_info *vf; u16 vlan_id; int i; - static const u8 bcast_addr[ETH_ALEN] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - vf = &adapter->ahw->sriov->vf_info[0]; - INIT_LIST_HEAD(&tmp_list); - head = &adapter->vf_mc_list; - netif_addr_lock_bh(netdev); - - while (!list_empty(head)) { - cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list); - list_move(&cur->list, &tmp_list); - } - - netif_addr_unlock_bh(netdev); - while (!list_empty(&tmp_list)) { - cur = list_entry((&tmp_list)->next, - struct qlcnic_mac_vlan_list, list); - if (!qlcnic_sriov_check_any_vlan(vf)) { - qlcnic_nic_add_mac(adapter, bcast_addr, 0); - qlcnic_nic_add_mac(adapter, cur->mac_addr, 0); - } else { - mutex_lock(&vf->vlan_list_lock); - for (i = 0; i < sriov->num_allowed_vlans; i++) { - vlan_id = vf->sriov_vlans[i]; - if (vlan_id) { - qlcnic_nic_add_mac(adapter, bcast_addr, - vlan_id); - qlcnic_nic_add_mac(adapter, - cur->mac_addr, - vlan_id); - } - } - mutex_unlock(&vf->vlan_list_lock); - if (qlcnic_84xx_check(adapter)) { - qlcnic_nic_add_mac(adapter, bcast_addr, 0); - qlcnic_nic_add_mac(adapter, cur->mac_addr, 0); - } + if (!qlcnic_sriov_check_any_vlan(vf)) { + qlcnic_nic_add_mac(adapter, mac, 0); + } else { + spin_lock(&vf->vlan_list_lock); + for (i = 0; i < sriov->num_allowed_vlans; i++) { + vlan_id = vf->sriov_vlans[i]; + if (vlan_id) + qlcnic_nic_add_mac(adapter, mac, vlan_id); } - list_del(&cur->list); - kfree(cur); + spin_unlock(&vf->vlan_list_lock); + if (qlcnic_84xx_check(adapter)) + qlcnic_nic_add_mac(adapter, mac, 0); } } @@ -1518,6 +1500,7 @@ void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc) struct list_head *head = &bc->async_list; struct qlcnic_async_work_list *entry; + flush_workqueue(bc->bc_async_wq); while (!list_empty(head)) { entry = list_entry(head->next, struct qlcnic_async_work_list, list); @@ -1527,10 +1510,14 @@ void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc) } } -static void qlcnic_sriov_vf_set_multi(struct net_device *netdev) +void qlcnic_sriov_vf_set_multi(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_hardware_context *ahw = adapter->ahw; + static const u8 bcast_addr[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + struct netdev_hw_addr *ha; u32 mode = VPORT_MISS_MODE_DROP; if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) @@ -1542,23 +1529,27 @@ static void qlcnic_sriov_vf_set_multi(struct net_device *netdev) } else if ((netdev->flags & IFF_ALLMULTI) || (netdev_mc_count(netdev) > ahw->max_mc_count)) { mode = VPORT_MISS_MODE_ACCEPT_MULTI; + } else { + qlcnic_vf_add_mc_list(netdev, bcast_addr); + if (!netdev_mc_empty(netdev)) { + netdev_for_each_mc_addr(ha, netdev) + qlcnic_vf_add_mc_list(netdev, ha->addr); + } } - if (qlcnic_sriov_vf_check(adapter)) - qlcnic_vf_add_mc_list(netdev); - qlcnic_nic_set_promisc(adapter, mode); } -static void qlcnic_sriov_handle_async_multi(struct work_struct *work) +static void qlcnic_sriov_handle_async_issue_cmd(struct work_struct *work) { struct qlcnic_async_work_list *entry; - struct net_device *netdev; + struct qlcnic_adapter *adapter; + struct qlcnic_cmd_args *cmd; entry = container_of(work, struct qlcnic_async_work_list, work); - netdev = (struct net_device *)entry->ptr; - - qlcnic_sriov_vf_set_multi(netdev); + adapter = entry->ptr; + cmd = entry->cmd; + __qlcnic_sriov_issue_cmd(adapter, cmd); return; } @@ -1588,8 +1579,9 @@ qlcnic_sriov_get_free_node_async_work(struct qlcnic_back_channel *bc) return entry; } -static void qlcnic_sriov_schedule_bc_async_work(struct qlcnic_back_channel *bc, - work_func_t func, void *data) +static void qlcnic_sriov_schedule_async_cmd(struct qlcnic_back_channel *bc, + work_func_t func, void *data, + struct qlcnic_cmd_args *cmd) { struct qlcnic_async_work_list *entry = NULL; @@ -1598,21 +1590,23 @@ static void qlcnic_sriov_schedule_bc_async_work(struct qlcnic_back_channel *bc, return; entry->ptr = data; + entry->cmd = cmd; INIT_WORK(&entry->work, func); queue_work(bc->bc_async_wq, &entry->work); } -void qlcnic_sriov_vf_schedule_multi(struct net_device *netdev) +static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *adapter, + struct qlcnic_cmd_args *cmd) { - struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc; if (adapter->need_fw_reset) - return; + return -EIO; - qlcnic_sriov_schedule_bc_async_work(bc, qlcnic_sriov_handle_async_multi, - netdev); + qlcnic_sriov_schedule_async_cmd(bc, qlcnic_sriov_handle_async_issue_cmd, + adapter, cmd); + return 0; } static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter) @@ -1890,7 +1884,7 @@ static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov, if (!vf->sriov_vlans) return err; - mutex_lock(&vf->vlan_list_lock); + spin_lock_bh(&vf->vlan_list_lock); for (i = 0; i < sriov->num_allowed_vlans; i++) { if (vf->sriov_vlans[i] == vlan_id) { @@ -1899,7 +1893,7 @@ static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov, } } - mutex_unlock(&vf->vlan_list_lock); + spin_unlock_bh(&vf->vlan_list_lock); return err; } @@ -1908,12 +1902,12 @@ static int qlcnic_sriov_validate_num_vlans(struct qlcnic_sriov *sriov, { int err = 0; - mutex_lock(&vf->vlan_list_lock); + spin_lock_bh(&vf->vlan_list_lock); if (vf->num_vlan >= sriov->num_allowed_vlans) err = -EINVAL; - mutex_unlock(&vf->vlan_list_lock); + spin_unlock_bh(&vf->vlan_list_lock); return err; } @@ -1966,7 +1960,7 @@ static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id, if (!vf->sriov_vlans) return; - mutex_lock(&vf->vlan_list_lock); + spin_lock_bh(&vf->vlan_list_lock); switch (opcode) { case QLC_VLAN_ADD: @@ -1979,7 +1973,7 @@ static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id, netdev_err(adapter->netdev, "Invalid VLAN operation\n"); } - mutex_unlock(&vf->vlan_list_lock); + spin_unlock_bh(&vf->vlan_list_lock); return; } @@ -1987,6 +1981,7 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, u16 vid, u8 enable) { struct qlcnic_sriov *sriov = adapter->ahw->sriov; + struct net_device *netdev = adapter->netdev; struct qlcnic_vf_info *vf; struct qlcnic_cmd_args cmd; int ret; @@ -2012,14 +2007,18 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, dev_err(&adapter->pdev->dev, "Failed to configure guest VLAN, err=%d\n", ret); } else { + netif_addr_lock_bh(netdev); qlcnic_free_mac_list(adapter); + netif_addr_unlock_bh(netdev); if (enable) qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_ADD); else qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_DELETE); - qlcnic_set_multi(adapter->netdev); + netif_addr_lock_bh(netdev); + qlcnic_set_multi(netdev); + netif_addr_unlock_bh(netdev); } qlcnic_free_mbx_args(&cmd); @@ -2150,11 +2149,11 @@ bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *vf) { bool err = false; - mutex_lock(&vf->vlan_list_lock); + spin_lock_bh(&vf->vlan_list_lock); if (vf->num_vlan) err = true; - mutex_unlock(&vf->vlan_list_lock); + spin_unlock_bh(&vf->vlan_list_lock); return err; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index df409086e4d3..199ab7c6fbad 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -784,7 +784,7 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, struct qlcnic_vf_info *vf, u16 vlan, u8 op) { - struct qlcnic_cmd_args cmd; + struct qlcnic_cmd_args *cmd; struct qlcnic_macvlan_mbx mv; struct qlcnic_vport *vp; u8 *addr; @@ -794,21 +794,27 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, vp = vf->vp; - if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN)) + cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + if (!cmd) return -ENOMEM; + err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN); + if (err) + goto free_cmd; + + cmd->type = QLC_83XX_MBX_CMD_NO_WAIT; vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func); if (vpid < 0) { err = -EINVAL; - goto out; + goto free_args; } if (vlan) op = ((op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL); - cmd.req.arg[1] = op | (1 << 8) | (3 << 6); - cmd.req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31; + cmd->req.arg[1] = op | (1 << 8) | (3 << 6); + cmd->req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31; addr = vp->mac; mv.vlan = vlan; @@ -818,18 +824,18 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, mv.mac_addr3 = addr[3]; mv.mac_addr4 = addr[4]; mv.mac_addr5 = addr[5]; - buf = &cmd.req.arg[2]; + buf = &cmd->req.arg[2]; memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx)); - err = qlcnic_issue_cmd(adapter, &cmd); + err = qlcnic_issue_cmd(adapter, cmd); - if (err) - dev_err(&adapter->pdev->dev, - "MAC-VLAN %s to CAM failed, err=%d.\n", - ((op == 1) ? "add " : "delete "), err); + if (!err) + return err; -out: - qlcnic_free_mbx_args(&cmd); +free_args: + qlcnic_free_mbx_args(cmd); +free_cmd: + kfree(cmd); return err; } @@ -851,7 +857,7 @@ static void qlcnic_83xx_cfg_default_mac_vlan(struct qlcnic_adapter *adapter, sriov = adapter->ahw->sriov; - mutex_lock(&vf->vlan_list_lock); + spin_lock_bh(&vf->vlan_list_lock); if (vf->num_vlan) { for (i = 0; i < sriov->num_allowed_vlans; i++) { vlan = vf->sriov_vlans[i]; @@ -860,7 +866,7 @@ static void qlcnic_83xx_cfg_default_mac_vlan(struct qlcnic_adapter *adapter, opcode); } } - mutex_unlock(&vf->vlan_list_lock); + spin_unlock_bh(&vf->vlan_list_lock); if (vf->vp->vlan_mode != QLC_PVID_MODE) { if (qlcnic_83xx_pf_check(adapter) && -- cgit v1.2.1 From d747c3337484afac9953c44ea56a912869778559 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Fri, 9 May 2014 02:51:31 -0400 Subject: qlcnic: Add mac learning support to SR-IOV VF. o SR-IOV VF can be uplinked to bridge/macvtap device. Enable mac learning to support communication through embedded switch. o Learn vlan filters based on QLCNIC_VLAN_FILTERING flag. Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 12 +++++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 12 ++--- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 16 +++++-- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | 1 + .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 51 +++++++++++++++++++--- .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 14 ++---- 6 files changed, 78 insertions(+), 28 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 7bad613becba..557b911a89f8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -1019,6 +1019,8 @@ struct qlcnic_ipaddr { #define QLCNIC_DEL_VXLAN_PORT 0x200000 #endif +#define QLCNIC_VLAN_FILTERING 0x800000 + #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) #define QLCNIC_IS_TSO_CAPABLE(adapter) \ @@ -2355,6 +2357,16 @@ static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter) return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false; } +static inline bool qlcnic_sriov_check(struct qlcnic_adapter *adapter) +{ + bool status; + + status = (qlcnic_sriov_pf_check(adapter) || + qlcnic_sriov_vf_check(adapter)) ? true : false; + + return status; +} + static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) { if (qlcnic_84xx_check(adapter)) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index deb2278b48d5..e45bf09af0c9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -313,20 +313,16 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, u16 vlan_id = 0; u8 hindex, hval; - if (!qlcnic_sriov_pf_check(adapter)) { - if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) - return; - } else { + if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) + return; + + if (adapter->flags & QLCNIC_VLAN_FILTERING) { if (protocol == ETH_P_8021Q) { vh = (struct vlan_ethhdr *)skb->data; vlan_id = ntohs(vh->h_vlan_TCI); } else if (vlan_tx_tag_present(skb)) { vlan_id = vlan_tx_tag_get(skb); } - - if (ether_addr_equal(phdr->h_source, adapter->mac_addr) && - !vlan_id) - return; } memcpy(&src_addr, phdr->h_source, ETH_ALEN); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 1a52a781401f..8a570fa3542b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -378,7 +378,8 @@ static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], if (!adapter->fdb_mac_learn) return ndo_dflt_fdb_del(ndm, tb, netdev, addr); - if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { + if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) || + qlcnic_sriov_check(adapter)) { if (is_unicast_ether_addr(addr)) { err = dev_uc_del(netdev, addr); if (!err) @@ -402,7 +403,8 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], if (!adapter->fdb_mac_learn) return ndo_dflt_fdb_add(ndm, tb, netdev, addr, flags); - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) && + !qlcnic_sriov_check(adapter)) { pr_info("%s: FDB e-switch is not enabled\n", __func__); return -EOPNOTSUPP; } @@ -432,7 +434,8 @@ static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb, if (!adapter->fdb_mac_learn) return ndo_dflt_fdb_dump(skb, ncb, netdev, idx); - if (adapter->flags & QLCNIC_ESWITCH_ENABLED) + if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) || + qlcnic_sriov_check(adapter)) idx = ndo_dflt_fdb_dump(skb, ncb, netdev, idx); return idx; @@ -2809,6 +2812,8 @@ static int qlcnic_close(struct net_device *netdev) return 0; } +#define QLCNIC_VF_LB_BUCKET_SIZE 1 + void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) { void *head; @@ -2824,7 +2829,10 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) spin_lock_init(&adapter->mac_learn_lock); spin_lock_init(&adapter->rx_mac_learn_lock); - if (qlcnic_82xx_check(adapter)) { + if (qlcnic_sriov_vf_check(adapter)) { + filter_size = QLCNIC_83XX_SRIOV_VF_MAX_MAC - 1; + adapter->fhash.fbucket_size = QLCNIC_VF_LB_BUCKET_SIZE; + } else if (qlcnic_82xx_check(adapter)) { filter_size = QLCNIC_LB_MAX_FILTERS; adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE; } else { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h index 54159bde2bc7..335b50f7bd3e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h @@ -52,6 +52,7 @@ enum qlcnic_bc_commands { QLCNIC_BC_CMD_CFG_GUEST_VLAN = 0x3, }; +#define QLCNIC_83XX_SRIOV_VF_MAX_MAC 2 #define QLC_BC_CMD 1 struct qlcnic_trans_list { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 44cd5bd03744..3b39ab2ad5e9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -199,6 +199,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) goto qlcnic_destroy_async_wq; } sriov->vf_info[i].vp = vp; + vp->vlan_mode = QLC_GUEST_VLAN_MODE; vp->max_tx_bw = MAX_BW; vp->spoofchk = false; random_ether_addr(vp->mac); @@ -517,6 +518,8 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, { int err; + adapter->flags |= QLCNIC_VLAN_FILTERING; + adapter->ahw->total_nic_func = 1; INIT_LIST_HEAD(&adapter->vf_mc_list); if (!qlcnic_use_msi_x && !!qlcnic_use_msi) dev_warn(&adapter->pdev->dev, @@ -772,6 +775,7 @@ static int qlcnic_sriov_prepare_bc_hdr(struct qlcnic_bc_trans *trans, cmd->req.arg = (u32 *)trans->req_pay; cmd->rsp.arg = (u32 *)trans->rsp_pay; cmd_op = cmd->req.arg[0] & 0xff; + cmd->cmd_op = cmd_op; remainder = (trans->rsp_pay_size) % (bc_pay_sz); num_frags = (trans->rsp_pay_size) / (bc_pay_sz); if (remainder) @@ -1410,12 +1414,17 @@ retry: (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) { rsp = QLCNIC_RCODE_SUCCESS; } else { - rsp = mbx_err_code; - if (!rsp) - rsp = 1; - dev_err(dev, - "MBX command 0x%x failed with err:0x%x for VF %d\n", - opcode, mbx_err_code, func); + if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) { + rsp = QLCNIC_RCODE_SUCCESS; + } else { + rsp = mbx_err_code; + if (!rsp) + rsp = 1; + + dev_err(dev, + "MBX command 0x%x failed with err:0x%x for VF %d\n", + opcode, mbx_err_code, func); + } } err_out: @@ -1537,6 +1546,28 @@ void qlcnic_sriov_vf_set_multi(struct net_device *netdev) } } + /* configure unicast MAC address, if there is not sufficient space + * to store all the unicast addresses then enable promiscuous mode + */ + if (netdev_uc_count(netdev) > ahw->max_uc_count) { + mode = VPORT_MISS_MODE_ACCEPT_ALL; + } else if (!netdev_uc_empty(netdev)) { + netdev_for_each_uc_addr(ha, netdev) + qlcnic_vf_add_mc_list(netdev, ha->addr); + } + + if (adapter->pdev->is_virtfn) { + if (mode == VPORT_MISS_MODE_ACCEPT_ALL && + !adapter->fdb_mac_learn) { + qlcnic_alloc_lb_filters_mem(adapter); + adapter->drv_mac_learn = 1; + adapter->rx_mac_learn = true; + } else { + adapter->drv_mac_learn = 0; + adapter->rx_mac_learn = false; + } + } + qlcnic_nic_set_promisc(adapter, mode); } @@ -1830,6 +1861,12 @@ static int qlcnic_sriov_vf_idc_unknown_state(struct qlcnic_adapter *adapter) return 0; } +static void qlcnic_sriov_vf_periodic_tasks(struct qlcnic_adapter *adapter) +{ + if (adapter->fhash.fnum) + qlcnic_prune_lb_filters(adapter); +} + static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *work) { struct qlcnic_adapter *adapter; @@ -1861,6 +1898,8 @@ static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *work) } idc->prev_state = idc->curr_state; + qlcnic_sriov_vf_periodic_tasks(adapter); + if (!ret && test_bit(QLC_83XX_MODULE_LOADED, &idc->status)) qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state, idc->delay); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 199ab7c6fbad..6d2f72f114f2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -84,7 +84,7 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter, info->max_tx_ques = res->num_tx_queues / max; if (qlcnic_83xx_pf_check(adapter)) - num_macs = 1; + num_macs = QLCNIC_83XX_SRIOV_VF_MAX_MAC; info->max_rx_mcast_mac_filters = res->num_rx_mcast_mac_filters; @@ -338,9 +338,12 @@ static int qlcnic_sriov_pf_cfg_vlan_filtering(struct qlcnic_adapter *adapter, cmd.req.arg[1] = 0x4; if (enable) { + adapter->flags |= QLCNIC_VLAN_FILTERING; cmd.req.arg[1] |= BIT_16; if (qlcnic_84xx_check(adapter)) cmd.req.arg[1] |= QLC_SRIOV_ALLOW_VLAN0; + } else { + adapter->flags &= ~QLCNIC_VLAN_FILTERING; } err = qlcnic_issue_cmd(adapter, &cmd); @@ -1253,7 +1256,6 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, struct qlcnic_vf_info *vf, struct qlcnic_cmd_args *cmd) { - struct qlcnic_macvlan_mbx *macvlan; struct qlcnic_vport *vp = vf->vp; u8 op, new_op; @@ -1263,14 +1265,6 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, cmd->req.arg[1] |= (vf->vp->handle << 16); cmd->req.arg[1] |= BIT_31; - macvlan = (struct qlcnic_macvlan_mbx *)&cmd->req.arg[2]; - if (!(macvlan->mac_addr0 & BIT_0)) { - dev_err(&adapter->pdev->dev, - "MAC address change is not allowed from VF %d", - vf->pci_func); - return -EINVAL; - } - if (vp->vlan_mode == QLC_PVID_MODE) { op = cmd->req.arg[1] & 0x7; cmd->req.arg[1] &= ~0x7; -- cgit v1.2.1 From 8d37ba023f0ccab342df9ba216650e23aa147109 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Fri, 9 May 2014 02:51:32 -0400 Subject: qlcnic: Collect firmware dump using DMA on 82xx adapters o Add support to collect RDMEM section of firmware dump using PEX DMA method. o This patch uses most of the code used for PEX DMA support on 83xx series adapters and some refactoring. Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 31 ++++++------------ .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 4 +-- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 12 +++---- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 8 +++-- .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c | 37 +++++++++++----------- 5 files changed, 42 insertions(+), 50 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 7c125d7fb547..a4a4ec0b68f8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -3037,19 +3037,18 @@ void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter) QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK); } -int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, +int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, u32 *data, u32 count) { int i, j, ret = 0; u32 temp; - int err = 0; /* Check alignment */ if (addr & 0xF) return -EIO; mutex_lock(&adapter->ahw->mem_lock); - qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0); + qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0); for (i = 0; i < count; i++, addr += 16) { if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET, @@ -3060,26 +3059,16 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, return -EIO; } - qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr); - qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO, - *data++); - qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI, - *data++); - qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO, - *data++); - qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI, - *data++); - qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL, - QLCNIC_TA_WRITE_ENABLE); - qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL, - QLCNIC_TA_WRITE_START); + qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr); + qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++); + qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++); + qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++); + qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++); + qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE); + qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START); for (j = 0; j < MAX_CTL_CHECK; j++) { - temp = QLCRD32(adapter, QLCNIC_MS_CTRL, &err); - if (err == -EIO) { - mutex_unlock(&adapter->ahw->mem_lock); - return err; - } + temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL); if ((temp & TA_CTL_BUSY) == 0) break; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 88d809c35633..97784d09933f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -560,7 +560,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *); void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); -void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); +int qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); int qlcnic_ind_rd(struct qlcnic_adapter *, u32); int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *); int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *, @@ -617,7 +617,6 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *, u32); int qlcnic_83xx_lock_driver(struct qlcnic_adapter *); void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *); int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *); -int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32); int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *); int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *, int); int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *); @@ -659,4 +658,5 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *); u32 qlcnic_83xx_get_cap_size(void *, int); void qlcnic_83xx_set_sys_info(void *, int, u32); void qlcnic_83xx_store_cap_mask(void *, u32); +int qlcnic_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32); #endif diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 34d273794e96..f33559b72528 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -1363,8 +1363,8 @@ static int qlcnic_83xx_copy_bootloader(struct qlcnic_adapter *adapter) return ret; } /* 16 byte write to MS memory */ - ret = qlcnic_83xx_ms_mem_write128(adapter, dest, (u32 *)p_cache, - size / 16); + ret = qlcnic_ms_mem_write128(adapter, dest, (u32 *)p_cache, + size / 16); if (ret) { vfree(p_cache); return ret; @@ -1389,8 +1389,8 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) p_cache = (u32 *)fw->data; addr = (u64)dest; - ret = qlcnic_83xx_ms_mem_write128(adapter, addr, - p_cache, size / 16); + ret = qlcnic_ms_mem_write128(adapter, addr, + p_cache, size / 16); if (ret) { dev_err(&adapter->pdev->dev, "MS memory write failed\n"); release_firmware(fw); @@ -1405,8 +1405,8 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) data[i] = fw->data[size + i]; for (; i < 16; i++) data[i] = 0; - ret = qlcnic_83xx_ms_mem_write128(adapter, addr, - (u32 *)data, 1); + ret = qlcnic_ms_mem_write128(adapter, addr, + (u32 *)data, 1); if (ret) { dev_err(&adapter->pdev->dev, "MS memory write failed\n"); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index e5352b70314a..c9e8574959b7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -373,12 +373,16 @@ int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr) return data; } -void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data) +int qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data) { + int ret = 0; + if (qlcnic_82xx_check(adapter)) qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data); else - qlcnic_83xx_wrt_reg_indirect(adapter, addr, data); + ret = qlcnic_83xx_wrt_reg_indirect(adapter, addr, data); + + return ret; } static int diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c index 37b979b1266b..f7694da8ed5d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c @@ -238,6 +238,8 @@ void qlcnic_82xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) hdr->drv_cap_mask = hdr->cap_mask; fw_dump->cap_mask = hdr->cap_mask; + + fw_dump->use_pex_dma = (hdr->capabilities & BIT_0) ? true : false; } inline u32 qlcnic_82xx_get_cap_size(void *t_hdr, int index) @@ -276,6 +278,8 @@ inline void qlcnic_83xx_set_saved_state(void *t_hdr, u32 index, hdr->saved_state[index] = value; } +#define QLCNIC_TEMPLATE_VERSION (0x20001) + void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) { struct qlcnic_83xx_dump_template_hdr *hdr; @@ -288,6 +292,9 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) hdr->drv_cap_mask = hdr->cap_mask; fw_dump->cap_mask = hdr->cap_mask; + + fw_dump->use_pex_dma = (fw_dump->version & 0xfffff) >= + QLCNIC_TEMPLATE_VERSION; } inline u32 qlcnic_83xx_get_cap_size(void *t_hdr, int index) @@ -658,29 +665,28 @@ out: static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter, struct __mem *mem) { - struct qlcnic_83xx_dump_template_hdr *tmpl_hdr; struct device *dev = &adapter->pdev->dev; u32 dma_no, dma_base_addr, temp_addr; int i, ret, dma_sts; + void *tmpl_hdr; tmpl_hdr = adapter->ahw->fw_dump.tmpl_hdr; - dma_no = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX]; + dma_no = qlcnic_get_saved_state(adapter, tmpl_hdr, + QLC_83XX_DMA_ENGINE_INDEX); dma_base_addr = QLC_DMA_REG_BASE_ADDR(dma_no); temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_LOW; - ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, - mem->desc_card_addr); + ret = qlcnic_ind_wr(adapter, temp_addr, mem->desc_card_addr); if (ret) return ret; temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_HI; - ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, 0); + ret = qlcnic_ind_wr(adapter, temp_addr, 0); if (ret) return ret; temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL; - ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, - mem->start_dma_cmd); + ret = qlcnic_ind_wr(adapter, temp_addr, mem->start_dma_cmd); if (ret) return ret; @@ -710,15 +716,16 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter, struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; u32 temp, dma_base_addr, size = 0, read_size = 0; struct qlcnic_pex_dma_descriptor *dma_descr; - struct qlcnic_83xx_dump_template_hdr *tmpl_hdr; struct device *dev = &adapter->pdev->dev; dma_addr_t dma_phys_addr; void *dma_buffer; + void *tmpl_hdr; tmpl_hdr = fw_dump->tmpl_hdr; /* Check if DMA engine is available */ - temp = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX]; + temp = qlcnic_get_saved_state(adapter, tmpl_hdr, + QLC_83XX_DMA_ENGINE_INDEX); dma_base_addr = QLC_DMA_REG_BASE_ADDR(temp); temp = qlcnic_ind_rd(adapter, dma_base_addr + QLC_DMA_CMD_STATUS_CTRL); @@ -764,8 +771,8 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter, /* Write DMA descriptor to MS memory*/ temp = sizeof(struct qlcnic_pex_dma_descriptor) / 16; - *ret = qlcnic_83xx_ms_mem_write128(adapter, mem->desc_card_addr, - (u32 *)dma_descr, temp); + *ret = qlcnic_ms_mem_write128(adapter, mem->desc_card_addr, + (u32 *)dma_descr, temp); if (*ret) { dev_info(dev, "Failed to write DMA descriptor to MS memory at address 0x%x\n", mem->desc_card_addr); @@ -1141,8 +1148,6 @@ free_mem: return err; } -#define QLCNIC_TEMPLATE_VERSION (0x20001) - int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) { struct qlcnic_hardware_context *ahw; @@ -1203,12 +1208,6 @@ flash_temp: "Default minidump capture mask 0x%x\n", fw_dump->cap_mask); - if (qlcnic_83xx_check(adapter) && - (fw_dump->version & 0xfffff) >= QLCNIC_TEMPLATE_VERSION) - fw_dump->use_pex_dma = true; - else - fw_dump->use_pex_dma = false; - qlcnic_enable_fw_dump_state(adapter); return 0; -- cgit v1.2.1 From 27a4041e16b5bab07d74e82bb09d0933f7737cf6 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Fri, 9 May 2014 02:51:33 -0400 Subject: qlcnic: Update version to 5.3.59 Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 557b911a89f8..6cb24dc864ba 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 58 -#define QLCNIC_LINUX_VERSIONID "5.3.58" +#define _QLCNIC_LINUX_SUBVERSION 59 +#define QLCNIC_LINUX_VERSIONID "5.3.59" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit v1.2.1 From f06c7f9f92295faf701a9628b383156c4efb6119 Mon Sep 17 00:00:00 2001 From: dingtianhong Date: Fri, 9 May 2014 14:58:05 +0800 Subject: vlan: rename __vlan_find_dev_deep() to __vlan_find_dev_deep_rcu() The __vlan_find_dev_deep should always called in RCU, according David's suggestion, rename to __vlan_find_dev_deep_rcu looks more reasonable. Signed-off-by: Ding Tianhong Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index d2e18b52caba..8a2aeb85e320 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -4146,7 +4146,7 @@ void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) rcu_read_lock(); for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { - dev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), vid); + dev = __vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), vid); if (!dev) continue; qlcnic_config_indev_addr(adapter, dev, event); -- cgit v1.2.1 From 7ad24ea4bf620a32631d7b3069c3e30c078b0c3e Mon Sep 17 00:00:00 2001 From: Wilfried Klaebe Date: Sun, 11 May 2014 00:12:32 +0000 Subject: net: get rid of SET_ETHTOOL_OPS net: get rid of SET_ETHTOOL_OPS Dave Miller mentioned he'd like to see SET_ETHTOOL_OPS gone. This does that. Mostly done via coccinelle script: @@ struct ethtool_ops *ops; struct net_device *dev; @@ - SET_ETHTOOL_OPS(dev, ops); + dev->ethtool_ops = ops; Compile tested only, but I'd seriously wonder if this broke anything. Suggested-by: Dave Miller Signed-off-by: Wilfried Klaebe Acked-by: Felipe Balbi Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 8a2aeb85e320..f0a285359e66 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2265,10 +2265,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, qlcnic_change_mtu(netdev, netdev->mtu); - if (qlcnic_sriov_vf_check(adapter)) - SET_ETHTOOL_OPS(netdev, &qlcnic_sriov_vf_ethtool_ops); - else - SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); + netdev->ethtool_ops = (qlcnic_sriov_vf_check(adapter)) ? + &qlcnic_sriov_vf_ethtool_ops : &qlcnic_ethtool_ops; netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO | @@ -2682,7 +2680,7 @@ err_out_disable_pdev: err_out_maintenance_mode: set_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state); netdev->netdev_ops = &qlcnic_netdev_failed_ops; - SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops); + netdev->ethtool_ops = &qlcnic_ethtool_failed_ops; ahw->port_type = QLCNIC_XGBE; if (qlcnic_83xx_check(adapter)) -- cgit v1.2.1 From 2b3d9655119625cc102756395715292150a8980e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= Date: Wed, 21 May 2014 19:24:03 +0200 Subject: qlogic: Use time_before() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To be future-proof and for better readability the time comparisons are modified to use time_before() instead of plain, error-prone math. Signed-off-by: Manuel Schölling Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index c9e8574959b7..851cb4a80d50 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -620,7 +620,7 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) struct hlist_node *n; struct hlist_head *head; int i; - unsigned long time; + unsigned long expires; u8 cmd; for (i = 0; i < adapter->fhash.fbucket_size; i++) { @@ -628,8 +628,8 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) hlist_for_each_entry_safe(tmp_fil, n, head, fnode) { cmd = tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL; - time = tmp_fil->ftime; - if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) { + expires = tmp_fil->ftime + QLCNIC_FILTER_AGE * HZ; + if (time_before(expires, jiffies)) { qlcnic_sre_macaddr_change(adapter, tmp_fil->faddr, tmp_fil->vlan_id, @@ -647,8 +647,8 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) hlist_for_each_entry_safe(tmp_fil, n, head, fnode) { - time = tmp_fil->ftime; - if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) { + expires = tmp_fil->ftime + QLCNIC_FILTER_AGE * HZ; + if (time_before(expires, jiffies)) { spin_lock_bh(&adapter->rx_mac_learn_lock); adapter->rx_fhash.fnum--; hlist_del(&tmp_fil->fnode); -- cgit v1.2.1 From ed616689a3d95eb6c9bdbb1ef74b0f50cbdf276a Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Thu, 22 May 2014 09:59:05 -0400 Subject: net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool. o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed to have a bandwidth of at least this value. max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth of up to this value. o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced which takes 4 arguments: netdev, VF number, min_tx_rate, max_tx_rate o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler. o Drivers that currently implement ndo_set_vf_tx_rate should now call ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet implemented by driver. o If user enters only one of either min_tx_rate or max_tx_rate, then, userland should read back the other value from driver and set both for IFLA_VF_RATE. Drivers that have not yet implemented IFLA_VF_RATE should always return min_tx_rate as 0 when read from ip tool. o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then IFLA_VF_RATE should override. o Idea is to have consistent display of rate values to user. o Usage example: - ./ip link set p4p1 vf 0 rate 900 ./ip link show p4p1 32: p4p1: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps vf 1 MAC f6:c6:7c:3f:3d:6c vf 2 MAC 56:32:43:98:d7:71 vf 3 MAC d6:be:c3:b5:85:ff vf 4 MAC ee:a9:9a:1e:19:14 vf 5 MAC 4a:d0:4c:07:52:18 vf 6 MAC 3a:76:44:93:62:f9 vf 7 MAC 82:e9:e7:e3:15:1a ./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200 ./ip link show p4p1 32: p4p1: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps, min_tx_rate 200Mbps vf 1 MAC f6:c6:7c:3f:3d:6c vf 2 MAC 56:32:43:98:d7:71 vf 3 MAC d6:be:c3:b5:85:ff vf 4 MAC ee:a9:9a:1e:19:14 vf 5 MAC 4a:d0:4c:07:52:18 vf 6 MAC 3a:76:44:93:62:f9 vf 7 MAC 82:e9:e7:e3:15:1a ./ip link set p4p1 vf 0 max_tx_rate 600 rate 300 ./ip link show p4p1 32: p4p1: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps, min_tx_rate 200Mbps vf 1 MAC f6:c6:7c:3f:3d:6c vf 2 MAC 56:32:43:98:d7:71 vf 3 MAC d6:be:c3:b5:85:ff vf 4 MAC ee:a9:9a:1e:19:14 vf 5 MAC 4a:d0:4c:07:52:18 vf 6 MAC 3a:76:44:93:62:f9 vf 7 MAC 82:e9:e7:e3:15:1a Signed-off-by: Sucheta Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 1 + drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | 2 +- .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 1 + .../net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 52 +++++++++++++++------- 5 files changed, 41 insertions(+), 17 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 6e7527e2b595..41abe6070466 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -1319,6 +1319,7 @@ struct qlcnic_eswitch { #define QL_STATUS_INVALID_PARAM -1 #define MAX_BW 100 /* % of link speed */ +#define MIN_BW 1 /* % of link speed */ #define MAX_VLAN_ID 4095 #define MIN_VLAN_ID 2 #define DEFAULT_MAC_LEARN 1 diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index f0a285359e66..f06ba90b4282 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -525,7 +525,7 @@ static const struct net_device_ops qlcnic_netdev_ops = { #endif #ifdef CONFIG_QLCNIC_SRIOV .ndo_set_vf_mac = qlcnic_sriov_set_vf_mac, - .ndo_set_vf_tx_rate = qlcnic_sriov_set_vf_tx_rate, + .ndo_set_vf_rate = qlcnic_sriov_set_vf_tx_rate, .ndo_get_vf_config = qlcnic_sriov_get_vf_config, .ndo_set_vf_vlan = qlcnic_sriov_set_vf_vlan, .ndo_set_vf_spoofchk = qlcnic_sriov_set_vf_spoofchk, diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h index 335b50f7bd3e..4677b2edccca 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h @@ -233,7 +233,7 @@ bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *, void qlcnic_sriov_pf_reset(struct qlcnic_adapter *); int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *); int qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *); -int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int); +int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int); int qlcnic_sriov_get_vf_config(struct net_device *, int , struct ifla_vf_info *); int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 498fa6350c8d..2bdd9deffb38 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -201,6 +201,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) sriov->vf_info[i].vp = vp; vp->vlan_mode = QLC_GUEST_VLAN_MODE; vp->max_tx_bw = MAX_BW; + vp->min_tx_bw = MIN_BW; vp->spoofchk = false; random_ether_addr(vp->mac); dev_info(&adapter->pdev->dev, diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 6d2f72f114f2..a29538b86edf 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -1848,7 +1848,8 @@ int qlcnic_sriov_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) return 0; } -int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, int tx_rate) +int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, + int min_tx_rate, int max_tx_rate) { struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_sriov *sriov = adapter->ahw->sriov; @@ -1863,35 +1864,52 @@ int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, int tx_rate) if (vf >= sriov->num_vfs) return -EINVAL; - if (tx_rate >= 10000 || tx_rate < 100) { + vf_info = &sriov->vf_info[vf]; + vp = vf_info->vp; + vpid = vp->handle; + + if (!min_tx_rate) + min_tx_rate = QLC_VF_MIN_TX_RATE; + + if (max_tx_rate && + (max_tx_rate >= 10000 || max_tx_rate < min_tx_rate)) { netdev_err(netdev, - "Invalid Tx rate, allowed range is [%d - %d]", - QLC_VF_MIN_TX_RATE, QLC_VF_MAX_TX_RATE); + "Invalid max Tx rate, allowed range is [%d - %d]", + min_tx_rate, QLC_VF_MAX_TX_RATE); return -EINVAL; } - if (tx_rate == 0) - tx_rate = 10000; + if (!max_tx_rate) + max_tx_rate = 10000; - vf_info = &sriov->vf_info[vf]; - vp = vf_info->vp; - vpid = vp->handle; + if (min_tx_rate && + (min_tx_rate > max_tx_rate || min_tx_rate < QLC_VF_MIN_TX_RATE)) { + netdev_err(netdev, + "Invalid min Tx rate, allowed range is [%d - %d]", + QLC_VF_MIN_TX_RATE, max_tx_rate); + return -EINVAL; + } if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) { if (qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, vpid)) return -EIO; - nic_info.max_tx_bw = tx_rate / 100; + nic_info.max_tx_bw = max_tx_rate / 100; + nic_info.min_tx_bw = min_tx_rate / 100; nic_info.bit_offsets = BIT_0; if (qlcnic_sriov_pf_set_vport_info(adapter, &nic_info, vpid)) return -EIO; } - vp->max_tx_bw = tx_rate / 100; + vp->max_tx_bw = max_tx_rate / 100; + netdev_info(netdev, + "Setting Max Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n", + max_tx_rate, vp->max_tx_bw, vf); + vp->min_tx_bw = min_tx_rate / 100; netdev_info(netdev, - "Setting Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n", - tx_rate, vp->max_tx_bw, vf); + "Setting Min Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n", + min_tx_rate, vp->min_tx_bw, vf); return 0; } @@ -1990,9 +2008,13 @@ int qlcnic_sriov_get_vf_config(struct net_device *netdev, ivi->qos = vp->qos; ivi->spoofchk = vp->spoofchk; if (vp->max_tx_bw == MAX_BW) - ivi->tx_rate = 0; + ivi->max_tx_rate = 0; + else + ivi->max_tx_rate = vp->max_tx_bw * 100; + if (vp->min_tx_bw == MIN_BW) + ivi->min_tx_rate = 0; else - ivi->tx_rate = vp->max_tx_bw * 100; + ivi->min_tx_rate = vp->min_tx_bw * 100; ivi->vf = vf; return 0; -- cgit v1.2.1 From c531692073847fe64635f6992d774fb319e3529a Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Wed, 4 Jun 2014 03:40:54 -0400 Subject: qlcnic: Initialize mailbox cmd structure to zero o Uninitialzed fields in mailbox command structure caused commands to time out randomly due to garbage values so initialize it to zero. Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 6afe9c1f5ab9..d9216afa93c1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -454,6 +454,7 @@ static int qlcnic_sriov_get_vf_acl(struct qlcnic_adapter *adapter) struct qlcnic_cmd_args cmd; int ret = 0; + memset(&cmd, 0, sizeof(cmd)); ret = qlcnic_sriov_alloc_bc_mbx_args(&cmd, QLCNIC_BC_CMD_GET_ACL); if (ret) return ret; @@ -1441,6 +1442,7 @@ static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_o struct qlcnic_vf_info *vf = &adapter->ahw->sriov->vf_info[0]; int ret; + memset(&cmd, 0, sizeof(cmd)); if (qlcnic_sriov_alloc_bc_mbx_args(&cmd, cmd_op)) return -ENOMEM; @@ -1998,6 +2000,7 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args cmd; int ret; + memset(&cmd, 0, sizeof(cmd)); if (vid == 0) return 0; -- cgit v1.2.1 From 5e3ec11b642e2e50484dce5ef2500f5aca47a40f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 9 Jun 2014 17:55:39 +0300 Subject: qlcnic: remove duplicate QLC_83XX_GET_LSO_CAPABILITY define The QLC_83XX_GET_LSO_CAPABILITY define is cut and pasted twice so we can delete the second instance. Signed-off-by: Dan Carpenter Acked-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 97784d09933f..2bf101a47d02 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -418,7 +418,6 @@ enum qlcnic_83xx_states { #define QLC_83XX_GET_FUNC_MODE_FROM_NPAR_INFO(val) (val & 0x80000000) #define QLC_83XX_GET_LRO_CAPABILITY(val) (val & 0x20) #define QLC_83XX_GET_LSO_CAPABILITY(val) (val & 0x40) -#define QLC_83XX_GET_LSO_CAPABILITY(val) (val & 0x40) #define QLC_83XX_GET_HW_LRO_CAPABILITY(val) (val & 0x400) #define QLC_83XX_GET_VLAN_ALIGN_CAPABILITY(val) (val & 0x4000) #define QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(val) (val & 0x20000) -- cgit v1.2.1 From 4da005cf1e30897520106114a8ce11a5aa558497 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Wed, 11 Jun 2014 14:09:11 -0400 Subject: 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 ++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 14 ++++++++-- .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c | 32 ++++++++++------------ 3 files changed, 28 insertions(+), 20 deletions(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') 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; } -- cgit v1.2.1 From 18e0d625336a7690dcb358e2f4157becfa65183b Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Wed, 11 Jun 2014 14:09:12 -0400 Subject: 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(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') 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); -- cgit v1.2.1 From 038782d6d0d92c3cc98ffc08cd78cfe46a2eca41 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Wed, 11 Jun 2014 14:09:13 -0400 Subject: 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(-) (limited to 'drivers/net/ethernet/qlogic/qlcnic') 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)) -- cgit v1.2.1