~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/net/ieee802154_netdev.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php