diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h index d03a2bda4e68..09f869b5be0c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h @@ -84,6 +84,11 @@ enum iwl_mac_conf_subcmd_ids { * @NAN_ULW_ATTR_NOTIF: &struct iwl_nan_ulw_attr_notif */ NAN_ULW_ATTR_NOTIF = 0xf2, + /** + * @NAN_SCHED_UPDATE_COMPLETED_NOTIF: + * &struct iwl_nan_sched_update_completed_notif + */ + NAN_SCHED_UPDATE_COMPLETED_NOTIF = 0xf3, /** * @NAN_DW_END_NOTIF: &struct iwl_nan_dw_end_notif */ @@ -1421,4 +1426,28 @@ struct iwl_nan_ulw_attr_notif { u8 attr[IWL_NAN_MAX_ENDLESS_ULW_ATTR_LEN]; } __packed; /* NAN_ULW_ATTR_NOTIF_API_S_VER_1 */ +/** + * enum iwl_nan_sched_update_status - NAN schedule update status + * + * @IWL_NAN_SCHED_UPDATE_SUCCESS: schedule update completed successfully + * @IWL_NAN_SCHED_UPDATE_FAILURE: schedule update failed. Currently not expected + * to happen, but reserved for future use. + */ +enum iwl_nan_sched_update_status { + IWL_NAN_SCHED_UPDATE_SUCCESS = 0, + IWL_NAN_SCHED_UPDATE_FAILURE = 1, +}; + +/** + * struct iwl_nan_sched_update_completed_notif - NAN schedule update completed + * + * @status: status of the schedule update operation. See + * &enum iwl_nan_sched_update_status + * @reserved: reserved + */ +struct iwl_nan_sched_update_completed_notif { + u8 status; + u8 reserved[3]; +} __packed; /* NAN_SCHED_UPDATE_COMPLETED_NTF_API_S_VER_1 */ + #endif /* __iwl_fw_api_mac_cfg_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 054bb1134425..0ef7c24831d8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -238,6 +238,7 @@ static const struct iwl_hcmd_names iwl_mld_mac_conf_names[] = { HCMD_NAME(NAN_SCHEDULE_CMD), HCMD_NAME(NAN_PEER_CMD), HCMD_NAME(NAN_ULW_ATTR_NOTIF), + HCMD_NAME(NAN_SCHED_UPDATE_COMPLETED_NOTIF), HCMD_NAME(NAN_DW_END_NOTIF), HCMD_NAME(NAN_JOINED_CLUSTER_NOTIF), HCMD_NAME(MISSED_BEACONS_NOTIF), diff --git a/drivers/net/wireless/intel/iwlwifi/mld/nan.c b/drivers/net/wireless/intel/iwlwifi/mld/nan.c index d13b2374b642..d34a9a2cbeae 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/nan.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/nan.c @@ -689,11 +689,20 @@ void iwl_mld_nan_vif_cfg_changed(struct iwl_mld *mld, switch (version) { case 1: + if (sched_cfg->deferred) { + IWL_ERR(mld, + "NAN: deferred schedule not supported by FW\n"); + return; + } + cmd_size = sizeof(struct iwl_nan_schedule_cmd_v1); break; case 2: cmd_size = sizeof(struct iwl_nan_schedule_cmd); + if (sched_cfg->deferred) + cmd.deferred = 1; + if (sched_cfg->avail_blob_len && !WARN_ON(sched_cfg->avail_blob_len > sizeof(cmd.avail_attr.attr))) { @@ -869,6 +878,40 @@ void iwl_mld_nan_vif_cfg_changed(struct iwl_mld *mld, } } +bool iwl_mld_cancel_nan_sched_update_completed_notif(struct iwl_mld *mld, + struct iwl_rx_packet *pkt, + u32 obj_id) +{ + return true; +} + +void iwl_mld_handle_nan_sched_update_completed_notif(struct iwl_mld *mld, + struct iwl_rx_packet *pkt) +{ + struct iwl_nan_sched_update_completed_notif *notif = (void *)pkt->data; + struct ieee80211_vif *vif = mld->nan_device_vif; + + if (IWL_FW_CHECK(mld, !vif, + "NAN: schedule update completed without NAN vif\n")) + return; + + if (IWL_FW_CHECK(mld, !ieee80211_vif_nan_started(vif), + "NAN: schedule update completed without NAN started\n")) + return; + + /* + * Deferred schedule update should not fail in firmware since all + * channels and links were added. + */ + IWL_FW_CHECK(mld, notif->status != IWL_NAN_SCHED_UPDATE_SUCCESS, + "NAN: deferred schedule update failed\n"); + + if (WARN_ON(!vif->cfg.nan_sched.deferred)) + return; + + ieee80211_nan_sched_update_done(vif); +} + int iwl_mld_mac802111_nan_peer_sched_changed(struct ieee80211_hw *hw, struct ieee80211_sta *sta) { diff --git a/drivers/net/wireless/intel/iwlwifi/mld/nan.h b/drivers/net/wireless/intel/iwlwifi/mld/nan.h index f4e4cd4b4e8d..5411bca52cde 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/nan.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/nan.h @@ -42,6 +42,8 @@ void iwl_mld_handle_nan_ulw_attr_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); +void iwl_mld_handle_nan_sched_update_completed_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); @@ -51,6 +53,9 @@ bool iwl_mld_cancel_nan_ulw_attr_notif(struct iwl_mld *mld, bool iwl_mld_cancel_nan_dw_end_notif(struct iwl_mld *mld, struct iwl_rx_packet *pkt, u32 obj_id); +bool iwl_mld_cancel_nan_sched_update_completed_notif(struct iwl_mld *mld, + struct iwl_rx_packet *pkt, + u32 obj_id); void iwl_mld_nan_vif_cfg_changed(struct iwl_mld *mld, struct ieee80211_vif *vif, u64 changes); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c index a5074bbc7e24..d7383022a0ed 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c @@ -348,6 +348,8 @@ CMD_VERSIONS(beacon_filter_notif, CMD_VER_ENTRY(2, iwl_beacon_filter_notif)) CMD_VERSIONS(nan_cluster_notif, CMD_VER_ENTRY(1, iwl_nan_cluster_notif)) CMD_VERSIONS(nan_ulw_attr_notif, CMD_VER_ENTRY(1, iwl_nan_ulw_attr_notif)) CMD_VERSIONS(nan_dw_end_notif, CMD_VER_ENTRY(1, iwl_nan_dw_end_notif)) +CMD_VERSIONS(nan_sched_update_completed_notif, + CMD_VER_ENTRY(1, iwl_nan_sched_update_completed_notif)) DEFINE_SIMPLE_CANCELLATION(session_prot, iwl_session_prot_notif, mac_link_id) DEFINE_SIMPLE_CANCELLATION(tlc, iwl_tlc_update_notif, sta_id) @@ -468,6 +470,8 @@ const struct iwl_rx_handler iwl_mld_rx_handlers[] = { nan_ulw_attr_notif) RX_HANDLER_OF_NAN(MAC_CONF_GROUP, NAN_DW_END_NOTIF, nan_dw_end_notif) + RX_HANDLER_OF_NAN(MAC_CONF_GROUP, NAN_SCHED_UPDATE_COMPLETED_NOTIF, + nan_sched_update_completed_notif) }; EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_rx_handlers);