Skip to content

Commit 354d381

Browse files
Pedersen, Thomasjmberg-intel
authored andcommitted
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 <[email protected]> Signed-off-by: Johannes Berg <[email protected]>
1 parent 3ff23cd commit 354d381

File tree

6 files changed

+68
-6
lines changed

6 files changed

+68
-6
lines changed

include/net/mac80211.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,6 +3169,12 @@ enum ieee80211_reconfig_type {
31693169
* required function.
31703170
* The callback can sleep.
31713171
*
3172+
* @offset_tsf: Offset the TSF timer by the specified value in the
3173+
* firmware/hardware. Preferred to set_tsf as it avoids delay between
3174+
* calling set_tsf() and hardware getting programmed, which will show up
3175+
* as TSF delay. Is not a required function.
3176+
* The callback can sleep.
3177+
*
31723178
* @reset_tsf: Reset the TSF timer and allow firmware/hardware to synchronize
31733179
* with other STAs in the IBSS. This is only used in IBSS mode. This
31743180
* function is optional if the firmware/hardware takes full care of
@@ -3549,6 +3555,8 @@ struct ieee80211_ops {
35493555
u64 (*get_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
35503556
void (*set_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
35513557
u64 tsf);
3558+
void (*offset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3559+
s64 offset);
35523560
void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
35533561
int (*tx_last_beacon)(struct ieee80211_hw *hw);
35543562
int (*ampdu_action)(struct ieee80211_hw *hw,

net/mac80211/debugfs_netdev.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -556,9 +556,15 @@ static ssize_t ieee80211_if_parse_tsf(
556556
ret = kstrtoull(buf, 10, &tsf);
557557
if (ret < 0)
558558
return ret;
559-
if (tsf_is_delta)
560-
tsf = drv_get_tsf(local, sdata) + tsf_is_delta * tsf;
561-
if (local->ops->set_tsf) {
559+
if (tsf_is_delta && local->ops->offset_tsf) {
560+
drv_offset_tsf(local, sdata, tsf_is_delta * 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;
562568
drv_set_tsf(local, sdata, tsf);
563569
wiphy_info(local->hw.wiphy,
564570
"debugfs set TSF to %#018llx\n", tsf);

net/mac80211/driver-ops.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,21 @@ void drv_set_tsf(struct ieee80211_local *local,
215215
trace_drv_return_void(local);
216216
}
217217

218+
void 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+
218233
void drv_reset_tsf(struct ieee80211_local *local,
219234
struct ieee80211_sub_if_data *sdata)
220235
{

net/mac80211/driver-ops.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,9 @@ u64 drv_get_tsf(struct ieee80211_local *local,
569569
void drv_set_tsf(struct ieee80211_local *local,
570570
struct ieee80211_sub_if_data *sdata,
571571
u64 tsf);
572+
void drv_offset_tsf(struct ieee80211_local *local,
573+
struct ieee80211_sub_if_data *sdata,
574+
s64 offset);
572575
void drv_reset_tsf(struct ieee80211_local *local,
573576
struct ieee80211_sub_if_data *sdata);
574577

net/mac80211/mesh_sync.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,13 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
7070
}
7171
spin_unlock_bh(&ifmsh->sync_offset_lock);
7272

73-
tsf = drv_get_tsf(local, sdata);
74-
if (tsf != -1ULL)
75-
drv_set_tsf(local, sdata, tsf + tsfdelta);
73+
if (local->ops->offset_tsf) {
74+
drv_offset_tsf(local, sdata, tsfdelta);
75+
} else {
76+
tsf = drv_get_tsf(local, sdata);
77+
if (tsf != -1ULL)
78+
drv_set_tsf(local, sdata, tsf + tsfdelta);
79+
}
7680
}
7781

7882
static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,

net/mac80211/trace.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,32 @@ TRACE_EVENT(drv_set_tsf,
984984
)
985985
);
986986

987+
TRACE_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+
9871013
DEFINE_EVENT(local_sdata_evt, drv_reset_tsf,
9881014
TP_PROTO(struct ieee80211_local *local,
9891015
struct ieee80211_sub_if_data *sdata),

0 commit comments

Comments
 (0)