aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_init.c')
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c109
1 files changed, 89 insertions, 20 deletions
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
46qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, 46qlcnic_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
49static int
50qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter);
51
49static void crb_addr_transform_setup(void) 52static 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
547int 550static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter)
548qlcnic_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
574out_err:
575 dev_err(&adapter->pdev->dev, "Command Peg initialization not "
576 "complete, state: 0x%x.\n", val);
577 return -EIO;
578}
579
580static int
581qlcnic_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
605int
606qlcnic_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
574int 623int
@@ -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
995static int
996qlcnic_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
946int 1015int
947qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) 1016qlcnic_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 }