Skip to content

Commit

Permalink
qlcnic: modify reset recovery path in diag mode
Browse files Browse the repository at this point in the history
Provide diagnostics routines enough time to unwind before
proceeding with reset recovery.

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sony Chacko authored and David S. Miller committed May 25, 2013
1 parent 4690a7e commit 099907f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
6 changes: 5 additions & 1 deletion drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,6 @@ int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
void qlcnic_update_cmd_producer(struct qlcnic_host_tx_ring *);

/* Functions from qlcnic_ethtool.c */

int qlcnic_check_loopback_buff(unsigned char *, u8 []);
int qlcnic_do_lb_test(struct qlcnic_adapter *, u8);
int qlcnic_loopback_test(struct net_device *, u8);
Expand Down Expand Up @@ -1897,6 +1896,11 @@ static inline void qlcnic_release_diag_lock(struct qlcnic_adapter *adapter)
clear_bit(__QLCNIC_DIAG_MODE, &adapter->state);
}

static inline int qlcnic_check_diag_status(struct qlcnic_adapter *adapter)
{
return test_bit(__QLCNIC_DIAG_MODE, &adapter->state);
}

extern const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops;
extern const struct ethtool_ops qlcnic_ethtool_ops;
extern const struct ethtool_ops qlcnic_ethtool_failed_ops;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ struct qlc_83xx_idc {
u8 vnic_state;
u8 vnic_wait_limit;
u8 quiesce_req;
u8 delay_reset;
char **name;
};

Expand Down
35 changes: 28 additions & 7 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
ahw->idc.collect_dump = 0;
ahw->reset_context = 0;
adapter->tx_timeo_cnt = 0;
ahw->idc.delay_reset = 0;

clear_bit(__QLCNIC_RESETTING, &adapter->state);
}
Expand Down Expand Up @@ -883,21 +884,41 @@ static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter)
int ret = 0;

if (adapter->ahw->idc.prev_state != QLC_83XX_IDC_DEV_NEED_RESET) {
qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
set_bit(__QLCNIC_RESETTING, &adapter->state);
clear_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE)
qlcnic_83xx_disable_vnic_mode(adapter, 1);
qlcnic_83xx_idc_detach_driver(adapter);

if (qlcnic_check_diag_status(adapter)) {
dev_info(&adapter->pdev->dev,
"%s: Wait for diag completion\n", __func__);
adapter->ahw->idc.delay_reset = 1;
return 0;
} else {
qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
qlcnic_83xx_idc_detach_driver(adapter);
}
}

/* Check ACK from other functions */
ret = qlcnic_83xx_idc_check_reset_ack_reg(adapter);
if (ret) {
if (qlcnic_check_diag_status(adapter)) {
dev_info(&adapter->pdev->dev,
"%s: Waiting for reset ACK\n", __func__);
return 0;
"%s: Wait for diag completion\n", __func__);
return -1;
} else {
if (adapter->ahw->idc.delay_reset) {
qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
qlcnic_83xx_idc_detach_driver(adapter);
adapter->ahw->idc.delay_reset = 0;
}

/* Check for ACK from other functions */
ret = qlcnic_83xx_idc_check_reset_ack_reg(adapter);
if (ret) {
dev_info(&adapter->pdev->dev,
"%s: Waiting for reset ACK\n", __func__);
return -1;
}
}

/* Transit to INIT state and restart the HW */
Expand Down

0 comments on commit 099907f

Please sign in to comment.