aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/qlcnic/qlcnic_main.c
diff options
context:
space:
mode:
authorSritej Velaga <sritej.velaga@qlogic.com>2011-06-22 02:52:17 +0000
committerDavid S. Miller <davem@davemloft.net>2011-06-24 01:17:06 -0700
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 347a4a8d126..0ddbb80eefc 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)
/* This will be reset for mezz cards */
adapter->portnum = adapter->ahw->pci_func;
- /* Get FW dump template and store it */
- if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
- qlcnic_fw_cmd_get_minidump_temp(adapter);
-
err = qlcnic_get_board_info(adapter);
if (err) {
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)
goto err_out_decr_ref;
}
+ /* Get FW dump template and store it */
+ if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
+ if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
+ dev_info(&pdev->dev,
+ "Supports FW dump capability\n");
+
if (qlcnic_read_mac_addr(adapter))
dev_warn(&pdev->dev, "failed to read mac addr\n");
@@ -2683,11 +2685,16 @@ err:
static int
qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
{
- int act, state;
+ int act, state, active_mask;
state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
+ if (adapter->flags & QLCNIC_FW_RESET_OWNER) {
+ active_mask = (~(1 << (adapter->ahw->pci_func * 4)));
+ act = act & active_mask;
+ }
+
if (((state & 0x11111111) == (act & 0x11111111)) ||
((act & 0x11111111) == ((state >> 1) & 0x11111111)))
return 0;
@@ -2826,6 +2833,11 @@ qlcnic_fwinit_work(struct work_struct *work)
if (!qlcnic_check_drv_state(adapter)) {
skip_ack_check:
+ if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
+ qlcnic_api_unlock(adapter);
+ goto wait_npar;
+ }
+
dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
if (dev_state == QLCNIC_DEV_NEED_RESET) {
@@ -2836,6 +2848,7 @@ skip_ack_check:
qlcnic_idc_debug_info(adapter, 0);
QLCDB(adapter, DRV, "Take FW dump\n");
qlcnic_dump_fw(adapter);
+ adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
}
qlcnic_api_unlock(adapter);
@@ -2900,9 +2913,11 @@ qlcnic_detach_work(struct work_struct *work)
if (adapter->temp == QLCNIC_TEMP_PANIC)
goto err_ret;
-
- if (qlcnic_set_drv_state(adapter, adapter->dev_state))
- goto err_ret;
+ /* Dont ack if this instance is the reset owner */
+ if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
+ if (qlcnic_set_drv_state(adapter, adapter->dev_state))
+ goto err_ret;
+ }
adapter->fw_wait_cnt = 0;
@@ -2947,6 +2962,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
if (state == QLCNIC_DEV_READY) {
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
+ adapter->flags |= QLCNIC_FW_RESET_OWNER;
QLCDB(adapter, DRV, "NEED_RESET state set\n");
qlcnic_idc_debug_info(adapter, 0);
}