示例#1
0
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);
}
示例#2
0
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);
	}
}