コード例 #1
0
int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
{
    struct qlcnic_hardware_context *ahw = adapter->ahw;
    struct qlc_83xx_idc *idc = &ahw->idc;
    u32 state;

    state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
    while (state != QLCNIC_DEV_NPAR_OPER && idc->vnic_wait_limit--) {
        msleep(1000);
        state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
    }

    if (!idc->vnic_wait_limit) {
        dev_err(&adapter->pdev->dev,
                "vNIC mode not operational, state check timed out.\n");
        return -EIO;
    }

    return 0;
}
コード例 #2
0
static int qlcnic_sriov_check_dev_ready(struct qlcnic_adapter *adapter)
{
	u32 state;

	do {
		msleep(20);
		if (++adapter->fw_fail_cnt > QLC_BC_CMD_MAX_RETRY_CNT)
			return -EIO;
		state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE);
	} while (state != QLC_83XX_IDC_DEV_READY);

	return 0;
}
コード例 #3
0
/**
 * qlcnic_83xx_vnic_opmode
 *
 * @adapter: adapter structure
 * Identify virtual NIC operational modes.
 *
 * Returns: Success(0) or error code.
 *
 **/
int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
{
    u32 op_mode, priv_level;
    struct qlcnic_hardware_context *ahw = adapter->ahw;
    struct qlcnic_nic_template *nic_ops = adapter->nic_ops;

    qlcnic_get_func_no(adapter);
    op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);

    if (op_mode == QLC_83XX_DEFAULT_OPMODE)
        priv_level = QLCNIC_MGMT_FUNC;
    else
        priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
                     ahw->pci_func);
    switch (priv_level) {
    case QLCNIC_NON_PRIV_FUNC:
        ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
        ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
        nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic;
        break;
    case QLCNIC_PRIV_FUNC:
        ahw->op_mode = QLCNIC_PRIV_FUNC;
        ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry;
        nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic;
        break;
    case QLCNIC_MGMT_FUNC:
        ahw->op_mode = QLCNIC_MGMT_FUNC;
        ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
        nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic;
        break;
    default:
        dev_err(&adapter->pdev->dev, "Invalid Virtual NIC opmode\n");
        return -EIO;
    }

    if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
        adapter->flags |= QLCNIC_ESWITCH_ENABLED;
    else
        adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;

    ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
    ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;

    return 0;
}
コード例 #4
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;
}
コード例 #5
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;
}