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