diff options
| author | Kyle Evans <kevans@FreeBSD.org> | 2019-01-24 03:47:47 +0000 |
|---|---|---|
| committer | Kyle Evans <kevans@FreeBSD.org> | 2019-01-24 03:47:47 +0000 |
| commit | df34d80aa79fdebdc42c80a9974ed69ccf20c276 (patch) | |
| tree | 0b786a54b56eeedf2a52fd84eadfbfef8c4dc362 /sys/dev/iwm | |
| parent | 9a949c99e629f4a0e07a28daa137a3bb52fe9ce8 (diff) | |
Notes
Diffstat (limited to 'sys/dev/iwm')
| -rw-r--r-- | sys/dev/iwm/if_iwm.c | 10 | ||||
| -rw-r--r-- | sys/dev/iwm/if_iwm_time_event.c | 75 | ||||
| -rw-r--r-- | sys/dev/iwm/if_iwm_time_event.h | 2 | ||||
| -rw-r--r-- | sys/dev/iwm/if_iwmvar.h | 6 |
4 files changed, 78 insertions, 15 deletions
diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c index c197d991dd37..0a971f60491a 100644 --- a/sys/dev/iwm/if_iwm.c +++ b/sys/dev/iwm/if_iwm.c @@ -5375,15 +5375,9 @@ iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m) break; } - case IWM_TIME_EVENT_NOTIFICATION: { - struct iwm_time_event_notif *notif; - notif = (void *)pkt->data; - - IWM_DPRINTF(sc, IWM_DEBUG_INTR, - "TE notif status = 0x%x action = 0x%x\n", - notif->status, notif->action); + case IWM_TIME_EVENT_NOTIFICATION: + iwm_mvm_rx_time_event_notif(sc, pkt); break; - } /* * Firmware versions 21 and 22 generate some DEBUG_LOG_MSG diff --git a/sys/dev/iwm/if_iwm_time_event.c b/sys/dev/iwm/if_iwm_time_event.c index 340d19d27246..a468b01656cf 100644 --- a/sys/dev/iwm/if_iwm_time_event.c +++ b/sys/dev/iwm/if_iwm_time_event.c @@ -159,12 +159,73 @@ __FBSDID("$FreeBSD$"); #include <dev/iwm/if_iwm_pcie_trans.h> #include <dev/iwm/if_iwm_time_event.h> +#define TU_TO_HZ(tu) (((uint64_t)(tu) * 1024 * hz) / 1000000) + +static void +iwm_mvm_te_clear_data(struct iwm_softc *sc) +{ + sc->sc_time_event_uid = 0; + sc->sc_time_event_duration = 0; + sc->sc_time_event_end_ticks = 0; + sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE; +} + +/* + * Handles a FW notification for an event that is known to the driver. + * + * @mvm: the mvm component + * @te_data: the time event data + * @notif: the notification data corresponding the time event data. + */ +static void +iwm_mvm_te_handle_notif(struct iwm_softc *sc, + struct iwm_time_event_notif *notif) +{ + IWM_DPRINTF(sc, IWM_DEBUG_TE, + "Handle time event notif - UID = 0x%x action %d\n", + le32toh(notif->unique_id), + le32toh(notif->action)); + + if (!le32toh(notif->status)) { + const char *msg; + + if (notif->action & htole32(IWM_TE_V2_NOTIF_HOST_EVENT_START)) + msg = "Time Event start notification failure"; + else + msg = "Time Event end notification failure"; + + IWM_DPRINTF(sc, IWM_DEBUG_TE, "%s\n", msg); + } + + if (le32toh(notif->action) & IWM_TE_V2_NOTIF_HOST_EVENT_END) { + IWM_DPRINTF(sc, IWM_DEBUG_TE, + "TE ended - current time %d, estimated end %d\n", + ticks, sc->sc_time_event_end_ticks); + + iwm_mvm_te_clear_data(sc); + } else if (le32toh(notif->action) & IWM_TE_V2_NOTIF_HOST_EVENT_START) { + sc->sc_time_event_end_ticks = + ticks + TU_TO_HZ(sc->sc_time_event_duration); + } else { + device_printf(sc->sc_dev, "Got TE with unknown action\n"); + } +} + /* - * For the high priority TE use a time event type that has similar priority to - * the FW's action scan priority. + * The Rx handler for time event notifications */ -#define IWM_MVM_ROC_TE_TYPE_NORMAL IWM_TE_P2P_DEVICE_DISCOVERABLE -#define IWM_MVM_ROC_TE_TYPE_MGMT_TX IWM_TE_P2P_CLIENT_ASSOC +void +iwm_mvm_rx_time_event_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt) +{ + struct iwm_time_event_notif *notif = (void *)pkt->data; + + IWM_DPRINTF(sc, IWM_DEBUG_TE, + "Time event notification - UID = 0x%x action %d\n", + le32toh(notif->unique_id), + le32toh(notif->action)); + + iwm_mvm_te_handle_notif(sc, notif); +} static int iwm_mvm_te_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, @@ -241,6 +302,8 @@ iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp, IWM_DPRINTF(sc, IWM_DEBUG_TE, "Add new TE, duration %d TU\n", le32toh(te_cmd->duration)); + sc->sc_time_event_duration = le32toh(te_cmd->duration); + /* * Use a notification wait, which really just processes the * command response and doesn't wait for anything, in order @@ -279,8 +342,6 @@ iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp, return ret; } -#define TU_TO_HZ(tu) (((uint64_t)(tu) * 1024 * hz) / 1000000) - 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) @@ -362,7 +423,7 @@ iwm_mvm_stop_session_protection(struct iwm_softc *sc, struct iwm_vap *ivp) "%s: Removing TE 0x%x\n", __func__, le32toh(time_cmd.id)); if (iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(time_cmd), &time_cmd) == 0) - sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE; + iwm_mvm_te_clear_data(sc); DELAY(100); } diff --git a/sys/dev/iwm/if_iwm_time_event.h b/sys/dev/iwm/if_iwm_time_event.h index 0e6dd8887997..d64da78557ec 100644 --- a/sys/dev/iwm/if_iwm_time_event.h +++ b/sys/dev/iwm/if_iwm_time_event.h @@ -107,6 +107,8 @@ #ifndef __IF_IWM_TIME_EVENT_H__ #define __IF_IWM_TIME_EVENT_H__ +extern void iwm_mvm_rx_time_event_notif(struct iwm_softc *sc, + struct iwm_rx_packet *pkt); extern 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); extern void iwm_mvm_stop_session_protection(struct iwm_softc *sc, diff --git a/sys/dev/iwm/if_iwmvar.h b/sys/dev/iwm/if_iwmvar.h index 536027493a1a..c4ecd46bbab9 100644 --- a/sys/dev/iwm/if_iwmvar.h +++ b/sys/dev/iwm/if_iwmvar.h @@ -566,6 +566,12 @@ struct iwm_softc { /* Unique ID (assigned by the firmware) of the current Time Event. */ uint32_t sc_time_event_uid; + + /* Duration of the Time Event in TU. */ + uint32_t sc_time_event_duration; + + /* Expected end of the Time Event in HZ ticks. */ + int sc_time_event_end_ticks; }; #define IWM_LOCK_INIT(_sc) \ |
