1e705c121SKalle Valo /******************************************************************************
2e705c121SKalle Valo  *
3e705c121SKalle Valo  * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
40c4cb731SJohannes Berg  * Copyright(C) 2016 Intel Deutschland GmbH
5e705c121SKalle Valo  *
6e705c121SKalle Valo  * This program is free software; you can redistribute it and/or modify it
7e705c121SKalle Valo  * under the terms of version 2 of the GNU General Public License as
8e705c121SKalle Valo  * published by the Free Software Foundation.
9e705c121SKalle Valo  *
10e705c121SKalle Valo  * This program is distributed in the hope that it will be useful, but WITHOUT
11e705c121SKalle Valo  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12e705c121SKalle Valo  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13e705c121SKalle Valo  * more details.
14e705c121SKalle Valo  *
15e705c121SKalle Valo  * You should have received a copy of the GNU General Public License along with
16e705c121SKalle Valo  * this program; if not, write to the Free Software Foundation, Inc.,
17e705c121SKalle Valo  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18e705c121SKalle Valo  *
19e705c121SKalle Valo  * The full GNU General Public License is included in this distribution in the
20e705c121SKalle Valo  * file called LICENSE.
21e705c121SKalle Valo  *
22e705c121SKalle Valo  * Contact Information:
23cb2f8277SEmmanuel Grumbach  *  Intel Linux Wireless <linuxwifi@intel.com>
24e705c121SKalle Valo  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25e705c121SKalle Valo  *
26e705c121SKalle Valo  *****************************************************************************/
27e705c121SKalle Valo 
28e705c121SKalle Valo #ifndef __IWLWIFI_DEVICE_TRACE
29e705c121SKalle Valo #include <linux/skbuff.h>
30e705c121SKalle Valo #include <linux/ieee80211.h>
31e705c121SKalle Valo #include <net/cfg80211.h>
32e705c121SKalle Valo #include "iwl-trans.h"
33e705c121SKalle Valo #if !defined(__IWLWIFI_DEVICE_TRACE)
34e705c121SKalle Valo static inline bool iwl_trace_data(struct sk_buff *skb)
35e705c121SKalle Valo {
36e705c121SKalle Valo 	struct ieee80211_hdr *hdr = (void *)skb->data;
370c4cb731SJohannes Berg 	__le16 fc = hdr->frame_control;
380c4cb731SJohannes Berg 	int offs = 24; /* start with normal header length */
39e705c121SKalle Valo 
400c4cb731SJohannes Berg 	if (!ieee80211_is_data(fc))
41e705c121SKalle Valo 		return false;
420c4cb731SJohannes Berg 
430c4cb731SJohannes Berg 	/* Try to determine if the frame is EAPOL. This might have false
440c4cb731SJohannes Berg 	 * positives (if there's no RFC 1042 header and we compare to some
450c4cb731SJohannes Berg 	 * payload instead) but since we're only doing tracing that's not
460c4cb731SJohannes Berg 	 * a problem.
470c4cb731SJohannes Berg 	 */
480c4cb731SJohannes Berg 
490c4cb731SJohannes Berg 	if (ieee80211_has_a4(fc))
500c4cb731SJohannes Berg 		offs += 6;
510c4cb731SJohannes Berg 	if (ieee80211_is_data_qos(fc))
520c4cb731SJohannes Berg 		offs += 2;
530c4cb731SJohannes Berg 	/* don't account for crypto - these are unencrypted */
540c4cb731SJohannes Berg 
550c4cb731SJohannes Berg 	/* also account for the RFC 1042 header, of course */
560c4cb731SJohannes Berg 	offs += 6;
570c4cb731SJohannes Berg 
580c4cb731SJohannes Berg 	return skb->len > offs + 2 &&
590c4cb731SJohannes Berg 	       *(__be16 *)(skb->data + offs) == cpu_to_be16(ETH_P_PAE);
60e705c121SKalle Valo }
61e705c121SKalle Valo 
62e705c121SKalle Valo static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
63e705c121SKalle Valo 				      void *rxbuf, size_t len)
64e705c121SKalle Valo {
65e705c121SKalle Valo 	struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32));
66e705c121SKalle Valo 	struct ieee80211_hdr *hdr;
67e705c121SKalle Valo 
68e705c121SKalle Valo 	if (cmd->cmd != trans->rx_mpdu_cmd)
69e705c121SKalle Valo 		return len;
70e705c121SKalle Valo 
71e705c121SKalle Valo 	hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) +
72e705c121SKalle Valo 			trans->rx_mpdu_cmd_hdr_size);
73e705c121SKalle Valo 	if (!ieee80211_is_data(hdr->frame_control))
74e705c121SKalle Valo 		return len;
75e705c121SKalle Valo 	/* maybe try to identify EAPOL frames? */
76e705c121SKalle Valo 	return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size +
77e705c121SKalle Valo 		ieee80211_hdrlen(hdr->frame_control);
78e705c121SKalle Valo }
79e705c121SKalle Valo #endif
80e705c121SKalle Valo 
81e705c121SKalle Valo #define __IWLWIFI_DEVICE_TRACE
82e705c121SKalle Valo 
83e705c121SKalle Valo #include <linux/tracepoint.h>
84e705c121SKalle Valo #include <linux/device.h>
85e705c121SKalle Valo #include "iwl-trans.h"
86e705c121SKalle Valo 
87e705c121SKalle Valo 
88e705c121SKalle Valo #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
89e705c121SKalle Valo #undef TRACE_EVENT
90e705c121SKalle Valo #define TRACE_EVENT(name, proto, ...) \
91e705c121SKalle Valo static inline void trace_ ## name(proto) {}
92e705c121SKalle Valo #undef DECLARE_EVENT_CLASS
93e705c121SKalle Valo #define DECLARE_EVENT_CLASS(...)
94e705c121SKalle Valo #undef DEFINE_EVENT
95e705c121SKalle Valo #define DEFINE_EVENT(evt_class, name, proto, ...) \
96e705c121SKalle Valo static inline void trace_ ## name(proto) {}
97e705c121SKalle Valo #endif
98e705c121SKalle Valo 
99e705c121SKalle Valo #define DEV_ENTRY	__string(dev, dev_name(dev))
100e705c121SKalle Valo #define DEV_ASSIGN	__assign_str(dev, dev_name(dev))
101e705c121SKalle Valo 
102e705c121SKalle Valo #include "iwl-devtrace-io.h"
103e705c121SKalle Valo #include "iwl-devtrace-ucode.h"
104e705c121SKalle Valo #include "iwl-devtrace-msg.h"
105e705c121SKalle Valo #include "iwl-devtrace-data.h"
106e705c121SKalle Valo #include "iwl-devtrace-iwlwifi.h"
107e705c121SKalle Valo 
108e705c121SKalle Valo #endif /* __IWLWIFI_DEVICE_TRACE */
109