qlcnic: restore NPAR config data after recovery
authorAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Tue, 13 Jul 2010 20:33:35 +0000 (20:33 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Jul 2010 20:54:17 +0000 (13:54 -0700)
o NPAR configuration which is programmed in fw, need to
  restore after fw recovery.
o Update version to 5.0.7

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/qlcnic/qlcnic.h
drivers/net/qlcnic/qlcnic_ctx.c
drivers/net/qlcnic/qlcnic_main.c

index 064464201cbb481dd8b7f456ff3ed1f4fb222d3b..e1894775e5aa21f26e5255917849b2394524e423 100644 (file)
@@ -51,8 +51,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 6
-#define QLCNIC_LINUX_VERSIONID  "5.0.6"
+#define _QLCNIC_LINUX_SUBVERSION 7
+#define QLCNIC_LINUX_VERSIONID  "5.0.7"
 #define QLCNIC_DRV_IDC_VER  0x01
 
 #define QLCNIC_VERSION_CODE(a, b, c)   (((a) << 24) + ((b) << 16) + (c))
@@ -949,7 +949,6 @@ struct qlcnic_adapter {
        u8 has_link_events;
        u8 fw_type;
        u16 tx_context_id;
-       u16 mtu;
        u16 is_up;
 
        u16 link_speed;
@@ -1044,6 +1043,8 @@ struct qlcnic_pci_info {
 
 struct qlcnic_npar_info {
        u16     vlan_id;
+       u16     min_bw;
+       u16     max_bw;
        u8      phy_port;
        u8      type;
        u8      active;
index cdd44b4136ae88d5f391d3bc6b718f68da16316d..cc5d861d9a128bfc932da00a6bb0917a7ac26931 100644 (file)
@@ -636,6 +636,8 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter,
                        QLCNIC_CDRP_CMD_GET_NIC_INFO);
 
        if (err == QLCNIC_RCODE_SUCCESS) {
+               npar_info->pci_func = le16_to_cpu(nic_info->pci_func);
+               npar_info->op_mode = le16_to_cpu(nic_info->op_mode);
                npar_info->phys_port = le16_to_cpu(nic_info->phys_port);
                npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode);
                npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques);
index d5c94a3364f7d565b78c88f455a210038bda335e..8d2d62ff1a37487ed729d649ceb14e113d3e9bd8 100644 (file)
@@ -507,6 +507,8 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
                        adapter->npars[pfn].type = pci_info[i].type;
                        adapter->npars[pfn].phy_port = pci_info[i].default_port;
                        adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN;
+                       adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
+                       adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
                }
 
                for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
@@ -770,6 +772,50 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
        adapter->max_rds_rings = 2;
 }
 
+static int
+qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
+{
+       int i, err = 0;
+       struct qlcnic_npar_info *npar;
+       struct qlcnic_info nic_info;
+
+       if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
+           !adapter->need_fw_reset)
+               return 0;
+
+       if (adapter->op_mode == QLCNIC_MGMT_FUNC) {
+               /* Set the NPAR config data after FW reset */
+               for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+                       npar = &adapter->npars[i];
+                       if (npar->type != QLCNIC_TYPE_NIC)
+                               continue;
+                       err = qlcnic_get_nic_info(adapter, &nic_info, i);
+                       if (err)
+                               goto err_out;
+                       nic_info.min_tx_bw = npar->min_bw;
+                       nic_info.max_tx_bw = npar->max_bw;
+                       err = qlcnic_set_nic_info(adapter, &nic_info);
+                       if (err)
+                               goto err_out;
+
+                       if (npar->enable_pm) {
+                               err = qlcnic_config_port_mirroring(adapter,
+                                               npar->dest_npar, 1, i);
+                               if (err)
+                                       goto err_out;
+
+                       }
+                       npar->mac_learning = DEFAULT_MAC_LEARN;
+                       npar->host_vlan_tag = 0;
+                       npar->promisc_mode = 0;
+                       npar->discard_tagged = 0;
+                       npar->vlan_id = 0;
+               }
+       }
+err_out:
+       return err;
+}
+
 static int
 qlcnic_start_firmware(struct qlcnic_adapter *adapter)
 {
@@ -834,10 +880,9 @@ wait_init:
        qlcnic_idc_debug_info(adapter, 1);
 
        qlcnic_check_options(adapter);
-
-       if (adapter->flags & QLCNIC_ESWITCH_ENABLED &&
-               adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
-               qlcnic_dev_set_npar_ready(adapter);
+       if (qlcnic_reset_npar_config(adapter))
+               goto err_out;
+       qlcnic_dev_set_npar_ready(adapter);
 
        adapter->need_fw_reset = 0;
 
@@ -2486,6 +2531,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 {
        u32 state;
 
+       adapter->need_fw_reset = 1;
        if (qlcnic_api_lock(adapter))
                return;
 
@@ -2506,6 +2552,9 @@ qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
 {
        u32 state;
 
+       if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
+               adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
+               return;
        if (qlcnic_api_lock(adapter))
                return;
 
@@ -3019,7 +3068,7 @@ static struct bin_attribute bin_attr_mem = {
        .write = qlcnic_sysfs_write_mem,
 };
 
-int
+static int
 validate_pm_config(struct qlcnic_adapter *adapter,
                        struct qlcnic_pm_func_cfg *pm_cfg, int count)
 {
@@ -3118,7 +3167,7 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj,
        return size;
 }
 
-int
+static int
 validate_esw_config(struct qlcnic_adapter *adapter,
                        struct qlcnic_esw_func_cfg *esw_cfg, int count)
 {
@@ -3154,9 +3203,8 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
        struct device *dev = container_of(kobj, struct device, kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_esw_func_cfg *esw_cfg;
-       u8 id, discard_tagged, promsc_mode, mac_learn;
-       u8 vlan_tagging, pci_func, vlan_id;
        int count, rem, i, ret;
+       u8 id, pci_func;
 
        count   = size / sizeof(struct qlcnic_esw_func_cfg);
        rem     = size % sizeof(struct qlcnic_esw_func_cfg);
@@ -3171,17 +3219,13 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
        for (i = 0; i < count; i++) {
                pci_func = esw_cfg[i].pci_func;
                id = adapter->npars[pci_func].phy_port;
-               vlan_tagging = esw_cfg[i].host_vlan_tag;
-               promsc_mode = esw_cfg[i].promisc_mode;
-               mac_learn = esw_cfg[i].mac_learning;
-               vlan_id = esw_cfg[i].vlan_id;
-               discard_tagged = esw_cfg[i].discard_tagged;
-               ret = qlcnic_config_switch_port(adapter, id, vlan_tagging,
-                                               discard_tagged,
-                                               promsc_mode,
-                                               mac_learn,
-                                               pci_func,
-                                               vlan_id);
+               ret = qlcnic_config_switch_port(adapter, id,
+                                               esw_cfg[i].host_vlan_tag,
+                                               esw_cfg[i].discard_tagged,
+                                               esw_cfg[i].promisc_mode,
+                                               esw_cfg[i].mac_learning,
+                                               esw_cfg[i].pci_func,
+                                               esw_cfg[i].vlan_id);
                if (ret)
                        return ret;
        }
@@ -3227,7 +3271,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
        return size;
 }
 
-int
+static int
 validate_npar_config(struct qlcnic_adapter *adapter,
                                struct qlcnic_npar_func_cfg *np_cfg, int count)
 {
@@ -3282,6 +3326,8 @@ qlcnic_sysfs_write_npar_config(struct file *file, struct kobject *kobj,
                ret = qlcnic_set_nic_info(adapter, &nic_info);
                if (ret)
                        return ret;
+               adapter->npars[i].min_bw = nic_info.min_tx_bw;
+               adapter->npars[i].max_bw = nic_info.max_tx_bw;
        }
 
        return size;