diff options
author | Amit Kumar Salecha <amit.salecha@qlogic.com> | 2010-08-16 20:34:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-17 06:59:46 -0400 |
commit | 3c4b23b1be212d1b8494655182c0d4cef0a37be3 (patch) | |
tree | 9bf2241d05e19d5ed8b289fca4fb976a66ac3a69 /drivers/net/qlcnic | |
parent | 933fce12a33f219e9021a9ab7b2f9cff94fa8b0e (diff) |
qlcnic: device state management fixes for virtual func
o NPAR state should be set to operationl by Mangement function only.
o NPAR state should be set to non operational before device reset.
o VF function should wait for NPAR state to be operational.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hdr.h | 5 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 80 |
2 files changed, 51 insertions, 34 deletions
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 15fc32070be3..bd346d9aac94 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h | |||
@@ -718,8 +718,9 @@ enum { | |||
718 | #define QLCNIC_DEV_FAILED 0x6 | 718 | #define QLCNIC_DEV_FAILED 0x6 |
719 | #define QLCNIC_DEV_QUISCENT 0x7 | 719 | #define QLCNIC_DEV_QUISCENT 0x7 |
720 | 720 | ||
721 | #define QLCNIC_DEV_NPAR_NOT_RDY 0 | 721 | #define QLCNIC_DEV_NPAR_NON_OPER 0 /* NON Operational */ |
722 | #define QLCNIC_DEV_NPAR_RDY 1 | 722 | #define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */ |
723 | #define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */ | ||
723 | 724 | ||
724 | #define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) | 725 | #define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) |
725 | #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) | 726 | #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 4ecbf41230cb..70c4b6b0031e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -2398,7 +2398,7 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2398 | { | 2398 | { |
2399 | struct qlcnic_adapter *adapter = container_of(work, | 2399 | struct qlcnic_adapter *adapter = container_of(work, |
2400 | struct qlcnic_adapter, fw_work.work); | 2400 | struct qlcnic_adapter, fw_work.work); |
2401 | u32 dev_state = 0xf, npar_state; | 2401 | u32 dev_state = 0xf; |
2402 | 2402 | ||
2403 | if (qlcnic_api_lock(adapter)) | 2403 | if (qlcnic_api_lock(adapter)) |
2404 | goto err_ret; | 2404 | goto err_ret; |
@@ -2412,16 +2412,8 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2412 | } | 2412 | } |
2413 | 2413 | ||
2414 | if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { | 2414 | if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { |
2415 | npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | 2415 | qlcnic_api_unlock(adapter); |
2416 | if (npar_state == QLCNIC_DEV_NPAR_RDY) { | 2416 | goto wait_npar; |
2417 | qlcnic_api_unlock(adapter); | ||
2418 | goto wait_npar; | ||
2419 | } else { | ||
2420 | qlcnic_schedule_work(adapter, qlcnic_fwinit_work, | ||
2421 | FW_POLL_DELAY); | ||
2422 | qlcnic_api_unlock(adapter); | ||
2423 | return; | ||
2424 | } | ||
2425 | } | 2417 | } |
2426 | 2418 | ||
2427 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { | 2419 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { |
@@ -2470,20 +2462,17 @@ wait_npar: | |||
2470 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); | 2462 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); |
2471 | 2463 | ||
2472 | switch (dev_state) { | 2464 | switch (dev_state) { |
2473 | case QLCNIC_DEV_QUISCENT: | 2465 | case QLCNIC_DEV_READY: |
2474 | case QLCNIC_DEV_NEED_QUISCENT: | ||
2475 | case QLCNIC_DEV_NEED_RESET: | ||
2476 | qlcnic_schedule_work(adapter, | ||
2477 | qlcnic_fwinit_work, FW_POLL_DELAY); | ||
2478 | return; | ||
2479 | case QLCNIC_DEV_FAILED: | ||
2480 | break; | ||
2481 | |||
2482 | default: | ||
2483 | if (!adapter->nic_ops->start_firmware(adapter)) { | 2466 | if (!adapter->nic_ops->start_firmware(adapter)) { |
2484 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | 2467 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); |
2485 | return; | 2468 | return; |
2486 | } | 2469 | } |
2470 | case QLCNIC_DEV_FAILED: | ||
2471 | break; | ||
2472 | default: | ||
2473 | qlcnic_schedule_work(adapter, | ||
2474 | qlcnic_fwinit_work, FW_POLL_DELAY); | ||
2475 | return; | ||
2487 | } | 2476 | } |
2488 | 2477 | ||
2489 | err_ret: | 2478 | err_ret: |
@@ -2530,6 +2519,22 @@ err_ret: | |||
2530 | 2519 | ||
2531 | } | 2520 | } |
2532 | 2521 | ||
2522 | /*Transit NPAR state to NON Operational */ | ||
2523 | static void | ||
2524 | qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) | ||
2525 | { | ||
2526 | u32 state; | ||
2527 | |||
2528 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | ||
2529 | if (state == QLCNIC_DEV_NPAR_NON_OPER) | ||
2530 | return; | ||
2531 | |||
2532 | if (qlcnic_api_lock(adapter)) | ||
2533 | return; | ||
2534 | QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER); | ||
2535 | qlcnic_api_unlock(adapter); | ||
2536 | } | ||
2537 | |||
2533 | /*Transit to RESET state from READY state only */ | 2538 | /*Transit to RESET state from READY state only */ |
2534 | static void | 2539 | static void |
2535 | qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | 2540 | qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) |
@@ -2548,6 +2553,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | |||
2548 | qlcnic_idc_debug_info(adapter, 0); | 2553 | qlcnic_idc_debug_info(adapter, 0); |
2549 | } | 2554 | } |
2550 | 2555 | ||
2556 | QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER); | ||
2551 | qlcnic_api_unlock(adapter); | 2557 | qlcnic_api_unlock(adapter); |
2552 | } | 2558 | } |
2553 | 2559 | ||
@@ -2555,21 +2561,14 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | |||
2555 | static void | 2561 | static void |
2556 | qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) | 2562 | qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) |
2557 | { | 2563 | { |
2558 | u32 state; | ||
2559 | |||
2560 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || | 2564 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || |
2561 | adapter->op_mode == QLCNIC_NON_PRIV_FUNC) | 2565 | adapter->op_mode != QLCNIC_MGMT_FUNC) |
2562 | return; | 2566 | return; |
2563 | if (qlcnic_api_lock(adapter)) | 2567 | if (qlcnic_api_lock(adapter)) |
2564 | return; | 2568 | return; |
2565 | 2569 | ||
2566 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | 2570 | QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_OPER); |
2567 | 2571 | QLCDB(adapter, DRV, "NPAR operational state set\n"); | |
2568 | if (state != QLCNIC_DEV_NPAR_RDY) { | ||
2569 | QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, | ||
2570 | QLCNIC_DEV_NPAR_RDY); | ||
2571 | QLCDB(adapter, DRV, "NPAR READY state set\n"); | ||
2572 | } | ||
2573 | 2572 | ||
2574 | qlcnic_api_unlock(adapter); | 2573 | qlcnic_api_unlock(adapter); |
2575 | } | 2574 | } |
@@ -2631,8 +2630,11 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) | |||
2631 | qlcnic_dev_request_reset(adapter); | 2630 | qlcnic_dev_request_reset(adapter); |
2632 | 2631 | ||
2633 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2632 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
2634 | if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT) | 2633 | if (state == QLCNIC_DEV_NEED_RESET || |
2634 | state == QLCNIC_DEV_NEED_QUISCENT) { | ||
2635 | qlcnic_set_npar_non_operational(adapter); | ||
2635 | adapter->need_fw_reset = 1; | 2636 | adapter->need_fw_reset = 1; |
2637 | } | ||
2636 | 2638 | ||
2637 | heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); | 2639 | heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); |
2638 | if (heartbit != adapter->heartbit) { | 2640 | if (heartbit != adapter->heartbit) { |
@@ -2822,11 +2824,25 @@ static int | |||
2822 | qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) | 2824 | qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) |
2823 | { | 2825 | { |
2824 | int err; | 2826 | int err; |
2827 | u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; | ||
2828 | u32 npar_state; | ||
2825 | 2829 | ||
2826 | err = qlcnic_can_start_firmware(adapter); | 2830 | err = qlcnic_can_start_firmware(adapter); |
2827 | if (err) | 2831 | if (err) |
2828 | return err; | 2832 | return err; |
2829 | 2833 | ||
2834 | npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | ||
2835 | while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { | ||
2836 | msleep(1000); | ||
2837 | npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | ||
2838 | } | ||
2839 | |||
2840 | if (!npar_opt_timeo) { | ||
2841 | dev_err(&adapter->pdev->dev, | ||
2842 | "Waiting for NPAR state to opertional timeout\n"); | ||
2843 | return -EIO; | ||
2844 | } | ||
2845 | |||
2830 | qlcnic_check_options(adapter); | 2846 | qlcnic_check_options(adapter); |
2831 | 2847 | ||
2832 | adapter->need_fw_reset = 0; | 2848 | adapter->need_fw_reset = 0; |