[PATCH v2] mac80211: mesh: fix RCU warning
ifmsh->csa is an RCU-protected pointer. The writer context in ieee80211_mesh_finish_csa() is already mutually exclusive with wdev->sdata.mtx, but the RCU checker did not know this. Use rcu_dereference_protected() to avoid a warning. fixes the following warning: [ 12.519089] = [ 12.520042] WARNING: suspicious RCU usage [ 12.520652] 5.1.0-rc7-wt+ #16 Tainted: GW [ 12.521409] - [ 12.521972] net/mac80211/mesh.c:1223 suspicious rcu_dereference_check() usage! [ 12.522928] other info that might help us debug this: [ 12.523984] rcu_scheduler_active = 2, debug_locks = 1 [ 12.524855] 5 locks held by kworker/u8:2/152: [ 12.525438] #0: 057be08c ((wq_completion)phy0){+.+.}, at: process_one_work+0x1a2/0x620 [ 12.526607] #1: 59c6b07a ((work_completion)(&sdata->csa_finalize_work)){+.+.}, at: process_one_work+0x1a2/0x620 [ 12.528001] #2: f184ba7d (&wdev->mtx){+.+.}, at: ieee80211_csa_finalize_work+0x2f/0x90 [ 12.529116] #3: 831a1f54 (&local->mtx){+.+.}, at: ieee80211_csa_finalize_work+0x47/0x90 [ 12.530233] #4: fd06f988 (&local->chanctx_mtx){+.+.}, at: ieee80211_csa_finalize_work+0x51/0x90 Signed-off-by: Thomas Pedersen --- v2: rcu_read_lock() doesn't make sense. Use rcu_dereference_protected() (Johannes) --- net/mac80211/mesh.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 766e5e5..d5aba50 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1220,7 +1220,8 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) ifmsh->chsw_ttl = 0; /* Remove the CSA and MCSP elements from the beacon */ - tmp_csa_settings = rcu_dereference(ifmsh->csa); + tmp_csa_settings = rcu_dereference_protected(ifmsh->csa, + lockdep_is_held(&sdata->wdev.mtx)); RCU_INIT_POINTER(ifmsh->csa, NULL); if (tmp_csa_settings) kfree_rcu(tmp_csa_settings, rcu_head); @@ -1242,6 +1243,8 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, struct mesh_csa_settings *tmp_csa_settings; int ret = 0; + lockdep_assert_held(&sdata->wdev.mtx); + tmp_csa_settings = kmalloc(sizeof(*tmp_csa_settings), GFP_ATOMIC); if (!tmp_csa_settings) -- 2.7.4
Re: [PATCH] mac80211: mesh: fix RCU warning
On Fri, May 24, 2019 at 1:29 AM Johannes Berg wrote: > > On Wed, 2019-05-15 at 15:21 -0700, Thomas Pedersen wrote: > > ifmsh->csa was being dereferenced without the RCU read > > lock held. > > > +++ b/net/mac80211/mesh.c > > @@ -1220,10 +1220,12 @@ int ieee80211_mesh_finish_csa(struct > > ieee80211_sub_if_data *sdata) > > ifmsh->chsw_ttl = 0; > > > > /* Remove the CSA and MCSP elements from the beacon */ > > + rcu_read_lock(); > > tmp_csa_settings = rcu_dereference(ifmsh->csa); > > RCU_INIT_POINTER(ifmsh->csa, NULL); > > if (tmp_csa_settings) > > kfree_rcu(tmp_csa_settings, rcu_head); > > + rcu_read_unlock(); > > This seems wrong to me. > > Really this code is the *writer* side, so you should do something like > this: Thanks this looks correct. I should've thought about this a tiny bit more ;) > diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c > index 766e5e5bab8a..d578147ad7e8 100644 > --- a/net/mac80211/mesh.c > +++ b/net/mac80211/mesh.c > @@ -1220,7 +1220,8 @@ int ieee80211_mesh_finish_csa(struct > ieee80211_sub_if_data *sdata) > ifmsh->chsw_ttl = 0; > > /* Remove the CSA and MCSP elements from the beacon */ > - tmp_csa_settings = rcu_dereference(ifmsh->csa); > + tmp_csa_settings = rcu_dereference_protected(ifmsh->csa, > + lockdep_is_held(&sdata->wdev.mtx)); > RCU_INIT_POINTER(ifmsh->csa, NULL); > if (tmp_csa_settings) > kfree_rcu(tmp_csa_settings, rcu_head); > @@ -1242,6 +1243,8 @@ int ieee80211_mesh_csa_beacon(struct > ieee80211_sub_if_data *sdata, > struct mesh_csa_settings *tmp_csa_settings; > int ret = 0; > > + lockdep_assert_held(&sdata->wdev.mtx); > + > tmp_csa_settings = kmalloc(sizeof(*tmp_csa_settings), >GFP_ATOMIC); > if (!tmp_csa_settings) > > > Can you test that and send a proper patch? > > johannes > -- thomas
Re: [PATCH] mac80211: mesh: fix RCU warning
On Wed, May 15, 2019 at 3:21 PM Thomas Pedersen wrote: > > ifmsh->csa was being dereferenced without the RCU read > lock held. > > fixes the following warning: > > [ 74.930435] = > [ 74.932066] WARNING: suspicious RCU usage > [ 74.933671] 4.20.13 #5 Tainted: GW > [ 74.935804] - > [ 74.937427] net/mac80211/mesh.c:1218 suspicious rcu_dereference_check() > usage! > [ 74.940473] other info that might help us debug this: > [ 74.943654] rcu_scheduler_active = 2, debug_locks = 1 > [ 74.946311] 5 locks held by kworker/u8:3/107: > [ 74.948087] #0: 7623c1f0 > ((wq_completion)"%s"wiphy_name(local->hw.wiphy)){+.+.}, at: > process_one_work+0x1a2/0x610 > [ 74.952464] #1: 077b4215 > ((work_completion)(&sdata->csa_finalize_work)){+.+.}, at: > process_one_work+0x1a2/0x610 > [ 74.957228] #2: e02b12da (&wdev->mtx){+.+.}, at: > ieee80211_csa_finalize_work+0x2f/0x90 > [ 74.959870] #3: e6855095 (&local->mtx){+.+.}, at: > ieee80211_csa_finalize_work+0x47/0x90 > [ 74.962937] #4: bb5e3bca (&local->chanctx_mtx){+.+.}, at: > ieee80211_csa_finalize_work+0x51/0x90 Sorry the commit message is a little out of date, I actually tested on 5.1.0-rc7-wt as well. > Signed-off-by: Thomas Pedersen > --- > net/mac80211/mesh.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c > index 766e5e5..70aeb34 100644 > --- a/net/mac80211/mesh.c > +++ b/net/mac80211/mesh.c > @@ -1220,10 +1220,12 @@ int ieee80211_mesh_finish_csa(struct > ieee80211_sub_if_data *sdata) > ifmsh->chsw_ttl = 0; > > /* Remove the CSA and MCSP elements from the beacon */ > + rcu_read_lock(); > tmp_csa_settings = rcu_dereference(ifmsh->csa); > RCU_INIT_POINTER(ifmsh->csa, NULL); > if (tmp_csa_settings) > kfree_rcu(tmp_csa_settings, rcu_head); > + rcu_read_unlock(); > ret = ieee80211_mesh_rebuild_beacon(sdata); > if (ret) > return -EINVAL; > -- > 2.7.4 > -- thomas
[PATCH] mac80211: mesh: fix RCU warning
ifmsh->csa was being dereferenced without the RCU read lock held. fixes the following warning: [ 74.930435] = [ 74.932066] WARNING: suspicious RCU usage [ 74.933671] 4.20.13 #5 Tainted: GW [ 74.935804] - [ 74.937427] net/mac80211/mesh.c:1218 suspicious rcu_dereference_check() usage! [ 74.940473] other info that might help us debug this: [ 74.943654] rcu_scheduler_active = 2, debug_locks = 1 [ 74.946311] 5 locks held by kworker/u8:3/107: [ 74.948087] #0: 7623c1f0 ((wq_completion)"%s"wiphy_name(local->hw.wiphy)){+.+.}, at: process_one_work+0x1a2/0x610 [ 74.952464] #1: 077b4215 ((work_completion)(&sdata->csa_finalize_work)){+.+.}, at: process_one_work+0x1a2/0x610 [ 74.957228] #2: e02b12da (&wdev->mtx){+.+.}, at: ieee80211_csa_finalize_work+0x2f/0x90 [ 74.959870] #3: e6855095 (&local->mtx){+.+.}, at: ieee80211_csa_finalize_work+0x47/0x90 [ 74.962937] #4: bb5e3bca (&local->chanctx_mtx){+.+.}, at: ieee80211_csa_finalize_work+0x51/0x90 Signed-off-by: Thomas Pedersen --- net/mac80211/mesh.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 766e5e5..70aeb34 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1220,10 +1220,12 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) ifmsh->chsw_ttl = 0; /* Remove the CSA and MCSP elements from the beacon */ + rcu_read_lock(); tmp_csa_settings = rcu_dereference(ifmsh->csa); RCU_INIT_POINTER(ifmsh->csa, NULL); if (tmp_csa_settings) kfree_rcu(tmp_csa_settings, rcu_head); + rcu_read_unlock(); ret = ieee80211_mesh_rebuild_beacon(sdata); if (ret) return -EINVAL; -- 2.7.4
preparing for 802.11ah channels
Hello, I'm working on defining new channels for S1G PHYs in mac80211. These are in the 900MHz range and center frequency for the 1MHz channels are on a half MHz, while the existing channel definitions are in units of MHz. In order to support the new channels we could change the internal center frequency units to KHz and extend the nl80211 API so NL80211_FREQUENCY_ATTR_FREQ and NL80211_ATTR_WIPHY_FREQ get _KHZ variants while renaming the original attributes to _MHZ to reflect the units. >From looking at the code it looks like this should be fairly straightforward, if involving a lot of changes since the driver declarations would have to change too. Am I missing something obviously wrong, or does this sound reasonable? Thanks, Thomas
Re: Query on queues in mesh mode
On Wed, Mar 7, 2018 at 8:39 AM, Phani Siriki wrote: > Hi Thomas > > Thank you for your reply. > > Could you please let me know how can I verify these queues on a mesh > router? (I am using TPLink router with Ath9k chipset). try $ iw mesh0 mpath dump The mpath queue length is under the "QLEN" heading. > Also, the TXQ parameters can only be set if device is in AP or P2P > mode. Do you have any idea why this restriction is in place? I don't think there is any reason modifying the queue parameters wouldn't work in mesh mode. Why don't you hack up that code and give it a try. > https://github.com/torvalds/linux/blob/master/net/wireless/nl80211.c > > static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) > { > >if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { > >if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && >netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) > return -EINVAL; >... > } > > Best Regards > Phani > > On Tue, Mar 6, 2018 at 11:59 PM, Thomas Pedersen wrote: >> On Thu, Mar 1, 2018 at 7:27 AM, Phani Siriki wrote: >>> Hi All >>> >>> I am trying to understand the queuing mechanism wireless mesh networks. >>> >>> As per AP mode is concerned, there are four queues (BK, BE, Vi, VO) >>> and traffic is controlled based on CWmin, CWmax, AIFS and TxOP. >>> >>> Does, mesh mode also involve these queues? Does mesh mode have any >>> queue or it is just a single queue? >> >> mesh mode maps to the different ACs like AP mode. The only additional >> queue in mesh is the mpath->frame_queue, which may be used if an >> active mpath for a given RA can't be found. >> >> -- >> thomas -- thomas
Re: Query on queues in mesh mode
On Thu, Mar 1, 2018 at 7:27 AM, Phani Siriki wrote: > Hi All > > I am trying to understand the queuing mechanism wireless mesh networks. > > As per AP mode is concerned, there are four queues (BK, BE, Vi, VO) > and traffic is controlled based on CWmin, CWmax, AIFS and TxOP. > > Does, mesh mode also involve these queues? Does mesh mode have any > queue or it is just a single queue? mesh mode maps to the different ACs like AP mode. The only additional queue in mesh is the mpath->frame_queue, which may be used if an active mpath for a given RA can't be found. -- thomas
Re: oops on cloned-mac 802.11s stations
On Tue, Dec 19, 2017 at 2:05 AM, Johannes Berg wrote: > On Mon, 2017-12-18 at 03:44 +0100, Gui Iribarren wrote: >> Steps to reproduce: >> join a 802.11s mesh with a nodeA, and then join the same 802.11s mesh >> with another nodeB, so that both nodes MAC addresses are exactly the >> same (i.e. nodeB is "cloning" nodeA MAC) >> >> Expected result: >> nodeA and nodeB coexist in a conflicting state, silently >> (not saying that this is a desired scenario, of course; just came across >> this while testing radios that accidentally had the same (fake) address. >> the warning might ring a bell to someone, so reporting it here just for >> the record) >> >> What actually happens: >> both on nodeA and nodeB, the log is flooded with these warnings: > > That's hardly an "oops", but yeah, not nice. > > Somewhere we should drop packets if they appear to come from ourselves. > Perhaps like this: > > diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c > index b3cff69bfd66..fd580614085b 100644 > --- a/net/mac80211/rx.c > +++ b/net/mac80211/rx.c > @@ -3625,6 +3625,8 @@ static bool ieee80211_accept_frame(struct > ieee80211_rx_data *rx) > } > return true; > case NL80211_IFTYPE_MESH_POINT: > + if (ether_addr_equal(sdata->vif.addr, hdr->addr2)) > + return false; > if (multicast) > return true; > return ether_addr_equal(sdata->vif.addr, hdr->addr1); Makes sense. -- thomas
Re: [PATCH] mac80211: fix the update of path metric for RANN frame
Thanks Chun-Yeow, this is a good change. On Tue, Nov 14, 2017 at 7:20 AM, Chun-Yeow Yeoh wrote: > The previous path metric update from RANN frame has not considered > the own link metric toward the transmitting mesh STA. Fix this. > > Reported-by: Michael65535 > Signed-off-by: Chun-Yeow Yeoh > --- > net/mac80211/mesh_hwmp.c | 15 +-- > 1 file changed, 9 insertions(+), 6 deletions(-) > > diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c > index c1d1b86..35ad398 100644 > --- a/net/mac80211/mesh_hwmp.c > +++ b/net/mac80211/mesh_hwmp.c > @@ -797,7 +797,7 @@ static void hwmp_rann_frame_process(struct > ieee80211_sub_if_data *sdata, > struct mesh_path *mpath; > u8 ttl, flags, hopcount; > const u8 *orig_addr; > - u32 orig_sn, metric, metric_txsta, interval; > + u32 orig_sn, new_metric, orig_metric, last_hop_metric, interval; > bool root_is_gate; > > ttl = rann->rann_ttl; > @@ -808,7 +808,7 @@ static void hwmp_rann_frame_process(struct > ieee80211_sub_if_data *sdata, > interval = le32_to_cpu(rann->rann_interval); > hopcount = rann->rann_hopcount; > hopcount++; > - metric = le32_to_cpu(rann->rann_metric); > + orig_metric = le32_to_cpu(rann->rann_metric); > > /* Ignore our own RANNs */ > if (ether_addr_equal(orig_addr, sdata->vif.addr)) > @@ -825,7 +825,10 @@ static void hwmp_rann_frame_process(struct > ieee80211_sub_if_data *sdata, > return; > } > > - metric_txsta = airtime_link_metric_get(local, sta); > + last_hop_metric = airtime_link_metric_get(local, sta); > + new_metric = orig_metric + last_hop_metric; > + if (new_metric < orig_metric) > + new_metric = MAX_METRIC; > > mpath = mesh_path_lookup(sdata, orig_addr); > if (!mpath) { > @@ -838,7 +841,7 @@ static void hwmp_rann_frame_process(struct > ieee80211_sub_if_data *sdata, > } > > if (!(SN_LT(mpath->sn, orig_sn)) && > - !(mpath->sn == orig_sn && metric < mpath->rann_metric)) { > + !(mpath->sn == orig_sn && new_metric < mpath->rann_metric)) { > rcu_read_unlock(); > return; > } > @@ -856,7 +859,7 @@ static void hwmp_rann_frame_process(struct > ieee80211_sub_if_data *sdata, > } > > mpath->sn = orig_sn; > - mpath->rann_metric = metric + metric_txsta; > + mpath->rann_metric = new_metric; > mpath->is_root = true; > /* Recording RANNs sender address to send individually > * addressed PREQs destined for root mesh STA */ > @@ -876,7 +879,7 @@ static void hwmp_rann_frame_process(struct > ieee80211_sub_if_data *sdata, > mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, >orig_sn, 0, NULL, 0, broadcast_addr, >hopcount, ttl, interval, > - metric + metric_txsta, 0, sdata); > + new_metric, 0, sdata); > } > > rcu_read_unlock(); > -- > 2.3.0 > -- thomas
Re: Incorrect mesh path seq num
On Mon, Sep 4, 2017 at 6:19 AM, Johannes Berg wrote: > On Fri, 2017-09-01 at 13:07 -0700, Thomas Pedersen wrote: >> On Thu, Aug 31, 2017 at 11:30 PM, Greg Maitz >> wrote: >> > Hi guys, >> > >> > I'm seeing a problem when I work on the wireless mesh between two >> > linux devices. The root node has 3.18 kernel while the next hop >> > station runs 2.6.37 kernel. I found the mpath->sn value is >> > incorrect >> > most of the time on the device having 2.6.37 kernel. After >> > examining >> > the code, in function hwmp_route_info_get [mesh_hwmp.c], after >> > mesh_path_lookup, the sequence number (i.e, mpath->sn) is >> > incorrect. >> > For instance, I see mpath->sn having value 0x3095. It should be >> > 0x9530, while the orig_sn is having value 0x9531. >> >> Looks like an endianess bug. Are you testing on two platforms of >> different endianess? > > Even if that's the case, wouldn't it mean some kind of conversion is > missing somewhere? Yes. I looked for a missing conversion, but couldn't find it. Greg, where / how are you printing mpath->sn? mpath dump or a printk you added? -- thomas
Re: Incorrect mesh path seq num
On Thu, Aug 31, 2017 at 11:30 PM, Greg Maitz wrote: > Hi guys, > > I'm seeing a problem when I work on the wireless mesh between two > linux devices. The root node has 3.18 kernel while the next hop > station runs 2.6.37 kernel. I found the mpath->sn value is incorrect > most of the time on the device having 2.6.37 kernel. After examining > the code, in function hwmp_route_info_get [mesh_hwmp.c], after > mesh_path_lookup, the sequence number (i.e, mpath->sn) is incorrect. > For instance, I see mpath->sn having value 0x3095. It should be > 0x9530, while the orig_sn is having value 0x9531. Looks like an endianess bug. Are you testing on two platforms of different endianess? > This results in the > last hop metric to become zero in function mesh_rx_path_sel_frame and > hwmp_preq_frame_process doesn't get called. Is this a known problem? > Can anyone provide suggestions to debug further? -- thomas
Re: [PATCH v2] mac80211: Jitter HWMP MPATH reply frames to reduce collision on dense networks.
On Thu, Mar 2, 2017 at 9:41 AM, Jesse Jones wrote: >> Hi Alexis, >> >> > This is loosely based on RFC5148, specifically event-triggered message >> > generation as described in section 5.2. >> >> I'm confused. I see how that generally seems to apply to any mobile >> network, but it *does* state up-front that >> In some instances, these problems can be solved in these lower >> layers, but in other instances, some help at the network and higher >> layers is necessary. >> >> I believe 802.11 *does* in fact solve these issues at lower layers. Can >> you explain how you observed any problem in this area? > > Well it certainly attempts to via stuff like carrier sense. But that is not > fool proof and any time two routers hear a frame and both decide to forward > it immediately there is a chance that they will both sense the air at the > same time, decide that it is clear, and lose both their forwarded frames due > to a collision. How often that happens is hard to say but we have observed > that exact behavior a few years ago with an 802.11 multicast routing > protocol and adding jitter significantly improved reliability. Have you tried performing RTS/CTS before sending path selection frames to manage the hidden node problem? -- thomas
Re: [PATCH 3/3] mac80211: clear failure average upon mesh path deactivation
On Tue, Jan 31, 2017 at 11:33 AM, Rajkumar Manoharan wrote: > On 2017-01-31 09:51, Thomas Pedersen wrote: >> >> Hi Rajkumar, >> >> Thanks this looks good, but.. >> >> On Fri, Jan 27, 2017 at 4:01 PM, Rajkumar Manoharan >> wrote: >>> >>> Mesh moving average should be cleared, whenever mesh paths >>> to the given station are deactivated due to bad link. This will >>> give enough room to analysis more tx status than retaining the >>> current average. >>> > [...] >>> >>> ret = rhashtable_walk_init(&tbl->rhead, &iter, GFP_ATOMIC); >>> if (ret) >>> @@ -535,8 +536,11 @@ void mesh_plink_broken(struct sta_info *sta) >>> sdata->u.mesh.mshcfg.element_ttl, >>> mpath->dst, mpath->sn, >>> WLAN_REASON_MESH_PATH_DEST_UNREACHABLE, >>> bcast); >>> + paths_deactivated = true; >>> } >>> } >>> + if (paths_deactivated) >>> + sta->mesh->fail_avg = 0; >> >> >> .. why this indirection? Just reset mesh->fail_avg unconditionally in >> this function? >> > Hmm... As fixed paths are not affected, resetting fail_avg for fixed path > may give > wrong metric. no? I don't think setting fail_avg = 0 will affect existing fixed mpath code. Anyway metrics should not affect whether a fixed mpath is chosen. -- thomas
Re: [PATCH 3/3] mac80211: clear failure average upon mesh path deactivation
Hi Rajkumar, Thanks this looks good, but.. On Fri, Jan 27, 2017 at 4:01 PM, Rajkumar Manoharan wrote: > Mesh moving average should be cleared, whenever mesh paths > to the given station are deactivated due to bad link. This will > give enough room to analysis more tx status than retaining the > current average. > > Signed-off-by: Rajkumar Manoharan > --- > net/mac80211/mesh_pathtbl.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c > index f0e6175a9821..208ad36c0a7f 100644 > --- a/net/mac80211/mesh_pathtbl.c > +++ b/net/mac80211/mesh_pathtbl.c > @@ -510,6 +510,7 @@ void mesh_plink_broken(struct sta_info *sta) > struct mesh_path *mpath; > struct rhashtable_iter iter; > int ret; > + bool paths_deactivated = false; > > ret = rhashtable_walk_init(&tbl->rhead, &iter, GFP_ATOMIC); > if (ret) > @@ -535,8 +536,11 @@ void mesh_plink_broken(struct sta_info *sta) > sdata->u.mesh.mshcfg.element_ttl, > mpath->dst, mpath->sn, > WLAN_REASON_MESH_PATH_DEST_UNREACHABLE, > bcast); > + paths_deactivated = true; > } > } > + if (paths_deactivated) > + sta->mesh->fail_avg = 0; .. why this indirection? Just reset mesh->fail_avg unconditionally in this function? -- thomas
Re: [PATCH] mac80211: Remove invalid flag operations in mesh TSF synchronization
On Fri, Dec 2, 2016 at 10:59 PM, Masashi Honma wrote: > On 2016/12/03 06:13, Bob Copeland wrote: >> >> On Fri, Dec 02, 2016 at 12:07:18PM -0800, Thomas Pedersen wrote: > > > # Rejected by linux wireless ML. This is resubmission. > > thomas and Bob, Thanks for comments. > >> 802.11-2012 13.13.2.2.3: >> The mesh STA checks if the transmitter of the Beacon frame or Probe >> Response frame is in the >> process of the TBTT adjustment (see 13.13.4.4.3). > > There are two functionalities. > > 1) 13.13.2.2 Neighbor offset synchronization method > 2) 13.13.4.4 TBTT adjustment > > The ifmsh->adjusting_tbtt flag implements "TBTT Adjusting field" in the > Mesh Configuration field. > > The flag is updated by 2). > 13.13.4.4.3 TBTT scanning and adjustment procedures: > The mesh STA shall set the TBTT Adjusting field in the Mesh > Configuration element to 1 in order to announce that the TBTT > adjustment procedure is ongoing. > > And the flag is refered by 1) as you said. > > > The purpose of the flag is to prevent 1) while 2) is ongoing. > > In other words, 1) has only read access authority to the flag. However, > previous code updated the flag in 1). In addition, there is no code for > 2). So I just remove the invalid accessing codes. I don't think 1) has read only access to that flag. A TSF adjust will by definition move the TBTT as well. -- thomas
Re: [PATCH] mac80211: Remove invalid flag operations in mesh TSF synchronization
On Wed, Nov 30, 2016 at 2:44 PM, Masashi Honma wrote: > mesh_sync_offset_adjust_tbtt() implements Extensible synchronization > framework ([1] 13.13.2 Extensible synchronization framework). It shall > not operate the flag "TBTT Adjusting subfield" ([1] 8.4.2.100.8 Mesh > Capability), since it is used only for MBCA ([1] 13.13.4 Mesh beacon > collision avoidance, see 13.13.4.4.3 TBTT scanning and adjustment > procedures for detail). So this patch remove the flag operations. 802.11-2012 13.13.2.2.3: The mesh STA checks if the transmitter of the Beacon frame or Probe Response frame is in the process of the TBTT adjustment (see 13.13.4.4.3). If the received frame contains the Mesh Configuration element and the TBTT Adjusting subfield in the Mesh Configuration field is 1, the mesh STA shall invalidate the T offset value for this neighbor STA and shall not perform the following steps. so, no? I think we need to indicate a TSF adjustment is taking place. -- thomas
[PATCH RESEND v2] cfg80211: add bitrate for 20MHz MCS 9
Some drivers (ath10k) report MCS 9 @ 20MHz, which technically isn't defined. To get more meaningful value than 0 out of this however, just extrapolate a bitrate from ratio of MCS 7 and 9 in channels where it is allowed. Signed-off-by: Thomas Pedersen --- v2: add MCS 9 bitrate instead of capping at MCS 8 --- net/wireless/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/util.c b/net/wireless/util.c index 32060f8..30fc320 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1163,7 +1163,7 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate) 5850, 6500, 7800, - 0, + 8650, }, { 1350, 2700, -- 2.10.0.297.gf6727b0
[PATCH 0/4] ath10k: fix mesh sync operation
This patchset introduces a new ieee80211_op offset_tsf(), which gives the driver a s64 TSF offset for TSF adjustment. This is more accurate than programming absolute TSF since programming delay is avoided. ath10k can't get the current TSF or program an absolute TSF, so we remove those ops to not mislead the stack and hopefully avoid future bugs. Tested on QCA4019 with firmware 10.4-3.2.1-0033. After this change Toffset remains stable to within 5us. Thomas Pedersen (4): mac80211: add offset_tsf driver op ath10k: implement offset_tsf ieee80211_op ath10k: remove set/get_tsf ieee80211_ops mac80211: mesh: decrease max drift drivers/net/wireless/ath/ath10k/mac.c | 45 +++ drivers/net/wireless/ath/ath10k/wmi-tlv.c | 1 - drivers/net/wireless/ath/ath10k/wmi.c | 6 ++--- drivers/net/wireless/ath/ath10k/wmi.h | 8 +- include/net/mac80211.h| 8 ++ net/mac80211/debugfs_netdev.c | 12 ++--- net/mac80211/driver-ops.c | 15 +++ net/mac80211/driver-ops.h | 3 +++ net/mac80211/mesh_sync.c | 12 ++--- net/mac80211/trace.h | 26 ++ 10 files changed, 94 insertions(+), 42 deletions(-) -- 2.10.0.297.gf6727b0
[PATCH 4/4] mac80211: mesh: decrease max drift
The old value was 30ms, which means mesh sync will treat any value below as merely TSF drift. This isn't really reasonable (typical drift is < 10us/s) since people probably want to adjust TSF in smaller increments (for ie. beacon collision avoidance) without mesh sync fighting back. Change max drift adjustment to 0.8ms, so manual TSF adjustments can be made in 1ms increments, with some margin. Signed-off-by: Thomas Pedersen --- net/mac80211/mesh_sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index 22ca43c..faca22c 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c @@ -28,7 +28,7 @@ * could be, for instance, in case a neighbor is restarted and its TSF counter * reset. */ -#define TOFFSET_MAXIMUM_ADJUSTMENT 3 /* 30 ms */ +#define TOFFSET_MAXIMUM_ADJUSTMENT 800 /* 0.8 ms */ struct sync_method { u8 method; -- 2.10.0.297.gf6727b0
[PATCH 2/4] ath10k: implement offset_tsf ieee80211_op
Current set_tsf is implemented in terms of TSF_INCREMENT only. Instead support new WMI command TSF_DECREMENT and export these through offset_tsf. Advantage is we get more accurate TSF adjustments, and don't calculate wrong offset in case absolute TSF was calculated from rx_mactime (actual TSF). The new WMI command is available in firmware 10.4-3.2.1-00033 for QCA4019 chips. Old drivers on new firmware or vice versa shouldn't be a problem since get/set tsf logic was already broken. Signed-off-by: Thomas Pedersen --- drivers/net/wireless/ath/ath10k/mac.c | 25 + drivers/net/wireless/ath/ath10k/wmi.c | 2 ++ drivers/net/wireless/ath/ath10k/wmi.h | 7 +++ 3 files changed, 34 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 76297d6..06bd027 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -6992,6 +6992,30 @@ static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ath10k_warn(ar, "failed to set tsf offset: %d\n", ret); } +static void ath10k_offset_tsf(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, s64 tsf_offset) +{ + struct ath10k *ar = hw->priv; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + u32 offset, vdev_param; + int ret; + + if (tsf_offset < 0) { + vdev_param = ar->wmi.vdev_param->dec_tsf; + offset = -tsf_offset; + } else { + vdev_param = ar->wmi.vdev_param->inc_tsf; + offset = tsf_offset; + } + + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + vdev_param, offset); + + if (ret && ret != -EOPNOTSUPP) + ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n", + offset, vdev_param, ret); +} + static int ath10k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params) @@ -7455,6 +7479,7 @@ static const struct ieee80211_ops ath10k_ops = { .sta_rc_update = ath10k_sta_rc_update, .get_tsf= ath10k_get_tsf, .set_tsf= ath10k_set_tsf, + .offset_tsf = ath10k_offset_tsf, .ampdu_action = ath10k_ampdu_action, .get_et_sset_count = ath10k_debug_get_et_sset_count, .get_et_stats = ath10k_debug_get_et_stats, diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 38993d7..430074b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1013,6 +1013,8 @@ static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = { .rx_decap_type = WMI_10_4_VDEV_PARAM_RX_DECAP_TYPE, .bw_nss_ratemask = WMI_10_4_VDEV_PARAM_BW_NSS_RATEMASK, .set_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT, + .inc_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT, + .dec_tsf = WMI_10_4_VDEV_PARAM_TSF_DECREMENT, }; static struct wmi_pdev_param_map wmi_pdev_param_map = { diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 1b243c8..9d13c6f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -4677,6 +4677,8 @@ struct wmi_vdev_param_map { u32 rx_decap_type; u32 bw_nss_ratemask; u32 set_tsf; + u32 inc_tsf; + u32 dec_tsf; }; #define WMI_VDEV_PARAM_UNSUPPORTED 0 @@ -5009,6 +5011,11 @@ enum wmi_10_4_vdev_param { WMI_10_4_VDEV_PARAM_STA_KICKOUT, WMI_10_4_VDEV_PARAM_CAPABILITIES, WMI_10_4_VDEV_PARAM_TSF_INCREMENT, + WMI_10_4_VDEV_PARAM_RX_FILTER, + WMI_10_4_VDEV_PARAM_MGMT_TX_POWER, + WMI_10_4_VDEV_PARAM_ATF_SSID_SCHED_POLICY, + WMI_10_4_VDEV_PARAM_DISABLE_DYN_BW_RTS, + WMI_10_4_VDEV_PARAM_TSF_DECREMENT, }; #define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0) -- 2.10.0.297.gf6727b0
[PATCH 3/4] ath10k: remove set/get_tsf ieee80211_ops
Neither of these did the right thing: - get_tsf just returned 0 - set_tsf assumed a simple offset was applied against get_tsf(), which works, except in the case of calculating TSF from rx_mactime (actual TSF). Just remove them for now. We can reimplement set_tsf in terms of TSF increment/decrement in the future if get_tsf is ever supported by FW. Signed-off-by: Thomas Pedersen --- drivers/net/wireless/ath/ath10k/mac.c | 38 --- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 1 - drivers/net/wireless/ath/ath10k/wmi.c | 4 drivers/net/wireless/ath/ath10k/wmi.h | 1 - 4 files changed, 44 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 06bd027..9806546 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -6956,42 +6956,6 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, ieee80211_queue_work(hw, &arsta->update_wk); } -static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - /* -* FIXME: Return 0 for time being. Need to figure out whether FW -* has the API to fetch 64-bit local TSF -*/ - - return 0; -} - -static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u64 tsf) -{ - struct ath10k *ar = hw->priv; - struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); - u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf; - int ret; - - /* Workaround: -* -* Given tsf argument is entire TSF value, but firmware accepts -* only TSF offset to current TSF. -* -* get_tsf function is used to get offset value, however since -* ath10k_get_tsf is not implemented properly, it will return 0 always. -* Luckily all the caller functions to set_tsf, as of now, also rely on -* get_tsf function to get entire tsf value such get_tsf() + tsf_delta, -* final tsf offset value to firmware will be arithmetically correct. -*/ - tsf_offset = tsf - ath10k_get_tsf(hw, vif); - ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, - vdev_param, tsf_offset); - if (ret && ret != -EOPNOTSUPP) - ath10k_warn(ar, "failed to set tsf offset: %d\n", ret); -} - static void ath10k_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, s64 tsf_offset) { @@ -7477,8 +7441,6 @@ static const struct ieee80211_ops ath10k_ops = { .get_survey = ath10k_get_survey, .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask, .sta_rc_update = ath10k_sta_rc_update, - .get_tsf= ath10k_get_tsf, - .set_tsf= ath10k_set_tsf, .offset_tsf = ath10k_offset_tsf, .ampdu_action = ath10k_ampdu_action, .get_et_sset_count = ath10k_debug_get_et_sset_count, diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index e64f593..5e399c6 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -3464,7 +3464,6 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, - .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED, }; static const struct wmi_ops wmi_tlv_ops = { diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 430074b..8661400 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -785,7 +785,6 @@ static struct wmi_vdev_param_map wmi_vdev_param_map = { .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, - .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED, }; /* 10.X WMI VDEV param map */ @@ -861,7 +860,6 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = { .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, - .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED, }; static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = { @@ -936,7 +934,6 @@ static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = { .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, - .set_tsf = WMI_10X_VDEV_PARAM_TSF_INCREMENT, }; static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = { @@ -1012,7 +1009,
[PATCH 1/4] mac80211: add offset_tsf driver op
Allows ie. mesh sync code to make incremental TSF adjustments, avoiding any uncertainty introduced by delay in programming absolute TSF. Signed-off-by: Thomas Pedersen --- include/net/mac80211.h| 8 net/mac80211/debugfs_netdev.c | 12 +--- net/mac80211/driver-ops.c | 15 +++ net/mac80211/driver-ops.h | 3 +++ net/mac80211/mesh_sync.c | 10 +++--- net/mac80211/trace.h | 26 ++ 6 files changed, 68 insertions(+), 6 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5296100..6312cbda9f 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3166,6 +3166,12 @@ enum ieee80211_reconfig_type { * required function. * The callback can sleep. * + * @offset_tsf: Offset the TSF timer by the specified value in the + * firmware/hardware. Preferred to set_tsf as it avoids delay between + * calling set_tsf() and hardware getting programmed, which will show up + * as TSF delay. Is not a required function. + * The callback can sleep. + * * @reset_tsf: Reset the TSF timer and allow firmware/hardware to synchronize * with other STAs in the IBSS. This is only used in IBSS mode. This * function is optional if the firmware/hardware takes full care of @@ -3531,6 +3537,8 @@ struct ieee80211_ops { u64 (*get_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*set_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf); + void (*offset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + s64 offset); void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int (*tx_last_beacon)(struct ieee80211_hw *hw); int (*ampdu_action)(struct ieee80211_hw *hw, diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 5d35c0f..bcec124 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -556,9 +556,15 @@ static ssize_t ieee80211_if_parse_tsf( ret = kstrtoull(buf, 10, &tsf); if (ret < 0) return ret; - if (tsf_is_delta) - tsf = drv_get_tsf(local, sdata) + tsf_is_delta * tsf; - if (local->ops->set_tsf) { + if (tsf_is_delta && local->ops->offset_tsf) { + drv_offset_tsf(local, sdata, tsf_is_delta * tsf); + wiphy_info(local->hw.wiphy, + "debugfs offset TSF by %018lld\n", + tsf_is_delta * tsf); + } else if (local->ops->set_tsf) { + if (tsf_is_delta) + tsf = drv_get_tsf(local, sdata) + + tsf_is_delta * tsf; drv_set_tsf(local, sdata, tsf); wiphy_info(local->hw.wiphy, "debugfs set TSF to %#018llx\n", tsf); diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c index c701b64..bb886e7 100644 --- a/net/mac80211/driver-ops.c +++ b/net/mac80211/driver-ops.c @@ -215,6 +215,21 @@ void drv_set_tsf(struct ieee80211_local *local, trace_drv_return_void(local); } +void drv_offset_tsf(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + s64 offset) +{ + might_sleep(); + + if (!check_sdata_in_driver(sdata)) + return; + + trace_drv_offset_tsf(local, sdata, offset); + if (local->ops->offset_tsf) + local->ops->offset_tsf(&local->hw, &sdata->vif, offset); + trace_drv_return_void(local); +} + void drv_reset_tsf(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata) { diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index fe35a1c..f47781ab1 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -568,6 +568,9 @@ u64 drv_get_tsf(struct ieee80211_local *local, void drv_set_tsf(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, u64 tsf); +void drv_offset_tsf(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + s64 offset); void drv_reset_tsf(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index 64bc22a..22ca43c 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c @@ -70,9 +70,13 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) } spin_unlock_bh(&ifmsh->sync_offset_lock); - tsf = drv_get_tsf(local, sdata); - if (tsf != -1ULL) -
[PATCH v2] cfg80211: add bitrate for 20MHz MCS 9
Some drivers (ath10k) report MCS 9 @ 20MHz, which technically isn't defined. To get more meaningful value than 0 out of this however, just extrapolate a bitrate from ratio of MCS 7 and 9 in channels where it is allowed. Signed-off-by: Thomas Pedersen --- v2: add MCS 9 bitrate instead of capping at MCS 8 --- net/wireless/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/util.c b/net/wireless/util.c index b7d1592..3e83170 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1157,7 +1157,7 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate) 5850, 6500, 7800, - 0, + 8650, }, { 1350, 2700, -- 2.1.4
[PATCH] ath10k: enable peer stats by default
IFTYPE_MESH_POINT need to rely on these for accurate path selection metrics. Other modes will probably also find them useful. Enabling peer stats has the side effect of reducing max number of STAs from 128 to 118. There should be negligible performance impact. If users really need 128 STAs and don't mind losing out on peer stats, they can still disable them: echo 0 > debugfs/ieee80211/phyn/ath10k/peer_stats Signed-off-by: Thomas Pedersen --- drivers/net/wireless/ath/ath10k/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index c9d163e..c0ab4f4 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -2145,6 +2145,9 @@ static void ath10k_core_register_work(struct work_struct *work) struct ath10k *ar = container_of(work, struct ath10k, register_work); int status; + /* peer stats are enabled by default */ + set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags); + status = ath10k_core_probe_fw(ar); if (status) { ath10k_err(ar, "could not probe fw (%d)\n", status); -- 2.1.4
[PATCH] cfg80211: cap 20MHz VHT bitrate at MCS 8
Some drivers (ath10k) report MCS 9 @ 20MHz, which technically isn't allowed. To get more meaningful value than 0 out of this however, just cap the bitrate for 20MHz to MCS 8. Signed-off-by: Thomas Pedersen --- net/wireless/util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/wireless/util.c b/net/wireless/util.c index 0675f51..5fb0249 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1157,7 +1157,9 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate) 5850, 6500, 7800, - 0, + /* some drivers report MCS 9 for 20MHz anyway. Clip to MCS 8 + * bitrate as it's closer than 0 */ + 7800, }, { 1350, 2700, -- 2.1.4
[PATCH] mac80211: make mpath path fixing more robust
A fixed mpath was not quite being treated as such: 1) if a PERR frame was received, a fixed mpath was deactivated. 2) queued path discovery for fixed mpath was potentially being considered, changing mpath state. 3) other mpath flags were potentially being inherited when fixing the mpath. Just assign PATH_FIXED and SN_VALID. This solves several issues when fixing a mesh path in one direction. The reverse direction mpath should probably also be fixed, or root announcements at least be enabled. Signed-off-by: Thomas Pedersen --- net/mac80211/mesh_hwmp.c| 3 ++- net/mac80211/mesh_pathtbl.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index fa7d37c..b747c96 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -757,6 +757,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, sta = next_hop_deref_protected(mpath); if (mpath->flags & MESH_PATH_ACTIVE && ether_addr_equal(ta, sta->sta.addr) && + !(mpath->flags & MESH_PATH_FIXED) && (!(mpath->flags & MESH_PATH_SN_VALID) || SN_GT(target_sn, mpath->sn) || target_sn == 0)) { mpath->flags &= ~MESH_PATH_ACTIVE; @@ -1023,7 +1024,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) goto enddiscovery; spin_lock_bh(&mpath->state_lock); - if (mpath->flags & MESH_PATH_DELETED) { + if (mpath->flags & (MESH_PATH_DELETED | MESH_PATH_FIXED)) { spin_unlock_bh(&mpath->state_lock); goto enddiscovery; } diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 6db2ddf..8e3d2d1 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -826,7 +826,7 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop) mpath->metric = 0; mpath->hop_count = 0; mpath->exp_time = 0; - mpath->flags |= MESH_PATH_FIXED; + mpath->flags = (MESH_PATH_FIXED | MESH_PATH_SN_VALID); mesh_path_activate(mpath); spin_unlock_bh(&mpath->state_lock); mesh_path_tx_pending(mpath); -- 2.1.4
Re: [PATCH] mac80211: Send peering open frame again if beacon from listen state peer is received
Hi Kenzoh, Looks like your email is part HTML. Please submit using git-send-email. Your patch looks ok, just a small comment below. On 11/12/2014 08:27 PM, Nishikawa, Kenzoh via Devel wrote: > net/mac80211/mesh_plink.c |6 ++ > 1 file changed, 6 insertions(+) > diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c > index 32c7bd0..5ca4306 100644 > --- a/net/mac80211/mesh_plink.c > +++ b/net/mac80211/mesh_plink.c > > @@ -524,6 +524,12 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, > sdata->u.mesh.mshcfg.auto_open_plinks && > rssi_threshold_check(sta, sdata)) >changed = mesh_plink_open(sta); > +else if (sta->plink_state == NL80211_PLINK_LISTEN && You should probably check for (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) as well like in mesh_sta_info_alloc(). > + sdata->u.mesh.user_mpm) > + cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, > + elems->ie_start, > + elems->total_len, > + GFP_KERNEL); > ieee80211_mps_frame_release(sta, elems); > out: -- thomas -- 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: Mesh Support in brcmsmac
On Tue, Sep 9, 2014, at 06:26 AM, John W. Linville wrote: > On Tue, Sep 09, 2014 at 12:28:54PM +0200, Arend van Spriel wrote: > > + linux-wireless > > > > On 09/09/14 12:22, chandrika parimoo wrote: > > >Hello, > > > > > >I have broadcom bcm4313 card and am using brcmsmac driver which does not > > >have mesh support currently. > > >I wanted to know if there is a workaround for it? > > > > No workaround. I am not familiar with wireless mesh networking. I suppose > > there are people on the linux-wireless mailing list who know what is needed > > from a mac80211 driver (like brcmsmac) to enable mesh networking. > > The main things is the beacons, no? Yeah mainly beacons, but also 4addr frames and FIF_OTHER_BSS filter. -- thomas -- 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