Support the new iwx(4) firmware session protection command.
authorstsp <stsp@openbsd.org>
Thu, 29 Jul 2021 11:58:35 +0000 (11:58 +0000)
committerstsp <stsp@openbsd.org>
Thu, 29 Jul 2021 11:58:35 +0000 (11:58 +0000)
Required for having associations succeed with new firmware.

ok kevlo@

sys/dev/pci/if_iwx.c
sys/dev/pci/if_iwxreg.h

index 46017d3..c6f8b3f 100644 (file)
@@ -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 <info@genua.de>
@@ -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;
index eaaff8e..0af7042 100644 (file)
@@ -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 */