void iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp, uint32_t duration, uint32_t max_delay) { struct iwm_time_event_cmd time_cmd = {}; time_cmd.action = htole32(IWM_FW_CTXT_ACTION_ADD); time_cmd.id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color)); time_cmd.id = htole32(IWM_TE_BSS_STA_AGGRESSIVE_ASSOC); time_cmd.apply_time = htole32(0); time_cmd.max_frags = IWM_TE_V2_FRAG_NONE; time_cmd.max_delay = htole32(max_delay); /* TODO: why do we need to interval = bi if it is not periodic? */ time_cmd.interval = htole32(1); time_cmd.duration = htole32(duration); time_cmd.repeat = 1; time_cmd.policy = htole16(IWM_TE_V2_NOTIF_HOST_EVENT_START | IWM_TE_V2_NOTIF_HOST_EVENT_END | IWM_T2_V2_START_IMMEDIATELY); iwm_mvm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd); }
void iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp, uint32_t duration, uint32_t max_delay, boolean_t wait_for_notif) { const uint16_t te_notif_response[] = { IWM_TIME_EVENT_NOTIFICATION }; struct iwm_notification_wait wait_te_notif; struct iwm_time_event_cmd time_cmd = {}; /* Do nothing if a time event is already scheduled. */ if (sc->sc_flags & IWM_FLAG_TE_ACTIVE) return; time_cmd.action = htole32(IWM_FW_CTXT_ACTION_ADD); time_cmd.id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color)); time_cmd.id = htole32(IWM_TE_BSS_STA_AGGRESSIVE_ASSOC); time_cmd.apply_time = htole32(0); time_cmd.max_frags = IWM_TE_V2_FRAG_NONE; time_cmd.max_delay = htole32(max_delay); /* TODO: why do we need to interval = bi if it is not periodic? */ time_cmd.interval = htole32(1); time_cmd.duration = htole32(duration); time_cmd.repeat = 1; time_cmd.policy = htole16(IWM_TE_V2_NOTIF_HOST_EVENT_START | IWM_TE_V2_NOTIF_HOST_EVENT_END | IWM_T2_V2_START_IMMEDIATELY); if (!wait_for_notif) { iwm_mvm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd); DELAY(100); sc->sc_flags |= IWM_FLAG_TE_ACTIVE; return; } /* * Create notification_wait for the TIME_EVENT_NOTIFICATION to use * right after we send the time event */ iwm_init_notification_wait(sc->sc_notif_wait, &wait_te_notif, te_notif_response, NELEM(te_notif_response), iwm_mvm_te_notif, /*te_data*/NULL); /* If TE was sent OK - wait for the notification that started */ if (iwm_mvm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd)) { IWM_DPRINTF(sc, IWM_DEBUG_TE, "%s: Failed to add TE to protect session\n", __func__); iwm_remove_notification(sc->sc_notif_wait, &wait_te_notif); } else { sc->sc_flags |= IWM_FLAG_TE_ACTIVE; IWM_UNLOCK(sc); if (iwm_wait_notification(sc->sc_notif_wait, &wait_te_notif, TU_TO_HZ(max_delay))) { IWM_DPRINTF(sc, IWM_DEBUG_TE, "%s: Failed to protect session until TE\n", __func__); } IWM_LOCK(sc); } }