diff options
author | Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> | 2013-02-09 04:29:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-11 02:04:13 -0500 |
commit | 65ab999da808f72e3fe82be8f7d35050d3126005 (patch) | |
tree | d6c68363a0ae3b9cf0074acd1626744d5362682d /drivers | |
parent | dce056cb215e4803ed6e9efffd03705ca0671913 (diff) |
qlcnic: fix mailbox response handling
o Do not read mailbox registers on timeout
o Add a helper function to handle mailbox response
Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 51b4340deffa..f7b39d1067fb 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -664,6 +664,21 @@ static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter, | |||
664 | pr_info("\n"); | 664 | pr_info("\n"); |
665 | } | 665 | } |
666 | 666 | ||
667 | /* Mailbox response for mac rcode */ | ||
668 | static u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter) | ||
669 | { | ||
670 | u32 fw_data; | ||
671 | u8 mac_cmd_rcode; | ||
672 | |||
673 | fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2)); | ||
674 | mac_cmd_rcode = (u8)fw_data; | ||
675 | if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE || | ||
676 | mac_cmd_rcode == QLC_83XX_MAC_PRESENT || | ||
677 | mac_cmd_rcode == QLC_83XX_MAC_ABSENT) | ||
678 | return QLCNIC_RCODE_SUCCESS; | ||
679 | return 1; | ||
680 | } | ||
681 | |||
667 | static u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter) | 682 | static u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter) |
668 | { | 683 | { |
669 | u32 data; | 684 | u32 data; |
@@ -686,7 +701,7 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, | |||
686 | { | 701 | { |
687 | int i; | 702 | int i; |
688 | u16 opcode; | 703 | u16 opcode; |
689 | u8 mbx_err_code, mac_cmd_rcode; | 704 | u8 mbx_err_code; |
690 | u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd; | 705 | u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd; |
691 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 706 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
692 | 707 | ||
@@ -722,45 +737,44 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, | |||
722 | QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER); | 737 | QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER); |
723 | poll: | 738 | poll: |
724 | rsp = qlcnic_83xx_mbx_poll(adapter); | 739 | rsp = qlcnic_83xx_mbx_poll(adapter); |
725 | /* Get the FW response data */ | ||
726 | fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); | ||
727 | mbx_err_code = QLCNIC_MBX_STATUS(fw_data); | ||
728 | rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); | ||
729 | opcode = QLCNIC_MBX_RSP(fw_data); | ||
730 | |||
731 | if (rsp != QLCNIC_RCODE_TIMEOUT) { | 740 | if (rsp != QLCNIC_RCODE_TIMEOUT) { |
741 | /* Get the FW response data */ | ||
742 | fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); | ||
732 | if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { | 743 | if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { |
733 | qlcnic_83xx_process_aen(adapter); | 744 | qlcnic_83xx_process_aen(adapter); |
734 | mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); | 745 | mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); |
735 | if (mbx_val) | 746 | if (mbx_val) |
736 | goto poll; | 747 | goto poll; |
737 | } else if ((mbx_err_code == QLCNIC_MBX_RSP_OK) || | 748 | } |
738 | (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) { | 749 | mbx_err_code = QLCNIC_MBX_STATUS(fw_data); |
739 | qlcnic_83xx_get_mbx_data(adapter, cmd); | 750 | rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); |
751 | opcode = QLCNIC_MBX_RSP(fw_data); | ||
752 | qlcnic_83xx_get_mbx_data(adapter, cmd); | ||
753 | |||
754 | switch (mbx_err_code) { | ||
755 | case QLCNIC_MBX_RSP_OK: | ||
756 | case QLCNIC_MBX_PORT_RSP_OK: | ||
740 | rsp = QLCNIC_RCODE_SUCCESS; | 757 | rsp = QLCNIC_RCODE_SUCCESS; |
741 | } else { | 758 | break; |
742 | qlcnic_83xx_get_mbx_data(adapter, cmd); | 759 | default: |
743 | if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) { | 760 | if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) { |
744 | fw_data = readl(QLCNIC_MBX_FW(ahw, 2)); | 761 | rsp = qlcnic_83xx_mac_rcode(adapter); |
745 | mac_cmd_rcode = (u8)fw_data; | 762 | if (!rsp) |
746 | if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE || | ||
747 | mac_cmd_rcode == QLC_83XX_MAC_PRESENT || | ||
748 | mac_cmd_rcode == QLC_83XX_MAC_ABSENT) { | ||
749 | rsp = QLCNIC_RCODE_SUCCESS; | ||
750 | goto out; | 763 | goto out; |
751 | } | ||
752 | } | 764 | } |
753 | dev_info(&adapter->pdev->dev, | 765 | dev_err(&adapter->pdev->dev, |
754 | "MBX command 0x%x failed with err:0x%x\n", | 766 | "MBX command 0x%x failed with err:0x%x\n", |
755 | opcode, mbx_err_code); | 767 | opcode, mbx_err_code); |
756 | rsp = mbx_err_code; | 768 | rsp = mbx_err_code; |
757 | qlcnic_dump_mbx(adapter, cmd); | 769 | qlcnic_dump_mbx(adapter, cmd); |
770 | break; | ||
758 | } | 771 | } |
759 | } else { | 772 | goto out; |
760 | dev_info(&adapter->pdev->dev, | ||
761 | "MBX command 0x%x timed out\n", opcode); | ||
762 | qlcnic_dump_mbx(adapter, cmd); | ||
763 | } | 773 | } |
774 | |||
775 | dev_err(&adapter->pdev->dev, "MBX command 0x%x timed out\n", | ||
776 | QLCNIC_MBX_RSP(mbx_cmd)); | ||
777 | rsp = QLCNIC_RCODE_TIMEOUT; | ||
764 | out: | 778 | out: |
765 | /* clear fw mbx control register */ | 779 | /* clear fw mbx control register */ |
766 | QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER); | 780 | QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER); |