mac80211: add fast-rx path
[cascardo/linux.git] / net / mac80211 / sta_info.h
index 053f5c4..a0a0660 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2002-2005, Devicescape Software, Inc.
  * Copyright 2013-2014  Intel Mobile Communications GmbH
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015-2016 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -18,6 +18,7 @@
 #include <linux/average.h>
 #include <linux/etherdevice.h>
 #include <linux/rhashtable.h>
+#include <linux/u64_stats_sync.h>
 #include "key.h"
 
 /**
@@ -69,6 +70,8 @@
  * @WLAN_STA_MPSP_RECIPIENT: local STA is recipient of a MPSP.
  * @WLAN_STA_PS_DELIVER: station woke up, but we're still blocking TX
  *     until pending frames are delivered
+ *
+ * @NUM_WLAN_STA_FLAGS: number of defined flags
  */
 enum ieee80211_sta_info_flags {
        WLAN_STA_AUTH,
@@ -97,6 +100,8 @@ enum ieee80211_sta_info_flags {
        WLAN_STA_MPSP_OWNER,
        WLAN_STA_MPSP_RECIPIENT,
        WLAN_STA_PS_DELIVER,
+
+       NUM_WLAN_STA_FLAGS,
 };
 
 #define ADDBA_RESP_INTERVAL HZ
@@ -280,6 +285,38 @@ struct ieee80211_fast_tx {
        struct rcu_head rcu_head;
 };
 
+/**
+ * struct ieee80211_fast_rx - RX fastpath information
+ * @dev: netdevice for reporting the SKB
+ * @vif_type: (P2P-less) interface type of the original sdata (sdata->vif.type)
+ * @vif_addr: interface address
+ * @rfc1042_hdr: copy of the RFC 1042 SNAP header (to have in cache)
+ * @control_port_protocol: control port protocol copied from sdata
+ * @expected_ds_bits: from/to DS bits expected
+ * @icv_len: length of the MIC if present
+ * @key: bool indicating encryption is expected (key is set)
+ * @sta_notify: notify the MLME code (once)
+ * @internal_forward: forward froms internally on AP/VLAN type interfaces
+ * @da_offs: offset of the DA in the header (for header conversion)
+ * @sa_offs: offset of the SA in the header (for header conversion)
+ * @rcu_head: RCU head for freeing this structure
+ */
+struct ieee80211_fast_rx {
+       struct net_device *dev;
+       enum nl80211_iftype vif_type;
+       u8 vif_addr[ETH_ALEN] __aligned(2);
+       u8 rfc1042_hdr[6] __aligned(2);
+       __be16 control_port_protocol;
+       __le16 expected_ds_bits;
+       u8 icv_len;
+       u8 key:1,
+          sta_notify:1,
+          internal_forward:1;
+       u8 da_offs, sa_offs;
+
+       struct rcu_head rcu_head;
+};
+
 /**
  * struct mesh_sta - mesh STA information
  * @plink_lock: serialize access to plink fields
@@ -371,7 +408,7 @@ DECLARE_EWMA(signal, 1024, 8)
  * @ampdu_mlme: A-MPDU state machine state
  * @timer_to_tid: identity mapping to ID timers
  * @mesh: mesh STA information
- * @debugfs: debug filesystem info
+ * @debugfs_dir: debug filesystem directory dentry
  * @dead: set to true when sta is unlinked
  * @removed: set to true when sta is being removed from sta_list
  * @uploaded: set to true when sta is uploaded to the driver
@@ -386,6 +423,7 @@ DECLARE_EWMA(signal, 1024, 8)
  * @cipher_scheme: optional cipher scheme for this station
  * @reserved_tid: reserved TID (if any, otherwise IEEE80211_TID_UNRESERVED)
  * @fast_tx: TX fastpath information
+ * @fast_rx: RX fastpath information
  * @tdls_chandef: a TDLS peer can have a wider chandef that is compatible to
  *     the BSS one.
  * @tx_stats: TX statistics
@@ -409,6 +447,7 @@ struct sta_info {
        spinlock_t lock;
 
        struct ieee80211_fast_tx __rcu *fast_tx;
+       struct ieee80211_fast_rx __rcu *fast_rx;
 
 #ifdef CONFIG_MAC80211_MESH
        struct mesh_sta *mesh;
@@ -440,22 +479,23 @@ struct sta_info {
        /* Updated from RX path only, no locking requirements */
        struct {
                unsigned long packets;
-               u64 bytes;
                unsigned long last_rx;
                unsigned long num_duplicates;
                unsigned long fragments;
                unsigned long dropped;
                int last_signal;
-               struct ewma_signal avg_signal;
                u8 chains;
                s8 chain_signal_last[IEEE80211_MAX_CHAINS];
-               struct ewma_signal chain_signal_avg[IEEE80211_MAX_CHAINS];
-               int last_rate_idx;
-               u32 last_rate_flag;
-               u32 last_rate_vht_flag;
-               u8 last_rate_vht_nss;
+               u16 last_rate;
+
+               struct u64_stats_sync syncp;
+               u64 bytes;
                u64 msdu[IEEE80211_NUM_TIDS + 1];
        } rx_stats;
+       struct {
+               struct ewma_signal signal;
+               struct ewma_signal chain_signal[IEEE80211_MAX_CHAINS];
+       } rx_stats_avg;
 
        /* Plus 1 for non-QoS frames */
        __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
@@ -468,6 +508,7 @@ struct sta_info {
                unsigned long last_tdls_pkt_time;
                u64 msdu_retries[IEEE80211_NUM_TIDS + 1];
                u64 msdu_failed[IEEE80211_NUM_TIDS + 1];
+               unsigned long last_ack;
        } status_stats;
 
        /* Updated from TX path only, no locking requirements */
@@ -486,10 +527,7 @@ struct sta_info {
        u8 timer_to_tid[IEEE80211_NUM_TIDS];
 
 #ifdef CONFIG_MAC80211_DEBUGFS
-       struct sta_info_debugfsdentries {
-               struct dentry *dir;
-               bool add_has_run;
-       } debugfs;
+       struct dentry *debugfs_dir;
 #endif
 
        enum ieee80211_sta_rx_bandwidth cur_max_bandwidth;
@@ -677,4 +715,44 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
 void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
 void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta);
 
+unsigned long ieee80211_sta_last_active(struct sta_info *sta);
+
+#define STA_STATS_RATE_INVALID         0
+#define STA_STATS_RATE_VHT             0x8000
+#define STA_STATS_RATE_HT              0x4000
+#define STA_STATS_RATE_LEGACY          0x2000
+#define STA_STATS_RATE_SGI             0x1000
+#define STA_STATS_RATE_BW_SHIFT                9
+#define STA_STATS_RATE_BW_MASK         (0x7 << STA_STATS_RATE_BW_SHIFT)
+
+static inline u16 sta_stats_encode_rate(struct ieee80211_rx_status *s)
+{
+       u16 r = s->rate_idx;
+
+       if (s->vht_flag & RX_VHT_FLAG_80MHZ)
+               r |= RATE_INFO_BW_80 << STA_STATS_RATE_BW_SHIFT;
+       else if (s->vht_flag & RX_VHT_FLAG_160MHZ)
+               r |= RATE_INFO_BW_160 << STA_STATS_RATE_BW_SHIFT;
+       else if (s->flag & RX_FLAG_40MHZ)
+               r |= RATE_INFO_BW_40 << STA_STATS_RATE_BW_SHIFT;
+       else if (s->flag & RX_FLAG_10MHZ)
+               r |= RATE_INFO_BW_10 << STA_STATS_RATE_BW_SHIFT;
+       else if (s->flag & RX_FLAG_5MHZ)
+               r |= RATE_INFO_BW_5 << STA_STATS_RATE_BW_SHIFT;
+       else
+               r |= RATE_INFO_BW_20 << STA_STATS_RATE_BW_SHIFT;
+
+       if (s->flag & RX_FLAG_SHORT_GI)
+               r |= STA_STATS_RATE_SGI;
+
+       if (s->flag & RX_FLAG_VHT)
+               r |= STA_STATS_RATE_VHT | (s->vht_nss << 4);
+       else if (s->flag & RX_FLAG_HT)
+               r |= STA_STATS_RATE_HT;
+       else
+               r |= STA_STATS_RATE_LEGACY | (s->band << 4);
+
+       return r;
+}
+
 #endif /* STA_INFO_H */