[PATCH] mac80211: rewrite Kconfig text for mesh

2018-12-04 Thread Bob Copeland
Lubomir Rintel recently pointed out a dead link for o11s.org, and
repointed it to a still live, but also stale website.  As far as I
know, no one is updating the content at open80211s.org.

Since this Kconfig text was originally written, though, the 802.11s
mesh drafts were approved and ultimately rolled into 802.11 proper.
Meanwhile, the implementation has converged on the final standard,
so we can lose all of the text here and provide something that's a
little more helpful and accurate.

Signed-off-by: Bob Copeland 
---
 net/mac80211/Kconfig | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index f869e35d0974..6b09355dfc90 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -57,14 +57,13 @@ comment "Some wireless drivers require a rate control 
algorithm"
depends on MAC80211 && MAC80211_HAS_RC=n
 
 config MAC80211_MESH
-   bool "Enable mac80211 mesh networking (pre-802.11s) support"
+   bool "Enable mac80211 mesh networking support"
depends on MAC80211
---help---
-This options enables support of Draft 802.11s mesh networking.
-The implementation is based on Draft 2.08 of the Mesh Networking
-amendment.  However, no compliance with that draft is claimed or even
-possible, as drafts leave a number of identifiers to be defined after
-ratification.  For more information visit http://o11s.org/.
+ Select this option to enable 802.11 mesh operation in mac80211
+ drivers that support it.  802.11 mesh connects multiple stations
+ over (possibly multi-hop) wireless links to form a single logical
+ LAN.
 
 config MAC80211_LEDS
bool "Enable LED triggers"
-- 
2.11.0



Re: mac80211_hwsim: multiple antennas

2018-11-23 Thread Bob Copeland
On Wed, Nov 21, 2018 at 01:30:40PM +0100, Johannes Berg wrote:
> On Wed, 2018-11-21 at 09:26 -0300, Ramon Fontes wrote:
> > Sorry. I meant throughput.
> 
> Yeah, well. There's no actual medium (access) simulation in hwsim, so
> the actual throughput you get only depends on the performance of your
> CPU. 33Mbps seems quite low, but of course I don't know where you're
> running this.
> 
> Then again, you say you're using wmediumd, so perhaps that *does* have
> some sort of medium simulation these days? I didn't think it has it but
> I may very well be wrong on that.

wmediumd does simulate the medium, but it only ever handled simple OFDM
PHY rates, not MCS or aggregation or anything else from the last decade :)

-- 
Bob Copeland %% https://bobcopeland.com/


[PATCH] {nl,mac}80211: add rssi to mesh candidates

2018-10-26 Thread Bob Copeland
When peering is in userspace, some implementations may want to control
which peers are accepted based on RSSI in addition to the information
elements being sent today.  Add signal level so that info is available
to clients.

Signed-off-by: Bob Copeland 
---
 include/net/cfg80211.h|  3 ++-
 net/mac80211/mesh.c   |  3 ++-
 net/mac80211/mesh.h   |  3 ++-
 net/mac80211/mesh_plink.c | 32 ++--
 net/wireless/nl80211.c|  7 +--
 5 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1fa41b7a1be3..2e7710adacb0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5328,7 +5328,8 @@ void cfg80211_ibss_joined(struct net_device *dev, const 
u8 *bssid,
  * cfg80211 then sends a notification to userspace.
  */
 void cfg80211_notify_new_peer_candidate(struct net_device *dev,
-   const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp);
+   const u8 *macaddr, const u8 *ie, u8 ie_len,
+   int sig_dbm, gfp_t gfp);
 
 /**
  * DOC: RFkill integration
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 8bad414c52ad..ea76d4dbdd49 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1191,7 +1191,8 @@ static void ieee80211_mesh_rx_bcn_presp(struct 
ieee80211_sub_if_data *sdata,
if (!sdata->u.mesh.user_mpm ||
sdata->u.mesh.mshcfg.rssi_threshold == 0 ||
sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal)
-   mesh_neighbour_update(sdata, mgmt->sa, );
+   mesh_neighbour_update(sdata, mgmt->sa, ,
+ rx_status);
}
 
if (ifmsh->sync_ops)
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 21526630bf65..cad6592c52a1 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -273,7 +273,8 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
 
 /* Mesh plinks */
 void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
-  u8 *hw_addr, struct ieee802_11_elems *ie);
+  u8 *hw_addr, struct ieee802_11_elems *ie,
+  struct ieee80211_rx_status *rx_status);
 bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
 u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
 void mesh_plink_timer(struct timer_list *t);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 5b5b0f95ffd1..9e8d80533562 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -513,7 +513,8 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, 
u8 *hw_addr)
 
 static struct sta_info *
 mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
-   struct ieee802_11_elems *elems)
+   struct ieee802_11_elems *elems,
+   struct ieee80211_rx_status *rx_status)
 {
struct sta_info *sta = NULL;
 
@@ -521,11 +522,17 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, 
u8 *addr,
if (sdata->u.mesh.user_mpm ||
sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
if (mesh_peer_accepts_plinks(elems) &&
-   mesh_plink_availables(sdata))
+   mesh_plink_availables(sdata)) {
+   int sig = 0;
+
+   if (ieee80211_hw_check(>local->hw, SIGNAL_DBM))
+   sig = rx_status->signal;
+
cfg80211_notify_new_peer_candidate(sdata->dev, addr,
   elems->ie_start,
   elems->total_len,
-  GFP_KERNEL);
+  sig, GFP_KERNEL);
+   }
} else
sta = __mesh_sta_info_alloc(sdata, addr);
 
@@ -538,13 +545,15 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, 
u8 *addr,
  * @sdata: local meshif
  * @addr: peer's address
  * @elems: IEs from beacon or mesh peering frame.
+ * @rx_status: rx status for the frame for signal reporting
  *
  * Return existing or newly allocated sta_info under RCU read lock.
  * (re)initialize with given IEs.
  */
 static struct sta_info *
 mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
- u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU)
+ u8 *addr, struct ieee802_11_elems *elems,
+ struct ieee80211_rx_status *rx_status) __acquires(RCU)
 {
struct sta_info *sta = NULL;
 
@@ -555,7 +564,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
} else {
rcu_read_unlock();
/* can't run atomic */
-   sta = mesh_sta_info_alloc(sdata, a

[PATCH v2 3/3] {nl,mac}80211: add dot11MeshConnectedToMeshGate to meshconf

2018-10-25 Thread Bob Copeland
When userspace is controlling mesh routing, it may have better
knowledge about whether a mesh STA is connected to a mesh
gate than the kernel mpath table.  Add dot11MeshConnectedToMeshGate
to the mesh config so that such applications can explicitly
signal that a mesh STA is connected to a gate, which will then
be advertised in the beacon.

Signed-off-by: Bob Copeland 
---

v2: add policy range and type comment

 include/net/cfg80211.h| 5 +
 include/uapi/linux/nl80211.h  | 8 +++-
 net/mac80211/cfg.c| 3 +++
 net/mac80211/debugfs_netdev.c | 3 +++
 net/mac80211/mesh.c   | 3 ++-
 net/wireless/nl80211.c| 8 +++-
 6 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f2cb1a3c9651..cddaa9dacb27 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1562,6 +1562,10 @@ struct bss_parameters {
  * @plink_timeout: If no tx activity is seen from a STA we've established
  * peering with for longer than this time (in seconds), then remove it
  * from the STA's list of peers.  Default is 30 minutes.
+ * @dot11MeshConnectedToMeshGate: if set to true, advertise that this STA is
+ *  connected to a mesh gate in mesh formation info.  If false, the
+ *  value in mesh formation is determined by the presence of root paths
+ *  in the mesh path table
  */
 struct mesh_config {
u16 dot11MeshRetryTimeout;
@@ -1581,6 +1585,7 @@ struct mesh_config {
u16 dot11MeshHWMPperrMinInterval;
u16 dot11MeshHWMPnetDiameterTraversalTime;
u8 dot11MeshHWMPRootMode;
+   bool dot11MeshConnectedToMeshGate;
u16 dot11MeshHWMPRannInterval;
bool dot11MeshGateAnnouncementProtocol;
bool dot11MeshForwarding;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f2d79f9b4b5a..ba0dc0afdc29 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3075,7 +3075,7 @@ enum nl80211_sta_bss_param {
  * some packets with an FCS error due to TA corruption. Hence this counter
  * might not be fully accurate.
  * @NL80211_STA_INFO_CONNECTED_TO_GATE: set to true if STA has a path to a
- * mesh gate
+ * mesh gate (u8, 0 or 1)
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
@@ -3898,6 +3898,11 @@ enum nl80211_mesh_power_mode {
  * remove it from the STA's list of peers. You may set this to 0 to disable
  * the removal of the STA. Default is 30 minutes.
  *
+ * @NL80211_MESHCONF_CONNECTED_TO_GATE: If set to true then this mesh STA
+ * will advertise that it is connected to a gate in the mesh formation
+ * field.  If left unset then the mesh formation field will only
+ * advertise such if there is an active root mesh path.
+ *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
  */
 enum nl80211_meshconf_params {
@@ -3930,6 +3935,7 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_POWER_MODE,
NL80211_MESHCONF_AWAKE_WINDOW,
NL80211_MESHCONF_PLINK_TIMEOUT,
+   NL80211_MESHCONF_CONNECTED_TO_GATE,
 
/* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 51622333d460..6d1c54f28df7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2028,6 +2028,9 @@ static int ieee80211_update_mesh_config(struct wiphy 
*wiphy,
nconf->dot11MeshAwakeWindowDuration;
if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask))
conf->plink_timeout = nconf->plink_timeout;
+   if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_GATE, mask))
+   conf->dot11MeshConnectedToMeshGate =
+   nconf->dot11MeshConnectedToMeshGate;
ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON);
return 0;
 }
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index c813207bb123..cff0fb3578c9 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -641,6 +641,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
 IEEE80211_IF_FILE(power_mode, u.mesh.mshcfg.power_mode, DEC);
 IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
  u.mesh.mshcfg.dot11MeshAwakeWindowDuration, DEC);
+IEEE80211_IF_FILE(dot11MeshConnectedToMeshGate,
+ u.mesh.mshcfg.dot11MeshConnectedToMeshGate, DEC);
 #endif
 
 #define DEBUGFS_ADD_MODE(name, mode) \
@@ -762,6 +764,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data 
*sdata)
MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
MESHPARAMS_ADD(power_mode);
MESHPARAMS_ADD(dot11MeshAwakeWindowDuration);
+   MESHPARAMS_ADD(dot11MeshConnectedToMeshGate);
 #undef MESHPARAMS_ADD
 }
 #endif
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 19205c821dee..4869280a6413 100644
--- a/net/mac80211/mesh.c
+++

[PATCH 1/3] mac80211: mesh: advertise gates in mesh formation

2018-10-25 Thread Bob Copeland
The Connected to Mesh Gate subfield (802.11-2016 9.4.2.98.7) in the Mesh
Formation Info field is currently unset.  This field may be useful in
determining which MBSSes to join or which mesh STAs to peer with.

If this mesh STA is a gate, by having turned on mesh gate announcements,
or if we have a path to one (e.g. by having received RANNs) then set this
bit to 1.

Signed-off-by: Bob Copeland 
---
 net/mac80211/mesh.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 8bad414c52ad..19205c821dee 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -254,6 +254,8 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data 
*sdata,
struct ieee80211_if_mesh *ifmsh = >u.mesh;
u8 *pos, neighbors;
u8 meshconf_len = sizeof(struct ieee80211_meshconf_ie);
+   bool is_connected_to_gate = ifmsh->num_gates > 0 ||
+   ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol;
 
if (skb_tailroom(skb) < 2 + meshconf_len)
return -ENOMEM;
@@ -278,7 +280,7 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data 
*sdata,
/* Mesh Formation Info - number of neighbors */
neighbors = atomic_read(>estab_plinks);
neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS);
-   *pos++ = neighbors << 1;
+   *pos++ = (neighbors << 1) | is_connected_to_gate;
/* Mesh capability */
*pos = 0x00;
*pos |= ifmsh->mshcfg.dot11MeshForwarding ?
-- 
2.11.0



[PATCH 2/3] {nl,mac}80211: report gate connectivity in station info

2018-10-25 Thread Bob Copeland
Capture the current state of gate connectivity from the mesh
formation field in mesh config whenever we receive a beacon,
and report that via GET_STATION.  This allows applications
doing mesh peering in userspace to make peering decisions
based on peers' current upstream connectivity.

Signed-off-by: Bob Copeland 
---
 include/linux/ieee80211.h| 2 ++
 include/net/cfg80211.h   | 3 +++
 include/uapi/linux/nl80211.h | 3 +++
 net/mac80211/mesh_plink.c| 3 +++
 net/mac80211/sta_info.c  | 4 +++-
 net/mac80211/sta_info.h  | 2 ++
 net/wireless/nl80211.c   | 1 +
 7 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 0ef67f837ae1..407d6fd66fa9 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -812,6 +812,8 @@ enum mesh_config_capab_flags {
IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL   = 0x40,
 };
 
+#define IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE 0x1
+
 /**
  * mesh channel switch parameters element's flag indicator
  *
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1fa41b7a1be3..f2cb1a3c9651 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1296,6 +1296,7 @@ struct cfg80211_tid_stats {
  * @rx_beacon: number of beacons received from this peer
  * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received
  * from this peer
+ * @connected_to_gate: true if mesh STA has a path to mesh gate
  * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer
  * @pertid: per-TID statistics, see  cfg80211_tid_stats, using the last
  * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs.
@@ -1350,6 +1351,8 @@ struct station_info {
u64 rx_beacon;
u64 rx_duration;
u8 rx_beacon_signal_avg;
+   u8 connected_to_gate;
+
struct cfg80211_tid_stats *pertid;
s8 ack_signal;
s8 avg_ack_signal;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 6d610bae30a9..f2d79f9b4b5a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3074,6 +3074,8 @@ enum nl80211_sta_bss_param {
  * with an FCS error (u32, from this station). This count may not include
  * some packets with an FCS error due to TA corruption. Hence this counter
  * might not be fully accurate.
+ * @NL80211_STA_INFO_CONNECTED_TO_GATE: set to true if STA has a path to a
+ * mesh gate
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
@@ -3116,6 +3118,7 @@ enum nl80211_sta_info {
NL80211_STA_INFO_ACK_SIGNAL_AVG,
NL80211_STA_INFO_RX_MPDUS,
NL80211_STA_INFO_FCS_ERROR_COUNT,
+   NL80211_STA_INFO_CONNECTED_TO_GATE,
 
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 5b5b0f95ffd1..5f45a2b273df 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -590,6 +590,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data 
*sdata,
if (!sta)
goto out;
 
+   sta->mesh->connected_to_gate = elems->mesh_config->meshconf_form &
+   IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE;
+
if (mesh_peer_accepts_plinks(elems) &&
sta->mesh->plink_state == NL80211_PLINK_LISTEN &&
sdata->u.mesh.accepting_plinks &&
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index fb8c2252ac0e..971f06911ff8 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2267,7 +2267,8 @@ void sta_set_sinfo(struct sta_info *sta, struct 
station_info *sinfo,
 BIT_ULL(NL80211_STA_INFO_PLINK_STATE) |
 BIT_ULL(NL80211_STA_INFO_LOCAL_PM) |
 BIT_ULL(NL80211_STA_INFO_PEER_PM) |
-BIT_ULL(NL80211_STA_INFO_NONPEER_PM);
+BIT_ULL(NL80211_STA_INFO_NONPEER_PM) |
+BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE);
 
sinfo->llid = sta->mesh->llid;
sinfo->plid = sta->mesh->plid;
@@ -2279,6 +2280,7 @@ void sta_set_sinfo(struct sta_info *sta, struct 
station_info *sinfo,
sinfo->local_pm = sta->mesh->local_pm;
sinfo->peer_pm = sta->mesh->peer_pm;
sinfo->nonpeer_pm = sta->mesh->nonpeer_pm;
+   sinfo->connected_to_gate = sta->mesh->connected_to_gate;
 #endif
}
 
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 9a04327d71d1..8eb29041be54 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -364,6 +364,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8)
  * @nonpeer_pm: STA power save mode towards non-pe

[PATCH 3/3] {nl,mac}80211: add dot11MeshConnectedToMeshGate to meshconf

2018-10-25 Thread Bob Copeland
When userspace is controlling mesh routing, it may have better
knowledge about whether a mesh STA is connected to a mesh
gate than the kernel mpath table.  Add dot11MeshConnectedToMeshGate
to the mesh config so that such applications can explicitly
signal that a mesh STA is connected to a gate, which will then
be advertised in the beacon.

Signed-off-by: Bob Copeland 
---
 include/net/cfg80211.h| 5 +
 include/uapi/linux/nl80211.h  | 6 ++
 net/mac80211/cfg.c| 3 +++
 net/mac80211/debugfs_netdev.c | 3 +++
 net/mac80211/mesh.c   | 3 ++-
 net/wireless/nl80211.c| 8 +++-
 6 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f2cb1a3c9651..cddaa9dacb27 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1562,6 +1562,10 @@ struct bss_parameters {
  * @plink_timeout: If no tx activity is seen from a STA we've established
  * peering with for longer than this time (in seconds), then remove it
  * from the STA's list of peers.  Default is 30 minutes.
+ * @dot11MeshConnectedToMeshGate: if set to true, advertise that this STA is
+ *  connected to a mesh gate in mesh formation info.  If false, the
+ *  value in mesh formation is determined by the presence of root paths
+ *  in the mesh path table
  */
 struct mesh_config {
u16 dot11MeshRetryTimeout;
@@ -1581,6 +1585,7 @@ struct mesh_config {
u16 dot11MeshHWMPperrMinInterval;
u16 dot11MeshHWMPnetDiameterTraversalTime;
u8 dot11MeshHWMPRootMode;
+   bool dot11MeshConnectedToMeshGate;
u16 dot11MeshHWMPRannInterval;
bool dot11MeshGateAnnouncementProtocol;
bool dot11MeshForwarding;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f2d79f9b4b5a..d04391ae4acd 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3898,6 +3898,11 @@ enum nl80211_mesh_power_mode {
  * remove it from the STA's list of peers. You may set this to 0 to disable
  * the removal of the STA. Default is 30 minutes.
  *
+ * @NL80211_MESHCONF_CONNECTED_TO_GATE: If set to true then this mesh STA
+ * will advertise that it is connected to a gate in the mesh formation
+ * field.  If left unset then the mesh formation field will only
+ * advertise such if there is an active root mesh path.
+ *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
  */
 enum nl80211_meshconf_params {
@@ -3930,6 +3935,7 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_POWER_MODE,
NL80211_MESHCONF_AWAKE_WINDOW,
NL80211_MESHCONF_PLINK_TIMEOUT,
+   NL80211_MESHCONF_CONNECTED_TO_GATE,
 
/* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 51622333d460..6d1c54f28df7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2028,6 +2028,9 @@ static int ieee80211_update_mesh_config(struct wiphy 
*wiphy,
nconf->dot11MeshAwakeWindowDuration;
if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask))
conf->plink_timeout = nconf->plink_timeout;
+   if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_GATE, mask))
+   conf->dot11MeshConnectedToMeshGate =
+   nconf->dot11MeshConnectedToMeshGate;
ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON);
return 0;
 }
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index c813207bb123..cff0fb3578c9 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -641,6 +641,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
 IEEE80211_IF_FILE(power_mode, u.mesh.mshcfg.power_mode, DEC);
 IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
  u.mesh.mshcfg.dot11MeshAwakeWindowDuration, DEC);
+IEEE80211_IF_FILE(dot11MeshConnectedToMeshGate,
+ u.mesh.mshcfg.dot11MeshConnectedToMeshGate, DEC);
 #endif
 
 #define DEBUGFS_ADD_MODE(name, mode) \
@@ -762,6 +764,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data 
*sdata)
MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
MESHPARAMS_ADD(power_mode);
MESHPARAMS_ADD(dot11MeshAwakeWindowDuration);
+   MESHPARAMS_ADD(dot11MeshConnectedToMeshGate);
 #undef MESHPARAMS_ADD
 }
 #endif
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 19205c821dee..4869280a6413 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -255,7 +255,8 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data 
*sdata,
u8 *pos, neighbors;
u8 meshconf_len = sizeof(struct ieee80211_meshconf_ie);
bool is_connected_to_gate = ifmsh->num_gates > 0 ||
-   ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol;
+   ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol ||
+   ifmsh->mshcf

[PATCH] mac80211: fix pending queue hang due to TX_DROP

2018-09-05 Thread Bob Copeland
In our environment running lots of mesh nodes, we are seeing the
pending queue hang periodically, with the debugfs queues file showing
lines such as:

00: 0x/348

i.e. there are a large number of frames but no stop reason set.

One way this could happen is if queue processing from the pending
tasklet exited early without processing all frames, and without having
some future event (incoming frame, stop reason flag, ...) to reschedule
it.

Exactly this can occur today if ieee80211_tx() returns false due to
packet drops or power-save buffering in the tx handlers.  In the
past, this function would return true in such cases, and the change
to false doesn't seem to be intentional.  Fix this case by reverting
to the previous behavior.

Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ 
dequeue")
Signed-off-by: Bob Copeland 
---
 net/mac80211/tx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e88547842239..6b83dc397c3e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1907,7 +1907,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data 
*sdata,
sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
 
if (invoke_tx_handlers_early())
-   return false;
+   return true;
 
if (ieee80211_queue_skb(local, sdata, tx.sta, tx.skb))
return true;
-- 
2.11.0



[PATCH] nl80211: relax ht operation checks for mesh

2018-06-24 Thread Bob Copeland
Commit 9757235f451c, "nl80211: correct checks for
NL80211_MESHCONF_HT_OPMODE value") relaxed the range for the HT
operation field in meshconf, while also adding checks requiring
the non-greenfield and non-ht-sta bits to be set in certain
circumstances.  The latter bit is actually reserved for mesh BSSes
according to Table 9-168 in 802.11-2016, so in fact it should not
be set.

wpa_supplicant sets these bits because the mesh and AP code share
the same implementation, but authsae does not.  As a result, some
meshconf updates from authsae which set only the NONHT_MIXED
protection bits were being rejected.

In order to avoid breaking userspace by changing the rules again,
simply accept the values with or without the bits set, and mask
off the reserved bit to match the spec.

While in here, update the 802.11-2012 reference to 802.11-2016.

Fixes: 9757235f451c ("nl80211: correct checks for NL80211_MESHCONF_HT_OPMODE 
value")
Cc: Masashi Honma 
Signed-off-by: Bob Copeland 
---
 net/wireless/nl80211.c | 19 +++
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f5e36a23cae3..c9ba4edf25cc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5837,7 +5837,7 @@ do {  
\
  nl80211_check_s32);
/*
 * Check HT operation mode based on
-* IEEE 802.11 2012 8.4.2.59 HT Operation element.
+* IEEE 802.11-2016 9.4.2.57 HT Operation element.
 */
if (tb[NL80211_MESHCONF_HT_OPMODE]) {
ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
@@ -5847,22 +5847,9 @@ do { 
\
  IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
return -EINVAL;
 
-   if ((ht_opmode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
-   (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
-   return -EINVAL;
+   /* NON_HT_STA bit is reserved, but some programs set it */
+   ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
 
-   switch (ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION) {
-   case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
-   case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
-   if (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)
-   return -EINVAL;
-   break;
-   case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
-   case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
-   if (!(ht_opmode & 
IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
-   return -EINVAL;
-   break;
-   }
cfg->ht_opmode = ht_opmode;
mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
}
-- 
2.9.5



Re: [PATCH] ath10k: transmit queued frames after waking queues

2018-05-25 Thread Bob Copeland
On Fri, May 25, 2018 at 02:36:56PM +0200, Niklas Cassel wrote:
> A spin lock does have the advantage of ordering: memory operations issued
> before the spin_unlock_bh() will be completed before the spin_unlock_bh()
> operation has completed.
> 
> However, ath10k_htt_tx_dec_pending() was called earlier in the same function,
> which decreases htt->num_pending_tx, so that write will be completed before
> our read. That is the only ordering we care about here (if we should call
> ath10k_mac_tx_push_pending() or not).

Sure.  I also understand that reading inside a lock and operating on the
value outside the lock isn't really the definition of synchronization
(doesn't really matter in this case though).

I was just suggesting that the implicit memory barrier in the spin unlock
that we are already paying for would be sufficient here too, and it matches
the semantic of "tx fields under tx_lock."  On the other hand, maybe it's
just me, but I tend to look askance at just-in-case READ_ONCEs sprinkled
about.

-- 
Bob Copeland %% https://bobcopeland.com/


Re: [PATCH] ath10k: transmit queued frames after waking queues

2018-05-24 Thread Bob Copeland
On Mon, May 21, 2018 at 10:37:01PM +0200, Niklas Cassel wrote:
> On Thu, May 17, 2018 at 03:26:25PM -0700, Adrian Chadd wrote:
> > On Thu, 17 May 2018 at 16:16, Niklas Cassel <niklas.cas...@linaro.org>
> > wrote:
> > 
> > > diff --git a/drivers/net/wireless/ath/ath10k/txrx.c
> > b/drivers/net/wireless/ath/ath10k/txrx.c
> > > index cda164f6e9f6..1d3b2d2c3fee 100644
> > > --- a/drivers/net/wireless/ath/ath10k/txrx.c
> > > +++ b/drivers/net/wireless/ath/ath10k/txrx.c
> > > @@ -95,6 +95,9 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
> > >  wake_up(>empty_tx_wq);
> > >  spin_unlock_bh(>tx_lock);
> > 
> > > +   if (htt->num_pending_tx <= 3 && !list_empty(>txqs))
> > > +   ath10k_mac_tx_push_pending(ar);
> > > +
> > 
> > Just sanity checking - what's protecting htt->num_pending_tx? or is it
> > serialised some other way?
[...]
> I can't see that any of the examples applies, but let's add READ_ONCE(),
> to make sure that the compiler doesn't try to optimize this.

Couldn't you just move the num_pending_tx read inside tx_lock which is 2 lines
above?  I think all the other manipulations are protected by tx_lock.

-- 
Bob Copeland %% https://bobcopeland.com/


[PATCH] mac80211: mesh: fix premature update of rc stats

2018-05-17 Thread Bob Copeland
The mesh_neighbour_update() function, queued via beacon rx, can race with
userspace creating the same station.  If the station already exists by the
time mesh_neighbour_update() is called, the function wrongly assumes rate
control has been initialized and calls rate_control_rate_update(), which
in turn calls into the driver.

Updating the rate control before it has been initialized can cause a
crash in some drivers, for example this firmware crash in ath10k due
to sta->rx_nss being 0:

[ 3078.088247] mesh0: Inserted STA 5c:e2:8c:f1:ab:ba
[ 3078.258407] ath10k_pci :0d:00.0: firmware crashed! (uuid 
d6ed5961-93cc-4d61-803f-5eda55bb8643)
[ 3078.258421] ath10k_pci :0d:00.0: qca988x hw2.0 target 0x4100016c chip_id 
0x043202ff sub :
[ 3078.258426] ath10k_pci :0d:00.0: kconfig debug 1 debugfs 1 tracing 1 dfs 
0 testmode 0
[ 3078.258608] ath10k_pci :0d:00.0: firmware ver 10.2.4.70.59-2 api 5 
features no-p2p,raw-mode,mfp crc32 4159f498
[ 3078.258613] ath10k_pci :0d:00.0: board_file api 1 bmi_id N/A crc32 
bebc7c08
[ 3078.258617] ath10k_pci :0d:00.0: htt-ver 2.1 wmi-op 5 htt-op 2 cal otp 
max-sta 128 raw 0 hwcrypto 1
[ 3078.260627] ath10k_pci :0d:00.0: firmware register dump:
[ 3078.260640] ath10k_pci :0d:00.0: [00]: 0x4100016C 0x15B3 0x009A31BB 
0x00955B31
[ 3078.260647] ath10k_pci :0d:00.0: [04]: 0x009A31BB 0x00060130 0x0008 
0x0007
[ 3078.260652] ath10k_pci :0d:00.0: [08]: 0x 0x00955B31 0x 
0x0040F89E
[ 3078.260656] ath10k_pci :0d:00.0: [12]: 0x0009 0x 0x009580F5 
0x00958117
[ 3078.260660] ath10k_pci :0d:00.0: [16]: 0x00958080 0x0094085D 0x 
0x
[ 3078.260664] ath10k_pci :0d:00.0: [20]: 0x409A31BB 0x0040AA84 0x0002 
0x0001
[ 3078.260669] ath10k_pci :0d:00.0: [24]: 0x809A2B8D 0x0040AAE4 0x0088 
0xC09A31BB
[ 3078.260673] ath10k_pci :0d:00.0: [28]: 0x809898C8 0x0040AB04 0x0043F91C 
0x009C6458
[ 3078.260677] ath10k_pci :0d:00.0: [32]: 0x809B66AC 0x0040AB34 0x009C6458 
0x0043F91C
[ 3078.260686] ath10k_pci :0d:00.0: [36]: 0x809B2824 0x0040ADA4 0x0040 
0x00416EB4
[ 3078.260692] ath10k_pci :0d:00.0: [40]: 0x809C07D9 0x0040ADE4 0x0040AE08 
0x00412028
[ 3078.260696] ath10k_pci :0d:00.0: [44]: 0x809486FA 0x0040AE04 0x0001 
0x
[ 3078.260700] ath10k_pci :0d:00.0: [48]: 0x80948E2C 0x0040AEA4 0x0041F4F0 
0x00412634
[ 3078.260704] ath10k_pci :0d:00.0: [52]: 0x809BFC39 0x0040AEC4 0x0041F4F0 
0x0001
[ 3078.260709] ath10k_pci :0d:00.0: [56]: 0x80940F18 0x0040AF14 0x0010 
0x00403AC0
[ 3078.284130] ath10k_pci :0d:00.0: failed to to request monitor vdev 1 
stop: -108

Fix this by checking whether the sta has already initialized rate control
using the flag for that purpose.  We can also drop the unnecessary insert
parameter here.

Signed-off-by: Bob Copeland <bobcopel...@fb.com>
---
 net/mac80211/mesh_plink.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 0f6c9ca..5b5b0f9 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -401,7 +401,7 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
 
 static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
   struct sta_info *sta,
-  struct ieee802_11_elems *elems, bool insert)
+  struct ieee802_11_elems *elems)
 {
struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband;
@@ -447,7 +447,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data 
*sdata,
sta->sta.bandwidth = IEEE80211_STA_RX_BW_20;
}
 
-   if (insert)
+   if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
rate_control_rate_init(sta);
else
rate_control_rate_update(local, sband, sta, changed);
@@ -551,7 +551,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
rcu_read_lock();
sta = sta_info_get(sdata, addr);
if (sta) {
-   mesh_sta_info_init(sdata, sta, elems, false);
+   mesh_sta_info_init(sdata, sta, elems);
} else {
rcu_read_unlock();
/* can't run atomic */
@@ -561,7 +561,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
return NULL;
}
 
-   mesh_sta_info_init(sdata, sta, elems, true);
+   mesh_sta_info_init(sdata, sta, elems);
 
if (sta_info_insert_rcu(sta))
return NULL;
-- 
2.9.0



Re: [PATCH for-4.13] brcmfmac: fix regression in brcmf_sdio_txpkt_hdalign()

2017-07-12 Thread Bob Copeland
On Wed, Jul 12, 2017 at 10:32:48AM +0100, Arend van Spriel wrote:
> Recent change in brcmf_sdio_txpkt_hdalign() changed the
> behavior and now always returns 0. This resulted in a
> regression which basically renders the device useless.

Should this go via netdev as well, or just wait for Kalle (returning
on Sunday)?

-- 
Bob Copeland %% https://bobcopeland.com/


Deleting old wireless-testing tags

2017-03-01 Thread Bob Copeland
Hi all,

wireless-testing will resume again next week when the merge window opens,
and with 203 w-t tags since I started maintaining it a little over a year
ago, it's about time for some house-keeping.  I plan to delete some of the
older tags in the kernel.org copy.

Before I do so, quick straw poll of anyone using this kernel: are there
specific tags I should keep, or any specific time period I should keep them
around?

E.g. I believe lede/openwrt are using compat-wireless builds generated from
wireless-testing; it might be worth retaining those particular tags just for
reference.  I guess a few folks may be using it as a development tree and
would want a couple of kernel release cycles maintained, and so on.

-- 
Bob Copeland %% http://bobcopeland.com/


Re: [PATCH] mac80211: Remove invalid flag operations in mesh TSF synchronization

2016-12-07 Thread Bob Copeland
On Wed, Dec 07, 2016 at 09:55:41PM +0900, Masashi Honma wrote:
> >It's called mesh_sync_offset_adjust_tbtt() which matches more closely
> >"TBTT adjustment" than "neighbor offset synchronization"?
> 
> I think so. Because there is not any code creating "TBTT Adjustment Request
> frame" even though the frame is required by "TBTT adjustment".

This mesh_sync_offset_adjust_tbtt is definitely doing offset
synchronization, so probably "tbtt" should be renamed "tsf" here.

> >The code
> >looks more like offset synchronization though. Perhaps there's some
> >confusing and it's kinda doing both?
> 
> In theory, updating the flag with 1) looks not correct because it is not
> clearly defined in spec.
> 
> In practice, I could consider extending the meaning of the flag over the
> spec to use it to avoid referring the updating TSF value by peer as Thomas
> said. I have took the statistics how many TSF drift
> (ifmsh->sync_offset_clockdrift_max) happens. The attached file shows the
> stats. The horizontal axis shows TSF drift time(usec) and vertical axis
> shows how many time the drift occurred. The graph shows almost drifts are
> under 20usec. In contrast, 2) could causes more than 1000usec drift. So 1)
> looks not so large enough to protect with the flag.

Yes, offset synchronization is (given decent clocks) supposed to be only
for small tweaks.  We will do it up to .8 ms drift though -- above .8 ms, we
just reset drift to zero and adopt the new timing offset.  You can see this
kind of large "drift" by restarting a station.

Actually, looking at the code now it doesn't make a lot of sense to set
this flag for offset sync because TOFFSET_KNOWN flag is completely cleared
whenever that is set, so we have to be forgetting the current t_offset all
the time?

-- 
Bob Copeland %% http://bobcopeland.com/


Re: ath10k stuck in mesh mode

2016-11-19 Thread Bob Copeland
On Fri, Nov 18, 2016 at 10:43:06PM +0100, Matteo Grandi wrote:
> So the question is: who decide if use MIMO and higher MCS hopefully on
> 80MHz channel or not? Is the firmware? Is there a way to force the
> interface to use 80MHz and/or MIMO? (iw provide the possibility to
> choose between [HT20/HT40-/HT40+]).

You can specify the channel width like so:

iw dev wlan0 set freq 5745 80 5775
iw dev wlan0 mesh join mesh-vht

-- 
Bob Copeland %% http://bobcopeland.com/


Re: [PATCH] mac80211: fix sequence number allocation regression

2016-10-12 Thread Bob Copeland
On Wed, Oct 12, 2016 at 08:49:45AM +0200, Johannes Berg wrote:
> On Tue, 2016-10-11 at 11:28 +0200, Felix Fietkau wrote:
> > The recent commit that moved around TX handlers dropped the sequence
> > number allocation at the end of ieee80211_tx_dequeue and calls
> > ieee80211_tx_h_sequence instead (for the non-fast-xmit case).
> > However, it did not change the fast-xmit sequence allocation
> > condition
> > in ieee80211_xmit_fast_finish, which skipped seqno alloc if
> > intermediate
> > tx queues are being used.
> > 
> > Drop the now obsolete condition.
> 
> Hm. I don't know what tree you're looking at, but it looks like I *did*
> in fact resolve this correctly; the (now) erroneous condition doesn't
> exist in mac80211 nor in mac80211-next (nor net, net-next, linux).
> 
> It does seem to exist in wireless-testing, but that's not something I
> can control.

Sorry about that, I should've rechecked this after Johannes did the merge.
I applied this patch (to wireless-testing) and pushed tag wt-2016-10-12.
Let me know of any further issues.

As a check I also diffed against mac80211-next/master and found additional
merge damage in the diff which I fixed up.  Once the merge window closes
in a few days, I'll resync to the masters of all the trees.

-- 
Bob Copeland %% http://bobcopeland.com/


Re: Final 4.8 w-t build is wt-2016-10-03

2016-10-03 Thread Bob Copeland
On Mon, Oct 03, 2016 at 04:42:58PM +0200, Christian Lamparter wrote:
> Thanks for the timely update. 
> I have a request: can you please pull Linus' kernel tags?
> Currently the last tag from Linus' is v4.4-rc4 [0] and
> everything between v4.4-rc5 and v4.8 is missing?!

I've done this now.

-- 
Bob Copeland %% http://bobcopeland.com/


Re: Final 4.8 w-t build is wt-2016-10-03

2016-10-03 Thread Bob Copeland
On Mon, Oct 03, 2016 at 04:42:58PM +0200, Christian Lamparter wrote:
> Hello,
> 
> On Monday, October 3, 2016 9:45:07 AM CEST Bob Copeland wrote:
> > Per the subject, Linus released 4.8 yesterday so, unless I broke something
> > in recent conflict resolutions, wireless-testing is on pause until the
> > merge window closes in two weeks.  Have a happy (Canadian) thanksgiving!
> > 
> > https://git.kernel.org/cgit/linux/kernel/git/wireless/wireless-testing.git
> 
> Thanks for the timely update. 
> I have a request: can you please pull Linus' kernel tags?
> Currently the last tag from Linus' is v4.4-rc4 [0] and
> everything between v4.4-rc5 and v4.8 is missing?!

Sure, I can start including them.  I stopped pushing them in 4.4 era
because I thought it might be too cluttered to have these non-wt tags
sitting around, but it's no problem to go back and push the old ones
and do that going forward.

-- 
Bob Copeland %% http://bobcopeland.com/


Final 4.8 w-t build is wt-2016-10-03

2016-10-03 Thread Bob Copeland
Per the subject, Linus released 4.8 yesterday so, unless I broke something
in recent conflict resolutions, wireless-testing is on pause until the
merge window closes in two weeks.  Have a happy (Canadian) thanksgiving!

https://git.kernel.org/cgit/linux/kernel/git/wireless/wireless-testing.git

-- 
Bob Copeland %% http://bobcopeland.com/


Re: Using ath5k/ath9k radio for constant-tx noise source.

2016-09-18 Thread Bob Copeland
On Wed, Aug 19, 2015 at 12:07:50PM -0700, Ben Greear wrote:
> I have a commercial AP that is using a CM9 ath5k radio (evidently, I could be 
> wrong)
> and it has the ability to do a constant transmit of raw noise (RF probe shows
> noise, but a monitor-port sniffer does not see any frames from the CM9).
> 
> I don't know the low-level details of how it is doing this, but I suspect
> it is using something like madwifi for a driver.
> 
> Does anyone know how this can be done with modern software and
> ath5k or ath9k NICs?

So, see the below patch for something that might work.  I only dusted off
and compile-tested this, and I'm not sure if it is controllable to the
extent that would be needed for things like DFS testing.

Just to reiterate the disclaimer, I'm told running radio in this mode for
an extended period of time can damage it, so -- good luck.

Note, ath9k has another kind of tx-99 mode which just sends out packets
constantly; ath5k is of course capable of doing that kind of thing too.
Setup for that is mostly the same except the descriptor list is just
self-linked and some of the phy tricks aren't needed.

>From fd374ea31833f705d6a08bb8f8e171cfcda8c302 Mon Sep 17 00:00:00 2001
From: Bob Copeland <m...@bobcopeland.com>
Date: Tue, 17 May 2016 00:24:42 -0400
Subject: [PATCH] ath5k: add continuous-wave transmit mode

Continuous-wave mode is a kind of testmode in which RF is emitted on
a single carrier frequency; sometimes this kind of thing is needed
for FCC certification.  Some Atheros devices support entering this
mode for testing.

This patch demonstrates (some of?) the settings needed to get the
device into the mode.  I don't claim to understand it and the PHY
is 100% undocumented as far as I know, so a lot of this is guesswork
based on what is done in some versions of madwifi.  It seems to work
on one radio I tried it on (monitored with ath9k's spectral scan and
my own "speccy" tool) -- but it might well destroy yours, so, don't
run it unless you don't care about that possibility.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 drivers/net/wireless/ath/ath5k/Makefile |   1 +
 drivers/net/wireless/ath/ath5k/ath5k.h  |   1 +
 drivers/net/wireless/ath/ath5k/base.h   |   3 +
 drivers/net/wireless/ath/ath5k/debug.c  |  47 
 drivers/net/wireless/ath/ath5k/tx99.c   | 200 
 5 files changed, 252 insertions(+)
 create mode 100644 drivers/net/wireless/ath/ath5k/tx99.c

diff --git a/drivers/net/wireless/ath/ath5k/Makefile 
b/drivers/net/wireless/ath/ath5k/Makefile
index 1b3a34f..afc699f 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -16,6 +16,7 @@ ath5k-y   += rfkill.o
 ath5k-y+= ani.o
 ath5k-y+= sysfs.o
 ath5k-y+= mac80211-ops.o
+ath5k-y+= tx99.o
 ath5k-$(CONFIG_ATH5K_DEBUG)+= debug.o
 ath5k-$(CONFIG_ATH5K_AHB)  += ahb.o
 ath5k-$(CONFIG_ATH5K_PCI)  += pci.o
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h 
b/drivers/net/wireless/ath/ath5k/ath5k.h
index 67fedb6..8c86a96 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1446,6 +1446,7 @@ struct ath5k_hw {
 
/* Calibration mask */
u8  ah_cal_mask;
+   booltx99_active;
 
/*
 * Function pointers
diff --git a/drivers/net/wireless/ath/ath5k/base.h 
b/drivers/net/wireless/ath/ath5k/base.h
index 97469d0..3e50c747 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -112,6 +112,9 @@ const char *ath5k_chip_name(enum ath5k_srev_type type, 
u_int16_t val);
 int ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops);
 void ath5k_deinit_ah(struct ath5k_hw *ah);
 
+void ath5k_tx99_cw_start(struct ath5k_hw *ah);
+void ath5k_tx99_cw_stop(struct ath5k_hw *ah);
+
 /* Check whether BSSID mask is supported */
 #define ath5k_hw_hasbssidmask(_ah) (ah->ah_version == AR5K_AR5212)
 
diff --git a/drivers/net/wireless/ath/ath5k/debug.c 
b/drivers/net/wireless/ath/ath5k/debug.c
index 4f8d9ed..260f061 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -991,6 +991,50 @@ static const struct file_operations fops_eeprom = {
 };
 
 
+static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+   char buf[3];
+   struct ath5k_hw *ah = file->private_data;
+
+   if (!ah->tx99_active)
+   buf[0] = '0';
+   else
+   buf[0] = '1';
+   buf[1] = '\n';
+   buf[2] = '\0';
+   return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t write_file_tx99(struct file *file, const char __user *use

Re: Using ath5k/ath9k radio for constant-tx noise source.

2016-09-15 Thread Bob Copeland
On Wed, Sep 14, 2016 at 05:22:46PM -0700, Ben Greear wrote:
> On 08/20/2015 08:11 AM, Zefir Kurtisi wrote:
> >On 08/19/2015 09:07 PM, Ben Greear wrote:
> >>I have a commercial AP that is using a CM9 ath5k radio (evidently, I could 
> >>be wrong)
> >>and it has the ability to do a constant transmit of raw noise (RF probe 
> >>shows
> >>noise, but a monitor-port sniffer does not see any frames from the CM9).
> >>
> >>I don't know the low-level details of how it is doing this, but I suspect
> >>it is using something like madwifi for a driver.
> >>
> >>Does anyone know how this can be done with modern software and
> >>ath5k or ath9k NICs?

Hi Ben,

I wrote some code to do this on ath5k -- I can post a patch if you're
interested in using ath5k for this.

Here's a snapshot of what it looks like when running on ch.1:

https://bobcopeland.com/images/speccy-testmode.png

-- 
Bob Copeland %% http://bobcopeland.com/


[PATCH] mwifiex: fix error handling in mwifiex_create_custom_regdomain

2016-09-14 Thread Bob Copeland
smatch reports:

sta_cmdresp.c:1053 mwifiex_create_custom_regdomain() warn: possible memory leak 
of 'regd'

Indeed, mwifiex_create_custom_regdomain() returns NULL in the
case that channel is missing in the TLV without freeing regd.

Moreover, some other error paths in this function return ERR_PTR
values which are assigned without checking to the regd field in
the mwifiex_adapter struct.  The latter is only null-checked where
used.

Fix by freeing regd in the error path, and only update
priv->adapter->regd if the returned pointer is valid.

Cc: Amitkumar Karwar <akar...@marvell.com>
Cc: Nishant Sarmukadam <nisha...@marvell.com>
Signed-off-by: Bob Copeland <m...@bobcopeland.com>

---
Note, compile-tested only.  It might make sense to instead remove
the ERR_PTR stuff if there is no plan to report them further up the
call stack but I just went for the minimal patch here.
---
 drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c 
b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
index 3344a26..8548027 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
@@ -1049,8 +1049,10 @@ mwifiex_create_custom_regdomain(struct mwifiex_private 
*priv,
enum nl80211_band band;
 
chan = *buf++;
-   if (!chan)
+   if (!chan) {
+   kfree(regd);
return NULL;
+   }
chflags = *buf++;
band = (chan <= 14) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
freq = ieee80211_channel_to_frequency(chan, band);
@@ -1116,6 +1118,7 @@ static int mwifiex_ret_chan_region_cfg(struct 
mwifiex_private *priv,
u16 action = le16_to_cpu(reg->action);
u16 tlv, tlv_buf_len, tlv_buf_left;
struct mwifiex_ie_types_header *head;
+   struct ieee80211_regdomain *regd;
u8 *tlv_buf;
 
if (action != HostCmd_ACT_GEN_GET)
@@ -1137,10 +1140,10 @@ static int mwifiex_ret_chan_region_cfg(struct 
mwifiex_private *priv,
mwifiex_dbg_dump(priv->adapter, CMD_D, "CHAN:",
 (u8 *)head + sizeof(*head),
 tlv_buf_len);
-   priv->adapter->regd =
-   mwifiex_create_custom_regdomain(priv,
-   (u8 *)head +
-   sizeof(*head), tlv_buf_len);
+   regd = mwifiex_create_custom_regdomain(priv,
+   (u8 *)head + sizeof(*head), tlv_buf_len);
+   if (!IS_ERR(regd))
+   priv->adapter->regd = regd;
break;
}
 
-- 
2.9.0



Re: [PATCH 3/3] mwifiex: add custom regulatory domain support

2016-09-09 Thread Bob Copeland
On Tue, Aug 09, 2016 at 08:20:46PM +0530, Amitkumar Karwar wrote:
> This patch creates custom regulatory rules based on the information
> received from firmware and enable them during wiphy registration.
> 
> Signed-off-by: Amitkumar Karwar <akar...@marvell.com>

Hi,

This patch recently landed in wireless-testing but I noticed (or well,
smatch noticed) some issues with the error paths:

> + if (adapter->regd) {

does null-check here and elsewhere...

> +static struct ieee80211_regdomain *
> +mwifiex_create_custom_regdomain(struct mwifiex_private *priv,
> + u8 *buf, u16 buf_len)
> +{
> + u16 num_chan = buf_len / 2;
> + struct ieee80211_regdomain *regd;
> + struct ieee80211_reg_rule *rule;
> + bool new_rule;
> + int regd_size, idx, freq, prev_freq = 0;
> + u32 bw, prev_bw = 0;
> + u8 chflags, prev_chflags = 0, valid_rules = 0;
> +
> + if (WARN_ON_ONCE(num_chan > NL80211_MAX_SUPP_REG_RULES))
> + return ERR_PTR(-EINVAL);
> +

...returns ERR_PTR here

> + regd_size = sizeof(struct ieee80211_regdomain) +
> + num_chan * sizeof(struct ieee80211_reg_rule);
> +
> + regd = kzalloc(regd_size, GFP_KERNEL);
> + if (!regd)
> + return ERR_PTR(-ENOMEM);

and here.

> +
> + for (idx = 0; idx < num_chan; idx++) {
> + u8 chan;
> + enum nl80211_band band;
> +
> + chan = *buf++;
> + if (!chan)
> + return NULL;

^ here, returns null, leaking regd

> + chflags = *buf++;
> + band = (chan <= 14) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
> + freq = ieee80211_channel_to_frequency(chan, band);
> + new_rule = false;
> +
> + if (chflags & MWIFIEX_CHANNEL_DISABLED)
> + continue;
> +
> + if (band == NL80211_BAND_5GHZ) {
> + if (!(chflags & MWIFIEX_CHANNEL_NOHT80))
> + bw = MHZ_TO_KHZ(80);
> + else if (!(chflags & MWIFIEX_CHANNEL_NOHT40))
> + bw = MHZ_TO_KHZ(40);
> + else
> + bw = MHZ_TO_KHZ(20);
> + } else {
> + if (!(chflags & MWIFIEX_CHANNEL_NOHT40))
> + bw = MHZ_TO_KHZ(40);
> + else
> + bw = MHZ_TO_KHZ(20);
> + }
> +
> + if (idx == 0 || prev_chflags != chflags || prev_bw != bw ||
> + freq - prev_freq > 20) {
> + valid_rules++;
> + new_rule = true;
> + }
> +
> + rule = >reg_rules[valid_rules - 1];
> +
> + rule->freq_range.end_freq_khz = MHZ_TO_KHZ(freq + 10);
> +
> + prev_chflags = chflags;
> + prev_freq = freq;
> + prev_bw = bw;
> +
> + if (!new_rule)
> + continue;
> +
> + rule->freq_range.start_freq_khz = MHZ_TO_KHZ(freq - 10);
> + rule->power_rule.max_eirp = DBM_TO_MBM(19);
> +
> + if (chflags & MWIFIEX_CHANNEL_PASSIVE)
> + rule->flags = NL80211_RRF_NO_IR;
> +
> + if (chflags & MWIFIEX_CHANNEL_DFS)
> + rule->flags = NL80211_RRF_DFS;
> +
> + rule->freq_range.max_bandwidth_khz = bw;
> + }
> +
> + regd->n_reg_rules = valid_rules;
> + regd->alpha2[0] = '9';
> + regd->alpha2[1] = '9';
> +
> + return regd;
> +}

[...]

>  static int mwifiex_ret_chan_region_cfg(struct mwifiex_private *priv,
>  struct host_cmd_ds_command *resp)
>  {
> @@ -1050,6 +1137,10 @@ static int mwifiex_ret_chan_region_cfg(struct 
> mwifiex_private *priv,
>   mwifiex_dbg_dump(priv->adapter, CMD_D, "CHAN:",
>(u8 *)head + sizeof(*head),
>tlv_buf_len);
> + priv->adapter->regd =
> + mwifiex_create_custom_regdomain(priv,
> + (u8 *)head +
> + sizeof(*head), tlv_buf_len);

Here regd is assigned without checking IS_ERR.

-- 
Bob Copeland %% http://bobcopeland.com/


wireless-testing on 4.8-rc1

2016-08-08 Thread Bob Copeland
Hi all,

Now that Linus closed the merge window for 4.8, I'm resuming near-daily
wireless-testing builds at:

http://git.kernel.org/cgit/linux/kernel/git/wireless/wireless-testing.git

The first tag in this series is wt-2016-08-08.  Let us know of any issues.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] iw: display 5/10 MHz channel widths

2016-07-22 Thread Bob Copeland
On Fri, Jul 22, 2016 at 07:53:35PM +1000, Julian Calaby wrote:
> Hi Bob,

Hi!

> > --- a/interface.c
> > +++ b/interface.c
> > @@ -295,6 +295,10 @@ char *channel_width_name(enum nl80211_chan_width width)
> > return "80+80 MHz";
> > case NL80211_CHAN_WIDTH_160:
> > return "160 MHz";
> > +   case NL80211_CHAN_WIDTH_5:
> > +   return "5 MHz";
> > +   case NL80211_CHAN_WIDTH_10:
> > +   return "10 MHz";
> > default:
> > return "unknown";
> > }
> 
> Judging by the previous two entries, it looks like the case statements
> are sorted, so should these ones therefore be at the top of the list?

These are sorted by NL80211_CHAN_WIDTH_* attribute value, which makes
a little more sense to me than sorting by the string or numerically by
width, but sure, I can do it either way.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] ath9k: fix misleading indent

2016-07-21 Thread Bob Copeland
Fixes smatch warning:

ath9k_vif_iter_set_beacon() warn if statement not indented

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 drivers/net/wireless/ath/ath9k/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c 
b/drivers/net/wireless/ath/ath9k/main.c
index 7594650..70ca746 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -919,7 +919,7 @@ static void ath9k_vif_iter_set_beacon(struct 
ath9k_vif_iter_data *iter_data,
} else {
if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP &&
vif->type == NL80211_IFTYPE_AP)
-   iter_data->primary_beacon_vif = vif;
+   iter_data->primary_beacon_vif = vif;
}
 
iter_data->beacons = true;
-- 
2.9.0

--
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] iw: display 5/10 MHz channel widths

2016-07-21 Thread Bob Copeland
iw was showing 'width: unknown' for channels on OCB interfaces; teach
it the values for 5/10 MHz so it will show the configured width.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 interface.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/interface.c b/interface.c
index 209561d..2802235 100644
--- a/interface.c
+++ b/interface.c
@@ -295,6 +295,10 @@ char *channel_width_name(enum nl80211_chan_width width)
return "80+80 MHz";
case NL80211_CHAN_WIDTH_160:
return "160 MHz";
+   case NL80211_CHAN_WIDTH_5:
+   return "5 MHz";
+   case NL80211_CHAN_WIDTH_10:
+   return "10 MHz";
default:
return "unknown";
}
-- 
2.9.0

--
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] mac80211: End the MPSP even if EOSP frame was not received

2016-07-20 Thread Bob Copeland
On Wed, Jul 20, 2016 at 04:11:33PM +0900, Masashi Honma wrote:
> On 2016年07月19日 19:40, Bob Copeland wrote:
> >
> >OK, do we need to also clear WLAN_STA_PS_STA flag for the peer in
> >ieee80211_mps_sta_status_update(), or does the node completely repeer?
> >
> >ISTR running into a problem where rebooted peer (previously in power-save)
> >would send popen but we would buffer the response due to stale PS sta
> >flag.
[...]
>
> So looks no problem.

Ok, thanks for testing that - fwiw original patch

Acked-by: Bob Copeland <m...@bobcopeland.com>

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 v2 2/3] mac80211: mesh: improve path resolving time

2016-07-19 Thread Bob Copeland
On Tue, Jul 19, 2016 at 01:02:13PM +, Machani, Yaniv wrote:
> On Tue, Jul 19, 2016 at 15:44:56, Bob Copeland wrote:
> > > IEEE 802.11-2012 has defined dot11MeshHWMPpreqMinInterval attribute 
> > > to specify the minimum interval of time during which a mesh STA can 
> > > send only one Action frame containing a PREQ element. This is to 
> > > avoid flooding of broadcast PREQ frame especially when the number of 
> > > mesh STA is increased.
> > 
> > Good point, according to 13.10.9.3, conditions for sending PREQ include:
> > 
> > "The mesh STA has not sent a PREQ element for the target mesh STAs 
> > less than dot11MeshHWMPpreqMinInterval TUs ago. If this is the case, 
> > the transmission of the PREQ has to be postponed until this condition 
> > becomes true."
> > 
> 
> As I see it, the key point here is "for the target meh STA", 
> Today, the code will not send a PREQ to ANY target if
> dot11MeshHWMPpreqMinInterval didn't passed.
> The information is saved in the 'ifmsh->last_preq', and not per path.

The standard also says (which Chun-Yeow partially quoted):

dot11MeshHWMPpreqMinInterval OBJECT-TYPE
SYNTAX Unsigned32 (1..65535)
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"This is a control variable.
It is written by an external management entity.
Changes take effect as soon as practical in the implementation.
This attribute specifies the minimum interval of time (in TUs) during
which a mesh STA can send only one Action frame containing a PREQ element."
DEFVAL { 100 }
::= { dot11MeshHWMPConfigEntry 4}

This wording seems to indicate that it is not per path.  Perhaps this
should be clarified in the standard.  (If the intent turns out to be per
path, then I guess we should fix it by storing last_preq per path instead.)

Ignoring the standard for a second, let's explore this: can you give
some idea on how many stations are in your target network, how frequently
a given pair of nodes unpeer, what sort of improvements you see with the
patch?  It should then be pretty easy to run some simulations to see the
scenarios where this helps and where it hurts.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 v2 2/3] mac80211: mesh: improve path resolving time

2016-07-19 Thread Bob Copeland
On Tue, Jul 19, 2016 at 12:59:56AM +0800, Chun-Yeow Yeoh wrote:
> > To improve that, added an 'immediate' flag to be used when the path needs 
> > to be resolved.
> > Once set, a PREQ frame will be send w/o considering the MinInterval 
> > parameter.
> 
> Suggest that you try to reduce the mesh_hwmp_preq_min_interval to your
> desired value instead of introducing a new patch specific to your use
> case.
> 
> IEEE 802.11-2012 has defined dot11MeshHWMPpreqMinInterval attribute to
> specify the minimum interval of time during which a mesh STA can send
> only one Action frame containing a PREQ element. This is to avoid
> flooding of broadcast PREQ frame especially when the number of mesh
> STA is increased.

Good point, according to 13.10.9.3, conditions for sending PREQ include:

"The mesh STA has not sent a PREQ element for the target mesh STAs less
than dot11MeshHWMPpreqMinInterval TUs ago. If this is the case, the
transmission of the PREQ has to be postponed until this condition becomes
true."

Adopting this patch would violate that, so please disregard my suggested
rewrites; we should just skip this one.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 v2 2/3] mac80211: mesh: improve path resolving time

2016-07-19 Thread Bob Copeland
On Wed, Jul 13, 2016 at 02:45:25PM +0300, Yaniv Machani wrote:
> When a packet is received for transmission,
> a PREQ frame is sent to resolve the appropriate path to the desired 
> destination.
> After path was established, any sequential PREQ will be sent only after
> dot11MeshHWMPpreqMinInterval, which usually set to few seconds.
> 
> This implementation has an impact in cases where we would like to
> resolve the path quickly.
> A clear example is when a peer was disconnected from us,
> while he acted as a hop to our destination.
> Although the path table will be cleared, the next PREQ frame will be sent 
> only after reaching the MinInterval.
> This will cause unwanted delay, possibly of few seconds until the traffic 
> will resume.
> 
>   if (!(mpath->flags & MESH_PATH_RESOLVING))
> - mesh_queue_preq(mpath, PREQ_Q_F_START);
> + mesh_queue_preq(mpath, PREQ_Q_F_START, true);

What about something like this here instead:

if (!(mpath->flags & MESH_PATH_RESOLVING)) {
/* force next preq to be sent without delay */
ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
mesh_queue_preq(mpath, PREQ_Q_F_START);
}

Maybe a little more magic, but it has a comment explaining it and doesn't
add a bool parameter everywhere.  Or, maybe even just do it inside
mesh_queue_preq() based on having PREQ_Q_F_START && !PREQ_Q_F_REFRESH (if
those are the only cases where "true" is passed).

Generally I try to avoid bool parameters where possible because when you
look at a callsite, you don't know immediately what "true" and "false"
mean, and also each one you add doubles the code paths through a given
function.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: End the MPSP even if EOSP frame was not received

2016-07-19 Thread Bob Copeland
On Tue, Jul 19, 2016 at 11:16:24AM +0900, Masashi Honma wrote:
> This patch does not fix starting MPSP, this patch fixes ending of MPSP.
> Without this patch, local peer continues MPSP even if we lost opposite peer
> accidentally.

OK, do we need to also clear WLAN_STA_PS_STA flag for the peer in
ieee80211_mps_sta_status_update(), or does the node completely repeer?

ISTR running into a problem where rebooted peer (previously in power-save)
would send popen but we would buffer the response due to stale PS sta
flag.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/3] mac80211: mesh: fixed HT ies in beacon template

2016-07-18 Thread Bob Copeland
On Wed, Jul 13, 2016 at 02:45:40PM +0300, Yaniv Machani wrote:
> The HT capab info field inside the HT capab IE of the mesh beacon
> is incorrect (in the case of 20MHz channel width).
> To fix this driver will check configuration from cfg and
> will build it accordingly.

> +/* determine capability flags */
> + cap = sband->ht_cap.cap;
> +
> +/* if channel width is 20MHz - configure HT capab accordingly*/
> + if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20) {
> + cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
> + cap &= ~IEEE80211_HT_CAP_DSSSCCK40;
> + }

Is it required that HT capability match the HT operation in this case?

> diff --git a/net/mac80211/util.c b/net/mac80211/util.c
> index 42bf0b6..5375a82 100644
> --- a/net/mac80211/util.c
> +++ b/net/mac80211/util.c
> @@ -2349,10 +2349,7 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct 
> ieee80211_sta_ht_cap *ht_cap,
>   ht_oper->operation_mode = cpu_to_le16(prot_mode);
>   ht_oper->stbc_param = 0x;
>  
> - /* It seems that Basic MCS set and Supported MCS set
> -are identical for the first 10 bytes */
>   memset(_oper->basic_set, 0, 16);
> - memcpy(_oper->basic_set, _cap->mcs, 10);

This change doesn't look right (basic mcs set will be all zeroes) but
then, neither does the original code.  Basic MCS set for a mesh STA should
be the mandatory MCSes according to 9.7.4.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: End the MPSP even if EOSP frame was not received

2016-07-13 Thread Bob Copeland
On Wed, Jul 13, 2016 at 04:04:35PM +0900, Masashi Honma wrote:
> The mesh STA sends QoS frame with EOSP (end of service period)
> subfiled=1 to end the MPSP(mesh peer service period). Previously, if
> the frame was not acked by peer, the mesh STA did not end the MPSP.
> This patch ends the MPSP even if the QoS frame was no acked.

Hmm, my recollection on this stuff is a little fuzzy.  So we only get
here if the peer sta is in doze state, but it shouldn't do that if we
are in an MPSP.  So, is the real problem that we don't wait for an ack
from the peer before marking ourselves in a MPSP?

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 1/4] mac80211: mesh: flush stations before beacons are stopped

2016-07-13 Thread Bob Copeland
On Wed, Jul 13, 2016 at 10:11:25AM +, Machani, Yaniv wrote:
> > > Some drivers (e.g. wl18xx) expect that the last stage in the 
> > > de-initialization process will be stopping the beacons, similar to ap.
> > > Update ieee80211_stop_mesh() flow accordingly.
> > >
> > How well have you tested that with other drivers?
> > 
> 
> Sorry for the delayed response (I've been out) and thanks for your comments,
> I have tested it with RT3572 as well, and didn't see any issue.
> I'll update the comment to reflect that.

I'll give this a test on ath10k and wcn36xx as they are the ones most
likely to care about ordering.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 v2] cfg80211: Add mesh peer AID setting API

2016-07-06 Thread Bob Copeland
On Wed, Jul 06, 2016 at 02:42:34PM +0200, Johannes Berg wrote:
> > + * @NL80211_ATTR_MESH_PEER_AID: Association ID for the mesh peer
> > (u16). This is
> > + * used to pull the stored data for mesh peer in power save
> > state.
> > 
> Why does this need new API all over?
> 
> It seems to me that it could just use the regular NL80211_ATTR_STA_AID
> attribute, and the cfg80211 code would already be in place, and you'd
> just need to add a single line to mac80211 and
> to cfg80211_check_station_change() to accept that.

We are already using NL80211_ATTR_STA_AID, though -- one is for the
station's AID (in our TIM, which is NL80211_ATTR_STA_AID) and the new one
is for our AID in the peer's TIM.

There is the NL80211_ATTR_PEER_AID but that seems specific to TDLS and
also doesn't appear to be processed in the necessary way (e.g. overrides
STA_AID in nl80211_new_station).

-- 
Bob Copeland %% http://bobcopeland.com/
--
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: Add mesh peer AID setting API

2016-06-30 Thread Bob Copeland
On Thu, Jun 30, 2016 at 06:00:58PM +0900, Masashi Honma wrote:
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 7bbb00d..2fa5896 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -805,6 +805,7 @@ struct station_parameters {
>   u32 sta_modify_mask;
>   int listen_interval;
>   u16 aid;
> + u16 mesh_aid;

Let's call it peer_aid or mesh_peer_aid or something like that, per my
email on hostapd list.  Also you probably saw kbuild robot pointed out
missing documentation for the field.

> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index c503e96..f41fb61 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -4410,6 +4410,9 @@ static int nl80211_set_station(struct sk_buff *skb, 
> struct genl_info *info)
>   nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
>   if (params.plink_state >= NUM_NL80211_PLINK_STATES)
>   return -EINVAL;
> + if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
> + params.mesh_aid = nla_get_u16(
> + info->attrs[NL80211_ATTR_MESH_PEER_AID]);

We need a check against IEEE80211_MAX_AID somewhere.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: mesh: fixed HT ies in beacon template

2016-06-28 Thread Bob Copeland
On Tue, Jun 28, 2016 at 02:13:06PM +0300, Yaniv Machani wrote:
> From: Meirav Kama <meir...@ti.com>
> 
> There are several values in HT info elements of mesh beacon (built by the
> mac80211) that are incorrect.

Would be good to enumerate the problems here.

> To fix them:
> 1. mac80211 will check configuration from cfg and will build accordingly.
> 2. changes made in mesh default values.

What is wrong with the defaults?

>   sband = local->hw.wiphy->bands[band];
>   if (!sband->ht_cap.ht_supported ||
> @@ -431,11 +433,40 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data 
> *sdata,
>   sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
>   return 0;
>  
> +/* determine capability flags */
> + cap = sband->ht_cap.cap;

There is some weird whitespace here (space instead of tabs for the
comment).

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 4/4] mac80211: sta_info: max_peers reached falsely

2016-06-28 Thread Bob Copeland
On Tue, Jun 28, 2016 at 02:13:07PM +0300, Yaniv Machani wrote:
> From: Meirav Kama <meir...@ti.com>
> 
> Issue happened when receiving delete_sta command without
> changing plink_state from ESTAB to HOLDING before.
> When receiving delete_sta command for mesh interface
> verify plink_state is not ESTAB and if so, decrease
> plink count and update beacon.

This should be fixed already (and properly) by the patch
"mac80211: Fix mesh estab links counting" -- please let us
know if you have a case that's still broken with that fix.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/cfg: mesh: fix healing time when a mesh peer is disconnecting

2016-06-28 Thread Bob Copeland
On Tue, Jun 28, 2016 at 02:13:05PM +0300, Yaniv Machani wrote:
> From: Maital Hahn <mait...@ti.com>
> 
> Once receiving a CLOSE action frame from the disconnecting peer,
> flush all entries in the path table which has this peer as the
> next hop.

Please address the user-visible behavior in your commit messages.
Does it crash?  Does it send frames to an invalid peer?  Do
frames get dropped?

> In addition, upon receiving a packet, if next hop is not found,
> trigger PERQ immidiatly, instead of just putting it in the queue.

"PREQ"

Please split this into a separate patch that we can review
separately (and also give the "why" in the commit log).

> Signed-off-by: Maital Hahn <mait...@ti.com>
> Acked-by: Yaniv Machani <yani...@ti.com>
> ---
>  net/mac80211/cfg.c   |  1 +
>  net/mac80211/mesh.c  |  3 ++-
>  net/mac80211/mesh_hwmp.c | 42 +-
>  3 files changed, 28 insertions(+), 18 deletions(-)
> 
> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
> index 0c12e40..f876ef7 100644
> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -1011,6 +1011,7 @@ static void sta_apply_mesh_params(struct 
> ieee80211_local *local,
>   if (sta->mesh->plink_state == NL80211_PLINK_ESTAB)
>   changed = mesh_plink_dec_estab_count(sdata);
>   sta->mesh->plink_state = params->plink_state;
> + mesh_path_flush_by_nexthop(sta);

This isn't necessary, caller should already be doing
mesh_path_flush_by_nexthop() in every case I could see.  Besides it
cannot be done under plink lock.

> +++ b/net/mac80211/mesh.c
> @@ -159,7 +159,8 @@ void mesh_sta_cleanup(struct sta_info *sta)
>   if (!sdata->u.mesh.user_mpm) {
>   changed |= mesh_plink_deactivate(sta);
>   del_timer_sync(>mesh->plink_timer);
> - }
> + } else
> + mesh_path_flush_by_nexthop(sta);

And this is already fixed in mac80211-next.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: use common cleanup for user/!user_mpm

2016-06-25 Thread Bob Copeland
We've accumulated a couple of different fixes now to mesh_sta_cleanup()
due to the different paths that user_mpm and !user_mpm cases take -- one
fix to flush nexthop paths and one to fix the counting.

The only caller of mesh_plink_deactivate() is mesh_sta_cleanup(), so we
can push the user_mpm checks down into there in order to share more
code.

In doing so, we can remove an extra call to mesh_path_flush_by_nexthop()
and the (unnecessary) call to mesh_accept_plinks_update().  This will
also ensure the powersaving state code gets called in the user_mpm case.

The only cleanup tasks we need to avoid when MPM is in user-space
are sending the peering frames and stopping the plink timer, so wrap
those in the appropriate check.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---

This applies on top of Jouni's patch,
"mac80211: Fix mesh estab_plinks counting in STA removal case", so
this can go for -next.

 net/mac80211/mesh.c   | 20 +---
 net/mac80211/mesh_plink.c | 16 
 2 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6a1603b..c66411d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -148,25 +148,7 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data 
*sdata)
 void mesh_sta_cleanup(struct sta_info *sta)
 {
struct ieee80211_sub_if_data *sdata = sta->sdata;
-   u32 changed = 0;
-
-   /*
-* maybe userspace handles peer allocation and peering, but in either
-* case the beacon is still generated by the kernel and we might need
-* an update.
-*/
-   if (sdata->u.mesh.user_mpm &&
-   sta->mesh->plink_state == NL80211_PLINK_ESTAB)
-   changed |= mesh_plink_dec_estab_count(sdata);
-   changed |= mesh_accept_plinks_update(sdata);
-   if (!sdata->u.mesh.user_mpm) {
-   changed |= mesh_plink_deactivate(sta);
-   del_timer_sync(>mesh->plink_timer);
-   }
-
-   /* make sure no readers can access nexthop sta from here on */
-   mesh_path_flush_by_nexthop(sta);
-   synchronize_net();
+   u32 changed = mesh_plink_deactivate(sta);
 
if (changed)
ieee80211_mbss_info_change_notify(sdata, changed);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 79f2a0a..7fcdcf6 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -370,13 +370,21 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
 
spin_lock_bh(>mesh->plink_lock);
changed = __mesh_plink_deactivate(sta);
-   sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
-   mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
-   sta->sta.addr, sta->mesh->llid, sta->mesh->plid,
-   sta->mesh->reason);
+
+   if (!sdata->u.mesh.user_mpm) {
+   sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
+   mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
+   sta->sta.addr, sta->mesh->llid,
+   sta->mesh->plid, sta->mesh->reason);
+   }
spin_unlock_bh(>mesh->plink_lock);
+   if (!sdata->u.mesh.user_mpm)
+   del_timer_sync(>mesh->plink_timer);
mesh_path_flush_by_nexthop(sta);
 
+   /* make sure no readers can access nexthop sta from here on */
+   synchronize_net();
+
return changed;
 }
 
-- 
2.9.0

--
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] mac80211: Fix mesh estab_plinks counting in STA removal case

2016-06-21 Thread Bob Copeland
On Tue, Jun 21, 2016 at 06:26:02PM -0400, Bob Copeland wrote:
> Looks further buggy, so perhaps this untested patch would work, i.e.
    (still)

> @@ -370,13 +372,19 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
>  
>   spin_lock_bh(>mesh->plink_lock);
>   changed = __mesh_plink_deactivate(sta);
> - sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
> - mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
> - sta->sta.addr, sta->mesh->llid, sta->mesh->plid,
> - sta->mesh->reason);
> +
> + if (sdata->u.mesh.user_mpm) {

should be !sdata->u.mesh.user_mpm :)

> + sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
> + mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
> + sta->sta.addr, sta->mesh->llid, 
> sta->mesh->plid,
> + sta->mesh->reason);
> + }
>   spin_unlock_bh(>mesh->plink_lock);
>   mesh_path_flush_by_nexthop(sta);
>  
> + /* make sure no readers can access nexthop sta from here on */
> + synchronize_net();
> +
>   return changed;
>  }
>  
> -- 
> 2.9.0
> 

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: Fix mesh estab_plinks counting in STA removal case

2016-06-21 Thread Bob Copeland
On Tue, Jun 21, 2016 at 09:09:10PM +0200, Johannes Berg wrote:
> 
> >      */
> > -   changed = mesh_accept_plinks_update(sdata);
> > +   if (sdata->u.mesh.user_mpm &&
> > +   sta->mesh->plink_state == NL80211_PLINK_ESTAB)
> > +   changed |= mesh_plink_dec_estab_count(sdata);
> > +   changed |= mesh_accept_plinks_update(sdata);
> >     if (!sdata->u.mesh.user_mpm) {
> >     changed |= mesh_plink_deactivate(sta);
> >     del_timer_sync(>mesh->plink_timer);
> > 
> 
> Does it have to be done before the mesh_accept_plinks_update()?
> 
> If not, you should put it with the existing u.mesh.user_mpm check. If
> yes, then the code is further buggy since only mesh_plink_deactivate()
> will call it when the kernel MPM is used.

Looks further buggy, so perhaps this untested patch would work, i.e.
move the accepting-plinks change closer to the decrement, and push
the user_mpm check down into mesh_plink_deactivate to just
avoid sending the peering frames.  [There's also a bit there for
power saving that we likely want to keep for secure networks.]

Then again maybe accepting_plinks flag should just be computed when
used instead of tracking the state separately.

---
 net/mac80211/mesh.c   | 18 ++
 net/mac80211/mesh_plink.c | 16 
 2 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 21b1fdf..3c150f8 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -148,22 +148,8 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data 
*sdata)
 void mesh_sta_cleanup(struct sta_info *sta)
 {
struct ieee80211_sub_if_data *sdata = sta->sdata;
-   u32 changed;
-
-   /*
-* maybe userspace handles peer allocation and peering, but in either
-* case the beacon is still generated by the kernel and we might need
-* an update.
-*/
-   changed = mesh_accept_plinks_update(sdata);
-   if (!sdata->u.mesh.user_mpm) {
-   changed |= mesh_plink_deactivate(sta);
-   del_timer_sync(>mesh->plink_timer);
-   }
-
-   /* make sure no readers can access nexthop sta from here on */
-   mesh_path_flush_by_nexthop(sta);
-   synchronize_net();
+   u32 changed = mesh_plink_deactivate(sta);
+   del_timer_sync(>mesh->plink_timer);
 
if (changed)
ieee80211_mbss_info_change_notify(sdata, changed);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 79f2a0a..69ac7a8 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -349,6 +349,8 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta)
changed = mesh_plink_dec_estab_count(sdata);
sta->mesh->plink_state = NL80211_PLINK_BLOCKED;
 
+   changed |= mesh_accept_plinks_update(sdata);
+
ieee80211_mps_sta_status_update(sta);
changed |= ieee80211_mps_set_sta_local_pm(sta,
NL80211_MESH_POWER_UNKNOWN);
@@ -370,13 +372,19 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
 
spin_lock_bh(>mesh->plink_lock);
changed = __mesh_plink_deactivate(sta);
-   sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
-   mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
-   sta->sta.addr, sta->mesh->llid, sta->mesh->plid,
-   sta->mesh->reason);
+
+   if (sdata->u.mesh.user_mpm) {
+   sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
+   mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
+   sta->sta.addr, sta->mesh->llid, 
sta->mesh->plid,
+   sta->mesh->reason);
+   }
spin_unlock_bh(>mesh->plink_lock);
mesh_path_flush_by_nexthop(sta);
 
+   /* make sure no readers can access nexthop sta from here on */
+   synchronize_net();
+
return changed;
 }
 
-- 
2.9.0

--
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 0/3] *** Mesh Path Selection Metric Calculation ***

2016-06-21 Thread Bob Copeland
On Mon, Jun 20, 2016 at 04:00:19PM +0300, Maxim Altshul wrote:
> 2. Implements the opcode and the mechanism that reports the rates
> in TI driver.

Does this mean TI driver will support mesh at some point?

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] ath10k: Fix a typo in spectral code commments

2016-06-16 Thread Bob Copeland
On Tue, Jun 14, 2016 at 11:03:54AM +0530, Mohammed Shafi Shajakhan wrote:
> From: Mohammed Shafi Shajakhan <moham...@qti.qualcomm.com>
> 
> Found this obvious typo while going through the spectral
> code design in ath10k

>   /* TODO: As experiments with an analogue sender and various
> -  * configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz)
> +  * configurations (fft-sizes of 64/128/256 and 20/40/80 Mhz)
>* show, the particular configuration of 80 MHz/64 bins does
>* not match with the other smaples at all. Until the reason
>* for that is found, don't report these samples.

Also "smaples" :)

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] ath10k: fix potential null dereference bugs

2016-06-14 Thread Bob Copeland
On Tue, Jun 14, 2016 at 01:51:24PM +, Kalle Valo wrote:
> > It's not clear that's the same situation, since tun->sk is very likely
> > to have been an actual pointer, not an embedded thing like drv_priv.

Just to follow up on that thread, I did research it a bit yesterday and
came to the conclusion that it is UB even when the target is in the same
struct.  However, in a not very scientific survey, I didn't see either clang
or gcc remove the test in a simplified test case (with -O3 and without
-fno-delete-null-pointer-checks).  If drv_priv were an actual pointer, gcc
did remove it but clang did not.  So, there's that.

> > However, with all this, I think I'd simply not take any chances - the
> > patch isn't exactly invasive and in some cases (for example the first
> > hunk of the patch) will even improve the code to the point where the
> > compiler could warn about uninitialized usage of the pointer when the
> > code gets modified to use it in case of !txq->sta.
> >
> > I'd take it, but I guess it's Kalle's decision :)
> 
> Yeah, I'm leaning towards Johannes. These are not really invasive.

Thanks, and sorry about the checkpatch -- I did run checkpatch on it but
for some reason my version only complained about some of them.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] ath10k: fix potential null dereference bugs

2016-06-13 Thread Bob Copeland
On Mon, Jun 13, 2016 at 11:08:59AM +0200, Johannes Berg wrote:
> On Mon, 2016-06-13 at 07:39 +0200, Michal Kazior wrote:
> > 
> > FWIW all of these are false positives. I think this was already
> > pointed out some time ago. The drv_priv stuff is merely an offset
> > (see how ieee80211_vif and ieee80211_sta are defined) and the
> > according structure is always checked beforehand.

OK, fair enough, sorry for the noise.  I'm daily running sparse / smatch
on wireless-testing; although these had been around for a while they
showed up as new "errors" because of some line number changes, but I'll
squelch them going forward.

> IIRC, doing something like that can (sometimes?) still get you into
> undefined behaviour territory, so the compiler could potentially
> "optimize" away the later NULL check.

So I did just go and check the generated code for each of these cases
and gcc didn't elide the subsequent if-test, at least on x86-64 and my
compiler / build config.  Given http://lwn.net/Articles/342330, it seems
possible, though.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] ath10k: fix potential null dereference bugs

2016-06-10 Thread Bob Copeland
Smatch warns about a number of cases in ath10k where a pointer is
null-checked after it has already been dereferenced, in code involving
ath10k private virtual interface pointers.

Fix these by making the dereference happen later.

Addresses the following smatch warnings:

drivers/net/wireless/ath/ath10k/mac.c:3651 ath10k_mac_txq_init() warn: variable 
dereferenced before check 'txq' (see line 3649)
drivers/net/wireless/ath/ath10k/mac.c:3664 ath10k_mac_txq_unref() warn: 
variable dereferenced before check 'txq' (see line 3659)
drivers/net/wireless/ath/ath10k/htt_tx.c:70 __ath10k_htt_tx_txq_recalc() warn: 
variable dereferenced before check 'txq->sta' (see line 52)
drivers/net/wireless/ath/ath10k/htt_tx.c:740 ath10k_htt_tx_get_vdev_id() warn: 
variable dereferenced before check 'cb->vif' (see line 736)
drivers/net/wireless/ath/ath10k/txrx.c:86 ath10k_txrx_tx_unref() warn: variable 
dereferenced before check 'txq' (see line 84)
drivers/net/wireless/ath/ath10k/wmi.c:1837 ath10k_wmi_op_gen_mgmt_tx() warn: 
variable dereferenced before check 'cb->vif' (see line 1825)

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
Although I glanced at a few cases, by and large I didn't check
whether the if() tests were correct but assumed they were.

Also, I only compile-tested this.

 drivers/net/wireless/ath/ath10k/htt_tx.c | 15 +--
 drivers/net/wireless/ath/ath10k/mac.c|  6 --
 drivers/net/wireless/ath/ath10k/txrx.c   |  5 +++--
 drivers/net/wireless/ath/ath10k/wmi.c|  8 +---
 4 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c 
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 6269c61..dfcc43d 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -49,7 +49,7 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw 
*hw,
   struct ieee80211_txq *txq)
 {
struct ath10k *ar = hw->priv;
-   struct ath10k_sta *arsta = (void *)txq->sta->drv_priv;
+   struct ath10k_sta *arsta;
struct ath10k_vif *arvif = (void *)txq->vif->drv_priv;
unsigned long frame_cnt;
unsigned long byte_cnt;
@@ -67,10 +67,12 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw 
*hw,
if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH_PULL)
return;
 
-   if (txq->sta)
+   if (txq->sta) {
+   arsta = (void *)txq->sta->drv_priv;
peer_id = arsta->peer_id;
-   else
+   } else {
peer_id = arvif->peer_id;
+   }
 
tid = txq->tid;
bit = BIT(peer_id % 32);
@@ -733,13 +735,14 @@ static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, 
struct sk_buff *skb)
 {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
-   struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
+   struct ath10k_vif *arvif;
 
if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
return ar->scan.vdev_id;
-   else if (cb->vif)
+   else if (cb->vif) {
+   arvif = (void *)cb->vif->drv_priv;
return arvif->vdev_id;
-   else if (ar->monitor_started)
+   } else if (ar->monitor_started)
return ar->monitor_vdev_id;
else
return 0;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 6dd1d26..4eee4b9 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3646,17 +3646,18 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct 
*work)
 
 static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
 {
-   struct ath10k_txq *artxq = (void *)txq->drv_priv;
+   struct ath10k_txq *artxq;
 
if (!txq)
return;
 
+   artxq = (void *)txq->drv_priv;
INIT_LIST_HEAD(>list);
 }
 
 static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
 {
-   struct ath10k_txq *artxq = (void *)txq->drv_priv;
+   struct ath10k_txq *artxq;
struct ath10k_skb_cb *cb;
struct sk_buff *msdu;
int msdu_id;
@@ -3664,6 +3665,7 @@ static void ath10k_mac_txq_unref(struct ath10k *ar, 
struct ieee80211_txq *txq)
if (!txq)
return;
 
+   artxq = (void *)txq->drv_priv;
spin_lock_bh(>txqs_lock);
if (!list_empty(>list))
list_del_init(>list);
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c 
b/drivers/net/wireless/ath/ath10k/txrx.c
index 576e7c4..9f17863 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -81,10 +81,11 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
 
skb_cb = ATH10K_SKB_CB(msdu);
txq = skb_cb->txq;
-

[PATCH] ath5k: fix misplaced default label in sifs switch

2016-06-02 Thread Bob Copeland
In this switch statement, the default case does not always assign
sifs.  In practice, ah->ah_bwmode cannot take values besides the
other labels, so this is not an actual problem, but it looks odd
and smatch complains thus:

ath5k_hw_get_default_sifs() warn: missing break? reassigning 'sifs'

Silence the warning by moving default label up a line.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 drivers/net/wireless/ath/ath5k/pcu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath5k/pcu.c 
b/drivers/net/wireless/ath/ath5k/pcu.c
index fc47b70..f23c851 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -219,8 +219,8 @@ ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
sifs = AR5K_INIT_SIFS_QUARTER_RATE;
break;
case AR5K_BWMODE_DEFAULT:
-   sifs = AR5K_INIT_SIFS_DEFAULT_BG;
default:
+   sifs = AR5K_INIT_SIFS_DEFAULT_BG;
if (channel->band == NL80211_BAND_5GHZ)
sifs = AR5K_INIT_SIFS_DEFAULT_A;
break;
-- 
2.1.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: wireless-testing on 4.7

2016-06-01 Thread Bob Copeland
+ Luca, Emmanuel

On Tue, May 31, 2016 at 10:06:57PM -0600, Reinoud Koornstra wrote:
> Today I compiled 4.6+ and pulled sources today
> iwlwifi isn't super smooth.

I assume you mean wireless-testing, based on 4.7-rc1 (as this email is
in reply to my announcement of same).

> 
> [  112.345457] wlp4s0: authenticate with 00:30:44:1d:cf:2b
> [  112.349002] wlp4s0: send auth to 00:30:44:1d:cf:2b (try 1/3)
> [  112.349647] wlp4s0: authenticated
> [  112.352456] wlp4s0: associate with 00:30:44:1d:cf:2b (try 1/3)
> [  112.353764] wlp4s0: RX AssocResp from 00:30:44:1d:cf:2b (capab=0x11
> status=0 aid=3)
> [  112.355035] wlp4s0: associated
> [  112.355393] IPv6: ADDRCONF(NETDEV_CHANGE): wlp4s0: link becomes ready
> [  118.616327] wlp4s0: deauthenticated from 00:30:44:1d:cf:2b (Reason:
> 15=4WAY_HANDSHAKE_TIMEOUT)
> [  128.673812] wlp4s0: authenticate with 00:30:44:1d:cf:2b
> [  128.676997] wlp4s0: send auth to 00:30:44:1d:cf:2b (try 1/3)
> [  128.677648] wlp4s0: authenticated
> [  128.678691] wlp4s0: associate with 00:30:44:1d:cf:2b (try 1/3)
> [  128.679807] wlp4s0: RX AssocResp from 00:30:44:1d:cf:2b (capab=0x11
> status=0 aid=3)
> [  128.681198] wlp4s0: associated
> 
> I never experienced the 4 way handshake 802.11i timeout in my home setup.
> With other setups plenty of times, especially with mediatek drivers. :)
> If you wish I can sniff and see which side is at fault.

I have not noticed any problems on my laptop with iwldvm on a 6205, with
latest wireless-testing.  But maybe intel devs can weigh in.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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


wireless-testing on 4.7

2016-05-29 Thread Bob Copeland
Since Linus released 4.7-rc1 today, I've resumed wireless-testing
updates since its merge window hiatus, with tag wt-2016-05-29.

Please test and let me know of any issues.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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: "kernel: BUG: scheduling while atomic:" errors with linux kernel 4.6

2016-05-19 Thread Bob Copeland
+linux-wireless

On Thu, May 19, 2016 at 03:11:16PM -0600, James Feeney wrote:
> Arch linux 4.6-1
> wpa_supplicant 1:2.5-3
> Toshiba Satellite, circa 2011, with a Pentium Dual-Core Mobile
> Error is not seen on other machines.
> 
> kernel: BUG: scheduling while atomic: wpa_supplicant/375/0x0002

This is a kernel bug, not a wpa_supplicant bug.  The linux-wireless mailing
list would be a more appropriate venue for this bug report.


> May 19 10:26:07 lapis kernel: BUG: scheduling while atomic: 
> wpa_supplicant/627/0x0002
[...]
> May 19 10:26:07 lapis kernel:  [] __schedule+0x899/0xad0
> May 19 10:26:07 lapis kernel:  [] schedule+0x3c/0x90
> May 19 10:26:07 lapis kernel:  [] 
> schedule_hrtimeout_range_clock+0xa2/0x120
> May 19 10:26:07 lapis kernel:  [] ? hrtimer_init+0x120/0x120
> May 19 10:26:07 lapis kernel:  [] ? 
> schedule_hrtimeout_range_clock+0x96/0x120
> May 19 10:26:07 lapis kernel:  [] 
> schedule_hrtimeout_range+0x13/0x20
> May 19 10:26:07 lapis kernel:  [] usleep_range+0x4f/0x70
> May 19 10:26:07 lapis kernel:  [] rtl_rfreg_delay+0x38/0x50 
> [rtlwifi]
> May 19 10:26:07 lapis kernel:  [] 
> rtl92c_phy_config_rf_with_headerfile+0xc7/0xe0 [rtl8192ce]

[Probably due to this kernel change:

commit 49f86ec21c01b654f6ec47f2f4567f4f9ebaa26b
Author: Larry Finger <larry.fin...@lwfinger.net>
Date:   Mon Feb 15 16:12:07 2016 -0600

rtlwifi: Change long delays to sleeps


...apparently this function isn't in sleepable context after all.]

-- 
Bob Copeland %% http://bobcopeland.com/
--
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: wifi driver crashes openwrt device

2016-05-15 Thread Bob Copeland
On Tue, May 10, 2016 at 03:17:25PM +, andy wrote:
> hello, every body.
>   I developed an openwrt device based on git clone 
> git://git.openwrt.org/15.05/openwrt.git.
>   I found that my device rebooted during wifi initializing sometimes, maybe 
> one in twenty. 
>   The wifi driver is compat-wireless-2016-01-10.tar.bz2.
>   Could somebody give some hint or help me to resolve this wired issue?
>   Thank you very much.

Hi Andy,

You will probably need to capture a stack trace from the device in order
for someone to be able to help, otherwise we can only guess.  A serial
console can help with that.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 v2] mac80211: mesh: flush mesh paths unconditionally

2016-05-15 Thread Bob Copeland
r_handle_frame_finish+0x3db/0x3db [bridge]
[  348.530014]  [] ? resched_curr+0x19/0x37
[  348.530014]  [] ? check_preempt_wakeup+0xbf/0xfe
[  348.530014]  [] ? ktime_get_with_offset+0x5c/0xfc
[  348.530014]  [] __netif_receive_skb+0x47/0x55
[  348.530014]  [] netif_receive_skb_internal+0x40/0x5a
[  348.530014]  [] napi_gro_receive+0x3a/0x94
[  348.530014]  [] igb_poll+0x6fd/0x9ad [igb]
[  348.530014]  [] ? swake_up_locked+0x14/0x26
[  348.530014]  [] net_rx_action+0xde/0x250
[  348.530014]  [] __do_softirq+0x8a/0x163
[  348.530014]  [] ? __hrtimer_tasklet_trampoline+0x19/0x19
[  348.530014]  [] do_softirq_own_stack+0x26/0x2c
[  348.530014]  
[  348.530014]  [] irq_exit+0x31/0x6f
[  348.530014]  [] do_IRQ+0x8d/0xa0
[  348.530014]  [] common_interrupt+0x2c/0x40
[  348.530014] Code: e7 8c 00 66 81 ff 88 00 75 12 85 d2 75 0e b2 c3 b8 83 e9 
29 f9 e8 a7 5f f9 c6 eb 74 66 81 e3 8c 005
[  348.530014] EIP: [] ieee80211_mps_set_frame_flags+0x40/0xaa 
[mac80211] SS:ESP 0068:f6409a40
[  348.530014] CR2: 00020040
[  348.530014] ---[ end trace 48556ac26779732e ]---
[  348.530014] Kernel panic - not syncing: Fatal exception in interrupt
[  348.530014] Kernel Offset: disabled

Cc: sta...@vger.kernel.org
Reported-by: Fred Veldini <fred.veld...@gmail.com>
Tested-by: Fred Veldini <fred.veld...@gmail.com>
Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
v1: "mac80211: mesh: flush paths early in sta destroy"

v2: Dropped block_mpath bit, just do this in part2 so that
sta_info_get is guaranteed not to return the
to-be-deleted sta, and add a second synchronize_rcu to
wait for concurrent readers.  Changed title.

 net/mac80211/mesh.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 4c6404e1ad6e..21b1fdf5d01d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -161,6 +161,10 @@ void mesh_sta_cleanup(struct sta_info *sta)
del_timer_sync(>mesh->plink_timer);
}
 
+   /* make sure no readers can access nexthop sta from here on */
+   mesh_path_flush_by_nexthop(sta);
+   synchronize_net();
+
if (changed)
ieee80211_mbss_info_change_notify(sdata, changed);
 }
-- 
2.6.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


Re: [PATCH] mac80211: mesh: flush mesh paths early in sta destroy

2016-05-15 Thread Bob Copeland
On Sat, May 14, 2016 at 08:54:13PM +0200, Felix Fietkau wrote:
> > +   WLAN_STA_BLOCK_MPATH,
> I think this flag needs to be added to sta_flag_names in debugfs_sta.c

On further reflection, using a flag for this is racy anyway, even if
quite narrow.  Maybe I should just flush in part2 unconditionally and have
a second synchronize_net().

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: mesh: flush mesh paths early in sta destroy

2016-05-14 Thread Bob Copeland
On Sat, May 14, 2016 at 08:54:13PM +0200, Felix Fietkau wrote:
> > +   WLAN_STA_BLOCK_MPATH,
> I think this flag needs to be added to sta_flag_names in debugfs_sta.c
> 
> - Felix

Good point.  I also missed the part where mesh_path_assign_nexthop
should return an error to indicate the path shouldn't be activated.

So, I'll send a v2 tomorrow, additional comments welcome in the
meantime.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: mesh: flush mesh paths early in sta destroy

2016-05-14 Thread Bob Copeland
dle_frame+0x1e6/0x240 [bridge]
[  348.530014]  [] ? br_handle_local_finish+0x6a/0x6a [bridge]
[  348.530014]  [] __netif_receive_skb_core+0x43a/0x66b
[  348.530014]  [] ? br_handle_frame_finish+0x3db/0x3db [bridge]
[  348.530014]  [] ? resched_curr+0x19/0x37
[  348.530014]  [] ? check_preempt_wakeup+0xbf/0xfe
[  348.530014]  [] ? ktime_get_with_offset+0x5c/0xfc
[  348.530014]  [] __netif_receive_skb+0x47/0x55
[  348.530014]  [] netif_receive_skb_internal+0x40/0x5a
[  348.530014]  [] napi_gro_receive+0x3a/0x94
[  348.530014]  [] igb_poll+0x6fd/0x9ad [igb]
[  348.530014]  [] ? swake_up_locked+0x14/0x26
[  348.530014]  [] net_rx_action+0xde/0x250
[  348.530014]  [] __do_softirq+0x8a/0x163
[  348.530014]  [] ? __hrtimer_tasklet_trampoline+0x19/0x19
[  348.530014]  [] do_softirq_own_stack+0x26/0x2c
[  348.530014]  
[  348.530014]  [] irq_exit+0x31/0x6f
[  348.530014]  [] do_IRQ+0x8d/0xa0
[  348.530014]  [] common_interrupt+0x2c/0x40
[  348.530014] Code: e7 8c 00 66 81 ff 88 00 75 12 85 d2 75 0e b2 c3 b8 83 e9 
29 f9 e8 a7 5f f9 c6 eb 74 66 81 e3 8c 005
[  348.530014] EIP: [] ieee80211_mps_set_frame_flags+0x40/0xaa 
[mac80211] SS:ESP 0068:f6409a40
[  348.530014] CR2: 00020040
[  348.530014] ---[ end trace 48556ac26779732e ]---
[  348.530014] Kernel panic - not syncing: Fatal exception in interrupt
[  348.530014] Kernel Offset: disabled

Cc: sta...@vger.kernel.org
Reported-by: Fred Veldini <fred.veld...@gmail.com>
Tested-by: Fred Veldini <fred.veld...@gmail.com>
Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
>From git history, this appears to go back to earliest commits adding
authsae support.  I reproduced in a 4.4 kernel, which predates all of
the mesh pathtable rework, though it is harder to hit there than in
the current code.

This is slightly different from the version Fred tested (CCed) --
the version I sent him didn't have the BLOCK_MPATH part, but that
seems necessary to me to prevent re-adding in hwmp_route_info_get().
But I can reproduce the above crash and this patch fixes it for
me.
---
 net/mac80211/mesh_pathtbl.c |  4 
 net/mac80211/sta_info.c | 10 ++
 net/mac80211/sta_info.h |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 6db2ddfa0695..798c522b6522 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -87,6 +87,10 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, 
struct sta_info *sta)
struct ieee80211_hdr *hdr;
unsigned long flags;
 
+   /* sta is being deleted, don't add back */
+   if (test_sta_flag(sta, WLAN_STA_BLOCK_MPATH))
+   return;
+
rcu_assign_pointer(mpath->next_hop, sta);
 
spin_lock_irqsave(>frame_queue.lock, flags);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 5ccfdbd406bd..f2a1bfa53c04 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -914,6 +914,16 @@ static int __must_check __sta_info_destroy_part1(struct 
sta_info *sta)
list_del_rcu(>list);
sta->removed = true;
 
+   /*
+* Remove all path table references to the station (and prevent
+* adding new ones) so that new mesh transmissions won't use it
+* as a next hop.
+*/
+   if (ieee80211_vif_is_mesh(>vif)) {
+   set_sta_flag(sta, WLAN_STA_BLOCK_MPATH);
+   mesh_path_flush_by_nexthop(sta);
+   }
+
drv_sta_pre_rcu_remove(local, sta->sdata, sta);
 
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index c8b8ccc370eb..65ecd3746c3b 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -70,6 +70,7 @@
  * @WLAN_STA_MPSP_RECIPIENT: local STA is recipient of a MPSP.
  * @WLAN_STA_PS_DELIVER: station woke up, but we're still blocking TX
  * until pending frames are delivered
+ * @WLAN_STA_BLOCK_MPATH: block adding this station as a mesh path
  *
  * @NUM_WLAN_STA_FLAGS: number of defined flags
  */
@@ -100,6 +101,7 @@ enum ieee80211_sta_info_flags {
WLAN_STA_MPSP_OWNER,
WLAN_STA_MPSP_RECIPIENT,
WLAN_STA_PS_DELIVER,
+   WLAN_STA_BLOCK_MPATH,
 
NUM_WLAN_STA_FLAGS,
 };
-- 
2.6.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] ath9k: remove repetitions of mask array size

2016-04-16 Thread Bob Copeland
The constant "123", which is the number of elements in
mask_m / mask_p, is repeated several times in this function.

Replace memsets with array initialization, and replace a loop
conditional with ARRAY_SIZE() so that we don't repeat ourselves.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c 
b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 1b271b9..8eea8d2 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -260,8 +260,8 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,
int cur_bin;
int upper, lower, cur_vit_mask;
int i;
-   int8_t mask_m[123];
-   int8_t mask_p[123];
+   int8_t mask_m[123] = {0};
+   int8_t mask_p[123] = {0};
int8_t mask_amt;
int tmp_mask;
static const int pilot_mask_reg[4] = {
@@ -274,9 +274,6 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,
};
static const int inc[4] = { 0, 100, 0, 0 };
 
-   memset(_m, 0, sizeof(int8_t) * 123);
-   memset(_p, 0, sizeof(int8_t) * 123);
-
cur_bin = -6000;
upper = bin + 100;
lower = bin - 100;
@@ -302,7 +299,7 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,
upper = bin + 120;
lower = bin - 120;
 
-   for (i = 0; i < 123; i++) {
+   for (i = 0; i < ARRAY_SIZE(mask_m); i++) {
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
/* workaround for gcc bug #37014 */
volatile int tmp_v = abs(cur_vit_mask - bin);
-- 
2.1.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] ath9k: ar5008_hw_cmn_spur_mitigate: add missing mask_m & mask_p initialisation

2016-04-16 Thread Bob Copeland
On Sat, Apr 16, 2016 at 08:01:59AM +0200, Oleksij Rempel wrote:
> > For a future patch, "sizeof(mask_m)" or even just:
> > 
> > u8 mask_m[123] = {0};
> > 
> > ... would be better here.  I looked at this bit and thought, no way is
> > "123" actually correct.  Lo and behold, that is actually the number of
> > array elements, whether that has a basis in something real or not :)
> 
> If you already on it can you please rework it on top of this patch?
> This complete function can be probably reworked.

I wasn't on it, but yeah I'll send a patch on top of this momentarily :)

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] ath9k: ar5008_hw_cmn_spur_mitigate: add missing mask_m & mask_p initialisation

2016-04-15 Thread Bob Copeland
On Tue, Apr 12, 2016 at 07:37:44PM +0200, Oleksij Rempel wrote:
> by moving common code to ar5008_hw_cmn_spur_mitigate i forgot to move
> mask_m & mask_p initialisation. This coused a performance regression
> on ar9281.
> 
> Fixes: f911085ffa88 ("ath9k: split ar5008_hw_spur_mitigate and reuse common 
> code in ar9002_hw_spur_mitigate.")
> Reported-by: Gustav Frederiksen <lkml2...@openmailbox.org>
> Tested-by: Gustav Frederiksen <lkml2...@openmailbox.org>
> Signed-off-by: Oleksij Rempel <li...@rempel-privat.de>
> ---
>  drivers/net/wireless/ath/ath9k/ar5008_phy.c | 8 +++-
>  drivers/net/wireless/ath/ath9k/ar9002_phy.c | 5 -
>  2 files changed, 3 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c 
> b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
> index 8f87930..1b271b9 100644
> --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
> +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
> @@ -274,6 +274,9 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,
>   };
>   static const int inc[4] = { 0, 100, 0, 0 };
>  
> + memset(_m, 0, sizeof(int8_t) * 123);
> + memset(_p, 0, sizeof(int8_t) * 123);
> +

For a future patch, "sizeof(mask_m)" or even just:

u8 mask_m[123] = {0};

... would be better here.  I looked at this bit and thought, no way is
"123" actually correct.  Lo and behold, that is actually the number of
array elements, whether that has a basis in something real or not :)

-- 
Bob Copeland %% http://bobcopeland.com/
--
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


wireless-testing updated for 4.6

2016-03-27 Thread Bob Copeland
Linus released 4.6-rc1 yesterday, so wireless-testing is now updated to 4.6
and resuming near-daily updates.

Do let me know of any issues.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/2] mac80211: mesh: fix cleanup for mesh pathtable

2016-03-26 Thread Bob Copeland
+0x14b/0x24e
[   47.753026]  [] worker_thread+0x249/0x343
[   47.753026]  [] ? process_scheduled_works+0x24/0x24
[   47.753026]  [] kthread+0x9e/0xa3
[   47.753026]  [] ret_from_kernel_thread+0x20/0x40
[   47.753026]  [] ? kthread_parkme+0x18/0x18
[   47.753026] Code: 6b c0 85 c0 75 05 e8 fb 74 fc ff 89 f8 84 c0 75 08 8d 45 
e8 e8 34 dd 33 00 83 c4 28 5b 5e 5f 5d c3 55 8b 80 10 02 00 00 89 e5 5d <8b> 40 
f0 c3 55 b9 04 00 00 00 89 e5 52 8b 90 10 02 00 00 8d 45
[   47.753026] EIP: [] kthread_data+0xa/0xe SS:ESP 0068:f6463a78
[   47.753026] CR2: fff0
[   47.753026] ---[ end trace 867ca0bdd0767790 ]---

Fixes: 3b302ada7f0a ("mac80211: mesh: move path tables into if_mesh")
Reported-by: Fred Veldini <fred.veld...@gmail.com>
Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
Just to try to make it somewhat clear, there are a total of three outstanding
patches to fix bugs in my half-baked rhashtable conversion: these two, and
also "mac80211: mesh: fix crash in mesh_path_timer".

The other series of 5 patches, starting with:
"[PATCH 1/5] mac80211: mesh: handle failed alloc for rmc cache" -- are less
critical, with the possible exception of 1/5, but I've never seen that one
actually happen in the wild.

I don't believe these patchsets will conflict with each other, but do let me
know if I need to respin for something, or if we should drop the whole thing
and I should resend with patches applied.

 net/mac80211/iface.c | 2 +-
 net/mac80211/mesh.c  | 7 ++-
 net/mac80211/mesh.h  | 1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 453b4e741780..097ece8b5c02 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1093,7 +1093,7 @@ static void ieee80211_teardown_sdata(struct 
ieee80211_sub_if_data *sdata)
sdata->fragment_next = 0;
 
if (ieee80211_vif_is_mesh(>vif))
-   mesh_rmc_free(sdata);
+   ieee80211_mesh_teardown_sdata(sdata);
 }
 
 static void ieee80211_uninit(struct net_device *dev)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 1a2aaf461e98..dcc1facc807c 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -905,7 +905,6 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data 
*sdata)
/* flush STAs and mpaths on this iface */
sta_info_flush(sdata);
mesh_path_flush_by_iface(sdata);
-   mesh_pathtbl_unregister(sdata);
 
/* free all potentially still buffered group-addressed frames */
local->total_ps_buffered -= skb_queue_len(>ps.bc_buf);
@@ -1403,3 +1402,9 @@ void ieee80211_mesh_init_sdata(struct 
ieee80211_sub_if_data *sdata)
 
sdata->vif.bss_conf.bssid = zero_addr;
 }
+
+void ieee80211_mesh_teardown_sdata(struct ieee80211_sub_if_data *sdata)
+{
+   mesh_rmc_free(sdata);
+   mesh_pathtbl_unregister(sdata);
+}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index f298987228c9..26b9ccbe1fce 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -219,6 +219,7 @@ void ieee80211s_init(void);
 void ieee80211s_update_metric(struct ieee80211_local *local,
  struct sta_info *sta, struct sk_buff *skb);
 void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
+void ieee80211_mesh_teardown_sdata(struct ieee80211_sub_if_data *sdata);
 int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
 void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh);
-- 
2.6.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


Re: [RFCv2 0/3] mac80211: implement fq codel

2016-03-19 Thread Bob Copeland
On Wed, Mar 16, 2016 at 11:36:31AM -0700, Dave Taht wrote:
> That is the sanest 802.11e queue behavior I have ever seen!  (at both
> 6 and 300mbit! in the ath10k patched mac test)

Out of curiosity, why does BE have larger latency than BK in that chart?
I'd have expected the opposite.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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: [RFCv2 0/3] mac80211: implement fq codel

2016-03-19 Thread Bob Copeland
On Thu, Mar 17, 2016 at 09:55:03AM +0100, Michal Kazior wrote:
> If you consider Wi-Fi is half-duplex and latency in the entire stack
> (for processing ICMP and UDP_RR) is greater than 11e contention window
> timings you can get your BE flow responses with extra delay (since
> other queues might have responses ready quicker).

Got it, that makes sense.  Thanks for the explanation!

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/5] mac80211: mesh: reorder structure members

2016-03-18 Thread Bob Copeland
Reduce padding waste in struct mesh_table and struct rmc_entry by
moving the smaller fields to the end.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 net/mac80211/mesh.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 46b540a25d9d..4a59c034cc6d 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -133,11 +133,10 @@ struct mesh_path {
  * @rhash: the rhashtable containing struct mesh_paths, keyed by dest addr
  */
 struct mesh_table {
-   atomic_t entries;   /* Up to MAX_MESH_NEIGHBOURS */
struct hlist_head known_gates;
spinlock_t gates_lock;
-
struct rhashtable rhead;
+   atomic_t entries;   /* Up to MAX_MESH_NEIGHBOURS */
 };
 
 /* Recent multicast cache */
@@ -159,8 +158,8 @@ struct mesh_table {
  */
 struct rmc_entry {
struct hlist_node list;
-   u32 seqnum;
unsigned long exp_time;
+   u32 seqnum;
u8 sa[ETH_ALEN];
 };
 
-- 
2.6.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 0/5] mesh struct cleanups

2016-03-18 Thread Bob Copeland
This series makes a few minor mesh cleanups after the rhashtable
rework -- mostly some reductions in padding and allocation waste.

Bob Copeland (5):
  mac80211: mesh: handle failed alloc for rmc cache
  mac80211: mesh: use hlist for rmc cache
  mac80211: mesh: embed gates hlist head directly
  mac80211: mesh: reorder structure members
  mac80211: mesh: fix mesh path kerneldoc

 net/mac80211/mesh.c | 21 +
 net/mac80211/mesh.h | 31 +--
 net/mac80211/mesh_pathtbl.c | 18 --
 3 files changed, 34 insertions(+), 36 deletions(-)

-- 
2.6.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


wireless-testing paused for merge window

2016-03-14 Thread Bob Copeland
With the release of 4.5, I did one last tag today in wireless-testing.git
with the current state of the wireless trees (wt-2016-03-14).

As I did for most of the last merge window, I plan to sit out the chaos
and wait for 4.6-rc1 to resume the near-daily wireless-testing builds.

See you in a couple of weeks...

-- 
Bob Copeland %% http://bobcopeland.com/
--
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: [RFC/RFT] mac80211: implement fq_codel for software queuing

2016-03-08 Thread Bob Copeland
On Tue, Mar 08, 2016 at 08:12:21AM +0100, Michal Kazior wrote:
> However other drivers (e.g. ath10k) have offloaded rate control on
> device. There's currently no way of doing this calculation. I was
> thinking of drivers exporting tx_rate to mac80211 in some way - either
> via a simple sta->tx_rate scalar that the driver is responsible for
> updating, or a EWMA that driver updates (hopefully) periodically and
> often enough. This should in theory at least allow an estimate how
> much data on average you can fit into given time frame (e.g. txop, or
> hardcoded 1ms).

What about implementing ops->get_expected_throughput?  This would be
useful for mesh (both 11s and batman) as well since they need to
estimate link quality to pick a path.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: mesh: fix crash in mesh_path_timer

2016-03-06 Thread Bob Copeland
The mesh_path_reclaim() function, called from an rcu callback, cancels
the mesh_path_timer associated with a mesh path.  Unfortunately, this
call can happen much later, perhaps after the hash table itself is
destroyed.

Such a situation led to the following crash in mesh_path_send_to_gates()
when dereferencing the tbl pointer:

[   23.901661] BUG: unable to handle kernel NULL pointer dereference at 
0008
[   23.905516] IP: [] mesh_path_send_to_gates+0x2b/0x740
[   23.908757] PGD 99ca067 PUD 99c4067 PMD 0
[   23.910789] Oops:  [#1] PREEMPT SMP DEBUG_PAGEALLOC
[   23.913485] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.5.0-rc6-wt+ #43
[   23.916675] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
Debian-1.8.2-1 04/01/2014
[   23.920471] task: 81685500 ti: 81678000 task.ti: 
81678000
[   23.922619] RIP: 0010:[]  [] 
mesh_path_send_to_gates+0x2b/0x740
[   23.925237] RSP: 0018:88000b403d30  EFLAGS: 00010286
[   23.926739] RAX:  RBX: 880009bc0d20 RCX: 0102
[   23.928796] RDX: 002e RSI: 0001 RDI: 880009bc0d20
[   23.930895] RBP: 88000b403e18 R08: 0001 R09: 0001
[   23.932917] R10:  R11: 0001 R12: 880009c20940
[   23.936370] R13: 880009bc0e70 R14: 880009c21c40 R15: 880009bc0d20
[   23.939823] FS:  () GS:88000b40() 
knlGS:
[   23.943688] CS:  0010 DS:  ES:  CR0: 8005003b
[   23.946429] CR2: 0008 CR3: 099c5000 CR4: 06b0
[   23.949861] Stack:
[   23.950840]  002e 880009c20940 88000b403da8 
8109e551
[   23.954467]  82711be2 002e  
8166a5f5
[   23.958141]  00685ce8 0246 880009bc0d20 
880009c20940
[   23.961801] Call Trace:
[   23.962987]  
[   23.963963]  [] ? vprintk_emit+0x351/0x5e0
[   23.966782]  [] ? vprintk_default+0x1f/0x30
[   23.969529]  [] ? printk+0x48/0x50
[   23.971956]  [] mesh_path_timer+0x133/0x160
[   23.974707]  [] ? mesh_nexthop_resolve+0x230/0x230
[   23.95]  [] call_timer_fn+0xce/0x330
[   23.980448]  [] ? call_timer_fn+0x5/0x330
[   23.983126]  [] ? mesh_nexthop_resolve+0x230/0x230
[   23.986091]  [] run_timer_softirq+0x22c/0x390

Instead of cancelling in the RCU callback, set a new flag to prevent the
timer from being rearmed, and then cancel the timer synchronously when
freeing the mesh path.  This leaves mesh_path_reclaim() doing nothing
but kfree, so switch to kfree_rcu().

Fixes: 3b302ada7f0a ("mac80211: mesh: move path tables into if_mesh")
Reported-by: Jouni Malinen <j...@w1.fi>
Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 net/mac80211/mesh.h |  3 +++
 net/mac80211/mesh_hwmp.c|  2 ++
 net/mac80211/mesh_pathtbl.c | 34 +++---
 3 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index cc6854db156e..e1415c952e9c 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -32,6 +32,8 @@
  * @MESH_PATH_RESOLVED: the mesh path can has been resolved
  * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination
  * already queued up, waiting for the discovery process to start.
+ * @MESH_PATH_DELETED: the mesh path has been deleted and should no longer
+ * be used
  *
  * MESH_PATH_RESOLVED is used by the mesh path timer to
  * decide when to stop or cancel the mesh path discovery.
@@ -43,6 +45,7 @@ enum mesh_path_flags {
MESH_PATH_FIXED =   BIT(3),
MESH_PATH_RESOLVED =BIT(4),
MESH_PATH_REQ_QUEUED =  BIT(5),
+   MESH_PATH_DELETED = BIT(6),
 };
 
 /**
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index c6be0b4f4058..bdf4647c158c 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1012,6 +1012,8 @@ void mesh_path_start_discovery(struct 
ieee80211_sub_if_data *sdata)
goto enddiscovery;
 
spin_lock_bh(>state_lock);
+   if (mpath->flags & MESH_PATH_DELETED)
+   goto enddiscovery;
mpath->flags &= ~MESH_PATH_REQ_QUEUED;
if (preq_node->flags & PREQ_Q_F_START) {
if (mpath->flags & MESH_PATH_RESOLVING) {
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 7455397f8c3b..2c2c81e1d7c9 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -18,6 +18,9 @@
 #include "ieee80211_i.h"
 #include "mesh.h"
 
+static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath);
+static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path 
*mpath);
+
 static u32 mesh_table_hash(const void *addr, u32 len, u32 seed)
 {
/* Use last four bytes of hw addr as hash index */
@@ -40,18 +43,12 @@ static inline 

refcnt fix in wireless-testing

2016-03-04 Thread Bob Copeland
Just a quick note that if you are using a recent wireless-testing,
there's a reference counting bug which was fixed in net-next:

https://git.kernel.org/davem/net-next/c/799977d9aaf

I've cherry-picked this commit for today's build and will keep doing
so for the 4.5.x series or until no longer needed.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 1/2] rhashtable: accept GFP flags in rhashtable_walk_init

2016-03-03 Thread Bob Copeland
On Thu, Mar 03, 2016 at 04:26:19PM +0100, Johannes Berg wrote:
> On Wed, 2016-03-02 at 10:09 -0500, Bob Copeland wrote:
> > In certain cases, the 802.11 mesh pathtable code wants to
> > iterate over all of the entries in the forwarding table from
> > the receive path, which is inside an RCU read-side critical
> > section.  Enable walks inside atomic sections by allowing
> > GFP_ATOMIC allocations for the walker state.
> > 
> > Change all existing callsites to pass in GFP_KERNEL.
> 
> Applied both. You missed 3 callsites, I've fixed those. I hope I got
> them all :)

Ouch, thanks for the catch, I must've grepped only in net.
And now I added those files to my build config. :)

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/2] rhashtable: accept GFP flags in rhashtable_walk_init

2016-03-02 Thread Bob Copeland
In certain cases, the 802.11 mesh pathtable code wants to
iterate over all of the entries in the forwarding table from
the receive path, which is inside an RCU read-side critical
section.  Enable walks inside atomic sections by allowing
GFP_ATOMIC allocations for the walker state.

Change all existing callsites to pass in GFP_KERNEL.

Cc: Thomas Graf <tg...@suug.ch>
Cc: net...@vger.kernel.org
Acked-by: Thomas Graf <tg...@suug.ch>
Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
(-RFC, +Thomas's Ack)

 include/linux/rhashtable.h | 3 ++-
 lib/rhashtable.c   | 6 --
 net/ipv6/ila/ila_xlat.c| 3 ++-
 net/netfilter/nft_hash.c   | 4 ++--
 net/netlink/af_netlink.c   | 3 ++-
 net/sctp/proc.c| 3 ++-
 6 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 63bd7601b6de..3eef0802a0cd 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -346,7 +346,8 @@ struct bucket_table *rhashtable_insert_slow(struct 
rhashtable *ht,
struct bucket_table *old_tbl);
 int rhashtable_insert_rehash(struct rhashtable *ht, struct bucket_table *tbl);
 
-int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter);
+int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter,
+gfp_t gfp);
 void rhashtable_walk_exit(struct rhashtable_iter *iter);
 int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU);
 void *rhashtable_walk_next(struct rhashtable_iter *iter);
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index cc808707d1cf..5d845ffd7982 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -487,6 +487,7 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_slow);
  * rhashtable_walk_init - Initialise an iterator
  * @ht:Table to walk over
  * @iter:  Hash table Iterator
+ * @gfp:   GFP flags for allocations
  *
  * This function prepares a hash table walk.
  *
@@ -504,14 +505,15 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_slow);
  * You must call rhashtable_walk_exit if this function returns
  * successfully.
  */
-int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter)
+int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter,
+gfp_t gfp)
 {
iter->ht = ht;
iter->p = NULL;
iter->slot = 0;
iter->skip = 0;
 
-   iter->walker = kmalloc(sizeof(*iter->walker), GFP_KERNEL);
+   iter->walker = kmalloc(sizeof(*iter->walker), gfp);
if (!iter->walker)
return -ENOMEM;
 
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 295ca29a23c3..0b03533453e4 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -501,7 +501,8 @@ static int ila_nl_dump_start(struct netlink_callback *cb)
struct ila_net *ilan = net_generic(net, ila_net_id);
struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args;
 
-   return rhashtable_walk_init(>rhash_table, >rhiter);
+   return rhashtable_walk_init(>rhash_table, >rhiter,
+   GFP_KERNEL);
 }
 
 static int ila_nl_dump_done(struct netlink_callback *cb)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 3f9d45d3d9b7..6fa016564f90 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -192,7 +192,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const 
struct nft_set *set,
u8 genmask = nft_genmask_cur(read_pnet(>pnet));
int err;
 
-   err = rhashtable_walk_init(>ht, );
+   err = rhashtable_walk_init(>ht, , GFP_KERNEL);
iter->err = err;
if (err)
return;
@@ -248,7 +248,7 @@ static void nft_hash_gc(struct work_struct *work)
priv = container_of(work, struct nft_hash, gc_work.work);
set  = nft_set_container_of(priv);
 
-   err = rhashtable_walk_init(>ht, );
+   err = rhashtable_walk_init(>ht, , GFP_KERNEL);
if (err)
goto schedule;
 
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index c8416792cce0..6e0cbdeb21d3 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2335,7 +2335,8 @@ static int netlink_walk_start(struct nl_seq_iter *iter)
 {
int err;
 
-   err = rhashtable_walk_init(_table[iter->link].hash, >hti);
+   err = rhashtable_walk_init(_table[iter->link].hash, >hti,
+  GFP_KERNEL);
if (err) {
iter->link = MAX_LINKS;
return err;
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index cfc3c7101a38..c5991e5e5daf 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -319,7 +319,8 @@ static int sctp_transport_walk_start(struct seq_file *seq)
struct sctp_ht_iter *iter = seq->private

[PATCH 2/2] mac80211: mesh: convert path table to rhashtable

2016-03-02 Thread Bob Copeland
In the time since the mesh path table was implemented as an
RCU-traversable, dynamically growing hash table, a generic RCU
hashtable implementation was added to the kernel.

Switch the mesh path table over to rhashtable to remove some code
and also gain some features like automatic shrinking.

Cc: Thomas Graf <tg...@suug.ch>
Cc: net...@vger.kernel.org
Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 net/mac80211/ieee80211_i.h  |  11 +-
 net/mac80211/mesh.c |   6 -
 net/mac80211/mesh.h |  31 +-
 net/mac80211/mesh_pathtbl.c | 786 ++--
 4 files changed, 259 insertions(+), 575 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index db7f0dbebc4b..c8945e2d8a86 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -697,17 +697,10 @@ struct ieee80211_if_mesh {
/* offset from skb->data while building IE */
int meshconf_offset;
 
-   struct mesh_table __rcu *mesh_paths;
-   struct mesh_table __rcu *mpp_paths; /* Store paths for MPP */
+   struct mesh_table *mesh_paths;
+   struct mesh_table *mpp_paths; /* Store paths for MPP */
int mesh_paths_generation;
int mpp_paths_generation;
-
-   /* Protects assignment of the mesh_paths/mpp_paths table
-* pointer for resize against reading it for add/delete
-* of individual paths.  Pure readers (lookups) just use
-* RCU.
-*/
-   rwlock_t pathtbl_resize_lock;
 };
 
 #ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c92af2a7714d..a216c439b6f2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1347,12 +1347,6 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data 
*sdata)
   ifmsh->last_preq + 
msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval)))
mesh_path_start_discovery(sdata);
 
-   if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, >wrkq_flags))
-   mesh_mpath_table_grow(sdata);
-
-   if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, >wrkq_flags))
-   mesh_mpp_table_grow(sdata);
-
if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, >wrkq_flags))
ieee80211_mesh_housekeeping(sdata);
 
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index f3cc3917e048..cc6854db156e 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -51,10 +51,6 @@ enum mesh_path_flags {
  *
  *
  * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
- * @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs
- * to grow.
- * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
- * grow
  * @MESH_WORK_ROOT: the mesh root station needs to send a frame
  * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to 
other
  * mesh nodes
@@ -62,8 +58,6 @@ enum mesh_path_flags {
  */
 enum mesh_deferred_task_flags {
MESH_WORK_HOUSEKEEPING,
-   MESH_WORK_GROW_MPATH_TABLE,
-   MESH_WORK_GROW_MPP_TABLE,
MESH_WORK_ROOT,
MESH_WORK_DRIFT_ADJUST,
MESH_WORK_MBSS_CHANGED,
@@ -105,6 +99,7 @@ enum mesh_deferred_task_flags {
 struct mesh_path {
u8 dst[ETH_ALEN];
u8 mpp[ETH_ALEN];   /* used for MPP or MAP */
+   struct rhash_head rhash;
struct hlist_node gate_list;
struct ieee80211_sub_if_data *sdata;
struct sta_info __rcu *next_hop;
@@ -129,34 +124,17 @@ struct mesh_path {
 /**
  * struct mesh_table
  *
- * @hash_buckets: array of hash buckets of the table
- * @hashwlock: array of locks to protect write operations, one per bucket
- * @hash_mask: 2^size_order - 1, used to compute hash idx
- * @hash_rnd: random value used for hash computations
  * @entries: number of entries in the table
- * @free_node: function to free nodes of the table
- * @copy_node: function to copy nodes of the table
- * @size_order: determines size of the table, there will be 2^size_order hash
- * buckets
  * @known_gates: list of known mesh gates and their mpaths by the station. The
  * gate's mpath may or may not be resolved and active.
- *
- * rcu_head: RCU head to free the table
+ * @rhash: the rhashtable containing struct mesh_paths, keyed by dest addr
  */
 struct mesh_table {
-   /* Number of buckets will be 2^N */
-   struct hlist_head *hash_buckets;
-   spinlock_t *hashwlock;  /* One per bucket, for add/del */
-   unsigned int hash_mask; /* (2^size_order) - 1 */
-   __u32 hash_rnd; /* Used for hash generation */
atomic_t entries;   /* Up to MAX_MESH_NEIGHBOURS */
-   void (*free_node) (struct hlist_node *p, bool free_leafs);
-   int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
-   int size_order;
struct hlist_head *known_gates;
spinlock_t gates_lock;
 
-   struct rcu_head rcu_head;
+

Re: [PATCH RFC 1/2] rhashtable: accept GFP flags in rhashtable_walk_init

2016-03-01 Thread Bob Copeland
On Tue, Mar 01, 2016 at 02:54:16PM +0100, Johannes Berg wrote:
> On Sun, 2016-02-28 at 20:06 -0500, Bob Copeland wrote:
> > In certain cases, the 802.11 mesh pathtable code wants to
> > iterate over all of the entries in the forwarding table from
> > the receive path, which is inside an RCU read-side critical
> > section.  Enable walks inside atomic sections by allowing
> > GFP_ATOMIC allocations for the walker state.
> > 
> > Change all existing callsites to pass in GFP_KERNEL.
> 
> Both look fine to me.
> 
> I see you have more patches for mesh, so this probably can't go through
> net-next tree directly.

Yeah, these two are on top of the other mesh path table changes.

So either both of these could go via mac80211-next or we could do the
1/2 in net-next and wait to apply 2/2 in mac80211-next.  Whatever works
for you guys.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/3] ath9k: fix a misleading indentation

2016-02-28 Thread Bob Copeland
These lines belong inside the if-statement above, not in the
main body of the switch.

Found by smatch.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c 
b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 201425e7f9cb..3e011f84211f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1332,11 +1332,11 @@ skip_ws_det:
chan->channel,
aniState->mrcCCK ? "on" : "off",
is_on ? "on" : "off");
-   if (is_on)
-   ah->stats.ast_ani_ccklow++;
-   else
-   ah->stats.ast_ani_cckhigh++;
-   aniState->mrcCCK = is_on;
+   if (is_on)
+   ah->stats.ast_ani_ccklow++;
+   else
+   ah->stats.ast_ani_cckhigh++;
+   aniState->mrcCCK = is_on;
}
break;
}
-- 
2.6.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/3] ath9k_htc: fix up indents with spaces

2016-02-28 Thread Bob Copeland
Use tabs here.  Found by smatch.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 drivers/net/wireless/ath/ath9k/htc_drv_init.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c 
b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 8647ab77c019..c2249ad54085 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -262,11 +262,11 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr,
__be32 tmpval[8];
int i, ret;
 
-   for (i = 0; i < count; i++) {
-  tmpaddr[i] = cpu_to_be32(addr[i]);
-   }
+   for (i = 0; i < count; i++) {
+   tmpaddr[i] = cpu_to_be32(addr[i]);
+   }
 
-   ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
+   ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
   (u8 *)tmpaddr , sizeof(u32) * count,
   (u8 *)tmpval, sizeof(u32) * count,
   100);
@@ -275,9 +275,9 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr,
"Multiple REGISTER READ FAILED (count: %d)\n", count);
}
 
-   for (i = 0; i < count; i++) {
-  val[i] = be32_to_cpu(tmpval[i]);
-   }
+   for (i = 0; i < count; i++) {
+   val[i] = be32_to_cpu(tmpval[i]);
+   }
 }
 
 static void ath9k_regwrite_multi(struct ath_common *common)
-- 
2.6.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 RFC 1/2] rhashtable: accept GFP flags in rhashtable_walk_init

2016-02-28 Thread Bob Copeland
In certain cases, the 802.11 mesh pathtable code wants to
iterate over all of the entries in the forwarding table from
the receive path, which is inside an RCU read-side critical
section.  Enable walks inside atomic sections by allowing
GFP_ATOMIC allocations for the walker state.

Change all existing callsites to pass in GFP_KERNEL.

Cc: Thomas Graf <tg...@suug.ch>
Cc: net...@vger.kernel.org
Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 include/linux/rhashtable.h | 3 ++-
 lib/rhashtable.c   | 6 --
 net/ipv6/ila/ila_xlat.c| 3 ++-
 net/netfilter/nft_hash.c   | 4 ++--
 net/netlink/af_netlink.c   | 3 ++-
 net/sctp/proc.c| 3 ++-
 6 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 63bd7601b6de..3eef0802a0cd 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -346,7 +346,8 @@ struct bucket_table *rhashtable_insert_slow(struct 
rhashtable *ht,
struct bucket_table *old_tbl);
 int rhashtable_insert_rehash(struct rhashtable *ht, struct bucket_table *tbl);
 
-int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter);
+int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter,
+gfp_t gfp);
 void rhashtable_walk_exit(struct rhashtable_iter *iter);
 int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU);
 void *rhashtable_walk_next(struct rhashtable_iter *iter);
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index cc808707d1cf..5d845ffd7982 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -487,6 +487,7 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_slow);
  * rhashtable_walk_init - Initialise an iterator
  * @ht:Table to walk over
  * @iter:  Hash table Iterator
+ * @gfp:   GFP flags for allocations
  *
  * This function prepares a hash table walk.
  *
@@ -504,14 +505,15 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_slow);
  * You must call rhashtable_walk_exit if this function returns
  * successfully.
  */
-int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter)
+int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter,
+gfp_t gfp)
 {
iter->ht = ht;
iter->p = NULL;
iter->slot = 0;
iter->skip = 0;
 
-   iter->walker = kmalloc(sizeof(*iter->walker), GFP_KERNEL);
+   iter->walker = kmalloc(sizeof(*iter->walker), gfp);
if (!iter->walker)
return -ENOMEM;
 
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 295ca29a23c3..0b03533453e4 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -501,7 +501,8 @@ static int ila_nl_dump_start(struct netlink_callback *cb)
struct ila_net *ilan = net_generic(net, ila_net_id);
struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args;
 
-   return rhashtable_walk_init(>rhash_table, >rhiter);
+   return rhashtable_walk_init(>rhash_table, >rhiter,
+   GFP_KERNEL);
 }
 
 static int ila_nl_dump_done(struct netlink_callback *cb)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 3f9d45d3d9b7..6fa016564f90 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -192,7 +192,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const 
struct nft_set *set,
u8 genmask = nft_genmask_cur(read_pnet(>pnet));
int err;
 
-   err = rhashtable_walk_init(>ht, );
+   err = rhashtable_walk_init(>ht, , GFP_KERNEL);
iter->err = err;
if (err)
return;
@@ -248,7 +248,7 @@ static void nft_hash_gc(struct work_struct *work)
priv = container_of(work, struct nft_hash, gc_work.work);
set  = nft_set_container_of(priv);
 
-   err = rhashtable_walk_init(>ht, );
+   err = rhashtable_walk_init(>ht, , GFP_KERNEL);
if (err)
goto schedule;
 
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index c8416792cce0..6e0cbdeb21d3 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2335,7 +2335,8 @@ static int netlink_walk_start(struct nl_seq_iter *iter)
 {
int err;
 
-   err = rhashtable_walk_init(_table[iter->link].hash, >hti);
+   err = rhashtable_walk_init(_table[iter->link].hash, >hti,
+  GFP_KERNEL);
if (err) {
iter->link = MAX_LINKS;
return err;
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index cfc3c7101a38..c5991e5e5daf 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -319,7 +319,8 @@ static int sctp_transport_walk_start(struct seq_file *seq)
struct sctp_ht_iter *iter = seq->private;
int err;
 
-   err = rhashtable_walk_init(

[PATCH RFC 2/2] mac80211: mesh: convert path table to rhashtable

2016-02-28 Thread Bob Copeland
In the time since the mesh path table was implemented as an
RCU-traversable, dynamically growing hash table, a generic RCU
hashtable implementation was added to the kernel.

Switch the mesh path table over to rhashtable to remove some code
and also gain some features like automatic shrinking.

Cc: Thomas Graf <tg...@suug.ch>
Cc: net...@vger.kernel.org
Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 net/mac80211/ieee80211_i.h  |  11 +-
 net/mac80211/mesh.c |   6 -
 net/mac80211/mesh.h |  31 +-
 net/mac80211/mesh_pathtbl.c | 786 ++--
 4 files changed, 259 insertions(+), 575 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 597f1b6260f4..a2857cd6d479 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -697,17 +697,10 @@ struct ieee80211_if_mesh {
/* offset from skb->data while building IE */
int meshconf_offset;
 
-   struct mesh_table __rcu *mesh_paths;
-   struct mesh_table __rcu *mpp_paths; /* Store paths for MPP */
+   struct mesh_table *mesh_paths;
+   struct mesh_table *mpp_paths; /* Store paths for MPP */
int mesh_paths_generation;
int mpp_paths_generation;
-
-   /* Protects assignment of the mesh_paths/mpp_paths table
-* pointer for resize against reading it for add/delete
-* of individual paths.  Pure readers (lookups) just use
-* RCU.
-*/
-   rwlock_t pathtbl_resize_lock;
 };
 
 #ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c92af2a7714d..a216c439b6f2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1347,12 +1347,6 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data 
*sdata)
   ifmsh->last_preq + 
msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval)))
mesh_path_start_discovery(sdata);
 
-   if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, >wrkq_flags))
-   mesh_mpath_table_grow(sdata);
-
-   if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, >wrkq_flags))
-   mesh_mpp_table_grow(sdata);
-
if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, >wrkq_flags))
ieee80211_mesh_housekeeping(sdata);
 
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index f3cc3917e048..cc6854db156e 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -51,10 +51,6 @@ enum mesh_path_flags {
  *
  *
  * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
- * @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs
- * to grow.
- * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
- * grow
  * @MESH_WORK_ROOT: the mesh root station needs to send a frame
  * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to 
other
  * mesh nodes
@@ -62,8 +58,6 @@ enum mesh_path_flags {
  */
 enum mesh_deferred_task_flags {
MESH_WORK_HOUSEKEEPING,
-   MESH_WORK_GROW_MPATH_TABLE,
-   MESH_WORK_GROW_MPP_TABLE,
MESH_WORK_ROOT,
MESH_WORK_DRIFT_ADJUST,
MESH_WORK_MBSS_CHANGED,
@@ -105,6 +99,7 @@ enum mesh_deferred_task_flags {
 struct mesh_path {
u8 dst[ETH_ALEN];
u8 mpp[ETH_ALEN];   /* used for MPP or MAP */
+   struct rhash_head rhash;
struct hlist_node gate_list;
struct ieee80211_sub_if_data *sdata;
struct sta_info __rcu *next_hop;
@@ -129,34 +124,17 @@ struct mesh_path {
 /**
  * struct mesh_table
  *
- * @hash_buckets: array of hash buckets of the table
- * @hashwlock: array of locks to protect write operations, one per bucket
- * @hash_mask: 2^size_order - 1, used to compute hash idx
- * @hash_rnd: random value used for hash computations
  * @entries: number of entries in the table
- * @free_node: function to free nodes of the table
- * @copy_node: function to copy nodes of the table
- * @size_order: determines size of the table, there will be 2^size_order hash
- * buckets
  * @known_gates: list of known mesh gates and their mpaths by the station. The
  * gate's mpath may or may not be resolved and active.
- *
- * rcu_head: RCU head to free the table
+ * @rhash: the rhashtable containing struct mesh_paths, keyed by dest addr
  */
 struct mesh_table {
-   /* Number of buckets will be 2^N */
-   struct hlist_head *hash_buckets;
-   spinlock_t *hashwlock;  /* One per bucket, for add/del */
-   unsigned int hash_mask; /* (2^size_order) - 1 */
-   __u32 hash_rnd; /* Used for hash generation */
atomic_t entries;   /* Up to MAX_MESH_NEIGHBOURS */
-   void (*free_node) (struct hlist_node *p, bool free_leafs);
-   int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
-   int size_order;
struct hlist_head *known_gates;
spinlock_t gates_lock;
 
-   struct rcu_head rcu_head;
+

[PATCH 4/4] mac80211: mesh: embed known gates list in struct mesh_path

2016-02-28 Thread Bob Copeland
The mesh path table uses a struct mesh_node in its hlists in
order to support a resizable hash table: the mesh_node provides
an indirection to the actual mesh path so that two different
bucket lists can point to the same path entry.

However, for the known gates list, we don't need this indirection
because there is ever only one list.  So we can just embed the
hlist_node in the mesh path itself, which simplifies things a bit
and saves a linear search whenever we need to find an item in
the list.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 net/mac80211/mesh.h |   1 +
 net/mac80211/mesh_pathtbl.c | 100 +++-
 2 files changed, 45 insertions(+), 56 deletions(-)

diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 601992b6cd8a..f3cc3917e048 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -105,6 +105,7 @@ enum mesh_deferred_task_flags {
 struct mesh_path {
u8 dst[ETH_ALEN];
u8 mpp[ETH_ALEN];   /* used for MPP or MAP */
+   struct hlist_node gate_list;
struct ieee80211_sub_if_data *sdata;
struct sta_info __rcu *next_hop;
struct timer_list timer;
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 4794240e8f94..e4daf4b94eaf 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -119,10 +119,18 @@ static void mesh_table_free(struct mesh_table *tbl, bool 
free_leafs)
 {
struct hlist_head *mesh_hash;
struct hlist_node *p, *q;
-   struct mpath_node *gate;
+   struct mesh_path *gate;
int i;
 
mesh_hash = tbl->hash_buckets;
+   if (free_leafs) {
+   spin_lock_bh(>gates_lock);
+   hlist_for_each_entry_safe(gate, q,
+ tbl->known_gates, gate_list)
+   hlist_del(>gate_list);
+   kfree(tbl->known_gates);
+   spin_unlock_bh(>gates_lock);
+   }
for (i = 0; i <= tbl->hash_mask; i++) {
spin_lock_bh(>hashwlock[i]);
hlist_for_each_safe(p, q, _hash[i]) {
@@ -131,16 +139,6 @@ static void mesh_table_free(struct mesh_table *tbl, bool 
free_leafs)
}
spin_unlock_bh(>hashwlock[i]);
}
-   if (free_leafs) {
-   spin_lock_bh(>gates_lock);
-   hlist_for_each_entry_safe(gate, q,
-tbl->known_gates, list) {
-   hlist_del(>list);
-   kfree(gate);
-   }
-   kfree(tbl->known_gates);
-   spin_unlock_bh(>gates_lock);
-   }
 
__mesh_table_free(tbl);
 }
@@ -431,30 +429,26 @@ mpp_path_lookup_by_idx(struct ieee80211_sub_if_data 
*sdata, int idx)
 int mesh_path_add_gate(struct mesh_path *mpath)
 {
struct mesh_table *tbl;
-   struct mpath_node *gate, *new_gate;
int err;
 
rcu_read_lock();
tbl = rcu_dereference(mpath->sdata->u.mesh.mesh_paths);
 
-   hlist_for_each_entry_rcu(gate, tbl->known_gates, list)
-   if (gate->mpath == mpath) {
-   err = -EEXIST;
-   goto err_rcu;
-   }
-
-   new_gate = kzalloc(sizeof(struct mpath_node), GFP_ATOMIC);
-   if (!new_gate) {
-   err = -ENOMEM;
+   spin_lock_bh(>state_lock);
+   if (mpath->is_gate) {
+   err = -EEXIST;
+   spin_unlock_bh(>state_lock);
goto err_rcu;
}
-
mpath->is_gate = true;
mpath->sdata->u.mesh.num_gates++;
-   new_gate->mpath = mpath;
-   spin_lock_bh(>gates_lock);
-   hlist_add_head_rcu(_gate->list, tbl->known_gates);
-   spin_unlock_bh(>gates_lock);
+
+   spin_lock(>gates_lock);
+   hlist_add_head_rcu(>gate_list, tbl->known_gates);
+   spin_unlock(>gates_lock);
+
+   spin_unlock_bh(>state_lock);
+
mpath_dbg(mpath->sdata,
  "Mesh path: Recorded new gate: %pM. %d known gates\n",
  mpath->dst, mpath->sdata->u.mesh.num_gates);
@@ -468,28 +462,22 @@ err_rcu:
  * mesh_gate_del - remove a mesh gate from the list of known gates
  * @tbl: table which holds our list of known gates
  * @mpath: gate mpath
- *
- * Locking: must be called inside rcu_read_lock() section
  */
 static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
 {
-   struct mpath_node *gate;
-   struct hlist_node *q;
+   lockdep_assert_held(>state_lock);
+   if (!mpath->is_gate)
+   return;
 
-   hlist_for_each_entry_safe(gate, q, tbl->known_gates, list) {
-   if (gate->mpath != mpath)
-   continue;
-   spin_lock_bh(>gates_lock);
-   hlist_del_rcu(>list);
-  

[PATCH 1/4] mac80211: mesh: move path tables into if_mesh

2016-02-28 Thread Bob Copeland
The mesh path and mesh gate hashtables are global, containing
all of the mpaths for every mesh interface, but the paths are
all tied logically to a single interface.  The common case is
just a single mesh interface, so optimize for that by moving
the global hashtable into the per-interface struct.

Doing so allows us to drop sdata pointer comparisons inside
the lookups and also saves a few bytes of BSS and data.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 net/mac80211/cfg.c  |   4 +-
 net/mac80211/ieee80211_i.h  |  12 +++
 net/mac80211/mesh.c |  10 ++-
 net/mac80211/mesh.h |  10 +--
 net/mac80211/mesh_pathtbl.c | 181 +++-
 net/mac80211/tx.c   |   2 +-
 6 files changed, 104 insertions(+), 115 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index fe1704c4e8fb..b37adb60c9cb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1499,7 +1499,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 
*next_hop,
 
memset(pinfo, 0, sizeof(*pinfo));
 
-   pinfo->generation = mesh_paths_generation;
+   pinfo->generation = mpath->sdata->u.mesh.mesh_paths_generation;
 
pinfo->filled = MPATH_INFO_FRAME_QLEN |
MPATH_INFO_SN |
@@ -1577,7 +1577,7 @@ static void mpp_set_pinfo(struct mesh_path *mpath, u8 
*mpp,
memset(pinfo, 0, sizeof(*pinfo));
memcpy(mpp, mpath->mpp, ETH_ALEN);
 
-   pinfo->generation = mpp_paths_generation;
+   pinfo->generation = mpath->sdata->u.mesh.mpp_paths_generation;
 }
 
 static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 1630975c89f1..597f1b6260f4 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -696,6 +696,18 @@ struct ieee80211_if_mesh {
 
/* offset from skb->data while building IE */
int meshconf_offset;
+
+   struct mesh_table __rcu *mesh_paths;
+   struct mesh_table __rcu *mpp_paths; /* Store paths for MPP */
+   int mesh_paths_generation;
+   int mpp_paths_generation;
+
+   /* Protects assignment of the mesh_paths/mpp_paths table
+* pointer for resize against reading it for add/delete
+* of individual paths.  Pure readers (lookups) just use
+* RCU.
+*/
+   rwlock_t pathtbl_resize_lock;
 };
 
 #ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index d32cefcb63b0..c92af2a7714d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -25,7 +25,6 @@ bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
 
 void ieee80211s_init(void)
 {
-   mesh_pathtbl_init();
mesh_allocated = 1;
rm_cache = kmem_cache_create("mesh_rmc", sizeof(struct rmc_entry),
 0, 0, NULL);
@@ -35,7 +34,6 @@ void ieee80211s_stop(void)
 {
if (!mesh_allocated)
return;
-   mesh_pathtbl_unregister();
kmem_cache_destroy(rm_cache);
 }
 
@@ -902,6 +900,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data 
*sdata)
/* flush STAs and mpaths on this iface */
sta_info_flush(sdata);
mesh_path_flush_by_iface(sdata);
+   mesh_pathtbl_unregister(sdata);
 
/* free all potentially still buffered group-addressed frames */
local->total_ps_buffered -= skb_queue_len(>ps.bc_buf);
@@ -1349,10 +1348,10 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data 
*sdata)
mesh_path_start_discovery(sdata);
 
if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, >wrkq_flags))
-   mesh_mpath_table_grow();
+   mesh_mpath_table_grow(sdata);
 
if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, >wrkq_flags))
-   mesh_mpp_table_grow();
+   mesh_mpp_table_grow(sdata);
 
if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, >wrkq_flags))
ieee80211_mesh_housekeeping(sdata);
@@ -1388,6 +1387,9 @@ void ieee80211_mesh_init_sdata(struct 
ieee80211_sub_if_data *sdata)
/* Allocate all mesh structures when creating the first mesh interface. 
*/
if (!mesh_allocated)
ieee80211s_init();
+
+   mesh_pathtbl_init(sdata);
+
setup_timer(>mesh_path_timer,
ieee80211_mesh_path_timer,
(unsigned long) sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 87c017a3b1ce..601992b6cd8a 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -300,8 +300,8 @@ void mesh_sta_cleanup(struct sta_info *sta);
 
 /* Private interfaces */
 /* Mesh tables */
-void mesh_mpath_table_grow(void);
-void mesh_mpp_table_grow(void);
+void mesh_mpath_table_grow(struct ieee80211_sub_if_data *sdata);
+void mesh_mpp_table_grow(struct ieee80211_sub_if_data *sdata);
 /* Mesh p

[PATCH 2/4] mac80211: mesh: don't hash sdata in mpath tables

2016-02-28 Thread Bob Copeland
Now that the sdata pointer is the same for all entries of a
path table, hashing it is pointless, so hash only the address.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 net/mac80211/mesh_pathtbl.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 0508b37b0471..fc3cc350df8c 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -177,12 +177,10 @@ errcopy:
return -ENOMEM;
 }
 
-static u32 mesh_table_hash(const u8 *addr, struct ieee80211_sub_if_data *sdata,
-  struct mesh_table *tbl)
+static u32 mesh_table_hash(const u8 *addr, struct mesh_table *tbl)
 {
-   /* Use last four bytes of hw addr and interface index as hash index */
-   return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex,
-   tbl->hash_rnd) & tbl->hash_mask;
+   /* Use last four bytes of hw addr as hash index */
+   return jhash_1word(*(u32 *)(addr+2), tbl->hash_rnd) & tbl->hash_mask;
 }
 
 
@@ -331,7 +329,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table 
*tbl, const u8 *dst,
struct hlist_head *bucket;
struct mpath_node *node;
 
-   bucket = >hash_buckets[mesh_table_hash(dst, sdata, tbl)];
+   bucket = >hash_buckets[mesh_table_hash(dst, tbl)];
hlist_for_each_entry_rcu(node, bucket, list) {
mpath = node->mpath;
if (ether_addr_equal(dst, mpath->dst)) {
@@ -538,7 +536,7 @@ struct mesh_path *mesh_path_add(struct 
ieee80211_sub_if_data *sdata,
read_lock_bh(>u.mesh.pathtbl_resize_lock);
tbl = resize_dereference_mesh_paths(sdata);
 
-   hash_idx = mesh_table_hash(dst, sdata, tbl);
+   hash_idx = mesh_table_hash(dst, tbl);
bucket = >hash_buckets[hash_idx];
 
spin_lock(>hashwlock[hash_idx]);
@@ -687,7 +685,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
 
tbl = resize_dereference_mpp_paths(sdata);
 
-   hash_idx = mesh_table_hash(dst, sdata, tbl);
+   hash_idx = mesh_table_hash(dst, tbl);
bucket = >hash_buckets[hash_idx];
 
spin_lock(>hashwlock[hash_idx]);
@@ -905,7 +903,7 @@ static int table_path_del(struct mesh_table __rcu *rcu_tbl,
int err = 0;
 
tbl = resize_dereference_paths(sdata, rcu_tbl);
-   hash_idx = mesh_table_hash(addr, sdata, tbl);
+   hash_idx = mesh_table_hash(addr, tbl);
bucket = >hash_buckets[hash_idx];
 
spin_lock(>hashwlock[hash_idx]);
@@ -1107,7 +1105,7 @@ static int mesh_path_node_copy(struct hlist_node *p, 
struct mesh_table *newtbl)
node = hlist_entry(p, struct mpath_node, list);
mpath = node->mpath;
new_node->mpath = mpath;
-   hash_idx = mesh_table_hash(mpath->dst, mpath->sdata, newtbl);
+   hash_idx = mesh_table_hash(mpath->dst, newtbl);
hlist_add_head(_node->list,
>hash_buckets[hash_idx]);
return 0;
-- 
2.6.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] mesh: factor out common mesh path allocation code

2016-02-28 Thread Bob Copeland
Remove duplicate code to allocate and initialize a mesh
path or mesh proxy path.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 net/mac80211/mesh_pathtbl.c | 51 +
 1 file changed, 28 insertions(+), 23 deletions(-)

diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index fc3cc350df8c..4794240e8f94 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -501,6 +501,31 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
return sdata->u.mesh.num_gates;
 }
 
+static
+struct mesh_path *mesh_path_new(struct ieee80211_sub_if_data *sdata,
+   const u8 *dst, gfp_t gfp_flags)
+{
+   struct mesh_path *new_mpath;
+
+   new_mpath = kzalloc(sizeof(struct mesh_path), gfp_flags);
+   if (!new_mpath)
+   return NULL;
+
+   memcpy(new_mpath->dst, dst, ETH_ALEN);
+   eth_broadcast_addr(new_mpath->rann_snd_addr);
+   new_mpath->is_root = false;
+   new_mpath->sdata = sdata;
+   new_mpath->flags = 0;
+   skb_queue_head_init(_mpath->frame_queue);
+   new_mpath->timer.data = (unsigned long) new_mpath;
+   new_mpath->timer.function = mesh_path_timer;
+   new_mpath->exp_time = jiffies;
+   spin_lock_init(_mpath->state_lock);
+   init_timer(_mpath->timer);
+
+   return new_mpath;
+}
+
 /**
  * mesh_path_add - allocate and add a new path to the mesh path table
  * @dst: destination address of the path (ETH_ALEN length)
@@ -548,7 +573,7 @@ struct mesh_path *mesh_path_add(struct 
ieee80211_sub_if_data *sdata,
}
 
err = -ENOMEM;
-   new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC);
+   new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC);
if (!new_mpath)
goto err_path_alloc;
 
@@ -556,19 +581,7 @@ struct mesh_path *mesh_path_add(struct 
ieee80211_sub_if_data *sdata,
if (!new_node)
goto err_node_alloc;
 
-   memcpy(new_mpath->dst, dst, ETH_ALEN);
-   eth_broadcast_addr(new_mpath->rann_snd_addr);
-   new_mpath->is_root = false;
-   new_mpath->sdata = sdata;
-   new_mpath->flags = 0;
-   skb_queue_head_init(_mpath->frame_queue);
new_node->mpath = new_mpath;
-   new_mpath->timer.data = (unsigned long) new_mpath;
-   new_mpath->timer.function = mesh_path_timer;
-   new_mpath->exp_time = jiffies;
-   spin_lock_init(_mpath->state_lock);
-   init_timer(_mpath->timer);
-
hlist_add_head_rcu(_node->list, bucket);
if (atomic_inc_return(>entries) >=
MEAN_CHAIN_LEN * (tbl->hash_mask + 1))
@@ -664,7 +677,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
return -ENOTSUPP;
 
err = -ENOMEM;
-   new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC);
+   new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC);
if (!new_mpath)
goto err_path_alloc;
 
@@ -672,17 +685,9 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
if (!new_node)
goto err_node_alloc;
 
-   read_lock_bh(>u.mesh.pathtbl_resize_lock);
-   memcpy(new_mpath->dst, dst, ETH_ALEN);
memcpy(new_mpath->mpp, mpp, ETH_ALEN);
-   new_mpath->sdata = sdata;
-   new_mpath->flags = 0;
-   skb_queue_head_init(_mpath->frame_queue);
new_node->mpath = new_mpath;
-   init_timer(_mpath->timer);
-   new_mpath->exp_time = jiffies;
-   spin_lock_init(_mpath->state_lock);
-
+   read_lock_bh(>u.mesh.pathtbl_resize_lock);
tbl = resize_dereference_mpp_paths(sdata);
 
hash_idx = mesh_table_hash(dst, tbl);
-- 
2.6.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


Re: obtain commit list

2016-02-17 Thread Bob Copeland
On Wed, Feb 17, 2016 at 11:40:26AM +0100, Arend Van Spriel wrote:
> Hi Bob,
> 
> With the old wireless testing I used to provide a list of commits that
> were merged from wireless-testing into our internal repo. I am trying to
> determine the strategy to produce that list with the new
> wireless-testing using rebase stategy. Do you have a good suggestion for
> that?

Hi Arend,

So I suppose it depends somewhat on how you are using the tree, whether
you are merging w-t still or rebasing your own tree, but here's a couple
of barely tested ideas.  [Corrections welcome, I just tried a few things
that looked "close enough", but I suppose some cases where the downstream
trees rebase could muck up the result somewhat.]

Suppose I want to see which commits have been added between two
wireless-testing tags, I can do, for example:

git log wt-2016-02-17 ^wt-2016-02-15 -- net drivers/net/wireless | \
git shortlog

You'll see a handful of merge commits from me that don't end up in the
upstream, but otherwise should see a reasonable set of commits that got
merged, in this case a few iwlwifi patches.

Now suppose you're rebasing your internal tree on top of w-t/master
periodically, e.g., you have:

wt-oldbase -- A -- B -- C -- D

And rebase onto a new w-t tag to get (suppose A is merged upstream):

wt-newbase -- B' -- C' -- D'

wt-oldbase and wt-newbase actually have dated tags associated with them,
but perhaps it is too much work to look them up and you just use
"wireless-testing/master" in your rebase script.

Then you could do the same thing but first get the base of the tree:

wt_oldbase=$(git merge-base --fork-point wireless-testing/master D)
wt_newbase=$(git merge-base --fork-point wireless-testing/master D')
git log $wt_newbase ^$wt_oldbase

Hope that helps,
Bob

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 v3 0/3] mac80211: add cleanup path for MPP table entries

2016-02-03 Thread Bob Copeland
On Wed, Feb 03, 2016 at 01:58:35PM +0100, Henning Rogge wrote:
> Henning Rogge (3):
>   mac80211: Remove MPP table entries with MPath
>   mac80211: let unused MPP table entries timeout
>   mac80211: Unify mesh and mpp path removal function
> 
>  net/mac80211/mesh_pathtbl.c | 102 
> +++-
>  net/mac80211/rx.c   |   1 +
>  net/mac80211/tx.c   |   5 ++-
>  3 files changed, 97 insertions(+), 11 deletions(-)

Thanks for the revisions.  For what it's worth, series:

Acked-by: Bob Copeland <m...@bobcopeland.com>

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 v2] mac80211: mesh: drop constant field mean_chain_len

2016-01-30 Thread Bob Copeland
The mean_chain_len field in struct mesh_table is copied whenever a
new mesh table is allocated, but only ever has the value 2 and is
never otherwise updated, so just remove it and use the related
define instead.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---

v2: Upon rereading the commit log, noticed some lies.  Reworded.

v1: Sending this by itself as it's pretty trivial and doesn't conflict with
other outstanding patches.

 net/mac80211/mesh.h | 3 ---
 net/mac80211/mesh_pathtbl.c | 9 +++--
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 4a8019f..87c017a 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -137,8 +137,6 @@ struct mesh_path {
  * @copy_node: function to copy nodes of the table
  * @size_order: determines size of the table, there will be 2^size_order hash
  * buckets
- * @mean_chain_len: maximum average length for the hash buckets' list, if it is
- * reached, the table will grow
  * @known_gates: list of known mesh gates and their mpaths by the station. The
  * gate's mpath may or may not be resolved and active.
  *
@@ -154,7 +152,6 @@ struct mesh_table {
void (*free_node) (struct hlist_node *p, bool free_leafs);
int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
int size_order;
-   int mean_chain_len;
struct hlist_head *known_gates;
spinlock_t gates_lock;
 
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index dadf8dc..c95bdb8 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -160,11 +160,10 @@ static int mesh_table_grow(struct mesh_table *oldtbl,
int i;
 
if (atomic_read(>entries)
-   < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1))
+   < MEAN_CHAIN_LEN * (oldtbl->hash_mask + 1))
return -EAGAIN;
 
newtbl->free_node = oldtbl->free_node;
-   newtbl->mean_chain_len = oldtbl->mean_chain_len;
newtbl->copy_node = oldtbl->copy_node;
newtbl->known_gates = oldtbl->known_gates;
atomic_set(>entries, atomic_read(>entries));
@@ -585,7 +584,7 @@ struct mesh_path *mesh_path_add(struct 
ieee80211_sub_if_data *sdata,
 
hlist_add_head_rcu(_node->list, bucket);
if (atomic_inc_return(>entries) >=
-   tbl->mean_chain_len * (tbl->hash_mask + 1))
+   MEAN_CHAIN_LEN * (tbl->hash_mask + 1))
grow = 1;
 
mesh_paths_generation++;
@@ -714,7 +713,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
 
hlist_add_head_rcu(_node->list, bucket);
if (atomic_inc_return(>entries) >=
-   tbl->mean_chain_len * (tbl->hash_mask + 1))
+   MEAN_CHAIN_LEN * (tbl->hash_mask + 1))
grow = 1;
 
spin_unlock(>hashwlock[hash_idx]);
@@ -1076,7 +1075,6 @@ int mesh_pathtbl_init(void)
return -ENOMEM;
tbl_path->free_node = _path_node_free;
tbl_path->copy_node = _path_node_copy;
-   tbl_path->mean_chain_len = MEAN_CHAIN_LEN;
tbl_path->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC);
if (!tbl_path->known_gates) {
ret = -ENOMEM;
@@ -1092,7 +1090,6 @@ int mesh_pathtbl_init(void)
}
tbl_mpp->free_node = _path_node_free;
tbl_mpp->copy_node = _path_node_copy;
-   tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN;
tbl_mpp->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC);
if (!tbl_mpp->known_gates) {
ret = -ENOMEM;
-- 
2.1.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] mac80211: mesh: drop write-only var mean_chain_len

2016-01-30 Thread Bob Copeland
On Thu, Jan 28, 2016 at 09:24:12AM -0500, Bob Copeland wrote:
> mean_chain_len is copied into mesh path table
> structures, but only ever has the value 2 and
> is never read, so just remove it.

Disregard, I sent a v2 (under a different subject) where the commit log
actually makes sense.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 v2 3/3] mac80211: Unify mesh and mpp path removal function

2016-01-30 Thread Bob Copeland
On Fri, Jan 29, 2016 at 11:08:58AM +0100, Henning Rogge wrote:
> @@ -951,37 +974,14 @@ enddel:
>   */
>  static int mpp_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
>  {
> - struct mesh_table *tbl;
> - struct mesh_path *mpath;
> - struct mpath_node *node;
> - struct hlist_head *bucket;
> - int hash_idx;
> - int err = 0;
> -
> - /* flush relevant mpp entries first */
> - mpp_flush_by_proxy(sdata, addr);
> -

Is it intentional that mpp_path_del no longer calls mpp_flush_by_proxy()
while mesh_path_del does?

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 0/2] mac80211: add cleanup path for MPP table entries

2016-01-28 Thread Bob Copeland
On Tue, Jan 19, 2016 at 09:04:30AM +0100, Henning Rogge wrote:
> Currently MPP table entries are only removed from memory when their
> 802.11s mesh interface goes down. This can make the kernel to remember
> a growing list of proxied mac addresses which are not relevant or even
> reachable anymore.

Just so I know what to do with my series: do you plan to resend these
with comments addressed?  Or I could adopt the patches if you want.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] mac80211: mesh: drop write-only var mean_chain_len

2016-01-28 Thread Bob Copeland
mean_chain_len is copied into mesh path table
structures, but only ever has the value 2 and
is never read, so just remove it.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---

Sending this by itself as it's pretty trivial and doesn't conflict with
other outstanding patches.

 net/mac80211/mesh.h | 3 ---
 net/mac80211/mesh_pathtbl.c | 9 +++--
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 4a8019f..87c017a 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -137,8 +137,6 @@ struct mesh_path {
  * @copy_node: function to copy nodes of the table
  * @size_order: determines size of the table, there will be 2^size_order hash
  * buckets
- * @mean_chain_len: maximum average length for the hash buckets' list, if it is
- * reached, the table will grow
  * @known_gates: list of known mesh gates and their mpaths by the station. The
  * gate's mpath may or may not be resolved and active.
  *
@@ -154,7 +152,6 @@ struct mesh_table {
void (*free_node) (struct hlist_node *p, bool free_leafs);
int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
int size_order;
-   int mean_chain_len;
struct hlist_head *known_gates;
spinlock_t gates_lock;
 
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index dadf8dc..c95bdb8 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -160,11 +160,10 @@ static int mesh_table_grow(struct mesh_table *oldtbl,
int i;
 
if (atomic_read(>entries)
-   < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1))
+   < MEAN_CHAIN_LEN * (oldtbl->hash_mask + 1))
return -EAGAIN;
 
newtbl->free_node = oldtbl->free_node;
-   newtbl->mean_chain_len = oldtbl->mean_chain_len;
newtbl->copy_node = oldtbl->copy_node;
newtbl->known_gates = oldtbl->known_gates;
atomic_set(>entries, atomic_read(>entries));
@@ -585,7 +584,7 @@ struct mesh_path *mesh_path_add(struct 
ieee80211_sub_if_data *sdata,
 
hlist_add_head_rcu(_node->list, bucket);
if (atomic_inc_return(>entries) >=
-   tbl->mean_chain_len * (tbl->hash_mask + 1))
+   MEAN_CHAIN_LEN * (tbl->hash_mask + 1))
grow = 1;
 
mesh_paths_generation++;
@@ -714,7 +713,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
 
hlist_add_head_rcu(_node->list, bucket);
if (atomic_inc_return(>entries) >=
-   tbl->mean_chain_len * (tbl->hash_mask + 1))
+   MEAN_CHAIN_LEN * (tbl->hash_mask + 1))
grow = 1;
 
spin_unlock(>hashwlock[hash_idx]);
@@ -1076,7 +1075,6 @@ int mesh_pathtbl_init(void)
return -ENOMEM;
tbl_path->free_node = _path_node_free;
tbl_path->copy_node = _path_node_copy;
-   tbl_path->mean_chain_len = MEAN_CHAIN_LEN;
tbl_path->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC);
if (!tbl_path->known_gates) {
ret = -ENOMEM;
@@ -1092,7 +1090,6 @@ int mesh_pathtbl_init(void)
}
tbl_mpp->free_node = _path_node_free;
tbl_mpp->copy_node = _path_node_copy;
-   tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN;
tbl_mpp->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC);
if (!tbl_mpp->known_gates) {
ret = -ENOMEM;
-- 
2.1.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 0/2] mac80211: add cleanup path for MPP table entries

2016-01-28 Thread Bob Copeland
On Thu, Jan 28, 2016 at 04:07:52PM +0100, Henning Rogge wrote:
> > Just so I know what to do with my series: do you plan to resend these
> > with comments addressed?  Or I could adopt the patches if you want.
> 
> What would be easier for you?
> 
> I can easily resend a "v2" tomorrow, depends on how much work it would
> be for you to integrate them (or adapt them) to your patch set.

It's roughly the same amount of work, so whatever works for you is fine
by me.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 0/4] ath10k: rename mesh and add abstraction layer

2016-01-27 Thread Bob Copeland
On Wed, Jan 27, 2016 at 10:55:53AM -0800, Peter Oh wrote:
> Split Mesh service to 11s Mesh and non-11s Mesh according to
> firmware service bit to help users distinguish 11s Mesh from
> non 11s Mesh.
> And add abstraction layer for vdev subtype to solve subtype mismatch
> and to give flexible compatibility among different firmware revisions.

Out of curiosity, which non-11s mesh, if you can share?

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 1/2] mac80211: Remove connected MPP table entries with MPath

2016-01-26 Thread Bob Copeland
On Tue, Jan 26, 2016 at 12:41:25PM +0100, Johannes Berg wrote:
> > +   mpp = node->mpath;
> > +   if (ether_addr_equal(mpp->mpp, proxy)) {
> > +   spin_lock(>hashwlock[i]);
> > +   __mesh_path_del(tbl, node);
> > +   spin_unlock(>hashwlock[i]);
> 
> It also doesn't seem like for_each_mesh_entry() can deal with "node"
> getting deleted from underneath it? It accesses it through
> hlist_next_rcu() after the deletion, so you have a use-after-free here
> afaict.

But __mesh_path_del() doesn't free it immediately: it does:

hlist_del_rcu(>list);
call_rcu(>rcu, mesh_path_node_reclaim);

...so this should be ok if in an rcu read-side critical section, right?

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 1/2] mac80211: Remove connected MPP table entries with MPath

2016-01-26 Thread Bob Copeland
On Tue, Jan 26, 2016 at 09:53:33PM +0100, Johannes Berg wrote:
> Oh. Interesting. Yeah, I guess that should be OK then.
> 
> It's not *nice*, since that's pretty much unexpected, and you then do
> need the rcu_read_lock() ... hmm.

Yeah, I puzzled over that a bit last week as well -- I rewrote it like
this in the series I haven't posted yet:

void mesh_path_flush_by_nexthop(struct sta_info *sta)
{
[...]
rhashtable_walk_start();
while ((mpath = rhashtable_walk_next())) {
if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN)
continue;
if (IS_ERR(mpath))
break;

if (rcu_access_pointer(mpath->next_hop) == sta)
__mesh_path_del(tbl, mpath);
}
rhashtable_walk_stop();
[...]
}

...this still relies on the rcu read lock inside _walk_start and _walk_stop,
though.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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 1/2] mac80211: Remove connected MPP table entries with MPath

2016-01-26 Thread Bob Copeland
On Tue, Jan 26, 2016 at 10:32:23PM +0100, Johannes Berg wrote:
> On Tue, 2016-01-26 at 22:31 +0100, Johannes Berg wrote:
> > On Tue, 2016-01-26 at 16:22 -0500, Bob Copeland wrote:
> > >  
> > > void mesh_path_flush_by_nexthop(struct sta_info *sta)
> > > {
> > > [...]
> > >   rhashtable_walk_start();
> > 
> > It seems you need to check the return value here?
> > 
> 
> Actually, maybe not. Not sure I understand the return to beginning
> though.

I'll RFC that patch, it doesn't work right now anyway as
rhashtable_walk_init() does a GFP_KERNEL allocation and we want to call
it from the RX path (maybe not a good idea, but that's what the code
currently does).

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/2] mac80211: let unused MPP table entries timeout

2016-01-26 Thread Bob Copeland
On Tue, Jan 19, 2016 at 09:04:32AM +0100, Henning Rogge wrote:
>   err = -ENXIO;
> -enddel:
> +enddelpath:

Concur about it being better to leave this label alone, also the diff looks
weird because it continues:

> + mesh_paths_generation++;
> + spin_unlock(>hashwlock[hash_idx]);
> + read_unlock_bh(_resize_lock);
> + return err;
> +}

[...]

> + err = -ENXIO;
> +enddelmpp:
>   mesh_paths_generation++;
>   spin_unlock(>hashwlock[hash_idx]);
>   read_unlock_bh(_resize_lock);

At first I wondered why the last half of the function was changed, but then
I saw that.  Shouldn't the above be "mpp_paths_generation++;"?

In general I'd like to merge these two into one function; the only thing
different is the initial table pointer that gets dereferenced and the
generation counter (and now the labels).  So something like this should
be doable:

static int mesh_table_delete(struct ieee80211_sub_if_data *sdata,
 struct mesh_table *tbl,
 const u8 *addr)
{
/* basically what mesh_path_del is today */
}

int mesh_path_del(...)
{
tbl = resize_dereference_mesh_paths();
ret = mesh_table_delete(sdata, tbl, addr);
mesh_paths_generation++;
return ret;
}

int mpp_path_del(...)
{
tbl = resize_dereference_mpp_paths();
ret = mesh_table_delete(sdata, tbl, addr);
    mpp_paths_generation++;
return ret;
}

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/2] mac80211: let unused MPP table entries timeout

2016-01-23 Thread Bob Copeland
On Sat, Jan 23, 2016 at 10:39:04AM +0100, Henning Rogge wrote:
> > FYI I have a patch set I'm testing which rewrites a big chunk of
> > the path table stuff.
> 
> Does it include some cleanup paths for the MPP table? At the moment
> the "missing cleanup" still allows remote users to make the Linux
> kernel to allocate as much memory as it wants... with no way to free
> it except for shutting down the interface.

No, it needs these patches too.  I did harmonize them a little bit,
so that e.g. the expiry check will be done during lookup, but I didn't
add an equivalent to flush-by-proxy.

One issue it does address is that the path table can eventually shrink
by virtue of the rhashtable, whereas now the bucket size is
ever-growing.

> > Let me know if you want me to base on top.
> 
> I would like them to go in first... my experience of the kernel code
> (outside some parts of the wifi stack) is not that good, so I don't
> know how long I would need to adapt the patches to your new data
> structures.

Ok, sounds good, I'll just rebase on top of yours.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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/2] mac80211: let unused MPP table entries timeout

2016-01-22 Thread Bob Copeland
On Tue, Jan 19, 2016 at 09:04:32AM +0100, Henning Rogge wrote:
> Remember the last time when a mpp table entry is used for
> rx or tx and remove them after MESH_PATH_EXPIRE time.

FYI I have a patch set I'm testing which rewrites a big chunk of
the path table stuff.

As I haven't posted it yet, I guess it doesn't matter if this
goes in first or not, I can adjust -- but it will conflict as-is.
I was hoping to post it early next week after a few fixes.

Let me know if you want me to base on top.

Shortlog looks like:

Bob Copeland (6):
  mac80211: mesh: move path tables into ieee82011_if_mesh
  mac80211: mesh: don't hash subif data in mesh path tables
  mac80211: mesh: factor out common mesh path allocation code
  mac80211: mesh: embed known gates list in struct mesh_path
  mac80211: mesh: convert path table to rhashtable
  mac80211: mesh: get rid of write-only field mean_chain_len

-- 
Bob Copeland %% http://bobcopeland.com/
--
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] Revert "mac80211_hwsim: support any address in userspace"

2015-12-19 Thread Bob Copeland
This reverts commit cd37a90b2a417e5882414e19954eeed174aa4d29.

Different userspace programs interpreted HWSIM_ATTR_ADDR_TRANSMITTER
and HWSIM_ATTR_ADDR_RECEIVER differently: some expected it to
be an unchanging hardware address that is tied to the radio despite
which address is configured on the interface, while others expected
to be a copy of the address in the frame (the configured address).
The intent of the original authors is unclear.

The latter interpretation doesn't really work properly with multiple
vifs and broadcast frames.  Also, as the TA is already in the
frame, userspace programs can actually support configured addresses
in the former interpretation by mapping between them and the supplied
HWSIM_ATTR_ADDR_TRANSMITTER.

So, in the interest of API stability, revert to the previous mode
of operation and going forward use the former interpretation.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
I made minimal changes to wmediumd and it works fine so far with the
revert.  I've a little more to do there, but it is good enough that
hostapd test case passes with the new wmediumd binary, with or without
this patch.

 drivers/net/wireless/mac80211_hwsim.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index c32889a1e39c..a28414c50edf 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -991,7 +991,8 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw 
*hw,
goto nla_put_failure;
}
 
-   if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, ETH_ALEN, hdr->addr2))
+   if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
+   ETH_ALEN, data->addresses[1].addr))
goto nla_put_failure;
 
/* We get the skb->data */
@@ -2736,7 +2737,7 @@ static struct mac80211_hwsim_data 
*get_hwsim_data_ref_from_addr(const u8 *addr)
 
spin_lock_bh(_radio_lock);
list_for_each_entry(data, _radios, list) {
-   if (mac80211_hwsim_addr_match(data, addr)) {
+   if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) {
_found = true;
break;
}
-- 
2.6.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


Re: question on "mac80211_hwsim: support any address in userspace"

2015-12-17 Thread Bob Copeland
On Wed, Dec 16, 2015 at 02:14:18PM -0800, Ben Greear wrote:
> On 12/16/2015 09:30 AM, Adam R. Welle wrote:
> >
> >>Well, it was always rather awkward since it was the *second* address :)
> >
> >Could somebody provide background information on why the decision was
> >made to use a second address for the netlink frames instead of the same
> >address as was used for the non-netlink frames?
> 
> I would be fine with always using the first address instead of the second,
> in case that helps someone.

It doesn't really, that would break old wmediumd.

> We could also set the address at creation time easily enough.  Then it
> could still be unique across many machines if you managed it.

We already have a way to change mac addresses; adding a new API to change
the default address seems pointless to me.

-- 
Bob Copeland %% http://bobcopeland.com/
--
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


  1   2   >