[iwm] Use notification wait API to wait for calibration to complete.
Tested: * 7260, STA mode (2g, 5g) Obtained from: DragonflyBSD commit 1e0cf8ec6fcd77978f5336297ece61a415790f84
This commit is contained in:
parent
6e39c65025
commit
31f7edff40
@ -284,6 +284,8 @@ struct iwm_nvm_section {
|
|||||||
uint8_t *data;
|
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_store_cscheme(struct iwm_softc *, const uint8_t *, size_t);
|
||||||
static int iwm_firmware_store_section(struct iwm_softc *,
|
static int iwm_firmware_store_section(struct iwm_softc *,
|
||||||
enum iwm_ucode_type,
|
enum iwm_ucode_type,
|
||||||
@ -2750,6 +2752,28 @@ iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
|
|||||||
sizeof(phy_cfg_cmd), &phy_cfg_cmd);
|
sizeof(phy_cfg_cmd), &phy_cfg_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
|
iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
|
||||||
enum iwm_ucode_type ucode_type)
|
enum iwm_ucode_type ucode_type)
|
||||||
@ -2788,7 +2812,12 @@ iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
|
|||||||
static int
|
static int
|
||||||
iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
|
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 */
|
/* do not operate with rfkill switch turned on */
|
||||||
if ((sc->sc_flags & IWM_FLAG_RFKILL) && !justnvm) {
|
if ((sc->sc_flags & IWM_FLAG_RFKILL) && !justnvm) {
|
||||||
@ -2797,81 +2826,80 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
|
|||||||
return EPERM;
|
return EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc->sc_init_complete = 0;
|
iwm_init_notification_wait(sc->sc_notif_wait,
|
||||||
if ((error = iwm_mvm_load_ucode_wait_alive(sc,
|
&calib_wait,
|
||||||
IWM_UCODE_INIT)) != 0) {
|
init_complete,
|
||||||
device_printf(sc->sc_dev, "failed to load init firmware\n");
|
nitems(init_complete),
|
||||||
return error;
|
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 (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");
|
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);
|
IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, sc->nvm_data->hw_addr);
|
||||||
|
goto error;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = iwm_send_bt_init_conf(sc)) != 0) {
|
ret = iwm_send_bt_init_conf(sc);
|
||||||
|
if (ret) {
|
||||||
device_printf(sc->sc_dev,
|
device_printf(sc->sc_dev,
|
||||||
"failed to send bt coex configuration: %d\n", error);
|
"failed to send bt coex configuration: %d\n", ret);
|
||||||
return error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init Smart FIFO. */
|
/* Init Smart FIFO. */
|
||||||
error = iwm_mvm_sf_config(sc, IWM_SF_INIT_OFF);
|
ret = iwm_mvm_sf_config(sc, IWM_SF_INIT_OFF);
|
||||||
if (error != 0)
|
if (ret)
|
||||||
return error;
|
goto 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
|
|
||||||
|
|
||||||
/* Send TX valid antennas before triggering calibrations */
|
/* Send TX valid antennas before triggering calibrations */
|
||||||
error = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc));
|
ret = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc));
|
||||||
if (error != 0) {
|
if (ret) {
|
||||||
device_printf(sc->sc_dev,
|
device_printf(sc->sc_dev,
|
||||||
"failed to send antennas before calibration: %d\n", error);
|
"failed to send antennas before calibration: %d\n", ret);
|
||||||
return error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send phy configurations command to init uCode
|
* Send phy configurations command to init uCode
|
||||||
* to start the 16.0 uCode init image internal calibrations.
|
* 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,
|
device_printf(sc->sc_dev,
|
||||||
"%s: failed to run internal calibration: %d\n",
|
"%s: Failed to run INIT calibrations: %d\n",
|
||||||
__func__, error);
|
__func__, ret);
|
||||||
return error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Nothing to do but wait for the init complete notification
|
* Nothing to do but wait for the init complete notification
|
||||||
* from the firmware
|
* from the firmware.
|
||||||
*/
|
*/
|
||||||
while (!sc->sc_init_complete) {
|
IWM_UNLOCK(sc);
|
||||||
error = msleep(&sc->sc_init_complete, &sc->sc_mtx,
|
ret = iwm_wait_notification(sc->sc_notif_wait, &calib_wait,
|
||||||
0, "iwminit", 2*hz);
|
IWM_MVM_UCODE_CALIB_TIMEOUT);
|
||||||
if (error) {
|
IWM_LOCK(sc);
|
||||||
device_printf(sc->sc_dev, "init complete failed: %d\n",
|
|
||||||
sc->sc_init_complete);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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; }
|
break; }
|
||||||
|
|
||||||
case IWM_CALIB_RES_NOTIF_PHY_DB:
|
case IWM_CALIB_RES_NOTIF_PHY_DB:
|
||||||
iwm_phy_db_set_section(sc->sc_phy_db, pkt);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IWM_STATISTICS_NOTIFICATION: {
|
case IWM_STATISTICS_NOTIFICATION: {
|
||||||
@ -5452,8 +5479,6 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IWM_INIT_COMPLETE_NOTIF:
|
case IWM_INIT_COMPLETE_NOTIF:
|
||||||
sc->sc_init_complete = 1;
|
|
||||||
wakeup(&sc->sc_init_complete);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IWM_SCAN_OFFLOAD_COMPLETE: {
|
case IWM_SCAN_OFFLOAD_COMPLETE: {
|
||||||
|
@ -452,7 +452,6 @@ struct iwm_softc {
|
|||||||
struct iwm_dma_info fw_dma;
|
struct iwm_dma_info fw_dma;
|
||||||
|
|
||||||
int sc_fw_chunk_done;
|
int sc_fw_chunk_done;
|
||||||
int sc_init_complete;
|
|
||||||
|
|
||||||
struct iwm_ucode_status sc_uc;
|
struct iwm_ucode_status sc_uc;
|
||||||
enum iwm_ucode_type sc_uc_current;
|
enum iwm_ucode_type sc_uc_current;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user