mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 19:13:03 -04:00
wifi: iwlwifi: mld: add peer schedule support
Add support for NAN peer schedule configuration and update. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Co-developed-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20260510234534.ede42401c3ee.I8e483edd1e917dfa59901b520db595cea28906e3@changeid Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
This commit is contained in:
committed by
Miri Korenblit
parent
03779b6966
commit
ddb509accc
@@ -76,6 +76,10 @@ enum iwl_mac_conf_subcmd_ids {
|
||||
* @NAN_SCHEDULE_CMD: &struct iwl_nan_schedule_cmd
|
||||
*/
|
||||
NAN_SCHEDULE_CMD = 0x13,
|
||||
/**
|
||||
* @NAN_PEER_CMD: &struct iwl_nan_peer_cmd
|
||||
*/
|
||||
NAN_PEER_CMD = 0x14,
|
||||
/**
|
||||
* @NAN_DW_END_NOTIF: &struct iwl_nan_dw_end_notif
|
||||
*/
|
||||
@@ -1268,6 +1272,44 @@ struct iwl_nan_schedule_cmd {
|
||||
} __packed channels[NUM_PHY_CTX];
|
||||
} __packed; /* NAN_SCHEDULE_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_nan_peer_cmd - NAN peer command
|
||||
* @nmi_sta_id: NAN management station ID
|
||||
* @sequence_id: NAN Availability attribute sequence ID
|
||||
* @committed_dw_info: committed DW info from the NAN Device
|
||||
* Capability attribute
|
||||
* @max_channel_switch_time: maximum channel switch time
|
||||
* (in microseconds); 0 means unavailable
|
||||
* @reserved: (reserved)
|
||||
* @per_phy: per-PHY information for this peer, indexed by PHY ID
|
||||
* @per_phy.availability_map: bitmap of which slots this peer
|
||||
* is available in on this PHY. 0 indicates the this per-PHY entry
|
||||
* is unused.
|
||||
* @per_phy.channel_entry: the channel description the peer is using,
|
||||
* used for comparisons in ULW management
|
||||
* @per_phy.link_id: FW link ID, should be a valid id.
|
||||
* @per_phy.map_id: map ID from peer's NAN Availability attributec
|
||||
* @initial_ulw_size: size of the initial ULW blob
|
||||
* @initial_ulw: initial ULW data from the peer
|
||||
*/
|
||||
struct iwl_nan_peer_cmd {
|
||||
u8 nmi_sta_id;
|
||||
u8 sequence_id;
|
||||
__le16 committed_dw_info;
|
||||
__le16 max_channel_switch_time;
|
||||
__le16 reserved;
|
||||
|
||||
struct {
|
||||
__le32 availability_map;
|
||||
u8 channel_entry[6];
|
||||
u8 link_id;
|
||||
u8 map_id;
|
||||
} __packed per_phy[NUM_PHY_CTX];
|
||||
|
||||
__le32 initial_ulw_size;
|
||||
u8 initial_ulw[];
|
||||
} __packed; /* NAN_PEER_SCHEDULE_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_nan_cluster_notif_flags - flags for the cluster notification
|
||||
*
|
||||
|
||||
@@ -2863,4 +2863,5 @@ const struct ieee80211_ops iwl_mld_hw_ops = {
|
||||
.start_nan = iwl_mld_start_nan,
|
||||
.stop_nan = iwl_mld_stop_nan,
|
||||
.nan_change_conf = iwl_mld_nan_change_config,
|
||||
.nan_peer_sched_changed = iwl_mld_mac802111_nan_peer_sched_changed,
|
||||
};
|
||||
|
||||
@@ -237,6 +237,7 @@ static const struct iwl_hcmd_names iwl_mld_mac_conf_names[] = {
|
||||
HCMD_NAME(ROC_CMD),
|
||||
HCMD_NAME(NAN_CFG_CMD),
|
||||
HCMD_NAME(NAN_SCHEDULE_CMD),
|
||||
HCMD_NAME(NAN_PEER_CMD),
|
||||
HCMD_NAME(NAN_DW_END_NOTIF),
|
||||
HCMD_NAME(NAN_JOINED_CLUSTER_NOTIF),
|
||||
HCMD_NAME(MISSED_BEACONS_NOTIF),
|
||||
|
||||
@@ -664,3 +664,87 @@ void iwl_mld_nan_vif_cfg_changed(struct iwl_mld *mld,
|
||||
iwl_mld_rm_vif(mld, vif);
|
||||
}
|
||||
}
|
||||
|
||||
int iwl_mld_mac802111_nan_peer_sched_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
|
||||
struct ieee80211_nan_peer_sched *sched = sta->nan_sched;
|
||||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(mld_sta->vif);
|
||||
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
|
||||
struct iwl_mld_nan_link *nan_link;
|
||||
struct iwl_nan_peer_cmd cmd = {
|
||||
.nmi_sta_id = mld_sta->deflink.fw_id,
|
||||
.sequence_id = sched->seq_id,
|
||||
.committed_dw_info = cpu_to_le16(sched->committed_dw),
|
||||
.max_channel_switch_time = cpu_to_le16(sched->max_chan_switch),
|
||||
.initial_ulw_size = cpu_to_le32(sched->ulw_size),
|
||||
.per_phy[0 ... NUM_PHY_CTX - 1] = {
|
||||
/* unused by FW if availability_map == 0 */
|
||||
.map_id = CFG80211_NAN_INVALID_MAP_ID,
|
||||
.link_id = FW_CTXT_ID_INVALID,
|
||||
},
|
||||
/* .initial_ulw directly provided below by data[1]/len[1] */
|
||||
};
|
||||
struct iwl_host_cmd hcmd = {
|
||||
.id = WIDE_ID(MAC_CONF_GROUP, NAN_PEER_CMD),
|
||||
.data[0] = &cmd,
|
||||
.len[0] = sizeof(cmd),
|
||||
.data[1] = sched->init_ulw,
|
||||
.len[1] = sched->ulw_size,
|
||||
.dataflags[1] = IWL_HCMD_DFL_DUP,
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(sched->maps); i++) {
|
||||
if (sched->maps[i].map_id == CFG80211_NAN_INVALID_MAP_ID)
|
||||
continue;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(sched->maps[i].slots) != 32);
|
||||
for (int slot = 0;
|
||||
slot < ARRAY_SIZE(sched->maps[i].slots);
|
||||
slot++) {
|
||||
struct ieee80211_chanctx_conf *ctx;
|
||||
struct ieee80211_nan_channel *chan;
|
||||
struct iwl_mld_phy *phy;
|
||||
|
||||
chan = sched->maps[i].slots[slot];
|
||||
if (!chan)
|
||||
continue;
|
||||
|
||||
ctx = chan->chanctx_conf;
|
||||
if (!ctx)
|
||||
continue;
|
||||
|
||||
phy = iwl_mld_phy_from_mac80211(ctx);
|
||||
|
||||
for_each_mld_nan_valid_link(mld_vif, nan_link) {
|
||||
if (nan_link->chanctx == ctx) {
|
||||
cmd.per_phy[phy->fw_id].link_id =
|
||||
nan_link->fw_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WARN_ON(cmd.per_phy[phy->fw_id].link_id ==
|
||||
FW_CTXT_ID_INVALID))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* each channel can only appear in one map,
|
||||
* upper layers enforce that
|
||||
*/
|
||||
if (WARN_ON(cmd.per_phy[phy->fw_id].map_id != CFG80211_NAN_INVALID_MAP_ID &&
|
||||
cmd.per_phy[phy->fw_id].map_id != sched->maps[i].map_id))
|
||||
continue;
|
||||
|
||||
cmd.per_phy[phy->fw_id].map_id = sched->maps[i].map_id;
|
||||
memcpy(cmd.per_phy[phy->fw_id].channel_entry,
|
||||
chan->channel_entry,
|
||||
sizeof(cmd.per_phy[phy->fw_id].channel_entry));
|
||||
cmd.per_phy[phy->fw_id].availability_map |=
|
||||
cpu_to_le32(BIT(slot));
|
||||
}
|
||||
}
|
||||
|
||||
return iwl_mld_send_cmd(mld, &hcmd);
|
||||
}
|
||||
|
||||
@@ -50,4 +50,7 @@ void iwl_mld_nan_vif_cfg_changed(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
u64 changes);
|
||||
|
||||
int iwl_mld_mac802111_nan_peer_sched_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta);
|
||||
|
||||
#endif /* __iwl_mld_nan_h__ */
|
||||
|
||||
Reference in New Issue
Block a user