2013-03-21 14:48:11

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH v2 1/4] cfg80211: add P2P Notice of Absence attribute

Add P2P Notice of Absence attribute structure.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
include/linux/ieee80211.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 4cf0c9e..d10b5bb 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1027,6 +1027,26 @@ enum ieee80211_p2p_attr_id {
IEEE80211_P2P_ATTR_MAX
};

+/* Notice of Absence attribute - described in P2P spec 4.1.14 */
+/* Typical max value used here */
+#define IEEE80211_P2P_NOA_DESC_MAX 4
+
+struct ieee80211_p2p_noa_desc {
+ u8 count;
+ __le32 duration;
+ __le32 interval;
+ __le32 start_time;
+} __packed;
+
+struct ieee80211_p2p_noa_attr {
+ u8 index;
+ u8 oppps_ctwindow;
+ struct ieee80211_p2p_noa_desc desc[IEEE80211_P2P_NOA_DESC_MAX];
+} __packed;
+
+#define IEEE80211_P2P_OPPPS_ENABLE_BIT BIT(7)
+#define IEEE80211_P2P_OPPPS_CTWINDOW_MASK 0x7F
+
/**
* struct ieee80211_bar - HT Block Ack Request
*
--
1.7.9.5



2013-03-21 14:48:22

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH v2 4/4] iwlwifi: mvm: use ieee80211_noa_attr

Use ieee80211_noa_attr structure while
handling P2P PS.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 2779235..1f884b6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -669,6 +669,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);

@@ -678,7 +679,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);
}
@@ -914,6 +916,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);

@@ -924,8 +927,11 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap,
action == FW_CTXT_ACTION_ADD);

- 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);
}
--
1.7.9.5


2013-03-21 14:48:19

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH v2 3/4] mac80211: P2P add NOA settings

Add P2P NOA settings for STA mode.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
include/net/mac80211.h | 3 +--
net/mac80211/cfg.c | 21 ++++++++++++++++-----
net/mac80211/ieee80211_i.h | 2 +-
net/mac80211/mlme.c | 45 ++++++++++++++++++++++++--------------------
net/mac80211/trace.h | 6 ++----
5 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index cdd7cea..582e743 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -363,8 +363,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;
};

/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1d1ddab..e9cf6c2 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -960,8 +960,11 @@ 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;
+ 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)
@@ -1956,12 +1959,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;
}

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f4433f0..11451ee 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -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;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 14612cd..54d0338 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1655,20 +1655,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();
@@ -1793,8 +1790,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));
@@ -2955,24 +2953,30 @@ 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;
+ 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;
- 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;
}
}
@@ -3515,6 +3519,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);

diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e7db2b8..b9322b5 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -359,8 +359,7 @@ TRACE_EVENT(drv_bss_info_changed,
__dynamic_array(u8, ssid, info->ssid_len);
__field(bool, hidden_ssid);
__field(int, txpower)
- __field(u8, p2p_ctwindow)
- __field(bool, p2p_oppps)
+ __field(u8, p2p_oppps_ctwindow)
),

TP_fast_assign(
@@ -400,8 +399,7 @@ TRACE_EVENT(drv_bss_info_changed,
memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len);
__entry->hidden_ssid = info->hidden_ssid;
__entry->txpower = info->txpower;
- __entry->p2p_ctwindow = info->p2p_ctwindow;
- __entry->p2p_oppps = info->p2p_oppps;
+ __entry->p2p_oppps_ctwindow = info->p2p_noa_attr.oppps_ctwindow;
),

TP_printk(
--
1.7.9.5


2013-03-22 10:42:20

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v2 1/4] cfg80211: add P2P Notice of Absence attribute

Applied all, squashing 3 and 4 to not break compile inbetween.

johannes


2013-03-21 14:48:15

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH v2 2/4] mac80211: use ieee80211_p2p_noa_attr structure

Use ieee80211_p2p_noa_attr structure during
P2P_PS (oppps) detection.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
net/mac80211/mlme.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index fdc06e3..14612cd 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1655,18 +1655,20 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
rcu_read_lock();
ies = rcu_dereference(cbss->ies);
if (ies) {
- u8 noa[2];
+ struct ieee80211_p2p_noa_attr noa;
int ret;

ret = cfg80211_get_p2p_attr(
ies->data, ies->len,
IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
- noa, sizeof(noa));
+ (u8 *) &noa, sizeof(noa));
if (ret >= 2) {
- bss_conf->p2p_oppps = noa[1] & 0x80;
- bss_conf->p2p_ctwindow = noa[1] & 0x7f;
+ bss_conf->p2p_oppps = noa.oppps_ctwindow &
+ IEEE80211_P2P_OPPPS_ENABLE_BIT;
+ bss_conf->p2p_ctwindow = noa.oppps_ctwindow &
+ IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
bss_info_changed |= BSS_CHANGED_P2P_PS;
- sdata->u.mgd.p2p_noa_index = noa[0];
+ sdata->u.mgd.p2p_noa_index = noa.index;
}
}
rcu_read_unlock();
@@ -2953,18 +2955,20 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
}

if (sdata->vif.p2p) {
- u8 noa[2];
+ struct ieee80211_p2p_noa_attr noa;
int ret;

ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
len - baselen,
IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
- noa, sizeof(noa));
- if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa[0]) {
- bss_conf->p2p_oppps = noa[1] & 0x80;
- bss_conf->p2p_ctwindow = noa[1] & 0x7f;
+ (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;
- sdata->u.mgd.p2p_noa_index = noa[0];
+ sdata->u.mgd.p2p_noa_index = noa.index;
/*
* make sure we update all information, the CRC
* mechanism doesn't look at P2P attributes.
--
1.7.9.5