|
@@ -838,6 +838,16 @@ enum ieee80211_vht_opmode_bits {
|
|
|
|
|
|
#define WLAN_SA_QUERY_TR_ID_LEN 2
|
|
|
|
|
|
+/**
|
|
|
+ * struct ieee80211_tpc_report_ie
|
|
|
+ *
|
|
|
+ * This structure refers to "TPC Report element"
|
|
|
+ */
|
|
|
+struct ieee80211_tpc_report_ie {
|
|
|
+ u8 tx_power;
|
|
|
+ u8 link_margin;
|
|
|
+} __packed;
|
|
|
+
|
|
|
struct ieee80211_mgmt {
|
|
|
__le16 frame_control;
|
|
|
__le16 duration;
|
|
@@ -973,6 +983,13 @@ struct ieee80211_mgmt {
|
|
|
u8 action_code;
|
|
|
u8 operating_mode;
|
|
|
} __packed vht_opmode_notif;
|
|
|
+ struct {
|
|
|
+ u8 action_code;
|
|
|
+ u8 dialog_token;
|
|
|
+ u8 tpc_elem_id;
|
|
|
+ u8 tpc_elem_length;
|
|
|
+ struct ieee80211_tpc_report_ie tpc;
|
|
|
+ } __packed tpc_report;
|
|
|
} u;
|
|
|
} __packed action;
|
|
|
} u;
|
|
@@ -1865,6 +1882,7 @@ enum ieee80211_category {
|
|
|
WLAN_CATEGORY_DLS = 2,
|
|
|
WLAN_CATEGORY_BACK = 3,
|
|
|
WLAN_CATEGORY_PUBLIC = 4,
|
|
|
+ WLAN_CATEGORY_RADIO_MEASUREMENT = 5,
|
|
|
WLAN_CATEGORY_HT = 7,
|
|
|
WLAN_CATEGORY_SA_QUERY = 8,
|
|
|
WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
|
|
@@ -2378,4 +2396,51 @@ static inline bool ieee80211_check_tim(const struct ieee80211_tim_ie *tim,
|
|
|
#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024))
|
|
|
#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x))
|
|
|
|
|
|
+/**
|
|
|
+ * ieee80211_action_contains_tpc - checks if the frame contains TPC element
|
|
|
+ * @skb: the skb containing the frame, length will be checked
|
|
|
+ *
|
|
|
+ * This function checks if it's either TPC report action frame or Link
|
|
|
+ * Measurement report action frame as defined in IEEE Std. 802.11-2012 8.5.2.5
|
|
|
+ * and 8.5.7.5 accordingly.
|
|
|
+ */
|
|
|
+static inline bool ieee80211_action_contains_tpc(struct sk_buff *skb)
|
|
|
+{
|
|
|
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
|
|
+
|
|
|
+ if (!ieee80211_is_action(mgmt->frame_control))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE +
|
|
|
+ sizeof(mgmt->u.action.u.tpc_report))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * TPC report - check that:
|
|
|
+ * category = 0 (Spectrum Management) or 5 (Radio Measurement)
|
|
|
+ * spectrum management action = 3 (TPC/Link Measurement report)
|
|
|
+ * TPC report EID = 35
|
|
|
+ * TPC report element length = 2
|
|
|
+ *
|
|
|
+ * The spectrum management's tpc_report struct is used here both for
|
|
|
+ * parsing tpc_report and radio measurement's link measurement report
|
|
|
+ * frame, since the relevant part is identical in both frames.
|
|
|
+ */
|
|
|
+ if (mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT &&
|
|
|
+ mgmt->u.action.category != WLAN_CATEGORY_RADIO_MEASUREMENT)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ /* both spectrum mgmt and link measurement have same action code */
|
|
|
+ if (mgmt->u.action.u.tpc_report.action_code !=
|
|
|
+ WLAN_ACTION_SPCT_TPC_RPRT)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (mgmt->u.action.u.tpc_report.tpc_elem_id != WLAN_EID_TPC_REPORT ||
|
|
|
+ mgmt->u.action.u.tpc_report.tpc_elem_length !=
|
|
|
+ sizeof(struct ieee80211_tpc_report_ie))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
#endif /* LINUX_IEEE80211_H */
|