aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-08-02 02:04:37 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-02 02:04:37 -0400
commitbd3f5433255292d8d5080b532e729a577ec4912c (patch)
tree7014045ce2e42c7582fab7ae09d17d66acbee314
parenta594e4f8c31c400024293b2e97fc7d3faaae74da (diff)
parent375345677c05cf87f1f0ff3d366e3f6000716955 (diff)
Merge branch 'qlcnic'
Himanshu Madhani says: ==================== This series contains following patches o in v2 series, we received feedback on return codes to use standard error codes instead of mixing custom error codes. We have modified patch for loopback diagnostic test to return standard error codes. o rest of the 3 patches in the series are for mailbox refactoring Current driver-firmware mailbox interface was operating in polling mode because of some limitations with the earlier versions of 83xx adapter firmware. These issues are resolved now and we are implementing the mailbox interface in interrupt mode. There are three patches which refactors mailbox handling: * Interrupt mode mailbox implantation. * Replace poll mode mailbox interfaces with interrupt mode interfaces. * Operate mailbox in poll mode when interrupts are not available. changes from v2 -> v3 * Addressed review feedback to use standard return codes for loopback diagnostic test. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-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;