From: stsp Date: Thu, 29 Jul 2021 11:58:35 +0000 (+0000) Subject: Support the new iwx(4) firmware session protection command. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=308c5283d02df88ff51f561370eaae657ce1b0f7;p=openbsd Support the new iwx(4) firmware session protection command. Required for having associations succeed with new firmware. ok kevlo@ --- diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c index 46017d37cda..c6f8b3f1357 100644 --- a/sys/dev/pci/if_iwx.c +++ b/sys/dev/pci/if_iwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwx.c,v 1.81 2021/07/29 11:57:59 stsp Exp $ */ +/* $OpenBSD: if_iwx.c,v 1.82 2021/07/29 11:58:35 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -298,6 +298,8 @@ int iwx_nic_rx_init(struct iwx_softc *); int iwx_nic_init(struct iwx_softc *); int iwx_enable_txq(struct iwx_softc *, int, int, int, int); void iwx_post_alive(struct iwx_softc *); +int iwx_schedule_session_protection(struct iwx_softc *, struct iwx_node *, + uint32_t); void iwx_protect_session(struct iwx_softc *, struct iwx_node *, uint32_t, uint32_t); void iwx_unprotect_session(struct iwx_softc *, struct iwx_node *); @@ -2597,6 +2599,23 @@ out: return err; } +int +iwx_schedule_session_protection(struct iwx_softc *sc, struct iwx_node *in, + uint32_t duration) +{ + struct iwx_session_prot_cmd cmd = { + .id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, + in->in_color)), + .action = htole32(IWX_FW_CTXT_ACTION_ADD), + .conf_id = htole32(IWX_SESSION_PROTECT_CONF_ASSOC), + .duration_tu = htole32(duration * IEEE80211_DUR_TU), + }; + uint32_t cmd_id; + + cmd_id = iwx_cmd_id(IWX_SESSION_PROTECTION_CMD, IWX_MAC_CONF_GROUP, 0); + return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd); +} + void iwx_protect_session(struct iwx_softc *sc, struct iwx_node *in, uint32_t duration, uint32_t max_delay) @@ -6835,9 +6854,12 @@ iwx_auth(struct iwx_softc *sc) duration = in->in_ni.ni_intval * 2; else duration = IEEE80211_DUR_TU; - iwx_protect_session(sc, in, duration, in->in_ni.ni_intval / 2); + if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_SESSION_PROT_CMD)) + err = iwx_schedule_session_protection(sc, in, duration); + else + iwx_protect_session(sc, in, duration, in->in_ni.ni_intval / 2); - return 0; + return err; rm_sta: if (generation == sc->sc_generation) { @@ -8575,6 +8597,8 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf_list *ml) break; } + case IWX_WIDE_ID(IWX_MAC_CONF_GROUP, + IWX_SESSION_PROTECTION_CMD): case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, IWX_NVM_GET_INFO): case IWX_ADD_STA_KEY: @@ -8674,6 +8698,10 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf_list *ml) break; } + case IWX_WIDE_ID(IWX_MAC_CONF_GROUP, + IWX_SESSION_PROTECTION_NOTIF): + break; + case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_FSEQ_VER_MISMATCH_NOTIFICATION): break; diff --git a/sys/dev/pci/if_iwxreg.h b/sys/dev/pci/if_iwxreg.h index eaaff8ec6fa..0af70424750 100644 --- a/sys/dev/pci/if_iwxreg.h +++ b/sys/dev/pci/if_iwxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwxreg.h,v 1.26 2021/07/29 11:57:59 stsp Exp $ */ +/* $OpenBSD: if_iwxreg.h,v 1.27 2021/07/29 11:58:35 stsp Exp $ */ /*- * Based on BSD-licensed source modules in the Linux iwlwifi driver, @@ -1655,6 +1655,10 @@ struct iwx_tx_queue_cfg_rsp { #define IWX_INIT_EXTENDED_CFG_CMD 0x03 #define IWX_FW_ERROR_RECOVERY_CMD 0x07 +/* MAC_CONF group subcommand IDs */ +#define IWX_SESSION_PROTECTION_CMD 0x05 +#define IWX_SESSION_PROTECTION_NOTIF 0xfb + /* DATA_PATH group subcommand IDs */ #define IWX_DQA_ENABLE_CMD 0x00 #define IWX_TLC_MNG_CONFIG_CMD 0x0f @@ -2785,6 +2789,86 @@ struct iwx_time_event_notif { uint32_t status; } __packed; /* IWX_MAC_TIME_EVENT_NTFY_API_S_VER_1 */ +/** + * enum iwx_session_prot_conf_id - session protection's configurations + * @SESSION_PROTECT_CONF_ASSOC: Start a session protection for association. + * The firmware will allocate two events. + * Valid for BSS_STA and P2P_STA. + * * A rather short event that can't be fragmented and with a very + * high priority. If every goes well (99% of the cases) the + * association should complete within this first event. During + * that event, no other activity will happen in the firmware, + * which is why it can't be too long. + * The length of this event is hard-coded in the firmware: 300TUs. + * * Another event which can be much longer (it's duration is + * configurable by the driver) which has a slightly lower + * priority and that can be fragmented allowing other activities + * to run while this event is running. + * The firmware will automatically remove both events once the driver sets + * the BSS MAC as associated. Neither of the events will be removed + * for the P2P_STA MAC. + * Only the duration is configurable for this protection. + * @SESSION_PROTECT_CONF_GO_CLIENT_ASSOC: not used + * @SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV: Schedule the P2P Device to be in + * listen mode. Will be fragmented. Valid only on the P2P Device MAC. + * Valid only on the P2P Device MAC. The firmware will take into account + * the duration, the interval and the repetition count. + * @SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION: Schedule the P2P Device to be be + * able to run the GO Negotiation. Will not be fragmented and not + * repetitive. Valid only on the P2P Device MAC. Only the duration will + * be taken into account. + * @SESSION_PROTECT_CONF_MAX_ID: not used + */ +enum iwx_session_prot_conf_id { + IWX_SESSION_PROTECT_CONF_ASSOC, + IWX_SESSION_PROTECT_CONF_GO_CLIENT_ASSOC, + IWX_SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV, + IWX_SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION, + IWX_SESSION_PROTECT_CONF_MAX_ID, +}; /* SESSION_PROTECTION_CONF_ID_E_VER_1 */ + +/** + * struct iwx_session_prot_cmd - configure a session protection + * @id_and_color: the id and color of the mac for which this session protection + * is sent + * @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE + * @conf_id: see &enum iwx_mvm_session_prot_conf_id + * @duration_tu: the duration of the whole protection in TUs. + * @repetition_count: not used + * @interval: not used + * + * Note: the session protection will always be scheduled to start as + * early as possible, but the maximum delay is configuration dependent. + * The firmware supports only one concurrent session protection per vif. + * Adding a new session protection will remove any currently running session. + */ +struct iwx_session_prot_cmd { + /* COMMON_INDEX_HDR_API_S_VER_1 hdr */ + uint32_t id_and_color; + uint32_t action; + uint32_t conf_id; + uint32_t duration_tu; + uint32_t repetition_count; + uint32_t interval; +} __packed; /* SESSION_PROTECTION_CMD_API_S_VER_1 */ + +/** + * struct iwx_session_prot_notif - session protection started / ended + * @mac_id: the mac id for which the session protection started / ended + * @status: 1 means success, 0 means failure + * @start: 1 means the session protection started, 0 means it ended + * @conf_id: see &enum iwx_mvm_session_prot_conf_id + * + * Note that any session protection will always get two notifications: start + * and end even the firmware could not schedule it. + */ +struct iwx_session_prot_notif { + uint32_t mac_id; + uint32_t status; + uint32_t start; + uint32_t conf_id; +} __packed; /* SESSION_PROTECTION_NOTIFICATION_API_S_VER_2 */ + /* Bindings and Time Quota */