int qlcnic_83xx_enable_vnic_mode(struct qlcnic_adapter *adapter, int lock) { if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY; } QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_OPER); if (lock) qlcnic_83xx_unlock_driver(adapter); return 0; }
int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock) { struct qlcnic_hardware_context *ahw = adapter->ahw; if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY; } QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_NON_OPER); ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER; if (lock) qlcnic_83xx_unlock_driver(adapter); return 0; }
int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter) { u8 id; int ret = -EBUSY; u32 data = QLCNIC_MGMT_FUNC; struct qlcnic_hardware_context *ahw = adapter->ahw; if (qlcnic_83xx_lock_driver(adapter)) return ret; id = ahw->pci_func; data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, id)) | QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC, id); QLCWRX(adapter->ahw, QLC_83XX_DRV_OP_MODE, data); qlcnic_83xx_unlock_driver(adapter); return 0; }
static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, u32 *pay, u8 pci_func, u8 size) { u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val, wait_time = 0; struct qlcnic_hardware_context *ahw = adapter->ahw; unsigned long flags; u16 opcode; u8 mbx_err_code; int i, j; opcode = ((struct qlcnic_bc_hdr *)hdr)->cmd_op; if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) { dev_info(&adapter->pdev->dev, "Mailbox cmd attempted, 0x%x\n", opcode); dev_info(&adapter->pdev->dev, "Mailbox detached\n"); return 0; } spin_lock_irqsave(&ahw->mbx_lock, flags); mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); if (mbx_val) { QLCDB(adapter, DRV, "Mailbox cmd attempted, 0x%x\n", opcode); spin_unlock_irqrestore(&ahw->mbx_lock, flags); return QLCNIC_RCODE_TIMEOUT; } /* Fill in mailbox registers */ val = size + (sizeof(struct qlcnic_bc_hdr) / sizeof(u32)); mbx_cmd = 0x31 | (val << 16) | (adapter->ahw->fw_hal_version << 29); writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0)); mbx_cmd = 0x1 | (1 << 4); if (qlcnic_sriov_pf_check(adapter)) mbx_cmd |= (pci_func << 5); writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 1)); for (i = 2, j = 0; j < (sizeof(struct qlcnic_bc_hdr) / sizeof(u32)); i++, j++) { writel(*(hdr++), QLCNIC_MBX_HOST(ahw, i)); } for (j = 0; j < size; j++, i++) writel(*(pay++), QLCNIC_MBX_HOST(ahw, i)); /* Signal FW about the impending command */ QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER); /* Waiting for the mailbox cmd to complete and while waiting here * some AEN might arrive. If more than 5 seconds expire we can * assume something is wrong. */ poll: rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time); if (rsp != QLCNIC_RCODE_TIMEOUT) { /* Get the FW response data */ fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { __qlcnic_83xx_process_aen(adapter); goto poll; } mbx_err_code = QLCNIC_MBX_STATUS(fw_data); rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); opcode = QLCNIC_MBX_RSP(fw_data); switch (mbx_err_code) { case QLCNIC_MBX_RSP_OK: case QLCNIC_MBX_PORT_RSP_OK: rsp = QLCNIC_RCODE_SUCCESS; break; default: if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) { rsp = qlcnic_83xx_mac_rcode(adapter); if (!rsp) goto out; } dev_err(&adapter->pdev->dev, "MBX command 0x%x failed with err:0x%x\n", opcode, mbx_err_code); rsp = mbx_err_code; break; } goto out; } dev_err(&adapter->pdev->dev, "MBX command 0x%x timed out\n", QLCNIC_MBX_RSP(mbx_cmd)); rsp = QLCNIC_RCODE_TIMEOUT; out: /* clear fw mbx control register */ QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER); spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags); return rsp; }