summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPedersen, Thomas <twp@qca.qualcomm.com>2016-09-28 19:56:28 -0400
committerJohannes Berg <johannes.berg@intel.com>2016-09-30 07:45:44 -0400
commit354d381baf1126c45d03b5c0d87d22caf938b86b (patch)
treeef838588ad6a1f1c4b51e347794e5c5085a67cf1 /net
parent3ff23cd5654b9c8f4d567caa73439b4c39fbeaae (diff)
mac80211: add offset_tsf driver op and use it for mesh
This allows the mesh sync (and debugfs) code to make incremental TSF adjustments, avoiding any uncertainty introduced by delay in programming absolute TSF. Signed-off-by: Thomas Pedersen <twp@qca.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/debugfs_netdev.c12
-rw-r--r--net/mac80211/driver-ops.c15
-rw-r--r--net/mac80211/driver-ops.h3
-rw-r--r--net/mac80211/mesh_sync.c10
-rw-r--r--net/mac80211/trace.h26
5 files changed, 60 insertions, 6 deletions
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 5d35c0f37bb7..bcec1240f41d 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -556,9 +556,15 @@ static ssize_t ieee80211_if_parse_tsf(
556 ret = kstrtoull(buf, 10, &tsf); 556 ret = kstrtoull(buf, 10, &tsf);
557 if (ret < 0) 557 if (ret < 0)
558 return ret; 558 return ret;
559 if (tsf_is_delta) 559 if (tsf_is_delta && local->ops->offset_tsf) {
560 tsf = drv_get_tsf(local, sdata) + tsf_is_delta * tsf; 560 drv_offset_tsf(local, sdata, tsf_is_delta * tsf);
561 if (local->ops->set_tsf) { 561 wiphy_info(local->hw.wiphy,
562 "debugfs offset TSF by %018lld\n",
563 tsf_is_delta * tsf);
564 } else if (local->ops->set_tsf) {
565 if (tsf_is_delta)
566 tsf = drv_get_tsf(local, sdata) +
567 tsf_is_delta * tsf;
562 drv_set_tsf(local, sdata, tsf); 568 drv_set_tsf(local, sdata, tsf);
563 wiphy_info(local->hw.wiphy, 569 wiphy_info(local->hw.wiphy,
564 "debugfs set TSF to %#018llx\n", tsf); 570 "debugfs set TSF to %#018llx\n", tsf);
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index c701b6438bd9..bb886e7db47f 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,
215 trace_drv_return_void(local); 215 trace_drv_return_void(local);
216} 216}
217 217
218void drv_offset_tsf(struct ieee80211_local *local,
219 struct ieee80211_sub_if_data *sdata,
220 s64 offset)
221{
222 might_sleep();
223
224 if (!check_sdata_in_driver(sdata))
225 return;
226
227 trace_drv_offset_tsf(local, sdata, offset);
228 if (local->ops->offset_tsf)
229 local->ops->offset_tsf(&local->hw, &sdata->vif, offset);
230 trace_drv_return_void(local);
231}
232
218void drv_reset_tsf(struct ieee80211_local *local, 233void drv_reset_tsf(struct ieee80211_local *local,
219 struct ieee80211_sub_if_data *sdata) 234 struct ieee80211_sub_if_data *sdata)
220{ 235{
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index dea92c33b2ca..09f77e4a8a79 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -569,6 +569,9 @@ u64 drv_get_tsf(struct ieee80211_local *local,
569void drv_set_tsf(struct ieee80211_local *local, 569void drv_set_tsf(struct ieee80211_local *local,
570 struct ieee80211_sub_if_data *sdata, 570 struct ieee80211_sub_if_data *sdata,
571 u64 tsf); 571 u64 tsf);
572void drv_offset_tsf(struct ieee80211_local *local,
573 struct ieee80211_sub_if_data *sdata,
574 s64 offset);
572void drv_reset_tsf(struct ieee80211_local *local, 575void drv_reset_tsf(struct ieee80211_local *local,
573 struct ieee80211_sub_if_data *sdata); 576 struct ieee80211_sub_if_data *sdata);
574 577
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index 64bc22ad9496..22ca43c500e4 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)
70 } 70 }
71 spin_unlock_bh(&ifmsh->sync_offset_lock); 71 spin_unlock_bh(&ifmsh->sync_offset_lock);
72 72
73 tsf = drv_get_tsf(local, sdata); 73 if (local->ops->offset_tsf) {
74 if (tsf != -1ULL) 74 drv_offset_tsf(local, sdata, tsfdelta);
75 drv_set_tsf(local, sdata, tsf + tsfdelta); 75 } else {
76 tsf = drv_get_tsf(local, sdata);
77 if (tsf != -1ULL)
78 drv_set_tsf(local, sdata, tsf + tsfdelta);
79 }
76} 80}
77 81
78static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, 82static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 37891fa67e9a..92a47afaa989 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -984,6 +984,32 @@ TRACE_EVENT(drv_set_tsf,
984 ) 984 )
985); 985);
986 986
987TRACE_EVENT(drv_offset_tsf,
988 TP_PROTO(struct ieee80211_local *local,
989 struct ieee80211_sub_if_data *sdata,
990 s64 offset),
991
992 TP_ARGS(local, sdata, offset),
993
994 TP_STRUCT__entry(
995 LOCAL_ENTRY
996 VIF_ENTRY
997 __field(s64, tsf_offset)
998 ),
999
1000 TP_fast_assign(
1001 LOCAL_ASSIGN;
1002 VIF_ASSIGN;
1003 __entry->tsf_offset = offset;
1004 ),
1005
1006 TP_printk(
1007 LOCAL_PR_FMT VIF_PR_FMT " tsf offset:%lld",
1008 LOCAL_PR_ARG, VIF_PR_ARG,
1009 (unsigned long long)__entry->tsf_offset
1010 )
1011);
1012
987DEFINE_EVENT(local_sdata_evt, drv_reset_tsf, 1013DEFINE_EVENT(local_sdata_evt, drv_reset_tsf,
988 TP_PROTO(struct ieee80211_local *local, 1014 TP_PROTO(struct ieee80211_local *local,
989 struct ieee80211_sub_if_data *sdata), 1015 struct ieee80211_sub_if_data *sdata),