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

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
...@@ -662,6 +662,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm, ...@@ -662,6 +662,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
u32 action) u32 action)
{ {
struct iwl_mac_ctx_cmd cmd = {}; 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); 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, ...@@ -671,7 +672,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
/* Fill the data specific for station mode */ /* Fill the data specific for station mode */
iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta); 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); 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, ...@@ -892,6 +894,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
u32 action) u32 action)
{ {
struct iwl_mac_ctx_cmd cmd = {}; 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); 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, ...@@ -901,8 +904,11 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
/* Fill the data specific for GO mode */ /* Fill the data specific for GO mode */
iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap); 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.ctwin = cpu_to_le32(noa->oppps_ctwindow &
cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps); 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); return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
} }
......
...@@ -330,8 +330,7 @@ enum ieee80211_rssi_event { ...@@ -330,8 +330,7 @@ enum ieee80211_rssi_event {
* @ssid_len: Length of SSID given in @ssid. * @ssid_len: Length of SSID given in @ssid.
* @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode. * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode.
* @txpower: TX power in dBm * @txpower: TX power in dBm
* @p2p_ctwindow: P2P CTWindow, only for P2P client interfaces * @p2p_noa_attr: P2P NoA attribute for P2P powersave
* @p2p_oppps: P2P opportunistic PS is enabled
*/ */
struct ieee80211_bss_conf { struct ieee80211_bss_conf {
const u8 *bssid; const u8 *bssid;
...@@ -365,8 +364,7 @@ struct ieee80211_bss_conf { ...@@ -365,8 +364,7 @@ struct ieee80211_bss_conf {
size_t ssid_len; size_t ssid_len;
bool hidden_ssid; bool hidden_ssid;
int txpower; int txpower;
u8 p2p_ctwindow; struct ieee80211_p2p_noa_attr p2p_noa_attr;
bool p2p_oppps;
}; };
/** /**
......
...@@ -965,8 +965,13 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, ...@@ -965,8 +965,13 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
sdata->vif.bss_conf.hidden_ssid = sdata->vif.bss_conf.hidden_ssid =
(params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow; memset(&sdata->vif.bss_conf.p2p_noa_attr, 0,
sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps; 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); err = ieee80211_assign_beacon(sdata, &params->beacon);
if (err < 0) if (err < 0)
...@@ -1961,12 +1966,20 @@ static int ieee80211_change_bss(struct wiphy *wiphy, ...@@ -1961,12 +1966,20 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
} }
if (params->p2p_ctwindow >= 0) { 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; changed |= BSS_CHANGED_P2P_PS;
} }
if (params->p2p_opp_ps >= 0) { if (params->p2p_opp_ps > 0) {
sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps; 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; changed |= BSS_CHANGED_P2P_PS;
} }
......
...@@ -442,7 +442,7 @@ struct ieee80211_if_managed { ...@@ -442,7 +442,7 @@ struct ieee80211_if_managed {
u8 use_4addr; u8 use_4addr;
u8 p2p_noa_index; s16 p2p_noa_index;
/* Signal strength from the last Beacon frame in the current BSS. */ /* Signal strength from the last Beacon frame in the current BSS. */
int last_beacon_signal; int last_beacon_signal;
......
...@@ -1661,20 +1661,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ...@@ -1661,20 +1661,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
rcu_read_lock(); rcu_read_lock();
ies = rcu_dereference(cbss->ies); ies = rcu_dereference(cbss->ies);
if (ies) { if (ies) {
struct ieee80211_p2p_noa_attr noa;
int ret; int ret;
ret = cfg80211_get_p2p_attr( ret = cfg80211_get_p2p_attr(
ies->data, ies->len, ies->data, ies->len,
IEEE80211_P2P_ATTR_ABSENCE_NOTICE, IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
(u8 *) &noa, sizeof(noa)); (u8 *) &bss_conf->p2p_noa_attr,
sizeof(bss_conf->p2p_noa_attr));
if (ret >= 2) { if (ret >= 2) {
bss_conf->p2p_oppps = noa.oppps_ctwindow & sdata->u.mgd.p2p_noa_index =
IEEE80211_P2P_OPPPS_ENABLE_BIT; bss_conf->p2p_noa_attr.index;
bss_conf->p2p_ctwindow = noa.oppps_ctwindow &
IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
bss_info_changed |= BSS_CHANGED_P2P_PS; bss_info_changed |= BSS_CHANGED_P2P_PS;
sdata->u.mgd.p2p_noa_index = noa.index;
} }
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -1799,8 +1796,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -1799,8 +1796,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
changed |= BSS_CHANGED_ASSOC; changed |= BSS_CHANGED_ASSOC;
sdata->vif.bss_conf.assoc = false; sdata->vif.bss_conf.assoc = false;
sdata->vif.bss_conf.p2p_ctwindow = 0; ifmgd->p2p_noa_index = -1;
sdata->vif.bss_conf.p2p_oppps = false; 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 */ /* on the next assoc, re-program HT/VHT parameters */
memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
...@@ -2963,24 +2961,30 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ...@@ -2963,24 +2961,30 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
} }
if (sdata->vif.p2p) { if (sdata->vif.p2p) {
struct ieee80211_p2p_noa_attr noa; struct ieee80211_p2p_noa_attr noa = {};
int ret; int ret;
ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable, ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
len - baselen, len - baselen,
IEEE80211_P2P_ATTR_ABSENCE_NOTICE, IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
(u8 *) &noa, sizeof(noa)); (u8 *) &noa, sizeof(noa));
if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa.index) { if (ret >= 2) {
bss_conf->p2p_oppps = noa.oppps_ctwindow & if (sdata->u.mgd.p2p_noa_index != noa.index) {
IEEE80211_P2P_OPPPS_ENABLE_BIT; /* valid noa_attr and index changed */
bss_conf->p2p_ctwindow = noa.oppps_ctwindow & sdata->u.mgd.p2p_noa_index = noa.index;
IEEE80211_P2P_OPPPS_CTWINDOW_MASK; 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; changed |= BSS_CHANGED_P2P_PS;
sdata->u.mgd.p2p_noa_index = noa.index;
/*
* make sure we update all information, the CRC
* mechanism doesn't look at P2P attributes.
*/
ifmgd->beacon_crc_valid = false; ifmgd->beacon_crc_valid = false;
} }
} }
...@@ -3523,6 +3527,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) ...@@ -3523,6 +3527,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
ifmgd->powersave = sdata->wdev.ps; ifmgd->powersave = sdata->wdev.ps;
ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
ifmgd->p2p_noa_index = -1;
mutex_init(&ifmgd->mtx); mutex_init(&ifmgd->mtx);
......
...@@ -359,8 +359,7 @@ TRACE_EVENT(drv_bss_info_changed, ...@@ -359,8 +359,7 @@ TRACE_EVENT(drv_bss_info_changed,
__dynamic_array(u8, ssid, info->ssid_len); __dynamic_array(u8, ssid, info->ssid_len);
__field(bool, hidden_ssid); __field(bool, hidden_ssid);
__field(int, txpower) __field(int, txpower)
__field(u8, p2p_ctwindow) __field(u8, p2p_oppps_ctwindow)
__field(bool, p2p_oppps)
), ),
TP_fast_assign( TP_fast_assign(
...@@ -400,8 +399,7 @@ TRACE_EVENT(drv_bss_info_changed, ...@@ -400,8 +399,7 @@ TRACE_EVENT(drv_bss_info_changed,
memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len); memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len);
__entry->hidden_ssid = info->hidden_ssid; __entry->hidden_ssid = info->hidden_ssid;
__entry->txpower = info->txpower; __entry->txpower = info->txpower;
__entry->p2p_ctwindow = info->p2p_ctwindow; __entry->p2p_oppps_ctwindow = info->p2p_noa_attr.oppps_ctwindow;
__entry->p2p_oppps = info->p2p_oppps;
), ),
TP_printk( TP_printk(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment