diff options
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 260 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 81 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 18 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 134 |
6 files changed, 232 insertions, 264 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 5a49b64a93b4..cd95442341fd 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
| @@ -466,7 +466,6 @@ struct qlcnic_hardware_context { | |||
| 466 | u32 *ext_reg_tbl; | 466 | u32 *ext_reg_tbl; |
| 467 | u32 mbox_aen[QLC_83XX_MBX_AEN_CNT]; | 467 | u32 mbox_aen[QLC_83XX_MBX_AEN_CNT]; |
| 468 | u32 mbox_reg[4]; | 468 | u32 mbox_reg[4]; |
| 469 | spinlock_t mbx_lock; | ||
| 470 | struct qlcnic_mailbox *mailbox; | 469 | struct qlcnic_mailbox *mailbox; |
| 471 | }; | 470 | }; |
| 472 | 471 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 74c8d84dc43d..1eeeed89ef6f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
| @@ -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 | } |
| @@ -406,22 +410,25 @@ static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx) | |||
| 406 | 410 | ||
| 407 | static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter) | 411 | static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter) |
| 408 | { | 412 | { |
| 409 | u32 resp, event; | 413 | u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED; |
| 414 | struct qlcnic_mailbox *mbx = adapter->ahw->mailbox; | ||
| 410 | unsigned long flags; | 415 | unsigned long flags; |
| 411 | 416 | ||
| 412 | spin_lock_irqsave(&adapter->ahw->mbx_lock, flags); | 417 | spin_lock_irqsave(&mbx->aen_lock, flags); |
| 413 | |||
| 414 | resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL); | 418 | resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL); |
| 415 | if (!(resp & QLCNIC_SET_OWNER)) | 419 | if (!(resp & QLCNIC_SET_OWNER)) |
| 416 | goto out; | 420 | goto out; |
| 417 | 421 | ||
| 418 | event = readl(QLCNIC_MBX_FW(adapter->ahw, 0)); | 422 | event = readl(QLCNIC_MBX_FW(adapter->ahw, 0)); |
| 419 | if (event & QLCNIC_MBX_ASYNC_EVENT) | 423 | if (event & QLCNIC_MBX_ASYNC_EVENT) { |
| 420 | __qlcnic_83xx_process_aen(adapter); | 424 | __qlcnic_83xx_process_aen(adapter); |
| 421 | 425 | } else { | |
| 426 | if (atomic_read(&mbx->rsp_status) != rsp_status) | ||
| 427 | qlcnic_83xx_notify_mbx_response(mbx); | ||
| 428 | } | ||
| 422 | out: | 429 | out: |
| 423 | qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter); | 430 | qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter); |
| 424 | spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags); | 431 | spin_unlock_irqrestore(&mbx->aen_lock, flags); |
| 425 | } | 432 | } |
| 426 | 433 | ||
| 427 | irqreturn_t qlcnic_83xx_intr(int irq, void *data) | 434 | irqreturn_t qlcnic_83xx_intr(int irq, void *data) |
| @@ -694,6 +701,9 @@ static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter, | |||
| 694 | { | 701 | { |
| 695 | int i; | 702 | int i; |
| 696 | 703 | ||
| 704 | if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP) | ||
| 705 | return; | ||
| 706 | |||
| 697 | dev_info(&adapter->pdev->dev, | 707 | dev_info(&adapter->pdev->dev, |
| 698 | "Host MBX regs(%d)\n", cmd->req.num); | 708 | "Host MBX regs(%d)\n", cmd->req.num); |
| 699 | for (i = 0; i < cmd->req.num; i++) { | 709 | for (i = 0; i < cmd->req.num; i++) { |
| @@ -712,120 +722,74 @@ static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter, | |||
| 712 | pr_info("\n"); | 722 | pr_info("\n"); |
| 713 | } | 723 | } |
| 714 | 724 | ||
| 715 | /* Mailbox response for mac rcode */ | 725 | static inline void |
| 716 | 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) | ||
| 717 | { | 728 | { |
| 718 | u32 fw_data; | 729 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
| 719 | u8 mac_cmd_rcode; | 730 | int opcode = LSW(cmd->req.arg[0]); |
| 731 | unsigned long max_loops; | ||
| 720 | 732 | ||
| 721 | fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2)); | 733 | max_loops = cmd->total_cmds * QLC_83XX_MBX_CMD_LOOP; |
| 722 | mac_cmd_rcode = (u8)fw_data; | ||
| 723 | if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE || | ||
| 724 | mac_cmd_rcode == QLC_83XX_MAC_PRESENT || | ||
| 725 | mac_cmd_rcode == QLC_83XX_MAC_ABSENT) | ||
| 726 | return QLCNIC_RCODE_SUCCESS; | ||
| 727 | return 1; | ||
| 728 | } | ||
| 729 | 734 | ||
| 730 | u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter, u32 *wait_time) | 735 | for (; max_loops; max_loops--) { |
| 731 | { | 736 | if (atomic_read(&cmd->rsp_status) == |
| 732 | u32 data; | 737 | QLC_83XX_MBX_RESPONSE_ARRIVED) |
| 733 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 738 | return; |
| 734 | /* wait for mailbox completion */ | 739 | |
| 735 | do { | 740 | udelay(1); |
| 736 | data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL); | 741 | } |
| 737 | if (++(*wait_time) > QLCNIC_MBX_TIMEOUT) { | 742 | |
| 738 | data = QLCNIC_RCODE_TIMEOUT; | 743 | dev_err(&adapter->pdev->dev, |
| 739 | break; | 744 | "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n", |
| 740 | } | 745 | __func__, opcode, cmd->type, ahw->pci_func, ahw->op_mode); |
| 741 | mdelay(1); | 746 | flush_workqueue(ahw->mailbox->work_q); |
| 742 | } while (!data); | 747 | return; |
| 743 | return data; | ||
| 744 | } | 748 | } |
| 745 | 749 | ||
| 746 | int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter, | 750 | int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter, |
| 747 | struct qlcnic_cmd_args *cmd) | 751 | struct qlcnic_cmd_args *cmd) |
| 748 | { | 752 | { |
| 749 | int i; | 753 | struct qlcnic_mailbox *mbx = adapter->ahw->mailbox; |
| 750 | u16 opcode; | ||
| 751 | u8 mbx_err_code; | ||
| 752 | unsigned long flags; | ||
| 753 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 754 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
| 754 | u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, wait_time = 0; | 755 | int cmd_type, err, opcode; |
| 756 | unsigned long timeout; | ||
| 755 | 757 | ||
| 756 | opcode = LSW(cmd->req.arg[0]); | 758 | opcode = LSW(cmd->req.arg[0]); |
| 757 | if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) { | 759 | cmd_type = cmd->type; |
| 758 | dev_info(&adapter->pdev->dev, | 760 | err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout); |
| 759 | "Mailbox cmd attempted, 0x%x\n", opcode); | 761 | if (err) { |
| 760 | dev_info(&adapter->pdev->dev, "Mailbox detached\n"); | 762 | dev_err(&adapter->pdev->dev, |
| 761 | 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; | ||
| 762 | } | 767 | } |
| 763 | 768 | ||
| 764 | spin_lock_irqsave(&adapter->ahw->mbx_lock, flags); | 769 | switch (cmd_type) { |
| 765 | mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); | 770 | case QLC_83XX_MBX_CMD_WAIT: |
| 766 | 771 | if (!wait_for_completion_timeout(&cmd->completion, timeout)) { | |
| 767 | if (mbx_val) { | ||
| 768 | QLCDB(adapter, DRV, | ||
| 769 | "Mailbox cmd attempted, 0x%x\n", opcode); | ||
| 770 | QLCDB(adapter, DRV, | ||
| 771 | "Mailbox not available, 0x%x, collect FW dump\n", | ||
| 772 | mbx_val); | ||
