Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Mar 2018 06:13:01 +0000 (UTC)
From:      Eitan Adler <eadler@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r330183 - stable/11/sys/dev/iwm
Message-ID:  <201803010613.w216D1OZ046756@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: eadler
Date: Thu Mar  1 06:13:01 2018
New Revision: 330183
URL: https://svnweb.freebsd.org/changeset/base/330183

Log:
  MFC r314066:
  
  [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

Modified:
  stable/11/sys/dev/iwm/if_iwm.c
  stable/11/sys/dev/iwm/if_iwmreg.h
  stable/11/sys/dev/iwm/if_iwmvar.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/iwm/if_iwm.c
==============================================================================
--- stable/11/sys/dev/iwm/if_iwm.c	Thu Mar  1 06:01:33 2018	(r330182)
+++ stable/11/sys/dev/iwm/if_iwm.c	Thu Mar  1 06:13:01 2018	(r330183)
@@ -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_s
 					       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 q
 		    (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,34 +1709,38 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int q
 }
 
 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 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,67 +2739,72 @@ 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 */
 	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_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 *sc)
 }
 
 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;
 }
 
@@ -5175,7 +5334,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",
@@ -5230,7 +5389,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);
@@ -5292,7 +5451,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
@@ -5402,58 +5561,9 @@ 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;
+		case IWM_MVM_ALIVE:
+			break;
 
-			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_CALIB_RES_NOTIF_PHY_DB:
 			break;
 
@@ -5704,8 +5814,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: stable/11/sys/dev/iwm/if_iwmreg.h
==============================================================================
--- stable/11/sys/dev/iwm/if_iwmreg.h	Thu Mar  1 06:01:33 2018	(r330182)
+++ stable/11/sys/dev/iwm/if_iwmreg.h	Thu Mar  1 06:13:01 2018	(r330183)
@@ -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: stable/11/sys/dev/iwm/if_iwmvar.h
==============================================================================
--- stable/11/sys/dev/iwm/if_iwmvar.h	Thu Mar  1 06:01:33 2018	(r330182)
+++ stable/11/sys/dev/iwm/if_iwmvar.h	Thu Mar  1 06:13:01 2018	(r330183)
@@ -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
@@ -439,7 +430,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];
@@ -460,8 +451,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;
@@ -529,6 +520,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) \



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803010613.w216D1OZ046756>