]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: iwlwifi: mld: Declare support for NAN capabilities
authorIlan Peer <ilan.peer@intel.com>
Mon, 10 Nov 2025 16:08:47 +0000 (18:08 +0200)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Wed, 21 Jan 2026 12:23:01 +0000 (14:23 +0200)
And notify cfg80211 about NAN cluster events and DW end events.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20251110180612.eb49cb2172ce.Iaf59884242cb52351e24cb0711875851b5c863f8@changeid
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
drivers/net/wireless/intel/iwlwifi/mld/nan.c
drivers/net/wireless/intel/iwlwifi/mld/nan.h
drivers/net/wireless/intel/iwlwifi/mld/notif.c
drivers/net/wireless/intel/iwlwifi/mld/notif.h

index 357e1e80bdc52b585df0801e52f156cb47933663..9a58f2751d4ef714c579976a65835bb105993824 100644 (file)
@@ -344,6 +344,22 @@ static void iwl_mac_hw_set_wiphy(struct iwl_mld *mld)
                if (mld->nvm_data->bands[NL80211_BAND_5GHZ].n_channels)
                        hw->wiphy->nan_supported_bands |=
                                BIT(NL80211_BAND_5GHZ);
+
+               hw->wiphy->nan_capa.flags = WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC |
+                                           WIPHY_NAN_FLAGS_USERSPACE_DE;
+
+               hw->wiphy->nan_capa.op_mode = NAN_OP_MODE_PHY_MODE_MASK |
+                                             NAN_OP_MODE_80P80MHZ |
+                                             NAN_OP_MODE_160MHZ;
+
+               /* Support 2 antenna's for Tx and Rx */
+               hw->wiphy->nan_capa.n_antennas = 0x22;
+
+               /* Maximal channel switch time is 4 msec */
+               hw->wiphy->nan_capa.max_channel_switch_time = 4;
+               hw->wiphy->nan_capa.dev_capabilities =
+                       NAN_DEV_CAPA_EXT_KEY_ID_SUPPORTED |
+                       NAN_DEV_CAPA_NDPE_SUPPORTED;
        } else {
                wiphy->iface_combinations = iwl_mld_iface_combinations;
                /* Do not include NAN combinations */
index 0bce7a48ab2c6d48fbc933f9e853606193cdb8df..5104ba75b38c1e6d49dcae70fe3d0c6f96a3c734 100644 (file)
@@ -131,6 +131,12 @@ int iwl_mld_stop_nan(struct ieee80211_hw *hw,
        iwl_mld_flush_link_sta_txqs(mld, mld_vif->aux_sta.sta_id);
        iwl_mld_remove_aux_sta(mld, vif);
 
+       /* cancel based on object type being NAN, as the NAN objects do
+        * not have a unique identifier associated with them
+        */
+       iwl_mld_cancel_notifications_of_object(mld,
+                                              IWL_MLD_OBJECT_TYPE_NAN,
+                                              0);
        return 0;
 }
 
@@ -138,10 +144,43 @@ void iwl_mld_handle_nan_cluster_notif(struct iwl_mld *mld,
                                      struct iwl_rx_packet *pkt)
 {
        struct iwl_nan_cluster_notif *notif = (void *)pkt->data;
+       struct wireless_dev *wdev = mld->nan_device_vif ?
+               ieee80211_vif_to_wdev(mld->nan_device_vif) : NULL;
+       bool new_cluster = !!(notif->flags &
+                             IWL_NAN_CLUSTER_NOTIF_FLAG_NEW_CLUSTER);
+       u8 cluster_id[ETH_ALEN] __aligned(2) = {
+               0x50, 0x6f, 0x9a, 0x01, 0x00, 0x00
+       };
+       u16 id = le16_to_cpu(notif->cluster_id);
 
        IWL_DEBUG_INFO(mld,
                       "NAN: cluster event: cluster_id=0x%x, flags=0x%x\n",
-                      le16_to_cpu(notif->cluster_id), notif->flags);
+                      id, notif->flags);
+
+       if (IWL_FW_CHECK(mld, !wdev, "NAN: cluster event without wdev\n"))
+               return;
+
+       if (IWL_FW_CHECK(mld, !ieee80211_vif_nan_started(mld->nan_device_vif),
+                        "NAN: cluster event without NAN started\n"))
+               return;
+
+       *((u16 *)(cluster_id + 4)) = id;
+
+       cfg80211_nan_cluster_joined(wdev, cluster_id, new_cluster, GFP_KERNEL);
+}
+
+bool iwl_mld_cancel_nan_cluster_notif(struct iwl_mld *mld,
+                                     struct iwl_rx_packet *pkt,
+                                     u32 obj_id)
+{
+       return true;
+}
+
+bool iwl_mld_cancel_nan_dw_end_notif(struct iwl_mld *mld,
+                                    struct iwl_rx_packet *pkt,
+                                    u32 obj_id)
+{
+       return true;
 }
 
 void iwl_mld_handle_nan_dw_end_notif(struct iwl_mld *mld,
@@ -151,10 +190,16 @@ void iwl_mld_handle_nan_dw_end_notif(struct iwl_mld *mld,
        struct iwl_mld_vif *mld_vif = mld->nan_device_vif ?
                iwl_mld_vif_from_mac80211(mld->nan_device_vif) :
                NULL;
+       struct wireless_dev *wdev;
+       struct ieee80211_channel *chan;
 
        IWL_INFO(mld, "NAN: DW end: band=%u\n", notif->band);
 
-       if (!mld_vif)
+       if (IWL_FW_CHECK(mld, !mld_vif, "NAN: DW end without mld_vif\n"))
+               return;
+
+       if (IWL_FW_CHECK(mld, !ieee80211_vif_nan_started(mld->nan_device_vif),
+                        "NAN: DW end without NAN started\n"))
                return;
 
        if (WARN_ON(mld_vif->aux_sta.sta_id == IWL_INVALID_STA))
@@ -164,4 +209,26 @@ void iwl_mld_handle_nan_dw_end_notif(struct iwl_mld *mld,
                       mld_vif->aux_sta.sta_id);
 
        iwl_mld_flush_link_sta_txqs(mld, mld_vif->aux_sta.sta_id);
+
+       /* TODO: currently the notification specified the band on which the DW
+        * ended. Need to change that to the actual channel on which the next DW
+        * will be started.
+        */
+       switch (notif->band) {
+       case IWL_NAN_BAND_2GHZ:
+               chan = ieee80211_get_channel(mld->wiphy, 2437);
+               break;
+       case IWL_NAN_BAND_5GHZ:
+               /* TODO: use the actual channel */
+               chan = ieee80211_get_channel(mld->wiphy, 5745);
+               break;
+       default:
+               IWL_FW_CHECK(mld, false,
+                            "NAN: Invalid band %u in DW end notif\n",
+                            notif->band);
+               return;
+       }
+
+       wdev = ieee80211_vif_to_wdev(mld->nan_device_vif);
+       cfg80211_next_nan_dw_notif(wdev, chan, GFP_KERNEL);
 }
index c7b621393655caab339a7af5bbd686dc1095b15c..97607b74a1777c7d256f6fcf07d4c818c88e1c44 100644 (file)
@@ -16,3 +16,9 @@ void iwl_mld_handle_nan_cluster_notif(struct iwl_mld *mld,
                                      struct iwl_rx_packet *pkt);
 void iwl_mld_handle_nan_dw_end_notif(struct iwl_mld *mld,
                                     struct iwl_rx_packet *pkt);
+bool iwl_mld_cancel_nan_cluster_notif(struct iwl_mld *mld,
+                                     struct iwl_rx_packet *pkt,
+                                     u32 obj_id);
+bool iwl_mld_cancel_nan_dw_end_notif(struct iwl_mld *mld,
+                                    struct iwl_rx_packet *pkt,
+                                    u32 obj_id);
index eedb4818c647cd845c61b6b51b66ba831568431c..555542dc5e376ce8a9791803d488dcba7e776039 100644 (file)
@@ -111,6 +111,9 @@ static bool iwl_mld_cancel_##name##_notif(struct iwl_mld *mld,                      \
 #define RX_HANDLER_OF_FTM_REQ(_grp, _cmd, _name)                               \
        RX_HANDLER_OF_OBJ(_grp, _cmd, _name, FTM_REQ)
 
+#define RX_HANDLER_OF_NAN(_grp, _cmd, _name)                           \
+       RX_HANDLER_OF_OBJ(_grp, _cmd, _name, NAN)
+
 static void iwl_mld_handle_mfuart_notif(struct iwl_mld *mld,
                                        struct iwl_rx_packet *pkt)
 {
@@ -461,10 +464,10 @@ const struct iwl_rx_handler iwl_mld_rx_handlers[] = {
                           beacon_filter_notif)
        RX_HANDLER_OF_FTM_REQ(LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF,
                              ftm_resp_notif)
-       RX_HANDLER_NO_OBJECT(MAC_CONF_GROUP, NAN_JOINED_CLUSTER_NOTIF,
-                            nan_cluster_notif, RX_HANDLER_ASYNC)
-       RX_HANDLER_NO_OBJECT(MAC_CONF_GROUP, NAN_DW_END_NOTIF,
-                            nan_dw_end_notif, RX_HANDLER_ASYNC)
+       RX_HANDLER_OF_NAN(MAC_CONF_GROUP, NAN_JOINED_CLUSTER_NOTIF,
+                         nan_cluster_notif)
+       RX_HANDLER_OF_NAN(MAC_CONF_GROUP, NAN_DW_END_NOTIF,
+                         nan_dw_end_notif)
 };
 EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_rx_handlers);
 
index adcdd9dec192d60159bfa89644dd85b664a086f8..373c1a90d98eaa53ad84d9daf2858898fca53ea0 100644 (file)
@@ -25,6 +25,7 @@ enum iwl_mld_object_type {
        IWL_MLD_OBJECT_TYPE_ROC,
        IWL_MLD_OBJECT_TYPE_SCAN,
        IWL_MLD_OBJECT_TYPE_FTM_REQ,
+       IWL_MLD_OBJECT_TYPE_NAN,
 };
 
 void iwl_mld_cancel_notifications_of_object(struct iwl_mld *mld,