svn commit: r314066 - head/sys/dev/iwm
Adrian Chadd
adrian at FreeBSD.org
Wed Feb 22 02:23:16 UTC 2017
Author: adrian
Date: Wed Feb 22 02:23:14 2017
New Revision: 314066
URL: https://svnweb.freebsd.org/changeset/base/314066
Log:
[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
Modified:
head/sys/dev/iwm/if_iwm.c
head/sys/dev/iwm/if_iwmreg.h
head/sys/dev/iwm/if_iwmvar.h
Modified: head/sys/dev/iwm/if_iwm.c
==============================================================================
--- head/sys/dev/iwm/if_iwm.c Wed Feb 22 02:18:04 2017 (r314065)
+++ head/sys/dev/iwm/if_iwm.c Wed Feb 22 02:23:14 2017 (r314066)
@@ -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_so
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_800
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
(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
}
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) {
+ iwm_ict_reset(sc);
+
+ 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->sched_base, base);
+ __func__, sc->scd_base_addr, scd_base_addr);
}
- 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);
+ /* 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 i
*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_sof
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 iw
&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;
-
- IWM_WRITE(sc, IWM_CSR_INT, ~0);
+ int ret;
- 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_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));
@@ -2806,6 +2839,83 @@ iwm_send_phy_cfg_cmd(struct iwm_softc *s
}
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;
+
+ 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);
- sc->sc_uc_current = ucode_type;
- error = iwm_start_fw(sc, ucode_type);
+ 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;
Modified: head/sys/dev/iwm/if_iwmreg.h
==============================================================================
--- head/sys/dev/iwm/if_iwmreg.h Wed Feb 22 02:18:04 2017 (r314065)
+++ head/sys/dev/iwm/if_iwmreg.h Wed Feb 22 02:23:14 2017 (r314066)
@@ -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 */
Modified: head/sys/dev/iwm/if_iwmvar.h
==============================================================================
--- head/sys/dev/iwm/if_iwmvar.h Wed Feb 22 02:18:04 2017 (r314065)
+++ head/sys/dev/iwm/if_iwmvar.h Wed Feb 22 02:23:14 2017 (r314066)
@@ -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) \
More information about the svn-src-all
mailing list