aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_main.c
diff options
context:
space:
mode:
authorSritej Velaga <sritej.velaga@qlogic.com>2011-06-21 22:52:17 -0400
committerDavid S. Miller <davem@davemloft.net>2011-06-24 04:17:06 -0400
commit602ca6f00a0d95a0d0cec84f492324ee71d14e09 (patch)
tree50fdf6d21e2d5593086b8d5a5a906964f950b268 /drivers/net/qlcnic/qlcnic_main.c
parent21e842579a5fd1ce746be4e34ac53ef67d6f0a6b (diff)
qlcnic: Add capability to take FW dump deterministically
In presence of multiple functions, current driver implementation does not guarantee that the FW dump is taken by the same function that forces it. Change it by adding a fw reset owner flag that could be changed in the device reset path and only when a function determines that it needs to reset it. Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com> 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.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 347a4a8d1267..0ddbb80eefc7 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1590,10 +1590,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1590 /* This will be reset for mezz cards */ 1590 /* This will be reset for mezz cards */
1591 adapter->portnum = adapter->ahw->pci_func; 1591 adapter->portnum = adapter->ahw->pci_func;
1592 1592
1593 /* Get FW dump template and store it */
1594 if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
1595 qlcnic_fw_cmd_get_minidump_temp(adapter);
1596
1597 err = qlcnic_get_board_info(adapter); 1593 err = qlcnic_get_board_info(adapter);
1598 if (err) { 1594 if (err) {
1599 dev_err(&pdev->dev, "Error getting board config info.\n"); 1595 dev_err(&pdev->dev, "Error getting board config info.\n");
@@ -1612,6 +1608,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1612 goto err_out_decr_ref; 1608 goto err_out_decr_ref;
1613 } 1609 }
1614 1610
1611 /* Get FW dump template and store it */
1612 if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
1613 if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
1614 dev_info(&pdev->dev,
1615 "Supports FW dump capability\n");
1616
1615 if (qlcnic_read_mac_addr(adapter)) 1617 if (qlcnic_read_mac_addr(adapter))
1616 dev_warn(&pdev->dev, "failed to read mac addr\n"); 1618 dev_warn(&pdev->dev, "failed to read mac addr\n");
1617 1619
@@ -2683,11 +2685,16 @@ err:
2683static int 2685static int
2684qlcnic_check_drv_state(struct qlcnic_adapter *adapter) 2686qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
2685{ 2687{
2686 int act, state; 2688 int act, state, active_mask;
2687 2689
2688 state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); 2690 state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
2689 act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 2691 act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
2690 2692
2693 if (adapter->flags & QLCNIC_FW_RESET_OWNER) {
2694 active_mask = (~(1 << (adapter->ahw->pci_func * 4)));
2695 act = act & active_mask;
2696 }
2697
2691 if (((state & 0x11111111) == (act & 0x11111111)) || 2698 if (((state & 0x11111111) == (act & 0x11111111)) ||
2692 ((act & 0x11111111) == ((state >> 1) & 0x11111111))) 2699 ((act & 0x11111111) == ((state >> 1) & 0x11111111)))
2693 return 0; 2700 return 0;
@@ -2826,6 +2833,11 @@ qlcnic_fwinit_work(struct work_struct *work)
2826 2833
2827 if (!qlcnic_check_drv_state(adapter)) { 2834 if (!qlcnic_check_drv_state(adapter)) {
2828skip_ack_check: 2835skip_ack_check:
2836 if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
2837 qlcnic_api_unlock(adapter);
2838 goto wait_npar;
2839 }
2840
2829 dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); 2841 dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
2830 2842
2831 if (dev_state == QLCNIC_DEV_NEED_RESET) { 2843 if (dev_state == QLCNIC_DEV_NEED_RESET) {
@@ -2836,6 +2848,7 @@ skip_ack_check:
2836 qlcnic_idc_debug_info(adapter, 0); 2848 qlcnic_idc_debug_info(adapter, 0);
2837 QLCDB(adapter, DRV, "Take FW dump\n"); 2849 QLCDB(adapter, DRV, "Take FW dump\n");
2838 qlcnic_dump_fw(adapter); 2850 qlcnic_dump_fw(adapter);
2851 adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
2839 } 2852 }
2840 2853
2841 qlcnic_api_unlock(adapter); 2854 qlcnic_api_unlock(adapter);
@@ -2900,9 +2913,11 @@ qlcnic_detach_work(struct work_struct *work)
2900 2913
2901 if (adapter->temp == QLCNIC_TEMP_PANIC) 2914 if (adapter->temp == QLCNIC_TEMP_PANIC)
2902 goto err_ret; 2915 goto err_ret;
2903 2916 /* Dont ack if this instance is the reset owner */
2904 if (qlcnic_set_drv_state(adapter, adapter->dev_state)) 2917 if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
2905 goto err_ret; 2918 if (qlcnic_set_drv_state(adapter, adapter->dev_state))
2919 goto err_ret;
2920 }
2906 2921
2907 adapter->fw_wait_cnt = 0; 2922 adapter->fw_wait_cnt = 0;
2908 2923
@@ -2947,6 +2962,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
2947 2962
2948 if (state == QLCNIC_DEV_READY) { 2963 if (state == QLCNIC_DEV_READY) {
2949 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET); 2964 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
2965 adapter->flags |= QLCNIC_FW_RESET_OWNER;
2950 QLCDB(adapter, DRV, "NEED_RESET state set\n"); 2966 QLCDB(adapter, DRV, "NEED_RESET state set\n");
2951 qlcnic_idc_debug_info(adapter, 0); 2967 qlcnic_idc_debug_info(adapter, 0);
2952 } 2968 }