diff options
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 59 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 615 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 27 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 83 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 146 |
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 | ||
473 | struct qlcnic_adapter_stats { | 472 | struct 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 | ||
961 | struct qlcnic_filter { | 954 | struct 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 */ | ||
969 | struct 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 | |||
975 | struct qlcnic_adapter { | 983 | struct 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 | ||
1387 | struct qlcnic_cmd_args { | 1395 | struct 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 | ||
1393 | int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter); | 1412 | int 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 | ||
1622 | struct 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 | |||
1631 | int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *); | ||
1632 | void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *); | ||
1633 | void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx); | ||
1634 | void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx); | ||
1635 | |||
1603 | /* Adapter hardware abstraction */ | 1636 | /* Adapter hardware abstraction */ |
1604 | struct qlcnic_hardware_ops { | 1637 | struct 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 | ||
405 | static 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 | |||
401 | static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter) | 411 | static 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 | } | ||
416 | out: | 429 | out: |
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 | ||
421 | irqreturn_t qlcnic_83xx_intr(int irq, void *data) | 434 | irqreturn_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 | ||
632 | void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter) | 645 | void 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 */ | 725 | static inline void |
710 | u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter) | 726 | qlcnic_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 | ||
724 | u32 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 | ||
740 | int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, | 750 | int 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); | ||
780 | poll: | ||
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; | ||
818 | out: | ||
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 | ||
825 | int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx, | 795 | int 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 | ||
935 | static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter) | 907 | static 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 | ||
953 | static void qlcnic_83xx_mbx_poll_work(struct work_struct *work) | 928 | static 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 | ||
975 | void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter) | 951 | void 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); | ||
1406 | out: | 1391 | out: |
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 | ||
1621 | int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) | 1606 | int 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 | |||
1633 | out: | ||
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, | |||
1951 | int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, | 1946 | int 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); | 1988 | out: |
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, | |||
2093 | irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data) | 2095 | irqreturn_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 | |||
2107 | out: | 2114 | out: |
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 | |||
3456 | void 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 | |||
3462 | void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx) | ||
3463 | { | ||
3464 | destroy_workqueue(mbx->work_q); | ||
3465 | kfree(mbx); | ||
3466 | } | ||
3467 | |||
3468 | static inline void | ||
3469 | qlcnic_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 | |||
3482 | static 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 | |||
3500 | static 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 | |||
3518 | static 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 | |||
3527 | static 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 | |||
3542 | static 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 | |||
3577 | void 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 | |||
3588 | static 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 | |||
3615 | static 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 | |||
3635 | static 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 | |||
3666 | static 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 | |||
3716 | static 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 | |||
3724 | int 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 | ||
459 | enum 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 | |||
465 | enum 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 */ |
453 | enum qlc_83xx_ext_regs { | 474 | enum 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 */ |
500 | int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *); | 521 | int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *); |
501 | int qlcnic_83xx_mbx_op(struct qlcnic_adapter *, struct qlcnic_cmd_args *); | 522 | int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *, struct qlcnic_cmd_args *); |
502 | int qlcnic_83xx_setup_intr(struct qlcnic_adapter *, u8); | 523 | int qlcnic_83xx_setup_intr(struct qlcnic_adapter *, u8); |
503 | void qlcnic_83xx_get_func_no(struct qlcnic_adapter *); | 524 | void qlcnic_83xx_get_func_no(struct qlcnic_adapter *); |
504 | int qlcnic_83xx_cam_lock(struct qlcnic_adapter *); | 525 | int qlcnic_83xx_cam_lock(struct qlcnic_adapter *); |
@@ -551,7 +572,7 @@ void qlcnic_set_npar_data(struct qlcnic_adapter *, const struct qlcnic_info *, | |||
551 | void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *); | 572 | void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *); |
552 | irqreturn_t qlcnic_83xx_handle_aen(int, void *); | 573 | irqreturn_t qlcnic_83xx_handle_aen(int, void *); |
553 | int qlcnic_83xx_get_port_info(struct qlcnic_adapter *); | 574 | int qlcnic_83xx_get_port_info(struct qlcnic_adapter *); |
554 | void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *); | 575 | void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *); |
555 | void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *); | 576 | void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *); |
556 | irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *); | 577 | irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *); |
557 | irqreturn_t qlcnic_83xx_intr(int, void *); | 578 | irqreturn_t qlcnic_83xx_intr(int, void *); |
@@ -623,8 +644,6 @@ int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state); | |||
623 | int qlcnic_83xx_flash_test(struct qlcnic_adapter *); | 644 | int qlcnic_83xx_flash_test(struct qlcnic_adapter *); |
624 | int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *); | 645 | int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *); |
625 | int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *); | 646 | int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *); |
626 | u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *); | ||
627 | u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *); | ||
628 | void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *); | 647 | void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *); |
629 | void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *); | 648 | void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *); |
630 | void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *); | 649 | void 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 | **/ |
811 | static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) | 814 | static 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 | **/ |
883 | static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter) | 889 | static 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) | |||
2110 | int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) | 2119 | int 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; | 2179 | disable_mbx_intr: |
2180 | qlcnic_83xx_free_mbx_intr(adapter); | ||
2181 | |||
2182 | disable_intr: | ||
2183 | qlcnic_teardown_intr(adapter); | ||
2184 | |||
2185 | detach_mbx: | ||
2186 | qlcnic_83xx_detach_mailbox_work(adapter); | ||
2187 | qlcnic_83xx_free_mailbox(ahw->mailbox); | ||
2188 | exit: | ||
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); | |||
33 | static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *); | 33 | static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *); |
34 | static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *); | 34 | static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *); |
35 | static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *); | 35 | static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *); |
36 | static int qlcnic_sriov_vf_mbx_op(struct qlcnic_adapter *, | 36 | static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *, |
37 | struct qlcnic_cmd_args *); | 37 | struct qlcnic_cmd_args *); |
38 | static void qlcnic_sriov_process_bc_cmd(struct work_struct *); | 38 | static 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) | |||
286 | static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, | 286 | static 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, |
338 | poll: | 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; | ||
374 | out: | ||
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 | ||
381 | static void qlcnic_sriov_vf_cfg_buff_desc(struct qlcnic_adapter *adapter) | 323 | static 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 | ||
523 | static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter) | 465 | static 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 | ||
1392 | static int qlcnic_sriov_vf_mbx_op(struct qlcnic_adapter *adapter, | 1334 | static 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 | ||
1411 | retry: | 1354 | retry: |
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 | ||
1458 | cleanup_transaction: | 1401 | cleanup_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) | |||
1700 | static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter) | 1645 | static 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) | |||
1785 | static int | 1731 | static int |
1786 | qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter) | 1732 | qlcnic_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 | ||
1802 | static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter) | 1749 | static 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; |