xref: /linux/include/net/ieee802154_netdev.h (revision eeb9f5c2dcec90009d7cf12e780e7f9631993fc5)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * An interface between IEEE802.15.4 device and rest of the kernel.
4  *
5  * Copyright (C) 2007-2012 Siemens AG
6  *
7  * Written by:
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>
13  */
14 
15 #ifndef IEEE802154_NETDEVICE_H
16 #define IEEE802154_NETDEVICE_H
17 
18 #define IEEE802154_REQUIRED_SIZE(struct_type, member) \
19 	(offsetof(typeof(struct_type), member) + \
20 	sizeof(((typeof(struct_type) *)(NULL))->member))
21 
22 #define IEEE802154_ADDR_OFFSET \
23 	offsetof(typeof(struct sockaddr_ieee802154), addr)
24 
25 #define IEEE802154_MIN_NAMELEN (IEEE802154_ADDR_OFFSET + \
26 	IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, addr_type))
27 
28 #define IEEE802154_NAMELEN_SHORT (IEEE802154_ADDR_OFFSET + \
29 	IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, short_addr))
30 
31 #define IEEE802154_NAMELEN_LONG (IEEE802154_ADDR_OFFSET + \
32 	IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, hwaddr))
33 
34 #include <net/af_ieee802154.h>
35 #include <linux/netdevice.h>
36 #include <linux/skbuff.h>
37 #include <linux/ieee802154.h>
38 
39 #include <net/cfg802154.h>
40 
41 struct ieee802154_beacon_hdr {
42 #if defined(__LITTLE_ENDIAN_BITFIELD)
43 	u16 beacon_order:4,
44 	    superframe_order:4,
45 	    final_cap_slot:4,
46 	    battery_life_ext:1,
47 	    reserved0:1,
48 	    pan_coordinator:1,
49 	    assoc_permit:1;
50 	u8  gts_count:3,
51 	    gts_reserved:4,
52 	    gts_permit:1;
53 	u8  pend_short_addr_count:3,
54 	    reserved1:1,
55 	    pend_ext_addr_count:3,
56 	    reserved2:1;
57 #elif defined(__BIG_ENDIAN_BITFIELD)
58 	u16 assoc_permit:1,
59 	    pan_coordinator:1,
60 	    reserved0:1,
61 	    battery_life_ext:1,
62 	    final_cap_slot:4,
63 	    superframe_order:4,
64 	    beacon_order:4;
65 	u8  gts_permit:1,
66 	    gts_reserved:4,
67 	    gts_count:3;
68 	u8  reserved2:1,
69 	    pend_ext_addr_count:3,
70 	    reserved1:1,
71 	    pend_short_addr_count:3;
72 #else
73 #error	"Please fix <asm/byteorder.h>"
74 #endif
75 } __packed;
76 
77 struct ieee802154_mac_cmd_pl {
78 	u8  cmd_id;
79 } __packed;
80 
81 struct ieee802154_sechdr {
82 #if defined(__LITTLE_ENDIAN_BITFIELD)
83 	u8 level:3,
84 	   key_id_mode:2,
85 	   reserved:3;
86 #elif defined(__BIG_ENDIAN_BITFIELD)
87 	u8 reserved:3,
88 	   key_id_mode:2,
89 	   level:3;
90 #else
91 #error	"Please fix <asm/byteorder.h>"
92 #endif
93 	u8 key_id;
94 	__le32 frame_counter;
95 	union {
96 		__le32 short_src;
97 		__le64 extended_src;
98 	};
99 };
100 
101 struct ieee802154_hdr_fc {
102 #if defined(__LITTLE_ENDIAN_BITFIELD)
103 	u16 type:3,
104 	    security_enabled:1,
105 	    frame_pending:1,
106 	    ack_request:1,
107 	    intra_pan:1,
108 	    reserved:3,
109 	    dest_addr_mode:2,
110 	    version:2,
111 	    source_addr_mode:2;
112 #elif defined(__BIG_ENDIAN_BITFIELD)
113 	u16 reserved:1,
114 	    intra_pan:1,
115 	    ack_request:1,
116 	    frame_pending:1,
117 	    security_enabled:1,
118 	    type:3,
119 	    source_addr_mode:2,
120 	    version:2,
121 	    dest_addr_mode:2,
122 	    reserved2:2;
123 #else
124 #error	"Please fix <asm/byteorder.h>"
125 #endif
126 };
127 
128 struct ieee802154_assoc_req_pl {
129 #if defined(__LITTLE_ENDIAN_BITFIELD)
130 	u8 reserved1:1,
131 	   device_type:1,
132 	   power_source:1,
133 	   rx_on_when_idle:1,
134 	   assoc_type:1,
135 	   reserved2:1,
136 	   security_cap:1,
137 	   alloc_addr:1;
138 #elif defined(__BIG_ENDIAN_BITFIELD)
139 	u8 alloc_addr:1,
140 	   security_cap:1,
141 	   reserved2:1,
142 	   assoc_type:1,
143 	   rx_on_when_idle:1,
144 	   power_source:1,
145 	   device_type:1,
146 	   reserved1:1;
147 #else
148 #error	"Please fix <asm/byteorder.h>"
149 #endif
150 } __packed;
151 
152 struct ieee802154_assoc_resp_pl {
153 	__le16 short_addr;
154 	u8 status;
155 } __packed;
156 
157 enum ieee802154_frame_version {
158 	IEEE802154_2003_STD,
159 	IEEE802154_2006_STD,
160 	IEEE802154_STD,
161 	IEEE802154_RESERVED_STD,
162 	IEEE802154_MULTIPURPOSE_STD = IEEE802154_2003_STD,
163 };
164 
165 enum ieee802154_addressing_mode {
166 	IEEE802154_NO_ADDRESSING,
167 	IEEE802154_RESERVED,
168 	IEEE802154_SHORT_ADDRESSING,
169 	IEEE802154_EXTENDED_ADDRESSING,
170 };
171 
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,
178 };
179 
180 enum ieee802154_disassociation_reason {
181 	IEEE802154_COORD_WISHES_DEVICE_TO_LEAVE = 0x1,
182 	IEEE802154_DEVICE_WISHES_TO_LEAVE = 0x2,
183 };
184 
185 struct ieee802154_hdr {
186 	struct ieee802154_hdr_fc fc;
187 	u8 seq;
188 	struct ieee802154_addr source;
189 	struct ieee802154_addr dest;
190 	struct ieee802154_sechdr sec;
191 };
192 
193 struct ieee802154_beacon_frame {
194 	struct ieee802154_hdr mhr;
195 	struct ieee802154_beacon_hdr mac_pl;
196 };
197 
198 struct ieee802154_mac_cmd_frame {
199 	struct ieee802154_hdr mhr;
200 	struct ieee802154_mac_cmd_pl mac_pl;
201 };
202 
203 struct ieee802154_beacon_req_frame {
204 	struct ieee802154_hdr mhr;
205 	struct ieee802154_mac_cmd_pl mac_pl;
206 };
207 
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;
212 };
213 
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;
218 };
219 
220 struct ieee802154_disassociation_notif_frame {
221 	struct ieee802154_hdr mhr;
222 	struct ieee802154_mac_cmd_pl mac_pl;
223 	u8 disassoc_pl;
224 };
225 
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.
230  */
231 int ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr);
232 
233 /* pulls the entire 802.15.4 header off of the skb, including the security
234  * header, and performs pan id decompression
235  */
236 int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr);
237 
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
241  */
242 int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
243 			      struct ieee802154_hdr *hdr);
244 
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
247  * header_ops.parse
248  */
249 int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
250 
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);
258 
259 int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
260 
261 static inline int
262 ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec)
263 {
264 	switch (sec->level) {
265 	case IEEE802154_SCF_SECLEVEL_MIC32:
266 	case IEEE802154_SCF_SECLEVEL_ENC_MIC32:
267 		return 4;
268 	case IEEE802154_SCF_SECLEVEL_MIC64:
269 	case IEEE802154_SCF_SECLEVEL_ENC_MIC64:
270 		return 8;
271 	case IEEE802154_SCF_SECLEVEL_MIC128:
272 	case IEEE802154_SCF_SECLEVEL_ENC_MIC128:
273 		return 16;
274 	case IEEE802154_SCF_SECLEVEL_NONE:
275 	case IEEE802154_SCF_SECLEVEL_ENC:
276 	default:
277 		return 0;
278 	}
279 }
280 
281 static inline int ieee802154_hdr_length(struct sk_buff *skb)
282 {
283 	struct ieee802154_hdr hdr;
284 	int len = ieee802154_hdr_pull(skb, &hdr);
285 
286 	if (len > 0)
287 		skb_push(skb, len);
288 
289 	return len;
290 }
291 
292 static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1,
293 					 const struct ieee802154_addr *a2)
294 {
295 	if (a1->pan_id != a2->pan_id || a1->mode != a2->mode)
296 		return false;
297 
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))
302 		return false;
303 
304 	return true;
305 }
306 
307 static inline __le64 ieee802154_devaddr_from_raw(const void *raw)
308 {
309 	u64 temp;
310 
311 	memcpy(&temp, raw, IEEE802154_ADDR_LEN);
312 	return (__force __le64)swab64(temp);
313 }
314 
315 static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr)
316 {
317 	u64 temp = swab64((__force u64)addr);
318 
319 	memcpy(raw, &temp, IEEE802154_ADDR_LEN);
320 }
321 
322 static inline int
323 ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len)
324 {
325 	struct ieee802154_addr_sa *sa;
326 	int ret = 0;
327 
328 	sa = &daddr->addr;
329 	if (len < IEEE802154_MIN_NAMELEN)
330 		return -EINVAL;
331 	switch (sa->addr_type) {
332 	case IEEE802154_ADDR_NONE:
333 		break;
334 	case IEEE802154_ADDR_SHORT:
335 		if (len < IEEE802154_NAMELEN_SHORT)
336 			ret = -EINVAL;
337 		break;
338 	case IEEE802154_ADDR_LONG:
339 		if (len < IEEE802154_NAMELEN_LONG)
340 			ret = -EINVAL;
341 		break;
342 	default:
343 		ret = -EINVAL;
344 		break;
345 	}
346 	return ret;
347 }
348 
349 static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
350 					   const struct ieee802154_addr_sa *sa)
351 {
352 	a->mode = sa->addr_type;
353 	a->pan_id = cpu_to_le16(sa->pan_id);
354 
355 	switch (a->mode) {
356 	case IEEE802154_ADDR_SHORT:
357 		a->short_addr = cpu_to_le16(sa->short_addr);
358 		break;
359 	case IEEE802154_ADDR_LONG:
360 		a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr);
361 		break;
362 	}
363 }
364 
365 static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa,
366 					 const struct ieee802154_addr *a)
367 {
368 	sa->addr_type = a->mode;
369 	sa->pan_id = le16_to_cpu(a->pan_id);
370 
371 	switch (a->mode) {
372 	case IEEE802154_ADDR_SHORT:
373 		sa->short_addr = le16_to_cpu(a->short_addr);
374 		break;
375 	case IEEE802154_ADDR_LONG:
376 		ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr);
377 		break;
378 	}
379 }
380 
381 /*
382  * A control block of skb passed between the ARPHRD_IEEE802154 device
383  * and other stack parts.
384  */
385 struct ieee802154_mac_cb {
386 	u8 lqi;
387 	u8 type;
388 	bool ackreq;
389 	bool secen;
390 	bool secen_override;
391 	u8 seclevel;
392 	bool seclevel_override;
393 	struct ieee802154_addr source;
394 	struct ieee802154_addr dest;
395 };
396 
397 static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
398 {
399 	return (struct ieee802154_mac_cb *)skb->cb;
400 }
401 
402 static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb)
403 {
404 	BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb));
405 
406 	memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb));
407 	return mac_cb(skb);
408 }
409 
410 enum {
411 	IEEE802154_LLSEC_DEVKEY_IGNORE,
412 	IEEE802154_LLSEC_DEVKEY_RESTRICT,
413 	IEEE802154_LLSEC_DEVKEY_RECORD,
414 
415 	__IEEE802154_LLSEC_DEVKEY_MAX,
416 };
417 
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
422 
423 struct ieee802154_mac_params {
424 	s8 transmit_power;
425 	u8 min_be;
426 	u8 max_be;
427 	u8 csma_retries;
428 	s8 frame_retries;
429 
430 	bool lbt;
431 	struct wpan_phy_cca cca;
432 	s32 cca_ed_level;
433 };
434 
435 struct wpan_phy;
436 
437 enum {
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),
447 };
448 
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,
454 			  int changed);
455 
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);
461 
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);
465 
466 	int (*add_devkey)(struct net_device *dev,
467 			  __le64 device_addr,
468 			  const struct ieee802154_llsec_device_key *key);
469 	int (*del_devkey)(struct net_device *dev,
470 			  __le64 device_addr,
471 			  const struct ieee802154_llsec_device_key *key);
472 
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);
477 
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);
482 };
483 /*
484  * This should be located at net_device->ml_priv
485  *
486  * get_phy should increment the reference counting on returned phy.
487  * Use wpan_wpy_put to put that reference.
488  */
489 struct ieee802154_mlme_ops {
490 	/* The following fields are optional (can be NULL). */
491 
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,
500 			u8 reason);
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);
507 
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);
512 
513 	const struct ieee802154_llsec_ops *llsec;
514 };
515 
516 static inline struct ieee802154_mlme_ops *
517 ieee802154_mlme_ops(const struct net_device *dev)
518 {
519 	return dev->ml_priv;
520 }
521 
522 #endif
523