aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c743
1 files changed, 572 insertions, 171 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 9d4bb7f83904..a1818dae47b6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -11,6 +11,7 @@
11#include <linux/ipv6.h> 11#include <linux/ipv6.h>
12#include <linux/ethtool.h> 12#include <linux/ethtool.h>
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/aer.h>
14 15
15#define QLCNIC_MAX_TX_QUEUES 1 16#define QLCNIC_MAX_TX_QUEUES 1
16#define RSS_HASHTYPE_IP_TCP 0x3 17#define RSS_HASHTYPE_IP_TCP 0x3
@@ -67,6 +68,8 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
67 {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26}, 68 {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
68 {QLCNIC_CMD_CONFIG_VPORT, 4, 4}, 69 {QLCNIC_CMD_CONFIG_VPORT, 4, 4},
69 {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1}, 70 {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
71 {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
72 {QLCNIC_CMD_DCB_QUERY_PARAM, 2, 50},
70}; 73};
71 74
72const u32 qlcnic_83xx_ext_reg_tbl[] = { 75const u32 qlcnic_83xx_ext_reg_tbl[] = {
@@ -149,7 +152,7 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
149 .get_mac_address = qlcnic_83xx_get_mac_address, 152 .get_mac_address = qlcnic_83xx_get_mac_address,
150 .setup_intr = qlcnic_83xx_setup_intr, 153 .setup_intr = qlcnic_83xx_setup_intr,
151 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args, 154 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
152 .mbx_cmd = qlcnic_83xx_mbx_op, 155 .mbx_cmd = qlcnic_83xx_issue_cmd,
153 .get_func_no = qlcnic_83xx_get_func_no, 156 .get_func_no = qlcnic_83xx_get_func_no,
154 .api_lock = qlcnic_83xx_cam_lock, 157 .api_lock = qlcnic_83xx_cam_lock,
155 .api_unlock = qlcnic_83xx_cam_unlock, 158 .api_unlock = qlcnic_83xx_cam_unlock,
@@ -175,6 +178,10 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
175 .get_board_info = qlcnic_83xx_get_port_info, 178 .get_board_info = qlcnic_83xx_get_port_info,
176 .set_mac_filter_count = qlcnic_83xx_set_mac_filter_count, 179 .set_mac_filter_count = qlcnic_83xx_set_mac_filter_count,
177 .free_mac_list = qlcnic_82xx_free_mac_list, 180 .free_mac_list = qlcnic_82xx_free_mac_list,
181 .io_error_detected = qlcnic_83xx_io_error_detected,
182 .io_slot_reset = qlcnic_83xx_io_slot_reset,
183 .io_resume = qlcnic_83xx_io_resume,
184
178}; 185};
179 186
180static struct qlcnic_nic_template qlcnic_83xx_ops = { 187static struct qlcnic_nic_template qlcnic_83xx_ops = {
@@ -261,7 +268,7 @@ int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
261 } 268 }
262} 269}
263 270
264int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) 271int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr, int txq)
265{ 272{
266 int err, i, num_msix; 273 int err, i, num_msix;
267 struct qlcnic_hardware_context *ahw = adapter->ahw; 274 struct qlcnic_hardware_context *ahw = adapter->ahw;
@@ -362,6 +369,10 @@ static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
362 struct qlcnic_cmd_args *cmd) 369 struct qlcnic_cmd_args *cmd)
363{ 370{
364 int i; 371 int i;
372
373 if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
374 return;
375
365 for (i = 0; i < cmd->rsp.num; i++) 376 for (i = 0; i < cmd->rsp.num; i++)
366 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i)); 377 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
367} 378}
@@ -398,24 +409,33 @@ irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
398 return IRQ_HANDLED; 409 return IRQ_HANDLED;
399} 410}
400 411
412static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
413{
414 atomic_set(&mbx->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
415 complete(&mbx->completion);
416}
417
401static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter) 418static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
402{ 419{
403 u32 resp, event; 420 u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
421 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
404 unsigned long flags; 422 unsigned long flags;
405 423
406 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags); 424 spin_lock_irqsave(&mbx->aen_lock, flags);
407
408 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL); 425 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
409 if (!(resp & QLCNIC_SET_OWNER)) 426 if (!(resp & QLCNIC_SET_OWNER))
410 goto out; 427 goto out;
411 428
412 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0)); 429 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
413 if (event & QLCNIC_MBX_ASYNC_EVENT) 430 if (event & QLCNIC_MBX_ASYNC_EVENT) {
414 __qlcnic_83xx_process_aen(adapter); 431 __qlcnic_83xx_process_aen(adapter);
415 432 } else {
433 if (atomic_read(&mbx->rsp_status) != rsp_status)
434 qlcnic_83xx_notify_mbx_response(mbx);
435 }
416out: 436out:
417 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter); 437 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
418 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags); 438 spin_unlock_irqrestore(&mbx->aen_lock, flags);
419} 439}
420 440
421irqreturn_t qlcnic_83xx_intr(int irq, void *data) 441irqreturn_t qlcnic_83xx_intr(int irq, void *data)
@@ -515,7 +535,7 @@ int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
515 } 535 }
516 536
517 /* Enable mailbox interrupt */ 537 /* Enable mailbox interrupt */
518 qlcnic_83xx_enable_mbx_intrpt(adapter); 538 qlcnic_83xx_enable_mbx_interrupt(adapter);
519 539
520 return err; 540 return err;
521} 541}
@@ -628,7 +648,7 @@ void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
628 ahw->max_uc_count = count; 648 ahw->max_uc_count = count;
629} 649}
630 650
631void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter) 651void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *adapter)
632{ 652{
633 u32 val; 653 u32 val;
634 654
@@ -682,11 +702,14 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
682static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter, 702static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
683 u32 data[]); 703 u32 data[]);
684 704
685static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter, 705void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
686 struct qlcnic_cmd_args *cmd) 706 struct qlcnic_cmd_args *cmd)
687{ 707{
688 int i; 708 int i;
689 709
710 if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
711 return;
712
690 dev_info(&adapter->pdev->dev, 713 dev_info(&adapter->pdev->dev,
691 "Host MBX regs(%d)\n", cmd->req.num); 714 "Host MBX regs(%d)\n", cmd->req.num);
692 for (i = 0; i < cmd->req.num; i++) { 715 for (i = 0; i < cmd->req.num; i++) {
@@ -705,120 +728,73 @@ static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
705 pr_info("\n"); 728 pr_info("\n");
706} 729}
707 730
708/* Mailbox response for mac rcode */ 731static void qlcnic_83xx_poll_for_mbx_completion(struct qlcnic_adapter *adapter,
709u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter) 732 struct qlcnic_cmd_args *cmd)
710{ 733{
711 u32 fw_data; 734 struct qlcnic_hardware_context *ahw = adapter->ahw;
712 u8 mac_cmd_rcode; 735 int opcode = LSW(cmd->req.arg[0]);
736 unsigned long max_loops;
713 737
714 fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2)); 738 max_loops = cmd->total_cmds * QLC_83XX_MBX_CMD_LOOP;
715 mac_cmd_rcode = (u8)fw_data;
716 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
717 mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
718 mac_cmd_rcode == QLC_83XX_MAC_ABSENT)
719 return QLCNIC_RCODE_SUCCESS;
720 return 1;
721}
722 739
723u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter, u32 *wait_time) 740 for (; max_loops; max_loops--) {
724{ 741 if (atomic_read(&cmd->rsp_status) ==
725 u32 data; 742 QLC_83XX_MBX_RESPONSE_ARRIVED)
726 struct qlcnic_hardware_context *ahw = adapter->ahw; 743 return;
727 /* wait for mailbox completion */ 744
728 do { 745 udelay(1);
729 data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL); 746 }
730 if (++(*wait_time) > QLCNIC_MBX_TIMEOUT) { 747
731 data = QLCNIC_RCODE_TIMEOUT; 748 dev_err(&adapter->pdev->dev,
732 break; 749 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
733 } 750 __func__, opcode, cmd->type, ahw->pci_func, ahw->op_mode);
734 mdelay(1); 751 flush_workqueue(ahw->mailbox->work_q);
735 } while (!data); 752 return;
736 return data;
737} 753}
738 754
739int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, 755int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter,
740 struct qlcnic_cmd_args *cmd) 756 struct qlcnic_cmd_args *cmd)
741{ 757{
742 int i; 758 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
743 u16 opcode;
744 u8 mbx_err_code;
745 unsigned long flags;
746 struct qlcnic_hardware_context *ahw = adapter->ahw; 759 struct qlcnic_hardware_context *ahw = adapter->ahw;
747 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, wait_time = 0; 760 int cmd_type, err, opcode;
761 unsigned long timeout;
748 762
749 opcode = LSW(cmd->req.arg[0]); 763 opcode = LSW(cmd->req.arg[0]);
750 if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) { 764 cmd_type = cmd->type;
751 dev_info(&adapter->pdev->dev, 765 err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
752 "Mailbox cmd attempted, 0x%x\n", opcode); 766 if (err) {
753 dev_info(&adapter->pdev->dev, "Mailbox detached\n"); 767 dev_err(&adapter->pdev->dev,
754 return 0; 768 "%s: Mailbox not available, cmd_op=0x%x, cmd_context=0x%x, pci_func=0x%x, op_mode=0x%x\n",
769 __func__, opcode, cmd->type, ahw->pci_func,
770 ahw->op_mode);
771 return err;
755 } 772 }
756 773
757 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags); 774 switch (cmd_type) {
758 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); 775 case QLC_83XX_MBX_CMD_WAIT:
759 776 if (!wait_for_completion_timeout(&cmd->completion, timeout)) {
760 if (mbx_val) {
761 QLCDB(adapter, DRV,
762 "Mailbox cmd attempted, 0x%x\n", opcode);
763 QLCDB(adapter, DRV,
764 "Mailbox not available, 0x%x, collect FW dump\n",
765 mbx_val);
766 cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
767 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
768 return cmd->rsp.arg[0];
769 }
770
771 /* Fill in mailbox registers */
772 mbx_cmd = cmd->req.arg[0];
773 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
774 for (i = 1; i < cmd->req.num; i++)
775 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
776
777 /* Signal FW about the impending command */
778 QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
779poll:
780 rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
781 if (rsp != QLCNIC_RCODE_TIMEOUT) {
782 /* Get the FW response data */
783 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
784 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
785 __qlcnic_83xx_process_aen(adapter);
786 goto poll;
787 }
788 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
789 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
790 opcode = QLCNIC_MBX_RSP(fw_data);
791 qlcnic_83xx_get_mbx_data(adapter, cmd);
792
793 switch (mbx_err_code) {
794 case QLCNIC_MBX_RSP_OK:
795 case QLCNIC_MBX_PORT_RSP_OK:
796 rsp = QLCNIC_RCODE_SUCCESS;
797 break;
798 default:
799 if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
800 rsp = qlcnic_83xx_mac_rcode(adapter);
801 if (!rsp)
802 goto out;
803 }
804 dev_err(&adapter->pdev->dev, 777 dev_err(&adapter->pdev->dev,
805 "MBX command 0x%x failed with err:0x%x\n", 778 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
806 opcode, mbx_err_code); 779 __func__, opcode, cmd_type, ahw->pci_func,
807 rsp = mbx_err_code; 780 ahw->op_mode);
808 qlcnic_dump_mbx(adapter, cmd); 781 flush_workqueue(mbx->work_q);
809 break;
810 } 782 }
811 goto out; 783 break;
784 case QLC_83XX_MBX_CMD_NO_WAIT:
785 return 0;
786 case QLC_83XX_MBX_CMD_BUSY_WAIT:
787 qlcnic_83xx_poll_for_mbx_completion(adapter, cmd);
788 break;
789 default:
790 dev_err(&adapter->pdev->dev,
791 "%s: Invalid mailbox command, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
792 __func__, opcode, cmd_type, ahw->pci_func,
793 ahw->op_mode);
794 qlcnic_83xx_detach_mailbox_work(adapter);
812 } 795 }
813 796
814 dev_err(&adapter->pdev->dev, "MBX command 0x%x timed out\n", 797 return cmd->rsp_opcode;
815 QLCNIC_MBX_RSP(mbx_cmd));
816 rsp = QLCNIC_RCODE_TIMEOUT;
817out:
818 /* clear fw mbx control register */
819 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
820 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
821 return rsp;
822} 798}
823 799
824int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx, 800int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
@@ -828,6 +804,7 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
828 u32 temp; 804 u32 temp;
829 const struct qlcnic_mailbox_metadata *mbx_tbl; 805 const struct qlcnic_mailbox_metadata *mbx_tbl;
830 806
807 memset(mbx, 0, sizeof(struct qlcnic_cmd_args));
831 mbx_tbl = qlcnic_83xx_mbx_tbl; 808 mbx_tbl = qlcnic_83xx_mbx_tbl;
832 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl); 809 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
833 for (i = 0; i < size; i++) { 810 for (i = 0; i < size; i++) {
@@ -850,6 +827,7 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
850 memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num); 827 memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num);
851 temp = adapter->ahw->fw_hal_version << 29; 828 temp = adapter->ahw->fw_hal_version << 29;
852 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp); 829 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
830 mbx->cmd_op = type;
853 return 0; 831 return 0;
854 } 832 }
855 } 833 }
@@ -888,9 +866,9 @@ static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
888 866
889void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter) 867void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
890{ 868{
869 struct qlcnic_hardware_context *ahw = adapter->ahw;
891 u32 event[QLC_83XX_MBX_AEN_CNT]; 870 u32 event[QLC_83XX_MBX_AEN_CNT];
892 int i; 871 int i;
893 struct qlcnic_hardware_context *ahw = adapter->ahw;
894 872
895 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++) 873 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
896 event[i] = readl(QLCNIC_MBX_FW(ahw, i)); 874 event[i] = readl(QLCNIC_MBX_FW(ahw, i));
@@ -910,6 +888,7 @@ void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
910 &adapter->idc_aen_work, 0); 888 &adapter->idc_aen_work, 0);
911 break; 889 break;
912 case QLCNIC_MBX_TIME_EXTEND_EVENT: 890 case QLCNIC_MBX_TIME_EXTEND_EVENT:
891 ahw->extend_lb_time = event[1] >> 8 & 0xf;
913 break; 892 break;
914 case QLCNIC_MBX_BC_EVENT: 893 case QLCNIC_MBX_BC_EVENT:
915 qlcnic_sriov_handle_bc_event(adapter, event[1]); 894 qlcnic_sriov_handle_bc_event(adapter, event[1]);
@@ -922,6 +901,9 @@ void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
922 dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n", 901 dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
923 QLCNIC_MBX_RSP(event[0])); 902 QLCNIC_MBX_RSP(event[0]));
924 break; 903 break;
904 case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
905 qlcnic_dcb_handle_aen(adapter, (void *)&event[1]);
906 break;
925 default: 907 default:
926 dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n", 908 dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
927 QLCNIC_MBX_RSP(event[0])); 909 QLCNIC_MBX_RSP(event[0]));
@@ -933,20 +915,23 @@ void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
933 915
934static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter) 916static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
935{ 917{
918 u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
936 struct qlcnic_hardware_context *ahw = adapter->ahw; 919 struct qlcnic_hardware_context *ahw = adapter->ahw;
937 u32 resp, event; 920 struct qlcnic_mailbox *mbx = ahw->mailbox;
938 unsigned long flags; 921 unsigned long flags;
939 922
940 spin_lock_irqsave(&ahw->mbx_lock, flags); 923 spin_lock_irqsave(&mbx->aen_lock, flags);
941
942 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL); 924 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
943 if (resp & QLCNIC_SET_OWNER) { 925 if (resp & QLCNIC_SET_OWNER) {
944 event = readl(QLCNIC_MBX_FW(ahw, 0)); 926 event = readl(QLCNIC_MBX_FW(ahw, 0));
945 if (event & QLCNIC_MBX_ASYNC_EVENT) 927 if (event & QLCNIC_MBX_ASYNC_EVENT) {
946 __qlcnic_83xx_process_aen(adapter); 928 __qlcnic_83xx_process_aen(adapter);
929 } else {
930 if (atomic_read(&mbx->rsp_status) != rsp_status)
931 qlcnic_83xx_notify_mbx_response(mbx);
932 }
947 } 933 }
948 934 spin_unlock_irqrestore(&mbx->aen_lock, flags);
949 spin_unlock_irqrestore(&ahw->mbx_lock, flags);
950} 935}
951 936
952static void qlcnic_83xx_mbx_poll_work(struct work_struct *work) 937static void qlcnic_83xx_mbx_poll_work(struct work_struct *work)
@@ -969,6 +954,7 @@ void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *adapter)
969 return; 954 return;
970 955
971 INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work); 956 INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work);
957 queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work, 0);
972} 958}
973 959
974void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter) 960void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter)
@@ -1355,8 +1341,10 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1355 1341
1356 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 1342 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1357 /* disable and free mailbox interrupt */ 1343 /* disable and free mailbox interrupt */
1358 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) 1344 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
1345 qlcnic_83xx_enable_mbx_poll(adapter);
1359 qlcnic_83xx_free_mbx_intr(adapter); 1346 qlcnic_83xx_free_mbx_intr(adapter);
1347 }
1360 adapter->ahw->loopback_state = 0; 1348 adapter->ahw->loopback_state = 0;
1361 adapter->ahw->hw_ops->setup_link_event(adapter, 1); 1349 adapter->ahw->hw_ops->setup_link_event(adapter, 1);
1362 } 1350 }
@@ -1377,6 +1365,8 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1377 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 1365 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1378 sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1366 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1379 qlcnic_83xx_disable_intr(adapter, sds_ring); 1367 qlcnic_83xx_disable_intr(adapter, sds_ring);
1368 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1369 qlcnic_83xx_enable_mbx_poll(adapter);
1380 } 1370 }
1381 } 1371 }
1382 1372
@@ -1386,6 +1376,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1386 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 1376 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1387 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { 1377 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
1388 err = qlcnic_83xx_setup_mbx_intr(adapter); 1378 err = qlcnic_83xx_setup_mbx_intr(adapter);
1379 qlcnic_83xx_disable_mbx_poll(adapter);
1389 if (err) { 1380 if (err) {
1390 dev_err(&adapter->pdev->dev, 1381 dev_err(&adapter->pdev->dev,
1391 "%s: failed to setup mbx interrupt\n", 1382 "%s: failed to setup mbx interrupt\n",
@@ -1402,6 +1393,10 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1402 1393
1403 if (netif_running(netdev)) 1394 if (netif_running(netdev))
1404 __qlcnic_up(adapter, netdev); 1395 __qlcnic_up(adapter, netdev);
1396
1397 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST &&
1398 !(adapter->flags & QLCNIC_MSIX_ENABLED))
1399 qlcnic_83xx_disable_mbx_poll(adapter);
1405out: 1400out:
1406 netif_device_attach(netdev); 1401 netif_device_attach(netdev);
1407} 1402}
@@ -1619,26 +1614,33 @@ static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1619 1614
1620int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) 1615int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1621{ 1616{
1622 int err; 1617 struct qlcnic_cmd_args *cmd = NULL;
1623 u32 temp = 0; 1618 u32 temp = 0;
1624 struct qlcnic_cmd_args cmd; 1619 int err;
1625 1620
1626 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED) 1621 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1627 return -EIO; 1622 return -EIO;
1628 1623
1629 err = qlcnic_alloc_mbx_args(&cmd, adapter, 1624 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
1625 if (!cmd)
1626 return -ENOMEM;
1627
1628 err = qlcnic_alloc_mbx_args(cmd, adapter,
1630 QLCNIC_CMD_CONFIGURE_MAC_RX_MODE); 1629 QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1631 if (err) 1630 if (err)
1632 return err; 1631 goto out;
1633 1632
1633 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
1634 qlcnic_83xx_set_interface_id_promisc(adapter, &temp); 1634 qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
1635 cmd.req.arg[1] = (mode ? 1 : 0) | temp; 1635 cmd->req.arg[1] = (mode ? 1 : 0) | temp;
1636 err = qlcnic_issue_cmd(adapter, &cmd); 1636 err = qlcnic_issue_cmd(adapter, cmd);
1637 if (err) 1637 if (!err)
1638 dev_info(&adapter->pdev->dev, 1638 return err;
1639 "Promiscous mode config failed\n");
1640 1639
1641 qlcnic_free_mbx_args(&cmd); 1640 qlcnic_free_mbx_args(cmd);
1641
1642out:
1643 kfree(cmd);
1642 return err; 1644 return err;
1643} 1645}
1644 1646
@@ -1651,7 +1653,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1651 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { 1653 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1652 netdev_warn(netdev, 1654 netdev_warn(netdev,
1653 "Loopback test not supported in non privileged mode\n"); 1655 "Loopback test not supported in non privileged mode\n");
1654 return ret; 1656 return -ENOTSUPP;
1655 } 1657 }
1656 1658
1657 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { 1659 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
@@ -1679,19 +1681,17 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1679 /* Poll for link up event before running traffic */ 1681 /* Poll for link up event before running traffic */
1680 do { 1682 do {
1681 msleep(QLC_83XX_LB_MSLEEP_COUNT); 1683 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1682 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1683 qlcnic_83xx_process_aen(adapter);
1684 1684
1685 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { 1685 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1686 netdev_info(netdev, 1686 netdev_info(netdev,
1687 "Device is resetting, free LB test resources\n"); 1687 "Device is resetting, free LB test resources\n");
1688 ret = -EIO; 1688 ret = -EBUSY;
1689 goto free_diag_res; 1689 goto free_diag_res;
1690 } 1690 }
1691 if (loop++ > QLC_83XX_LB_WAIT_COUNT) { 1691 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1692 netdev_info(netdev, 1692 netdev_info(netdev,
1693 "Firmware didn't sent link up event to loopback request\n"); 1693 "Firmware didn't sent link up event to loopback request\n");
1694 ret = -QLCNIC_FW_NOT_RESPOND; 1694 ret = -ETIMEDOUT;
1695 qlcnic_83xx_clear_lb_mode(adapter, mode); 1695 qlcnic_83xx_clear_lb_mode(adapter, mode);
1696 goto free_diag_res; 1696 goto free_diag_res;
1697 } 1697 }
@@ -1700,7 +1700,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1700 /* Make sure carrier is off and queue is stopped during loopback */ 1700 /* Make sure carrier is off and queue is stopped during loopback */
1701 if (netif_running(netdev)) { 1701 if (netif_running(netdev)) {
1702 netif_carrier_off(netdev); 1702 netif_carrier_off(netdev);
1703 netif_stop_queue(netdev); 1703 netif_tx_stop_all_queues(netdev);
1704 } 1704 }
1705 1705
1706 ret = qlcnic_do_lb_test(adapter, mode); 1706 ret = qlcnic_do_lb_test(adapter, mode);
@@ -1716,18 +1716,42 @@ fail_diag_alloc:
1716 return ret; 1716 return ret;
1717} 1717}
1718 1718
1719static void qlcnic_extend_lb_idc_cmpltn_wait(struct qlcnic_adapter *adapter,
1720 u32 *max_wait_count)
1721{
1722 struct qlcnic_hardware_context *ahw = adapter->ahw;
1723 int temp;
1724
1725 netdev_info(adapter->netdev, "Recieved loopback IDC time extend event for 0x%x seconds\n",
1726 ahw->extend_lb_time);
1727 temp = ahw->extend_lb_time * 1000;
1728 *max_wait_count += temp / QLC_83XX_LB_MSLEEP_COUNT;
1729 ahw->extend_lb_time = 0;
1730}
1731
1719int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) 1732int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1720{ 1733{
1721 struct qlcnic_hardware_context *ahw = adapter->ahw; 1734 struct qlcnic_hardware_context *ahw = adapter->ahw;
1722 struct net_device *netdev = adapter->netdev; 1735 struct net_device *netdev = adapter->netdev;
1736 u32 config, max_wait_count;
1723 int status = 0, loop = 0; 1737 int status = 0, loop = 0;
1724 u32 config;
1725 1738
1739 ahw->extend_lb_time = 0;
1740 max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1726 status = qlcnic_83xx_get_port_config(adapter); 1741 status = qlcnic_83xx_get_port_config(adapter);
1727 if (status) 1742 if (status)
1728 return status; 1743 return status;
1729 1744
1730 config = ahw->port_config; 1745 config = ahw->port_config;
1746
1747 /* Check if port is already in loopback mode */
1748 if ((config & QLC_83XX_CFG_LOOPBACK_HSS) ||
1749 (config & QLC_83XX_CFG_LOOPBACK_EXT)) {
1750 netdev_err(netdev,
1751 "Port already in Loopback mode.\n");
1752 return -EINPROGRESS;
1753 }
1754
1731 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1755 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1732 1756
1733 if (mode == QLCNIC_ILB_MODE) 1757 if (mode == QLCNIC_ILB_MODE)
@@ -1748,21 +1772,24 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1748 /* Wait for Link and IDC Completion AEN */ 1772 /* Wait for Link and IDC Completion AEN */
1749 do { 1773 do {
1750 msleep(QLC_83XX_LB_MSLEEP_COUNT); 1774 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1751 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1752 qlcnic_83xx_process_aen(adapter);
1753 1775
1754 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { 1776 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1755 netdev_info(netdev, 1777 netdev_info(netdev,
1756 "Device is resetting, free LB test resources\n"); 1778 "Device is resetting, free LB test resources\n");
1757 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1779 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1758 return -EIO; 1780 return -EBUSY;
1759 } 1781 }
1760 if (loop++ > QLC_83XX_LB_WAIT_COUNT) { 1782
1761 netdev_err(netdev, 1783 if (ahw->extend_lb_time)
1762 "Did not receive IDC completion AEN\n"); 1784 qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1785 &max_wait_count);
1786
1787 if (loop++ > max_wait_count) {
1788 netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1789 __func__);
1763 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1790 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1764 qlcnic_83xx_clear_lb_mode(adapter, mode); 1791 qlcnic_83xx_clear_lb_mode(adapter, mode);
1765 return -EIO; 1792 return -ETIMEDOUT;
1766 } 1793 }
1767 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status)); 1794 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1768 1795
@@ -1774,10 +1801,12 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1774int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode) 1801int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1775{ 1802{
1776 struct qlcnic_hardware_context *ahw = adapter->ahw; 1803 struct qlcnic_hardware_context *ahw = adapter->ahw;
1804 u32 config = ahw->port_config, max_wait_count;
1777 struct net_device *netdev = adapter->netdev; 1805 struct net_device *netdev = adapter->netdev;
1778 int status = 0, loop = 0; 1806 int status = 0, loop = 0;
1779 u32 config = ahw->port_config;
1780 1807
1808 ahw->extend_lb_time = 0;
1809 max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1781 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1810 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1782 if (mode == QLCNIC_ILB_MODE) 1811 if (mode == QLCNIC_ILB_MODE)
1783 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS; 1812 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
@@ -1797,21 +1826,23 @@ int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1797 /* Wait for Link and IDC Completion AEN */ 1826 /* Wait for Link and IDC Completion AEN */
1798 do { 1827 do {
1799 msleep(QLC_83XX_LB_MSLEEP_COUNT); 1828 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1800 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1801 qlcnic_83xx_process_aen(adapter);
1802 1829
1803 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { 1830 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1804 netdev_info(netdev, 1831 netdev_info(netdev,
1805 "Device is resetting, free LB test resources\n"); 1832 "Device is resetting, free LB test resources\n");
1806 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1833 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1807 return -EIO; 1834 return -EBUSY;
1808 } 1835 }
1809 1836
1810 if (loop++ > QLC_83XX_LB_WAIT_COUNT) { 1837 if (ahw->extend_lb_time)
1811 netdev_err(netdev, 1838 qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1812 "Did not receive IDC completion AEN\n"); 1839 &max_wait_count);
1840
1841 if (loop++ > max_wait_count) {
1842 netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1843 __func__);
1813 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1844 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1814 return -EIO; 1845 return -ETIMEDOUT;
1815 } 1846 }
1816 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status)); 1847 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1817 1848
@@ -1950,25 +1981,31 @@ static void qlcnic_83xx_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
1950int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, 1981int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1951 u16 vlan_id, u8 op) 1982 u16 vlan_id, u8 op)
1952{ 1983{
1953 int err; 1984 struct qlcnic_cmd_args *cmd = NULL;
1954 u32 *buf, temp = 0;
1955 struct qlcnic_cmd_args cmd;
1956 struct qlcnic_macvlan_mbx mv; 1985 struct qlcnic_macvlan_mbx mv;
1986 u32 *buf, temp = 0;
1987 int err;
1957 1988
1958 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED) 1989 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1959 return -EIO; 1990 return -EIO;
1960 1991
1961 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN); 1992 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
1993 if (!cmd)
1994 return -ENOMEM;
1995
1996 err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
1962 if (err) 1997 if (err)
1963 return err; 1998 goto out;
1999
2000 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
1964 2001
1965 if (vlan_id) 2002 if (vlan_id)
1966 op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ? 2003 op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
1967 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL; 2004 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
1968 2005
1969 cmd.req.arg[1] = op | (1 << 8); 2006 cmd->req.arg[1] = op | (1 << 8);
1970 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp); 2007 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp);
1971 cmd.req.arg[1] |= temp; 2008 cmd->req.arg[1] |= temp;
1972 mv.vlan = vlan_id; 2009 mv.vlan = vlan_id;
1973 mv.mac_addr0 = addr[0]; 2010 mv.mac_addr0 = addr[0];
1974 mv.mac_addr1 = addr[1]; 2011 mv.mac_addr1 = addr[1];
@@ -1976,14 +2013,15 @@ int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1976 mv.mac_addr3 = addr[3]; 2013 mv.mac_addr3 = addr[3];
1977 mv.mac_addr4 = addr[4]; 2014 mv.mac_addr4 = addr[4];
1978 mv.mac_addr5 = addr[5]; 2015 mv.mac_addr5 = addr[5];
1979 buf = &cmd.req.arg[2]; 2016 buf = &cmd->req.arg[2];
1980 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx)); 2017 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
1981 err = qlcnic_issue_cmd(adapter, &cmd); 2018 err = qlcnic_issue_cmd(adapter, cmd);
1982 if (err) 2019 if (!err)
1983 dev_err(&adapter->pdev->dev, 2020 return err;
1984 "MAC-VLAN %s to CAM failed, err=%d.\n", 2021
1985 ((op == 1) ? "add " : "delete "), err); 2022 qlcnic_free_mbx_args(cmd);
1986 qlcnic_free_mbx_args(&cmd); 2023out:
2024 kfree(cmd);
1987 return err; 2025 return err;
1988} 2026}
1989 2027
@@ -2008,12 +2046,14 @@ void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
2008 cmd->req.arg[1] = type; 2046 cmd->req.arg[1] = type;
2009} 2047}
2010 2048
2011int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) 2049int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
2050 u8 function)
2012{ 2051{
2013 int err, i; 2052 int err, i;
2014 struct qlcnic_cmd_args cmd; 2053 struct qlcnic_cmd_args cmd;
2015 u32 mac_low, mac_high; 2054 u32 mac_low, mac_high;
2016 2055
2056 function = 0;
2017 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS); 2057 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
2018 if (err) 2058 if (err)
2019 return err; 2059 return err;
@@ -2099,10 +2139,12 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
2099irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data) 2139irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2100{ 2140{
2101 struct qlcnic_adapter *adapter = data; 2141 struct qlcnic_adapter *adapter = data;
2102 unsigned long flags; 2142 struct qlcnic_mailbox *mbx;
2103 u32 mask, resp, event; 2143 u32 mask, resp, event;
2144 unsigned long flags;
2104 2145
2105 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags); 2146 mbx = adapter->ahw->mailbox;
2147 spin_lock_irqsave(&mbx->aen_lock, flags);
2106 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL); 2148 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
2107 if (!(resp & QLCNIC_SET_OWNER)) 2149 if (!(resp & QLCNIC_SET_OWNER))
2108 goto out; 2150 goto out;
@@ -2110,11 +2152,13 @@ irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2110 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0)); 2152 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
2111 if (event & QLCNIC_MBX_ASYNC_EVENT) 2153 if (event & QLCNIC_MBX_ASYNC_EVENT)
2112 __qlcnic_83xx_process_aen(adapter); 2154 __qlcnic_83xx_process_aen(adapter);
2155 else
2156 qlcnic_83xx_notify_mbx_response(mbx);
2157
2113out: 2158out:
2114 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK); 2159 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
2115 writel(0, adapter->ahw->pci_base0 + mask); 2160 writel(0, adapter->ahw->pci_base0 + mask);
2116 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags); 2161 spin_unlock_irqrestore(&mbx->aen_lock, flags);
2117
2118 return IRQ_HANDLED; 2162 return IRQ_HANDLED;
2119} 2163}
2120 2164
@@ -2287,7 +2331,7 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
2287 pci_info->tx_max_bw, pci_info->mac); 2331 pci_info->tx_max_bw, pci_info->mac);
2288 } 2332 }
2289 if (ahw->op_mode == QLCNIC_MGMT_FUNC) 2333 if (ahw->op_mode == QLCNIC_MGMT_FUNC)
2290 dev_info(dev, "Max vNIC functions = %d, active vNIC functions = %d\n", 2334 dev_info(dev, "Max functions = %d, active functions = %d\n",
2291 ahw->max_pci_func, ahw->act_pci_func); 2335 ahw->max_pci_func, ahw->act_pci_func);
2292 2336
2293 } else { 2337 } else {
@@ -3477,3 +3521,360 @@ int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
3477 idc->delay); 3521 idc->delay);
3478 return err; 3522 return err;
3479} 3523}
3524
3525void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx)
3526{
3527 INIT_COMPLETION(mbx->completion);
3528 set_bit(QLC_83XX_MBX_READY, &mbx->status);
3529}
3530
3531void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx)
3532{
3533 destroy_workqueue(mbx->work_q);
3534 kfree(mbx);
3535}
3536
3537static inline void
3538qlcnic_83xx_notify_cmd_completion(struct qlcnic_adapter *adapter,
3539 struct qlcnic_cmd_args *cmd)
3540{
3541 atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
3542
3543 if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {
3544 qlcnic_free_mbx_args(cmd);
3545 kfree(cmd);
3546 return;
3547 }
3548 complete(&cmd->completion);
3549}
3550
3551static void qlcnic_83xx_flush_mbx_queue(struct qlcnic_adapter *adapter)
3552{
3553 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3554 struct list_head *head = &mbx->cmd_q;
3555 struct qlcnic_cmd_args *cmd = NULL;
3556
3557 spin_lock(&mbx->queue_lock);
3558
3559 while (!list_empty(head)) {
3560 cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
3561 dev_info(&adapter->pdev->dev, "%s: Mailbox command 0x%x\n",
3562 __func__, cmd->cmd_op);
3563 list_del(&cmd->list);
3564 mbx->num_cmds--;
3565 qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3566 }
3567
3568 spin_unlock(&mbx->queue_lock);
3569}
3570
3571static int qlcnic_83xx_check_mbx_status(struct qlcnic_adapter *adapter)
3572{
3573 struct qlcnic_hardware_context *ahw = adapter->ahw;
3574 struct qlcnic_mailbox *mbx = ahw->mailbox;
3575 u32 host_mbx_ctrl;
3576
3577 if (!test_bit(QLC_83XX_MBX_READY, &mbx->status))
3578 return -EBUSY;
3579
3580 host_mbx_ctrl = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
3581 if (host_mbx_ctrl) {
3582 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3583 ahw->idc.collect_dump = 1;
3584 return -EIO;
3585 }
3586
3587 return 0;
3588}
3589
3590static inline void qlcnic_83xx_signal_mbx_cmd(struct qlcnic_adapter *adapter,
3591 u8 issue_cmd)
3592{
3593 if (issue_cmd)
3594 QLCWRX(adapter->ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
3595 else
3596 QLCWRX(adapter->ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
3597}
3598
3599static void qlcnic_83xx_dequeue_mbx_cmd(struct qlcnic_adapter *adapter,
3600 struct qlcnic_cmd_args *cmd)
3601{
3602 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3603
3604 spin_lock(&mbx->queue_lock);
3605
3606 list_del(&cmd->list);
3607 mbx->num_cmds--;
3608
3609 spin_unlock(&mbx->queue_lock);
3610
3611 qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3612}
3613
3614static void qlcnic_83xx_encode_mbx_cmd(struct qlcnic_adapter *adapter,
3615 struct qlcnic_cmd_args *cmd)
3616{
3617 u32 mbx_cmd, fw_hal_version, hdr_size, total_size, tmp;
3618 struct qlcnic_hardware_context *ahw = adapter->ahw;
3619 int i, j;
3620
3621 if (cmd->op_type != QLC_83XX_MBX_POST_BC_OP) {
3622 mbx_cmd = cmd->req.arg[0];
3623 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3624 for (i = 1; i < cmd->req.num; i++)
3625 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
3626 } else {
3627 fw_hal_version = ahw->fw_hal_version;
3628 hdr_size = sizeof(struct qlcnic_bc_hdr) / sizeof(u32);
3629 total_size = cmd->pay_size + hdr_size;
3630 tmp = QLCNIC_CMD_BC_EVENT_SETUP | total_size << 16;
3631 mbx_cmd = tmp | fw_hal_version << 29;
3632 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3633
3634 /* Back channel specific operations bits */
3635 mbx_cmd = 0x1 | 1 << 4;
3636
3637 if (qlcnic_sriov_pf_check(adapter))
3638 mbx_cmd |= cmd->func_num << 5;
3639
3640 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 1));
3641
3642 for (i = 2, j = 0; j < hdr_size; i++, j++)
3643 writel(*(cmd->hdr++), QLCNIC_MBX_HOST(ahw, i));
3644 for (j = 0; j < cmd->pay_size; j++, i++)
3645 writel(*(cmd->pay++), QLCNIC_MBX_HOST(ahw, i));
3646 }
3647}
3648
3649void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *adapter)
3650{
3651 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3652
3653 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3654 complete(&mbx->completion);
3655 cancel_work_sync(&mbx->work);
3656 flush_workqueue(mbx->work_q);
3657 qlcnic_83xx_flush_mbx_queue(adapter);
3658}
3659
3660static int qlcnic_83xx_enqueue_mbx_cmd(struct qlcnic_adapter *adapter,
3661 struct qlcnic_cmd_args *cmd,
3662 unsigned long *timeout)
3663{
3664 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3665
3666 if (test_bit(QLC_83XX_MBX_READY, &mbx->status)) {
3667 atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
3668 init_completion(&cmd->completion);
3669 cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_UNKNOWN;
3670
3671 spin_lock(&mbx->queue_lock);
3672
3673 list_add_tail(&cmd->list, &mbx->cmd_q);
3674 mbx->num_cmds++;
3675 cmd->total_cmds = mbx->num_cmds;
3676 *timeout = cmd->total_cmds * QLC_83XX_MBX_TIMEOUT;
3677 queue_work(mbx->work_q, &mbx->work);
3678
3679 spin_unlock(&mbx->queue_lock);
3680
3681 return 0;
3682 }
3683
3684 return -EBUSY;
3685}
3686
3687static int qlcnic_83xx_check_mac_rcode(struct qlcnic_adapter *adapter,
3688 struct qlcnic_cmd_args *cmd)
3689{
3690 u8 mac_cmd_rcode;
3691 u32 fw_data;
3692
3693 if (cmd->cmd_op == QLCNIC_CMD_CONFIG_MAC_VLAN) {
3694 fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2));
3695 mac_cmd_rcode = (u8)fw_data;
3696 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
3697 mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
3698 mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
3699 cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
3700 return QLCNIC_RCODE_SUCCESS;
3701 }
3702 }
3703
3704 return -EINVAL;
3705}
3706
3707static void qlcnic_83xx_decode_mbx_rsp(struct qlcnic_adapter *adapter,
3708 struct qlcnic_cmd_args *cmd)
3709{
3710 struct qlcnic_hardware_context *ahw = adapter->ahw;
3711 struct device *dev = &adapter->pdev->dev;
3712 u8 mbx_err_code;
3713 u32 fw_data;
3714
3715 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
3716 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
3717 qlcnic_83xx_get_mbx_data(adapter, cmd);
3718
3719 switch (mbx_err_code) {
3720 case QLCNIC_MBX_RSP_OK:
3721 case QLCNIC_MBX_PORT_RSP_OK:
3722 cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
3723 break;
3724 default:
3725 if (!qlcnic_83xx_check_mac_rcode(adapter, cmd))
3726 break;
3727
3728 dev_err(dev, "%s: Mailbox command failed, opcode=0x%x, cmd_type=0x%x, func=0x%x, op_mode=0x%x, error=0x%x\n",
3729 __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
3730 ahw->op_mode, mbx_err_code);
3731 cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_FAILED;
3732 qlcnic_dump_mbx(adapter, cmd);
3733 }
3734
3735 return;
3736}
3737
3738static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
3739{
3740 struct qlcnic_mailbox *mbx = container_of(work, struct qlcnic_mailbox,
3741 work);
3742 struct qlcnic_adapter *adapter = mbx->adapter;
3743 struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
3744 struct device *dev = &adapter->pdev->dev;
3745 atomic_t *rsp_status = &mbx->rsp_status;
3746 struct list_head *head = &mbx->cmd_q;
3747 struct qlcnic_hardware_context *ahw;
3748 struct qlcnic_cmd_args *cmd = NULL;
3749
3750 ahw = adapter->ahw;
3751
3752 while (true) {
3753 if (qlcnic_83xx_check_mbx_status(adapter)) {
3754 qlcnic_83xx_flush_mbx_queue(adapter);
3755 return;
3756 }
3757
3758 atomic_set(rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
3759
3760 spin_lock(&mbx->queue_lock);
3761
3762 if (list_empty(head)) {
3763 spin_unlock(&mbx->queue_lock);
3764 return;
3765 }
3766 cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
3767
3768 spin_unlock(&mbx->queue_lock);
3769
3770 mbx_ops->encode_cmd(adapter, cmd);
3771 mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_REQUEST);
3772
3773 if (wait_for_completion_timeout(&mbx->completion,
3774 QLC_83XX_MBX_TIMEOUT)) {
3775 mbx_ops->decode_resp(adapter, cmd);
3776 mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_COMPLETION);
3777 } else {
3778 dev_err(dev, "%s: Mailbox command timeout, opcode=0x%x, cmd_type=0x%x, func=0x%x, op_mode=0x%x\n",
3779 __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
3780 ahw->op_mode);
3781 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3782 qlcnic_dump_mbx(adapter, cmd);
3783 qlcnic_83xx_idc_request_reset(adapter,
3784 QLCNIC_FORCE_FW_DUMP_KEY);
3785 cmd->rsp_opcode = QLCNIC_RCODE_TIMEOUT;
3786 }
3787 mbx_ops->dequeue_cmd(adapter, cmd);
3788 }
3789}
3790
3791static struct qlcnic_mbx_ops qlcnic_83xx_mbx_ops = {
3792 .enqueue_cmd = qlcnic_83xx_enqueue_mbx_cmd,
3793 .dequeue_cmd = qlcnic_83xx_dequeue_mbx_cmd,
3794 .decode_resp = qlcnic_83xx_decode_mbx_rsp,
3795 .encode_cmd = qlcnic_83xx_encode_mbx_cmd,
3796 .nofity_fw = qlcnic_83xx_signal_mbx_cmd,
3797};
3798
3799int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *adapter)
3800{
3801 struct qlcnic_hardware_context *ahw = adapter->ahw;
3802 struct qlcnic_mailbox *mbx;
3803
3804 ahw->mailbox = kzalloc(sizeof(*mbx), GFP_KERNEL);
3805 if (!ahw->mailbox)
3806 return -ENOMEM;
3807
3808 mbx = ahw->mailbox;
3809 mbx->ops = &qlcnic_83xx_mbx_ops;
3810 mbx->adapter = adapter;
3811
3812 spin_lock_init(&mbx->queue_lock);
3813 spin_lock_init(&mbx->aen_lock);
3814 INIT_LIST_HEAD(&mbx->cmd_q);
3815 init_completion(&mbx->completion);
3816
3817 mbx->work_q = create_singlethread_workqueue("qlcnic_mailbox");
3818 if (mbx->work_q == NULL) {
3819 kfree(mbx);
3820 return -ENOMEM;
3821 }
3822
3823 INIT_WORK(&mbx->work, qlcnic_83xx_mailbox_worker);
3824 set_bit(QLC_83XX_MBX_READY, &mbx->status);
3825 return 0;
3826}
3827
3828pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *pdev,
3829 pci_channel_state_t state)
3830{
3831 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3832
3833 if (state == pci_channel_io_perm_failure)
3834 return PCI_ERS_RESULT_DISCONNECT;
3835
3836 if (state == pci_channel_io_normal)
3837 return PCI_ERS_RESULT_RECOVERED;
3838
3839 set_bit(__QLCNIC_AER, &adapter->state);
3840 set_bit(__QLCNIC_RESETTING, &adapter->state);
3841
3842 qlcnic_83xx_aer_stop_poll_work(adapter);
3843
3844 pci_save_state(pdev);
3845 pci_disable_device(pdev);
3846
3847 return PCI_ERS_RESULT_NEED_RESET;
3848}
3849
3850pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *pdev)
3851{
3852 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3853 int err = 0;
3854
3855 pdev->error_state = pci_channel_io_normal;
3856 err = pci_enable_device(pdev);
3857 if (err)
3858 goto disconnect;
3859
3860 pci_set_power_state(pdev, PCI_D0);
3861 pci_set_master(pdev);
3862 pci_restore_state(pdev);
3863
3864 err = qlcnic_83xx_aer_reset(adapter);
3865 if (err == 0)
3866 return PCI_ERS_RESULT_RECOVERED;
3867disconnect:
3868 clear_bit(__QLCNIC_AER, &adapter->state);
3869 clear_bit(__QLCNIC_RESETTING, &adapter->state);
3870 return PCI_ERS_RESULT_DISCONNECT;
3871}
3872
3873void qlcnic_83xx_io_resume(struct pci_dev *pdev)
3874{
3875 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3876
3877 pci_cleanup_aer_uncorrect_error_status(pdev);
3878 if (test_and_clear_bit(__QLCNIC_AER, &adapter->state))
3879 qlcnic_83xx_aer_start_poll_work(adapter);
3880}