diff options
-rw-r--r-- | drivers/net/qlcnic/qlcnic.h | 2 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hdr.h | 6 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_init.c | 109 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 11 |
4 files changed, 100 insertions, 28 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 1f5c10bc9376..74eff18fc1ec 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -978,7 +978,7 @@ struct qlcnic_adapter { | |||
978 | u32 temp; | 978 | u32 temp; |
979 | 979 | ||
980 | u32 int_vec_bit; | 980 | u32 int_vec_bit; |
981 | u32 heartbit; | 981 | u32 heartbeat; |
982 | 982 | ||
983 | u8 max_mac_filters; | 983 | u8 max_mac_filters; |
984 | u8 dev_state; | 984 | u8 dev_state; |
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index bce1b1d541b7..716203e41dc7 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h | |||
@@ -747,8 +747,12 @@ enum { | |||
747 | 747 | ||
748 | #define QLCNIC_RESET_TIMEOUT_SECS 10 | 748 | #define QLCNIC_RESET_TIMEOUT_SECS 10 |
749 | #define QLCNIC_INIT_TIMEOUT_SECS 30 | 749 | #define QLCNIC_INIT_TIMEOUT_SECS 30 |
750 | #define QLCNIC_RCVPEG_CHECK_RETRY_COUNT 2000 | ||
751 | #define QLCNIC_RCVPEG_CHECK_DELAY 10 | ||
752 | #define QLCNIC_CMDPEG_CHECK_RETRY_COUNT 60 | ||
753 | #define QLCNIC_CMDPEG_CHECK_DELAY 500 | ||
750 | #define QLCNIC_HEARTBEAT_PERIOD_MSECS 200 | 754 | #define QLCNIC_HEARTBEAT_PERIOD_MSECS 200 |
751 | #define QLCNIC_HEARTBEAT_RETRY_COUNT 45 | 755 | #define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT 45 |
752 | 756 | ||
753 | #define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC))) | 757 | #define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC))) |
754 | #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) | 758 | #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) |
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index eb8256bec516..8e0e7a3bbf9e 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c | |||
@@ -46,6 +46,9 @@ static void | |||
46 | qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, | 46 | qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, |
47 | struct qlcnic_host_rds_ring *rds_ring); | 47 | struct qlcnic_host_rds_ring *rds_ring); |
48 | 48 | ||
49 | static int | ||
50 | qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter); | ||
51 | |||
49 | static void crb_addr_transform_setup(void) | 52 | static void crb_addr_transform_setup(void) |
50 | { | 53 | { |
51 | crb_addr_transform(XDMA); | 54 | crb_addr_transform(XDMA); |
@@ -544,31 +547,77 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) | |||
544 | return 0; | 547 | return 0; |
545 | } | 548 | } |
546 | 549 | ||
547 | int | 550 | static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter) |
548 | qlcnic_check_fw_status(struct qlcnic_adapter *adapter) | ||
549 | { | 551 | { |
550 | u32 heartbit, cmdpeg_state, ret = -EIO; | 552 | u32 val; |
551 | int retries = QLCNIC_HEARTBEAT_RETRY_COUNT; | 553 | int retries = QLCNIC_CMDPEG_CHECK_RETRY_COUNT; |
552 | 554 | ||
553 | adapter->heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); | ||
554 | do { | 555 | do { |
555 | msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS); | 556 | val = QLCRD32(adapter, CRB_CMDPEG_STATE); |
556 | heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); | 557 | |
557 | if (heartbit != adapter->heartbit) { | 558 | switch (val) { |
558 | cmdpeg_state = QLCRD32(adapter, CRB_CMDPEG_STATE); | 559 | case PHAN_INITIALIZE_COMPLETE: |
559 | /* Ensure peg states are initialized */ | 560 | case PHAN_INITIALIZE_ACK: |
560 | if (cmdpeg_state == PHAN_INITIALIZE_COMPLETE || | 561 | return 0; |
561 | cmdpeg_state == PHAN_INITIALIZE_ACK) { | 562 | case PHAN_INITIALIZE_FAILED: |
562 | /* Complete firmware handshake */ | 563 | goto out_err; |
563 | QLCWR32(adapter, CRB_CMDPEG_STATE, | 564 | default: |
564 | PHAN_INITIALIZE_ACK); | 565 | break; |
565 | ret = QLCNIC_RCODE_SUCCESS; | ||
566 | break; | ||
567 | } | ||
568 | } | 566 | } |
567 | |||
568 | msleep(QLCNIC_CMDPEG_CHECK_DELAY); | ||
569 | |||
569 | } while (--retries); | 570 | } while (--retries); |
570 | 571 | ||
571 | return ret; | 572 | QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED); |
573 | |||
574 | out_err: | ||
575 | dev_err(&adapter->pdev->dev, "Command Peg initialization not " | ||
576 | "complete, state: 0x%x.\n", val); | ||
577 | return -EIO; | ||
578 | } | ||
579 | |||
580 | static int | ||
581 | qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter) | ||
582 | { | ||
583 | u32 val; | ||
584 | int retries = QLCNIC_RCVPEG_CHECK_RETRY_COUNT; | ||
585 | |||
586 | do { | ||
587 | val = QLCRD32(adapter, CRB_RCVPEG_STATE); | ||
588 | |||
589 | if (val == PHAN_PEG_RCV_INITIALIZED) | ||
590 | return 0; | ||
591 | |||
592 | msleep(QLCNIC_RCVPEG_CHECK_DELAY); | ||
593 | |||
594 | } while (--retries); | ||
595 | |||
596 | if (!retries) { | ||
597 | dev_err(&adapter->pdev->dev, "Receive Peg initialization not " | ||
598 | "complete, state: 0x%x.\n", val); | ||
599 | return -EIO; | ||
600 | } | ||
601 | |||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | int | ||
606 | qlcnic_check_fw_status(struct qlcnic_adapter *adapter) | ||
607 | { | ||
608 | int err; | ||
609 | |||
610 | err = qlcnic_cmd_peg_ready(adapter); | ||
611 | if (err) | ||
612 | return err; | ||
613 | |||
614 | err = qlcnic_receive_peg_ready(adapter); | ||
615 | if (err) | ||
616 | return err; | ||
617 | |||
618 | QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); | ||
619 | |||
620 | return err; | ||
572 | } | 621 | } |
573 | 622 | ||
574 | int | 623 | int |
@@ -943,12 +992,32 @@ static void qlcnic_rom_lock_recovery(struct qlcnic_adapter *adapter) | |||
943 | qlcnic_pcie_sem_unlock(adapter, 2); | 992 | qlcnic_pcie_sem_unlock(adapter, 2); |
944 | } | 993 | } |
945 | 994 | ||
995 | static int | ||
996 | qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter) | ||
997 | { | ||
998 | u32 heartbeat, ret = -EIO; | ||
999 | int retries = QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT; | ||
1000 | |||
1001 | adapter->heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); | ||
1002 | |||
1003 | do { | ||
1004 | msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS); | ||
1005 | heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); | ||
1006 | if (heartbeat != adapter->heartbeat) { | ||
1007 | ret = QLCNIC_RCODE_SUCCESS; | ||
1008 | break; | ||
1009 | } | ||
1010 | } while (--retries); | ||
1011 | |||
1012 | return ret; | ||
1013 | } | ||
1014 | |||
946 | int | 1015 | int |
947 | qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) | 1016 | qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) |
948 | { | 1017 | { |
949 | u32 val, version, major, minor, build; | 1018 | u32 val, version, major, minor, build; |
950 | 1019 | ||
951 | if (qlcnic_check_fw_status(adapter)) { | 1020 | if (qlcnic_check_fw_hearbeat(adapter)) { |
952 | qlcnic_rom_lock_recovery(adapter); | 1021 | qlcnic_rom_lock_recovery(adapter); |
953 | return 1; | 1022 | return 1; |
954 | } | 1023 | } |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 6999d5aaa157..771a160b88c1 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -983,7 +983,7 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) | |||
983 | 983 | ||
984 | err = qlcnic_need_fw_reset(adapter); | 984 | err = qlcnic_need_fw_reset(adapter); |
985 | if (err == 0) | 985 | if (err == 0) |
986 | goto set_dev_ready; | 986 | goto check_fw_status; |
987 | 987 | ||
988 | err = qlcnic_pinit_from_rom(adapter); | 988 | err = qlcnic_pinit_from_rom(adapter); |
989 | if (err) | 989 | if (err) |
@@ -1002,7 +1002,6 @@ check_fw_status: | |||
1002 | if (err) | 1002 | if (err) |
1003 | goto err_out; | 1003 | goto err_out; |
1004 | 1004 | ||
1005 | set_dev_ready: | ||
1006 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); | 1005 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); |
1007 | qlcnic_idc_debug_info(adapter, 1); | 1006 | qlcnic_idc_debug_info(adapter, 1); |
1008 | 1007 | ||
@@ -2795,7 +2794,7 @@ done: | |||
2795 | static int | 2794 | static int |
2796 | qlcnic_check_health(struct qlcnic_adapter *adapter) | 2795 | qlcnic_check_health(struct qlcnic_adapter *adapter) |
2797 | { | 2796 | { |
2798 | u32 state = 0, heartbit; | 2797 | u32 state = 0, heartbeat; |
2799 | struct net_device *netdev = adapter->netdev; | 2798 | struct net_device *netdev = adapter->netdev; |
2800 | 2799 | ||
2801 | if (qlcnic_check_temp(adapter)) | 2800 | if (qlcnic_check_temp(adapter)) |
@@ -2811,9 +2810,9 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) | |||
2811 | adapter->need_fw_reset = 1; | 2810 | adapter->need_fw_reset = 1; |
2812 | } | 2811 | } |
2813 | 2812 | ||
2814 | heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); | 2813 | heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); |
2815 | if (heartbit != adapter->heartbit) { | 2814 | if (heartbeat != adapter->heartbeat) { |
2816 | adapter->heartbit = heartbit; | 2815 | adapter->heartbeat = heartbeat; |
2817 | adapter->fw_fail_cnt = 0; | 2816 | adapter->fw_fail_cnt = 0; |
2818 | if (adapter->need_fw_reset) | 2817 | if (adapter->need_fw_reset) |
2819 | goto detach; | 2818 | goto detach; |