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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.