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
41struct 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
77struct ieee802154_mac_cmd_pl {
78	u8  cmd_id;
79} __packed;
80
81struct 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
101struct 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
128enum ieee802154_frame_version {
129	IEEE802154_2003_STD,
130	IEEE802154_2006_STD,
131	IEEE802154_STD,
132	IEEE802154_RESERVED_STD,
133	IEEE802154_MULTIPURPOSE_STD = IEEE802154_2003_STD,
134};
135
136enum ieee802154_addressing_mode {
137	IEEE802154_NO_ADDRESSING,
138	IEEE802154_RESERVED,
139	IEEE802154_SHORT_ADDRESSING,
140	IEEE802154_EXTENDED_ADDRESSING,
141};
142
143struct ieee802154_hdr {
144	struct ieee802154_hdr_fc fc;
145	u8 seq;
146	struct ieee802154_addr source;
147	struct ieee802154_addr dest;
148	struct ieee802154_sechdr sec;
149};
150
151struct ieee802154_beacon_frame {
152	struct ieee802154_hdr mhr;
153	struct ieee802154_beacon_hdr mac_pl;
154};
155
156struct ieee802154_mac_cmd_frame {
157	struct ieee802154_hdr mhr;
158	struct ieee802154_mac_cmd_pl mac_pl;
159};
160
161struct ieee802154_beacon_req_frame {
162	struct ieee802154_hdr mhr;
163	struct ieee802154_mac_cmd_pl mac_pl;
164};
165
166/* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
167 * the contents of hdr will be, and the actual value of those bits in
168 * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
169 * version, if SECEN is set.
170 */
171int ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr);
172
173/* pulls the entire 802.15.4 header off of the skb, including the security
174 * header, and performs pan id decompression
175 */
176int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr);
177
178/* parses the frame control, sequence number of address fields in a given skb
179 * and stores them into hdr, performing pan id decompression and length checks
180 * to be suitable for use in header_ops.parse
181 */
182int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
183			      struct ieee802154_hdr *hdr);
184
185/* parses the full 802.15.4 header a given skb and stores them into hdr,
186 * performing pan id decompression and length checks to be suitable for use in
187 * header_ops.parse
188 */
189int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
190
191/* pushes/pulls various frame types into/from an skb */
192int ieee802154_beacon_push(struct sk_buff *skb,
193			   struct ieee802154_beacon_frame *beacon);
194int ieee802154_mac_cmd_push(struct sk_buff *skb, void *frame,
195			    const void *pl, unsigned int pl_len);
196int ieee802154_mac_cmd_pl_pull(struct sk_buff *skb,
197			       struct ieee802154_mac_cmd_pl *mac_pl);
198
199int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
200
201static inline int
202ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec)
203{
204	switch (sec->level) {
205	case IEEE802154_SCF_SECLEVEL_MIC32:
206	case IEEE802154_SCF_SECLEVEL_ENC_MIC32:
207		return 4;
208	case IEEE802154_SCF_SECLEVEL_MIC64:
209	case IEEE802154_SCF_SECLEVEL_ENC_MIC64:
210		return 8;
211	case IEEE802154_SCF_SECLEVEL_MIC128:
212	case IEEE802154_SCF_SECLEVEL_ENC_MIC128:
213		return 16;
214	case IEEE802154_SCF_SECLEVEL_NONE:
215	case IEEE802154_SCF_SECLEVEL_ENC:
216	default:
217		return 0;
218	}
219}
220
221static inline int ieee802154_hdr_length(struct sk_buff *skb)
222{
223	struct ieee802154_hdr hdr;
224	int len = ieee802154_hdr_pull(skb, &hdr);
225
226	if (len > 0)
227		skb_push(skb, len);
228
229	return len;
230}
231
232static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1,
233					 const struct ieee802154_addr *a2)
234{
235	if (a1->pan_id != a2->pan_id || a1->mode != a2->mode)
236		return false;
237
238	if ((a1->mode == IEEE802154_ADDR_LONG &&
239	     a1->extended_addr != a2->extended_addr) ||
240	    (a1->mode == IEEE802154_ADDR_SHORT &&
241	     a1->short_addr != a2->short_addr))
242		return false;
243
244	return true;
245}
246
247static inline __le64 ieee802154_devaddr_from_raw(const void *raw)
248{
249	u64 temp;
250
251	memcpy(&temp, raw, IEEE802154_ADDR_LEN);
252	return (__force __le64)swab64(temp);
253}
254
255static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr)
256{
257	u64 temp = swab64((__force u64)addr);
258
259	memcpy(raw, &temp, IEEE802154_ADDR_LEN);
260}
261
262static inline int
263ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len)
264{
265	struct ieee802154_addr_sa *sa;
266	int ret = 0;
267
268	sa = &daddr->addr;
269	if (len < IEEE802154_MIN_NAMELEN)
270		return -EINVAL;
271	switch (sa->addr_type) {
272	case IEEE802154_ADDR_NONE:
273		break;
274	case IEEE802154_ADDR_SHORT:
275		if (len < IEEE802154_NAMELEN_SHORT)
276			ret = -EINVAL;
277		break;
278	case IEEE802154_ADDR_LONG:
279		if (len < IEEE802154_NAMELEN_LONG)
280			ret = -EINVAL;
281		break;
282	default:
283		ret = -EINVAL;
284		break;
285	}
286	return ret;
287}
288
289static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
290					   const struct ieee802154_addr_sa *sa)
291{
292	a->mode = sa->addr_type;
293	a->pan_id = cpu_to_le16(sa->pan_id);
294
295	switch (a->mode) {
296	case IEEE802154_ADDR_SHORT:
297		a->short_addr = cpu_to_le16(sa->short_addr);
298		break;
299	case IEEE802154_ADDR_LONG:
300		a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr);
301		break;
302	}
303}
304
305static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa,
306					 const struct ieee802154_addr *a)
307{
308	sa->addr_type = a->mode;
309	sa->pan_id = le16_to_cpu(a->pan_id);
310
311	switch (a->mode) {
312	case IEEE802154_ADDR_SHORT:
313		sa->short_addr = le16_to_cpu(a->short_addr);
314		break;
315	case IEEE802154_ADDR_LONG:
316		ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr);
317		break;
318	}
319}
320
321/*
322 * A control block of skb passed between the ARPHRD_IEEE802154 device
323 * and other stack parts.
324 */
325struct ieee802154_mac_cb {
326	u8 lqi;
327	u8 type;
328	bool ackreq;
329	bool secen;
330	bool secen_override;
331	u8 seclevel;
332	bool seclevel_override;
333	struct ieee802154_addr source;
334	struct ieee802154_addr dest;
335};
336
337static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
338{
339	return (struct ieee802154_mac_cb *)skb->cb;
340}
341
342static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb)
343{
344	BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb));
345
346	memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb));
347	return mac_cb(skb);
348}
349
350enum {
351	IEEE802154_LLSEC_DEVKEY_IGNORE,
352	IEEE802154_LLSEC_DEVKEY_RESTRICT,
353	IEEE802154_LLSEC_DEVKEY_RECORD,
354
355	__IEEE802154_LLSEC_DEVKEY_MAX,
356};
357
358#define IEEE802154_MAC_SCAN_ED		0
359#define IEEE802154_MAC_SCAN_ACTIVE	1
360#define IEEE802154_MAC_SCAN_PASSIVE	2
361#define IEEE802154_MAC_SCAN_ORPHAN	3
362
363struct ieee802154_mac_params {
364	s8 transmit_power;
365	u8 min_be;
366	u8 max_be;
367	u8 csma_retries;
368	s8 frame_retries;
369
370	bool lbt;
371	struct wpan_phy_cca cca;
372	s32 cca_ed_level;
373};
374
375struct wpan_phy;
376
377enum {
378	IEEE802154_LLSEC_PARAM_ENABLED		= BIT(0),
379	IEEE802154_LLSEC_PARAM_FRAME_COUNTER	= BIT(1),
380	IEEE802154_LLSEC_PARAM_OUT_LEVEL	= BIT(2),
381	IEEE802154_LLSEC_PARAM_OUT_KEY		= BIT(3),
382	IEEE802154_LLSEC_PARAM_KEY_SOURCE	= BIT(4),
383	IEEE802154_LLSEC_PARAM_PAN_ID		= BIT(5),
384	IEEE802154_LLSEC_PARAM_HWADDR		= BIT(6),
385	IEEE802154_LLSEC_PARAM_COORD_HWADDR	= BIT(7),
386	IEEE802154_LLSEC_PARAM_COORD_SHORTADDR	= BIT(8),
387};
388
389struct ieee802154_llsec_ops {
390	int (*get_params)(struct net_device *dev,
391			  struct ieee802154_llsec_params *params);
392	int (*set_params)(struct net_device *dev,
393			  const struct ieee802154_llsec_params *params,
394			  int changed);
395
396	int (*add_key)(struct net_device *dev,
397		       const struct ieee802154_llsec_key_id *id,
398		       const struct ieee802154_llsec_key *key);
399	int (*del_key)(struct net_device *dev,
400		       const struct ieee802154_llsec_key_id *id);
401
402	int (*add_dev)(struct net_device *dev,
403		       const struct ieee802154_llsec_device *llsec_dev);
404	int (*del_dev)(struct net_device *dev, __le64 dev_addr);
405
406	int (*add_devkey)(struct net_device *dev,
407			  __le64 device_addr,
408			  const struct ieee802154_llsec_device_key *key);
409	int (*del_devkey)(struct net_device *dev,
410			  __le64 device_addr,
411			  const struct ieee802154_llsec_device_key *key);
412
413	int (*add_seclevel)(struct net_device *dev,
414			    const struct ieee802154_llsec_seclevel *sl);
415	int (*del_seclevel)(struct net_device *dev,
416			    const struct ieee802154_llsec_seclevel *sl);
417
418	void (*lock_table)(struct net_device *dev);
419	void (*get_table)(struct net_device *dev,
420			  struct ieee802154_llsec_table **t);
421	void (*unlock_table)(struct net_device *dev);
422};
423/*
424 * This should be located at net_device->ml_priv
425 *
426 * get_phy should increment the reference counting on returned phy.
427 * Use wpan_wpy_put to put that reference.
428 */
429struct ieee802154_mlme_ops {
430	/* The following fields are optional (can be NULL). */
431
432	int (*assoc_req)(struct net_device *dev,
433			struct ieee802154_addr *addr,
434			u8 channel, u8 page, u8 cap);
435	int (*assoc_resp)(struct net_device *dev,
436			struct ieee802154_addr *addr,
437			__le16 short_addr, u8 status);
438	int (*disassoc_req)(struct net_device *dev,
439			struct ieee802154_addr *addr,
440			u8 reason);
441	int (*start_req)(struct net_device *dev,
442			struct ieee802154_addr *addr,
443			u8 channel, u8 page, u8 bcn_ord, u8 sf_ord,
444			u8 pan_coord, u8 blx, u8 coord_realign);
445	int (*scan_req)(struct net_device *dev,
446			u8 type, u32 channels, u8 page, u8 duration);
447
448	int (*set_mac_params)(struct net_device *dev,
449			      const struct ieee802154_mac_params *params);
450	void (*get_mac_params)(struct net_device *dev,
451			       struct ieee802154_mac_params *params);
452
453	const struct ieee802154_llsec_ops *llsec;
454};
455
456static inline struct ieee802154_mlme_ops *
457ieee802154_mlme_ops(const struct net_device *dev)
458{
459	return dev->ml_priv;
460}
461
462#endif
463