svn commit: r313325 - head/sys/dev/iwm
Adrian Chadd
adrian at FreeBSD.org
Mon Feb 6 05:35:12 UTC 2017
Author: adrian
Date: Mon Feb 6 05:35:11 2017
New Revision: 313325
URL: https://svnweb.freebsd.org/changeset/base/313325
Log:
[iwm] Use notification wait API to wait for calibration to complete.
Tested:
* 7260, STA mode (2g, 5g)
Obtained from: DragonflyBSD commit 1e0cf8ec6fcd77978f5336297ece61a415790f84
Modified:
head/sys/dev/iwm/if_iwm.c
head/sys/dev/iwm/if_iwmvar.h
Modified: head/sys/dev/iwm/if_iwm.c
==============================================================================
--- head/sys/dev/iwm/if_iwm.c Mon Feb 6 05:34:47 2017 (r313324)
+++ head/sys/dev/iwm/if_iwm.c Mon Feb 6 05:35:11 2017 (r313325)
@@ -284,6 +284,8 @@ struct iwm_nvm_section {
uint8_t *data;
};
+#define IWM_MVM_UCODE_CALIB_TIMEOUT (2*hz)
+
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,
@@ -2751,6 +2753,28 @@ iwm_send_phy_cfg_cmd(struct iwm_softc *s
}
static int
+iwm_wait_phy_db_entry(struct iwm_softc *sc,
+ struct iwm_rx_packet *pkt, void *data)
+{
+ struct iwm_phy_db *phy_db = data;
+
+ if (pkt->hdr.code != IWM_CALIB_RES_NOTIF_PHY_DB) {
+ if(pkt->hdr.code != IWM_INIT_COMPLETE_NOTIF) {
+ device_printf(sc->sc_dev, "%s: Unexpected cmd: %d\n",
+ __func__, pkt->hdr.code);
+ }
+ return TRUE;
+ }
+
+ if (iwm_phy_db_set_section(phy_db, pkt)) {
+ device_printf(sc->sc_dev,
+ "%s: iwm_phy_db_set_section failed\n", __func__);
+ }
+
+ return FALSE;
+}
+
+static int
iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
enum iwm_ucode_type ucode_type)
{
@@ -2788,7 +2812,12 @@ iwm_mvm_load_ucode_wait_alive(struct iwm
static int
iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
{
- int error;
+ struct iwm_notification_wait calib_wait;
+ static const uint16_t init_complete[] = {
+ IWM_INIT_COMPLETE_NOTIF,
+ IWM_CALIB_RES_NOTIF_PHY_DB
+ };
+ int ret;
/* do not operate with rfkill switch turned on */
if ((sc->sc_flags & IWM_FLAG_RFKILL) && !justnvm) {
@@ -2797,81 +2826,80 @@ iwm_run_init_mvm_ucode(struct iwm_softc
return EPERM;
}
- sc->sc_init_complete = 0;
- if ((error = iwm_mvm_load_ucode_wait_alive(sc,
- IWM_UCODE_INIT)) != 0) {
- device_printf(sc->sc_dev, "failed to load init firmware\n");
- return error;
+ iwm_init_notification_wait(sc->sc_notif_wait,
+ &calib_wait,
+ init_complete,
+ nitems(init_complete),
+ iwm_wait_phy_db_entry,
+ sc->sc_phy_db);
+
+ /* Will also start the device */
+ ret = iwm_mvm_load_ucode_wait_alive(sc, IWM_UCODE_INIT);
+ if (ret) {
+ device_printf(sc->sc_dev, "Failed to start INIT ucode: %d\n",
+ ret);
+ goto error;
}
if (justnvm) {
- if ((error = iwm_nvm_init(sc)) != 0) {
+ /* Read nvm */
+ ret = iwm_nvm_init(sc);
+ if (ret) {
device_printf(sc->sc_dev, "failed to read nvm\n");
- return error;
+ goto error;
}
IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, sc->nvm_data->hw_addr);
-
- return 0;
+ goto error;
}
- if ((error = iwm_send_bt_init_conf(sc)) != 0) {
+ ret = iwm_send_bt_init_conf(sc);
+ if (ret) {
device_printf(sc->sc_dev,
- "failed to send bt coex configuration: %d\n", error);
- return error;
+ "failed to send bt coex configuration: %d\n", ret);
+ goto error;
}
/* Init Smart FIFO. */
- error = iwm_mvm_sf_config(sc, IWM_SF_INIT_OFF);
- if (error != 0)
- return error;
-
-#if 0
- IWM_DPRINTF(sc, IWM_DEBUG_RESET,
- "%s: phy_txant=0x%08x, nvm_valid_tx_ant=0x%02x, valid=0x%02x\n",
- __func__,
- ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_TX_CHAIN)
- >> IWM_FW_PHY_CFG_TX_CHAIN_POS),
- sc->nvm_data->valid_tx_ant,
- iwm_fw_valid_tx_ant(sc));
-#endif
+ ret = iwm_mvm_sf_config(sc, IWM_SF_INIT_OFF);
+ if (ret)
+ goto error;
/* Send TX valid antennas before triggering calibrations */
- error = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc));
- if (error != 0) {
+ ret = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc));
+ if (ret) {
device_printf(sc->sc_dev,
- "failed to send antennas before calibration: %d\n", error);
- return error;
+ "failed to send antennas before calibration: %d\n", ret);
+ goto error;
}
/*
* Send phy configurations command to init uCode
* to start the 16.0 uCode init image internal calibrations.
*/
- if ((error = iwm_send_phy_cfg_cmd(sc)) != 0 ) {
+ ret = iwm_send_phy_cfg_cmd(sc);
+ if (ret) {
device_printf(sc->sc_dev,
- "%s: failed to run internal calibration: %d\n",
- __func__, error);
- return error;
+ "%s: Failed to run INIT calibrations: %d\n",
+ __func__, ret);
+ goto error;
}
/*
* Nothing to do but wait for the init complete notification
- * from the firmware
+ * from the firmware.
*/
- while (!sc->sc_init_complete) {
- error = msleep(&sc->sc_init_complete, &sc->sc_mtx,
- 0, "iwminit", 2*hz);
- if (error) {
- device_printf(sc->sc_dev, "init complete failed: %d\n",
- sc->sc_init_complete);
- break;
- }
- }
+ IWM_UNLOCK(sc);
+ ret = iwm_wait_notification(sc->sc_notif_wait, &calib_wait,
+ IWM_MVM_UCODE_CALIB_TIMEOUT);
+ IWM_LOCK(sc);
- IWM_DPRINTF(sc, IWM_DEBUG_RESET, "init %scomplete\n",
- sc->sc_init_complete ? "" : "not ");
- return error;
+ goto out;
+
+error:
+ iwm_remove_notification(sc->sc_notif_wait, &calib_wait);
+out:
+ return ret;
}
/*
@@ -5387,7 +5415,6 @@ iwm_notif_intr(struct iwm_softc *sc)
break; }
case IWM_CALIB_RES_NOTIF_PHY_DB:
- iwm_phy_db_set_section(sc->sc_phy_db, pkt);
break;
case IWM_STATISTICS_NOTIFICATION: {
@@ -5452,8 +5479,6 @@ iwm_notif_intr(struct iwm_softc *sc)
break;
case IWM_INIT_COMPLETE_NOTIF:
- sc->sc_init_complete = 1;
- wakeup(&sc->sc_init_complete);
break;
case IWM_SCAN_OFFLOAD_COMPLETE: {
Modified: head/sys/dev/iwm/if_iwmvar.h
==============================================================================
--- head/sys/dev/iwm/if_iwmvar.h Mon Feb 6 05:34:47 2017 (r313324)
+++ head/sys/dev/iwm/if_iwmvar.h Mon Feb 6 05:35:11 2017 (r313325)
@@ -452,7 +452,6 @@ struct iwm_softc {
struct iwm_dma_info fw_dma;
int sc_fw_chunk_done;
- int sc_init_complete;
struct iwm_ucode_status sc_uc;
enum iwm_ucode_type sc_uc_current;
More information about the svn-src-all
mailing list