diff options
Diffstat (limited to 'net/mac80211/status.c')
-rw-r--r-- | net/mac80211/status.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 52a152b01b06..1ee85c402439 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/export.h> | 12 | #include <linux/export.h> |
13 | #include <linux/etherdevice.h> | 13 | #include <linux/etherdevice.h> |
14 | #include <linux/time.h> | ||
14 | #include <net/mac80211.h> | 15 | #include <net/mac80211.h> |
15 | #include <asm/unaligned.h> | 16 | #include <asm/unaligned.h> |
16 | #include "ieee80211_i.h" | 17 | #include "ieee80211_i.h" |
@@ -463,6 +464,77 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local, | |||
463 | } | 464 | } |
464 | 465 | ||
465 | /* | 466 | /* |
467 | * Measure Tx frame completion and removal time for Tx latency statistics | ||
468 | * calculation. A single Tx frame latency should be measured from when it | ||
469 | * is entering the Kernel until we receive Tx complete confirmation indication | ||
470 | * and remove the skb. | ||
471 | */ | ||
472 | static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local, | ||
473 | struct sk_buff *skb, | ||
474 | struct sta_info *sta, | ||
475 | struct ieee80211_hdr *hdr) | ||
476 | { | ||
477 | ktime_t skb_dprt; | ||
478 | struct timespec dprt_time; | ||
479 | u32 msrmnt; | ||
480 | u16 tid; | ||
481 | u8 *qc; | ||
482 | int i, bin_range_count, bin_count; | ||
483 | u32 *bin_ranges; | ||
484 | __le16 fc; | ||
485 | struct ieee80211_tx_latency_stat *tx_lat; | ||
486 | struct ieee80211_tx_latency_bin_ranges *tx_latency; | ||
487 | ktime_t skb_arv = skb->tstamp; | ||
488 | |||
489 | tx_latency = rcu_dereference(local->tx_latency); | ||
490 | |||
491 | /* assert Tx latency stats are enabled & frame arrived when enabled */ | ||
492 | if (!tx_latency || !ktime_to_ns(skb_arv)) | ||
493 | return; | ||
494 | |||
495 | fc = hdr->frame_control; | ||
496 | |||
497 | if (!ieee80211_is_data(fc)) /* make sure it is a data frame */ | ||
498 | return; | ||
499 | |||
500 | /* get frame tid */ | ||
501 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
502 | qc = ieee80211_get_qos_ctl(hdr); | ||
503 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
504 | } else { | ||
505 | tid = 0; | ||
506 | } | ||
507 | |||
508 | tx_lat = &sta->tx_lat[tid]; | ||
509 | |||
510 | ktime_get_ts(&dprt_time); /* time stamp completion time */ | ||
511 | skb_dprt = ktime_set(dprt_time.tv_sec, dprt_time.tv_nsec); | ||
512 | msrmnt = ktime_to_ms(ktime_sub(skb_dprt, skb_arv)); | ||
513 | |||
514 | if (tx_lat->max < msrmnt) /* update stats */ | ||
515 | tx_lat->max = msrmnt; | ||
516 | tx_lat->counter++; | ||
517 | tx_lat->sum += msrmnt; | ||
518 | |||
519 | if (!tx_lat->bins) /* bins not activated */ | ||
520 | return; | ||
521 | |||
522 | /* count how many Tx frames transmitted with the appropriate latency */ | ||
523 | bin_range_count = tx_latency->n_ranges; | ||
524 | bin_ranges = tx_latency->ranges; | ||
525 | bin_count = tx_lat->bin_count; | ||
526 | |||
527 | for (i = 0; i < bin_range_count; i++) { | ||
528 | if (msrmnt <= bin_ranges[i]) { | ||
529 | tx_lat->bins[i]++; | ||
530 | break; | ||
531 | } | ||
532 | } | ||
533 | if (i == bin_range_count) /* msrmnt is bigger than the biggest range */ | ||
534 | tx_lat->bins[i]++; | ||
535 | } | ||
536 | |||
537 | /* | ||
466 | * Use a static threshold for now, best value to be determined | 538 | * Use a static threshold for now, best value to be determined |
467 | * by testing ... | 539 | * by testing ... |
468 | * Should it depend on: | 540 | * Should it depend on: |
@@ -620,6 +692,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
620 | 692 | ||
621 | if (acked) | 693 | if (acked) |
622 | sta->last_ack_signal = info->status.ack_signal; | 694 | sta->last_ack_signal = info->status.ack_signal; |
695 | |||
696 | /* | ||
697 | * Measure frame removal for tx latency | ||
698 | * statistics calculation | ||
699 | */ | ||
700 | ieee80211_tx_latency_end_msrmnt(local, skb, sta, hdr); | ||
623 | } | 701 | } |
624 | 702 | ||
625 | rcu_read_unlock(); | 703 | rcu_read_unlock(); |