Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * IEEE802.15.4-2003 specification
0004  *
0005  * Copyright (C) 2007, 2008 Siemens AG
0006  *
0007  * Written by:
0008  * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
0009  * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
0010  * Maxim Osipov <maxim.osipov@siemens.com>
0011  * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
0012  * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
0013  */
0014 
0015 #ifndef LINUX_IEEE802154_H
0016 #define LINUX_IEEE802154_H
0017 
0018 #include <linux/types.h>
0019 #include <linux/random.h>
0020 
0021 #define IEEE802154_MTU          127
0022 #define IEEE802154_ACK_PSDU_LEN     5
0023 #define IEEE802154_MIN_PSDU_LEN     9
0024 #define IEEE802154_FCS_LEN      2
0025 #define IEEE802154_MAX_AUTH_TAG_LEN 16
0026 #define IEEE802154_FC_LEN       2
0027 #define IEEE802154_SEQ_LEN      1
0028 
0029 /*  General MAC frame format:
0030  *  2 bytes: Frame Control
0031  *  1 byte:  Sequence Number
0032  * 20 bytes: Addressing fields
0033  * 14 bytes: Auxiliary Security Header
0034  */
0035 #define IEEE802154_MAX_HEADER_LEN   (2 + 1 + 20 + 14)
0036 #define IEEE802154_MIN_HEADER_LEN   (IEEE802154_ACK_PSDU_LEN - \
0037                      IEEE802154_FCS_LEN)
0038 
0039 #define IEEE802154_PAN_ID_BROADCAST 0xffff
0040 #define IEEE802154_ADDR_SHORT_BROADCAST 0xffff
0041 #define IEEE802154_ADDR_SHORT_UNSPEC    0xfffe
0042 
0043 #define IEEE802154_EXTENDED_ADDR_LEN    8
0044 #define IEEE802154_SHORT_ADDR_LEN   2
0045 #define IEEE802154_PAN_ID_LEN       2
0046 
0047 #define IEEE802154_LIFS_PERIOD      40
0048 #define IEEE802154_SIFS_PERIOD      12
0049 #define IEEE802154_MAX_SIFS_FRAME_SIZE  18
0050 
0051 #define IEEE802154_MAX_CHANNEL      26
0052 #define IEEE802154_MAX_PAGE     31
0053 
0054 #define IEEE802154_FC_TYPE_BEACON   0x0 /* Frame is beacon */
0055 #define IEEE802154_FC_TYPE_DATA     0x1 /* Frame is data */
0056 #define IEEE802154_FC_TYPE_ACK      0x2 /* Frame is acknowledgment */
0057 #define IEEE802154_FC_TYPE_MAC_CMD  0x3 /* Frame is MAC command */
0058 
0059 #define IEEE802154_FC_TYPE_SHIFT        0
0060 #define IEEE802154_FC_TYPE_MASK     ((1 << 3) - 1)
0061 #define IEEE802154_FC_TYPE(x)       ((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT)
0062 #define IEEE802154_FC_SET_TYPE(v, x)    do {    \
0063     v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \
0064         (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \
0065     } while (0)
0066 
0067 #define IEEE802154_FC_SECEN_SHIFT   3
0068 #define IEEE802154_FC_SECEN     (1 << IEEE802154_FC_SECEN_SHIFT)
0069 #define IEEE802154_FC_FRPEND_SHIFT  4
0070 #define IEEE802154_FC_FRPEND        (1 << IEEE802154_FC_FRPEND_SHIFT)
0071 #define IEEE802154_FC_ACK_REQ_SHIFT 5
0072 #define IEEE802154_FC_ACK_REQ       (1 << IEEE802154_FC_ACK_REQ_SHIFT)
0073 #define IEEE802154_FC_INTRA_PAN_SHIFT   6
0074 #define IEEE802154_FC_INTRA_PAN     (1 << IEEE802154_FC_INTRA_PAN_SHIFT)
0075 
0076 #define IEEE802154_FC_SAMODE_SHIFT  14
0077 #define IEEE802154_FC_SAMODE_MASK   (3 << IEEE802154_FC_SAMODE_SHIFT)
0078 #define IEEE802154_FC_DAMODE_SHIFT  10
0079 #define IEEE802154_FC_DAMODE_MASK   (3 << IEEE802154_FC_DAMODE_SHIFT)
0080 
0081 #define IEEE802154_FC_VERSION_SHIFT 12
0082 #define IEEE802154_FC_VERSION_MASK  (3 << IEEE802154_FC_VERSION_SHIFT)
0083 #define IEEE802154_FC_VERSION(x)    ((x & IEEE802154_FC_VERSION_MASK) >> IEEE802154_FC_VERSION_SHIFT)
0084 
0085 #define IEEE802154_FC_SAMODE(x)     \
0086     (((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT)
0087 
0088 #define IEEE802154_FC_DAMODE(x)     \
0089     (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT)
0090 
0091 #define IEEE802154_SCF_SECLEVEL_MASK        7
0092 #define IEEE802154_SCF_SECLEVEL_SHIFT       0
0093 #define IEEE802154_SCF_SECLEVEL(x)      (x & IEEE802154_SCF_SECLEVEL_MASK)
0094 #define IEEE802154_SCF_KEY_ID_MODE_SHIFT    3
0095 #define IEEE802154_SCF_KEY_ID_MODE_MASK     (3 << IEEE802154_SCF_KEY_ID_MODE_SHIFT)
0096 #define IEEE802154_SCF_KEY_ID_MODE(x)       \
0097     ((x & IEEE802154_SCF_KEY_ID_MODE_MASK) >> IEEE802154_SCF_KEY_ID_MODE_SHIFT)
0098 
0099 #define IEEE802154_SCF_KEY_IMPLICIT     0
0100 #define IEEE802154_SCF_KEY_INDEX        1
0101 #define IEEE802154_SCF_KEY_SHORT_INDEX      2
0102 #define IEEE802154_SCF_KEY_HW_INDEX     3
0103 
0104 #define IEEE802154_SCF_SECLEVEL_NONE        0
0105 #define IEEE802154_SCF_SECLEVEL_MIC32       1
0106 #define IEEE802154_SCF_SECLEVEL_MIC64       2
0107 #define IEEE802154_SCF_SECLEVEL_MIC128      3
0108 #define IEEE802154_SCF_SECLEVEL_ENC     4
0109 #define IEEE802154_SCF_SECLEVEL_ENC_MIC32   5
0110 #define IEEE802154_SCF_SECLEVEL_ENC_MIC64   6
0111 #define IEEE802154_SCF_SECLEVEL_ENC_MIC128  7
0112 
0113 /* MAC footer size */
0114 #define IEEE802154_MFR_SIZE 2 /* 2 octets */
0115 
0116 /* MAC's Command Frames Identifiers */
0117 #define IEEE802154_CMD_ASSOCIATION_REQ      0x01
0118 #define IEEE802154_CMD_ASSOCIATION_RESP     0x02
0119 #define IEEE802154_CMD_DISASSOCIATION_NOTIFY    0x03
0120 #define IEEE802154_CMD_DATA_REQ         0x04
0121 #define IEEE802154_CMD_PANID_CONFLICT_NOTIFY    0x05
0122 #define IEEE802154_CMD_ORPHAN_NOTIFY        0x06
0123 #define IEEE802154_CMD_BEACON_REQ       0x07
0124 #define IEEE802154_CMD_COORD_REALIGN_NOTIFY 0x08
0125 #define IEEE802154_CMD_GTS_REQ          0x09
0126 
0127 /*
0128  * The return values of MAC operations
0129  */
0130 enum {
0131     /*
0132      * The requested operation was completed successfully.
0133      * For a transmission request, this value indicates
0134      * a successful transmission.
0135      */
0136     IEEE802154_SUCCESS = 0x0,
0137     /* The requested operation failed. */
0138     IEEE802154_MAC_ERROR = 0x1,
0139     /* The requested operation has been cancelled. */
0140     IEEE802154_CANCELLED = 0x2,
0141     /*
0142      * Device is ready to poll the coordinator for data in a non beacon
0143      * enabled PAN.
0144      */
0145     IEEE802154_READY_FOR_POLL = 0x3,
0146     /* Wrong frame counter. */
0147     IEEE802154_COUNTER_ERROR = 0xdb,
0148     /*
0149      * The frame does not conforms to the incoming key usage policy checking
0150      * procedure.
0151      */
0152     IEEE802154_IMPROPER_KEY_TYPE = 0xdc,
0153     /*
0154      * The frame does not conforms to the incoming security level usage
0155      * policy checking procedure.
0156      */
0157     IEEE802154_IMPROPER_SECURITY_LEVEL = 0xdd,
0158     /* Secured frame received with an empty Frame Version field. */
0159     IEEE802154_UNSUPPORTED_LEGACY = 0xde,
0160     /*
0161      * A secured frame is received or must be sent but security is not
0162      * enabled in the device. Or, the Auxiliary Security Header has security
0163      * level of zero in it.
0164      */
0165     IEEE802154_UNSUPPORTED_SECURITY = 0xdf,
0166     /* The beacon was lost following a synchronization request. */
0167     IEEE802154_BEACON_LOST = 0xe0,
0168     /*
0169      * A transmission could not take place due to activity on the
0170      * channel, i.e., the CSMA-CA mechanism has failed.
0171      */
0172     IEEE802154_CHANNEL_ACCESS_FAILURE = 0xe1,
0173     /* The GTS request has been denied by the PAN coordinator. */
0174     IEEE802154_DENIED = 0xe2,
0175     /* The attempt to disable the transceiver has failed. */
0176     IEEE802154_DISABLE_TRX_FAILURE = 0xe3,
0177     /*
0178      * The received frame induces a failed security check according to
0179      * the security suite.
0180      */
0181     IEEE802154_FAILED_SECURITY_CHECK = 0xe4,
0182     /*
0183      * The frame resulting from secure processing has a length that is
0184      * greater than aMACMaxFrameSize.
0185      */
0186     IEEE802154_FRAME_TOO_LONG = 0xe5,
0187     /*
0188      * The requested GTS transmission failed because the specified GTS
0189      * either did not have a transmit GTS direction or was not defined.
0190      */
0191     IEEE802154_INVALID_GTS = 0xe6,
0192     /*
0193      * A request to purge an MSDU from the transaction queue was made using
0194      * an MSDU handle that was not found in the transaction table.
0195      */
0196     IEEE802154_INVALID_HANDLE = 0xe7,
0197     /* A parameter in the primitive is out of the valid range.*/
0198     IEEE802154_INVALID_PARAMETER = 0xe8,
0199     /* No acknowledgment was received after aMaxFrameRetries. */
0200     IEEE802154_NO_ACK = 0xe9,
0201     /* A scan operation failed to find any network beacons.*/
0202     IEEE802154_NO_BEACON = 0xea,
0203     /* No response data were available following a request. */
0204     IEEE802154_NO_DATA = 0xeb,
0205     /* The operation failed because a short address was not allocated. */
0206     IEEE802154_NO_SHORT_ADDRESS = 0xec,
0207     /*
0208      * A receiver enable request was unsuccessful because it could not be
0209      * completed within the CAP.
0210      */
0211     IEEE802154_OUT_OF_CAP = 0xed,
0212     /*
0213      * A PAN identifier conflict has been detected and communicated to the
0214      * PAN coordinator.
0215      */
0216     IEEE802154_PAN_ID_CONFLICT = 0xee,
0217     /* A coordinator realignment command has been received. */
0218     IEEE802154_REALIGNMENT = 0xef,
0219     /* The transaction has expired and its information discarded. */
0220     IEEE802154_TRANSACTION_EXPIRED = 0xf0,
0221     /* There is no capacity to store the transaction. */
0222     IEEE802154_TRANSACTION_OVERFLOW = 0xf1,
0223     /*
0224      * The transceiver was in the transmitter enabled state when the
0225      * receiver was requested to be enabled.
0226      */
0227     IEEE802154_TX_ACTIVE = 0xf2,
0228     /* The appropriate key is not available in the ACL. */
0229     IEEE802154_UNAVAILABLE_KEY = 0xf3,
0230     /*
0231      * A SET/GET request was issued with the identifier of a PIB attribute
0232      * that is not supported.
0233      */
0234     IEEE802154_UNSUPPORTED_ATTRIBUTE = 0xf4,
0235     /* Missing source or destination address or address mode. */
0236     IEEE802154_INVALID_ADDRESS = 0xf5,
0237     /*
0238      * MLME asked to turn the receiver on, but the on time duration is too
0239      * big compared to the macBeaconOrder.
0240      */
0241     IEEE802154_ON_TIME_TOO_LONG = 0xf6,
0242     /*
0243      * MLME asaked to turn the receiver on, but the request was delayed for
0244      * too long before getting processed.
0245      */
0246     IEEE802154_PAST_TIME = 0xf7,
0247     /*
0248      * The StartTime parameter is nonzero, and the MLME is not currently
0249      * tracking the beacon of the coordinator through which it is
0250      * associated.
0251      */
0252     IEEE802154_TRACKING_OFF = 0xf8,
0253     /*
0254      * The index inside the hierarchical values in PIBAttribute is out of
0255      * range.
0256      */
0257     IEEE802154_INVALID_INDEX = 0xf9,
0258     /*
0259      * The number of PAN descriptors discovered during a scan has been
0260      * reached.
0261      */
0262     IEEE802154_LIMIT_REACHED = 0xfa,
0263     /*
0264      * The PIBAttribute parameter specifies an attribute that is a read-only
0265      * attribute.
0266      */
0267     IEEE802154_READ_ONLY = 0xfb,
0268     /*
0269      * A request to perform a scan operation failed because the MLME was
0270      * in the process of performing a previously initiated scan operation.
0271      */
0272     IEEE802154_SCAN_IN_PROGRESS = 0xfc,
0273     /* The outgoing superframe overlaps the incoming superframe. */
0274     IEEE802154_SUPERFRAME_OVERLAP = 0xfd,
0275     /* Any other error situation. */
0276     IEEE802154_SYSTEM_ERROR = 0xff,
0277 };
0278 
0279 /* frame control handling */
0280 #define IEEE802154_FCTL_FTYPE       0x0003
0281 #define IEEE802154_FCTL_ACKREQ      0x0020
0282 #define IEEE802154_FCTL_SECEN       0x0004
0283 #define IEEE802154_FCTL_INTRA_PAN   0x0040
0284 #define IEEE802154_FCTL_DADDR       0x0c00
0285 #define IEEE802154_FCTL_SADDR       0xc000
0286 
0287 #define IEEE802154_FTYPE_DATA       0x0001
0288 
0289 #define IEEE802154_FCTL_ADDR_NONE   0x0000
0290 #define IEEE802154_FCTL_DADDR_SHORT 0x0800
0291 #define IEEE802154_FCTL_DADDR_EXTENDED  0x0c00
0292 #define IEEE802154_FCTL_SADDR_SHORT 0x8000
0293 #define IEEE802154_FCTL_SADDR_EXTENDED  0xc000
0294 
0295 /*
0296  * ieee802154_is_data - check if type is IEEE802154_FTYPE_DATA
0297  * @fc: frame control bytes in little-endian byteorder
0298  */
0299 static inline int ieee802154_is_data(__le16 fc)
0300 {
0301     return (fc & cpu_to_le16(IEEE802154_FCTL_FTYPE)) ==
0302         cpu_to_le16(IEEE802154_FTYPE_DATA);
0303 }
0304 
0305 /**
0306  * ieee802154_is_secen - check if Security bit is set
0307  * @fc: frame control bytes in little-endian byteorder
0308  */
0309 static inline bool ieee802154_is_secen(__le16 fc)
0310 {
0311     return fc & cpu_to_le16(IEEE802154_FCTL_SECEN);
0312 }
0313 
0314 /**
0315  * ieee802154_is_ackreq - check if acknowledgment request bit is set
0316  * @fc: frame control bytes in little-endian byteorder
0317  */
0318 static inline bool ieee802154_is_ackreq(__le16 fc)
0319 {
0320     return fc & cpu_to_le16(IEEE802154_FCTL_ACKREQ);
0321 }
0322 
0323 /**
0324  * ieee802154_is_intra_pan - check if intra pan id communication
0325  * @fc: frame control bytes in little-endian byteorder
0326  */
0327 static inline bool ieee802154_is_intra_pan(__le16 fc)
0328 {
0329     return fc & cpu_to_le16(IEEE802154_FCTL_INTRA_PAN);
0330 }
0331 
0332 /*
0333  * ieee802154_daddr_mode - get daddr mode from fc
0334  * @fc: frame control bytes in little-endian byteorder
0335  */
0336 static inline __le16 ieee802154_daddr_mode(__le16 fc)
0337 {
0338     return fc & cpu_to_le16(IEEE802154_FCTL_DADDR);
0339 }
0340 
0341 /*
0342  * ieee802154_saddr_mode - get saddr mode from fc
0343  * @fc: frame control bytes in little-endian byteorder
0344  */
0345 static inline __le16 ieee802154_saddr_mode(__le16 fc)
0346 {
0347     return fc & cpu_to_le16(IEEE802154_FCTL_SADDR);
0348 }
0349 
0350 /**
0351  * ieee802154_is_valid_psdu_len - check if psdu len is valid
0352  * available lengths:
0353  *  0-4 Reserved
0354  *  5   MPDU (Acknowledgment)
0355  *  6-8 Reserved
0356  *  9-127   MPDU
0357  *
0358  * @len: psdu len with (MHR + payload + MFR)
0359  */
0360 static inline bool ieee802154_is_valid_psdu_len(u8 len)
0361 {
0362     return (len == IEEE802154_ACK_PSDU_LEN ||
0363         (len >= IEEE802154_MIN_PSDU_LEN && len <= IEEE802154_MTU));
0364 }
0365 
0366 /**
0367  * ieee802154_is_valid_extended_unicast_addr - check if extended addr is valid
0368  * @addr: extended addr to check
0369  */
0370 static inline bool ieee802154_is_valid_extended_unicast_addr(__le64 addr)
0371 {
0372     /* Bail out if the address is all zero, or if the group
0373      * address bit is set.
0374      */
0375     return ((addr != cpu_to_le64(0x0000000000000000ULL)) &&
0376         !(addr & cpu_to_le64(0x0100000000000000ULL)));
0377 }
0378 
0379 /**
0380  * ieee802154_is_broadcast_short_addr - check if short addr is broadcast
0381  * @addr: short addr to check
0382  */
0383 static inline bool ieee802154_is_broadcast_short_addr(__le16 addr)
0384 {
0385     return (addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST));
0386 }
0387 
0388 /**
0389  * ieee802154_is_unspec_short_addr - check if short addr is unspecified
0390  * @addr: short addr to check
0391  */
0392 static inline bool ieee802154_is_unspec_short_addr(__le16 addr)
0393 {
0394     return (addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC));
0395 }
0396 
0397 /**
0398  * ieee802154_is_valid_src_short_addr - check if source short address is valid
0399  * @addr: short addr to check
0400  */
0401 static inline bool ieee802154_is_valid_src_short_addr(__le16 addr)
0402 {
0403     return !(ieee802154_is_broadcast_short_addr(addr) ||
0404          ieee802154_is_unspec_short_addr(addr));
0405 }
0406 
0407 /**
0408  * ieee802154_random_extended_addr - generates a random extended address
0409  * @addr: extended addr pointer to place the random address
0410  */
0411 static inline void ieee802154_random_extended_addr(__le64 *addr)
0412 {
0413     get_random_bytes(addr, IEEE802154_EXTENDED_ADDR_LEN);
0414 
0415     /* clear the group bit, and set the locally administered bit */
0416     ((u8 *)addr)[IEEE802154_EXTENDED_ADDR_LEN - 1] &= ~0x01;
0417     ((u8 *)addr)[IEEE802154_EXTENDED_ADDR_LEN - 1] |= 0x02;
0418 }
0419 
0420 #endif /* LINUX_IEEE802154_H */