18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * An interface between IEEE802.15.4 device and rest of the kernel. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2007-2012 Siemens AG 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Written by: 88c2ecf20Sopenharmony_ci * Pavel Smolenskiy <pavel.smolenskiy@gmail.com> 98c2ecf20Sopenharmony_ci * Maxim Gorbachyov <maxim.gorbachev@siemens.com> 108c2ecf20Sopenharmony_ci * Maxim Osipov <maxim.osipov@siemens.com> 118c2ecf20Sopenharmony_ci * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 128c2ecf20Sopenharmony_ci * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#ifndef IEEE802154_NETDEVICE_H 168c2ecf20Sopenharmony_ci#define IEEE802154_NETDEVICE_H 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define IEEE802154_REQUIRED_SIZE(struct_type, member) \ 198c2ecf20Sopenharmony_ci (offsetof(typeof(struct_type), member) + \ 208c2ecf20Sopenharmony_ci sizeof(((typeof(struct_type) *)(NULL))->member)) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define IEEE802154_ADDR_OFFSET \ 238c2ecf20Sopenharmony_ci offsetof(typeof(struct sockaddr_ieee802154), addr) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define IEEE802154_MIN_NAMELEN (IEEE802154_ADDR_OFFSET + \ 268c2ecf20Sopenharmony_ci IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, addr_type)) 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define IEEE802154_NAMELEN_SHORT (IEEE802154_ADDR_OFFSET + \ 298c2ecf20Sopenharmony_ci IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, short_addr)) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define IEEE802154_NAMELEN_LONG (IEEE802154_ADDR_OFFSET + \ 328c2ecf20Sopenharmony_ci IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, hwaddr)) 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include <net/af_ieee802154.h> 358c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 368c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 378c2ecf20Sopenharmony_ci#include <linux/ieee802154.h> 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#include <net/cfg802154.h> 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistruct ieee802154_sechdr { 428c2ecf20Sopenharmony_ci#if defined(__LITTLE_ENDIAN_BITFIELD) 438c2ecf20Sopenharmony_ci u8 level:3, 448c2ecf20Sopenharmony_ci key_id_mode:2, 458c2ecf20Sopenharmony_ci reserved:3; 468c2ecf20Sopenharmony_ci#elif defined(__BIG_ENDIAN_BITFIELD) 478c2ecf20Sopenharmony_ci u8 reserved:3, 488c2ecf20Sopenharmony_ci key_id_mode:2, 498c2ecf20Sopenharmony_ci level:3; 508c2ecf20Sopenharmony_ci#else 518c2ecf20Sopenharmony_ci#error "Please fix <asm/byteorder.h>" 528c2ecf20Sopenharmony_ci#endif 538c2ecf20Sopenharmony_ci u8 key_id; 548c2ecf20Sopenharmony_ci __le32 frame_counter; 558c2ecf20Sopenharmony_ci union { 568c2ecf20Sopenharmony_ci __le32 short_src; 578c2ecf20Sopenharmony_ci __le64 extended_src; 588c2ecf20Sopenharmony_ci }; 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistruct ieee802154_hdr_fc { 628c2ecf20Sopenharmony_ci#if defined(__LITTLE_ENDIAN_BITFIELD) 638c2ecf20Sopenharmony_ci u16 type:3, 648c2ecf20Sopenharmony_ci security_enabled:1, 658c2ecf20Sopenharmony_ci frame_pending:1, 668c2ecf20Sopenharmony_ci ack_request:1, 678c2ecf20Sopenharmony_ci intra_pan:1, 688c2ecf20Sopenharmony_ci reserved:3, 698c2ecf20Sopenharmony_ci dest_addr_mode:2, 708c2ecf20Sopenharmony_ci version:2, 718c2ecf20Sopenharmony_ci source_addr_mode:2; 728c2ecf20Sopenharmony_ci#elif defined(__BIG_ENDIAN_BITFIELD) 738c2ecf20Sopenharmony_ci u16 reserved:1, 748c2ecf20Sopenharmony_ci intra_pan:1, 758c2ecf20Sopenharmony_ci ack_request:1, 768c2ecf20Sopenharmony_ci frame_pending:1, 778c2ecf20Sopenharmony_ci security_enabled:1, 788c2ecf20Sopenharmony_ci type:3, 798c2ecf20Sopenharmony_ci source_addr_mode:2, 808c2ecf20Sopenharmony_ci version:2, 818c2ecf20Sopenharmony_ci dest_addr_mode:2, 828c2ecf20Sopenharmony_ci reserved2:2; 838c2ecf20Sopenharmony_ci#else 848c2ecf20Sopenharmony_ci#error "Please fix <asm/byteorder.h>" 858c2ecf20Sopenharmony_ci#endif 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistruct ieee802154_hdr { 898c2ecf20Sopenharmony_ci struct ieee802154_hdr_fc fc; 908c2ecf20Sopenharmony_ci u8 seq; 918c2ecf20Sopenharmony_ci struct ieee802154_addr source; 928c2ecf20Sopenharmony_ci struct ieee802154_addr dest; 938c2ecf20Sopenharmony_ci struct ieee802154_sechdr sec; 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci/* pushes hdr onto the skb. fields of hdr->fc that can be calculated from 978c2ecf20Sopenharmony_ci * the contents of hdr will be, and the actual value of those bits in 988c2ecf20Sopenharmony_ci * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame 998c2ecf20Sopenharmony_ci * version, if SECEN is set. 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_ciint ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/* pulls the entire 802.15.4 header off of the skb, including the security 1048c2ecf20Sopenharmony_ci * header, and performs pan id decompression 1058c2ecf20Sopenharmony_ci */ 1068c2ecf20Sopenharmony_ciint ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/* parses the frame control, sequence number of address fields in a given skb 1098c2ecf20Sopenharmony_ci * and stores them into hdr, performing pan id decompression and length checks 1108c2ecf20Sopenharmony_ci * to be suitable for use in header_ops.parse 1118c2ecf20Sopenharmony_ci */ 1128c2ecf20Sopenharmony_ciint ieee802154_hdr_peek_addrs(const struct sk_buff *skb, 1138c2ecf20Sopenharmony_ci struct ieee802154_hdr *hdr); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci/* parses the full 802.15.4 header a given skb and stores them into hdr, 1168c2ecf20Sopenharmony_ci * performing pan id decompression and length checks to be suitable for use in 1178c2ecf20Sopenharmony_ci * header_ops.parse 1188c2ecf20Sopenharmony_ci */ 1198c2ecf20Sopenharmony_ciint ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ciint ieee802154_max_payload(const struct ieee802154_hdr *hdr); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic inline int 1248c2ecf20Sopenharmony_ciieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci switch (sec->level) { 1278c2ecf20Sopenharmony_ci case IEEE802154_SCF_SECLEVEL_MIC32: 1288c2ecf20Sopenharmony_ci case IEEE802154_SCF_SECLEVEL_ENC_MIC32: 1298c2ecf20Sopenharmony_ci return 4; 1308c2ecf20Sopenharmony_ci case IEEE802154_SCF_SECLEVEL_MIC64: 1318c2ecf20Sopenharmony_ci case IEEE802154_SCF_SECLEVEL_ENC_MIC64: 1328c2ecf20Sopenharmony_ci return 8; 1338c2ecf20Sopenharmony_ci case IEEE802154_SCF_SECLEVEL_MIC128: 1348c2ecf20Sopenharmony_ci case IEEE802154_SCF_SECLEVEL_ENC_MIC128: 1358c2ecf20Sopenharmony_ci return 16; 1368c2ecf20Sopenharmony_ci case IEEE802154_SCF_SECLEVEL_NONE: 1378c2ecf20Sopenharmony_ci case IEEE802154_SCF_SECLEVEL_ENC: 1388c2ecf20Sopenharmony_ci default: 1398c2ecf20Sopenharmony_ci return 0; 1408c2ecf20Sopenharmony_ci } 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistatic inline int ieee802154_hdr_length(struct sk_buff *skb) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci struct ieee802154_hdr hdr; 1468c2ecf20Sopenharmony_ci int len = ieee802154_hdr_pull(skb, &hdr); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci if (len > 0) 1498c2ecf20Sopenharmony_ci skb_push(skb, len); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci return len; 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1, 1558c2ecf20Sopenharmony_ci const struct ieee802154_addr *a2) 1568c2ecf20Sopenharmony_ci{ 1578c2ecf20Sopenharmony_ci if (a1->pan_id != a2->pan_id || a1->mode != a2->mode) 1588c2ecf20Sopenharmony_ci return false; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci if ((a1->mode == IEEE802154_ADDR_LONG && 1618c2ecf20Sopenharmony_ci a1->extended_addr != a2->extended_addr) || 1628c2ecf20Sopenharmony_ci (a1->mode == IEEE802154_ADDR_SHORT && 1638c2ecf20Sopenharmony_ci a1->short_addr != a2->short_addr)) 1648c2ecf20Sopenharmony_ci return false; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci return true; 1678c2ecf20Sopenharmony_ci} 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic inline __le64 ieee802154_devaddr_from_raw(const void *raw) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci u64 temp; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci memcpy(&temp, raw, IEEE802154_ADDR_LEN); 1748c2ecf20Sopenharmony_ci return (__force __le64)swab64(temp); 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci u64 temp = swab64((__force u64)addr); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci memcpy(raw, &temp, IEEE802154_ADDR_LEN); 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistatic inline int 1858c2ecf20Sopenharmony_ciieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci struct ieee802154_addr_sa *sa; 1888c2ecf20Sopenharmony_ci int ret = 0; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci sa = &daddr->addr; 1918c2ecf20Sopenharmony_ci if (len < IEEE802154_MIN_NAMELEN) 1928c2ecf20Sopenharmony_ci return -EINVAL; 1938c2ecf20Sopenharmony_ci switch (sa->addr_type) { 1948c2ecf20Sopenharmony_ci case IEEE802154_ADDR_NONE: 1958c2ecf20Sopenharmony_ci break; 1968c2ecf20Sopenharmony_ci case IEEE802154_ADDR_SHORT: 1978c2ecf20Sopenharmony_ci if (len < IEEE802154_NAMELEN_SHORT) 1988c2ecf20Sopenharmony_ci ret = -EINVAL; 1998c2ecf20Sopenharmony_ci break; 2008c2ecf20Sopenharmony_ci case IEEE802154_ADDR_LONG: 2018c2ecf20Sopenharmony_ci if (len < IEEE802154_NAMELEN_LONG) 2028c2ecf20Sopenharmony_ci ret = -EINVAL; 2038c2ecf20Sopenharmony_ci break; 2048c2ecf20Sopenharmony_ci default: 2058c2ecf20Sopenharmony_ci ret = -EINVAL; 2068c2ecf20Sopenharmony_ci break; 2078c2ecf20Sopenharmony_ci } 2088c2ecf20Sopenharmony_ci return ret; 2098c2ecf20Sopenharmony_ci} 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_cistatic inline void ieee802154_addr_from_sa(struct ieee802154_addr *a, 2128c2ecf20Sopenharmony_ci const struct ieee802154_addr_sa *sa) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci a->mode = sa->addr_type; 2158c2ecf20Sopenharmony_ci a->pan_id = cpu_to_le16(sa->pan_id); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci switch (a->mode) { 2188c2ecf20Sopenharmony_ci case IEEE802154_ADDR_SHORT: 2198c2ecf20Sopenharmony_ci a->short_addr = cpu_to_le16(sa->short_addr); 2208c2ecf20Sopenharmony_ci break; 2218c2ecf20Sopenharmony_ci case IEEE802154_ADDR_LONG: 2228c2ecf20Sopenharmony_ci a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr); 2238c2ecf20Sopenharmony_ci break; 2248c2ecf20Sopenharmony_ci } 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa, 2288c2ecf20Sopenharmony_ci const struct ieee802154_addr *a) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci sa->addr_type = a->mode; 2318c2ecf20Sopenharmony_ci sa->pan_id = le16_to_cpu(a->pan_id); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci switch (a->mode) { 2348c2ecf20Sopenharmony_ci case IEEE802154_ADDR_SHORT: 2358c2ecf20Sopenharmony_ci sa->short_addr = le16_to_cpu(a->short_addr); 2368c2ecf20Sopenharmony_ci break; 2378c2ecf20Sopenharmony_ci case IEEE802154_ADDR_LONG: 2388c2ecf20Sopenharmony_ci ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr); 2398c2ecf20Sopenharmony_ci break; 2408c2ecf20Sopenharmony_ci } 2418c2ecf20Sopenharmony_ci} 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci/* 2448c2ecf20Sopenharmony_ci * A control block of skb passed between the ARPHRD_IEEE802154 device 2458c2ecf20Sopenharmony_ci * and other stack parts. 2468c2ecf20Sopenharmony_ci */ 2478c2ecf20Sopenharmony_cistruct ieee802154_mac_cb { 2488c2ecf20Sopenharmony_ci u8 lqi; 2498c2ecf20Sopenharmony_ci u8 type; 2508c2ecf20Sopenharmony_ci bool ackreq; 2518c2ecf20Sopenharmony_ci bool secen; 2528c2ecf20Sopenharmony_ci bool secen_override; 2538c2ecf20Sopenharmony_ci u8 seclevel; 2548c2ecf20Sopenharmony_ci bool seclevel_override; 2558c2ecf20Sopenharmony_ci struct ieee802154_addr source; 2568c2ecf20Sopenharmony_ci struct ieee802154_addr dest; 2578c2ecf20Sopenharmony_ci}; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_cistatic inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb) 2608c2ecf20Sopenharmony_ci{ 2618c2ecf20Sopenharmony_ci return (struct ieee802154_mac_cb *)skb->cb; 2628c2ecf20Sopenharmony_ci} 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_cistatic inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb) 2658c2ecf20Sopenharmony_ci{ 2668c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb)); 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb)); 2698c2ecf20Sopenharmony_ci return mac_cb(skb); 2708c2ecf20Sopenharmony_ci} 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cienum { 2738c2ecf20Sopenharmony_ci IEEE802154_LLSEC_DEVKEY_IGNORE, 2748c2ecf20Sopenharmony_ci IEEE802154_LLSEC_DEVKEY_RESTRICT, 2758c2ecf20Sopenharmony_ci IEEE802154_LLSEC_DEVKEY_RECORD, 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci __IEEE802154_LLSEC_DEVKEY_MAX, 2788c2ecf20Sopenharmony_ci}; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci#define IEEE802154_MAC_SCAN_ED 0 2818c2ecf20Sopenharmony_ci#define IEEE802154_MAC_SCAN_ACTIVE 1 2828c2ecf20Sopenharmony_ci#define IEEE802154_MAC_SCAN_PASSIVE 2 2838c2ecf20Sopenharmony_ci#define IEEE802154_MAC_SCAN_ORPHAN 3 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_cistruct ieee802154_mac_params { 2868c2ecf20Sopenharmony_ci s8 transmit_power; 2878c2ecf20Sopenharmony_ci u8 min_be; 2888c2ecf20Sopenharmony_ci u8 max_be; 2898c2ecf20Sopenharmony_ci u8 csma_retries; 2908c2ecf20Sopenharmony_ci s8 frame_retries; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci bool lbt; 2938c2ecf20Sopenharmony_ci struct wpan_phy_cca cca; 2948c2ecf20Sopenharmony_ci s32 cca_ed_level; 2958c2ecf20Sopenharmony_ci}; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cistruct wpan_phy; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cienum { 3008c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_ENABLED = BIT(0), 3018c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_FRAME_COUNTER = BIT(1), 3028c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_OUT_LEVEL = BIT(2), 3038c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_OUT_KEY = BIT(3), 3048c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_KEY_SOURCE = BIT(4), 3058c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_PAN_ID = BIT(5), 3068c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_HWADDR = BIT(6), 3078c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_COORD_HWADDR = BIT(7), 3088c2ecf20Sopenharmony_ci IEEE802154_LLSEC_PARAM_COORD_SHORTADDR = BIT(8), 3098c2ecf20Sopenharmony_ci}; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistruct ieee802154_llsec_ops { 3128c2ecf20Sopenharmony_ci int (*get_params)(struct net_device *dev, 3138c2ecf20Sopenharmony_ci struct ieee802154_llsec_params *params); 3148c2ecf20Sopenharmony_ci int (*set_params)(struct net_device *dev, 3158c2ecf20Sopenharmony_ci const struct ieee802154_llsec_params *params, 3168c2ecf20Sopenharmony_ci int changed); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci int (*add_key)(struct net_device *dev, 3198c2ecf20Sopenharmony_ci const struct ieee802154_llsec_key_id *id, 3208c2ecf20Sopenharmony_ci const struct ieee802154_llsec_key *key); 3218c2ecf20Sopenharmony_ci int (*del_key)(struct net_device *dev, 3228c2ecf20Sopenharmony_ci const struct ieee802154_llsec_key_id *id); 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci int (*add_dev)(struct net_device *dev, 3258c2ecf20Sopenharmony_ci const struct ieee802154_llsec_device *llsec_dev); 3268c2ecf20Sopenharmony_ci int (*del_dev)(struct net_device *dev, __le64 dev_addr); 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci int (*add_devkey)(struct net_device *dev, 3298c2ecf20Sopenharmony_ci __le64 device_addr, 3308c2ecf20Sopenharmony_ci const struct ieee802154_llsec_device_key *key); 3318c2ecf20Sopenharmony_ci int (*del_devkey)(struct net_device *dev, 3328c2ecf20Sopenharmony_ci __le64 device_addr, 3338c2ecf20Sopenharmony_ci const struct ieee802154_llsec_device_key *key); 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci int (*add_seclevel)(struct net_device *dev, 3368c2ecf20Sopenharmony_ci const struct ieee802154_llsec_seclevel *sl); 3378c2ecf20Sopenharmony_ci int (*del_seclevel)(struct net_device *dev, 3388c2ecf20Sopenharmony_ci const struct ieee802154_llsec_seclevel *sl); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci void (*lock_table)(struct net_device *dev); 3418c2ecf20Sopenharmony_ci void (*get_table)(struct net_device *dev, 3428c2ecf20Sopenharmony_ci struct ieee802154_llsec_table **t); 3438c2ecf20Sopenharmony_ci void (*unlock_table)(struct net_device *dev); 3448c2ecf20Sopenharmony_ci}; 3458c2ecf20Sopenharmony_ci/* 3468c2ecf20Sopenharmony_ci * This should be located at net_device->ml_priv 3478c2ecf20Sopenharmony_ci * 3488c2ecf20Sopenharmony_ci * get_phy should increment the reference counting on returned phy. 3498c2ecf20Sopenharmony_ci * Use wpan_wpy_put to put that reference. 3508c2ecf20Sopenharmony_ci */ 3518c2ecf20Sopenharmony_cistruct ieee802154_mlme_ops { 3528c2ecf20Sopenharmony_ci /* The following fields are optional (can be NULL). */ 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci int (*assoc_req)(struct net_device *dev, 3558c2ecf20Sopenharmony_ci struct ieee802154_addr *addr, 3568c2ecf20Sopenharmony_ci u8 channel, u8 page, u8 cap); 3578c2ecf20Sopenharmony_ci int (*assoc_resp)(struct net_device *dev, 3588c2ecf20Sopenharmony_ci struct ieee802154_addr *addr, 3598c2ecf20Sopenharmony_ci __le16 short_addr, u8 status); 3608c2ecf20Sopenharmony_ci int (*disassoc_req)(struct net_device *dev, 3618c2ecf20Sopenharmony_ci struct ieee802154_addr *addr, 3628c2ecf20Sopenharmony_ci u8 reason); 3638c2ecf20Sopenharmony_ci int (*start_req)(struct net_device *dev, 3648c2ecf20Sopenharmony_ci struct ieee802154_addr *addr, 3658c2ecf20Sopenharmony_ci u8 channel, u8 page, u8 bcn_ord, u8 sf_ord, 3668c2ecf20Sopenharmony_ci u8 pan_coord, u8 blx, u8 coord_realign); 3678c2ecf20Sopenharmony_ci int (*scan_req)(struct net_device *dev, 3688c2ecf20Sopenharmony_ci u8 type, u32 channels, u8 page, u8 duration); 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci int (*set_mac_params)(struct net_device *dev, 3718c2ecf20Sopenharmony_ci const struct ieee802154_mac_params *params); 3728c2ecf20Sopenharmony_ci void (*get_mac_params)(struct net_device *dev, 3738c2ecf20Sopenharmony_ci struct ieee802154_mac_params *params); 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci const struct ieee802154_llsec_ops *llsec; 3768c2ecf20Sopenharmony_ci}; 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_cistatic inline struct ieee802154_mlme_ops * 3798c2ecf20Sopenharmony_ciieee802154_mlme_ops(const struct net_device *dev) 3808c2ecf20Sopenharmony_ci{ 3818c2ecf20Sopenharmony_ci return dev->ml_priv; 3828c2ecf20Sopenharmony_ci} 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci#endif 385