xref: /linux/include/net/ieee802154_netdev.h (revision 4949009eb8d40a441dcddcd96e101e77d31cf1b2)
1 /*
2  * An interface between IEEE802.15.4 device and rest of the kernel.
3  *
4  * Copyright (C) 2007-2012 Siemens AG
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * Written by:
16  * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
17  * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
18  * Maxim Osipov <maxim.osipov@siemens.com>
19  * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
20  * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
21  */
22 
23 #ifndef IEEE802154_NETDEVICE_H
24 #define IEEE802154_NETDEVICE_H
25 
26 #include <net/af_ieee802154.h>
27 #include <linux/netdevice.h>
28 #include <linux/skbuff.h>
29 #include <linux/ieee802154.h>
30 
31 struct ieee802154_sechdr {
32 #if defined(__LITTLE_ENDIAN_BITFIELD)
33 	u8 level:3,
34 	   key_id_mode:2,
35 	   reserved:3;
36 #elif defined(__BIG_ENDIAN_BITFIELD)
37 	u8 reserved:3,
38 	   key_id_mode:2,
39 	   level:3;
40 #else
41 #error	"Please fix <asm/byteorder.h>"
42 #endif
43 	u8 key_id;
44 	__le32 frame_counter;
45 	union {
46 		__le32 short_src;
47 		__le64 extended_src;
48 	};
49 };
50 
51 struct ieee802154_addr {
52 	u8 mode;
53 	__le16 pan_id;
54 	union {
55 		__le16 short_addr;
56 		__le64 extended_addr;
57 	};
58 };
59 
60 struct ieee802154_hdr_fc {
61 #if defined(__LITTLE_ENDIAN_BITFIELD)
62 	u16 type:3,
63 	    security_enabled:1,
64 	    frame_pending:1,
65 	    ack_request:1,
66 	    intra_pan:1,
67 	    reserved:3,
68 	    dest_addr_mode:2,
69 	    version:2,
70 	    source_addr_mode:2;
71 #elif defined(__BIG_ENDIAN_BITFIELD)
72 	u16 reserved:1,
73 	    intra_pan:1,
74 	    ack_request:1,
75 	    frame_pending:1,
76 	    security_enabled:1,
77 	    type:3,
78 	    source_addr_mode:2,
79 	    version:2,
80 	    dest_addr_mode:2,
81 	    reserved2:2;
82 #else
83 #error	"Please fix <asm/byteorder.h>"
84 #endif
85 };
86 
87 struct ieee802154_hdr {
88 	struct ieee802154_hdr_fc fc;
89 	u8 seq;
90 	struct ieee802154_addr source;
91 	struct ieee802154_addr dest;
92 	struct ieee802154_sechdr sec;
93 };
94 
95 /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
96  * the contents of hdr will be, and the actual value of those bits in
97  * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
98  * version, if SECEN is set.
99  */
100 int ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr);
101 
102 /* pulls the entire 802.15.4 header off of the skb, including the security
103  * header, and performs pan id decompression
104  */
105 int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr);
106 
107 /* parses the frame control, sequence number of address fields in a given skb
108  * and stores them into hdr, performing pan id decompression and length checks
109  * to be suitable for use in header_ops.parse
110  */
111 int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
112 			      struct ieee802154_hdr *hdr);
113 
114 /* parses the full 802.15.4 header a given skb and stores them into hdr,
115  * performing pan id decompression and length checks to be suitable for use in
116  * header_ops.parse
117  */
118 int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
119 
120 int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
121 
122 static inline int
123 ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec)
124 {
125 	switch (sec->level) {
126 	case IEEE802154_SCF_SECLEVEL_MIC32:
127 	case IEEE802154_SCF_SECLEVEL_ENC_MIC32:
128 		return 4;
129 	case IEEE802154_SCF_SECLEVEL_MIC64:
130 	case IEEE802154_SCF_SECLEVEL_ENC_MIC64:
131 		return 8;
132 	case IEEE802154_SCF_SECLEVEL_MIC128:
133 	case IEEE802154_SCF_SECLEVEL_ENC_MIC128:
134 		return 16;
135 	case IEEE802154_SCF_SECLEVEL_NONE:
136 	case IEEE802154_SCF_SECLEVEL_ENC:
137 	default:
138 		return 0;
139 	}
140 }
141 
142 static inline int ieee802154_hdr_length(struct sk_buff *skb)
143 {
144 	struct ieee802154_hdr hdr;
145 	int len = ieee802154_hdr_pull(skb, &hdr);
146 
147 	if (len > 0)
148 		skb_push(skb, len);
149 
150 	return len;
151 }
152 
153 static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1,
154 					 const struct ieee802154_addr *a2)
155 {
156 	if (a1->pan_id != a2->pan_id || a1->mode != a2->mode)
157 		return false;
158 
159 	if ((a1->mode == IEEE802154_ADDR_LONG &&
160 	     a1->extended_addr != a2->extended_addr) ||
161 	    (a1->mode == IEEE802154_ADDR_SHORT &&
162 	     a1->short_addr != a2->short_addr))
163 		return false;
164 
165 	return true;
166 }
167 
168 static inline __le64 ieee802154_devaddr_from_raw(const void *raw)
169 {
170 	u64 temp;
171 
172 	memcpy(&temp, raw, IEEE802154_ADDR_LEN);
173 	return (__force __le64)swab64(temp);
174 }
175 
176 static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr)
177 {
178 	u64 temp = swab64((__force u64)addr);
179 
180 	memcpy(raw, &temp, IEEE802154_ADDR_LEN);
181 }
182 
183 static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
184 					   const struct ieee802154_addr_sa *sa)
185 {
186 	a->mode = sa->addr_type;
187 	a->pan_id = cpu_to_le16(sa->pan_id);
188 
189 	switch (a->mode) {
190 	case IEEE802154_ADDR_SHORT:
191 		a->short_addr = cpu_to_le16(sa->short_addr);
192 		break;
193 	case IEEE802154_ADDR_LONG:
194 		a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr);
195 		break;
196 	}
197 }
198 
199 static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa,
200 					 const struct ieee802154_addr *a)
201 {
202 	sa->addr_type = a->mode;
203 	sa->pan_id = le16_to_cpu(a->pan_id);
204 
205 	switch (a->mode) {
206 	case IEEE802154_ADDR_SHORT:
207 		sa->short_addr = le16_to_cpu(a->short_addr);
208 		break;
209 	case IEEE802154_ADDR_LONG:
210 		ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr);
211 		break;
212 	}
213 }
214 
215 /*
216  * A control block of skb passed between the ARPHRD_IEEE802154 device
217  * and other stack parts.
218  */
219 struct ieee802154_mac_cb {
220 	u8 lqi;
221 	u8 type;
222 	bool ackreq;
223 	bool secen;
224 	bool secen_override;
225 	u8 seclevel;
226 	bool seclevel_override;
227 	struct ieee802154_addr source;
228 	struct ieee802154_addr dest;
229 };
230 
231 static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
232 {
233 	return (struct ieee802154_mac_cb *)skb->cb;
234 }
235 
236 static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb)
237 {
238 	BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb));
239 
240 	memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb));
241 	return mac_cb(skb);
242 }
243 
244 #define IEEE802154_LLSEC_KEY_SIZE 16
245 
246 struct ieee802154_llsec_key_id {
247 	u8 mode;
248 	u8 id;
249 	union {
250 		struct ieee802154_addr device_addr;
251 		__le32 short_source;
252 		__le64 extended_source;
253 	};
254 };
255 
256 struct ieee802154_llsec_key {
257 	u8 frame_types;
258 	u32 cmd_frame_ids;
259 	u8 key[IEEE802154_LLSEC_KEY_SIZE];
260 };
261 
262 struct ieee802154_llsec_key_entry {
263 	struct list_head list;
264 
265 	struct ieee802154_llsec_key_id id;
266 	struct ieee802154_llsec_key *key;
267 };
268 
269 struct ieee802154_llsec_device_key {
270 	struct list_head list;
271 
272 	struct ieee802154_llsec_key_id key_id;
273 	u32 frame_counter;
274 };
275 
276 enum {
277 	IEEE802154_LLSEC_DEVKEY_IGNORE,
278 	IEEE802154_LLSEC_DEVKEY_RESTRICT,
279 	IEEE802154_LLSEC_DEVKEY_RECORD,
280 
281 	__IEEE802154_LLSEC_DEVKEY_MAX,
282 };
283 
284 struct ieee802154_llsec_device {
285 	struct list_head list;
286 
287 	__le16 pan_id;
288 	__le16 short_addr;
289 	__le64 hwaddr;
290 	u32 frame_counter;
291 	bool seclevel_exempt;
292 
293 	u8 key_mode;
294 	struct list_head keys;
295 };
296 
297 struct ieee802154_llsec_seclevel {
298 	struct list_head list;
299 
300 	u8 frame_type;
301 	u8 cmd_frame_id;
302 	bool device_override;
303 	u32 sec_levels;
304 };
305 
306 struct ieee802154_llsec_params {
307 	bool enabled;
308 
309 	__be32 frame_counter;
310 	u8 out_level;
311 	struct ieee802154_llsec_key_id out_key;
312 
313 	__le64 default_key_source;
314 
315 	__le16 pan_id;
316 	__le64 hwaddr;
317 	__le64 coord_hwaddr;
318 	__le16 coord_shortaddr;
319 };
320 
321 struct ieee802154_llsec_table {
322 	struct list_head keys;
323 	struct list_head devices;
324 	struct list_head security_levels;
325 };
326 
327 #define IEEE802154_MAC_SCAN_ED		0
328 #define IEEE802154_MAC_SCAN_ACTIVE	1
329 #define IEEE802154_MAC_SCAN_PASSIVE	2
330 #define IEEE802154_MAC_SCAN_ORPHAN	3
331 
332 struct ieee802154_mac_params {
333 	s8 transmit_power;
334 	u8 min_be;
335 	u8 max_be;
336 	u8 csma_retries;
337 	s8 frame_retries;
338 
339 	bool lbt;
340 	u8 cca_mode;
341 	s32 cca_ed_level;
342 };
343 
344 struct wpan_phy;
345 
346 enum {
347 	IEEE802154_LLSEC_PARAM_ENABLED = 1 << 0,
348 	IEEE802154_LLSEC_PARAM_FRAME_COUNTER = 1 << 1,
349 	IEEE802154_LLSEC_PARAM_OUT_LEVEL = 1 << 2,
350 	IEEE802154_LLSEC_PARAM_OUT_KEY = 1 << 3,
351 	IEEE802154_LLSEC_PARAM_KEY_SOURCE = 1 << 4,
352 	IEEE802154_LLSEC_PARAM_PAN_ID = 1 << 5,
353 	IEEE802154_LLSEC_PARAM_HWADDR = 1 << 6,
354 	IEEE802154_LLSEC_PARAM_COORD_HWADDR = 1 << 7,
355 	IEEE802154_LLSEC_PARAM_COORD_SHORTADDR = 1 << 8,
356 };
357 
358 struct ieee802154_llsec_ops {
359 	int (*get_params)(struct net_device *dev,
360 			  struct ieee802154_llsec_params *params);
361 	int (*set_params)(struct net_device *dev,
362 			  const struct ieee802154_llsec_params *params,
363 			  int changed);
364 
365 	int (*add_key)(struct net_device *dev,
366 		       const struct ieee802154_llsec_key_id *id,
367 		       const struct ieee802154_llsec_key *key);
368 	int (*del_key)(struct net_device *dev,
369 		       const struct ieee802154_llsec_key_id *id);
370 
371 	int (*add_dev)(struct net_device *dev,
372 		       const struct ieee802154_llsec_device *llsec_dev);
373 	int (*del_dev)(struct net_device *dev, __le64 dev_addr);
374 
375 	int (*add_devkey)(struct net_device *dev,
376 			  __le64 device_addr,
377 			  const struct ieee802154_llsec_device_key *key);
378 	int (*del_devkey)(struct net_device *dev,
379 			  __le64 device_addr,
380 			  const struct ieee802154_llsec_device_key *key);
381 
382 	int (*add_seclevel)(struct net_device *dev,
383 			    const struct ieee802154_llsec_seclevel *sl);
384 	int (*del_seclevel)(struct net_device *dev,
385 			    const struct ieee802154_llsec_seclevel *sl);
386 
387 	void (*lock_table)(struct net_device *dev);
388 	void (*get_table)(struct net_device *dev,
389 			  struct ieee802154_llsec_table **t);
390 	void (*unlock_table)(struct net_device *dev);
391 };
392 /*
393  * This should be located at net_device->ml_priv
394  *
395  * get_phy should increment the reference counting on returned phy.
396  * Use wpan_wpy_put to put that reference.
397  */
398 struct ieee802154_mlme_ops {
399 	/* The following fields are optional (can be NULL). */
400 
401 	int (*assoc_req)(struct net_device *dev,
402 			struct ieee802154_addr *addr,
403 			u8 channel, u8 page, u8 cap);
404 	int (*assoc_resp)(struct net_device *dev,
405 			struct ieee802154_addr *addr,
406 			__le16 short_addr, u8 status);
407 	int (*disassoc_req)(struct net_device *dev,
408 			struct ieee802154_addr *addr,
409 			u8 reason);
410 	int (*start_req)(struct net_device *dev,
411 			struct ieee802154_addr *addr,
412 			u8 channel, u8 page, u8 bcn_ord, u8 sf_ord,
413 			u8 pan_coord, u8 blx, u8 coord_realign);
414 	int (*scan_req)(struct net_device *dev,
415 			u8 type, u32 channels, u8 page, u8 duration);
416 
417 	int (*set_mac_params)(struct net_device *dev,
418 			      const struct ieee802154_mac_params *params);
419 	void (*get_mac_params)(struct net_device *dev,
420 			       struct ieee802154_mac_params *params);
421 
422 	struct ieee802154_llsec_ops *llsec;
423 
424 	/* The fields below are required. */
425 
426 	/*
427 	 * FIXME: these should become the part of PIB/MIB interface.
428 	 * However we still don't have IB interface of any kind
429 	 */
430 	__le16 (*get_pan_id)(const struct net_device *dev);
431 	__le16 (*get_short_addr)(const struct net_device *dev);
432 	u8 (*get_dsn)(const struct net_device *dev);
433 };
434 
435 static inline struct ieee802154_mlme_ops *
436 ieee802154_mlme_ops(const struct net_device *dev)
437 {
438 	return dev->ml_priv;
439 }
440 
441 static inline struct ieee802154_reduced_mlme_ops *
442 ieee802154_reduced_mlme_ops(const struct net_device *dev)
443 {
444 	return dev->ml_priv;
445 }
446 
447 #endif
448