aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_main.c
diff options
context:
space:
mode:
authorAnirban Chakraborty <anirban.chakraborty@qlogic.com>2010-08-26 10:02:52 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-26 20:13:19 -0400
commit0866d96da02cccc3ca837d0d71687aba962b3f2f (patch)
treefdf48e0ccd0c92819c2d96d3e18562c4092bb471 /drivers/net/qlcnic/qlcnic_main.c
parent8cfdce080722101a7fd2a1eff9763ca4008ec626 (diff)
qlcnic: Fix driver load issue in FW hang
If there is a FW hang when the driver loads, it can not determine the FW operational mode. Fix it by checking the FW state first before issuing any FW commands to determine its capabilities and thereby detecting driver operational mode. Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c116
1 files changed, 62 insertions, 54 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 1b8f67dab9b8..6999d5aaa157 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -566,12 +566,11 @@ err_lock:
566 return ret; 566 return ret;
567} 567}
568 568
569static u32 569static void
570qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) 570qlcnic_check_vf(struct qlcnic_adapter *adapter)
571{ 571{
572 void __iomem *msix_base_addr; 572 void __iomem *msix_base_addr;
573 void __iomem *priv_op; 573 void __iomem *priv_op;
574 struct qlcnic_info nic_info;
575 u32 func; 574 u32 func;
576 u32 msix_base; 575 u32 msix_base;
577 u32 op_mode, priv_level; 576 u32 op_mode, priv_level;
@@ -586,20 +585,6 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
586 func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; 585 func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE;
587 adapter->ahw.pci_func = func; 586 adapter->ahw.pci_func = func;
588 587
589 if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) {
590 adapter->capabilities = nic_info.capabilities;
591
592 if (adapter->capabilities & BIT_6)
593 adapter->flags |= QLCNIC_ESWITCH_ENABLED;
594 else
595 adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
596 }
597
598 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
599 adapter->nic_ops = &qlcnic_ops;
600 return adapter->fw_hal_version;
601 }
602
603 /* Determine function privilege level */ 588 /* Determine function privilege level */
604 priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; 589 priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
605 op_mode = readl(priv_op); 590 op_mode = readl(priv_op);
@@ -608,37 +593,14 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
608 else 593 else
609 priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); 594 priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
610 595
611 switch (priv_level) { 596 if (priv_level == QLCNIC_NON_PRIV_FUNC) {
612 case QLCNIC_MGMT_FUNC:
613 adapter->op_mode = QLCNIC_MGMT_FUNC;
614 adapter->nic_ops = &qlcnic_ops;
615 qlcnic_init_pci_info(adapter);
616 /* Set privilege level for other functions */
617 qlcnic_set_function_modes(adapter);
618 dev_info(&adapter->pdev->dev,
619 "HAL Version: %d, Management function\n",
620 adapter->fw_hal_version);
621 break;
622 case QLCNIC_PRIV_FUNC:
623 adapter->op_mode = QLCNIC_PRIV_FUNC;
624 dev_info(&adapter->pdev->dev,
625 "HAL Version: %d, Privileged function\n",
626 adapter->fw_hal_version);
627 adapter->nic_ops = &qlcnic_ops;
628 break;
629 case QLCNIC_NON_PRIV_FUNC:
630 adapter->op_mode = QLCNIC_NON_PRIV_FUNC; 597 adapter->op_mode = QLCNIC_NON_PRIV_FUNC;
631 dev_info(&adapter->pdev->dev, 598 dev_info(&adapter->pdev->dev,
632 "HAL Version: %d Non Privileged function\n", 599 "HAL Version: %d Non Privileged function\n",
633 adapter->fw_hal_version); 600 adapter->fw_hal_version);
634 adapter->nic_ops = &qlcnic_vf_ops; 601 adapter->nic_ops = &qlcnic_vf_ops;
635 break; 602 } else
636 default: 603 adapter->nic_ops = &qlcnic_ops;
637 dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n",
638 priv_level);
639 return 0;
640 }
641 return adapter->fw_hal_version;
642} 604}
643 605
644static int 606static int
@@ -671,10 +633,7 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter)
671 adapter->ahw.pci_base0 = mem_ptr0; 633 adapter->ahw.pci_base0 = mem_ptr0;
672 adapter->ahw.pci_len0 = pci_len0; 634 adapter->ahw.pci_len0 = pci_len0;
673 635
674 if (!qlcnic_get_driver_mode(adapter)) { 636 qlcnic_check_vf(adapter);
675 iounmap(adapter->ahw.pci_base0);
676 return -EIO;
677 }
678 637
679 adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, 638 adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter,
680 QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func))); 639 QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func)));
@@ -719,6 +678,9 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
719 678
720 adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); 679 adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
721 680
681 if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED))
682 if (qlcnic_read_mac_addr(adapter))
683 dev_warn(&pdev->dev, "failed to read mac addr\n");
722 if (adapter->portnum == 0) { 684 if (adapter->portnum == 0) {
723 get_brd_name(adapter, brd_name); 685 get_brd_name(adapter, brd_name);
724 686
@@ -837,6 +799,51 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
837} 799}
838 800
839static int 801static int
802qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
803{
804 void __iomem *priv_op;
805 u32 op_mode, priv_level;
806 int err = 0;
807
808 if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED)
809 return 0;
810
811 priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
812 op_mode = readl(priv_op);
813 priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
814
815 if (op_mode == QLC_DEV_DRV_DEFAULT)
816 priv_level = QLCNIC_MGMT_FUNC;
817 else
818 priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
819
820 if (adapter->capabilities & BIT_6) {
821 adapter->flags |= QLCNIC_ESWITCH_ENABLED;
822 if (priv_level == QLCNIC_MGMT_FUNC) {
823 adapter->op_mode = QLCNIC_MGMT_FUNC;
824 err = qlcnic_init_pci_info(adapter);
825 if (err)
826 return err;
827 /* Set privilege level for other functions */
828 qlcnic_set_function_modes(adapter);
829 dev_info(&adapter->pdev->dev,
830 "HAL Version: %d, Management function\n",
831 adapter->fw_hal_version);
832 } else if (priv_level == QLCNIC_PRIV_FUNC) {
833 adapter->op_mode = QLCNIC_PRIV_FUNC;
834 dev_info(&adapter->pdev->dev,
835 "HAL Version: %d, Privileged function\n",
836 adapter->fw_hal_version);
837 }
838 } else
839 adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
840
841 adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
842
843 return err;
844}
845
846static int
840qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) 847qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
841{ 848{
842 struct qlcnic_esw_func_cfg esw_cfg; 849 struct qlcnic_esw_func_cfg esw_cfg;
@@ -1005,8 +1012,14 @@ set_dev_ready:
1005 err = qlcnic_reset_npar_config(adapter); 1012 err = qlcnic_reset_npar_config(adapter);
1006 if (err) 1013 if (err)
1007 goto err_out; 1014 goto err_out;
1008 qlcnic_dev_set_npar_ready(adapter);
1009 qlcnic_check_options(adapter); 1015 qlcnic_check_options(adapter);
1016 err = qlcnic_check_eswitch_mode(adapter);
1017 if (err) {
1018 dev_err(&adapter->pdev->dev,
1019 "Memory allocation failed for eswitch\n");
1020 goto err_out;
1021 }
1022 qlcnic_dev_set_npar_ready(adapter);
1010 adapter->need_fw_reset = 0; 1023 adapter->need_fw_reset = 0;
1011 1024
1012 qlcnic_release_firmware(adapter); 1025 qlcnic_release_firmware(adapter);
@@ -1015,6 +1028,7 @@ set_dev_ready:
1015err_out: 1028err_out:
1016 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); 1029 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED);
1017 dev_err(&adapter->pdev->dev, "Device state set to failed\n"); 1030 dev_err(&adapter->pdev->dev, "Device state set to failed\n");
1031
1018 qlcnic_release_firmware(adapter); 1032 qlcnic_release_firmware(adapter);
1019 return err; 1033 return err;
1020} 1034}
@@ -1419,9 +1433,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
1419 netdev->features |= NETIF_F_LRO; 1433 netdev->features |= NETIF_F_LRO;
1420 netdev->irq = adapter->msix_entries[0].vector; 1434 netdev->irq = adapter->msix_entries[0].vector;
1421 1435
1422 if (qlcnic_read_mac_addr(adapter))
1423 dev_warn(&pdev->dev, "failed to read mac addr\n");
1424
1425 netif_carrier_off(netdev); 1436 netif_carrier_off(netdev);
1426 netif_stop_queue(netdev); 1437 netif_stop_queue(netdev);
1427 1438
@@ -1515,9 +1526,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1515 goto err_out_iounmap; 1526 goto err_out_iounmap;
1516 } 1527 }
1517 1528
1518 if (qlcnic_read_mac_addr(adapter))
1519 dev_warn(&pdev->dev, "failed to read mac addr\n");
1520
1521 err = qlcnic_setup_idc_param(adapter); 1529 err = qlcnic_setup_idc_param(adapter);
1522 if (err) 1530 if (err)
1523 goto err_out_iounmap; 1531 goto err_out_iounmap;