Commit 67baf663 authored by Janusz Dziedzic's avatar Janusz Dziedzic Committed by Johannes Berg
Browse files

mac80211: add P2P NoA settings



Add P2P NoA settings for STA mode.

Signed-off-by: default avatarJanusz Dziedzic <janusz.dziedzic@tieto.com>
[fix docs]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 934457ee
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -662,6 +662,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
					   u32 action)
{
	struct iwl_mac_ctx_cmd cmd = {};
	struct ieee80211_p2p_noa_attr *noa = &vif->bss_conf.p2p_noa_attr;

	WARN_ON(vif->type != NL80211_IFTYPE_STATION || !vif->p2p);

@@ -671,7 +672,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
	/* Fill the data specific for station mode */
	iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta);

	cmd.p2p_sta.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
	cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow &
					IEEE80211_P2P_OPPPS_CTWINDOW_MASK);

	return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
}
@@ -892,6 +894,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
				   u32 action)
{
	struct iwl_mac_ctx_cmd cmd = {};
	struct ieee80211_p2p_noa_attr *noa = &vif->bss_conf.p2p_noa_attr;

	WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p);

@@ -901,8 +904,11 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
	/* Fill the data specific for GO mode */
	iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap);

	cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
	cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps);
	cmd.go.ctwin = cpu_to_le32(noa->oppps_ctwindow &
					IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
	cmd.go.opp_ps_enabled =
			cpu_to_le32(!!(noa->oppps_ctwindow &
					IEEE80211_P2P_OPPPS_ENABLE_BIT));

	return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
}
+2 −4
Original line number Diff line number Diff line
@@ -330,8 +330,7 @@ enum ieee80211_rssi_event {
 * @ssid_len: Length of SSID given in @ssid.
 * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode.
 * @txpower: TX power in dBm
 * @p2p_ctwindow: P2P CTWindow, only for P2P client interfaces
 * @p2p_oppps: P2P opportunistic PS is enabled
 * @p2p_noa_attr: P2P NoA attribute for P2P powersave
 */
struct ieee80211_bss_conf {
	const u8 *bssid;
@@ -365,8 +364,7 @@ struct ieee80211_bss_conf {
	size_t ssid_len;
	bool hidden_ssid;
	int txpower;
	u8 p2p_ctwindow;
	bool p2p_oppps;
	struct ieee80211_p2p_noa_attr p2p_noa_attr;
};

/**
+18 −5
Original line number Diff line number Diff line
@@ -965,8 +965,13 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
	sdata->vif.bss_conf.hidden_ssid =
		(params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);

	sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow;
	sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps;
	memset(&sdata->vif.bss_conf.p2p_noa_attr, 0,
	       sizeof(sdata->vif.bss_conf.p2p_noa_attr));
	sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow =
		params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
	if (params->p2p_opp_ps)
		sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
					IEEE80211_P2P_OPPPS_ENABLE_BIT;

	err = ieee80211_assign_beacon(sdata, &params->beacon);
	if (err < 0)
@@ -1961,12 +1966,20 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
	}

	if (params->p2p_ctwindow >= 0) {
		sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow;
		sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow &=
					~IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
		sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
			params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
		changed |= BSS_CHANGED_P2P_PS;
	}

	if (params->p2p_opp_ps >= 0) {
		sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps;
	if (params->p2p_opp_ps > 0) {
		sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
					IEEE80211_P2P_OPPPS_ENABLE_BIT;
		changed |= BSS_CHANGED_P2P_PS;
	} else if (params->p2p_opp_ps == 0) {
		sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow &=
					~IEEE80211_P2P_OPPPS_ENABLE_BIT;
		changed |= BSS_CHANGED_P2P_PS;
	}

+1 −1
Original line number Diff line number Diff line
@@ -442,7 +442,7 @@ struct ieee80211_if_managed {

	u8 use_4addr;

	u8 p2p_noa_index;
	s16 p2p_noa_index;

	/* Signal strength from the last Beacon frame in the current BSS. */
	int last_beacon_signal;
+25 −20
Original line number Diff line number Diff line
@@ -1661,20 +1661,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
		rcu_read_lock();
		ies = rcu_dereference(cbss->ies);
		if (ies) {
			struct ieee80211_p2p_noa_attr noa;
			int ret;

			ret = cfg80211_get_p2p_attr(
					ies->data, ies->len,
					IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
					(u8 *) &noa, sizeof(noa));
					(u8 *) &bss_conf->p2p_noa_attr,
					sizeof(bss_conf->p2p_noa_attr));
			if (ret >= 2) {
				bss_conf->p2p_oppps = noa.oppps_ctwindow &
						IEEE80211_P2P_OPPPS_ENABLE_BIT;
				bss_conf->p2p_ctwindow = noa.oppps_ctwindow &
						IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
				sdata->u.mgd.p2p_noa_index =
					bss_conf->p2p_noa_attr.index;
				bss_info_changed |= BSS_CHANGED_P2P_PS;
				sdata->u.mgd.p2p_noa_index = noa.index;
			}
		}
		rcu_read_unlock();
@@ -1799,8 +1796,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
	changed |= BSS_CHANGED_ASSOC;
	sdata->vif.bss_conf.assoc = false;

	sdata->vif.bss_conf.p2p_ctwindow = 0;
	sdata->vif.bss_conf.p2p_oppps = false;
	ifmgd->p2p_noa_index = -1;
	memset(&sdata->vif.bss_conf.p2p_noa_attr, 0,
	       sizeof(sdata->vif.bss_conf.p2p_noa_attr));

	/* on the next assoc, re-program HT/VHT parameters */
	memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
@@ -2963,26 +2961,32 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
	}

	if (sdata->vif.p2p) {
		struct ieee80211_p2p_noa_attr noa;
		struct ieee80211_p2p_noa_attr noa = {};
		int ret;

		ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
					    len - baselen,
					    IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
					    (u8 *) &noa, sizeof(noa));
		if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa.index) {
			bss_conf->p2p_oppps = noa.oppps_ctwindow &
						IEEE80211_P2P_OPPPS_ENABLE_BIT;
			bss_conf->p2p_ctwindow = noa.oppps_ctwindow &
						IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
			changed |= BSS_CHANGED_P2P_PS;
		if (ret >= 2) {
			if (sdata->u.mgd.p2p_noa_index != noa.index) {
				/* valid noa_attr and index changed */
				sdata->u.mgd.p2p_noa_index = noa.index;
				memcpy(&bss_conf->p2p_noa_attr, &noa, sizeof(noa));
				changed |= BSS_CHANGED_P2P_PS;
				/*
				 * make sure we update all information, the CRC
				 * mechanism doesn't look at P2P attributes.
				 */
				ifmgd->beacon_crc_valid = false;
			}
		} else if (sdata->u.mgd.p2p_noa_index != -1) {
			/* noa_attr not found and we had valid noa_attr before */
			sdata->u.mgd.p2p_noa_index = -1;
			memset(&bss_conf->p2p_noa_attr, 0, sizeof(bss_conf->p2p_noa_attr));
			changed |= BSS_CHANGED_P2P_PS;
			ifmgd->beacon_crc_valid = false;
		}
	}

	if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
@@ -3523,6 +3527,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
	ifmgd->powersave = sdata->wdev.ps;
	ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
	ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
	ifmgd->p2p_noa_index = -1;

	mutex_init(&ifmgd->mtx);

Loading