Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 215113
b: refs/heads/master
c: b8c1762
h: refs/heads/master
i:
  215111: 847df66
v: v3
  • Loading branch information
Amit Kumar Salecha authored and David S. Miller committed Oct 8, 2010
1 parent 79fd322 commit a0df0b3
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f7ec804a3edd2f7cf98a42bcad741d89d547c117
refs/heads/master: b8c17620458b82fd868f4813e1ff18368a832b7c
2 changes: 2 additions & 0 deletions trunk/drivers/net/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,8 @@ int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter);
void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);

/* Functions from qlcnic_main.c */
int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter);
void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter);
int qlcnic_reset_context(struct qlcnic_adapter *);
u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd);
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/qlcnic/qlcnic_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,11 @@ static int qlcnic_loopback_test(struct net_device *netdev)
if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
return -EIO;

if (qlcnic_request_quiscent_mode(adapter)) {
clear_bit(__QLCNIC_RESETTING, &adapter->state);
return -EIO;
}

ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
if (ret)
goto clear_it;
Expand All @@ -722,6 +727,7 @@ static int qlcnic_loopback_test(struct net_device *netdev)
qlcnic_diag_free_res(netdev, max_sds_rings);

clear_it:
qlcnic_clear_quiscent_mode(adapter);
adapter->max_sds_rings = max_sds_rings;
clear_bit(__QLCNIC_RESETTING, &adapter->state);
return ret;
Expand Down
83 changes: 66 additions & 17 deletions trunk/drivers/net/qlcnic/qlcnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2712,7 +2712,8 @@ qlcnic_fwinit_work(struct work_struct *work)
goto err_ret;

dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
if (dev_state == QLCNIC_DEV_QUISCENT) {
if (dev_state == QLCNIC_DEV_QUISCENT ||
dev_state == QLCNIC_DEV_NEED_QUISCENT) {
qlcnic_api_unlock(adapter);
qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
FW_POLL_DELAY * 2);
Expand All @@ -2734,18 +2735,6 @@ qlcnic_fwinit_work(struct work_struct *work)
skip_ack_check:
dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);

if (dev_state == QLCNIC_DEV_NEED_QUISCENT) {
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
QLCNIC_DEV_QUISCENT);
qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
FW_POLL_DELAY * 2);
QLCDB(adapter, DRV, "Quiscing the driver\n");
qlcnic_idc_debug_info(adapter, 0);

qlcnic_api_unlock(adapter);
return;
}

if (dev_state == QLCNIC_DEV_NEED_RESET) {
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
QLCNIC_DEV_INITIALIZING);
Expand Down Expand Up @@ -2802,7 +2791,12 @@ qlcnic_detach_work(struct work_struct *work)

netif_device_detach(netdev);

qlcnic_down(adapter, netdev);
/* Dont grab rtnl lock during Quiscent mode */
if (adapter->dev_state == QLCNIC_DEV_NEED_QUISCENT) {
if (netif_running(netdev))
__qlcnic_down(adapter, netdev);
} else
qlcnic_down(adapter, netdev);

status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1);

Expand Down Expand Up @@ -2844,6 +2838,61 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
qlcnic_api_unlock(adapter);
}

/* Caller should held RESETTING bit.
* This should be call in sync with qlcnic_request_quiscent_mode.
*/
void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter)
{
qlcnic_clr_drv_state(adapter);
qlcnic_api_lock(adapter);
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
qlcnic_api_unlock(adapter);
}

/* Caller should held RESETTING bit.
*/
int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter)
{
u8 timeo = adapter->dev_init_timeo / 2;
u32 state;

if (qlcnic_api_lock(adapter))
return -EIO;

state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
if (state != QLCNIC_DEV_READY)
return -EIO;

QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_QUISCENT);
qlcnic_api_unlock(adapter);
QLCDB(adapter, DRV, "NEED QUISCENT state set\n");
qlcnic_idc_debug_info(adapter, 0);

qlcnic_set_drv_state(adapter, QLCNIC_DEV_NEED_QUISCENT);

do {
msleep(2000);
state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
if (state == QLCNIC_DEV_QUISCENT)
return 0;
if (!qlcnic_check_drv_state(adapter)) {
if (qlcnic_api_lock(adapter))
return -EIO;
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
QLCNIC_DEV_QUISCENT);
qlcnic_api_unlock(adapter);
QLCDB(adapter, DRV, "QUISCENT mode set\n");
return 0;
}
} while (--timeo);

dev_err(&adapter->pdev->dev, "Failed to quiesce device, DRV_STATE=%08x"
" DRV_ACTIVE=%08x\n", QLCRD32(adapter, QLCNIC_CRB_DRV_STATE),
QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE));
qlcnic_clear_quiscent_mode(adapter);
return -EIO;
}

/*Transit to RESET state from READY state only */
static void
qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
Expand Down Expand Up @@ -2951,11 +3000,11 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
qlcnic_dev_request_reset(adapter);

state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
if (state == QLCNIC_DEV_NEED_RESET ||
state == QLCNIC_DEV_NEED_QUISCENT) {
if (state == QLCNIC_DEV_NEED_RESET) {
qlcnic_set_npar_non_operational(adapter);
adapter->need_fw_reset = 1;
}
} else if (state == QLCNIC_DEV_NEED_QUISCENT)
goto detach;

heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
if (heartbeat != adapter->heartbeat) {
Expand Down

0 comments on commit a0df0b3

Please sign in to comment.