コード例 #1
0
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;
}
コード例 #2
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;
}
コード例 #3
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;
}
コード例 #4
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;
}