aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h59
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c615
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h27
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c83
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c6
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c6
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c18
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c146
8 files changed, 651 insertions, 309 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index b00cf5665eab..eae41bcc0145 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -20,7 +20,6 @@
20#include <linux/tcp.h> 20#include <linux/tcp.h>
21#include <linux/skbuff.h> 21#include <linux/skbuff.h>
22#include <linux/firmware.h> 22#include <linux/firmware.h>
23
24#include <linux/ethtool.h> 23#include <linux/ethtool.h>
25#include <linux/mii.h> 24#include <linux/mii.h>
26#include <linux/timer.h> 25#include <linux/timer.h>
@@ -38,8 +37,8 @@
38 37
39#define _QLCNIC_LINUX_MAJOR 5 38#define _QLCNIC_LINUX_MAJOR 5
40#define _QLCNIC_LINUX_MINOR 2 39#define _QLCNIC_LINUX_MINOR 2
41#define _QLCNIC_LINUX_SUBVERSION 44 40#define _QLCNIC_LINUX_SUBVERSION 45
42#define QLCNIC_LINUX_VERSIONID "5.2.44" 41#define QLCNIC_LINUX_VERSIONID "5.2.45"
43#define QLCNIC_DRV_IDC_VER 0x01 42#define QLCNIC_DRV_IDC_VER 0x01
44#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ 43#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
45 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) 44 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -467,7 +466,7 @@ struct qlcnic_hardware_context {
467 u32 *ext_reg_tbl; 466 u32 *ext_reg_tbl;
468 u32 mbox_aen[QLC_83XX_MBX_AEN_CNT]; 467 u32 mbox_aen[QLC_83XX_MBX_AEN_CNT];
469 u32 mbox_reg[4]; 468 u32 mbox_reg[4];
470 spinlock_t mbx_lock; 469 struct qlcnic_mailbox *mailbox;
471}; 470};
472 471
473struct qlcnic_adapter_stats { 472struct qlcnic_adapter_stats {
@@ -950,12 +949,6 @@ struct qlcnic_ipaddr {
950#define QLCNIC_READD_AGE 20 949#define QLCNIC_READD_AGE 20
951#define QLCNIC_LB_MAX_FILTERS 64 950#define QLCNIC_LB_MAX_FILTERS 64
952#define QLCNIC_LB_BUCKET_SIZE 32 951#define QLCNIC_LB_BUCKET_SIZE 32
953
954/* QLCNIC Driver Error Code */
955#define QLCNIC_FW_NOT_RESPOND 51
956#define QLCNIC_TEST_IN_PROGRESS 52
957#define QLCNIC_UNDEFINED_ERROR 53
958#define QLCNIC_LB_CABLE_NOT_CONN 54
959#define QLCNIC_ILB_MAX_RCV_LOOP 10 952#define QLCNIC_ILB_MAX_RCV_LOOP 10
960 953
961struct qlcnic_filter { 954struct qlcnic_filter {
@@ -972,6 +965,21 @@ struct qlcnic_filter_hash {
972 u16 fbucket_size; 965 u16 fbucket_size;
973}; 966};
974 967
968/* Mailbox specific data structures */
969struct qlcnic_mailbox {
970 struct workqueue_struct *work_q;
971 struct qlcnic_adapter *adapter;
972 struct qlcnic_mbx_ops *ops;
973 struct work_struct work;
974 struct completion completion;
975 struct list_head cmd_q;
976 unsigned long status;
977 spinlock_t queue_lock; /* Mailbox queue lock */
978 spinlock_t aen_lock; /* Mailbox response/AEN lock */
979 atomic_t rsp_status;
980 u32 num_cmds;
981};
982
975struct qlcnic_adapter { 983struct qlcnic_adapter {
976 struct qlcnic_hardware_context *ahw; 984 struct qlcnic_hardware_context *ahw;
977 struct qlcnic_recv_context *recv_ctx; 985 struct qlcnic_recv_context *recv_ctx;
@@ -1385,9 +1393,20 @@ struct _cdrp_cmd {
1385}; 1393};
1386 1394
1387struct qlcnic_cmd_args { 1395struct qlcnic_cmd_args {
1388 struct _cdrp_cmd req; 1396 struct completion completion;
1389 struct _cdrp_cmd rsp; 1397 struct list_head list;
1390 int op_type; 1398 struct _cdrp_cmd req;
1399 struct _cdrp_cmd rsp;
1400 atomic_t rsp_status;
1401 int pay_size;
1402 u32 rsp_opcode;
1403 u32 total_cmds;
1404 u32 op_type;
1405 u32 type;
1406 u32 cmd_op;
1407 u32 *hdr; /* Back channel message header */
1408 u32 *pay; /* Back channel message payload */
1409 u8 func_num;
1391}; 1410};
1392 1411
1393int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter); 1412int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter);
@@ -1600,6 +1619,20 @@ struct qlcnic_nic_template {
1600 int (*resume)(struct qlcnic_adapter *); 1619 int (*resume)(struct qlcnic_adapter *);
1601}; 1620};
1602 1621
1622struct qlcnic_mbx_ops {
1623 int (*enqueue_cmd) (struct qlcnic_adapter *,
1624 struct qlcnic_cmd_args *, unsigned long *);
1625 void (*dequeue_cmd) (struct qlcnic_adapter *, struct qlcnic_cmd_args *);
1626 void (*decode_resp) (struct qlcnic_adapter *, struct qlcnic_cmd_args *);
1627 void (*encode_cmd) (struct qlcnic_adapter *, struct qlcnic_cmd_args *);
1628 void (*nofity_fw) (struct qlcnic_adapter *, u8);
1629};
1630
1631int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *);
1632void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *);
1633void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx);
1634void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx);
1635
1603/* Adapter hardware abstraction */ 1636/* Adapter hardware abstraction */
1604struct qlcnic_hardware_ops { 1637struct qlcnic_hardware_ops {
1605 void (*read_crb) (struct qlcnic_adapter *, char *, loff_t, size_t); 1638 void (*read_crb) (struct qlcnic_adapter *, char *, loff_t, size_t);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 0913c623a67e..948ab72a2bc7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -149,7 +149,7 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
149 .get_mac_address = qlcnic_83xx_get_mac_address, 149 .get_mac_address = qlcnic_83xx_get_mac_address,
150 .setup_intr = qlcnic_83xx_setup_intr, 150 .setup_intr = qlcnic_83xx_setup_intr,
151 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args, 151 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
152 .mbx_cmd = qlcnic_83xx_mbx_op, 152 .mbx_cmd = qlcnic_83xx_issue_cmd,
153 .get_func_no = qlcnic_83xx_get_func_no, 153 .get_func_no = qlcnic_83xx_get_func_no,
154 .api_lock = qlcnic_83xx_cam_lock, 154 .api_lock = qlcnic_83xx_cam_lock,
155 .api_unlock = qlcnic_83xx_cam_unlock, 155 .api_unlock = qlcnic_83xx_cam_unlock,
@@ -362,6 +362,10 @@ static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
362 struct qlcnic_cmd_args *cmd) 362 struct qlcnic_cmd_args *cmd)
363{ 363{
364 int i; 364 int i;
365
366 if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
367 return;
368
365 for (i = 0; i < cmd->rsp.num; i++) 369 for (i = 0; i < cmd->rsp.num; i++)
366 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i)); 370 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
367} 371}
@@ -398,24 +402,33 @@ irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
398 return IRQ_HANDLED; 402 return IRQ_HANDLED;
399} 403}
400 404
405static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
406{
407 atomic_set(&mbx->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
408 complete(&mbx->completion);
409}
410
401static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter) 411static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
402{ 412{
403 u32 resp, event; 413 u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
414 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
404 unsigned long flags; 415 unsigned long flags;
405 416
406 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags); 417 spin_lock_irqsave(&mbx->aen_lock, flags);
407
408 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL); 418 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
409 if (!(resp & QLCNIC_SET_OWNER)) 419 if (!(resp & QLCNIC_SET_OWNER))
410 goto out; 420 goto out;
411 421
412 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0)); 422 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
413 if (event & QLCNIC_MBX_ASYNC_EVENT) 423 if (event & QLCNIC_MBX_ASYNC_EVENT) {
414 __qlcnic_83xx_process_aen(adapter); 424 __qlcnic_83xx_process_aen(adapter);
415 425 } else {
426 if (atomic_read(&mbx->rsp_status) != rsp_status)
427 qlcnic_83xx_notify_mbx_response(mbx);
428 }
416out: 429out:
417 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter); 430 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
418 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags); 431 spin_unlock_irqrestore(&mbx->aen_lock, flags);
419} 432}
420 433
421irqreturn_t qlcnic_83xx_intr(int irq, void *data) 434irqreturn_t qlcnic_83xx_intr(int irq, void *data)
@@ -515,7 +528,7 @@ int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
515 } 528 }
516 529
517 /* Enable mailbox interrupt */ 530 /* Enable mailbox interrupt */
518 qlcnic_83xx_enable_mbx_intrpt(adapter); 531 qlcnic_83xx_enable_mbx_interrupt(adapter);
519 532
520 return err; 533 return err;
521} 534}
@@ -629,7 +642,7 @@ void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
629 ahw->max_uc_count = count; 642 ahw->max_uc_count = count;
630} 643}
631 644
632void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter) 645void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *adapter)
633{ 646{
634 u32 val; 647 u32 val;
635 648
@@ -688,6 +701,9 @@ static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
688{ 701{
689 int i; 702 int i;
690 703
704 if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
705 return;
706
691 dev_info(&adapter->pdev->dev, 707 dev_info(&adapter->pdev->dev,
692 "Host MBX regs(%d)\n", cmd->req.num); 708 "Host MBX regs(%d)\n", cmd->req.num);
693 for (i = 0; i < cmd->req.num; i++) { 709 for (i = 0; i < cmd->req.num; i++) {
@@ -706,120 +722,74 @@ static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
706 pr_info("\n"); 722 pr_info("\n");
707} 723}
708 724
709/* Mailbox response for mac rcode */ 725static inline void
710u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter) 726qlcnic_83xx_poll_for_mbx_completion(struct qlcnic_adapter *adapter,
727 struct qlcnic_cmd_args *cmd)
711{ 728{
712 u32 fw_data; 729 struct qlcnic_hardware_context *ahw = adapter->ahw;
713 u8 mac_cmd_rcode; 730 int opcode = LSW(cmd->req.arg[0]);
731 unsigned long max_loops;
714 732
715 fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2)); 733 max_loops = cmd->total_cmds * QLC_83XX_MBX_CMD_LOOP;
716 mac_cmd_rcode = (u8)fw_data;
717 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
718 mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
719 mac_cmd_rcode == QLC_83XX_MAC_ABSENT)
720 return QLCNIC_RCODE_SUCCESS;
721 return 1;
722}
723 734
724u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter, u32 *wait_time) 735 for (; max_loops; max_loops--) {
725{ 736 if (atomic_read(&cmd->rsp_status) ==
726 u32 data; 737 QLC_83XX_MBX_RESPONSE_ARRIVED)
727 struct qlcnic_hardware_context *ahw = adapter->ahw; 738 return;
728 /* wait for mailbox completion */ 739
729 do { 740 udelay(1);
730 data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL); 741 }
731 if (++(*wait_time) > QLCNIC_MBX_TIMEOUT) { 742
732 data = QLCNIC_RCODE_TIMEOUT; 743 dev_err(&adapter->pdev->dev,
733 break; 744 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
734 } 745 __func__, opcode, cmd->type, ahw->pci_func, ahw->op_mode);
735 mdelay(1); 746 flush_workqueue(ahw->mailbox->work_q);
736 } while (!data); 747 return;
737 return data;
738} 748}
739 749
740int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, 750int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter,
741 struct qlcnic_cmd_args *cmd) 751 struct qlcnic_cmd_args *cmd)
742{ 752{
743 int i; 753 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
744 u16 opcode;
745 u8 mbx_err_code;
746 unsigned long flags;
747 struct qlcnic_hardware_context *ahw = adapter->ahw; 754 struct qlcnic_hardware_context *ahw = adapter->ahw;
748 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, wait_time = 0; 755 int cmd_type, err, opcode;
756 unsigned long timeout;
749 757
750 opcode = LSW(cmd->req.arg[0]); 758 opcode = LSW(cmd->req.arg[0]);
751 if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) { 759 cmd_type = cmd->type;
752 dev_info(&adapter->pdev->dev, 760 err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
753 "Mailbox cmd attempted, 0x%x\n", opcode); 761 if (err) {
754 dev_info(&adapter->pdev->dev, "Mailbox detached\n"); 762 dev_err(&adapter->pdev->dev,
755 return 0; 763 "%s: Mailbox not available, cmd_op=0x%x, cmd_context=0x%x, pci_func=0x%x, op_mode=0x%x\n",
764 __func__, opcode, cmd->type, ahw->pci_func,
765 ahw->op_mode);
766 return err;
756 } 767 }
757 768
758 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags); 769 switch (cmd_type) {
759 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); 770 case QLC_83XX_MBX_CMD_WAIT:
760 771 if (!wait_for_completion_timeout(&cmd->completion, timeout)) {
761 if (mbx_val) {
762 QLCDB(adapter, DRV,
763 "Mailbox cmd attempted, 0x%x\n", opcode);
764 QLCDB(adapter, DRV,
765 "Mailbox not available, 0x%x, collect FW dump\n",
766 mbx_val);
767 cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
768 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
769 return cmd->rsp.arg[0];
770 }
771
772 /* Fill in mailbox registers */
773 mbx_cmd = cmd->req.arg[0];
774 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
775 for (i = 1; i < cmd->req.num; i++)
776 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
777
778 /* Signal FW about the impending command */
779 QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
780poll:
781 rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
782 if (rsp != QLCNIC_RCODE_TIMEOUT) {
783 /* Get the FW response data */
784 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
785 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
786 __qlcnic_83xx_process_aen(adapter);
787 goto poll;
788 }
789 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
790 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
791 opcode = QLCNIC_MBX_RSP(fw_data);
792 qlcnic_83xx_get_mbx_data(adapter, cmd);
793
794 switch (mbx_err_code) {
795 case QLCNIC_MBX_RSP_OK:
796 case QLCNIC_MBX_PORT_RSP_OK:
797 rsp = QLCNIC_RCODE_SUCCESS;
798 break;
799 default:
800 if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
801 rsp = qlcnic_83xx_mac_rcode(adapter);
802 if (!rsp)
803 goto out;
804 }
805 dev_err(&adapter->pdev->dev, 772 dev_err(&adapter->pdev->dev,
806 "MBX command 0x%x failed with err:0x%x\n", 773 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
807 opcode, mbx_err_code); 774 __func__, opcode, cmd_type, ahw->pci_func,
808 rsp = mbx_err_code; 775 ahw->op_mode);
809 qlcnic_dump_mbx(adapter, cmd); 776 flush_workqueue(mbx->work_q);
810 break;
811 } 777 }
812 goto out; 778 break;
779 case QLC_83XX_MBX_CMD_NO_WAIT:
780 return 0;
781 case QLC_83XX_MBX_CMD_BUSY_WAIT:
782 qlcnic_83xx_poll_for_mbx_completion(adapter, cmd);
783 break;
784 default:
785 dev_err(&adapter->pdev->dev,
786 "%s: Invalid mailbox command, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
787 __func__, opcode, cmd_type, ahw->pci_func,
788 ahw->op_mode);
789 qlcnic_83xx_detach_mailbox_work(adapter);
813 } 790 }
814 791
815 dev_err(&adapter->pdev->dev, "MBX command 0x%x timed out\n", 792 return cmd->rsp_opcode;
816 QLCNIC_MBX_RSP(mbx_cmd));
817 rsp = QLCNIC_RCODE_TIMEOUT;
818out:
819 /* clear fw mbx control register */
820 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
821 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
822 return rsp;
823} 793}
824 794
825int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx, 795int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
@@ -829,6 +799,7 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
829 u32 temp; 799 u32 temp;
830 const struct qlcnic_mailbox_metadata *mbx_tbl; 800 const struct qlcnic_mailbox_metadata *mbx_tbl;
831 801
802 memset(mbx, 0, sizeof(struct qlcnic_cmd_args));
832 mbx_tbl = qlcnic_83xx_mbx_tbl; 803 mbx_tbl = qlcnic_83xx_mbx_tbl;
833 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl); 804 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
834 for (i = 0; i < size; i++) { 805 for (i = 0; i < size; i++) {
@@ -851,6 +822,7 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
851 memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num); 822 memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num);
852 temp = adapter->ahw->fw_hal_version << 29; 823 temp = adapter->ahw->fw_hal_version << 29;
853 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp); 824 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
825 mbx->cmd_op = type;
854 return 0; 826 return 0;
855 } 827 }
856 } 828 }
@@ -934,20 +906,23 @@ void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
934 906
935static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter) 907static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
936{ 908{
909 u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
937 struct qlcnic_hardware_context *ahw = adapter->ahw; 910 struct qlcnic_hardware_context *ahw = adapter->ahw;
938 u32 resp, event; 911 struct qlcnic_mailbox *mbx = ahw->mailbox;
939 unsigned long flags; 912 unsigned long flags;
940 913
941 spin_lock_irqsave(&ahw->mbx_lock, flags); 914 spin_lock_irqsave(&mbx->aen_lock, flags);
942
943 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL); 915 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
944 if (resp & QLCNIC_SET_OWNER) { 916 if (resp & QLCNIC_SET_OWNER) {
945 event = readl(QLCNIC_MBX_FW(ahw, 0)); 917 event = readl(QLCNIC_MBX_FW(ahw, 0));
946 if (event & QLCNIC_MBX_ASYNC_EVENT) 918 if (event & QLCNIC_MBX_ASYNC_EVENT) {
947 __qlcnic_83xx_process_aen(adapter); 919 __qlcnic_83xx_process_aen(adapter);
920 } else {
921 if (atomic_read(&mbx->rsp_status) != rsp_status)
922 qlcnic_83xx_notify_mbx_response(mbx);
923 }
948 } 924 }
949 925 spin_unlock_irqrestore(&mbx->aen_lock, flags);
950 spin_unlock_irqrestore(&ahw->mbx_lock, flags);
951} 926}
952 927
953static void qlcnic_83xx_mbx_poll_work(struct work_struct *work) 928static void qlcnic_83xx_mbx_poll_work(struct work_struct *work)
@@ -970,6 +945,7 @@ void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *adapter)
970 return; 945 return;
971 946
972 INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work); 947 INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work);
948 queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work, 0);
973} 949}
974 950
975void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter) 951void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter)
@@ -1356,8 +1332,10 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1356 1332
1357 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 1333 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1358 /* disable and free mailbox interrupt */ 1334 /* disable and free mailbox interrupt */
1359 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) 1335 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
1336 qlcnic_83xx_enable_mbx_poll(adapter);
1360 qlcnic_83xx_free_mbx_intr(adapter); 1337 qlcnic_83xx_free_mbx_intr(adapter);
1338 }
1361 adapter->ahw->loopback_state = 0; 1339 adapter->ahw->loopback_state = 0;
1362 adapter->ahw->hw_ops->setup_link_event(adapter, 1); 1340 adapter->ahw->hw_ops->setup_link_event(adapter, 1);
1363 } 1341 }
@@ -1378,6 +1356,8 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1378 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 1356 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1379 sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1357 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1380 qlcnic_83xx_disable_intr(adapter, sds_ring); 1358 qlcnic_83xx_disable_intr(adapter, sds_ring);
1359 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1360 qlcnic_83xx_enable_mbx_poll(adapter);
1381 } 1361 }
1382 } 1362 }
1383 1363
@@ -1387,6 +1367,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1387 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 1367 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1388 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { 1368 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
1389 err = qlcnic_83xx_setup_mbx_intr(adapter); 1369 err = qlcnic_83xx_setup_mbx_intr(adapter);
1370 qlcnic_83xx_disable_mbx_poll(adapter);
1390 if (err) { 1371 if (err) {
1391 dev_err(&adapter->pdev->dev, 1372 dev_err(&adapter->pdev->dev,
1392 "%s: failed to setup mbx interrupt\n", 1373 "%s: failed to setup mbx interrupt\n",
@@ -1403,6 +1384,10 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1403 1384
1404 if (netif_running(netdev)) 1385 if (netif_running(netdev))
1405 __qlcnic_up(adapter, netdev); 1386 __qlcnic_up(adapter, netdev);
1387
1388 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST &&
1389 !(adapter->flags & QLCNIC_MSIX_ENABLED))
1390 qlcnic_83xx_disable_mbx_poll(adapter);
1406out: 1391out:
1407 netif_device_attach(netdev); 1392 netif_device_attach(netdev);
1408} 1393}
@@ -1620,26 +1605,33 @@ static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1620 1605
1621int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) 1606int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1622{ 1607{
1623 int err; 1608 struct qlcnic_cmd_args *cmd = NULL;
1624 u32 temp = 0; 1609 u32 temp = 0;
1625 struct qlcnic_cmd_args cmd; 1610 int err;
1626 1611
1627 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED) 1612 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1628 return -EIO; 1613 return -EIO;
1629 1614
1630 err = qlcnic_alloc_mbx_args(&cmd, adapter, 1615 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
1616 if (!cmd)
1617 return -ENOMEM;
1618
1619 err = qlcnic_alloc_mbx_args(cmd, adapter,
1631 QLCNIC_CMD_CONFIGURE_MAC_RX_MODE); 1620 QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1632 if (err) 1621 if (err)
1633 return err; 1622 goto out;
1634 1623
1624 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
1635 qlcnic_83xx_set_interface_id_promisc(adapter, &temp); 1625 qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
1636 cmd.req.arg[1] = (mode ? 1 : 0) | temp; 1626 cmd->req.arg[1] = (mode ? 1 : 0) | temp;
1637 err = qlcnic_issue_cmd(adapter, &cmd); 1627 err = qlcnic_issue_cmd(adapter, cmd);
1638 if (err) 1628 if (!err)
1639 dev_info(&adapter->pdev->dev, 1629 return err;
1640 "Promiscous mode config failed\n");
1641 1630
1642 qlcnic_free_mbx_args(&cmd); 1631 qlcnic_free_mbx_args(cmd);
1632
1633out:
1634 kfree(cmd);
1643 return err; 1635 return err;
1644} 1636}
1645 1637
@@ -1652,7 +1644,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1652 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { 1644 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1653 netdev_warn(netdev, 1645 netdev_warn(netdev,
1654 "Loopback test not supported in non privileged mode\n"); 1646 "Loopback test not supported in non privileged mode\n");
1655 return ret; 1647 return -ENOTSUPP;
1656 } 1648 }
1657 1649
1658 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { 1650 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
@@ -1680,19 +1672,17 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1680 /* Poll for link up event before running traffic */ 1672 /* Poll for link up event before running traffic */
1681 do { 1673 do {
1682 msleep(QLC_83XX_LB_MSLEEP_COUNT); 1674 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1683 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1684 qlcnic_83xx_process_aen(adapter);
1685 1675
1686 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { 1676 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1687 netdev_info(netdev, 1677 netdev_info(netdev,
1688 "Device is resetting, free LB test resources\n"); 1678 "Device is resetting, free LB test resources\n");
1689 ret = -EIO; 1679 ret = -EBUSY;
1690 goto free_diag_res; 1680 goto free_diag_res;
1691 } 1681 }
1692 if (loop++ > QLC_83XX_LB_WAIT_COUNT) { 1682 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1693 netdev_info(netdev, 1683 netdev_info(netdev,
1694 "Firmware didn't sent link up event to loopback request\n"); 1684 "Firmware didn't sent link up event to loopback request\n");
1695 ret = -QLCNIC_FW_NOT_RESPOND; 1685 ret = -ETIMEDOUT;
1696 qlcnic_83xx_clear_lb_mode(adapter, mode); 1686 qlcnic_83xx_clear_lb_mode(adapter, mode);
1697 goto free_diag_res; 1687 goto free_diag_res;
1698 } 1688 }
@@ -1729,6 +1719,15 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1729 return status; 1719 return status;
1730 1720
1731 config = ahw->port_config; 1721 config = ahw->port_config;
1722
1723 /* Check if port is already in loopback mode */
1724 if ((config & QLC_83XX_CFG_LOOPBACK_HSS) ||
1725 (config & QLC_83XX_CFG_LOOPBACK_EXT)) {
1726 netdev_err(netdev,
1727 "Port already in Loopback mode.\n");
1728 return -EINPROGRESS;
1729 }
1730
1732 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1731 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1733 1732
1734 if (mode == QLCNIC_ILB_MODE) 1733 if (mode == QLCNIC_ILB_MODE)
@@ -1749,21 +1748,19 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1749 /* Wait for Link and IDC Completion AEN */ 1748 /* Wait for Link and IDC Completion AEN */
1750 do { 1749 do {
1751 msleep(QLC_83XX_LB_MSLEEP_COUNT); 1750 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1752 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1753 qlcnic_83xx_process_aen(adapter);
1754 1751
1755 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { 1752 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1756 netdev_info(netdev, 1753 netdev_info(netdev,
1757 "Device is resetting, free LB test resources\n"); 1754 "Device is resetting, free LB test resources\n");
1758 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1755 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1759 return -EIO; 1756 return -EBUSY;
1760 } 1757 }
1761 if (loop++ > QLC_83XX_LB_WAIT_COUNT) { 1758 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1762 netdev_err(netdev, 1759 netdev_err(netdev,
1763 "Did not receive IDC completion AEN\n"); 1760 "Did not receive IDC completion AEN\n");
1764 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1761 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1765 qlcnic_83xx_clear_lb_mode(adapter, mode); 1762 qlcnic_83xx_clear_lb_mode(adapter, mode);
1766 return -EIO; 1763 return -ETIMEDOUT;
1767 } 1764 }
1768 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status)); 1765 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1769 1766
@@ -1798,21 +1795,19 @@ int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1798 /* Wait for Link and IDC Completion AEN */ 1795 /* Wait for Link and IDC Completion AEN */
1799 do { 1796 do {
1800 msleep(QLC_83XX_LB_MSLEEP_COUNT); 1797 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1801 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1802 qlcnic_83xx_process_aen(adapter);
1803 1798
1804 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { 1799 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1805 netdev_info(netdev, 1800 netdev_info(netdev,
1806 "Device is resetting, free LB test resources\n"); 1801 "Device is resetting, free LB test resources\n");
1807 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1802 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1808 return -EIO; 1803 return -EBUSY;
1809 } 1804 }
1810 1805
1811 if (loop++ > QLC_83XX_LB_WAIT_COUNT) { 1806 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1812 netdev_err(netdev, 1807 netdev_err(netdev,
1813 "Did not receive IDC completion AEN\n"); 1808 "Did not receive IDC completion AEN\n");
1814 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status); 1809 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1815 return -EIO; 1810 return -ETIMEDOUT;
1816 } 1811 }
1817 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status)); 1812 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1818 1813
@@ -1951,25 +1946,31 @@ static void qlcnic_83xx_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
1951int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, 1946int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1952 u16 vlan_id, u8 op) 1947 u16 vlan_id, u8 op)
1953{ 1948{
1954 int err; 1949 struct qlcnic_cmd_args *cmd = NULL;
1955 u32 *buf, temp = 0;
1956 struct qlcnic_cmd_args cmd;
1957 struct qlcnic_macvlan_mbx mv; 1950 struct qlcnic_macvlan_mbx mv;
1951 u32 *buf, temp = 0;
1952 int err;
1958 1953
1959 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED) 1954 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1960 return -EIO; 1955 return -EIO;
1961 1956
1962 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN); 1957 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
1958 if (!cmd)
1959 return -ENOMEM;
1960
1961 err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
1963 if (err) 1962 if (err)
1964 return err; 1963 goto out;
1964
1965 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
1965 1966
1966 if (vlan_id) 1967 if (vlan_id)
1967 op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ? 1968 op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
1968 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL; 1969 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
1969 1970
1970 cmd.req.arg[1] = op | (1 << 8); 1971 cmd->req.arg[1] = op | (1 << 8);
1971 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp); 1972 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp);
1972 cmd.req.arg[1] |= temp; 1973 cmd->req.arg[1] |= temp;
1973 mv.vlan = vlan_id; 1974 mv.vlan = vlan_id;
1974 mv.mac_addr0 = addr[0]; 1975 mv.mac_addr0 = addr[0];
1975 mv.mac_addr1 = addr[1]; 1976 mv.mac_addr1 = addr[1];
@@ -1977,14 +1978,15 @@ int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1977 mv.mac_addr3 = addr[3]; 1978 mv.mac_addr3 = addr[3];
1978 mv.mac_addr4 = addr[4]; 1979 mv.mac_addr4 = addr[4];
1979 mv.mac_addr5 = addr[5]; 1980 mv.mac_addr5 = addr[5];
1980 buf = &cmd.req.arg[2]; 1981 buf = &cmd->req.arg[2];
1981 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx)); 1982 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
1982 err = qlcnic_issue_cmd(adapter, &cmd); 1983 err = qlcnic_issue_cmd(adapter, cmd);
1983 if (err) 1984 if (!err)
1984 dev_err(&adapter->pdev->dev, 1985 return err;
1985 "MAC-VLAN %s to CAM failed, err=%d.\n", 1986
1986 ((op == 1) ? "add " : "delete "), err); 1987 qlcnic_free_mbx_args(cmd);
1987 qlcnic_free_mbx_args(&cmd); 1988out:
1989 kfree(cmd);
1988 return err; 1990 return err;
1989} 1991}
1990 1992
@@ -2093,10 +2095,12 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
2093irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data) 2095irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2094{ 2096{
2095 struct qlcnic_adapter *adapter = data; 2097 struct qlcnic_adapter *adapter = data;
2096 unsigned long flags; 2098 struct qlcnic_mailbox *mbx;
2097 u32 mask, resp, event; 2099 u32 mask, resp, event;
2100 unsigned long flags;
2098 2101
2099 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags); 2102 mbx = adapter->ahw->mailbox;
2103 spin_lock_irqsave(&mbx->aen_lock, flags);
2100 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL); 2104 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
2101 if (!(resp & QLCNIC_SET_OWNER)) 2105 if (!(resp & QLCNIC_SET_OWNER))
2102 goto out; 2106 goto out;
@@ -2104,11 +2108,13 @@ irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2104 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0)); 2108 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
2105 if (event & QLCNIC_MBX_ASYNC_EVENT) 2109 if (event & QLCNIC_MBX_ASYNC_EVENT)
2106 __qlcnic_83xx_process_aen(adapter); 2110 __qlcnic_83xx_process_aen(adapter);
2111 else
2112 qlcnic_83xx_notify_mbx_response(mbx);
2113
2107out: 2114out:
2108 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK); 2115 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
2109 writel(0, adapter->ahw->pci_base0 + mask); 2116 writel(0, adapter->ahw->pci_base0 + mask);
2110 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags); 2117 spin_unlock_irqrestore(&mbx->aen_lock, flags);
2111
2112 return IRQ_HANDLED; 2118 return IRQ_HANDLED;
2113} 2119}
2114 2120
@@ -3446,3 +3452,300 @@ int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
3446 idc->delay); 3452 idc->delay);
3447 return err; 3453 return err;
3448} 3454}
3455
3456void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx)
3457{
3458 INIT_COMPLETION(mbx->completion);
3459 set_bit(QLC_83XX_MBX_READY, &mbx->status);
3460}
3461
3462void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx)
3463{
3464 destroy_workqueue(mbx->work_q);
3465 kfree(mbx);
3466}
3467
3468static inline void
3469qlcnic_83xx_notify_cmd_completion(struct qlcnic_adapter *adapter,
3470 struct qlcnic_cmd_args *cmd)
3471{
3472 atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
3473
3474 if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {
3475 qlcnic_free_mbx_args(cmd);
3476 kfree(cmd);
3477 return;
3478 }
3479 complete(&cmd->completion);
3480}
3481
3482static inline void qlcnic_83xx_flush_mbx_queue(struct qlcnic_adapter *adapter)
3483{
3484 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3485 struct list_head *head = &mbx->cmd_q;
3486 struct qlcnic_cmd_args *cmd = NULL;
3487
3488 spin_lock(&mbx->queue_lock);
3489
3490 while (!list_empty(head)) {
3491 cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
3492 list_del(&cmd->list);
3493 mbx->num_cmds--;
3494 qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3495 }
3496
3497 spin_unlock(&mbx->queue_lock);
3498}
3499
3500static inline int qlcnic_83xx_check_mbx_status(struct qlcnic_adapter *adapter)
3501{
3502 struct qlcnic_hardware_context *ahw = adapter->ahw;
3503 struct qlcnic_mailbox *mbx = ahw->mailbox;
3504 u32 host_mbx_ctrl;
3505
3506 if (!test_bit(QLC_83XX_MBX_READY, &mbx->status))
3507 return -EBUSY;
3508
3509 host_mbx_ctrl = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
3510 if (host_mbx_ctrl) {
3511 ahw->idc.collect_dump = 1;
3512 return -EIO;
3513 }
3514
3515 return 0;
3516}
3517
3518static inline void qlcnic_83xx_signal_mbx_cmd(struct qlcnic_adapter *adapter,
3519 u8 issue_cmd)
3520{
3521 if (issue_cmd)
3522 QLCWRX(adapter->ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
3523 else
3524 QLCWRX(adapter->ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
3525}
3526
3527static inline void qlcnic_83xx_dequeue_mbx_cmd(struct qlcnic_adapter *adapter,
3528 struct qlcnic_cmd_args *cmd)
3529{
3530 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3531
3532 spin_lock(&mbx->queue_lock);
3533
3534 list_del(&cmd->list);
3535 mbx->num_cmds--;
3536
3537 spin_unlock(&mbx->queue_lock);
3538
3539 qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3540}
3541
3542static void qlcnic_83xx_encode_mbx_cmd(struct qlcnic_adapter *adapter,
3543 struct qlcnic_cmd_args *cmd)
3544{
3545 u32 mbx_cmd, fw_hal_version, hdr_size, total_size, tmp;
3546 struct qlcnic_hardware_context *ahw = adapter->ahw;
3547 int i, j;
3548
3549 if (cmd->op_type != QLC_83XX_MBX_POST_BC_OP) {
3550 mbx_cmd = cmd->req.arg[0];
3551 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3552 for (i = 1; i < cmd->req.num; i++)
3553 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
3554 } else {
3555 fw_hal_version = ahw->fw_hal_version;
3556 hdr_size = sizeof(struct qlcnic_bc_hdr) / sizeof(u32);
3557 total_size = cmd->pay_size + hdr_size;
3558 tmp = QLCNIC_CMD_BC_EVENT_SETUP | total_size << 16;
3559 mbx_cmd = tmp | fw_hal_version << 29;
3560 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3561
3562 /* Back channel specific operations bits */
3563 mbx_cmd = 0x1 | 1 << 4;
3564
3565 if (qlcnic_sriov_pf_check(adapter))
3566 mbx_cmd |= cmd->func_num << 5;
3567
3568 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 1));
3569
3570 for (i = 2, j = 0; j < hdr_size; i++, j++)
3571 writel(*(cmd->hdr++), QLCNIC_MBX_HOST(ahw, i));
3572 for (j = 0; j < cmd->pay_size; j++, i++)
3573 writel(*(cmd->pay++), QLCNIC_MBX_HOST(ahw, i));
3574 }
3575}
3576
3577void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *adapter)
3578{
3579 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3580
3581 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3582 complete(&mbx->completion);
3583 cancel_work_sync(&mbx->work);
3584 flush_workqueue(mbx->work_q);
3585 qlcnic_83xx_flush_mbx_queue(adapter);
3586}
3587
3588static inline int qlcnic_83xx_enqueue_mbx_cmd(struct qlcnic_adapter *adapter,
3589 struct qlcnic_cmd_args *cmd,
3590 unsigned long *timeout)
3591{
3592 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3593
3594 if (test_bit(QLC_83XX_MBX_READY, &mbx->status)) {
3595 atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
3596 init_completion(&cmd->completion);
3597 cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_UNKNOWN;
3598
3599 spin_lock(&mbx->queue_lock);
3600
3601 list_add_tail(&cmd->list, &mbx->cmd_q);
3602 mbx->num_cmds++;
3603 cmd->total_cmds = mbx->num_cmds;
3604 *timeout = cmd->total_cmds * QLC_83XX_MBX_TIMEOUT;
3605 queue_work(mbx->work_q, &mbx->work);
3606
3607 spin_unlock(&mbx->queue_lock);
3608
3609 return 0;
3610 }
3611
3612 return -EBUSY;
3613}
3614
3615static inline int qlcnic_83xx_check_mac_rcode(struct qlcnic_adapter *adapter,
3616 struct qlcnic_cmd_args *cmd)
3617{
3618 u8 mac_cmd_rcode;
3619 u32 fw_data;
3620
3621 if (cmd->cmd_op == QLCNIC_CMD_CONFIG_MAC_VLAN) {
3622 fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2));
3623 mac_cmd_rcode = (u8)fw_data;
3624 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
3625 mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
3626 mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
3627 cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
3628 return QLCNIC_RCODE_SUCCESS;
3629 }
3630 }
3631
3632 return -EINVAL;
3633}
3634
3635static void qlcnic_83xx_decode_mbx_rsp(struct qlcnic_adapter *adapter,
3636 struct qlcnic_cmd_args *cmd)
3637{
3638 struct qlcnic_hardware_context *ahw = adapter->ahw;
3639 struct device *dev = &adapter->pdev->dev;
3640 u8 mbx_err_code;
3641 u32 fw_data;
3642
3643 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
3644 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
3645 qlcnic_83xx_get_mbx_data(adapter, cmd);
3646
3647 switch (mbx_err_code) {
3648 case QLCNIC_MBX_RSP_OK:
3649 case QLCNIC_MBX_PORT_RSP_OK:
3650 cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
3651 break;
3652 default:
3653 if (!qlcnic_83xx_check_mac_rcode(adapter, cmd))
3654 break;
3655
3656 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",
3657 __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
3658 ahw->op_mode, mbx_err_code);
3659 cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_FAILED;
3660 qlcnic_dump_mbx(adapter, cmd);
3661 }
3662
3663 return;
3664}
3665
3666static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
3667{
3668 struct qlcnic_mailbox *mbx = container_of(work, struct qlcnic_mailbox,
3669 work);
3670 struct qlcnic_adapter *adapter = mbx->adapter;
3671 struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
3672 struct device *dev = &adapter->pdev->dev;
3673 atomic_t *rsp_status = &mbx->rsp_status;
3674 struct list_head *head = &mbx->cmd_q;
3675 struct qlcnic_hardware_context *ahw;
3676 struct qlcnic_cmd_args *cmd = NULL;
3677
3678 ahw = adapter->ahw;
3679
3680 while (true) {
3681 if (qlcnic_83xx_check_mbx_status(adapter))
3682 return;
3683
3684 atomic_set(rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
3685
3686 spin_lock(&mbx->queue_lock);
3687
3688 if (list_empty(head)) {
3689 spin_unlock(&mbx->queue_lock);
3690 return;
3691 }
3692 cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
3693
3694 spin_unlock(&mbx->queue_lock);
3695
3696 mbx_ops->encode_cmd(adapter, cmd);
3697 mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_REQUEST);
3698
3699 if (wait_for_completion_timeout(&mbx->completion,
3700 QLC_83XX_MBX_TIMEOUT)) {
3701 mbx_ops->decode_resp(adapter, cmd);
3702 mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_COMPLETION);
3703 } else {
3704 dev_err(dev, "%s: Mailbox command timeout, opcode=0x%x, cmd_type=0x%x, func=0x%x, op_mode=0x%x\n",
3705 __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
3706 ahw->op_mode);
3707 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3708 qlcnic_83xx_idc_request_reset(adapter,
3709 QLCNIC_FORCE_FW_DUMP_KEY);
3710 cmd->rsp_opcode = QLCNIC_RCODE_TIMEOUT;
3711 }
3712 mbx_ops->dequeue_cmd(adapter, cmd);
3713 }
3714}
3715
3716static struct qlcnic_mbx_ops qlcnic_83xx_mbx_ops = {
3717 .enqueue_cmd = qlcnic_83xx_enqueue_mbx_cmd,
3718 .dequeue_cmd = qlcnic_83xx_dequeue_mbx_cmd,
3719 .decode_resp = qlcnic_83xx_decode_mbx_rsp,
3720 .encode_cmd = qlcnic_83xx_encode_mbx_cmd,
3721 .nofity_fw = qlcnic_83xx_signal_mbx_cmd,
3722};
3723
3724int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *adapter)
3725{
3726 struct qlcnic_hardware_context *ahw = adapter->ahw;
3727 struct qlcnic_mailbox *mbx;
3728
3729 ahw->mailbox = kzalloc(sizeof(*mbx), GFP_KERNEL);
3730 if (!ahw->mailbox)
3731 return -ENOMEM;
3732
3733 mbx = ahw->mailbox;
3734 mbx->ops = &qlcnic_83xx_mbx_ops;
3735 mbx->adapter = adapter;
3736
3737 spin_lock_init(&mbx->queue_lock);
3738 spin_lock_init(&mbx->aen_lock);
3739 INIT_LIST_HEAD(&mbx->cmd_q);
3740 init_completion(&mbx->completion);
3741
3742 mbx->work_q = create_singlethread_workqueue("qlcnic_mailbox");
3743 if (mbx->work_q == NULL) {
3744 kfree(mbx);
3745 return -ENOMEM;
3746 }
3747
3748 INIT_WORK(&mbx->work, qlcnic_83xx_mailbox_worker);
3749 set_bit(QLC_83XX_MBX_READY, &mbx->status);
3750 return 0;
3751}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 2548d1403d75..9993705e0a43 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -89,6 +89,13 @@
89 89
90#define QLC_83XX_MAX_RESET_SEQ_ENTRIES 16 90#define QLC_83XX_MAX_RESET_SEQ_ENTRIES 16
91 91
92#define QLC_83XX_MBX_POST_BC_OP 0x1
93#define QLC_83XX_MBX_COMPLETION 0x0
94#define QLC_83XX_MBX_REQUEST 0x1
95
96#define QLC_83XX_MBX_TIMEOUT (5 * HZ)
97#define QLC_83XX_MBX_CMD_LOOP 5000000
98
92/* status descriptor mailbox data 99/* status descriptor mailbox data
93 * @phy_addr_{low|high}: physical address of buffer 100 * @phy_addr_{low|high}: physical address of buffer
94 * @sds_ring_size: buffer size 101 * @sds_ring_size: buffer size
@@ -449,6 +456,20 @@ enum qlcnic_83xx_states {
449#define QLC_83xx_FLASH_MAX_WAIT_USEC 100 456#define QLC_83xx_FLASH_MAX_WAIT_USEC 100
450#define QLC_83XX_FLASH_LOCK_TIMEOUT 10000 457#define QLC_83XX_FLASH_LOCK_TIMEOUT 10000
451 458
459enum qlc_83xx_mbx_cmd_type {
460 QLC_83XX_MBX_CMD_WAIT = 0,
461 QLC_83XX_MBX_CMD_NO_WAIT,
462 QLC_83XX_MBX_CMD_BUSY_WAIT,
463};
464
465enum qlc_83xx_mbx_response_states {
466 QLC_83XX_MBX_RESPONSE_WAIT = 0,
467 QLC_83XX_MBX_RESPONSE_ARRIVED,
468};
469
470#define QLC_83XX_MBX_RESPONSE_FAILED 0x2
471#define QLC_83XX_MBX_RESPONSE_UNKNOWN 0x3
472
452/* Additional registers in 83xx */ 473/* Additional registers in 83xx */
453enum qlc_83xx_ext_regs { 474enum qlc_83xx_ext_regs {
454 QLCNIC_GLOBAL_RESET = 0, 475 QLCNIC_GLOBAL_RESET = 0,
@@ -498,7 +519,7 @@ enum qlc_83xx_ext_regs {
498 519
499/* 83xx funcitons */ 520/* 83xx funcitons */
500int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *); 521int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *);
501int qlcnic_83xx_mbx_op(struct qlcnic_adapter *, struct qlcnic_cmd_args *); 522int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *, struct qlcnic_cmd_args *);
502int qlcnic_83xx_setup_intr(struct qlcnic_adapter *, u8); 523int qlcnic_83xx_setup_intr(struct qlcnic_adapter *, u8);
503void qlcnic_83xx_get_func_no(struct qlcnic_adapter *); 524void qlcnic_83xx_get_func_no(struct qlcnic_adapter *);
504int qlcnic_83xx_cam_lock(struct qlcnic_adapter *); 525int qlcnic_83xx_cam_lock(struct qlcnic_adapter *);
@@ -551,7 +572,7 @@ void qlcnic_set_npar_data(struct qlcnic_adapter *, const struct qlcnic_info *,
551void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *); 572void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *);
552irqreturn_t qlcnic_83xx_handle_aen(int, void *); 573irqreturn_t qlcnic_83xx_handle_aen(int, void *);
553int qlcnic_83xx_get_port_info(struct qlcnic_adapter *); 574int qlcnic_83xx_get_port_info(struct qlcnic_adapter *);
554void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *); 575void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *);
555void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *); 576void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *);
556irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *); 577irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *);
557irqreturn_t qlcnic_83xx_intr(int, void *); 578irqreturn_t qlcnic_83xx_intr(int, void *);
@@ -623,8 +644,6 @@ int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state);
623int qlcnic_83xx_flash_test(struct qlcnic_adapter *); 644int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
624int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *); 645int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *);
625int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *); 646int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *);
626u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *);
627u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *);
628void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *); 647void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
629void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *); 648void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
630void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *); 649void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index f41dfab1e9a3..bb7c649bfe53 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -399,6 +399,7 @@ static void qlcnic_83xx_idc_detach_driver(struct qlcnic_adapter *adapter)
399 struct net_device *netdev = adapter->netdev; 399 struct net_device *netdev = adapter->netdev;
400 400
401 netif_device_detach(netdev); 401 netif_device_detach(netdev);
402 qlcnic_83xx_detach_mailbox_work(adapter);
402 403
403 /* Disable mailbox interrupt */ 404 /* Disable mailbox interrupt */
404 qlcnic_83xx_disable_mbx_intr(adapter); 405 qlcnic_83xx_disable_mbx_intr(adapter);
@@ -610,6 +611,9 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
610{ 611{
611 int err; 612 int err;
612 613
614 qlcnic_83xx_reinit_mbx_work(adapter->ahw->mailbox);
615 qlcnic_83xx_enable_mbx_interrupt(adapter);
616
613 /* register for NIC IDC AEN Events */ 617 /* register for NIC IDC AEN Events */
614 qlcnic_83xx_register_nic_idc_func(adapter, 1); 618 qlcnic_83xx_register_nic_idc_func(adapter, 1);
615 619
@@ -617,7 +621,7 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
617 if (err) 621 if (err)
618 return err; 622 return err;
619 623
620 qlcnic_83xx_enable_mbx_intrpt(adapter); 624 qlcnic_83xx_enable_mbx_interrupt(adapter);
621 625
622 if (qlcnic_83xx_configure_opmode(adapter)) { 626 if (qlcnic_83xx_configure_opmode(adapter)) {
623 qlcnic_83xx_idc_enter_failed_state(adapter, 1); 627 qlcnic_83xx_idc_enter_failed_state(adapter, 1);
@@ -640,7 +644,6 @@ static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
640 struct qlcnic_hardware_context *ahw = adapter->ahw; 644 struct qlcnic_hardware_context *ahw = adapter->ahw;
641 645
642 qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1); 646 qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1);
643 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
644 qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); 647 qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
645 set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); 648 set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
646 649
@@ -810,9 +813,10 @@ static int qlcnic_83xx_idc_init_state(struct qlcnic_adapter *adapter)
810 **/ 813 **/
811static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) 814static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
812{ 815{
813 u32 val;
814 struct qlcnic_hardware_context *ahw = adapter->ahw; 816 struct qlcnic_hardware_context *ahw = adapter->ahw;
817 struct qlcnic_mailbox *mbx = ahw->mailbox;
815 int ret = 0; 818 int ret = 0;
819 u32 val;
816 820
817 /* Perform NIC configuration based ready state entry actions */ 821 /* Perform NIC configuration based ready state entry actions */
818 if (ahw->idc.state_entry(adapter)) 822 if (ahw->idc.state_entry(adapter))
@@ -824,7 +828,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
824 dev_err(&adapter->pdev->dev, 828 dev_err(&adapter->pdev->dev,
825 "Error: device temperature %d above limits\n", 829 "Error: device temperature %d above limits\n",
826 adapter->ahw->temp); 830 adapter->ahw->temp);
827 clear_bit(QLC_83XX_MBX_READY, &ahw->idc.status); 831 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
828 set_bit(__QLCNIC_RESETTING, &adapter->state); 832 set_bit(__QLCNIC_RESETTING, &adapter->state);
829 qlcnic_83xx_idc_detach_driver(adapter); 833 qlcnic_83xx_idc_detach_driver(adapter);
830 qlcnic_83xx_idc_enter_failed_state(adapter, 1); 834 qlcnic_83xx_idc_enter_failed_state(adapter, 1);
@@ -837,7 +841,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
837 if (ret) { 841 if (ret) {
838 adapter->flags |= QLCNIC_FW_HANG; 842 adapter->flags |= QLCNIC_FW_HANG;
839 if (!(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) { 843 if (!(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) {
840 clear_bit(QLC_83XX_MBX_READY, &ahw->idc.status); 844 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
841 set_bit(__QLCNIC_RESETTING, &adapter->state); 845 set_bit(__QLCNIC_RESETTING, &adapter->state);
842 qlcnic_83xx_idc_enter_need_reset_state(adapter, 1); 846 qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
843 } 847 }
@@ -845,6 +849,8 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
845 } 849 }
846 850
847 if ((val & QLC_83XX_IDC_GRACEFULL_RESET) || ahw->idc.collect_dump) { 851 if ((val & QLC_83XX_IDC_GRACEFULL_RESET) || ahw->idc.collect_dump) {
852 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
853
848 /* Move to need reset state and prepare for reset */ 854 /* Move to need reset state and prepare for reset */
849 qlcnic_83xx_idc_enter_need_reset_state(adapter, 1); 855 qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
850 return ret; 856 return ret;
@@ -882,12 +888,13 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
882 **/ 888 **/
883static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter) 889static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter)
884{ 890{
891 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
885 int ret = 0; 892 int ret = 0;
886 893
887 if (adapter->ahw->idc.prev_state != QLC_83XX_IDC_DEV_NEED_RESET) { 894 if (adapter->ahw->idc.prev_state != QLC_83XX_IDC_DEV_NEED_RESET) {
888 qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); 895 qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
889 set_bit(__QLCNIC_RESETTING, &adapter->state); 896 set_bit(__QLCNIC_RESETTING, &adapter->state);
890 clear_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status); 897 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
891 if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE) 898 if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE)
892 qlcnic_83xx_disable_vnic_mode(adapter, 1); 899 qlcnic_83xx_disable_vnic_mode(adapter, 1);
893 900
@@ -1079,7 +1086,6 @@ static void qlcnic_83xx_setup_idc_parameters(struct qlcnic_adapter *adapter)
1079 adapter->ahw->idc.name = (char **)qlc_83xx_idc_states; 1086 adapter->ahw->idc.name = (char **)qlc_83xx_idc_states;
1080 1087
1081 clear_bit(__QLCNIC_RESETTING, &adapter->state); 1088 clear_bit(__QLCNIC_RESETTING, &adapter->state);
1082 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
1083 set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); 1089 set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
1084 1090
1085 /* Check if reset recovery is disabled */ 1091 /* Check if reset recovery is disabled */
@@ -1190,6 +1196,9 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *adapter, u32 key)
1190{ 1196{
1191 u32 val; 1197 u32 val;
1192 1198
1199 if (qlcnic_sriov_vf_check(adapter))
1200 return;
1201
1193 if (qlcnic_83xx_lock_driver(adapter)) { 1202 if (qlcnic_83xx_lock_driver(adapter)) {
1194 dev_err(&adapter->pdev->dev, 1203 dev_err(&adapter->pdev->dev,
1195 "%s:failed, please retry\n", __func__); 1204 "%s:failed, please retry\n", __func__);
@@ -2110,17 +2119,35 @@ static void qlcnic_83xx_clear_function_resources(struct qlcnic_adapter *adapter)
2110int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) 2119int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
2111{ 2120{
2112 struct qlcnic_hardware_context *ahw = adapter->ahw; 2121 struct qlcnic_hardware_context *ahw = adapter->ahw;
2122 int err = 0;
2113 2123
2114 if (qlcnic_sriov_vf_check(adapter)) 2124 ahw->msix_supported = !!qlcnic_use_msi_x;
2115 return qlcnic_sriov_vf_init(adapter, pci_using_dac); 2125 err = qlcnic_83xx_init_mailbox_work(adapter);
2126 if (err)
2127 goto exit;
2116 2128
2117 if (qlcnic_83xx_check_hw_status(adapter)) 2129 if (qlcnic_sriov_vf_check(adapter)) {
2118 return -EIO; 2130 err = qlcnic_sriov_vf_init(adapter, pci_using_dac);
2131 if (err)
2132 goto detach_mbx;
2133 else
2134 return err;
2135 }
2119 2136
2120 /* Initilaize 83xx mailbox spinlock */ 2137 err = qlcnic_83xx_check_hw_status(adapter);
2121 spin_lock_init(&ahw->mbx_lock); 2138 if (err)
2139 goto detach_mbx;
2140
2141 err = qlcnic_setup_intr(adapter, 0);
2142 if (err) {
2143 dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n");
2144 goto disable_intr;
2145 }
2146
2147 err = qlcnic_83xx_setup_mbx_intr(adapter);
2148 if (err)
2149 goto disable_mbx_intr;
2122 2150
2123 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
2124 qlcnic_83xx_clear_function_resources(adapter); 2151 qlcnic_83xx_clear_function_resources(adapter);
2125 2152
2126 /* register for NIC IDC AEN Events */ 2153 /* register for NIC IDC AEN Events */
@@ -2129,21 +2156,35 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
2129 if (!qlcnic_83xx_read_flash_descriptor_table(adapter)) 2156 if (!qlcnic_83xx_read_flash_descriptor_table(adapter))
2130 qlcnic_83xx_read_flash_mfg_id(adapter); 2157 qlcnic_83xx_read_flash_mfg_id(adapter);
2131 2158
2132 if (qlcnic_83xx_idc_init(adapter)) 2159 err = qlcnic_83xx_idc_init(adapter);
2133 return -EIO; 2160 if (err)
2161 goto disable_mbx_intr;
2134 2162
2135 /* Configure default, SR-IOV or Virtual NIC mode of operation */ 2163 /* Configure default, SR-IOV or Virtual NIC mode of operation */
2136 if (qlcnic_83xx_configure_opmode(adapter)) 2164 err = qlcnic_83xx_configure_opmode(adapter);
2137 return -EIO; 2165 if (err)
2166 goto disable_mbx_intr;
2138 2167
2139 /* Perform operating mode specific initialization */ 2168 /* Perform operating mode specific initialization */
2140 if (adapter->nic_ops->init_driver(adapter)) 2169 err = adapter->nic_ops->init_driver(adapter);
2141 return -EIO; 2170 if (err)
2171 goto disable_mbx_intr;
2142 2172
2143 INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work); 2173 INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
2144 2174
2145 /* Periodically monitor device status */ 2175 /* Periodically monitor device status */
2146 qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work); 2176 qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work);
2177 return 0;
2147 2178
2148 return adapter->ahw->idc.err_code; 2179disable_mbx_intr:
2180 qlcnic_83xx_free_mbx_intr(adapter);
2181
2182disable_intr:
2183 qlcnic_teardown_intr(adapter);
2184
2185detach_mbx:
2186 qlcnic_83xx_detach_mailbox_work(adapter);
2187 qlcnic_83xx_free_mailbox(ahw->mailbox);
2188exit:
2189 return err;
2149} 2190}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 700a46324d09..94a728da3eb1 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -980,9 +980,9 @@ int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
980 msleep(500); 980 msleep(500);
981 qlcnic_process_rcv_ring_diag(sds_ring); 981 qlcnic_process_rcv_ring_diag(sds_ring);
982 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) { 982 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
983 netdev_info(netdev, "firmware didnt respond to loopback" 983 netdev_info(netdev,
984 " configure request\n"); 984 "Firmware didn't sent link up event to loopback request\n");
985 ret = -QLCNIC_FW_NOT_RESPOND; 985 ret = -ETIMEDOUT;
986 goto free_res; 986 goto free_res;
987 } else if (adapter->ahw->diag_cnt) { 987 } else if (adapter->ahw->diag_cnt) {
988 ret = adapter->ahw->diag_cnt; 988 ret = adapter->ahw->diag_cnt;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index d3f8797efcc3..1994b446c9e7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -919,17 +919,17 @@ static void qlcnic_handle_fw_message(int desc_cnt, int index,
919 break; 919 break;
920 case 1: 920 case 1:
921 dev_info(dev, "loopback already in progress\n"); 921 dev_info(dev, "loopback already in progress\n");
922 adapter->ahw->diag_cnt = -QLCNIC_TEST_IN_PROGRESS; 922 adapter->ahw->diag_cnt = -EINPROGRESS;
923 break; 923 break;
924 case 2: 924 case 2:
925 dev_info(dev, "loopback cable is not connected\n"); 925 dev_info(dev, "loopback cable is not connected\n");
926 adapter->ahw->diag_cnt = -QLCNIC_LB_CABLE_NOT_CONN; 926 adapter->ahw->diag_cnt = -ENODEV;
927 break; 927 break;
928 default: 928 default:
929 dev_info(dev, 929 dev_info(dev,
930 "loopback configure request failed, err %x\n", 930 "loopback configure request failed, err %x\n",
931 ret); 931 ret);
932 adapter->ahw->diag_cnt = -QLCNIC_UNDEFINED_ERROR; 932 adapter->ahw->diag_cnt = -EIO;
933 break; 933 break;
934 } 934 }
935 break; 935 break;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 4528f8ec333b..cdc24e4d7e5c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2141,16 +2141,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2141 dev_warn(&pdev->dev, 2141 dev_warn(&pdev->dev,
2142 "83xx adapter do not support MSI interrupts\n"); 2142 "83xx adapter do not support MSI interrupts\n");
2143 2143
2144 err = qlcnic_setup_intr(adapter, 0); 2144 if (qlcnic_82xx_check(adapter)) {
2145 if (err) { 2145 err = qlcnic_setup_intr(adapter, 0);
2146 dev_err(&pdev->dev, "Failed to setup interrupt\n"); 2146 if (err) {
2147 goto err_out_disable_msi; 2147 dev_err(&pdev->dev, "Failed to setup interrupt\n");
2148 }
2149
2150 if (qlcnic_83xx_check(adapter)) {
2151 err = qlcnic_83xx_setup_mbx_intr(adapter);
2152 if (err)
2153 goto err_out_disable_msi; 2148 goto err_out_disable_msi;
2149 }
2154 } 2150 }
2155 2151
2156 err = qlcnic_get_act_pci_func(adapter); 2152 err = qlcnic_get_act_pci_func(adapter);
@@ -2237,9 +2233,11 @@ static void qlcnic_remove(struct pci_dev *pdev)
2237 qlcnic_sriov_cleanup(adapter); 2233 qlcnic_sriov_cleanup(adapter);
2238 2234
2239 if (qlcnic_83xx_check(adapter)) { 2235 if (qlcnic_83xx_check(adapter)) {
2240 qlcnic_83xx_free_mbx_intr(adapter);
2241 qlcnic_83xx_register_nic_idc_func(adapter, 0); 2236 qlcnic_83xx_register_nic_idc_func(adapter, 0);
2242 cancel_delayed_work_sync(&adapter->idc_aen_work); 2237 cancel_delayed_work_sync(&adapter->idc_aen_work);
2238 qlcnic_83xx_free_mbx_intr(adapter);
2239 qlcnic_83xx_detach_mailbox_work(adapter);
2240 qlcnic_83xx_free_mailbox(ahw->mailbox);
2243 } 2241 }
2244 2242
2245 qlcnic_detach(adapter); 2243 qlcnic_detach(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 62380ce89905..e58c1d4fa01f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -33,7 +33,7 @@ static int qlcnic_sriov_alloc_bc_mbx_args(struct qlcnic_cmd_args *, u32);
33static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *); 33static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *);
34static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *); 34static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *);
35static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *); 35static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *);
36static int qlcnic_sriov_vf_mbx_op(struct qlcnic_adapter *, 36static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *,
37 struct qlcnic_cmd_args *); 37 struct qlcnic_cmd_args *);
38static void qlcnic_sriov_process_bc_cmd(struct work_struct *); 38static void qlcnic_sriov_process_bc_cmd(struct work_struct *);
39 39
@@ -45,7 +45,7 @@ static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {
45 .get_mac_address = qlcnic_83xx_get_mac_address, 45 .get_mac_address = qlcnic_83xx_get_mac_address,
46 .setup_intr = qlcnic_83xx_setup_intr, 46 .setup_intr = qlcnic_83xx_setup_intr,
47 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args, 47 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
48 .mbx_cmd = qlcnic_sriov_vf_mbx_op, 48 .mbx_cmd = qlcnic_sriov_issue_cmd,
49 .get_func_no = qlcnic_83xx_get_func_no, 49 .get_func_no = qlcnic_83xx_get_func_no,
50 .api_lock = qlcnic_83xx_cam_lock, 50 .api_lock = qlcnic_83xx_cam_lock,
51 .api_unlock = qlcnic_83xx_cam_unlock, 51 .api_unlock = qlcnic_83xx_cam_unlock,
@@ -286,96 +286,38 @@ void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
286static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, 286static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
287 u32 *pay, u8 pci_func, u8 size) 287 u32 *pay, u8 pci_func, u8 size)
288{ 288{
289 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val, wait_time = 0;
290 struct qlcnic_hardware_context *ahw = adapter->ahw; 289 struct qlcnic_hardware_context *ahw = adapter->ahw;
291 unsigned long flags; 290 struct qlcnic_mailbox *mbx = ahw->mailbox;
292 u16 opcode; 291 struct qlcnic_cmd_args cmd;
293 u8 mbx_err_code; 292 unsigned long timeout;
294 int i, j; 293 int err;
295
296 opcode = ((struct qlcnic_bc_hdr *)hdr)->cmd_op;
297
298 if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) {
299 dev_info(&adapter->pdev->dev,
300 "Mailbox cmd attempted, 0x%x\n", opcode);
301 dev_info(&adapter->pdev->dev, "Mailbox detached\n");
302 return 0;
303 }
304
305 spin_lock_irqsave(&ahw->mbx_lock, flags);
306
307 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
308 if (mbx_val) {
309 QLCDB(adapter, DRV, "Mailbox cmd attempted, 0x%x\n", opcode);
310 spin_unlock_irqrestore(&ahw->mbx_lock, flags);
311 return QLCNIC_RCODE_TIMEOUT;
312 }
313 /* Fill in mailbox registers */
314 val = size + (sizeof(struct qlcnic_bc_hdr) / sizeof(u32));
315 mbx_cmd = 0x31 | (val << 16) | (adapter->ahw->fw_hal_version << 29);
316
317 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
318 mbx_cmd = 0x1 | (1 << 4);
319 294
320 if (qlcnic_sriov_pf_check(adapter)) 295 memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));
321 mbx_cmd |= (pci_func << 5); 296 cmd.hdr = hdr;
297 cmd.pay = pay;
298 cmd.pay_size = size;
299 cmd.func_num = pci_func;
300 cmd.op_type = QLC_83XX_MBX_POST_BC_OP;
301 cmd.cmd_op = ((struct qlcnic_bc_hdr *)hdr)->cmd_op;
322 302
323 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 1)); 303 err = mbx->ops->enqueue_cmd(adapter, &cmd, &timeout);
324 for (i = 2, j = 0; j < (sizeof(struct qlcnic_bc_hdr) / sizeof(u32)); 304 if (err) {
325 i++, j++) { 305 dev_err(&adapter->pdev->dev,
326 writel(*(hdr++), QLCNIC_MBX_HOST(ahw, i)); 306 "%s: Mailbox not available, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
307 __func__, cmd.cmd_op, cmd.type, ahw->pci_func,
308 ahw->op_mode);
309 return err;
327 } 310 }
328 for (j = 0; j < size; j++, i++)
329 writel(*(pay++), QLCNIC_MBX_HOST(ahw, i));
330
331 /* Signal FW about the impending command */
332 QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
333 311
334 /* Waiting for the mailbox cmd to complete and while waiting here 312 if (!wait_for_completion_timeout(&cmd.completion, timeout)) {
335 * some AEN might arrive. If more than 5 seconds expire we can 313 dev_err(&adapter->pdev->dev,
336 * assume something is wrong. 314 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
337 */ 315 __func__, cmd.cmd_op, cmd.type, ahw->pci_func,
338poll: 316 ahw->op_mode);
339 rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time); 317 flush_workqueue(mbx->work_q);
340 if (rsp != QLCNIC_RCODE_TIMEOUT) {
341 /* Get the FW response data */
342 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
343 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
344 __qlcnic_83xx_process_aen(adapter);
345 goto poll;
346 }
347 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
348 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
349 opcode = QLCNIC_MBX_RSP(fw_data);
350
351 switch (mbx_err_code) {
352 case QLCNIC_MBX_RSP_OK:
353 case QLCNIC_MBX_PORT_RSP_OK:
354 rsp = QLCNIC_RCODE_SUCCESS;
355 break;
356 default:
357 if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
358 rsp = qlcnic_83xx_mac_rcode(adapter);
359 if (!rsp)
360 goto out;
361 }
362 dev_err(&adapter->pdev->dev,
363 "MBX command 0x%x failed with err:0x%x\n",
364 opcode, mbx_err_code);
365 rsp = mbx_err_code;
366 break;
367 }
368 goto out;
369 } 318 }
370 319
371 dev_err(&adapter->pdev->dev, "MBX command 0x%x timed out\n", 320 return cmd.rsp_opcode;
372 QLCNIC_MBX_RSP(mbx_cmd));
373 rsp = QLCNIC_RCODE_TIMEOUT;
374out:
375 /* clear fw mbx control register */
376 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
377 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
378 return rsp;
379} 321}
380 322
381static void qlcnic_sriov_vf_cfg_buff_desc(struct qlcnic_adapter *adapter) 323static void qlcnic_sriov_vf_cfg_buff_desc(struct qlcnic_adapter *adapter)
@@ -522,8 +464,8 @@ static int qlcnic_sriov_get_vf_acl(struct qlcnic_adapter *adapter)
522 464
523static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter) 465static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
524{ 466{
525 struct qlcnic_info nic_info;
526 struct qlcnic_hardware_context *ahw = adapter->ahw; 467 struct qlcnic_hardware_context *ahw = adapter->ahw;
468 struct qlcnic_info nic_info;
527 int err; 469 int err;
528 470
529 err = qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, 0); 471 err = qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, 0);
@@ -637,8 +579,6 @@ int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac)
637 struct qlcnic_hardware_context *ahw = adapter->ahw; 579 struct qlcnic_hardware_context *ahw = adapter->ahw;
638 int err; 580 int err;
639 581
640 spin_lock_init(&ahw->mbx_lock);
641 set_bit(QLC_83XX_MBX_READY, &ahw->idc.status);
642 set_bit(QLC_83XX_MODULE_LOADED, &ahw->idc.status); 582 set_bit(QLC_83XX_MODULE_LOADED, &ahw->idc.status);
643 ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY; 583 ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
644 ahw->reset_context = 0; 584 ahw->reset_context = 0;
@@ -1083,6 +1023,7 @@ static void qlcnic_sriov_process_bc_cmd(struct work_struct *work)
1083 if (test_bit(QLC_BC_VF_FLR, &vf->state)) 1023 if (test_bit(QLC_BC_VF_FLR, &vf->state))
1084 return; 1024 return;
1085 1025
1026 memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));
1086 trans = list_first_entry(&vf->rcv_act.wait_list, 1027 trans = list_first_entry(&vf->rcv_act.wait_list,
1087 struct qlcnic_bc_trans, list); 1028 struct qlcnic_bc_trans, list);
1088 adapter = vf->adapter; 1029 adapter = vf->adapter;
@@ -1232,6 +1173,7 @@ static void qlcnic_sriov_handle_bc_cmd(struct qlcnic_sriov *sriov,
1232 return; 1173 return;
1233 } 1174 }
1234 1175
1176 memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));
1235 cmd_op = hdr->cmd_op; 1177 cmd_op = hdr->cmd_op;
1236 if (qlcnic_sriov_alloc_bc_trans(&trans)) 1178 if (qlcnic_sriov_alloc_bc_trans(&trans))
1237 return; 1179 return;
@@ -1357,7 +1299,7 @@ int qlcnic_sriov_cfg_bc_intr(struct qlcnic_adapter *adapter, u8 enable)
1357 if (enable) 1299 if (enable)
1358 cmd.req.arg[1] = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7); 1300 cmd.req.arg[1] = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7);
1359 1301
1360 err = qlcnic_83xx_mbx_op(adapter, &cmd); 1302 err = qlcnic_83xx_issue_cmd(adapter, &cmd);
1361 1303
1362 if (err != QLCNIC_RCODE_SUCCESS) { 1304 if (err != QLCNIC_RCODE_SUCCESS) {
1363 dev_err(&adapter->pdev->dev, 1305 dev_err(&adapter->pdev->dev,
@@ -1389,10 +1331,11 @@ static int qlcnic_sriov_retry_bc_cmd(struct qlcnic_adapter *adapter,
1389 return -EIO; 1331 return -EIO;
1390} 1332}
1391 1333
1392static int qlcnic_sriov_vf_mbx_op(struct qlcnic_adapter *adapter, 1334static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,
1393 struct qlcnic_cmd_args *cmd) 1335 struct qlcnic_cmd_args *cmd)
1394{ 1336{
1395 struct qlcnic_hardware_context *ahw = adapter->ahw; 1337 struct qlcnic_hardware_context *ahw = adapter->ahw;
1338 struct qlcnic_mailbox *mbx = ahw->mailbox;
1396 struct device *dev = &adapter->pdev->dev; 1339 struct device *dev = &adapter->pdev->dev;
1397 struct qlcnic_bc_trans *trans; 1340 struct qlcnic_bc_trans *trans;
1398 int err; 1341 int err;
@@ -1409,7 +1352,7 @@ static int qlcnic_sriov_vf_mbx_op(struct qlcnic_adapter *adapter,
1409 goto cleanup_transaction; 1352 goto cleanup_transaction;
1410 1353
1411retry: 1354retry:
1412 if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) { 1355 if (!test_bit(QLC_83XX_MBX_READY, &mbx->status)) {
1413 rsp = -EIO; 1356 rsp = -EIO;
1414 QLCDB(adapter, DRV, "MBX not Ready!(cmd 0x%x) for VF 0x%x\n", 1357 QLCDB(adapter, DRV, "MBX not Ready!(cmd 0x%x) for VF 0x%x\n",
1415 QLCNIC_MBX_RSP(cmd->req.arg[0]), func); 1358 QLCNIC_MBX_RSP(cmd->req.arg[0]), func);
@@ -1452,7 +1395,7 @@ err_out:
1452 if (rsp == QLCNIC_RCODE_TIMEOUT) { 1395 if (rsp == QLCNIC_RCODE_TIMEOUT) {
1453 ahw->reset_context = 1; 1396 ahw->reset_context = 1;
1454 adapter->need_fw_reset = 1; 1397 adapter->need_fw_reset = 1;
1455 clear_bit(QLC_83XX_MBX_READY, &ahw->idc.status); 1398 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
1456 } 1399 }
1457 1400
1458cleanup_transaction: 1401cleanup_transaction:
@@ -1612,7 +1555,7 @@ static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter)
1612 int err; 1555 int err;
1613 1556
1614 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status); 1557 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
1615 qlcnic_83xx_enable_mbx_intrpt(adapter); 1558 qlcnic_83xx_enable_mbx_interrupt(adapter);
1616 1559
1617 err = qlcnic_sriov_cfg_bc_intr(adapter, 1); 1560 err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
1618 if (err) 1561 if (err)
@@ -1655,8 +1598,10 @@ static void qlcnic_sriov_vf_detach(struct qlcnic_adapter *adapter)
1655 struct net_device *netdev = adapter->netdev; 1598 struct net_device *netdev = adapter->netdev;
1656 u8 i, max_ints = ahw->num_msix - 1; 1599 u8 i, max_ints = ahw->num_msix - 1;
1657 1600
1658 qlcnic_83xx_disable_mbx_intr(adapter);
1659 netif_device_detach(netdev); 1601 netif_device_detach(netdev);
1602 qlcnic_83xx_detach_mailbox_work(adapter);
1603 qlcnic_83xx_disable_mbx_intr(adapter);
1604
1660 if (netif_running(netdev)) 1605 if (netif_running(netdev))
1661 qlcnic_down(adapter, netdev); 1606 qlcnic_down(adapter, netdev);
1662 1607
@@ -1700,6 +1645,7 @@ static int qlcnic_sriov_vf_handle_dev_ready(struct qlcnic_adapter *adapter)
1700static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter) 1645static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
1701{ 1646{
1702 struct qlcnic_hardware_context *ahw = adapter->ahw; 1647 struct qlcnic_hardware_context *ahw = adapter->ahw;
1648 struct qlcnic_mailbox *mbx = ahw->mailbox;
1703 struct device *dev = &adapter->pdev->dev; 1649 struct device *dev = &adapter->pdev->dev;
1704 struct qlc_83xx_idc *idc = &ahw->idc; 1650 struct qlc_83xx_idc *idc = &ahw->idc;
1705 u8 func = ahw->pci_func; 1651 u8 func = ahw->pci_func;
@@ -1710,7 +1656,7 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
1710 /* Skip the context reset and check if FW is hung */ 1656 /* Skip the context reset and check if FW is hung */
1711 if (adapter->reset_ctx_cnt < 3) { 1657 if (adapter->reset_ctx_cnt < 3) {
1712 adapter->need_fw_reset = 1; 1658 adapter->need_fw_reset = 1;
1713 clear_bit(QLC_83XX_MBX_READY, &idc->status); 1659 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
1714 dev_info(dev, 1660 dev_info(dev,
1715 "Resetting context, wait here to check if FW is in failed state\n"); 1661 "Resetting context, wait here to check if FW is in failed state\n");
1716 return 0; 1662 return 0;
@@ -1735,7 +1681,7 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
1735 __func__, adapter->reset_ctx_cnt, func); 1681 __func__, adapter->reset_ctx_cnt, func);
1736 set_bit(__QLCNIC_RESETTING, &adapter->state); 1682 set_bit(__QLCNIC_RESETTING, &adapter->state);
1737 adapter->need_fw_reset = 1; 1683 adapter->need_fw_reset = 1;
1738 clear_bit(QLC_83XX_MBX_READY, &idc->status); 1684 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
1739 qlcnic_sriov_vf_detach(adapter); 1685 qlcnic_sriov_vf_detach(adapter);
1740 adapter->need_fw_reset = 0; 1686 adapter->need_fw_reset = 0;
1741 1687
@@ -1785,6 +1731,7 @@ static int qlcnic_sriov_vf_idc_failed_state(struct qlcnic_adapter *adapter)
1785static int 1731static int
1786qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter) 1732qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter)
1787{ 1733{
1734 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
1788 struct qlc_83xx_idc *idc = &adapter->ahw->idc; 1735 struct qlc_83xx_idc *idc = &adapter->ahw->idc;
1789 1736
1790 dev_info(&adapter->pdev->dev, "Device is in quiescent state\n"); 1737 dev_info(&adapter->pdev->dev, "Device is in quiescent state\n");
@@ -1792,7 +1739,7 @@ qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter)
1792 set_bit(__QLCNIC_RESETTING, &adapter->state); 1739 set_bit(__QLCNIC_RESETTING, &adapter->state);
1793 adapter->tx_timeo_cnt = 0; 1740 adapter->tx_timeo_cnt = 0;
1794 adapter->reset_ctx_cnt = 0; 1741 adapter->reset_ctx_cnt = 0;
1795 clear_bit(QLC_83XX_MBX_READY, &idc->status); 1742 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
1796 qlcnic_sriov_vf_detach(adapter); 1743 qlcnic_sriov_vf_detach(adapter);
1797 } 1744 }
1798 1745
@@ -1801,6 +1748,7 @@ qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter)
1801 1748
1802static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter) 1749static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter)
1803{ 1750{
1751 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
1804 struct qlc_83xx_idc *idc = &adapter->ahw->idc; 1752 struct qlc_83xx_idc *idc = &adapter->ahw->idc;
1805 u8 func = adapter->ahw->pci_func; 1753 u8 func = adapter->ahw->pci_func;
1806 1754
@@ -1810,7 +1758,7 @@ static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter)
1810 set_bit(__QLCNIC_RESETTING, &adapter->state); 1758 set_bit(__QLCNIC_RESETTING, &adapter->state);
1811 adapter->tx_timeo_cnt = 0; 1759 adapter->tx_timeo_cnt = 0;
1812 adapter->reset_ctx_cnt = 0; 1760 adapter->reset_ctx_cnt = 0;
1813 clear_bit(QLC_83XX_MBX_READY, &idc->status); 1761 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
1814 qlcnic_sriov_vf_detach(adapter); 1762 qlcnic_sriov_vf_detach(adapter);
1815 } 1763 }
1816 return 0; 1764 return 0;
@@ -1988,7 +1936,7 @@ int qlcnic_sriov_vf_resume(struct qlcnic_adapter *adapter)
1988 int err; 1936 int err;
1989 1937
1990 set_bit(QLC_83XX_MODULE_LOADED, &idc->status); 1938 set_bit(QLC_83XX_MODULE_LOADED, &idc->status);
1991 qlcnic_83xx_enable_mbx_intrpt(adapter); 1939 qlcnic_83xx_enable_mbx_interrupt(adapter);
1992 err = qlcnic_sriov_cfg_bc_intr(adapter, 1); 1940 err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
1993 if (err) 1941 if (err)
1994 return err; 1942 return err;