xref: /openbmc/linux/include/linux/ieee802154.h (revision 57588c71)
11802d0beSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
24ca24acaSAlexander Aring /*
34ca24acaSAlexander Aring  * IEEE802.15.4-2003 specification
44ca24acaSAlexander Aring  *
54ca24acaSAlexander Aring  * Copyright (C) 2007, 2008 Siemens AG
64ca24acaSAlexander Aring  *
74ca24acaSAlexander Aring  * Written by:
84ca24acaSAlexander Aring  * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
94ca24acaSAlexander Aring  * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
104ca24acaSAlexander Aring  * Maxim Osipov <maxim.osipov@siemens.com>
114ca24acaSAlexander Aring  * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
124ca24acaSAlexander Aring  * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
134ca24acaSAlexander Aring  */
144ca24acaSAlexander Aring 
154ca24acaSAlexander Aring #ifndef LINUX_IEEE802154_H
164ca24acaSAlexander Aring #define LINUX_IEEE802154_H
174ca24acaSAlexander Aring 
18fa491001SAlexander Aring #include <linux/types.h>
1935d5a374SAlexander Aring #include <linux/random.h>
20fa491001SAlexander Aring 
214ca24acaSAlexander Aring #define IEEE802154_MTU			127
22306f7aa1SAlexander Aring #define IEEE802154_ACK_PSDU_LEN		5
23306f7aa1SAlexander Aring #define IEEE802154_MIN_PSDU_LEN		9
243f3c4bb5SAlexander Aring #define IEEE802154_FCS_LEN		2
2587a93e4eSAlexander Aring #define IEEE802154_MAX_AUTH_TAG_LEN	16
269cc577ddSAlexander Aring #define IEEE802154_FC_LEN		2
279cc577ddSAlexander Aring #define IEEE802154_SEQ_LEN		1
2887a93e4eSAlexander Aring 
2987a93e4eSAlexander Aring /*  General MAC frame format:
3087a93e4eSAlexander Aring  *  2 bytes: Frame Control
3187a93e4eSAlexander Aring  *  1 byte:  Sequence Number
3287a93e4eSAlexander Aring  * 20 bytes: Addressing fields
3387a93e4eSAlexander Aring  * 14 bytes: Auxiliary Security Header
3487a93e4eSAlexander Aring  */
3587a93e4eSAlexander Aring #define IEEE802154_MAX_HEADER_LEN	(2 + 1 + 20 + 14)
3687a93e4eSAlexander Aring #define IEEE802154_MIN_HEADER_LEN	(IEEE802154_ACK_PSDU_LEN - \
3787a93e4eSAlexander Aring 					 IEEE802154_FCS_LEN)
384ca24acaSAlexander Aring 
39702bf371SAlexander Aring #define IEEE802154_PAN_ID_BROADCAST	0xffff
409830c62aSAlexander Aring #define IEEE802154_ADDR_SHORT_BROADCAST	0xffff
419830c62aSAlexander Aring #define IEEE802154_ADDR_SHORT_UNSPEC	0xfffe
42702bf371SAlexander Aring 
431906bbbdSAlexander Aring #define IEEE802154_EXTENDED_ADDR_LEN	8
44118a5cf8SAlexander Aring #define IEEE802154_SHORT_ADDR_LEN	2
4519580cc1SAlexander Aring #define IEEE802154_PAN_ID_LEN		2
461906bbbdSAlexander Aring 
47ed3557c9SMiquel Raynal /* Duration in superframe order */
48ed3557c9SMiquel Raynal #define IEEE802154_MAX_SCAN_DURATION	14
49ed3557c9SMiquel Raynal #define IEEE802154_ACTIVE_SCAN_DURATION	15
50*57588c71SMiquel Raynal /* Superframe duration in slots */
51*57588c71SMiquel Raynal #define IEEE802154_SUPERFRAME_PERIOD	16
52*57588c71SMiquel Raynal /* Various periods expressed in symbols */
53*57588c71SMiquel Raynal #define IEEE802154_SLOT_PERIOD		60
5461f2dcbaSAlexander Aring #define IEEE802154_LIFS_PERIOD		40
5561f2dcbaSAlexander Aring #define IEEE802154_SIFS_PERIOD		12
563f3c4bb5SAlexander Aring #define IEEE802154_MAX_SIFS_FRAME_SIZE	18
5761f2dcbaSAlexander Aring 
58cb41c8ddSAlexander Aring #define IEEE802154_MAX_CHANNEL		26
59cb41c8ddSAlexander Aring #define IEEE802154_MAX_PAGE		31
60cb41c8ddSAlexander Aring 
614ca24acaSAlexander Aring #define IEEE802154_FC_TYPE_BEACON	0x0	/* Frame is beacon */
624ca24acaSAlexander Aring #define	IEEE802154_FC_TYPE_DATA		0x1	/* Frame is data */
634ca24acaSAlexander Aring #define IEEE802154_FC_TYPE_ACK		0x2	/* Frame is acknowledgment */
644ca24acaSAlexander Aring #define IEEE802154_FC_TYPE_MAC_CMD	0x3	/* Frame is MAC command */
654ca24acaSAlexander Aring 
664ca24acaSAlexander Aring #define IEEE802154_FC_TYPE_SHIFT		0
674ca24acaSAlexander Aring #define IEEE802154_FC_TYPE_MASK		((1 << 3) - 1)
684ca24acaSAlexander Aring #define IEEE802154_FC_TYPE(x)		((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT)
694ca24acaSAlexander Aring #define IEEE802154_FC_SET_TYPE(v, x)	do {	\
704ca24acaSAlexander Aring 	v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \
714ca24acaSAlexander Aring 	    (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \
724ca24acaSAlexander Aring 	} while (0)
734ca24acaSAlexander Aring 
744ca24acaSAlexander Aring #define IEEE802154_FC_SECEN_SHIFT	3
754ca24acaSAlexander Aring #define IEEE802154_FC_SECEN		(1 << IEEE802154_FC_SECEN_SHIFT)
764ca24acaSAlexander Aring #define IEEE802154_FC_FRPEND_SHIFT	4
774ca24acaSAlexander Aring #define IEEE802154_FC_FRPEND		(1 << IEEE802154_FC_FRPEND_SHIFT)
784ca24acaSAlexander Aring #define IEEE802154_FC_ACK_REQ_SHIFT	5
794ca24acaSAlexander Aring #define IEEE802154_FC_ACK_REQ		(1 << IEEE802154_FC_ACK_REQ_SHIFT)
804ca24acaSAlexander Aring #define IEEE802154_FC_INTRA_PAN_SHIFT	6
814ca24acaSAlexander Aring #define IEEE802154_FC_INTRA_PAN		(1 << IEEE802154_FC_INTRA_PAN_SHIFT)
824ca24acaSAlexander Aring 
834ca24acaSAlexander Aring #define IEEE802154_FC_SAMODE_SHIFT	14
844ca24acaSAlexander Aring #define IEEE802154_FC_SAMODE_MASK	(3 << IEEE802154_FC_SAMODE_SHIFT)
854ca24acaSAlexander Aring #define IEEE802154_FC_DAMODE_SHIFT	10
864ca24acaSAlexander Aring #define IEEE802154_FC_DAMODE_MASK	(3 << IEEE802154_FC_DAMODE_SHIFT)
874ca24acaSAlexander Aring 
884ca24acaSAlexander Aring #define IEEE802154_FC_VERSION_SHIFT	12
894ca24acaSAlexander Aring #define IEEE802154_FC_VERSION_MASK	(3 << IEEE802154_FC_VERSION_SHIFT)
904ca24acaSAlexander Aring #define IEEE802154_FC_VERSION(x)	((x & IEEE802154_FC_VERSION_MASK) >> IEEE802154_FC_VERSION_SHIFT)
914ca24acaSAlexander Aring 
924ca24acaSAlexander Aring #define IEEE802154_FC_SAMODE(x)		\
934ca24acaSAlexander Aring 	(((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT)
944ca24acaSAlexander Aring 
954ca24acaSAlexander Aring #define IEEE802154_FC_DAMODE(x)		\
964ca24acaSAlexander Aring 	(((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT)
974ca24acaSAlexander Aring 
984ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_MASK		7
994ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_SHIFT		0
1004ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL(x)		(x & IEEE802154_SCF_SECLEVEL_MASK)
1014ca24acaSAlexander Aring #define IEEE802154_SCF_KEY_ID_MODE_SHIFT	3
1024ca24acaSAlexander Aring #define IEEE802154_SCF_KEY_ID_MODE_MASK		(3 << IEEE802154_SCF_KEY_ID_MODE_SHIFT)
1034ca24acaSAlexander Aring #define IEEE802154_SCF_KEY_ID_MODE(x)		\
1044ca24acaSAlexander Aring 	((x & IEEE802154_SCF_KEY_ID_MODE_MASK) >> IEEE802154_SCF_KEY_ID_MODE_SHIFT)
1054ca24acaSAlexander Aring 
1064ca24acaSAlexander Aring #define IEEE802154_SCF_KEY_IMPLICIT		0
1074ca24acaSAlexander Aring #define IEEE802154_SCF_KEY_INDEX		1
1084ca24acaSAlexander Aring #define IEEE802154_SCF_KEY_SHORT_INDEX		2
1094ca24acaSAlexander Aring #define IEEE802154_SCF_KEY_HW_INDEX		3
1104ca24acaSAlexander Aring 
1114ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_NONE		0
1124ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_MIC32		1
1134ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_MIC64		2
1144ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_MIC128		3
1154ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_ENC		4
1164ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_ENC_MIC32	5
1174ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_ENC_MIC64	6
1184ca24acaSAlexander Aring #define IEEE802154_SCF_SECLEVEL_ENC_MIC128	7
1194ca24acaSAlexander Aring 
1204ca24acaSAlexander Aring /* MAC footer size */
1214ca24acaSAlexander Aring #define IEEE802154_MFR_SIZE	2 /* 2 octets */
1224ca24acaSAlexander Aring 
1234ca24acaSAlexander Aring /* MAC's Command Frames Identifiers */
1244ca24acaSAlexander Aring #define IEEE802154_CMD_ASSOCIATION_REQ		0x01
1254ca24acaSAlexander Aring #define IEEE802154_CMD_ASSOCIATION_RESP		0x02
1264ca24acaSAlexander Aring #define IEEE802154_CMD_DISASSOCIATION_NOTIFY	0x03
1274ca24acaSAlexander Aring #define IEEE802154_CMD_DATA_REQ			0x04
1284ca24acaSAlexander Aring #define IEEE802154_CMD_PANID_CONFLICT_NOTIFY	0x05
1294ca24acaSAlexander Aring #define IEEE802154_CMD_ORPHAN_NOTIFY		0x06
1304ca24acaSAlexander Aring #define IEEE802154_CMD_BEACON_REQ		0x07
1314ca24acaSAlexander Aring #define IEEE802154_CMD_COORD_REALIGN_NOTIFY	0x08
1324ca24acaSAlexander Aring #define IEEE802154_CMD_GTS_REQ			0x09
1334ca24acaSAlexander Aring 
1344ca24acaSAlexander Aring /*
1354ca24acaSAlexander Aring  * The return values of MAC operations
1364ca24acaSAlexander Aring  */
1374ca24acaSAlexander Aring enum {
1384ca24acaSAlexander Aring 	/*
1394ca24acaSAlexander Aring 	 * The requested operation was completed successfully.
1404ca24acaSAlexander Aring 	 * For a transmission request, this value indicates
1414ca24acaSAlexander Aring 	 * a successful transmission.
1424ca24acaSAlexander Aring 	 */
1434ca24acaSAlexander Aring 	IEEE802154_SUCCESS = 0x0,
144f06cfc23SMiquel Raynal 	/* The requested operation failed. */
145f06cfc23SMiquel Raynal 	IEEE802154_MAC_ERROR = 0x1,
146f06cfc23SMiquel Raynal 	/* The requested operation has been cancelled. */
147f06cfc23SMiquel Raynal 	IEEE802154_CANCELLED = 0x2,
148f06cfc23SMiquel Raynal 	/*
149f06cfc23SMiquel Raynal 	 * Device is ready to poll the coordinator for data in a non beacon
150f06cfc23SMiquel Raynal 	 * enabled PAN.
151f06cfc23SMiquel Raynal 	 */
152f06cfc23SMiquel Raynal 	IEEE802154_READY_FOR_POLL = 0x3,
153f06cfc23SMiquel Raynal 	/* Wrong frame counter. */
154f06cfc23SMiquel Raynal 	IEEE802154_COUNTER_ERROR = 0xdb,
155f06cfc23SMiquel Raynal 	/*
156f06cfc23SMiquel Raynal 	 * The frame does not conforms to the incoming key usage policy checking
157f06cfc23SMiquel Raynal 	 * procedure.
158f06cfc23SMiquel Raynal 	 */
159f06cfc23SMiquel Raynal 	IEEE802154_IMPROPER_KEY_TYPE = 0xdc,
160f06cfc23SMiquel Raynal 	/*
161f06cfc23SMiquel Raynal 	 * The frame does not conforms to the incoming security level usage
162f06cfc23SMiquel Raynal 	 * policy checking procedure.
163f06cfc23SMiquel Raynal 	 */
164f06cfc23SMiquel Raynal 	IEEE802154_IMPROPER_SECURITY_LEVEL = 0xdd,
165f06cfc23SMiquel Raynal 	/* Secured frame received with an empty Frame Version field. */
166f06cfc23SMiquel Raynal 	IEEE802154_UNSUPPORTED_LEGACY = 0xde,
167f06cfc23SMiquel Raynal 	/*
168f06cfc23SMiquel Raynal 	 * A secured frame is received or must be sent but security is not
169f06cfc23SMiquel Raynal 	 * enabled in the device. Or, the Auxiliary Security Header has security
170f06cfc23SMiquel Raynal 	 * level of zero in it.
171f06cfc23SMiquel Raynal 	 */
172f06cfc23SMiquel Raynal 	IEEE802154_UNSUPPORTED_SECURITY = 0xdf,
1734ca24acaSAlexander Aring 	/* The beacon was lost following a synchronization request. */
1745b0e5854SMiquel Raynal 	IEEE802154_BEACON_LOST = 0xe0,
1754ca24acaSAlexander Aring 	/*
1764ca24acaSAlexander Aring 	 * A transmission could not take place due to activity on the
1774ca24acaSAlexander Aring 	 * channel, i.e., the CSMA-CA mechanism has failed.
1784ca24acaSAlexander Aring 	 */
1795b0e5854SMiquel Raynal 	IEEE802154_CHANNEL_ACCESS_FAILURE = 0xe1,
1804ca24acaSAlexander Aring 	/* The GTS request has been denied by the PAN coordinator. */
1815b0e5854SMiquel Raynal 	IEEE802154_DENIED = 0xe2,
1824ca24acaSAlexander Aring 	/* The attempt to disable the transceiver has failed. */
1835b0e5854SMiquel Raynal 	IEEE802154_DISABLE_TRX_FAILURE = 0xe3,
1844ca24acaSAlexander Aring 	/*
1854ca24acaSAlexander Aring 	 * The received frame induces a failed security check according to
1864ca24acaSAlexander Aring 	 * the security suite.
1874ca24acaSAlexander Aring 	 */
1884ca24acaSAlexander Aring 	IEEE802154_FAILED_SECURITY_CHECK = 0xe4,
1894ca24acaSAlexander Aring 	/*
1904ca24acaSAlexander Aring 	 * The frame resulting from secure processing has a length that is
1914ca24acaSAlexander Aring 	 * greater than aMACMaxFrameSize.
1924ca24acaSAlexander Aring 	 */
1934ca24acaSAlexander Aring 	IEEE802154_FRAME_TOO_LONG = 0xe5,
1944ca24acaSAlexander Aring 	/*
1954ca24acaSAlexander Aring 	 * The requested GTS transmission failed because the specified GTS
1964ca24acaSAlexander Aring 	 * either did not have a transmit GTS direction or was not defined.
1974ca24acaSAlexander Aring 	 */
1984ca24acaSAlexander Aring 	IEEE802154_INVALID_GTS = 0xe6,
1994ca24acaSAlexander Aring 	/*
2004ca24acaSAlexander Aring 	 * A request to purge an MSDU from the transaction queue was made using
2014ca24acaSAlexander Aring 	 * an MSDU handle that was not found in the transaction table.
2024ca24acaSAlexander Aring 	 */
2034ca24acaSAlexander Aring 	IEEE802154_INVALID_HANDLE = 0xe7,
2044ca24acaSAlexander Aring 	/* A parameter in the primitive is out of the valid range.*/
2054ca24acaSAlexander Aring 	IEEE802154_INVALID_PARAMETER = 0xe8,
2064ca24acaSAlexander Aring 	/* No acknowledgment was received after aMaxFrameRetries. */
2074ca24acaSAlexander Aring 	IEEE802154_NO_ACK = 0xe9,
2084ca24acaSAlexander Aring 	/* A scan operation failed to find any network beacons.*/
2094ca24acaSAlexander Aring 	IEEE802154_NO_BEACON = 0xea,
2104ca24acaSAlexander Aring 	/* No response data were available following a request. */
2114ca24acaSAlexander Aring 	IEEE802154_NO_DATA = 0xeb,
2124ca24acaSAlexander Aring 	/* The operation failed because a short address was not allocated. */
2134ca24acaSAlexander Aring 	IEEE802154_NO_SHORT_ADDRESS = 0xec,
2144ca24acaSAlexander Aring 	/*
2154ca24acaSAlexander Aring 	 * A receiver enable request was unsuccessful because it could not be
2164ca24acaSAlexander Aring 	 * completed within the CAP.
2174ca24acaSAlexander Aring 	 */
2184ca24acaSAlexander Aring 	IEEE802154_OUT_OF_CAP = 0xed,
2194ca24acaSAlexander Aring 	/*
2204ca24acaSAlexander Aring 	 * A PAN identifier conflict has been detected and communicated to the
2214ca24acaSAlexander Aring 	 * PAN coordinator.
2224ca24acaSAlexander Aring 	 */
2235b0e5854SMiquel Raynal 	IEEE802154_PAN_ID_CONFLICT = 0xee,
2244ca24acaSAlexander Aring 	/* A coordinator realignment command has been received. */
2255b0e5854SMiquel Raynal 	IEEE802154_REALIGNMENT = 0xef,
2264ca24acaSAlexander Aring 	/* The transaction has expired and its information discarded. */
2274ca24acaSAlexander Aring 	IEEE802154_TRANSACTION_EXPIRED = 0xf0,
2284ca24acaSAlexander Aring 	/* There is no capacity to store the transaction. */
2294ca24acaSAlexander Aring 	IEEE802154_TRANSACTION_OVERFLOW = 0xf1,
2304ca24acaSAlexander Aring 	/*
2314ca24acaSAlexander Aring 	 * The transceiver was in the transmitter enabled state when the
2324ca24acaSAlexander Aring 	 * receiver was requested to be enabled.
2334ca24acaSAlexander Aring 	 */
2344ca24acaSAlexander Aring 	IEEE802154_TX_ACTIVE = 0xf2,
2354ca24acaSAlexander Aring 	/* The appropriate key is not available in the ACL. */
2364ca24acaSAlexander Aring 	IEEE802154_UNAVAILABLE_KEY = 0xf3,
2374ca24acaSAlexander Aring 	/*
2384ca24acaSAlexander Aring 	 * A SET/GET request was issued with the identifier of a PIB attribute
2394ca24acaSAlexander Aring 	 * that is not supported.
2404ca24acaSAlexander Aring 	 */
2415b0e5854SMiquel Raynal 	IEEE802154_UNSUPPORTED_ATTRIBUTE = 0xf4,
242f06cfc23SMiquel Raynal 	/* Missing source or destination address or address mode. */
243f06cfc23SMiquel Raynal 	IEEE802154_INVALID_ADDRESS = 0xf5,
244f06cfc23SMiquel Raynal 	/*
245f06cfc23SMiquel Raynal 	 * MLME asked to turn the receiver on, but the on time duration is too
246f06cfc23SMiquel Raynal 	 * big compared to the macBeaconOrder.
247f06cfc23SMiquel Raynal 	 */
248f06cfc23SMiquel Raynal 	IEEE802154_ON_TIME_TOO_LONG = 0xf6,
249f06cfc23SMiquel Raynal 	/*
250f06cfc23SMiquel Raynal 	 * MLME asaked to turn the receiver on, but the request was delayed for
251f06cfc23SMiquel Raynal 	 * too long before getting processed.
252f06cfc23SMiquel Raynal 	 */
253f06cfc23SMiquel Raynal 	IEEE802154_PAST_TIME = 0xf7,
254f06cfc23SMiquel Raynal 	/*
255f06cfc23SMiquel Raynal 	 * The StartTime parameter is nonzero, and the MLME is not currently
256f06cfc23SMiquel Raynal 	 * tracking the beacon of the coordinator through which it is
257f06cfc23SMiquel Raynal 	 * associated.
258f06cfc23SMiquel Raynal 	 */
259f06cfc23SMiquel Raynal 	IEEE802154_TRACKING_OFF = 0xf8,
260f06cfc23SMiquel Raynal 	/*
261f06cfc23SMiquel Raynal 	 * The index inside the hierarchical values in PIBAttribute is out of
262f06cfc23SMiquel Raynal 	 * range.
263f06cfc23SMiquel Raynal 	 */
264f06cfc23SMiquel Raynal 	IEEE802154_INVALID_INDEX = 0xf9,
265f06cfc23SMiquel Raynal 	/*
266f06cfc23SMiquel Raynal 	 * The number of PAN descriptors discovered during a scan has been
267f06cfc23SMiquel Raynal 	 * reached.
268f06cfc23SMiquel Raynal 	 */
269f06cfc23SMiquel Raynal 	IEEE802154_LIMIT_REACHED = 0xfa,
270f06cfc23SMiquel Raynal 	/*
271f06cfc23SMiquel Raynal 	 * The PIBAttribute parameter specifies an attribute that is a read-only
272f06cfc23SMiquel Raynal 	 * attribute.
273f06cfc23SMiquel Raynal 	 */
274f06cfc23SMiquel Raynal 	IEEE802154_READ_ONLY = 0xfb,
2754ca24acaSAlexander Aring 	/*
2764ca24acaSAlexander Aring 	 * A request to perform a scan operation failed because the MLME was
2774ca24acaSAlexander Aring 	 * in the process of performing a previously initiated scan operation.
2784ca24acaSAlexander Aring 	 */
2794ca24acaSAlexander Aring 	IEEE802154_SCAN_IN_PROGRESS = 0xfc,
280f06cfc23SMiquel Raynal 	/* The outgoing superframe overlaps the incoming superframe. */
281f06cfc23SMiquel Raynal 	IEEE802154_SUPERFRAME_OVERLAP = 0xfd,
282f06cfc23SMiquel Raynal 	/* Any other error situation. */
283f06cfc23SMiquel Raynal 	IEEE802154_SYSTEM_ERROR = 0xff,
2844ca24acaSAlexander Aring };
2854ca24acaSAlexander Aring 
286a6a6163bSMiquel Raynal /**
287a6a6163bSMiquel Raynal  * enum ieee802154_filtering_level - Filtering levels applicable to a PHY
288a6a6163bSMiquel Raynal  *
289a6a6163bSMiquel Raynal  * @IEEE802154_FILTERING_NONE: No filtering at all, what is received is
290a6a6163bSMiquel Raynal  *	forwarded to the softMAC
291a6a6163bSMiquel Raynal  * @IEEE802154_FILTERING_1_FCS: First filtering level, frames with an invalid
292a6a6163bSMiquel Raynal  *	FCS should be dropped
293a6a6163bSMiquel Raynal  * @IEEE802154_FILTERING_2_PROMISCUOUS: Second filtering level, promiscuous
294a6a6163bSMiquel Raynal  *	mode as described in the spec, identical in terms of filtering to the
295a6a6163bSMiquel Raynal  *	level one on PHY side, but at the MAC level the frame should be
296a6a6163bSMiquel Raynal  *	forwarded to the upper layer directly
297a6a6163bSMiquel Raynal  * @IEEE802154_FILTERING_3_SCAN: Third filtering level, scan related, where
298a6a6163bSMiquel Raynal  *	only beacons must be processed, all remaining traffic gets dropped
299a6a6163bSMiquel Raynal  * @IEEE802154_FILTERING_4_FRAME_FIELDS: Fourth filtering level actually
300a6a6163bSMiquel Raynal  *	enforcing the validity of the content of the frame with various checks
301a6a6163bSMiquel Raynal  */
302a6a6163bSMiquel Raynal enum ieee802154_filtering_level {
303a6a6163bSMiquel Raynal 	IEEE802154_FILTERING_NONE,
304a6a6163bSMiquel Raynal 	IEEE802154_FILTERING_1_FCS,
305a6a6163bSMiquel Raynal 	IEEE802154_FILTERING_2_PROMISCUOUS,
306a6a6163bSMiquel Raynal 	IEEE802154_FILTERING_3_SCAN,
307a6a6163bSMiquel Raynal 	IEEE802154_FILTERING_4_FRAME_FIELDS,
308a6a6163bSMiquel Raynal };
309a6a6163bSMiquel Raynal 
31054552d03SAlexander Aring /* frame control handling */
31154552d03SAlexander Aring #define IEEE802154_FCTL_FTYPE		0x0003
31279750ac4SAlexander Aring #define IEEE802154_FCTL_ACKREQ		0x0020
313bc405cd6SAlexandre Macabies #define IEEE802154_FCTL_SECEN		0x0004
31454552d03SAlexander Aring #define IEEE802154_FCTL_INTRA_PAN	0x0040
3159cc577ddSAlexander Aring #define IEEE802154_FCTL_DADDR		0x0c00
31619580cc1SAlexander Aring #define IEEE802154_FCTL_SADDR		0xc000
31754552d03SAlexander Aring 
31854552d03SAlexander Aring #define IEEE802154_FTYPE_DATA		0x0001
31954552d03SAlexander Aring 
3209cc577ddSAlexander Aring #define IEEE802154_FCTL_ADDR_NONE	0x0000
3219cc577ddSAlexander Aring #define IEEE802154_FCTL_DADDR_SHORT	0x0800
3229cc577ddSAlexander Aring #define IEEE802154_FCTL_DADDR_EXTENDED	0x0c00
32319580cc1SAlexander Aring #define IEEE802154_FCTL_SADDR_SHORT	0x8000
32419580cc1SAlexander Aring #define IEEE802154_FCTL_SADDR_EXTENDED	0xc000
3259cc577ddSAlexander Aring 
32654552d03SAlexander Aring /*
32754552d03SAlexander Aring  * ieee802154_is_data - check if type is IEEE802154_FTYPE_DATA
32854552d03SAlexander Aring  * @fc: frame control bytes in little-endian byteorder
32954552d03SAlexander Aring  */
ieee802154_is_data(__le16 fc)33054552d03SAlexander Aring static inline int ieee802154_is_data(__le16 fc)
33154552d03SAlexander Aring {
33254552d03SAlexander Aring 	return (fc & cpu_to_le16(IEEE802154_FCTL_FTYPE)) ==
33354552d03SAlexander Aring 		cpu_to_le16(IEEE802154_FTYPE_DATA);
33454552d03SAlexander Aring }
33554552d03SAlexander Aring 
33654552d03SAlexander Aring /**
337bc405cd6SAlexandre Macabies  * ieee802154_is_secen - check if Security bit is set
338bc405cd6SAlexandre Macabies  * @fc: frame control bytes in little-endian byteorder
339bc405cd6SAlexandre Macabies  */
ieee802154_is_secen(__le16 fc)340bc405cd6SAlexandre Macabies static inline bool ieee802154_is_secen(__le16 fc)
341bc405cd6SAlexandre Macabies {
342bc405cd6SAlexandre Macabies 	return fc & cpu_to_le16(IEEE802154_FCTL_SECEN);
343bc405cd6SAlexandre Macabies }
344bc405cd6SAlexandre Macabies 
345bc405cd6SAlexandre Macabies /**
34679750ac4SAlexander Aring  * ieee802154_is_ackreq - check if acknowledgment request bit is set
34779750ac4SAlexander Aring  * @fc: frame control bytes in little-endian byteorder
34879750ac4SAlexander Aring  */
ieee802154_is_ackreq(__le16 fc)34979750ac4SAlexander Aring static inline bool ieee802154_is_ackreq(__le16 fc)
35079750ac4SAlexander Aring {
35179750ac4SAlexander Aring 	return fc & cpu_to_le16(IEEE802154_FCTL_ACKREQ);
35279750ac4SAlexander Aring }
35379750ac4SAlexander Aring 
35479750ac4SAlexander Aring /**
35554552d03SAlexander Aring  * ieee802154_is_intra_pan - check if intra pan id communication
35654552d03SAlexander Aring  * @fc: frame control bytes in little-endian byteorder
35754552d03SAlexander Aring  */
ieee802154_is_intra_pan(__le16 fc)35854552d03SAlexander Aring static inline bool ieee802154_is_intra_pan(__le16 fc)
35954552d03SAlexander Aring {
36054552d03SAlexander Aring 	return fc & cpu_to_le16(IEEE802154_FCTL_INTRA_PAN);
36154552d03SAlexander Aring }
36254552d03SAlexander Aring 
3639cc577ddSAlexander Aring /*
3649cc577ddSAlexander Aring  * ieee802154_daddr_mode - get daddr mode from fc
3659cc577ddSAlexander Aring  * @fc: frame control bytes in little-endian byteorder
3669cc577ddSAlexander Aring  */
ieee802154_daddr_mode(__le16 fc)3679cc577ddSAlexander Aring static inline __le16 ieee802154_daddr_mode(__le16 fc)
3689cc577ddSAlexander Aring {
3699cc577ddSAlexander Aring 	return fc & cpu_to_le16(IEEE802154_FCTL_DADDR);
3709cc577ddSAlexander Aring }
3719cc577ddSAlexander Aring 
37219580cc1SAlexander Aring /*
37319580cc1SAlexander Aring  * ieee802154_saddr_mode - get saddr mode from fc
37419580cc1SAlexander Aring  * @fc: frame control bytes in little-endian byteorder
37519580cc1SAlexander Aring  */
ieee802154_saddr_mode(__le16 fc)37619580cc1SAlexander Aring static inline __le16 ieee802154_saddr_mode(__le16 fc)
37719580cc1SAlexander Aring {
37819580cc1SAlexander Aring 	return fc & cpu_to_le16(IEEE802154_FCTL_SADDR);
37919580cc1SAlexander Aring }
38019580cc1SAlexander Aring 
381fa491001SAlexander Aring /**
382fa491001SAlexander Aring  * ieee802154_is_valid_psdu_len - check if psdu len is valid
383306f7aa1SAlexander Aring  * available lengths:
384306f7aa1SAlexander Aring  *	0-4	Reserved
385306f7aa1SAlexander Aring  *	5	MPDU (Acknowledgment)
386306f7aa1SAlexander Aring  *	6-8	Reserved
387306f7aa1SAlexander Aring  *	9-127	MPDU
388306f7aa1SAlexander Aring  *
389fa491001SAlexander Aring  * @len: psdu len with (MHR + payload + MFR)
390fa491001SAlexander Aring  */
ieee802154_is_valid_psdu_len(u8 len)391b7594148SAlexander Aring static inline bool ieee802154_is_valid_psdu_len(u8 len)
392fa491001SAlexander Aring {
393306f7aa1SAlexander Aring 	return (len == IEEE802154_ACK_PSDU_LEN ||
394306f7aa1SAlexander Aring 		(len >= IEEE802154_MIN_PSDU_LEN && len <= IEEE802154_MTU));
395fa491001SAlexander Aring }
3964ca24acaSAlexander Aring 
397cb904b0aSAlexander Aring /**
398b7594148SAlexander Aring  * ieee802154_is_valid_extended_unicast_addr - check if extended addr is valid
399cb904b0aSAlexander Aring  * @addr: extended addr to check
400cb904b0aSAlexander Aring  */
ieee802154_is_valid_extended_unicast_addr(__le64 addr)401b7594148SAlexander Aring static inline bool ieee802154_is_valid_extended_unicast_addr(__le64 addr)
402cb904b0aSAlexander Aring {
403daf4e2c8SLennert Buytenhek 	/* Bail out if the address is all zero, or if the group
404daf4e2c8SLennert Buytenhek 	 * address bit is set.
405cb904b0aSAlexander Aring 	 */
4060d8a52f9SDan Carpenter 	return ((addr != cpu_to_le64(0x0000000000000000ULL)) &&
407daf4e2c8SLennert Buytenhek 		!(addr & cpu_to_le64(0x0100000000000000ULL)));
408cb904b0aSAlexander Aring }
409cb904b0aSAlexander Aring 
41035d5a374SAlexander Aring /**
411118a5cf8SAlexander Aring  * ieee802154_is_broadcast_short_addr - check if short addr is broadcast
412118a5cf8SAlexander Aring  * @addr: short addr to check
413118a5cf8SAlexander Aring  */
ieee802154_is_broadcast_short_addr(__le16 addr)414118a5cf8SAlexander Aring static inline bool ieee802154_is_broadcast_short_addr(__le16 addr)
415118a5cf8SAlexander Aring {
416118a5cf8SAlexander Aring 	return (addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST));
417118a5cf8SAlexander Aring }
418118a5cf8SAlexander Aring 
419118a5cf8SAlexander Aring /**
420118a5cf8SAlexander Aring  * ieee802154_is_unspec_short_addr - check if short addr is unspecified
421118a5cf8SAlexander Aring  * @addr: short addr to check
422118a5cf8SAlexander Aring  */
ieee802154_is_unspec_short_addr(__le16 addr)423118a5cf8SAlexander Aring static inline bool ieee802154_is_unspec_short_addr(__le16 addr)
424118a5cf8SAlexander Aring {
425118a5cf8SAlexander Aring 	return (addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC));
426118a5cf8SAlexander Aring }
427118a5cf8SAlexander Aring 
428118a5cf8SAlexander Aring /**
429118a5cf8SAlexander Aring  * ieee802154_is_valid_src_short_addr - check if source short address is valid
430118a5cf8SAlexander Aring  * @addr: short addr to check
431118a5cf8SAlexander Aring  */
ieee802154_is_valid_src_short_addr(__le16 addr)432118a5cf8SAlexander Aring static inline bool ieee802154_is_valid_src_short_addr(__le16 addr)
433118a5cf8SAlexander Aring {
434118a5cf8SAlexander Aring 	return !(ieee802154_is_broadcast_short_addr(addr) ||
435118a5cf8SAlexander Aring 		 ieee802154_is_unspec_short_addr(addr));
436118a5cf8SAlexander Aring }
437118a5cf8SAlexander Aring 
438118a5cf8SAlexander Aring /**
43935d5a374SAlexander Aring  * ieee802154_random_extended_addr - generates a random extended address
44035d5a374SAlexander Aring  * @addr: extended addr pointer to place the random address
44135d5a374SAlexander Aring  */
ieee802154_random_extended_addr(__le64 * addr)44235d5a374SAlexander Aring static inline void ieee802154_random_extended_addr(__le64 *addr)
44335d5a374SAlexander Aring {
44435d5a374SAlexander Aring 	get_random_bytes(addr, IEEE802154_EXTENDED_ADDR_LEN);
44535d5a374SAlexander Aring 
4463b369bd2SLennert Buytenhek 	/* clear the group bit, and set the locally administered bit */
4473b369bd2SLennert Buytenhek 	((u8 *)addr)[IEEE802154_EXTENDED_ADDR_LEN - 1] &= ~0x01;
4483b369bd2SLennert Buytenhek 	((u8 *)addr)[IEEE802154_EXTENDED_ADDR_LEN - 1] |= 0x02;
44935d5a374SAlexander Aring }
45035d5a374SAlexander Aring 
4514ca24acaSAlexander Aring #endif /* LINUX_IEEE802154_H */
452