[PATCH] mac80211: Fix ignored HT override configurations

2014-12-14 Thread Emmanuel Grumbach
From: Chaya Rachel Ivgi chaya.rachel.i...@intel.com

HT override configurations was ignored when choosing the channel
(until now, the override configuration affected only the
capabilities shown in the IEs).

The override configurations received only on association time,
so in this case we should determine the channel again.

Signed-off-by: Chaya Rachel Ivgi chaya.rachel.i...@intel.com
Signed-off-by: Emmanuel Grumbach emmanuel.grumb...@intel.com
---
 net/mac80211/mlme.c | 42 --
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 75a9bf5..9ae4c48 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -157,14 +157,18 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data 
*sdata,
 {
struct ieee80211_if_managed *ifmgd = sdata-u.mgd;
struct cfg80211_chan_def vht_chandef;
+   struct ieee80211_sta_ht_cap sta_ht_cap;
u32 ht_cfreq, ret;
 
+   memcpy(sta_ht_cap, sband-ht_cap, sizeof(sta_ht_cap));
+   ieee80211_apply_htcap_overrides(sdata, sta_ht_cap);
+
chandef-chan = channel;
chandef-width = NL80211_CHAN_WIDTH_20_NOHT;
chandef-center_freq1 = channel-center_freq;
chandef-center_freq2 = 0;
 
-   if (!ht_cap || !ht_oper || !sband-ht_cap.ht_supported) {
+   if (!ht_cap || !ht_oper || !sta_ht_cap.ht_supported) {
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
goto out;
}
@@ -197,7 +201,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data 
*sdata,
}
 
/* check 40 MHz support, if we have it */
-   if (sband-ht_cap.cap  IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+   if (sta_ht_cap.cap  IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
switch (ht_oper-ht_param  IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
chandef-width = NL80211_CHAN_WIDTH_40;
@@ -4196,9 +4200,13 @@ static int ieee80211_prep_connection(struct 
ieee80211_sub_if_data *sdata,
struct ieee80211_if_managed *ifmgd = sdata-u.mgd;
struct ieee80211_bss *bss = (void *)cbss-priv;
struct sta_info *new_sta = NULL;
-   bool have_sta = false;
+   struct ieee80211_supported_band *sband;
+   struct ieee80211_sta_ht_cap sta_ht_cap;
+   bool have_sta = false, is_override = false;
int err;
 
+   sband = local-hw.wiphy-bands[cbss-channel-band];
+
if (WARN_ON(!ifmgd-auth_data  !ifmgd-assoc_data))
return -EINVAL;
 
@@ -4213,24 +4221,30 @@ static int ieee80211_prep_connection(struct 
ieee80211_sub_if_data *sdata,
if (!new_sta)
return -ENOMEM;
}
-   if (new_sta) {
-   u32 rates = 0, basic_rates = 0;
-   bool have_higher_than_11mbit;
-   int min_rate = INT_MAX, min_rate_index = -1;
-   struct ieee80211_chanctx_conf *chanctx_conf;
-   struct ieee80211_supported_band *sband;
-   const struct cfg80211_bss_ies *ies;
-   int shift;
-   u32 rate_flags;
 
-   sband = local-hw.wiphy-bands[cbss-channel-band];
+   memcpy(sta_ht_cap, sband-ht_cap, sizeof(sta_ht_cap));
+   ieee80211_apply_htcap_overrides(sdata, sta_ht_cap);
 
+   is_override = (sta_ht_cap.cap  IEEE80211_HT_CAP_SUP_WIDTH_20_40) !=
+ (sband-ht_cap.cap 
+  IEEE80211_HT_CAP_SUP_WIDTH_20_40);
+
+   if (new_sta || is_override) {
err = ieee80211_prep_channel(sdata, cbss);
if (err) {
sta_info_free(local, new_sta);
return -EINVAL;
}
-   shift = ieee80211_vif_get_shift(sdata-vif);
+   }
+
+   if (new_sta) {
+   u32 rates = 0, basic_rates = 0;
+   bool have_higher_than_11mbit;
+   int min_rate = INT_MAX, min_rate_index = -1;
+   struct ieee80211_chanctx_conf *chanctx_conf;
+   const struct cfg80211_bss_ies *ies;
+   int shift = ieee80211_vif_get_shift(sdata-vif);
+   u32 rate_flags;
 
rcu_read_lock();
chanctx_conf = rcu_dereference(sdata-vif.chanctx_conf);
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] mac80211: handle power constraint and country IEs in RRM

2014-12-14 Thread Emmanuel Grumbach
From: Moshe Benji moshe.be...@intel.com

In beacons, handle the Country IE even if no Power Constraint IE
is present, and, capability wise, also in case that the Radio
Measurements capability is enabled.

In cases where the Country IE should be handled and that the
Power Constraint IE is not present, the Country IE alone will
set the power limit (and not both Country and Power Constraint
IEs).

Signed-off-by: Moshe Benji moshe.be...@intel.com
Signed-off-by: Emmanuel Grumbach emmanuel.grumb...@intel.com
---
 net/mac80211/mlme.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9ae4c48..31281fa 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1287,8 +1287,11 @@ ieee80211_find_80211h_pwr_constr(struct 
ieee80211_sub_if_data *sdata,
country_ie_len -= 3;
}
 
-   if (have_chan_pwr)
+   if (have_chan_pwr  pwr_constr_elem)
*pwr_reduction = *pwr_constr_elem;
+   else
+   *pwr_reduction = 0;
+
return have_chan_pwr;
 }
 
@@ -1317,10 +1320,11 @@ static u32 ieee80211_handle_pwr_constr(struct 
ieee80211_sub_if_data *sdata,
int chan_pwr = 0, pwr_reduction_80211h = 0;
int pwr_level_cisco, pwr_level_80211h;
int new_ap_level;
+   __le16 capab = mgmt-u.probe_resp.capab_info;
 
-   if (country_ie  pwr_constr_ie 
-   mgmt-u.probe_resp.capab_info 
-   cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) {
+   if (country_ie 
+   (capab  cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT) ||
+capab  cpu_to_le16(WLAN_CAPABILITY_RADIO_MEASURE))) {
has_80211h_pwr = ieee80211_find_80211h_pwr_constr(
sdata, channel, country_ie, country_ie_len,
pwr_constr_ie, chan_pwr, pwr_reduction_80211h);
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] mac80211: remove unused variable in ieee80211_parse_ch_switch_ie()

2014-12-14 Thread Emmanuel Grumbach
From: Luciano Coelho luciano.coe...@intel.com

The ht_oper variable is assigned a value, but never used in
ieee80211_parse_ch_switch_ie().  Remove it.

Signed-off-by: Luciano Coelho luciano.coe...@intel.com
Signed-off-by: Emmanuel Grumbach emmanuel.grumb...@intel.com
---
 net/mac80211/spectmgmt.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index efeba56..06e6ac8 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -34,19 +34,15 @@ int ieee80211_parse_ch_switch_ie(struct 
ieee80211_sub_if_data *sdata,
struct cfg80211_chan_def new_vht_chandef = {};
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
-   const struct ieee80211_ht_operation *ht_oper;
int secondary_channel_offset = -1;
 
sec_chan_offs = elems-sec_chan_offs;
wide_bw_chansw_ie = elems-wide_bw_chansw_ie;
-   ht_oper = elems-ht_operation;
 
if (sta_flags  (IEEE80211_STA_DISABLE_HT |
 IEEE80211_STA_DISABLE_40MHZ)) {
sec_chan_offs = NULL;
wide_bw_chansw_ie = NULL;
-   /* only used for bandwidth here */
-   ht_oper = NULL;
}
 
if (sta_flags  IEEE80211_STA_DISABLE_VHT)
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] mac80211: avoid reconfig if no interfaces are up

2014-12-14 Thread Emmanuel Grumbach
From: Eliad Peller el...@wizery.com

If there are no interfaces up, there is no reason
to continue the reconfig flow.

The current code might end up calling driver
callbacks (e.g. resume(), reconfig_complete())
while the driver is already stopped.

Signed-off-by: Eliad Peller eliadx.pel...@intel.com
Signed-off-by: Emmanuel Grumbach emmanuel.grumb...@intel.com
---
 net/mac80211/util.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 974ebe7..0f9bf47 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1735,6 +1735,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
struct cfg80211_sched_scan_request *sched_scan_req;
bool sched_scan_stopped = false;
 
+   /* nothing to do if HW shouldn't run */
+   if (!local-open_count)
+   goto wake_up;
+
 #ifdef CONFIG_PM
if (local-suspended)
local-resuming = true;
@@ -1756,9 +1760,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
reconfig_due_to_wowlan = true;
}
 #endif
-   /* everything else happens only if HW was up  running */
-   if (!local-open_count)
-   goto wake_up;
 
/*
 * Upon resume hardware can sometimes be goofy due to
@@ -2042,7 +2043,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 * If this is for hw restart things are still running.
 * We may want to change that later, however.
 */
-   if (!local-suspended || reconfig_due_to_wowlan)
+   if (local-open_count  (!local-suspended || reconfig_due_to_wowlan))
drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
 
if (!local-suspended)
@@ -2054,7 +2055,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mb();
local-resuming = false;
 
-   if (!reconfig_due_to_wowlan)
+   if (local-open_count  !reconfig_due_to_wowlan)
drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
 
list_for_each_entry(sdata, local-interfaces, list) {
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/4] mac80211: update sta bw on ht chanwidth action frame

2014-12-14 Thread Emmanuel Grumbach
From: Eliad Peller el...@wizery.com

Commit e1a0c6b (mac80211: stop toggling IEEE80211_HT_CAP_SUP_WIDTH_20_40)
mistakenly removed the actual update of sta-sta.bandwidth.

Refactor ieee80211_sta_cur_vht_bw() into multiple functions
(calculate caps-bw and chandef-bw separately, and min them
with cur_max_bandwidth).

On ht chanwidth action frame set only cur_max_bandwidth
(according to the sta capabilities) and recalc the sta bw.

Signed-off-by: Eliad Peller eliadx.pel...@intel.com
Signed-off-by: Emmanuel Grumbach emmanuel.grumb...@intel.com
---
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/rx.c  | 11 +--
 net/mac80211/vht.c | 73 --
 3 files changed, 47 insertions(+), 38 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index cc6e964..4f45cab 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1704,6 +1704,7 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct 
ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband,
const struct ieee80211_vht_cap *vht_cap_ie,
struct sta_info *sta);
+enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta);
 enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
 void ieee80211_sta_set_rx_nss(struct sta_info *sta);
 u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 49c23bd..444ebff 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2597,7 +2597,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
struct ieee80211_supported_band *sband;
u8 chanwidth = mgmt-u.action.u.ht_notify_cw.chanwidth;
-   enum ieee80211_sta_rx_bandwidth new_bw;
+   enum ieee80211_sta_rx_bandwidth max_bw, new_bw;
 
/* If it doesn't support 40 MHz it can't change ... */
if (!(rx-sta-sta.ht_cap.cap 
@@ -2605,13 +2605,18 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto handled;
 
if (chanwidth == IEEE80211_HT_CHANWIDTH_20MHZ)
-   new_bw = IEEE80211_STA_RX_BW_20;
+   max_bw = IEEE80211_STA_RX_BW_20;
else
-   new_bw = ieee80211_sta_cur_vht_bw(rx-sta);
+   max_bw = ieee80211_sta_cap_rx_bw(rx-sta);
+
+   /* set cur_max_bandwidth and recalc sta bw */
+   rx-sta-cur_max_bandwidth = max_bw;
+   new_bw = ieee80211_sta_cur_vht_bw(rx-sta);
 
if (rx-sta-sta.bandwidth == new_bw)
goto handled;
 
+   rx-sta-sta.bandwidth = new_bw;
sband = rx-local-hw.wiphy-bands[status-band];
 
rate_control_rate_update(local, sband, rx-sta,
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index bc9e8fc..85f9596 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -269,51 +269,54 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct 
ieee80211_sub_if_data *sdata,
sta-sta.bandwidth = ieee80211_sta_cur_vht_bw(sta);
 }
 
-enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta)
+enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta)
 {
-   struct ieee80211_sub_if_data *sdata = sta-sdata;
-   u32 cap = sta-sta.vht_cap.cap;
-   enum ieee80211_sta_rx_bandwidth bw;
+   struct ieee80211_sta_vht_cap *vht_cap = sta-sta.vht_cap;
+   u32 cap_width;
 
-   if (!sta-sta.vht_cap.vht_supported) {
-   bw = sta-sta.ht_cap.cap  IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
-   IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20;
-   goto check_max;
-   }
+   if (!vht_cap-vht_supported)
+   return sta-sta.ht_cap.cap  IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
+   IEEE80211_STA_RX_BW_40 :
+   IEEE80211_STA_RX_BW_20;
 
-   switch (sdata-vif.bss_conf.chandef.width) {
-   default:
-   WARN_ON_ONCE(1);
-   /* fall through */
+   cap_width = vht_cap-cap  IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+
+   if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ||
+   cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
+   return IEEE80211_STA_RX_BW_160;
+
+   return IEEE80211_STA_RX_BW_80;
+}
+
+static enum ieee80211_sta_rx_bandwidth
+ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
+{
+   switch (width) {
case NL80211_CHAN_WIDTH_20_NOHT:
case 

Re: [PATCH] nl80211: report new station / assoc event for the correct BSS

2014-12-14 Thread Arend van Spriel

On 12/13/14 23:31, Rafał Miłecki wrote:

On 6 December 2014 at 16:06, Rafał Miłeckizaj...@gmail.com  wrote:

drv-ctx always points to the first BSS and we should report event using
BSS related to the interface we got NL80211_CMD_NEW_STATION from.
This fixes STA association for drivers using NL80211_CMD_NEW_STATION and
multiple virtual interfaces.

Before:
nl80211: Drv Event 19 (NL80211_CMD_NEW_STATION) received for wlan0-1 (ifindex:7)
nl80211: New station 02:00:00:00:01:00
wlan0: STA 02:00:00:00:01:00 IEEE 802.11: associated

After:
nl80211: Drv Event 19 (NL80211_CMD_NEW_STATION) received for wlan0-1 (ifindex:7)
nl80211: New station 02:00:00:00:01:00
wlan0-1: STA 02:00:00:00:01:00 IEEE 802.11: associated

Signed-off-by: Rafał Miłeckizaj...@gmail.com
---
Hi guys :)

I recently heard about possible problems with handling BSS-es from Arend and was
working with nl80211 / hostapd anyway, so decided to take a look at this.

I think I found some bug in handling events that can be exposed when using
multiple virtual interfaces, hardware authentication and cfg80211_new_sta (which
gets translated into NL80211_CMD_NEW_STATION).

As you can see in the log called Before, hostapd was getting event from
wlan0-1 but then association was happening on the wlan0. This was breaking AP
mode on virtual interfaces (BSS other than the first one).

Please note, that this bug (I believe it's a bug) won't be exposed when running
mac80211_hwsim. In such case authentication is handled in hostapd and assoc
happens in handle_assoc_cb (not hostapd_notif_assoc) which handles BSS-es
correctly.

If you review this patch and it appears to be OK, I guess we will need similar
modification for other events.


Any opinions on this?


I would say you are right in your analysis. I have not tried this patch. 
I will ask Hante as he added Multiple-BSSID support. I assume this bug 
is not visible to any mac80211-based driver, right?


Regards,
Arend
--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] cfg80211: avoid intersection when applying custom reg

2014-12-14 Thread Arik Nemtsov
On Fri, Dec 12, 2014 at 2:41 PM, Johannes Berg
johan...@sipsolutions.net wrote:

 On Sun, 2014-12-07 at 18:03 +0200, Arik Nemtsov wrote:
  The custom-reg handling function can currently only add flags to a given
  channel. This results in stale flags being left applied. In some cases
  a channel was disabled and even the orig_flags were changed to reflect
  this.
 
  Previously the API was designed for a single invocation before wiphy
  registration, so this didn't matter. The previous approach doesn't scale
  well to self-managed regulatory devices, particularly when a more
  permissive regdom is applied after a restrictive one.

 This description (not the patch) only makes sense after the other series
 with self-managed, please resend it in the self-managed patchset.

Sure. I'll also make it self-managed only, so avoid possible
regressions, as Luis commented.

Arik
--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/1] staging: rtl8723au: Fix sparse warnings invalid assignment |=

2014-12-14 Thread Yannis Damigos
This is a patch to the hal/rtl8723au_xmit.c file that fixes various
warnings:
invalid warning: invalid assignment: |=
 left side has type unsigned int
 right side has type restricted __le32

found by sparse tool.

Signed-off-by: Yannis Damigos giannis.dami...@gmail.com
---
 drivers/staging/rtl8723au/hal/rtl8723au_xmit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c 
b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
index 6070510..e7e796e 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
@@ -79,7 +79,7 @@ static void fill_txdesc_sectype(struct pkt_attrib *pattrib, 
struct tx_desc *ptxd
}
 }
 
-static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
+static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw)
 {
/* DBG_8723A(cvs_mode =%d\n, pattrib-vcs_mode); */
 
-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] nl80211: report new station / assoc event for the correct BSS

2014-12-14 Thread Jouni Malinen
On Sun, Dec 14, 2014 at 10:25:45AM +0100, Arend van Spriel wrote:
 On 12/13/14 23:31, Rafał Miłecki wrote:
 On 6 December 2014 at 16:06, Rafał Miłeckizaj...@gmail.com  wrote:
 drv-ctx always points to the first BSS and we should report event using
 BSS related to the interface we got NL80211_CMD_NEW_STATION from.
 This fixes STA association for drivers using NL80211_CMD_NEW_STATION and
 multiple virtual interfaces.

 As you can see in the log called Before, hostapd was getting event from
 wlan0-1 but then association was happening on the wlan0. This was breaking 
 AP
 mode on virtual interfaces (BSS other than the first one).

 If you review this patch and it appears to be OK, I guess we will need 
 similar
 modification for other events.

 I would say you are right in your analysis. I have not tried this
 patch. I will ask Hante as he added Multiple-BSSID support. I assume
 this bug is not visible to any mac80211-based driver, right?

I think this is the first time I've heard of anyone using the multi-BSS
design where multiple BSSes are maintained within a single struct
hostapd_data instance with a driver that does not use hostapd as the AP
SME and MLME.  As such, this is getting to areas that have never been
even assumed to work.. Not that I have anything against making this
work, but it should be understood that this was not part of the criteria
for the event message design and yes, this would indeed require fixing
number of other places as well.

In practice, all cases where the driver takes care of authentication and
association frame exchanges have used multi-BSS design in a way that
hostapd gets two radios configured (e.g., two configuration files on
the command line, each pointing to a separate virtual interface). I'd
assume that could be used with nl80211 as well, but it may be reasonable
to extend the internal BSS control case (bss=ifname in hostapd.conf)
to provide a more consistent alternative for all drivers using the
nl80211 interface.

-- 
Jouni MalinenPGP id EFC895FA
--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] nl80211: report new station / assoc event for the correct BSS

2014-12-14 Thread Rafał Miłecki
On 14 December 2014 at 10:25, Arend van Spriel ar...@broadcom.com wrote:
 On 12/13/14 23:31, Rafał Miłecki wrote:

 On 6 December 2014 at 16:06, Rafał Miłeckizaj...@gmail.com  wrote:

 drv-ctx always points to the first BSS and we should report event using
 BSS related to the interface we got NL80211_CMD_NEW_STATION from.
 This fixes STA association for drivers using NL80211_CMD_NEW_STATION and
 multiple virtual interfaces.

 Before:
 nl80211: Drv Event 19 (NL80211_CMD_NEW_STATION) received for wlan0-1
 (ifindex:7)
 nl80211: New station 02:00:00:00:01:00
 wlan0: STA 02:00:00:00:01:00 IEEE 802.11: associated

 After:
 nl80211: Drv Event 19 (NL80211_CMD_NEW_STATION) received for wlan0-1
 (ifindex:7)
 nl80211: New station 02:00:00:00:01:00
 wlan0-1: STA 02:00:00:00:01:00 IEEE 802.11: associated

 Signed-off-by: Rafał Miłeckizaj...@gmail.com
 ---
 Hi guys :)

 I recently heard about possible problems with handling BSS-es from Arend
 and was
 working with nl80211 / hostapd anyway, so decided to take a look at this.

 I think I found some bug in handling events that can be exposed when
 using
 multiple virtual interfaces, hardware authentication and cfg80211_new_sta
 (which
 gets translated into NL80211_CMD_NEW_STATION).

 As you can see in the log called Before, hostapd was getting event from
 wlan0-1 but then association was happening on the wlan0. This was
 breaking AP
 mode on virtual interfaces (BSS other than the first one).

 Please note, that this bug (I believe it's a bug) won't be exposed when
 running
 mac80211_hwsim. In such case authentication is handled in hostapd and
 assoc
 happens in handle_assoc_cb (not hostapd_notif_assoc) which handles BSS-es
 correctly.

 If you review this patch and it appears to be OK, I guess we will need
 similar
 modification for other events.


 Any opinions on this?


 I would say you are right in your analysis. I have not tried this patch. I
 will ask Hante as he added Multiple-BSSID support. I assume this bug is not
 visible to any mac80211-based driver, right?

Yes. What I wrote about mac80211_hwsim applies to (almost?) all
mac80211 drivers (they usually don't handle authentication in
hardware).

-- 
Rafał
--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] staging: rtl8723au: os_dep: usb_intf.c: Fix for possible null pointer dereference

2014-12-14 Thread Rickard Strandqvist
There is otherwise a risk of a possible null pointer dereference.

Was largely found by using a static code analysis program called cppcheck.

Signed-off-by: Rickard Strandqvist rickard_strandqv...@spectrumdigital.se
---
 drivers/staging/rtl8723au/os_dep/usb_intf.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/rtl8723au/os_dep/usb_intf.c 
b/drivers/staging/rtl8723au/os_dep/usb_intf.c
index 865743e..71a6330 100644
--- a/drivers/staging/rtl8723au/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8723au/os_dep/usb_intf.c
@@ -351,10 +351,11 @@ error_exit:
 int rtw_hw_resume23a(struct rtw_adapter *padapter)
 {
struct pwrctrl_priv *pwrpriv = padapter-pwrctrlpriv;
-   struct net_device *pnetdev = padapter-pnetdev;
+   struct net_device *pnetdev;
 
if (padapter) { /* system resume */
DBG_8723A(== rtw_hw_resume23a\n);
+   pnetdev = padapter-pnetdev;
down(pwrpriv-lock);
pwrpriv-bips_processing = true;
rtw_reset_drv_sw23a(padapter);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] ath10k: Fix no-ack frame status

2014-12-14 Thread Sujith Manoharan
Kalle Valo wrote:
 Johannes, are you planning to take this? Or should I take this once the
 corresponding mac80211 patch trickles down to my tree?

Kalle, can you please pick this one ? I'll rebase and send the ath9k patch
to John once he starts merging patches.

Sujith
--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] mac80211: Fix accounting of multicast frames

2014-12-14 Thread Sujith Manoharan
Johannes Berg wrote:
 Seems fine, applied. I've worded the documentation a bit more strongly.

Thanks.

Sujith
--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: New WARNING from mac80211

2014-12-14 Thread Sujith Manoharan
Johannes Berg wrote:
 Would it be worthwhile to simply remove the warning and document how we
 can get there?

I think we can fix this by flushing old packets
in sdata-work after a HW scan completes. I'll test this
and post a patch for review.

Sujith
--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/5] ath10k: Add thermal mitigation support

2014-12-14 Thread Rajkumar Manoharan
The following patches add thermal sensor and thermal cooling device
support in ath10k. For sensor, hwmon interface is used. For controlling
temperature cooling device interface is used. For thermal mitigation,
tx throttling is done using hw MAC quiet time setting.

WMI support for reading temperature is available from 10.2.4 firmware
onwards. The firmware can be downloaded from

https://github.com/kvalo/ath10k-firmware/tree/master/10.2.4/untested

Rajkumar Manoharan (5):
  ath10k: add 10.2.4 firmware support
  ath10k: add wmi support for pdev_set_quiet_mode
  ath10k: add thermal cooling device support
  ath10k: add wmi interface for pdev_get_temperature
  ath10k: add thermal sensor device support

 drivers/net/wireless/ath/ath10k/Makefile  |   1 +
 drivers/net/wireless/ath/ath10k/core.c|  20 ++-
 drivers/net/wireless/ath/ath10k/core.h|   8 +
 drivers/net/wireless/ath/ath10k/hw.h  |   1 +
 drivers/net/wireless/ath/ath10k/thermal.c | 238 ++
 drivers/net/wireless/ath/ath10k/thermal.h |  58 
 drivers/net/wireless/ath/ath10k/wmi-ops.h |  39 +
 drivers/net/wireless/ath/ath10k/wmi-tlv.c |   3 +
 drivers/net/wireless/ath/ath10k/wmi.c |  62 
 drivers/net/wireless/ath/ath10k/wmi.h |  20 ++-
 10 files changed, 448 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/thermal.c
 create mode 100644 drivers/net/wireless/ath/ath10k/thermal.h

-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] ath10k: add 10.2.4 firmware support

2014-12-14 Thread Rajkumar Manoharan
10.2.4 firmware uses bitmask in wmi_resource_config to configure
10.2 firmware features like airtime fairness and rx batch mode instead
of maintaining separete bool entry. This allows new features that can be
configure during init time without breaking backward compatibility.

Signed-off-by: Rajkumar Manoharan rmano...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c | 8 +++-
 drivers/net/wireless/ath/ath10k/core.h | 5 +
 drivers/net/wireless/ath/ath10k/hw.h   | 1 +
 drivers/net/wireless/ath/ath10k/wmi.c  | 1 +
 drivers/net/wireless/ath/ath10k/wmi.h  | 7 ++-
 5 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 577a3d7..c05841e 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -894,7 +894,12 @@ static int ath10k_core_init_firmware_features(struct 
ath10k *ar)
 */
if (ar-wmi.op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar-fw_features)) {
-   if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, 
ar-fw_features))
+   if (test_bit(ATH10K_FW_FEATURE_WMI_10_2_4,
+ar-fw_features))
+   ar-wmi.op_version =
+   ATH10K_FW_WMI_OP_VERSION_10_2_4;
+   else if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
+ ar-fw_features))
ar-wmi.op_version = 
ATH10K_FW_WMI_OP_VERSION_10_2;
else
ar-wmi.op_version = 
ATH10K_FW_WMI_OP_VERSION_10_1;
@@ -911,6 +916,7 @@ static int ath10k_core_init_firmware_features(struct ath10k 
*ar)
break;
case ATH10K_FW_WMI_OP_VERSION_10_1:
case ATH10K_FW_WMI_OP_VERSION_10_2:
+   case ATH10K_FW_WMI_OP_VERSION_10_2_4:
ar-max_num_peers = TARGET_10X_NUM_PEERS;
ar-max_num_stations = TARGET_10X_NUM_STATIONS;
ar-htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 613355c..8083b91 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -387,6 +387,11 @@ enum ath10k_fw_features {
 */
ATH10K_FW_FEATURE_WMI_10_2 = 4,
 
+   /* Firmware 10.2.4 supports bitmask in resource config to configure
+* Airtime fairness and rx batch mode
+*/
+   ATH10K_FW_FEATURE_WMI_10_2_4 = 5,
+
/* keep last */
ATH10K_FW_FEATURE_COUNT,
 };
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 809c252..892b6f0 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -72,6 +72,7 @@ enum ath10k_fw_wmi_op_version {
ATH10K_FW_WMI_OP_VERSION_10_1 = 2,
ATH10K_FW_WMI_OP_VERSION_10_2 = 3,
ATH10K_FW_WMI_OP_VERSION_TLV = 4,
+   ATH10K_FW_WMI_OP_VERSION_10_2_4 = 5,
 
/* keep last */
ATH10K_FW_WMI_OP_VERSION_MAX,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index fa486f6..c42382c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -4748,6 +4748,7 @@ static const struct wmi_ops wmi_10_2_ops = {
 int ath10k_wmi_attach(struct ath10k *ar)
 {
switch (ar-wmi.op_version) {
+   case ATH10K_FW_WMI_OP_VERSION_10_2_4:
case ATH10K_FW_WMI_OP_VERSION_10_2:
ar-wmi.cmd = wmi_10_2_cmd_map;
ar-wmi.ops = wmi_10_2_ops;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index 97f902f..ce517bf 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1940,6 +1940,11 @@ struct wmi_resource_config_10x {
__le32 max_frag_entries;
 } __packed;
 
+enum wmi_10_2_feature_mask {
+   WMI_10_2_RX_BATCH_MODE = BIT(0),
+   WMI_10_2_ATF_CONFIG= BIT(1),
+};
+
 struct wmi_resource_config_10_2 {
struct wmi_resource_config_10x common;
__le32 max_peer_ext_stats;
@@ -1948,7 +1953,7 @@ struct wmi_resource_config_10_2 {
__le32 be_min_free;
__le32 vi_min_free;
__le32 vo_min_free;
-   __le32 rx_batchmode; /* 0-disable, 1-enable */
+   __le32 feature_mask;
 } __packed;
 
 #define NUM_UNITS_IS_NUM_VDEVS   0x1
-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/5] ath10k: add wmi support for pdev_set_quiet_mode

2014-12-14 Thread Rajkumar Manoharan
Add WMI support to send pdev_set_quiet_mode command to target.
This will be used for thermal mitigation purpose.

Signed-off-by: Rajkumar Manoharan rmano...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/wmi-ops.h | 22 ++
 drivers/net/wireless/ath/ath10k/wmi-tlv.c |  1 +
 drivers/net/wireless/ath/ath10k/wmi.c | 27 +++
 3 files changed, 50 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h 
b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 1fbc520..feed0fe 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -114,6 +114,10 @@ struct wmi_ops {
struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u32 module_enable);
struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter);
struct sk_buff *(*gen_pktlog_disable)(struct ath10k *ar);
+   struct sk_buff *(*gen_pdev_set_quiet_mode)(struct ath10k *ar,
+  u32 period, u32 duration,
+  u32 next_offset,
+  u32 enabled);
 };
 
 int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -818,4 +822,22 @@ ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar)
   ar-wmi.cmd-pdev_pktlog_disable_cmdid);
 }
 
+static inline int
+ath10k_wmi_pdev_set_quiet_mode(struct ath10k *ar, u32 period, u32 duration,
+  u32 next_offset, u32 enabled)
+{
+   struct sk_buff *skb;
+
+   if (!ar-wmi.ops-gen_pdev_set_quiet_mode)
+   return -EOPNOTSUPP;
+
+   skb = ar-wmi.ops-gen_pdev_set_quiet_mode(ar, period, duration,
+  next_offset, enabled);
+   if (IS_ERR(skb))
+   return PTR_ERR(skb);
+
+   return ath10k_wmi_cmd_send(ar, skb,
+  ar-wmi.cmd-pdev_set_quiet_mode_cmdid);
+}
+
 #endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c 
b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 1627ec5..e203dad 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -2204,6 +2204,7 @@ static const struct wmi_ops wmi_tlv_ops = {
.gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
.gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
.gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
+   /* .gen_pdev_set_quiet_mode not implemented */
 };
 
 //
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index c42382c..abf4c98 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -4589,6 +4589,30 @@ ath10k_wmi_op_gen_pktlog_disable(struct ath10k *ar)
return skb;
 }
 
+static struct sk_buff *
+ath10k_wmi_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period,
+ u32 duration, u32 next_offset,
+ u32 enabled)
+{
+   struct wmi_pdev_set_quiet_cmd *cmd;
+   struct sk_buff *skb;
+
+   skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
+   if (!skb)
+   return ERR_PTR(-ENOMEM);
+
+   cmd = (struct wmi_pdev_set_quiet_cmd *)skb-data;
+   cmd-period = __cpu_to_le32(period);
+   cmd-duration = __cpu_to_le32(duration);
+   cmd-next_start = __cpu_to_le32(next_offset);
+   cmd-enabled = __cpu_to_le32(enabled);
+
+   ath10k_dbg(ar, ATH10K_DBG_WMI,
+  wmi quiet param: period %u duration %u enabled %d\n,
+  period, duration, enabled);
+   return skb;
+}
+
 static const struct wmi_ops wmi_ops = {
.rx = ath10k_wmi_op_rx,
.map_svc = wmi_main_svc_map,
@@ -4638,6 +4662,7 @@ static const struct wmi_ops wmi_ops = {
.gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
+   .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
 };
 
 static const struct wmi_ops wmi_10_1_ops = {
@@ -4690,6 +4715,7 @@ static const struct wmi_ops wmi_10_1_ops = {
.gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
+   .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
 };
 
 static const struct wmi_ops wmi_10_2_ops = {
@@ -4743,6 +4769,7 @@ static const struct wmi_ops wmi_10_2_ops = {
.gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
+   .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
 };
 
 int ath10k_wmi_attach(struct ath10k *ar)
-- 
2.1.3

--
To 

[PATCH 3/5] ath10k: add thermal cooling device support

2014-12-14 Thread Rajkumar Manoharan
Thermal cooling device support is added to control the temperature
by throttling the data transmission for the given duration. Throttling
is done using hw MAC quiet time setting. Period, duration and offset
from TBTT can be set up to quiet the MAC transmits for the required duty
cycle (% of quiet duration). The thermal device allows user to configure
duty cycle.

The quiet params are derived as follows.
period = max(25TU, beacon interval / number of bss)
duration = period * duty cycle / 100

Quiet mode can be disabled by setting the duty cycle to 0. The cooling
device can be found under /sys/class/thermal/cooling_deviceX/.
Corresponding soft link to this device can be found under phy folder.

/sys/class/ieee80211/phy*/device/cooling_device.

To set duty cycle as 40%,

echo 40 /sys/class/ieee80211/phy*/device/cooling_device/cur_state

Signed-off-by: Rajkumar Manoharan rmano...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/Makefile  |   1 +
 drivers/net/wireless/ath/ath10k/core.c|  10 ++
 drivers/net/wireless/ath/ath10k/core.h|   3 +
 drivers/net/wireless/ath/ath10k/thermal.c | 155 ++
 drivers/net/wireless/ath/ath10k/thermal.h |  44 +
 5 files changed, 213 insertions(+)
 create mode 100644 drivers/net/wireless/ath/ath10k/thermal.c
 create mode 100644 drivers/net/wireless/ath/ath10k/thermal.h

diff --git a/drivers/net/wireless/ath/ath10k/Makefile 
b/drivers/net/wireless/ath/ath10k/Makefile
index 8abb66c..ffa3b1a 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -14,6 +14,7 @@ ath10k_core-y += mac.o \
 ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
 ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
 ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
+ath10k_core-$(CONFIG_THERMAL) += thermal.o
 
 obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
 ath10k_pci-y += pci.o \
diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index c05841e..2eb3f2c 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1232,9 +1232,18 @@ static void ath10k_core_register_work(struct work_struct 
*work)
goto err_debug_destroy;
}
 
+   status = ath10k_thermal_register(ar);
+   if (status) {
+   ath10k_err(ar, could not register thermal device: %d\n,
+  status);
+   goto err_spectral_destroy;
+   }
+
set_bit(ATH10K_FLAG_CORE_REGISTERED, ar-dev_flags);
return;
 
+err_spectral_destroy:
+   ath10k_spectral_destroy(ar);
 err_debug_destroy:
ath10k_debug_destroy(ar);
 err_unregister_mac:
@@ -1264,6 +1273,7 @@ void ath10k_core_unregister(struct ath10k *ar)
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, ar-dev_flags))
return;
 
+   ath10k_thermal_unregister(ar);
/* Stop spectral before unregistering from mac80211 to remove the
 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree
 * would be already be free'd recursively, leading to a double free.
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 8083b91..b7ba7cf 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -34,6 +34,7 @@
 #include ../regd.h
 #include ../dfs_pattern_detector.h
 #include spectral.h
+#include thermal.h
 
 #define MS(_v, _f) (((_v)  _f##_MASK)  _f##_LSB)
 #define SM(_v, _f) (((_v)  _f##_LSB)  _f##_MASK)
@@ -638,6 +639,8 @@ struct ath10k {
u32 fw_cold_reset_counter;
} stats;
 
+   struct ath10k_thermal thermal;
+
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
 };
diff --git a/drivers/net/wireless/ath/ath10k/thermal.c 
b/drivers/net/wireless/ath/ath10k/thermal.c
new file mode 100644
index 000..e98ce8c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/thermal.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2014 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include linux/device.h
+#include linux/sysfs.h
+#include linux/thermal.h
+#include core.h
+#include debug.h
+#include wmi-ops.h
+
+static int ath10k_thermal_get_active_vifs(struct 

[PATCH 4/5] ath10k: add wmi interface for pdev_get_temperature

2014-12-14 Thread Rajkumar Manoharan
Add WMI command support for reading temperature from the target and
corresponding WMI temperature event handler. The pdev_get_temperature
command is currently supported in 10.2 firmware alone.

Signed-off-by: Rajkumar Manoharan rmano...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/wmi-ops.h | 17 
 drivers/net/wireless/ath/ath10k/wmi-tlv.c |  2 ++
 drivers/net/wireless/ath/ath10k/wmi.c | 33 +++
 drivers/net/wireless/ath/ath10k/wmi.h | 13 
 4 files changed, 65 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h 
b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index feed0fe..20e2c30 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -118,6 +118,7 @@ struct wmi_ops {
   u32 period, u32 duration,
   u32 next_offset,
   u32 enabled);
+   struct sk_buff *(*gen_pdev_get_temperature)(struct ath10k *ar);
 };
 
 int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -840,4 +841,20 @@ ath10k_wmi_pdev_set_quiet_mode(struct ath10k *ar, u32 
period, u32 duration,
   ar-wmi.cmd-pdev_set_quiet_mode_cmdid);
 }
 
+static inline int
+ath10k_wmi_pdev_get_temperature(struct ath10k *ar)
+{
+   struct sk_buff *skb;
+
+   if (!ar-wmi.ops-gen_pdev_get_temperature)
+   return -EOPNOTSUPP;
+
+   skb = ar-wmi.ops-gen_pdev_get_temperature(ar);
+   if (IS_ERR(skb))
+   return PTR_ERR(skb);
+
+   return ath10k_wmi_cmd_send(ar, skb,
+  ar-wmi.cmd-pdev_get_temperature_cmdid);
+}
+
 #endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c 
b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index e203dad..4c050ce 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -2044,6 +2044,7 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = {
.force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID,
.gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID,
.gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
+   .pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED,
 };
 
 static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
@@ -2205,6 +2206,7 @@ static const struct wmi_ops wmi_tlv_ops = {
.gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
.gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
/* .gen_pdev_set_quiet_mode not implemented */
+   /* .gen_pdev_get_temperature not implemented */
 };
 
 //
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index abf4c98..c32dc19 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -145,6 +145,7 @@ static struct wmi_cmd_map wmi_cmd_map = {
.force_fw_hang_cmdid = WMI_FORCE_FW_HANG_CMDID,
.gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID,
.gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID,
+   .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
 };
 
 /* 10.X WMI cmd track */
@@ -267,6 +268,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
.force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED,
.gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID,
.gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID,
+   .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
 };
 
 /* MAIN WMI VDEV param map */
@@ -611,6 +613,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = {
.force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED,
.gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
.gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
+   .pdev_get_temperature_cmdid = WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
 };
 
 void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
@@ -2794,6 +2797,17 @@ int ath10k_wmi_event_ready(struct ath10k *ar, struct 
sk_buff *skb)
return 0;
 }
 
+static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb)
+{
+   const struct wmi_pdev_temperature_event *ev;
+
+   ev = (struct wmi_pdev_temperature_event *)skb-data;
+   if (WARN_ON(skb-len  sizeof(*ev)))
+   return -EPROTO;
+
+   return 0;
+}
+
 static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
 {
struct wmi_cmd_hdr *cmd_hdr;
@@ -3133,6 +3147,9 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, 
struct sk_buff *skb)
case WMI_10_2_READY_EVENTID:
ath10k_wmi_event_ready(ar, skb);
break;
+   case WMI_10_2_PDEV_TEMPERATURE_EVENTID:
+   ath10k_wmi_event_temperature(ar, skb);
+   break;
case WMI_10_2_RTT_KEEPALIVE_EVENTID:
case WMI_10_2_GPIO_INPUT_EVENTID:
case WMI_10_2_PEER_RATECODE_LIST_EVENTID:
@@ -4414,6 +4431,19 @@ 

[PATCH 5/5] ath10k: add thermal sensor device support

2014-12-14 Thread Rajkumar Manoharan
Temperature sensor generates electrical analog voltage from temperature
of each chain. The analog voltage is converted to digital value through
ADC. For reading temperature values fom user space, hw monitoring device
is used.

Whenever the user requests for current temperature, the driver sends WMI
command and wait for response. For reading temperature,

cat /sys/class/ieee80211/phy*/device/hwmon/hwmon2/temp1_input

Signed-off-by: Rajkumar Manoharan rmano...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c|  2 +
 drivers/net/wireless/ath/ath10k/thermal.c | 83 +++
 drivers/net/wireless/ath/ath10k/thermal.h | 14 ++
 drivers/net/wireless/ath/ath10k/wmi.c |  1 +
 4 files changed, 100 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 2eb3f2c..ed2abc9 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -840,6 +840,7 @@ static void ath10k_core_restart(struct work_struct *work)
complete_all(ar-offchan_tx_completed);
complete_all(ar-install_key_done);
complete_all(ar-vdev_setup_done);
+   complete_all(ar-thermal.wmi_sync);
wake_up(ar-htt.empty_tx_wq);
wake_up(ar-wmi.tx_credits_wq);
wake_up(ar-peer_mapping_wq);
@@ -1320,6 +1321,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, 
struct device *dev,
 
init_completion(ar-install_key_done);
init_completion(ar-vdev_setup_done);
+   init_completion(ar-thermal.wmi_sync);
 
INIT_DELAYED_WORK(ar-scan.timeout, ath10k_scan_timeout_work);
 
diff --git a/drivers/net/wireless/ath/ath10k/thermal.c 
b/drivers/net/wireless/ath/ath10k/thermal.c
index e98ce8c..d939135 100644
--- a/drivers/net/wireless/ath/ath10k/thermal.c
+++ b/drivers/net/wireless/ath/ath10k/thermal.c
@@ -17,6 +17,8 @@
 #include linux/device.h
 #include linux/sysfs.h
 #include linux/thermal.h
+#include linux/hwmon.h
+#include linux/hwmon-sysfs.h
 #include core.h
 #include debug.h
 #include wmi-ops.h
@@ -119,9 +121,72 @@ static struct thermal_cooling_device_ops 
ath10k_thermal_ops = {
.set_cur_state = ath10k_thermal_set_cur_dutycycle,
 };
 
+static ssize_t ath10k_thermal_show_temp(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct ath10k *ar = dev_get_drvdata(dev);
+   int ret, temperature;
+
+   mutex_lock(ar-conf_mutex);
+
+   /* Can't get temperature when the card is off */
+   if (ar-state != ATH10K_STATE_ON) {
+   ret = -ENETDOWN;
+   goto out;
+   }
+
+   reinit_completion(ar-thermal.wmi_sync);
+   ret = ath10k_wmi_pdev_get_temperature(ar);
+   if (ret) {
+   ath10k_warn(ar, failed to read temperature %d\n, ret);
+   goto out;
+   }
+
+   if (test_bit(ATH10K_FLAG_CRASH_FLUSH, ar-dev_flags)) {
+   ret = -ESHUTDOWN;
+   goto out;
+   }
+
+   ret = wait_for_completion_timeout(ar-thermal.wmi_sync,
+ ATH10K_THERMAL_SYNC_TIMEOUT_HZ);
+   if (ret == 0) {
+   ath10k_warn(ar, failed to synchronize thermal read\n);
+   ret = -ETIMEDOUT;
+   goto out;
+   }
+
+   spin_lock_bh(ar-data_lock);
+   temperature = ar-thermal.temperature;
+   spin_unlock_bh(ar-data_lock);
+
+   ret = snprintf(buf, PAGE_SIZE, %d, temperature);
+out:
+   mutex_unlock(ar-conf_mutex);
+   return ret;
+}
+
+void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature)
+{
+   spin_lock_bh(ar-data_lock);
+   ar-thermal.temperature = temperature;
+   spin_unlock_bh(ar-data_lock);
+   complete(ar-thermal.wmi_sync);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ath10k_thermal_show_temp,
+ NULL, 0);
+
+static struct attribute *ath10k_hwmon_attrs[] = {
+   sensor_dev_attr_temp1_input.dev_attr.attr,
+   NULL,
+};
+ATTRIBUTE_GROUPS(ath10k_hwmon);
+
 int ath10k_thermal_register(struct ath10k *ar)
 {
struct thermal_cooling_device *cdev;
+   struct device *hwmon_dev;
int ret;
 
cdev = thermal_cooling_device_register(ath10k_thermal, ar,
@@ -141,8 +206,26 @@ int ath10k_thermal_register(struct ath10k *ar)
}
 
ar-thermal.cdev = cdev;
+
+   /* Do not register hwmon device when temperature reading is not
+* supported by firmware
+*/
+   if (ar-wmi.op_version != ATH10K_FW_WMI_OP_VERSION_10_2_4)
+   return 0;
+
+   hwmon_dev = devm_hwmon_device_register_with_groups(ar-dev,
+  ath10k_hwmon, ar,
+  ath10k_hwmon_groups);
+   if (IS_ERR(hwmon_dev)) {
+   ath10k_err(ar, failed to register hwmon device: %ld\n,
+