val = QLCRDX(adapter->ahw, QLC_83XX_IDC_MIN_VERSION);
val = val & ~(0x3 << (adapter->portnum * 2));
val = val | (QLC_83XX_IDC_MINOR_VERSION << (adapter->portnum * 2));
QLCWRX(adapter->ahw, QLC_83XX_IDC_MIN_VERSION, val);
}
staticint qlcnic_83xx_idc_update_major_version(struct qlcnic_adapter *adapter, int lock)
{
u32 val;
if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_MAJ_VERSION);
val = val & ~0xFF;
val = val | QLC_83XX_IDC_MAJOR_VERSION;
QLCWRX(adapter->ahw, QLC_83XX_IDC_MAJ_VERSION, val);
if (lock)
qlcnic_83xx_unlock_driver(adapter);
return 0;
}
staticint
qlcnic_83xx_idc_update_drv_presence_reg(struct qlcnic_adapter *adapter, int status, int lock)
{
u32 val;
if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_DRV_PRESENCE);
if (status)
val = val | (1 << adapter->portnum); else
val = val & ~(1 << adapter->portnum);
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_MAJ_VERSION);
version = val & 0xFF;
if (version != QLC_83XX_IDC_MAJOR_VERSION) {
dev_info(&adapter->pdev->dev, "%s:mismatch. version 0x%x, expected version 0x%x\n",
__func__, version, QLC_83XX_IDC_MAJOR_VERSION); return -EIO;
}
return 0;
}
staticint qlcnic_83xx_idc_clear_registers(struct qlcnic_adapter *adapter, int lock)
{
u32 val;
if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
QLCWRX(adapter->ahw, QLC_83XX_IDC_DRV_ACK, 0); /* Clear graceful reset bit */
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
val &= ~QLC_83XX_IDC_GRACEFULL_RESET;
QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
if (lock)
qlcnic_83xx_unlock_driver(adapter);
return 0;
}
staticint qlcnic_83xx_idc_update_drv_ack_reg(struct qlcnic_adapter *adapter, int flag, int lock)
{
u32 val;
if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_DRV_ACK); if (flag)
val = val | (1 << adapter->portnum); else
val = val & ~(1 << adapter->portnum);
QLCWRX(adapter->ahw, QLC_83XX_IDC_DRV_ACK, val);
if (lock)
qlcnic_83xx_unlock_driver(adapter);
return 0;
}
staticint qlcnic_83xx_idc_check_timeout(struct qlcnic_adapter *adapter, int time_limit)
{
u64 seconds;
if (netif_running(netdev)) { if (qlcnic_up(adapter, netdev)) goto done;
qlcnic_restore_indev_addr(netdev, NETDEV_UP);
}
done:
netif_device_attach(netdev);
}
staticint qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter, int lock)
{ if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
qlcnic_83xx_idc_clear_registers(adapter, 0);
QLCWRX(adapter->ahw, QLC_83XX_IDC_DEV_STATE, QLC_83XX_IDC_DEV_FAILED); if (lock)
qlcnic_83xx_unlock_driver(adapter);
qlcnic_83xx_idc_log_state_history(adapter);
dev_info(&adapter->pdev->dev, "Device will enter failed state\n");
return 0;
}
staticint qlcnic_83xx_idc_enter_init_state(struct qlcnic_adapter *adapter, int lock)
{ if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
staticint qlcnic_83xx_idc_enter_need_quiesce(struct qlcnic_adapter *adapter, int lock)
{ if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
staticint
qlcnic_83xx_idc_enter_need_reset_state(struct qlcnic_adapter *adapter, int lock)
{ if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
staticint qlcnic_83xx_idc_enter_ready_state(struct qlcnic_adapter *adapter, int lock)
{ if (lock) { if (qlcnic_83xx_lock_driver(adapter)) return -EBUSY;
}
QLCWRX(adapter->ahw, QLC_83XX_IDC_DEV_STATE, QLC_83XX_IDC_DEV_READY); if (lock)
qlcnic_83xx_unlock_driver(adapter);
return 0;
}
/** * qlcnic_83xx_idc_find_reset_owner_id * * @adapter: adapter structure * * NIC gets precedence over ISCSI and ISCSI has precedence over FCOE. * Within the same class, function with lowest PCI ID assumes ownership * * Returns: reset owner id or failure indication (-EIO) *
**/ staticint qlcnic_83xx_idc_find_reset_owner_id(struct qlcnic_adapter *adapter)
{
u32 reg, reg1, reg2, i, j, owner, class;
status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1);
if (status & QLCNIC_RCODE_FATAL_ERROR) {
dev_err(&adapter->pdev->dev, "peg halt status1=0x%x\n", status); if (QLCNIC_FWERROR_CODE(status) == QLCNIC_FWERROR_FAN_FAILURE) {
dev_err(&adapter->pdev->dev, "On board active cooling fan failed. " "Device has been halted.\n");
dev_err(&adapter->pdev->dev, "Replace the adapter.\n"); return -EIO;
}
}
return 0;
}
int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
{ int err;
/** * qlcnic_83xx_idc_ready_state_entry * * @adapter: adapter structure * * Perform ready state initialization, this routine will get invoked only * once from READY state. * * Returns: Error code or Success(0) *
**/ int qlcnic_83xx_idc_ready_state_entry(struct qlcnic_adapter *adapter)
{ struct qlcnic_hardware_context *ahw = adapter->ahw;
if (ahw->idc.prev_state != QLC_83XX_IDC_DEV_READY) {
qlcnic_83xx_idc_update_idc_params(adapter); /* Re-attach the device if required */ if ((ahw->idc.prev_state == QLC_83XX_IDC_DEV_NEED_RESET) ||
(ahw->idc.prev_state == QLC_83XX_IDC_DEV_INIT)) { if (qlcnic_83xx_idc_reattach_driver(adapter)) return -EIO;
}
}
return 0;
}
/** * qlcnic_83xx_idc_vnic_pf_entry * * @adapter: adapter structure * * Ensure vNIC mode privileged function starts only after vNIC mode is * enabled by management function. * If vNIC mode is ready, start initialization. * * Returns: -EIO or 0 *
**/ int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *adapter)
{
u32 state; struct qlcnic_hardware_context *ahw = adapter->ahw;
/* Privileged function waits till mgmt function enables VNIC mode */
state = QLCRDX(adapter->ahw, QLC_83XX_VNIC_STATE); if (state != QLCNIC_DEV_NPAR_OPER) { if (!ahw->idc.vnic_wait_limit--) {
qlcnic_83xx_idc_enter_failed_state(adapter, 1); return -EIO;
}
dev_info(&adapter->pdev->dev, "vNIC mode disabled\n"); return -EIO;
} else { /* Perform one time initialization from ready state */ if (ahw->idc.vnic_state != QLCNIC_DEV_NPAR_OPER) {
qlcnic_83xx_idc_update_idc_params(adapter);
/* If the previous state is UNKNOWN, device will be
already attached properly by Init routine*/ if (ahw->idc.prev_state != QLC_83XX_IDC_DEV_UNKNOWN) { if (qlcnic_83xx_idc_reattach_driver(adapter)) return -EIO;
}
adapter->ahw->idc.vnic_state = QLCNIC_DEV_NPAR_OPER;
dev_info(&adapter->pdev->dev, "vNIC mode enabled\n");
}
}
/** * qlcnic_83xx_idc_cold_state_handler * * @adapter: adapter structure * * If HW is up and running device will enter READY state. * If firmware image from host needs to be loaded, device is * forced to start with the file firmware image. * * Returns: Error code or Success(0) *
**/ staticint qlcnic_83xx_idc_cold_state_handler(struct qlcnic_adapter *adapter)
{
qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 0);
qlcnic_83xx_idc_update_audit_reg(adapter, 1, 0);
/** * qlcnic_83xx_idc_init_state * * @adapter: adapter structure * * Reset owner will restart the device from this state. * Device will enter failed state if it remains * in this state for more than DEV_INIT time limit. * * Returns: Error code or Success(0) *
**/ staticint qlcnic_83xx_idc_init_state(struct qlcnic_adapter *adapter)
{ int timeout, ret = 0;
u32 owner;
timeout = QLC_83XX_IDC_INIT_TIMEOUT_SECS; if (adapter->ahw->idc.prev_state == QLC_83XX_IDC_DEV_NEED_RESET) {
owner = qlcnic_83xx_idc_find_reset_owner_id(adapter); if (adapter->ahw->pci_func == owner)
ret = qlcnic_83xx_idc_restart_hw(adapter, 1);
} else {
ret = qlcnic_83xx_idc_check_timeout(adapter, timeout);
}
return ret;
}
/** * qlcnic_83xx_idc_ready_state * * @adapter: adapter structure * * Perform IDC protocol specicifed actions after monitoring device state and * events. * * Returns: Error code or Success(0) *
**/ staticint qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
{ struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_mailbox *mbx = ahw->mailbox; int ret = 0;
u32 val;
/* Perform NIC configuration based ready state entry actions */ if (ahw->idc.state_entry(adapter)) return -EIO;
if (qlcnic_check_temp(adapter)) { if (ahw->temp == QLCNIC_TEMP_PANIC) {
qlcnic_83xx_idc_check_fan_failure(adapter);
dev_err(&adapter->pdev->dev, "Error: device temperature %d above limits\n",
adapter->ahw->temp);
clear_bit(QLC_83XX_MBX_READY, &mbx->status);
set_bit(__QLCNIC_RESETTING, &adapter->state);
qlcnic_83xx_idc_detach_driver(adapter);
qlcnic_83xx_idc_enter_failed_state(adapter, 1); return -EIO;
}
}
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
ret = qlcnic_83xx_check_heartbeat(adapter); if (ret) {
adapter->flags |= QLCNIC_FW_HANG; if (!(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) {
clear_bit(QLC_83XX_MBX_READY, &mbx->status);
set_bit(__QLCNIC_RESETTING, &adapter->state);
qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
} else {
netdev_info(adapter->netdev, "%s: Auto firmware recovery is disabled\n",
__func__);
qlcnic_83xx_idc_enter_failed_state(adapter, 1);
} return -EIO;
}
if ((val & QLC_83XX_IDC_GRACEFULL_RESET) || ahw->idc.collect_dump) {
clear_bit(QLC_83XX_MBX_READY, &mbx->status);
/* Move to need reset state and prepare for reset */
qlcnic_83xx_idc_enter_need_reset_state(adapter, 1); return ret;
}
/* Move to need quiesce state if requested */ if (adapter->ahw->idc.quiesce_req) {
qlcnic_83xx_idc_enter_need_quiesce(adapter, 1);
qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); return ret;
}
return ret;
}
/** * qlcnic_83xx_idc_need_reset_state * * @adapter: adapter structure * * Device will remain in this state until: * Reset request ACK's are received from all the functions * Wait time exceeds max time limit * * Returns: Error code or Success(0) *
**/ staticint qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter)
{ struct qlcnic_mailbox *mbx = adapter->ahw->mailbox; int ret = 0;
if (adapter->ahw->idc.prev_state != QLC_83XX_IDC_DEV_NEED_RESET) {
qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
set_bit(__QLCNIC_RESETTING, &adapter->state);
clear_bit(QLC_83XX_MBX_READY, &mbx->status); if (adapter->ahw->nic_mode == QLCNIC_VNIC_MODE)
qlcnic_83xx_disable_vnic_mode(adapter, 1);
if (qlcnic_check_diag_status(adapter)) {
dev_info(&adapter->pdev->dev, "%s: Wait for diag completion\n", __func__); return -1;
} else { if (adapter->ahw->idc.delay_reset) {
qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
qlcnic_83xx_idc_detach_driver(adapter);
adapter->ahw->idc.delay_reset = 0;
}
/* Check for ACK from other functions */
ret = qlcnic_83xx_idc_check_reset_ack_reg(adapter); if (ret) {
dev_info(&adapter->pdev->dev, "%s: Waiting for reset ACK\n", __func__); return -1;
}
}
/* Transit to INIT state and restart the HW */
qlcnic_83xx_idc_enter_init_state(adapter, 1);
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL); if (val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) {
owner = qlcnic_83xx_idc_find_reset_owner_id(adapter); if (ahw->pci_func == owner) {
qlcnic_83xx_stop_hw(adapter);
qlcnic_dump_fw(adapter);
}
}
netdev_warn(adapter->netdev, "%s: Reboot will be required to recover the adapter!!\n",
__func__);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
ahw->idc.err_code = -EIO;
ret = qlcnic_issue_cmd(adapter, &cmd); if (ret)
netdev_err(adapter->netdev, "Failed to set VXLAN port %d in adapter\n",
port);
qlcnic_free_mbx_args(&cmd);
return ret;
}
int qlcnic_set_vxlan_parsing(struct qlcnic_adapter *adapter, u16 port)
{ struct qlcnic_cmd_args cmd; int ret = 0;
memset(&cmd, 0, sizeof(cmd));
ret = qlcnic_alloc_mbx_args(&cmd, adapter,
QLCNIC_CMD_SET_INGRESS_ENCAP); if (ret) return ret;
cmd.req.arg[1] = port ? QLCNIC_ENABLE_INGRESS_ENCAP_PARSING :
QLCNIC_DISABLE_INGRESS_ENCAP_PARSING;
ret = qlcnic_issue_cmd(adapter, &cmd); if (ret)
netdev_err(adapter->netdev, "Failed to %s VXLAN parsing for port %d\n",
port ? "enable" : "disable", port); else
netdev_info(adapter->netdev, "%s VXLAN parsing for port %d\n",
port ? "Enabled" : "Disabled", port);
qlcnic_free_mbx_args(&cmd);
return ret;
}
staticvoid qlcnic_83xx_periodic_tasks(struct qlcnic_adapter *adapter)
{ if (adapter->fhash.fnum)
qlcnic_prune_lb_filters(adapter);
}
/** * qlcnic_83xx_idc_poll_dev_state * * @work: kernel work queue structure used to schedule the function * * Poll device state periodically and perform state specific * actions defined by Inter Driver Communication (IDC) protocol. * * Returns: None *
**/ void qlcnic_83xx_idc_poll_dev_state(struct work_struct *work)
{ struct qlcnic_adapter *adapter;
u32 state;
adapter = container_of(work, struct qlcnic_adapter, fw_work.work);
state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE);
switch (adapter->ahw->idc.curr_state) { case QLC_83XX_IDC_DEV_READY:
qlcnic_83xx_idc_ready_state(adapter); break; case QLC_83XX_IDC_DEV_NEED_RESET:
qlcnic_83xx_idc_need_reset_state(adapter); break; case QLC_83XX_IDC_DEV_NEED_QUISCENT:
qlcnic_83xx_idc_need_quiesce_state(adapter); break; case QLC_83XX_IDC_DEV_FAILED:
qlcnic_83xx_idc_failed_state(adapter); return; case QLC_83XX_IDC_DEV_INIT:
qlcnic_83xx_idc_init_state(adapter); break; case QLC_83XX_IDC_DEV_QUISCENT:
qlcnic_83xx_idc_quiesce_state(adapter); break; default:
qlcnic_83xx_idc_unknown_state(adapter); return;
}
adapter->ahw->idc.prev_state = adapter->ahw->idc.curr_state;
qlcnic_83xx_periodic_tasks(adapter);
/* Re-schedule the function */ if (test_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status))
qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
adapter->ahw->idc.delay);
}
/* Check if reset recovery is disabled */ if (!qlcnic_auto_fw_reset) { /* Propagate do not reset request to other functions */
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
val = val | QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY;
QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
}
}
state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE); if (qlcnic_83xx_idc_check_state_validity(adapter, state)) {
qlcnic_83xx_unlock_driver(adapter); return -EIO;
}
if (state != QLC_83XX_IDC_DEV_COLD && qlcnic_load_fw_file) {
QLCWRX(adapter->ahw, QLC_83XX_IDC_DEV_STATE,
QLC_83XX_IDC_DEV_COLD);
state = QLC_83XX_IDC_DEV_COLD;
}
adapter->ahw->idc.curr_state = state; /* First to load function should cold boot the device */ if (state == QLC_83XX_IDC_DEV_COLD)
qlcnic_83xx_idc_cold_state_handler(adapter);
/* Check if reset recovery is enabled */ if (qlcnic_auto_fw_reset) {
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
val = val & ~QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY;
QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
}
qlcnic_83xx_unlock_driver(adapter);
return 0;
}
int qlcnic_83xx_idc_init(struct qlcnic_adapter *adapter)
{ int ret = -EIO;
qlcnic_83xx_setup_idc_parameters(adapter);
if (qlcnic_83xx_get_reset_instruction_template(adapter)) return ret;
if (!qlcnic_83xx_idc_check_driver_presence_reg(adapter)) { if (qlcnic_83xx_idc_first_to_load_function_handler(adapter)) return -EIO;
} else { if (qlcnic_83xx_idc_check_major_version(adapter)) return -EIO;
}
qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
return 0;
}
void qlcnic_83xx_idc_exit(struct qlcnic_adapter *adapter)
{ int id;
u32 val;
while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
usleep_range(10000, 11000);
id = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
id = id & 0xFF;
if (id == adapter->portnum) {
dev_err(&adapter->pdev->dev, "%s: wait for lock recovery.. %d\n", __func__, id);
msleep(20);
id = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
id = id & 0xFF;
}
/* Clear driver presence bit */
val = QLCRDX(adapter->ahw, QLC_83XX_IDC_DRV_PRESENCE);
val = val & ~(1 << adapter->portnum);
QLCWRX(adapter->ahw, QLC_83XX_IDC_DRV_PRESENCE, val);
clear_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
/* FW image in file is in little endian, swap the data to nullify * the effect of writel() operation on big endian platform.
*/ for (i = 0; i < fw->size / sizeof(u32); i++)
temp[i] = __le32_to_cpu(temp_le[i]);
do {
msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS);
heartbeat = QLC_SHARED_REG_RD32(p_dev,
QLCNIC_PEG_ALIVE_COUNTER); if (heartbeat != p_dev->heartbeat) {
ret = QLCNIC_RCODE_SUCCESS; break;
}
} while (--retries);
do {
val = QLC_SHARED_REG_RD32(p_dev, QLCNIC_CMDPEG_STATE); if (val == QLC_83XX_CMDPEG_COMPLETE) return 0;
msleep(QLCNIC_CMDPEG_CHECK_DELAY);
} while (--retries);
if (p_rmw_hdr->index_a) {
value = p_dev->ahw->reset.array[p_rmw_hdr->index_a];
} else {
value = QLCRD32(p_dev, raddr, &err); if (err == -EIO) return;
}
value &= p_rmw_hdr->mask;
value <<= p_rmw_hdr->shl;
value >>= p_rmw_hdr->shr;
value |= p_rmw_hdr->or_value;
value ^= p_rmw_hdr->xor_value;
qlcnic_83xx_wrt_reg_indirect(p_dev, waddr, value);
}
for (i = 0; i < p_hdr->count; i++, entry++) {
qlcnic_83xx_wrt_reg_indirect(p_dev, entry->arg1,
entry->arg2); if (p_hdr->delay)
udelay((u32)(p_hdr->delay));
}
}
/* Read and Write instruction */ staticvoid qlcnic_83xx_read_write_list(struct qlcnic_adapter *p_dev, struct qlc_83xx_entry_hdr *p_hdr)
{ int i; struct qlc_83xx_entry *entry;
for (i = 0; i < p_hdr->count; i++, entry++) {
qlcnic_83xx_read_write_crb_reg(p_dev, entry->arg1,
entry->arg2); if (p_hdr->delay)
udelay((u32)(p_hdr->delay));
}
}
/* Poll HW register command */ staticvoid qlcnic_83xx_poll_list(struct qlcnic_adapter *p_dev, struct qlc_83xx_entry_hdr *p_hdr)
{ long delay; struct qlc_83xx_entry *entry; struct qlc_83xx_poll *poll; int i, err = 0; unsignedlong arg1, arg2;
for (i = 0; i < p_hdr->count; i++, entry++) {
qlcnic_83xx_rmw_crb_reg(p_dev, entry->arg1,
entry->arg2, rmw_hdr); if (p_hdr->delay)
udelay((u32)(p_hdr->delay));
}
}
staticvoid qlcnic_83xx_pause(struct qlc_83xx_entry_hdr *p_hdr)
{ if (p_hdr->delay)
mdelay((u32)((long)p_hdr->delay));
}
/* Read and poll register command */ staticvoid qlcnic_83xx_poll_read_list(struct qlcnic_adapter *p_dev, struct qlc_83xx_entry_hdr *p_hdr)
{ long delay; int index, i, j, err; struct qlc_83xx_quad_entry *entry; struct qlc_83xx_poll *poll; unsignedlong addr;
staticvoid qlcnic_83xx_template_end(struct qlcnic_adapter *p_dev)
{
p_dev->ahw->reset.template_end = 1; if (p_dev->ahw->reset.seq_error == 0)
dev_err(&p_dev->pdev->dev, "HW restart process completed successfully.\n"); else
dev_err(&p_dev->pdev->dev, "HW restart completed with timeout errors.\n");
}
/** * qlcnic_83xx_exec_template_cmd * * @p_dev: adapter structure * @p_buff: Poiter to instruction template * * Template provides instructions to stop, restart and initalize firmware. * These instructions are abstracted as a series of read, write and * poll operations on hardware registers. Register information and operation * specifics are not exposed to the driver. Driver reads the template from * flash and executes the instructions located at pre-defined offsets. * * Returns: None
* */ staticvoid qlcnic_83xx_exec_template_cmd(struct qlcnic_adapter *p_dev, char *p_buff)
{ int index, entries; struct qlc_83xx_entry_hdr *p_hdr; char *entry = p_buff;
ret = request_firmware(&fw_info->fw, fw_info->fw_file_name, dev); if (ret) {
dev_err(dev, "POST firmware can not be loaded, skipping POST\n"); return 0;
}
ret = qlcnic_83xx_copy_fw_file(adapter); if (ret) return ret;
/* eSwitch capability indicates vNIC mode. * vNIC and SRIOV are mutually exclusive operational modes. * If SR-IOV capability is detected, SR-IOV physical function * will get initialized in default mode. * SR-IOV virtual function initialization follows a * different code path and opmode. * SRIOV mode has precedence over vNIC mode.
*/ if (test_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state)) return QLC_83XX_DEFAULT_OPMODE;
if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) return QLCNIC_VNIC_MODE;
return QLC_83XX_DEFAULT_OPMODE;
}
int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
{ struct qlcnic_hardware_context *ahw = adapter->ahw;
u16 max_sds_rings, max_tx_rings; int ret;
ret = qlcnic_83xx_get_nic_configuration(adapter); if (ret == -EIO) return -EIO;
if (ret == QLCNIC_VNIC_MODE) {
ahw->nic_mode = QLCNIC_VNIC_MODE;
if (qlcnic_83xx_config_vnic_opmode(adapter)) return -EIO;
if (IS_QLC_83XX_USED(adapter, presence_mask, audit_mask)) {
status = qlcnic_alloc_mbx_args(&cmd, adapter,
QLCNIC_CMD_STOP_NIC_FUNC); if (status) return;
cmd.req.arg[1] = BIT_31;
status = qlcnic_issue_cmd(adapter, &cmd); if (status)
dev_err(&adapter->pdev->dev, "Failed to clean up the function resources\n");
qlcnic_free_mbx_args(&cmd);
}
}
int qlcnic_83xx_aer_reset(struct qlcnic_adapter *adapter)
{ struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlc_83xx_idc *idc = &ahw->idc; int ret = 0;
u32 owner;
/* Mark the previous IDC state as NEED_RESET so * that state_entry() will perform the reattachment * and bringup the device
*/
idc->prev_state = QLC_83XX_IDC_DEV_NEED_RESET;
owner = qlcnic_83xx_idc_find_reset_owner_id(adapter); if (ahw->pci_func == owner) {
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.52 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.