aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic
diff options
context:
space:
mode:
authorAmit Kumar Salecha <amit.salecha@qlogic.com>2010-08-16 20:34:20 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-17 06:59:46 -0400
commit3c4b23b1be212d1b8494655182c0d4cef0a37be3 (patch)
tree9bf2241d05e19d5ed8b289fca4fb976a66ac3a69 /drivers/net/qlcnic
parent933fce12a33f219e9021a9ab7b2f9cff94fa8b0e (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.h5
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c80
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
2489err_ret: 2478err_ret:
@@ -2530,6 +2519,22 @@ err_ret:
2530 2519
2531} 2520}
2532 2521
2522/*Transit NPAR state to NON Operational */
2523static void
2524qlcnic_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 */
2534static void 2539static void
2535qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) 2540qlcnic_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)
2555static void 2561static void
2556qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) 2562qlcnic_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
2822qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) 2824qlcnicvf_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;