[iwm] Sync IWM_MVM_ALIVE waiting and start_fw handling with iwlwifi.

* Use the notification wait API, like it's done in the Linux iwlwifi code,
  to wait for the IWM_MVM_ALIVE notification.

* This also should fix some firmware load interrupt issues, and errors
  in the nic lock using.

Tested:

* (adrian) Intel 7260, STA mode

Obtained from:	dragonflybsd.git a7697ea01c11fd493aec52260a02f31df680eb91
This commit is contained in:
adrian 2017-02-22 02:23:14 +00:00
parent cebadebe7e
commit 36aeb6e0ad
3 changed files with 253 additions and 146 deletions

View File

@ -285,8 +285,14 @@ struct iwm_nvm_section {
uint8_t *data;
};
#define IWM_MVM_UCODE_ALIVE_TIMEOUT hz
#define IWM_MVM_UCODE_CALIB_TIMEOUT (2*hz)
struct iwm_mvm_alive_data {
int valid;
uint32_t scd_base_addr;
};
static int iwm_store_cscheme(struct iwm_softc *, const uint8_t *, size_t);
static int iwm_firmware_store_section(struct iwm_softc *,
enum iwm_ucode_type,
@ -320,7 +326,7 @@ static int iwm_nic_rx_init(struct iwm_softc *);
static int iwm_nic_tx_init(struct iwm_softc *);
static int iwm_nic_init(struct iwm_softc *);
static int iwm_enable_txq(struct iwm_softc *, int, int, int);
static int iwm_post_alive(struct iwm_softc *);
static int iwm_trans_pcie_fw_alive(struct iwm_softc *, uint32_t);
static int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t,
uint16_t, uint8_t *, uint16_t *);
static int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
@ -367,7 +373,7 @@ static int iwm_pcie_load_given_ucode_8000(struct iwm_softc *,
const struct iwm_fw_sects *);
static int iwm_pcie_load_given_ucode(struct iwm_softc *,
const struct iwm_fw_sects *);
static int iwm_start_fw(struct iwm_softc *, enum iwm_ucode_type);
static int iwm_start_fw(struct iwm_softc *, const struct iwm_fw_sects *);
static int iwm_send_tx_ant_cfg(struct iwm_softc *, uint8_t);
static int iwm_send_phy_cfg_cmd(struct iwm_softc *);
static int iwm_mvm_load_ucode_wait_alive(struct iwm_softc *,
@ -1633,20 +1639,33 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
(0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE)
| (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
iwm_nic_unlock(sc);
iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid));
if (!iwm_nic_lock(sc)) {
device_printf(sc->sc_dev,
"%s: cannot enable txq %d\n", __func__, qid);
return EBUSY;
}
iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0);
iwm_nic_unlock(sc);
iwm_write_mem32(sc, sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
iwm_write_mem32(sc, sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
/* Set scheduler window size and frame limit. */
iwm_write_mem32(sc,
sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
sizeof(uint32_t),
((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
if (!iwm_nic_lock(sc)) {
device_printf(sc->sc_dev,
"%s: cannot enable txq %d\n", __func__, qid);
return EBUSY;
}
iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
(1 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
(fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) |
@ -1690,33 +1709,37 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
}
static int
iwm_post_alive(struct iwm_softc *sc)
iwm_trans_pcie_fw_alive(struct iwm_softc *sc, uint32_t scd_base_addr)
{
int nwords;
int error, chnl;
uint32_t base;
int clear_dwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
IWM_SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(uint32_t);
if (!iwm_nic_lock(sc))
return EBUSY;
base = iwm_read_prph(sc, IWM_SCD_SRAM_BASE_ADDR);
if (sc->sched_base != base) {
device_printf(sc->sc_dev,
"%s: sched addr mismatch: alive: 0x%x prph: 0x%x\n",
__func__, sc->sched_base, base);
}
iwm_ict_reset(sc);
/* Clear TX scheduler state in SRAM. */
nwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
IWM_SCD_CONTEXT_MEM_LOWER_BOUND)
/ sizeof(uint32_t);
iwm_nic_unlock(sc);
sc->scd_base_addr = iwm_read_prph(sc, IWM_SCD_SRAM_BASE_ADDR);
if (scd_base_addr != 0 &&
scd_base_addr != sc->scd_base_addr) {
device_printf(sc->sc_dev,
"%s: sched addr mismatch: alive: 0x%x prph: 0x%x\n",
__func__, sc->scd_base_addr, scd_base_addr);
}
/* reset context data, TX status and translation data */
error = iwm_write_mem(sc,
sc->sched_base + IWM_SCD_CONTEXT_MEM_LOWER_BOUND,
NULL, nwords);
sc->scd_base_addr + IWM_SCD_CONTEXT_MEM_LOWER_BOUND,
NULL, clear_dwords);
if (error)
goto out;
return EBUSY;
if (!iwm_nic_lock(sc))
return EBUSY;
/* Set physical address of TX scheduler rings (1KB aligned). */
iwm_write_prph(sc, IWM_SCD_DRAM_BASE_ADDR, sc->sched_dma.paddr >> 10);
@ -1745,14 +1768,14 @@ iwm_post_alive(struct iwm_softc *sc)
IWM_SETBITS(sc, IWM_FH_TX_CHICKEN_BITS_REG,
IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
iwm_nic_unlock(sc);
/* Enable L1-Active */
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) {
iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
}
out:
iwm_nic_unlock(sc);
return error;
}
@ -2589,6 +2612,8 @@ iwm_pcie_load_cpu_sections_8000(struct iwm_softc *sc,
*first_ucode_section = last_read_idx;
iwm_enable_interrupts(sc);
if (iwm_nic_lock(sc)) {
if (cpu == 1)
IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, 0xFFFF);
@ -2681,6 +2706,9 @@ iwm_pcie_load_given_ucode(struct iwm_softc *sc,
return ret;
}
iwm_enable_interrupts(sc);
/* release CPU reset */
IWM_WRITE(sc, IWM_CSR_RESET, 0);
return 0;
@ -2711,59 +2739,56 @@ iwm_pcie_load_given_ucode_8000(struct iwm_softc *sc,
&first_ucode_section);
}
static int
iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
/* XXX Get rid of this definition */
static inline void
iwm_enable_fw_load_int(struct iwm_softc *sc)
{
int error, w;
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
error = iwm_pcie_load_given_ucode_8000(sc,
&sc->sc_fw.fw_sects[ucode_type]);
} else {
error = iwm_pcie_load_given_ucode(sc,
&sc->sc_fw.fw_sects[ucode_type]);
}
if (error)
return error;
/* wait for the firmware to load */
for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++) {
error = msleep(&sc->sc_uc, &sc->sc_mtx, 0, "iwmuc", hz/10);
}
if (error || !sc->sc_uc.uc_ok) {
device_printf(sc->sc_dev, "could not load firmware\n");
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
device_printf(sc->sc_dev, "cpu1 status: 0x%x\n",
iwm_read_prph(sc, IWM_SB_CPU_1_STATUS));
device_printf(sc->sc_dev, "cpu2 status: 0x%x\n",
iwm_read_prph(sc, IWM_SB_CPU_2_STATUS));
}
}
return error;
IWM_DPRINTF(sc, IWM_DEBUG_INTR, "Enabling FW load interrupt\n");
sc->sc_intmask = IWM_CSR_INT_BIT_FH_TX;
IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
}
/* iwlwifi: pcie/trans.c */
/* XXX Add proper rfkill support code */
static int
iwm_start_fw(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
iwm_start_fw(struct iwm_softc *sc,
const struct iwm_fw_sects *fw)
{
int error;
int ret;
IWM_WRITE(sc, IWM_CSR_INT, ~0);
if ((error = iwm_nic_init(sc)) != 0) {
device_printf(sc->sc_dev, "unable to init nic\n");
return error;
/* This may fail if AMT took ownership of the device */
if (iwm_prepare_card_hw(sc)) {
device_printf(sc->sc_dev,
"%s: Exit HW not ready\n", __func__);
ret = EIO;
goto out;
}
IWM_WRITE(sc, IWM_CSR_INT, 0xFFFFFFFF);
iwm_disable_interrupts(sc);
/* make sure rfkill handshake bits are cleared */
IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR,
IWM_CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
/* clear (again), then enable host interrupts */
IWM_WRITE(sc, IWM_CSR_INT, ~0);
iwm_enable_interrupts(sc);
IWM_WRITE(sc, IWM_CSR_INT, 0xFFFFFFFF);
ret = iwm_nic_init(sc);
if (ret) {
device_printf(sc->sc_dev, "%s: Unable to init nic\n", __func__);
goto out;
}
/*
* Now, we load the firmware and don't want to be interrupted, even
* by the RF-Kill interrupt (hence mask all the interrupt besides the
* FH_TX interrupt which is needed to load the firmware). If the
* RF-Kill switch is toggled, we will find out after having loaded
* the firmware and return the proper value to the caller.
*/
iwm_enable_fw_load_int(sc);
/* really make sure rfkill handshake bits are cleared */
/* maybe we should write a few times more? just to make sure */
@ -2771,7 +2796,15 @@ iwm_start_fw(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
/* Load the given image to the HW */
return iwm_load_firmware(sc, ucode_type);
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000)
ret = iwm_pcie_load_given_ucode_8000(sc, fw);
else
ret = iwm_pcie_load_given_ucode(sc, fw);
/* XXX re-check RF-Kill state */
out:
return ret;
}
static int
@ -2790,7 +2823,7 @@ static int
iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
{
struct iwm_phy_cfg_cmd phy_cfg_cmd;
enum iwm_ucode_type ucode_type = sc->sc_uc_current;
enum iwm_ucode_type ucode_type = sc->cur_ucode;
/* Set parameters */
phy_cfg_cmd.phy_cfg = htole32(iwm_mvm_get_phy_config(sc));
@ -2805,6 +2838,83 @@ iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
sizeof(phy_cfg_cmd), &phy_cfg_cmd);
}
static int
iwm_alive_fn(struct iwm_softc *sc, struct iwm_rx_packet *pkt, void *data)
{
struct iwm_mvm_alive_data *alive_data = data;
struct iwm_mvm_alive_resp_ver1 *palive1;
struct iwm_mvm_alive_resp_ver2 *palive2;
struct iwm_mvm_alive_resp *palive;
if (iwm_rx_packet_payload_len(pkt) == sizeof(*palive1)) {
palive1 = (void *)pkt->data;
sc->support_umac_log = FALSE;
sc->error_event_table =
le32toh(palive1->error_event_table_ptr);
sc->log_event_table =
le32toh(palive1->log_event_table_ptr);
alive_data->scd_base_addr = le32toh(palive1->scd_base_ptr);
alive_data->valid = le16toh(palive1->status) ==
IWM_ALIVE_STATUS_OK;
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
"Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
le16toh(palive1->status), palive1->ver_type,
palive1->ver_subtype, palive1->flags);
} else if (iwm_rx_packet_payload_len(pkt) == sizeof(*palive2)) {
palive2 = (void *)pkt->data;
sc->error_event_table =
le32toh(palive2->error_event_table_ptr);
sc->log_event_table =
le32toh(palive2->log_event_table_ptr);
alive_data->scd_base_addr = le32toh(palive2->scd_base_ptr);
sc->umac_error_event_table =
le32toh(palive2->error_info_addr);
alive_data->valid = le16toh(palive2->status) ==
IWM_ALIVE_STATUS_OK;
if (sc->umac_error_event_table)
sc->support_umac_log = TRUE;
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
"Alive VER2 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
le16toh(palive2->status), palive2->ver_type,
palive2->ver_subtype, palive2->flags);
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
"UMAC version: Major - 0x%x, Minor - 0x%x\n",
palive2->umac_major, palive2->umac_minor);
} else if (iwm_rx_packet_payload_len(pkt) == sizeof(*palive)) {
palive = (void *)pkt->data;
sc->error_event_table =
le32toh(palive->error_event_table_ptr);
sc->log_event_table =
le32toh(palive->log_event_table_ptr);
alive_data->scd_base_addr = le32toh(palive->scd_base_ptr);
sc->umac_error_event_table =
le32toh(palive->error_info_addr);
alive_data->valid = le16toh(palive->status) ==
IWM_ALIVE_STATUS_OK;
if (sc->umac_error_event_table)
sc->support_umac_log = TRUE;
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
"Alive VER3 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
le16toh(palive->status), palive->ver_type,
palive->ver_subtype, palive->flags);
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
"UMAC version: Major - 0x%x, Minor - 0x%x\n",
le32toh(palive->umac_major),
le32toh(palive->umac_minor));
}
return TRUE;
}
static int
iwm_wait_phy_db_entry(struct iwm_softc *sc,
struct iwm_rx_packet *pkt, void *data)
@ -2831,27 +2941,76 @@ static int
iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
enum iwm_ucode_type ucode_type)
{
enum iwm_ucode_type old_type = sc->sc_uc_current;
struct iwm_notification_wait alive_wait;
struct iwm_mvm_alive_data alive_data;
const struct iwm_fw_sects *fw;
enum iwm_ucode_type old_type = sc->cur_ucode;
int error;
static const uint16_t alive_cmd[] = { IWM_MVM_ALIVE };
if ((error = iwm_read_firmware(sc, ucode_type)) != 0) {
device_printf(sc->sc_dev, "iwm_read_firmware: failed %d\n",
error);
return error;
}
fw = &sc->sc_fw.fw_sects[ucode_type];
sc->cur_ucode = ucode_type;
sc->ucode_loaded = FALSE;
sc->sc_uc_current = ucode_type;
error = iwm_start_fw(sc, ucode_type);
memset(&alive_data, 0, sizeof(alive_data));
iwm_init_notification_wait(sc->sc_notif_wait, &alive_wait,
alive_cmd, nitems(alive_cmd),
iwm_alive_fn, &alive_data);
error = iwm_start_fw(sc, fw);
if (error) {
device_printf(sc->sc_dev, "iwm_start_fw: failed %d\n", error);
sc->sc_uc_current = old_type;
sc->cur_ucode = old_type;
iwm_remove_notification(sc->sc_notif_wait, &alive_wait);
return error;
}
error = iwm_post_alive(sc);
/*
* Some things may run in the background now, but we
* just wait for the ALIVE notification here.
*/
IWM_UNLOCK(sc);
error = iwm_wait_notification(sc->sc_notif_wait, &alive_wait,
IWM_MVM_UCODE_ALIVE_TIMEOUT);
IWM_LOCK(sc);
if (error) {
device_printf(sc->sc_dev, "iwm_fw_alive: failed %d\n", error);
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
device_printf(sc->sc_dev,
"SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
iwm_read_prph(sc, IWM_SB_CPU_1_STATUS),
iwm_read_prph(sc, IWM_SB_CPU_2_STATUS));
}
sc->cur_ucode = old_type;
return error;
}
if (!alive_data.valid) {
device_printf(sc->sc_dev, "%s: Loaded ucode is not valid\n",
__func__);
sc->cur_ucode = old_type;
return EIO;
}
iwm_trans_pcie_fw_alive(sc, alive_data.scd_base_addr);
/*
* configure and operate fw paging mechanism.
* driver configures the paging flow only once, CPU2 paging image
* included in the IWM_UCODE_INIT image.
*/
if (fw->paging_mem_size) {
/* XXX implement FW paging */
device_printf(sc->sc_dev,
"%s: XXX FW paging not implemented yet\n", __func__);
}
if (!error)
sc->ucode_loaded = TRUE;
return error;
}
@ -5201,7 +5360,7 @@ iwm_nic_umac_error(struct iwm_softc *sc)
struct iwm_umac_error_event_table table;
uint32_t base;
base = sc->sc_uc.uc_umac_error_event_table;
base = sc->umac_error_event_table;
if (base < 0x800000) {
device_printf(sc->sc_dev, "Invalid error log pointer 0x%08x\n",
@ -5256,7 +5415,7 @@ iwm_nic_error(struct iwm_softc *sc)
uint32_t base;
device_printf(sc->sc_dev, "dumping device error log\n");
base = sc->sc_uc.uc_error_event_table;
base = sc->umac_error_event_table;
if (base < 0x800000) {
device_printf(sc->sc_dev,
"Invalid error log pointer 0x%08x\n", base);
@ -5318,7 +5477,7 @@ iwm_nic_error(struct iwm_softc *sc)
device_printf(sc->sc_dev, "%08X | timestamp\n", table.u_timestamp);
device_printf(sc->sc_dev, "%08X | flow_handler\n", table.flow_handler);
if (sc->sc_uc.uc_umac_error_event_table)
if (sc->umac_error_event_table)
iwm_nic_umac_error(sc);
}
#endif
@ -5428,57 +5587,8 @@ iwm_notif_intr(struct iwm_softc *sc)
case IWM_MFUART_LOAD_NOTIFICATION:
break;
case IWM_MVM_ALIVE: {
struct iwm_mvm_alive_resp_v1 *resp1;
struct iwm_mvm_alive_resp_v2 *resp2;
struct iwm_mvm_alive_resp_v3 *resp3;
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp1)) {
resp1 = (void *)pkt->data;
sc->sc_uc.uc_error_event_table
= le32toh(resp1->error_event_table_ptr);
sc->sc_uc.uc_log_event_table
= le32toh(resp1->log_event_table_ptr);
sc->sched_base = le32toh(resp1->scd_base_ptr);
if (resp1->status == IWM_ALIVE_STATUS_OK)
sc->sc_uc.uc_ok = 1;
else
sc->sc_uc.uc_ok = 0;
}
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp2)) {
resp2 = (void *)pkt->data;
sc->sc_uc.uc_error_event_table
= le32toh(resp2->error_event_table_ptr);
sc->sc_uc.uc_log_event_table
= le32toh(resp2->log_event_table_ptr);
sc->sched_base = le32toh(resp2->scd_base_ptr);
sc->sc_uc.uc_umac_error_event_table
= le32toh(resp2->error_info_addr);
if (resp2->status == IWM_ALIVE_STATUS_OK)
sc->sc_uc.uc_ok = 1;
else
sc->sc_uc.uc_ok = 0;
}
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp3)) {
resp3 = (void *)pkt->data;
sc->sc_uc.uc_error_event_table
= le32toh(resp3->error_event_table_ptr);
sc->sc_uc.uc_log_event_table
= le32toh(resp3->log_event_table_ptr);
sc->sched_base = le32toh(resp3->scd_base_ptr);
sc->sc_uc.uc_umac_error_event_table
= le32toh(resp3->error_info_addr);
if (resp3->status == IWM_ALIVE_STATUS_OK)
sc->sc_uc.uc_ok = 1;
else
sc->sc_uc.uc_ok = 0;
}
sc->sc_uc.uc_intr = 1;
wakeup(&sc->sc_uc);
break; }
case IWM_MVM_ALIVE:
break;
case IWM_CALIB_RES_NOTIF_PHY_DB:
break;
@ -5730,8 +5840,8 @@ iwm_intr(void *arg)
IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
/* ignored */
handled |= (r1 & (IWM_CSR_INT_BIT_ALIVE /*| IWM_CSR_INT_BIT_SCD*/));
/* Safely ignore these bits for debug checks below */
r1 &= ~(IWM_CSR_INT_BIT_ALIVE | IWM_CSR_INT_BIT_SCD);
if (r1 & IWM_CSR_INT_BIT_SW_ERR) {
int i;

View File

@ -2141,7 +2141,7 @@ enum {
#define IWM_ALIVE_FLG_RFKILL (1 << 0)
struct iwm_mvm_alive_resp_v1 {
struct iwm_mvm_alive_resp_ver1 {
uint16_t status;
uint16_t flags;
uint8_t ucode_minor;
@ -2163,7 +2163,7 @@ struct iwm_mvm_alive_resp_v1 {
uint32_t scd_base_ptr; /* SRAM address for SCD */
} __packed; /* IWM_ALIVE_RES_API_S_VER_1 */
struct iwm_mvm_alive_resp_v2 {
struct iwm_mvm_alive_resp_ver2 {
uint16_t status;
uint16_t flags;
uint8_t ucode_minor;
@ -2185,14 +2185,14 @@ struct iwm_mvm_alive_resp_v2 {
uint32_t scd_base_ptr; /* SRAM address for SCD */
uint32_t st_fwrd_addr; /* pointer to Store and forward */
uint32_t st_fwrd_size;
uint8_t umac_minor; /* UMAC version: minor */
uint8_t umac_major; /* UMAC version: major */
uint16_t umac_id; /* UMAC version: id */
uint32_t error_info_addr; /* SRAM address for UMAC error log */
uint8_t umac_minor; /* UMAC version: minor */
uint8_t umac_major; /* UMAC version: major */
uint16_t umac_id; /* UMAC version: id */
uint32_t error_info_addr; /* SRAM address for UMAC error log */
uint32_t dbg_print_buff_addr;
} __packed; /* ALIVE_RES_API_S_VER_2 */
struct iwm_mvm_alive_resp_v3 {
struct iwm_mvm_alive_resp {
uint16_t status;
uint16_t flags;
uint32_t ucode_minor;
@ -2212,7 +2212,7 @@ struct iwm_mvm_alive_resp_v3 {
uint32_t st_fwrd_size;
uint32_t umac_minor; /* UMAC version: minor */
uint32_t umac_major; /* UMAC version: major */
uint32_t error_info_addr; /* SRAM address for UMAC error log */
uint32_t error_info_addr; /* SRAM address for UMAC error log */
uint32_t dbg_print_buff_addr;
} __packed; /* ALIVE_RES_API_S_VER_3 */

View File

@ -299,15 +299,6 @@ struct iwm_rx_ring {
int cur;
};
struct iwm_ucode_status {
uint32_t uc_error_event_table;
uint32_t uc_umac_error_event_table;
uint32_t uc_log_event_table;
int uc_ok;
int uc_intr;
};
#define IWM_CMD_RESP_MAX PAGE_SIZE
#define IWM_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 500
@ -440,7 +431,7 @@ struct iwm_softc {
/* TX scheduler rings. */
struct iwm_dma_info sched_dma;
uint32_t sched_base;
uint32_t scd_base_addr;
/* TX/RX rings. */
struct iwm_tx_ring txq[IWM_MVM_MAX_QUEUES];
@ -461,8 +452,8 @@ struct iwm_softc {
int sc_fw_chunk_done;
struct iwm_ucode_status sc_uc;
enum iwm_ucode_type sc_uc_current;
enum iwm_ucode_type cur_ucode;
int ucode_loaded;
char sc_fwver[32];
int sc_capaflags;
@ -530,6 +521,12 @@ struct iwm_softc {
struct iwm_notif_wait_data *sc_notif_wait;
int cmd_hold_nic_awake;
/* Firmware status */
uint32_t error_event_table;
uint32_t log_event_table;
uint32_t umac_error_event_table;
int support_umac_log;
};
#define IWM_LOCK_INIT(_sc) \