/* Execute a single mailbox command. * Caller must hold PROC_ADDR semaphore. */ static int ql_exec_mb_cmd(struct ql_adapter *qdev, struct mbox_params *mbcp) { int i, status; /* * Make sure there's nothing pending. * This shouldn't happen. */ if (ql_read32(qdev, CSR) & CSR_HRI) return -EIO; status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK); if (status) return status; /* * Fill the outbound mailboxes. */ for (i = 0; i < mbcp->in_count; i++) { status = ql_write_mpi_reg(qdev, qdev->mailbox_in + i, mbcp->mbox_in[i]); if (status) goto end; } /* * Wake up the MPI firmware. */ ql_write32(qdev, CSR, CSR_CMD_SET_H2R_INT); end: ql_sem_unlock(qdev, SEM_PROC_REG_MASK); return status; }
int ql_unpause_mpi_risc(struct ql_adapter *qdev) { u32 tmp; /* Un-pause the RISC */ tmp = ql_read32(qdev, CSR); if (!(tmp & CSR_RP)) return -EIO; ql_write32(qdev, CSR, CSR_CMD_CLR_PAUSE); return 0; }
/* Wait for a single mailbox command to complete. * Returns zero on success. */ static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev) { int count = 100; u32 value; do { value = ql_read32(qdev, STS); if (value & STS_PI) return 0; mdelay(UDELAY_DELAY); /* 100ms */ } while (--count); return -ETIMEDOUT; }
/* Wait for a single mailbox command to complete. * Returns zero on success. */ static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev) { int count = 50; /* TODO: arbitrary for now. */ u32 value; do { value = ql_read32(qdev, STS); if (value & STS_PI) return 0; udelay(UDELAY_DELAY); /* 10us */ } while (--count); return -ETIMEDOUT; }
int ql_pause_mpi_risc(struct ql_adapter *qdev) { u32 tmp; int count = UDELAY_COUNT; /* Pause the RISC */ ql_write32(qdev, CSR, CSR_CMD_SET_PAUSE); do { tmp = ql_read32(qdev, CSR); if (tmp & CSR_RP) break; mdelay(UDELAY_DELAY); count--; } while (count); return (count == 0) ? -ETIMEDOUT : 0; }
int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data) { int status; /* wait for reg to come ready */ status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR); if (status) goto exit; /* set up for reg read */ ql_write32(qdev, PROC_ADDR, reg | PROC_ADDR_R); /* wait for reg to come ready */ status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR); if (status) goto exit; /* get the data */ *data = ql_read32(qdev, PROC_DATA); exit: return status; }
int ql_hard_reset_mpi_risc(struct ql_adapter *qdev) { u32 tmp; int count = UDELAY_COUNT; /* Reset the RISC */ ql_write32(qdev, CSR, CSR_CMD_SET_RST); do { tmp = ql_read32(qdev, CSR); if (tmp & CSR_RR) { ql_write32(qdev, CSR, CSR_CMD_CLR_RST); break; } mdelay(UDELAY_DELAY); count--; } while (count); return (count == 0) ? -ETIMEDOUT : 0; }
/* Determine if we are in charge of the firwmare. If * we are the lower of the 2 NIC pcie functions, or if * we are the higher function and the lower function * is not enabled. */ int ql_own_firmware(struct ql_adapter *qdev) { u32 temp; /* If we are the lower of the 2 NIC functions * on the chip the we are responsible for * core dump and firmware reset after an error. */ if (qdev->func < qdev->alt_func) return 1; /* If we are the higher of the 2 NIC functions * on the chip and the lower function is not * enabled, then we are responsible for * core dump and firmware reset after an error. */ temp = ql_read32(qdev, STS); if (!(temp & (1 << (8 + qdev->alt_func)))) return 1; return 0; }