Linux 6.9-rc1
[linux-2.6-microblaze.git] / include / net / ieee802154_netdev.h
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