Commit 602ca6f0 authored by Sritej Velaga's avatar Sritej Velaga Committed by David S. Miller

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: default avatarSritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: default avatarAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 21e84257
...@@ -895,6 +895,7 @@ struct qlcnic_ipaddr { ...@@ -895,6 +895,7 @@ struct qlcnic_ipaddr {
#define QLCNIC_MAC_OVERRIDE_DISABLED 0x400 #define QLCNIC_MAC_OVERRIDE_DISABLED 0x400
#define QLCNIC_PROMISC_DISABLED 0x800 #define QLCNIC_PROMISC_DISABLED 0x800
#define QLCNIC_NEED_FLR 0x1000 #define QLCNIC_NEED_FLR 0x1000
#define QLCNIC_FW_RESET_OWNER 0x2000
#define QLCNIC_IS_MSI_FAMILY(adapter) \ #define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
......
...@@ -95,8 +95,8 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) ...@@ -95,8 +95,8 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
QLCNIC_CDRP_CMD_TEMP_SIZE); QLCNIC_CDRP_CMD_TEMP_SIZE);
if (err != QLCNIC_RCODE_SUCCESS) { if (err != QLCNIC_RCODE_SUCCESS) {
err = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); err = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
dev_err(&adapter->pdev->dev, dev_info(&adapter->pdev->dev,
"Failed to get template size %d\n", err); "Can't get template size %d\n", err);
err = -EIO; err = -EIO;
return err; return err;
} }
......
...@@ -1590,10 +1590,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1590,10 +1590,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* This will be reset for mezz cards */ /* This will be reset for mezz cards */
adapter->portnum = adapter->ahw->pci_func; 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); err = qlcnic_get_board_info(adapter);
if (err) { if (err) {
dev_err(&pdev->dev, "Error getting board config info.\n"); 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,6 +1608,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_decr_ref; 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)) if (qlcnic_read_mac_addr(adapter))
dev_warn(&pdev->dev, "failed to read mac addr\n"); dev_warn(&pdev->dev, "failed to read mac addr\n");
...@@ -2683,11 +2685,16 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) ...@@ -2683,11 +2685,16 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
static int static int
qlcnic_check_drv_state(struct qlcnic_adapter *adapter) qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
{ {
int act, state; int act, state, active_mask;
state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 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)) || if (((state & 0x11111111) == (act & 0x11111111)) ||
((act & 0x11111111) == ((state >> 1) & 0x11111111))) ((act & 0x11111111) == ((state >> 1) & 0x11111111)))
return 0; return 0;
...@@ -2826,6 +2833,11 @@ qlcnic_fwinit_work(struct work_struct *work) ...@@ -2826,6 +2833,11 @@ qlcnic_fwinit_work(struct work_struct *work)
if (!qlcnic_check_drv_state(adapter)) { if (!qlcnic_check_drv_state(adapter)) {
skip_ack_check: 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); dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
if (dev_state == QLCNIC_DEV_NEED_RESET) { if (dev_state == QLCNIC_DEV_NEED_RESET) {
...@@ -2836,6 +2848,7 @@ qlcnic_fwinit_work(struct work_struct *work) ...@@ -2836,6 +2848,7 @@ qlcnic_fwinit_work(struct work_struct *work)
qlcnic_idc_debug_info(adapter, 0); qlcnic_idc_debug_info(adapter, 0);
QLCDB(adapter, DRV, "Take FW dump\n"); QLCDB(adapter, DRV, "Take FW dump\n");
qlcnic_dump_fw(adapter); qlcnic_dump_fw(adapter);
adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
} }
qlcnic_api_unlock(adapter); qlcnic_api_unlock(adapter);
...@@ -2900,9 +2913,11 @@ qlcnic_detach_work(struct work_struct *work) ...@@ -2900,9 +2913,11 @@ qlcnic_detach_work(struct work_struct *work)
if (adapter->temp == QLCNIC_TEMP_PANIC) if (adapter->temp == QLCNIC_TEMP_PANIC)
goto err_ret; goto err_ret;
/* Dont ack if this instance is the reset owner */
if (qlcnic_set_drv_state(adapter, adapter->dev_state)) if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
goto err_ret; if (qlcnic_set_drv_state(adapter, adapter->dev_state))
goto err_ret;
}
adapter->fw_wait_cnt = 0; adapter->fw_wait_cnt = 0;
...@@ -2947,6 +2962,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) ...@@ -2947,6 +2962,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
if (state == QLCNIC_DEV_READY) { if (state == QLCNIC_DEV_READY) {
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET); QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
adapter->flags |= QLCNIC_FW_RESET_OWNER;
QLCDB(adapter, DRV, "NEED_RESET state set\n"); QLCDB(adapter, DRV, "NEED_RESET state set\n");
qlcnic_idc_debug_info(adapter, 0); qlcnic_idc_debug_info(adapter, 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment