]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - include/net/ieee802154_netdev.h
ieee802154: move wpan-class.c to core.c
[mirror_ubuntu-eoan-kernel.git] / include / net / ieee802154_netdev.h
CommitLineData
9ec76716
SL
1/*
2 * An interface between IEEE802.15.4 device and rest of the kernel.
3 *
74a02fcf 4 * Copyright (C) 2007-2012 Siemens AG
9ec76716
SL
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 *
9ec76716
SL
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>
74a02fcf 20 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
9ec76716
SL
21 */
22
23#ifndef IEEE802154_NETDEVICE_H
24#define IEEE802154_NETDEVICE_H
25
c3a6114f 26#include <net/ieee802154.h>
1cd829c8 27#include <net/af_ieee802154.h>
94b4f6c2
PB
28#include <linux/netdevice.h>
29#include <linux/skbuff.h>
30
31struct 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};
1cd829c8 50
46ef0eb3
PB
51struct ieee802154_addr {
52 u8 mode;
53 __le16 pan_id;
54 union {
55 __le16 short_addr;
56 __le64 extended_addr;
57 };
58};
59
94b4f6c2
PB
60struct 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
87struct 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 */
100int 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 */
105int 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 */
111int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
112 struct ieee802154_hdr *hdr);
113
c3a6114f
PB
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 */
118int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
119
120int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
121
122static inline int
123ieee802154_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
94b4f6c2
PB
142static 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
46ef0eb3
PB
153static 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
168static 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
176static 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
183static 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
199static 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
9ec76716
SL
215/*
216 * A control block of skb passed between the ARPHRD_IEEE802154 device
217 * and other stack parts.
218 */
219struct ieee802154_mac_cb {
220 u8 lqi;
32edc40a
PB
221 u8 type;
222 bool ackreq;
223 bool secen;
f30be4d5
PB
224 bool secen_override;
225 u8 seclevel;
226 bool seclevel_override;
ae531b94
PB
227 struct ieee802154_addr source;
228 struct ieee802154_addr dest;
9ec76716
SL
229};
230
231static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
232{
233 return (struct ieee802154_mac_cb *)skb->cb;
234}
235
32edc40a 236static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb)
9ec76716 237{
32edc40a 238 BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb));
9ec76716 239
32edc40a
PB
240 memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb));
241 return mac_cb(skb);
9ec76716
SL
242}
243
dc20759f
PB
244#define IEEE802154_LLSEC_KEY_SIZE 16
245
246struct 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
256struct ieee802154_llsec_key {
257 u8 frame_types;
258 u32 cmd_frame_ids;
259 u8 key[IEEE802154_LLSEC_KEY_SIZE];
260};
261
262struct 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
269struct ieee802154_llsec_device_key {
270 struct list_head list;
271
272 struct ieee802154_llsec_key_id key_id;
273 u32 frame_counter;
274};
275
276enum {
277 IEEE802154_LLSEC_DEVKEY_IGNORE,
278 IEEE802154_LLSEC_DEVKEY_RESTRICT,
f0f77dc6 279 IEEE802154_LLSEC_DEVKEY_RECORD,
dc20759f
PB
280
281 __IEEE802154_LLSEC_DEVKEY_MAX,
282};
283
284struct 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
297struct 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
306struct 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
321struct ieee802154_llsec_table {
322 struct list_head keys;
323 struct list_head devices;
324 struct list_head security_levels;
325};
326
9ec76716
SL
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
e462ded6
PB
332struct 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
42723448 344struct wpan_phy;
dc20759f
PB
345
346enum {
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
29e02374
PB
358struct 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};
9ec76716
SL
392/*
393 * This should be located at net_device->ml_priv
42723448
DES
394 *
395 * get_phy should increment the reference counting on returned phy.
396 * Use wpan_wpy_put to put that reference.
9ec76716
SL
397 */
398struct ieee802154_mlme_ops {
56aa091d
WA
399 /* The following fields are optional (can be NULL). */
400
9ec76716 401 int (*assoc_req)(struct net_device *dev,
ae531b94 402 struct ieee802154_addr *addr,
16eea493 403 u8 channel, u8 page, u8 cap);
9ec76716 404 int (*assoc_resp)(struct net_device *dev,
ae531b94 405 struct ieee802154_addr *addr,
b70ab2e8 406 __le16 short_addr, u8 status);
9ec76716 407 int (*disassoc_req)(struct net_device *dev,
ae531b94 408 struct ieee802154_addr *addr,
9ec76716
SL
409 u8 reason);
410 int (*start_req)(struct net_device *dev,
ae531b94 411 struct ieee802154_addr *addr,
16eea493 412 u8 channel, u8 page, u8 bcn_ord, u8 sf_ord,
9ec76716
SL
413 u8 pan_coord, u8 blx, u8 coord_realign);
414 int (*scan_req)(struct net_device *dev,
16eea493 415 u8 type, u32 channels, u8 page, u8 duration);
9ec76716 416
e462ded6
PB
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
29e02374
PB
422 struct ieee802154_llsec_ops *llsec;
423
56aa091d
WA
424 /* The fields below are required. */
425
42723448
DES
426 struct wpan_phy *(*get_phy)(const struct net_device *dev);
427
9ec76716
SL
428 /*
429 * FIXME: these should become the part of PIB/MIB interface.
430 * However we still don't have IB interface of any kind
431 */
b70ab2e8
PB
432 __le16 (*get_pan_id)(const struct net_device *dev);
433 __le16 (*get_short_addr)(const struct net_device *dev);
a9966b58 434 u8 (*get_dsn)(const struct net_device *dev);
9ec76716
SL
435};
436
74a02fcf 437/* The IEEE 802.15.4 standard defines 2 type of the devices:
438 * - FFD - full functionality device
439 * - RFD - reduce functionality device
440 *
441 * So 2 sets of mlme operations are needed
442 */
443struct ieee802154_reduced_mlme_ops {
444 struct wpan_phy *(*get_phy)(const struct net_device *dev);
445};
446
447static inline struct ieee802154_mlme_ops *
448ieee802154_mlme_ops(const struct net_device *dev)
9ec76716
SL
449{
450 return dev->ml_priv;
451}
452
74a02fcf 453static inline struct ieee802154_reduced_mlme_ops *
454ieee802154_reduced_mlme_ops(const struct net_device *dev)
455{
456 return dev->ml_priv;
457}
9ec76716 458
74a02fcf 459#endif