1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * An interface between IEEE802.15.4 device and rest of the kernel.
5 * Copyright (C) 2007-2012 Siemens AG
8 * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
9 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
10 * Maxim Osipov <maxim.osipov@siemens.com>
11 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
12 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
15 #ifndef IEEE802154_NETDEVICE_H
16 #define IEEE802154_NETDEVICE_H
18 #define IEEE802154_REQUIRED_SIZE(struct_type, member) \
19 (offsetof(typeof(struct_type), member) + \
20 sizeof(((typeof(struct_type) *)(NULL))->member))
22 #define IEEE802154_ADDR_OFFSET \
23 offsetof(typeof(struct sockaddr_ieee802154), addr)
25 #define IEEE802154_MIN_NAMELEN (IEEE802154_ADDR_OFFSET + \
26 IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, addr_type))
28 #define IEEE802154_NAMELEN_SHORT (IEEE802154_ADDR_OFFSET + \
29 IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, short_addr))
31 #define IEEE802154_NAMELEN_LONG (IEEE802154_ADDR_OFFSET + \
32 IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, hwaddr))
34 #include <net/af_ieee802154.h>
35 #include <linux/netdevice.h>
36 #include <linux/skbuff.h>
37 #include <linux/ieee802154.h>
39 #include <net/cfg802154.h>
41 struct ieee802154_beacon_hdr
{
42 #if defined(__LITTLE_ENDIAN_BITFIELD)
53 u8 pend_short_addr_count
:3,
55 pend_ext_addr_count
:3,
57 #elif defined(__BIG_ENDIAN_BITFIELD)
69 pend_ext_addr_count
:3,
71 pend_short_addr_count
:3;
73 #error "Please fix <asm/byteorder.h>"
77 struct ieee802154_mac_cmd_pl
{
81 struct ieee802154_sechdr
{
82 #if defined(__LITTLE_ENDIAN_BITFIELD)
86 #elif defined(__BIG_ENDIAN_BITFIELD)
91 #error "Please fix <asm/byteorder.h>"
101 struct ieee802154_hdr_fc
{
102 #if defined(__LITTLE_ENDIAN_BITFIELD)
112 #elif defined(__BIG_ENDIAN_BITFIELD)
124 #error "Please fix <asm/byteorder.h>"
128 struct ieee802154_assoc_req_pl
{
129 #if defined(__LITTLE_ENDIAN_BITFIELD)
138 #elif defined(__BIG_ENDIAN_BITFIELD)
148 #error "Please fix <asm/byteorder.h>"
152 struct ieee802154_assoc_resp_pl
{
157 enum ieee802154_frame_version
{
161 IEEE802154_RESERVED_STD
,
162 IEEE802154_MULTIPURPOSE_STD
= IEEE802154_2003_STD
,
165 enum ieee802154_addressing_mode
{
166 IEEE802154_NO_ADDRESSING
,
168 IEEE802154_SHORT_ADDRESSING
,
169 IEEE802154_EXTENDED_ADDRESSING
,
172 enum ieee802154_association_status
{
173 IEEE802154_ASSOCIATION_SUCCESSFUL
= 0x00,
174 IEEE802154_PAN_AT_CAPACITY
= 0x01,
175 IEEE802154_PAN_ACCESS_DENIED
= 0x02,
176 IEEE802154_HOPPING_SEQUENCE_OFFSET_DUP
= 0x03,
177 IEEE802154_FAST_ASSOCIATION_SUCCESSFUL
= 0x80,
180 enum ieee802154_disassociation_reason
{
181 IEEE802154_COORD_WISHES_DEVICE_TO_LEAVE
= 0x1,
182 IEEE802154_DEVICE_WISHES_TO_LEAVE
= 0x2,
185 struct ieee802154_hdr
{
186 struct ieee802154_hdr_fc fc
;
188 struct ieee802154_addr source
;
189 struct ieee802154_addr dest
;
190 struct ieee802154_sechdr sec
;
193 struct ieee802154_beacon_frame
{
194 struct ieee802154_hdr mhr
;
195 struct ieee802154_beacon_hdr mac_pl
;
198 struct ieee802154_mac_cmd_frame
{
199 struct ieee802154_hdr mhr
;
200 struct ieee802154_mac_cmd_pl mac_pl
;
203 struct ieee802154_beacon_req_frame
{
204 struct ieee802154_hdr mhr
;
205 struct ieee802154_mac_cmd_pl mac_pl
;
208 struct ieee802154_association_req_frame
{
209 struct ieee802154_hdr mhr
;
210 struct ieee802154_mac_cmd_pl mac_pl
;
211 struct ieee802154_assoc_req_pl assoc_req_pl
;
214 struct ieee802154_association_resp_frame
{
215 struct ieee802154_hdr mhr
;
216 struct ieee802154_mac_cmd_pl mac_pl
;
217 struct ieee802154_assoc_resp_pl assoc_resp_pl
;
220 struct ieee802154_disassociation_notif_frame
{
221 struct ieee802154_hdr mhr
;
222 struct ieee802154_mac_cmd_pl mac_pl
;
226 /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
227 * the contents of hdr will be, and the actual value of those bits in
228 * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
229 * version, if SECEN is set.
231 int ieee802154_hdr_push(struct sk_buff
*skb
, struct ieee802154_hdr
*hdr
);
233 /* pulls the entire 802.15.4 header off of the skb, including the security
234 * header, and performs pan id decompression
236 int ieee802154_hdr_pull(struct sk_buff
*skb
, struct ieee802154_hdr
*hdr
);
238 /* parses the frame control, sequence number of address fields in a given skb
239 * and stores them into hdr, performing pan id decompression and length checks
240 * to be suitable for use in header_ops.parse
242 int ieee802154_hdr_peek_addrs(const struct sk_buff
*skb
,
243 struct ieee802154_hdr
*hdr
);
245 /* parses the full 802.15.4 header a given skb and stores them into hdr,
246 * performing pan id decompression and length checks to be suitable for use in
249 int ieee802154_hdr_peek(const struct sk_buff
*skb
, struct ieee802154_hdr
*hdr
);
251 /* pushes/pulls various frame types into/from an skb */
252 int ieee802154_beacon_push(struct sk_buff
*skb
,
253 struct ieee802154_beacon_frame
*beacon
);
254 int ieee802154_mac_cmd_push(struct sk_buff
*skb
, void *frame
,
255 const void *pl
, unsigned int pl_len
);
256 int ieee802154_mac_cmd_pl_pull(struct sk_buff
*skb
,
257 struct ieee802154_mac_cmd_pl
*mac_pl
);
259 int ieee802154_max_payload(const struct ieee802154_hdr
*hdr
);
262 ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr
*sec
)
264 switch (sec
->level
) {
265 case IEEE802154_SCF_SECLEVEL_MIC32
:
266 case IEEE802154_SCF_SECLEVEL_ENC_MIC32
:
268 case IEEE802154_SCF_SECLEVEL_MIC64
:
269 case IEEE802154_SCF_SECLEVEL_ENC_MIC64
:
271 case IEEE802154_SCF_SECLEVEL_MIC128
:
272 case IEEE802154_SCF_SECLEVEL_ENC_MIC128
:
274 case IEEE802154_SCF_SECLEVEL_NONE
:
275 case IEEE802154_SCF_SECLEVEL_ENC
:
281 static inline int ieee802154_hdr_length(struct sk_buff
*skb
)
283 struct ieee802154_hdr hdr
;
284 int len
= ieee802154_hdr_pull(skb
, &hdr
);
292 static inline bool ieee802154_addr_equal(const struct ieee802154_addr
*a1
,
293 const struct ieee802154_addr
*a2
)
295 if (a1
->pan_id
!= a2
->pan_id
|| a1
->mode
!= a2
->mode
)
298 if ((a1
->mode
== IEEE802154_ADDR_LONG
&&
299 a1
->extended_addr
!= a2
->extended_addr
) ||
300 (a1
->mode
== IEEE802154_ADDR_SHORT
&&
301 a1
->short_addr
!= a2
->short_addr
))
307 static inline __le64
ieee802154_devaddr_from_raw(const void *raw
)
311 memcpy(&temp
, raw
, IEEE802154_ADDR_LEN
);
312 return (__force __le64
)swab64(temp
);
315 static inline void ieee802154_devaddr_to_raw(void *raw
, __le64 addr
)
317 u64 temp
= swab64((__force u64
)addr
);
319 memcpy(raw
, &temp
, IEEE802154_ADDR_LEN
);
323 ieee802154_sockaddr_check_size(struct sockaddr_ieee802154
*daddr
, int len
)
325 struct ieee802154_addr_sa
*sa
;
329 if (len
< IEEE802154_MIN_NAMELEN
)
331 switch (sa
->addr_type
) {
332 case IEEE802154_ADDR_NONE
:
334 case IEEE802154_ADDR_SHORT
:
335 if (len
< IEEE802154_NAMELEN_SHORT
)
338 case IEEE802154_ADDR_LONG
:
339 if (len
< IEEE802154_NAMELEN_LONG
)
349 static inline void ieee802154_addr_from_sa(struct ieee802154_addr
*a
,
350 const struct ieee802154_addr_sa
*sa
)
352 a
->mode
= sa
->addr_type
;
353 a
->pan_id
= cpu_to_le16(sa
->pan_id
);
356 case IEEE802154_ADDR_SHORT
:
357 a
->short_addr
= cpu_to_le16(sa
->short_addr
);
359 case IEEE802154_ADDR_LONG
:
360 a
->extended_addr
= ieee802154_devaddr_from_raw(sa
->hwaddr
);
365 static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa
*sa
,
366 const struct ieee802154_addr
*a
)
368 sa
->addr_type
= a
->mode
;
369 sa
->pan_id
= le16_to_cpu(a
->pan_id
);
372 case IEEE802154_ADDR_SHORT
:
373 sa
->short_addr
= le16_to_cpu(a
->short_addr
);
375 case IEEE802154_ADDR_LONG
:
376 ieee802154_devaddr_to_raw(sa
->hwaddr
, a
->extended_addr
);
382 * A control block of skb passed between the ARPHRD_IEEE802154 device
383 * and other stack parts.
385 struct ieee802154_mac_cb
{
392 bool seclevel_override
;
393 struct ieee802154_addr source
;
394 struct ieee802154_addr dest
;
397 static inline struct ieee802154_mac_cb
*mac_cb(struct sk_buff
*skb
)
399 return (struct ieee802154_mac_cb
*)skb
->cb
;
402 static inline struct ieee802154_mac_cb
*mac_cb_init(struct sk_buff
*skb
)
404 BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb
) > sizeof(skb
->cb
));
406 memset(skb
->cb
, 0, sizeof(struct ieee802154_mac_cb
));
411 IEEE802154_LLSEC_DEVKEY_IGNORE
,
412 IEEE802154_LLSEC_DEVKEY_RESTRICT
,
413 IEEE802154_LLSEC_DEVKEY_RECORD
,
415 __IEEE802154_LLSEC_DEVKEY_MAX
,
418 #define IEEE802154_MAC_SCAN_ED 0
419 #define IEEE802154_MAC_SCAN_ACTIVE 1
420 #define IEEE802154_MAC_SCAN_PASSIVE 2
421 #define IEEE802154_MAC_SCAN_ORPHAN 3
423 struct ieee802154_mac_params
{
431 struct wpan_phy_cca cca
;
438 IEEE802154_LLSEC_PARAM_ENABLED
= BIT(0),
439 IEEE802154_LLSEC_PARAM_FRAME_COUNTER
= BIT(1),
440 IEEE802154_LLSEC_PARAM_OUT_LEVEL
= BIT(2),
441 IEEE802154_LLSEC_PARAM_OUT_KEY
= BIT(3),
442 IEEE802154_LLSEC_PARAM_KEY_SOURCE
= BIT(4),
443 IEEE802154_LLSEC_PARAM_PAN_ID
= BIT(5),
444 IEEE802154_LLSEC_PARAM_HWADDR
= BIT(6),
445 IEEE802154_LLSEC_PARAM_COORD_HWADDR
= BIT(7),
446 IEEE802154_LLSEC_PARAM_COORD_SHORTADDR
= BIT(8),
449 struct ieee802154_llsec_ops
{
450 int (*get_params
)(struct net_device
*dev
,
451 struct ieee802154_llsec_params
*params
);
452 int (*set_params
)(struct net_device
*dev
,
453 const struct ieee802154_llsec_params
*params
,
456 int (*add_key
)(struct net_device
*dev
,
457 const struct ieee802154_llsec_key_id
*id
,
458 const struct ieee802154_llsec_key
*key
);
459 int (*del_key
)(struct net_device
*dev
,
460 const struct ieee802154_llsec_key_id
*id
);
462 int (*add_dev
)(struct net_device
*dev
,
463 const struct ieee802154_llsec_device
*llsec_dev
);
464 int (*del_dev
)(struct net_device
*dev
, __le64 dev_addr
);
466 int (*add_devkey
)(struct net_device
*dev
,
468 const struct ieee802154_llsec_device_key
*key
);
469 int (*del_devkey
)(struct net_device
*dev
,
471 const struct ieee802154_llsec_device_key
*key
);
473 int (*add_seclevel
)(struct net_device
*dev
,
474 const struct ieee802154_llsec_seclevel
*sl
);
475 int (*del_seclevel
)(struct net_device
*dev
,
476 const struct ieee802154_llsec_seclevel
*sl
);
478 void (*lock_table
)(struct net_device
*dev
);
479 void (*get_table
)(struct net_device
*dev
,
480 struct ieee802154_llsec_table
**t
);
481 void (*unlock_table
)(struct net_device
*dev
);
484 * This should be located at net_device->ml_priv
486 * get_phy should increment the reference counting on returned phy.
487 * Use wpan_wpy_put to put that reference.
489 struct ieee802154_mlme_ops
{
490 /* The following fields are optional (can be NULL). */
492 int (*assoc_req
)(struct net_device
*dev
,
493 struct ieee802154_addr
*addr
,
494 u8 channel
, u8 page
, u8 cap
);
495 int (*assoc_resp
)(struct net_device
*dev
,
496 struct ieee802154_addr
*addr
,
497 __le16 short_addr
, u8 status
);
498 int (*disassoc_req
)(struct net_device
*dev
,
499 struct ieee802154_addr
*addr
,
501 int (*start_req
)(struct net_device
*dev
,
502 struct ieee802154_addr
*addr
,
503 u8 channel
, u8 page
, u8 bcn_ord
, u8 sf_ord
,
504 u8 pan_coord
, u8 blx
, u8 coord_realign
);
505 int (*scan_req
)(struct net_device
*dev
,
506 u8 type
, u32 channels
, u8 page
, u8 duration
);
508 int (*set_mac_params
)(struct net_device
*dev
,
509 const struct ieee802154_mac_params
*params
);
510 void (*get_mac_params
)(struct net_device
*dev
,
511 struct ieee802154_mac_params
*params
);
513 const struct ieee802154_llsec_ops
*llsec
;
516 static inline struct ieee802154_mlme_ops
*
517 ieee802154_mlme_ops(const struct net_device
*dev
)