[PATCH v3] mac80211: mesh: set tx_info->hw_queue to the correct queue upon packet forwarding

2016-08-08 Thread Yaniv Machani
From: Meirav Kama <meir...@ti.com>

MP received data frames from another MP. Frames are forwarded
from Rx to Tx to be transmitted to a third MP.
Upon cloning the skb, the tx_info was zeroed, and the
hw_queue wasn't set correctly, causing frames to be
inserted to queue 0 (VOICE). If re-queue occurred for some
reason, frame will be inserted to correct queue 2 (BE).
In this case frames are now dequeued from 2 different queues and
sent out of order.

Signed-off-by: Meirav Kama <meir...@ti.com>
Signed-off-by: Yaniv Machani <yani...@ti.com>
---
v3 - update the headline

 net/mac80211/rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9a1eb70..88dc744 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2392,6 +2392,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
info->control.vif = >sdata->vif;
info->control.jiffies = jiffies;
+   info->hw_queue = q;
if (is_multicast_ether_addr(fwd_hdr->addr1)) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
-- 
2.9.0



[PATCH v3 3/3] mac80211: mesh: fixed HT ies in beacon template

2016-07-13 Thread Yaniv Machani
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.

Signed-off-by: Meirav Kama <meir...@ti.com>
Signed-off-by: Yaniv Machani <yani...@ti.com>
---
V3 - Fixes redundant spaces,empty lines and added FALLTHROUGH note.

 net/mac80211/mesh.c | 33 -
 net/mac80211/util.c |  3 ---
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9214bc1..6a67049 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -422,6 +422,7 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
struct ieee80211_supported_band *sband;
u8 *pos;
+   u16 cap;
 
sband = local->hw.wiphy->bands[band];
if (!sband->ht_cap.ht_supported ||
@@ -430,11 +431,41 @@ 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;
+
+   /* 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;
+   }
+
+   /* set SM PS mode properly */
+   cap &= ~IEEE80211_HT_CAP_SM_PS;
+   switch (sdata->smps_mode) {
+   case IEEE80211_SMPS_AUTOMATIC:
+   case IEEE80211_SMPS_NUM_MODES:
+   WARN_ON(1);
+   /* FALLTHROUGH */
+   case IEEE80211_SMPS_OFF:
+   cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   case IEEE80211_SMPS_STATIC:
+   cap |= WLAN_HT_CAP_SM_PS_STATIC <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   case IEEE80211_SMPS_DYNAMIC:
+   cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   }
+
if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
return -ENOMEM;
 
pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_cap));
-   ieee80211_ie_build_ht_cap(pos, >ht_cap, sband->ht_cap.cap);
+   ieee80211_ie_build_ht_cap(pos, >ht_cap, cap);
 
return 0;
 }
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);
 
return pos + sizeof(struct ieee80211_ht_operation);
 }
-- 
2.9.0



[PATCH v2] mac80211: rx: frames received out of order

2016-07-13 Thread Yaniv Machani
From: Meirav Kama <meir...@ti.com>

Upon forwarding frames from Rx to Tx in mesh, driver clones the skb.
It zeros the tx_info and doesn't set hw_queue correctly. It then enqueues
the frame in queue 0 (VOICE) instead of the correct queue.
Upon re-queue of this frame, driver inserts it to the correct queue (e.g. BE).
After that, driver dequeue frames from 2 different queues and sends them out of 
order.
To fix this, driver will set the tx_info->hw_queue to the correct queue when 
cloning the skb.

Signed-off-by: Meirav Kama <meir...@ti.com>
Signed-off-by: Yaniv Machani <yani...@ti.com>
---
V2 - Revised comment

 net/mac80211/rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9a1eb70..88dc744 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2392,6 +2392,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
info->control.vif = >sdata->vif;
info->control.jiffies = jiffies;
+   info->hw_queue = q;
if (is_multicast_ether_addr(fwd_hdr->addr1)) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
-- 
2.9.0



[PATCH v2 1/3] mac80211: mesh: flush stations before beacons are stopped

2016-07-13 Thread Yaniv Machani
From: Maital Hahn <mait...@ti.com>

Some drivers (e.g. wl18xx) expect that the last stage in the
de-initialization process will be stopping the beacons, similar to AP flow.
Update ieee80211_stop_mesh() flow accordingly.
As peers can be removed dynamically, this would not impact other drivers.

Tested also on Ralink RT3572 chipset.

Signed-off-by: Maital Hahn <mait...@ti.com>
Signed-off-by: Yaniv Machani <yani...@ti.com>
---
V2- updated comment, patch was tested with RT3572

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

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 21b1fdf..9214bc1 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -896,20 +896,22 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data 
*sdata)
 
netif_carrier_off(sdata->dev);
 
+   /* flush STAs and mpaths on this iface */
+   sta_info_flush(sdata);
+   mesh_path_flush_by_iface(sdata);
+
/* stop the beacon */
ifmsh->mesh_id_len = 0;
sdata->vif.bss_conf.enable_beacon = false;
clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, >state);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+
+   /* remove beacon */
bcn = rcu_dereference_protected(ifmsh->beacon,
lockdep_is_held(>wdev.mtx));
RCU_INIT_POINTER(ifmsh->beacon, NULL);
kfree_rcu(bcn, rcu_head);
 
-   /* flush STAs and mpaths on this iface */
-   sta_info_flush(sdata);
-   mesh_path_flush_by_iface(sdata);
-
/* free all potentially still buffered group-addressed frames */
local->total_ps_buffered -= skb_queue_len(>ps.bc_buf);
skb_queue_purge(>ps.bc_buf);
-- 
2.9.0



[PATCH v2 0/3] Mesh mpm fixes and enhancements

2016-07-13 Thread Yaniv Machani
This patch set is addressing some issues found in the current 802.11s 
implementation, specifically when using hostap mpm. 
It's aligning the beacon format and handling some corner cases.

V2 - Updated patches following review comments.
   - Remove unneccary patches (already upsteamed)

Maital Hahn (1):
  mac80211: mesh: flush stations before beacons are stopped

Yaniv Machani (2):
  mac80211: mesh: improve path resolving time
  mac80211: mesh: fixed HT ies in beacon template

 net/mac80211/mesh.c  | 43 ++-
 net/mac80211/mesh_hwmp.c | 42 +-
 net/mac80211/util.c  |  3 ---
 3 files changed, 63 insertions(+), 25 deletions(-)

-- 
2.9.0



[PATCH v2 2/3] mac80211: mesh: improve path resolving time

2016-07-13 Thread Yaniv Machani
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.

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.

Signed-off-by: Maital Hahn <mait...@ti.com>
Signed-off-by: Yaniv Machani <yani...@ti.com>
---
v2 - Updated comment to explain the scenario better.
   - Removed unnccesary changes that was alreay upstreamed.
   
 net/mac80211/mesh_hwmp.c | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 8f9c3bd..9783d49 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -19,7 +19,7 @@
 
 #define MAX_PREQ_QUEUE_LEN 64
 
-static void mesh_queue_preq(struct mesh_path *, u8);
+static void mesh_queue_preq(struct mesh_path *, u8, bool);
 
 static inline u32 u32_field_get(const u8 *preq_elem, int offset, bool ae)
 {
@@ -830,7 +830,8 @@ static void hwmp_rann_frame_process(struct 
ieee80211_sub_if_data *sdata,
mhwmp_dbg(sdata,
  "time to refresh root mpath %pM\n",
  orig_addr);
-   mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
+   mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH,
+   false);
mpath->last_preq_to_root = jiffies;
}
 
@@ -925,7 +926,7 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data 
*sdata,
  * Locking: the function must be called from within a rcu read lock block.
  *
  */
-static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
+static void mesh_queue_preq(struct mesh_path *mpath, u8 flags, bool immediate)
 {
struct ieee80211_sub_if_data *sdata = mpath->sdata;
struct ieee80211_if_mesh *ifmsh = >u.mesh;
@@ -964,18 +965,24 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 
flags)
++ifmsh->preq_queue_len;
spin_unlock_bh(>mesh_preq_queue_lock);
 
-   if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
+   if (immediate) {
ieee80211_queue_work(>local->hw, >work);
+   } else {
+   if (time_after(jiffies,
+  ifmsh->last_preq + min_preq_int_jiff(sdata))) {
+   ieee80211_queue_work(>local->hw, >work);
 
-   else if (time_before(jiffies, ifmsh->last_preq)) {
-   /* avoid long wait if did not send preqs for a long time
-* and jiffies wrapped around
-*/
-   ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
-   ieee80211_queue_work(>local->hw, >work);
-   } else
-   mod_timer(>mesh_path_timer, ifmsh->last_preq +
-   min_preq_int_jiff(sdata));
+   } else if (time_before(jiffies, ifmsh->last_preq)) {
+   /* avoid long wait if did not send preqs for a long time
+* and jiffies wrapped around
+*/
+   ifmsh->last_preq = jiffies -
+  min_preq_int_jiff(sdata) - 1;
+   ieee80211_queue_work(>local->hw, >work);
+   } else
+   mod_timer(>mesh_path_timer, ifmsh->last_preq +
+ min_preq_int_jiff(sdata));
+   }
 }
 
 /**
@@ -1110,7 +1117,7 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data 
*sdata,
}
 
if (!(mpath->flags & MESH_PATH_RESOLVING))
-   mesh_queue_preq(mpath, PREQ_Q_F_START);
+   mesh_queue_preq(mpath, PREQ_Q_F_START, true);
 
if (skb_queue_len(>frame_queue) >= MESH_FRAME_QUEUE_LEN)
skb_to_free = skb_dequeue(>frame_queue);
@@ -1157,8 +1164,9 @@ int mesh_nexthop_lookup(struct ieee80211_sub_if_data 
*sdata,
   
msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
ether_addr_equal(sdata->vif.addr, hdr->addr4) &&
!(mpath->flags & MESH_PATH_RESOLVING) &&
-   !(mpath->flags & MESH_PATH_FIXED))
-  

[PATCH] mac80211: rx: frames received out of order

2016-07-13 Thread Yaniv Machani
From: Meirav Kama <meir...@ti.com>

MP received data frames from another MP. Frames are forwarded
from Rx to Tx to be transmitted to a third MP.
Upon cloning the skb, the tx_info was zeroed, and the
hw_queue wasn't set correctly, causing frames to be
inserted to queue 0 (VOICE). If re-queue occurred for some
reason, frame will be inserted to correct queue 2 (BE).
In this case frames are now dequeued from 2 different queues and
sent out of order.

Signed-off-by: Meirav Kama <meir...@ti.com>
Signed-off-by: Yaniv Machani <yani...@ti.com>
---
 net/mac80211/rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9a1eb70..88dc744 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2392,6 +2392,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
info->control.vif = >sdata->vif;
info->control.jiffies = jiffies;
+   info->hw_queue = q;
if (is_multicast_ether_addr(fwd_hdr->addr1)) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
-- 
2.9.0



[PATCH 3/3] mac80211: mesh: fixed HT ies in beacon template

2016-07-13 Thread Yaniv Machani
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.

Signed-off-by: Meirav Kama <meir...@ti.com>
Signed-off-by: Yaniv Machani <yani...@ti.com>
---
V3 - Updated comment
   - Removed CFG changes, as they are not correct.
   
 net/mac80211/mesh.c | 33 -
 net/mac80211/util.c |  3 ---
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9214bc1..275131d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -422,6 +422,8 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
struct ieee80211_supported_band *sband;
u8 *pos;
+   u16 cap;
+
 
sband = local->hw.wiphy->bands[band];
if (!sband->ht_cap.ht_supported ||
@@ -430,11 +432,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;
+
+/* 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;
+   }
+
+   /* set SM PS mode properly */
+   cap &= ~IEEE80211_HT_CAP_SM_PS;
+   switch (sdata->smps_mode) {
+   case IEEE80211_SMPS_AUTOMATIC:
+   case IEEE80211_SMPS_NUM_MODES:
+   WARN_ON(1);
+   case IEEE80211_SMPS_OFF:
+   cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   case IEEE80211_SMPS_STATIC:
+   cap |= WLAN_HT_CAP_SM_PS_STATIC <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   case IEEE80211_SMPS_DYNAMIC:
+   cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   }
+
if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
return -ENOMEM;
 
pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_cap));
-   ieee80211_ie_build_ht_cap(pos, >ht_cap, sband->ht_cap.cap);
+   ieee80211_ie_build_ht_cap(pos, >ht_cap, cap);
 
return 0;
 }
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);
 
return pos + sizeof(struct ieee80211_ht_operation);
 }
-- 
2.9.0



[PATCH] mac80211: rx: frames received out of order

2016-06-28 Thread Yaniv Machani
From: Meirav Kama <meir...@ti.com>

MP received data frames from another MP. Frames are forwarded
from Rx to Tx to be transmitted to a third MP.
Upon cloning the skb, the tx_info was zeroed, and the
hw_queue wasn't set correctly, causing frames to be
inserted to queue 0 (VOICE). If re-queue occurred for some
reason, frame will be inserted to correct queue 2 (BE).
In this case frames are now dequeued from 2 different queues and
sent out of order.

Signed-off-by: Meirav Kama <meir...@ti.com>
Acked-by: Yaniv Machani <yani...@ti.com>
---
 net/mac80211/rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9a1eb70..88dc744 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2392,6 +2392,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
info->control.vif = >sdata->vif;
info->control.jiffies = jiffies;
+   info->hw_queue = q;
if (is_multicast_ether_addr(fwd_hdr->addr1)) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
-- 
2.9.0



[PATCH] mac80211: util: mesh is not connected properly after recovery

2016-06-28 Thread Yaniv Machani
From: Maital Hahn <mait...@ti.com>

In the reconfigure process for mesh interface, moved the reconfiguration
of the mesh peers to be done only after restarting the beacons,
the same as it is done for AP.

Signed-off-by: Maital Hahn <mait...@ti.com>
Acked-by: Yaniv Machani <yani...@ti.com>
---
 net/mac80211/util.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 5375a82..2431684 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1910,6 +1910,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
ieee80211_reconfig_stations(sdata);
/* fall through */
case NL80211_IFTYPE_AP: /* AP stations are handled later */
+   case NL80211_IFTYPE_MESH_POINT: /* MP peers are handled later */
for (i = 0; i < IEEE80211_NUM_ACS; i++)
drv_conf_tx(local, sdata, i,
>tx_conf[i]);
@@ -2013,7 +2014,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
if (!sta->uploaded)
continue;
 
-   if (sta->sdata->vif.type != NL80211_IFTYPE_AP)
+   if ((sta->sdata->vif.type != NL80211_IFTYPE_AP) &&
+   (sta->sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
continue;
 
for (state = IEEE80211_STA_NOTEXIST;
-- 
2.9.0



[PATCH 1/4] mac80211: mesh: flush stations before beacons are stopped

2016-06-28 Thread Yaniv Machani
From: Maital Hahn <mait...@ti.com>

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.

Signed-off-by: Maital Hahn <mait...@ti.com>
Acked-by: Yaniv Machani <yani...@ti.com>
---
 net/mac80211/mesh.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 21b1fdf..9214bc1 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -896,20 +896,22 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data 
*sdata)
 
netif_carrier_off(sdata->dev);
 
+   /* flush STAs and mpaths on this iface */
+   sta_info_flush(sdata);
+   mesh_path_flush_by_iface(sdata);
+
/* stop the beacon */
ifmsh->mesh_id_len = 0;
sdata->vif.bss_conf.enable_beacon = false;
clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, >state);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+
+   /* remove beacon */
bcn = rcu_dereference_protected(ifmsh->beacon,
lockdep_is_held(>wdev.mtx));
RCU_INIT_POINTER(ifmsh->beacon, NULL);
kfree_rcu(bcn, rcu_head);
 
-   /* flush STAs and mpaths on this iface */
-   sta_info_flush(sdata);
-   mesh_path_flush_by_iface(sdata);
-
/* free all potentially still buffered group-addressed frames */
local->total_ps_buffered -= skb_queue_len(>ps.bc_buf);
skb_queue_purge(>ps.bc_buf);
-- 
2.9.0



[PATCH 4/4] mac80211: sta_info: max_peers reached falsely

2016-06-28 Thread Yaniv Machani
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.

Signed-off-by: Meirav Kama <meir...@ti.com>
Acked-by: Yaniv Machani <yani...@ti.com>
---
 net/mac80211/sta_info.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 76b737d..1ce6320 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1009,11 +1009,25 @@ int sta_info_destroy_addr_bss(struct 
ieee80211_sub_if_data *sdata,
 {
struct sta_info *sta;
int ret;
+#ifdef CONFIG_MAC80211_MESH
+   bool dec_links = false;
+#endif
 
mutex_lock(>local->sta_mtx);
sta = sta_info_get_bss(sdata, addr);
+#ifdef CONFIG_MAC80211_MESH
+   if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT &&
+   sta->mesh->plink_state == NL80211_PLINK_ESTAB)
+   dec_links = true;
+#endif
ret = __sta_info_destroy(sta);
mutex_unlock(>local->sta_mtx);
+#ifdef CONFIG_MAC80211_MESH
+   if (dec_links) {
+   mesh_plink_dec_estab_count(sdata);
+   ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON);
+   }
+#endif
 
return ret;
 }
-- 
2.9.0



[PATCH 3/4] mac80211: mesh: fixed HT ies in beacon template

2016-06-28 Thread Yaniv Machani
From: Meirav Kama <meir...@ti.com>

There are several values in HT info elements of mesh beacon (built by the
mac80211) that are incorrect.
To fix them:
1. mac80211 will check configuration from cfg and will build accordingly.
2. changes made in mesh default values.

Signed-off-by: Meirav Kama <meir...@ti.com>
Acked-by: Yaniv Machani <yani...@ti.com>
---
 net/mac80211/mesh.c | 33 -
 net/mac80211/util.c |  3 ---
 net/wireless/mesh.c |  2 +-
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 1f5be54..1b63b11 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -423,6 +423,8 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
struct ieee80211_supported_band *sband;
u8 *pos;
+   u16 cap;
+
 
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;
+
+/* 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;
+   }
+
+   /* set SM PS mode properly */
+   cap &= ~IEEE80211_HT_CAP_SM_PS;
+   switch (sdata->smps_mode) {
+   case IEEE80211_SMPS_AUTOMATIC:
+   case IEEE80211_SMPS_NUM_MODES:
+   WARN_ON(1);
+   case IEEE80211_SMPS_OFF:
+   cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   case IEEE80211_SMPS_STATIC:
+   cap |= WLAN_HT_CAP_SM_PS_STATIC <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   case IEEE80211_SMPS_DYNAMIC:
+   cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
+   IEEE80211_HT_CAP_SM_PS_SHIFT;
+   break;
+   }
+
if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
return -ENOMEM;
 
pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_cap));
-   ieee80211_ie_build_ht_cap(pos, >ht_cap, sband->ht_cap.cap);
+   ieee80211_ie_build_ht_cap(pos, >ht_cap, cap);
 
return 0;
 }
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);
 
return pos + sizeof(struct ieee80211_ht_operation);
 }
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index fa2066b..ac19a19 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -70,7 +70,7 @@ const struct mesh_config default_mesh_config = {
.dot11MeshGateAnnouncementProtocol = false,
.dot11MeshForwarding = true,
.rssi_threshold = MESH_RSSI_THRESHOLD,
-   .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED,
+   .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE,
.dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
.dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
.dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
-- 
2.9.0



[PATCH 2/4] mac80211/cfg: mesh: fix healing time when a mesh peer is disconnecting

2016-06-28 Thread Yaniv Machani
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.

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

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);
 
ieee80211_mps_sta_status_update(sta);
changed |= ieee80211_mps_set_sta_local_pm(sta,
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9214bc1..1f5be54 100644
--- a/net/mac80211/mesh.c
+++ 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);
 
/* make sure no readers can access nexthop sta from here on */
mesh_path_flush_by_nexthop(sta);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 8f9c3bd..9783d49 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -19,7 +19,7 @@
 
 #define MAX_PREQ_QUEUE_LEN 64
 
-static void mesh_queue_preq(struct mesh_path *, u8);
+static void mesh_queue_preq(struct mesh_path *, u8, bool);
 
 static inline u32 u32_field_get(const u8 *preq_elem, int offset, bool ae)
 {
@@ -830,7 +830,8 @@ static void hwmp_rann_frame_process(struct 
ieee80211_sub_if_data *sdata,
mhwmp_dbg(sdata,
  "time to refresh root mpath %pM\n",
  orig_addr);
-   mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
+   mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH,
+   false);
mpath->last_preq_to_root = jiffies;
}
 
@@ -925,7 +926,7 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data 
*sdata,
  * Locking: the function must be called from within a rcu read lock block.
  *
  */
-static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
+static void mesh_queue_preq(struct mesh_path *mpath, u8 flags, bool immediate)
 {
struct ieee80211_sub_if_data *sdata = mpath->sdata;
struct ieee80211_if_mesh *ifmsh = >u.mesh;
@@ -964,18 +965,24 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 
flags)
++ifmsh->preq_queue_len;
spin_unlock_bh(>mesh_preq_queue_lock);
 
-   if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
+   if (immediate) {
ieee80211_queue_work(>local->hw, >work);
+   } else {
+   if (time_after(jiffies,
+  ifmsh->last_preq + min_preq_int_jiff(sdata))) {
+   ieee80211_queue_work(>local->hw, >work);
 
-   else if (time_before(jiffies, ifmsh->last_preq)) {
-   /* avoid long wait if did not send preqs for a long time
-* and jiffies wrapped around
-*/
-   ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
-   ieee80211_queue_work(>local->hw, >work);
-   } else
-   mod_timer(>mesh_path_timer, ifmsh->last_preq +
-   min_preq_int_jiff(sdata));
+   } else if (time_before(jiffies, ifmsh->last_preq)) {
+   /* avoid long wait if did not send preqs for a long time
+* and jiffies wrapped around
+*/
+   ifmsh->last_preq = jiffies -
+  min_preq_int_jiff(sdata) - 1;
+   ieee80211_queue_work(>local->hw, >work);
+   } else
+   mod_timer(>mesh_path_timer, ifmsh->last_preq +
+ min_preq_int_jiff(sdata));
+   }
 }
 
 /**
@@ -1110,7 +1117,7 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data 
*sdata,
}
 
if (!(mpath->flags & MESH_PATH_RESOLVING))
-   me

[PATCH 0/4] Mesh mpm fixes and enhancements

2016-06-28 Thread Yaniv Machani
This patch set is addressing some issues found in the current 802.11s 
implementation,
specifically when using hostap mpm. 
It's aligning the beacon format and handling some corner cases.

Maital Hahn (2):
  mac80211: mesh: flush stations before beacons are stopped
  mac80211/cfg: mesh: fix healing time when a mesh peer is disconnecting

Meirav Kama (2):
  mac80211: mesh: fixed HT ies in beacon template
  mac80211: sta_info: max_peers reached falsely

 net/mac80211/cfg.c   |  1 +
 net/mac80211/mesh.c  | 46 --
 net/mac80211/mesh_hwmp.c | 42 +-
 net/mac80211/sta_info.c  | 14 ++
 net/mac80211/util.c  |  3 ---
 net/wireless/mesh.c  |  2 +-
 6 files changed, 81 insertions(+), 27 deletions(-)

-- 
2.9.0



[PATCH] wlcore/wl18xx: mesh: added initial mesh support for wl8

2016-06-28 Thread Yaniv Machani
From: Maital Hahn <mait...@ti.com>

1. Added support for interface and role of mesh type.
2. Enabled enable/start of mesh-point role,
   and opening and closing a connection with a mesh peer.
3. Added multirole combination of mesh and ap
   under the same limits of dual ap mode.
4. Add support for 'sta_rc_update' opcode for mesh IF.
   The 'sta_rc_update' opcode is being used in mesh_plink.c.
Add support in wlcore to handle this opcode correctly for mesh
(as opposed to current implementation that handles STA only).
5. Bumped the firmware version to support new Mesh functionality

Signed-off-by: Maital Hahn <mait...@ti.com>
Signed-off-by: Yaniv Machani <yani...@ti.com>
---
 drivers/net/wireless/ti/wl18xx/main.c | 15 ---
 drivers/net/wireless/ti/wl18xx/wl18xx.h   |  2 +-
 drivers/net/wireless/ti/wlcore/acx.h  |  1 +
 drivers/net/wireless/ti/wlcore/boot.c |  2 +-
 drivers/net/wireless/ti/wlcore/cmd.c  | 13 -
 drivers/net/wireless/ti/wlcore/main.c | 32 +++
 drivers/net/wireless/ti/wlcore/wlcore_i.h |  1 +
 7 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ti/wl18xx/main.c 
b/drivers/net/wireless/ti/wl18xx/main.c
index ae47c79..4811b74 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -1821,9 +1821,12 @@ static const struct ieee80211_iface_limit 
wl18xx_iface_limits[] = {
},
{
.max = 1,
-   .types = BIT(NL80211_IFTYPE_AP) |
-BIT(NL80211_IFTYPE_P2P_GO) |
-BIT(NL80211_IFTYPE_P2P_CLIENT),
+   .types =   BIT(NL80211_IFTYPE_AP)
+| BIT(NL80211_IFTYPE_P2P_GO)
+| BIT(NL80211_IFTYPE_P2P_CLIENT)
+#ifdef CONFIG_MAC80211_MESH
+| BIT(NL80211_IFTYPE_MESH_POINT)
+#endif
},
{
.max = 1,
@@ -1836,6 +1839,12 @@ static const struct ieee80211_iface_limit 
wl18xx_iface_ap_limits[] = {
.max = 2,
.types = BIT(NL80211_IFTYPE_AP),
},
+#ifdef CONFIG_MAC80211_MESH
+   {
+   .max = 1,
+   .types = BIT(NL80211_IFTYPE_MESH_POINT),
+   },
+#endif
{
.max = 1,
.types = BIT(NL80211_IFTYPE_P2P_DEVICE),
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h 
b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index 71e9e38..d65cc6d 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -29,7 +29,7 @@
 #define WL18XX_IFTYPE_VER  9
 #define WL18XX_MAJOR_VER   WLCORE_FW_VER_IGNORE
 #define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE
-#define WL18XX_MINOR_VER   11
+#define WL18XX_MINOR_VER   58
 
 #define WL18XX_CMD_MAX_SIZE  740
 
diff --git a/drivers/net/wireless/ti/wlcore/acx.h 
b/drivers/net/wireless/ti/wlcore/acx.h
index 0d61fae..6321ed4 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -105,6 +105,7 @@ enum wl12xx_role {
WL1271_ROLE_DEVICE,
WL1271_ROLE_P2P_CL,
WL1271_ROLE_P2P_GO,
+   WL1271_ROLE_MESH_POINT,
 
WL12XX_INVALID_ROLE_TYPE = 0xff
 };
diff --git a/drivers/net/wireless/ti/wlcore/boot.c 
b/drivers/net/wireless/ti/wlcore/boot.c
index 19b7ec7..f75d304 100644
--- a/drivers/net/wireless/ti/wlcore/boot.c
+++ b/drivers/net/wireless/ti/wlcore/boot.c
@@ -130,7 +130,7 @@ fail:
wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is invalid.\n"
 "Please use at least FW %s\n"
 "You can get the latest firmwares at:\n"
-"git://github.com/TI-OpenLink/firmwares.git",
+"git://git.ti.com/wilink8-wlan/wl18xx_fw.git",
 fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE],
 fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE],
 fw_ver[FW_VER_MINOR], min_fw_str);
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c 
b/drivers/net/wireless/ti/wlcore/cmd.c
index 3315356..d002dc7 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -629,11 +629,14 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct 
wl12xx_vif *wlvif)
 
wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id);
 
-   /* trying to use hidden SSID with an old hostapd version */
-   if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) {
-   wl1271_error("got a null SSID from beacon/bss");
-   ret = -EINVAL;
-   goto out;
+   /* If MESH --> ssid_len is always 0 */
+   if (!ieee80211_vif_is_mesh(vif)) {
+   /* trying to use hidden SSID with an old hostapd version */
+   if (wlvif->ssid_len == 0 && !bss_conf->hid

[PATCH v2] wlcore: time sync : add support for 64 bit clock

2016-06-27 Thread Yaniv Machani
Changed the configuration to support 64bit instead of 32bit
this in order to offload the driver from handling a wraparound.

Signed-off-by: Yaniv Machani <yani...@ti.com>
---
V2 - Update the interface parameters type to le16 from u16.

 drivers/net/wireless/ti/wl18xx/event.c | 26 +-
 drivers/net/wireless/ti/wl18xx/event.h | 19 +--
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ti/wl18xx/event.c 
b/drivers/net/wireless/ti/wl18xx/event.c
index ef81184..2c5df43 100644
--- a/drivers/net/wireless/ti/wl18xx/event.c
+++ b/drivers/net/wireless/ti/wl18xx/event.c
@@ -112,12 +112,18 @@ static int wlcore_smart_config_decode_event(struct wl1271 
*wl,
return 0;
 }
 
-static void wlcore_event_time_sync(struct wl1271 *wl, u16 tsf_msb, u16 tsf_lsb)
+static void wlcore_event_time_sync(struct wl1271 *wl,
+  u16 tsf_high_msb, u16 tsf_high_lsb,
+  u16 tsf_low_msb, u16 tsf_low_lsb)
 {
-   u32 clock;
-   /* convert the MSB+LSB to a u32 TSF value */
-   clock = (tsf_msb << 16) | tsf_lsb;
-   wl1271_info("TIME_SYNC_EVENT_ID: clock %u", clock);
+   u32 clock_low;
+   u32 clock_high;
+
+   clock_high = (tsf_high_msb << 16) | tsf_high_lsb;
+   clock_low = (tsf_low_msb << 16) | tsf_low_lsb;
+
+   wl1271_info("TIME_SYNC_EVENT_ID: clock_high %u, clock low %u",
+   clock_high, clock_low);
 }
 
 int wl18xx_process_mailbox_events(struct wl1271 *wl)
@@ -138,8 +144,10 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
 
if (vector & TIME_SYNC_EVENT_ID)
wlcore_event_time_sync(wl,
-   mbox->time_sync_tsf_msb,
-   mbox->time_sync_tsf_lsb);
+   mbox->time_sync_tsf_high_msb,
+   mbox->time_sync_tsf_high_lsb,
+   mbox->time_sync_tsf_low_msb,
+   mbox->time_sync_tsf_low_lsb);
 
if (vector & RADAR_DETECTED_EVENT_ID) {
wl1271_info("radar event: channel %d type %s",
@@ -187,11 +195,11 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
 */
if (vector & MAX_TX_FAILURE_EVENT_ID)
wlcore_event_max_tx_failure(wl,
-   le32_to_cpu(mbox->tx_retry_exceeded_bitmap));
+   le16_to_cpu(mbox->tx_retry_exceeded_bitmap));
 
if (vector & INACTIVE_STA_EVENT_ID)
wlcore_event_inactive_sta(wl,
-   le32_to_cpu(mbox->inactive_sta_bitmap));
+   le16_to_cpu(mbox->inactive_sta_bitmap));
 
if (vector & REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID)
wlcore_event_roc_complete(wl);
diff --git a/drivers/net/wireless/ti/wl18xx/event.h 
b/drivers/net/wireless/ti/wl18xx/event.h
index 070de12..ce8ea9c0 100644
--- a/drivers/net/wireless/ti/wl18xx/event.h
+++ b/drivers/net/wireless/ti/wl18xx/event.h
@@ -74,10 +74,16 @@ struct wl18xx_event_mailbox {
__le16 bss_loss_bitmap;
 
/* bitmap of stations (by HLID) which exceeded max tx retries */
-   __le32 tx_retry_exceeded_bitmap;
+   __le16 tx_retry_exceeded_bitmap;
+
+   /* time sync high msb*/
+   __le16 time_sync_tsf_high_msb;
 
/* bitmap of inactive stations (by HLID) */
-   __le32 inactive_sta_bitmap;
+   __le16 inactive_sta_bitmap;
+
+   /* time sync high lsb*/
+   __le16 time_sync_tsf_high_lsb;
 
/* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */
u8 rx_ba_role_id;
@@ -98,14 +104,15 @@ struct wl18xx_event_mailbox {
u8 sc_sync_channel;
u8 sc_sync_band;
 
-   /* time sync msb*/
-   u16 time_sync_tsf_msb;
+   /* time sync low msb*/
+   __le16 time_sync_tsf_low_msb;
+
/* radar detect */
u8 radar_channel;
u8 radar_type;
 
-   /* time sync lsb*/
-   u16 time_sync_tsf_lsb;
+   /* time sync low lsb*/
+   __le16 time_sync_tsf_low_lsb;
 
 } __packed;
 
-- 
2.9.0



[PATCH] wlcore: time sync : add support for 64 bit clock

2016-06-23 Thread Yaniv Machani
Changed the configuration to support 64bit instead of 32bit
this in order to offload the driver from handling a wraparound.

Signed-off-by: Yaniv Machani <yani...@ti.com>
---
 drivers/net/wireless/ti/wl18xx/event.c | 26 +-
 drivers/net/wireless/ti/wl18xx/event.h | 19 +--
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ti/wl18xx/event.c 
b/drivers/net/wireless/ti/wl18xx/event.c
index ef81184..2c5df43 100644
--- a/drivers/net/wireless/ti/wl18xx/event.c
+++ b/drivers/net/wireless/ti/wl18xx/event.c
@@ -112,12 +112,18 @@ static int wlcore_smart_config_decode_event(struct wl1271 
*wl,
return 0;
 }
 
-static void wlcore_event_time_sync(struct wl1271 *wl, u16 tsf_msb, u16 tsf_lsb)
+static void wlcore_event_time_sync(struct wl1271 *wl,
+  u16 tsf_high_msb, u16 tsf_high_lsb,
+  u16 tsf_low_msb, u16 tsf_low_lsb)
 {
-   u32 clock;
-   /* convert the MSB+LSB to a u32 TSF value */
-   clock = (tsf_msb << 16) | tsf_lsb;
-   wl1271_info("TIME_SYNC_EVENT_ID: clock %u", clock);
+   u32 clock_low;
+   u32 clock_high;
+
+   clock_high = (tsf_high_msb << 16) | tsf_high_lsb;
+   clock_low = (tsf_low_msb << 16) | tsf_low_lsb;
+
+   wl1271_info("TIME_SYNC_EVENT_ID: clock_high %u, clock low %u",
+   clock_high, clock_low);
 }
 
 int wl18xx_process_mailbox_events(struct wl1271 *wl)
@@ -138,8 +144,10 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
 
if (vector & TIME_SYNC_EVENT_ID)
wlcore_event_time_sync(wl,
-   mbox->time_sync_tsf_msb,
-   mbox->time_sync_tsf_lsb);
+   mbox->time_sync_tsf_high_msb,
+   mbox->time_sync_tsf_high_lsb,
+   mbox->time_sync_tsf_low_msb,
+   mbox->time_sync_tsf_low_lsb);
 
if (vector & RADAR_DETECTED_EVENT_ID) {
wl1271_info("radar event: channel %d type %s",
@@ -187,11 +195,11 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
 */
if (vector & MAX_TX_FAILURE_EVENT_ID)
wlcore_event_max_tx_failure(wl,
-   le32_to_cpu(mbox->tx_retry_exceeded_bitmap));
+   le16_to_cpu(mbox->tx_retry_exceeded_bitmap));
 
if (vector & INACTIVE_STA_EVENT_ID)
wlcore_event_inactive_sta(wl,
-   le32_to_cpu(mbox->inactive_sta_bitmap));
+   le16_to_cpu(mbox->inactive_sta_bitmap));
 
if (vector & REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID)
wlcore_event_roc_complete(wl);
diff --git a/drivers/net/wireless/ti/wl18xx/event.h 
b/drivers/net/wireless/ti/wl18xx/event.h
index 070de12..b436bf9 100644
--- a/drivers/net/wireless/ti/wl18xx/event.h
+++ b/drivers/net/wireless/ti/wl18xx/event.h
@@ -74,10 +74,16 @@ struct wl18xx_event_mailbox {
__le16 bss_loss_bitmap;
 
/* bitmap of stations (by HLID) which exceeded max tx retries */
-   __le32 tx_retry_exceeded_bitmap;
+   __le16 tx_retry_exceeded_bitmap;
+
+   /* time sync high msb*/
+   u16 time_sync_tsf_high_msb;
 
/* bitmap of inactive stations (by HLID) */
-   __le32 inactive_sta_bitmap;
+   __le16 inactive_sta_bitmap;
+
+   /* time sync high lsb*/
+   u16 time_sync_tsf_high_lsb;
 
/* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */
u8 rx_ba_role_id;
@@ -98,14 +104,15 @@ struct wl18xx_event_mailbox {
u8 sc_sync_channel;
u8 sc_sync_band;
 
-   /* time sync msb*/
-   u16 time_sync_tsf_msb;
+   /* time sync low msb*/
+   u16 time_sync_tsf_low_msb;
+
/* radar detect */
u8 radar_channel;
u8 radar_type;
 
-   /* time sync lsb*/
-   u16 time_sync_tsf_lsb;
+   /* time sync low lsb*/
+   u16 time_sync_tsf_low_lsb;
 
 } __packed;
 
-- 
2.9.0