ieee802154_netdev.h (8963B)
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#include <net/af_ieee802154.h> 19#include <linux/netdevice.h> 20#include <linux/skbuff.h> 21#include <linux/ieee802154.h> 22 23#include <net/cfg802154.h> 24 25struct ieee802154_sechdr { 26#if defined(__LITTLE_ENDIAN_BITFIELD) 27 u8 level:3, 28 key_id_mode:2, 29 reserved:3; 30#elif defined(__BIG_ENDIAN_BITFIELD) 31 u8 reserved:3, 32 key_id_mode:2, 33 level:3; 34#else 35#error "Please fix <asm/byteorder.h>" 36#endif 37 u8 key_id; 38 __le32 frame_counter; 39 union { 40 __le32 short_src; 41 __le64 extended_src; 42 }; 43}; 44 45struct ieee802154_hdr_fc { 46#if defined(__LITTLE_ENDIAN_BITFIELD) 47 u16 type:3, 48 security_enabled:1, 49 frame_pending:1, 50 ack_request:1, 51 intra_pan:1, 52 reserved:3, 53 dest_addr_mode:2, 54 version:2, 55 source_addr_mode:2; 56#elif defined(__BIG_ENDIAN_BITFIELD) 57 u16 reserved:1, 58 intra_pan:1, 59 ack_request:1, 60 frame_pending:1, 61 security_enabled:1, 62 type:3, 63 source_addr_mode:2, 64 version:2, 65 dest_addr_mode:2, 66 reserved2:2; 67#else 68#error "Please fix <asm/byteorder.h>" 69#endif 70}; 71 72struct ieee802154_hdr { 73 struct ieee802154_hdr_fc fc; 74 u8 seq; 75 struct ieee802154_addr source; 76 struct ieee802154_addr dest; 77 struct ieee802154_sechdr sec; 78}; 79 80/* pushes hdr onto the skb. fields of hdr->fc that can be calculated from 81 * the contents of hdr will be, and the actual value of those bits in 82 * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame 83 * version, if SECEN is set. 84 */ 85int ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr); 86 87/* pulls the entire 802.15.4 header off of the skb, including the security 88 * header, and performs pan id decompression 89 */ 90int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr); 91 92/* parses the frame control, sequence number of address fields in a given skb 93 * and stores them into hdr, performing pan id decompression and length checks 94 * to be suitable for use in header_ops.parse 95 */ 96int ieee802154_hdr_peek_addrs(const struct sk_buff *skb, 97 struct ieee802154_hdr *hdr); 98 99/* parses the full 802.15.4 header a given skb and stores them into hdr, 100 * performing pan id decompression and length checks to be suitable for use in 101 * header_ops.parse 102 */ 103int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr); 104 105int ieee802154_max_payload(const struct ieee802154_hdr *hdr); 106 107static inline int 108ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec) 109{ 110 switch (sec->level) { 111 case IEEE802154_SCF_SECLEVEL_MIC32: 112 case IEEE802154_SCF_SECLEVEL_ENC_MIC32: 113 return 4; 114 case IEEE802154_SCF_SECLEVEL_MIC64: 115 case IEEE802154_SCF_SECLEVEL_ENC_MIC64: 116 return 8; 117 case IEEE802154_SCF_SECLEVEL_MIC128: 118 case IEEE802154_SCF_SECLEVEL_ENC_MIC128: 119 return 16; 120 case IEEE802154_SCF_SECLEVEL_NONE: 121 case IEEE802154_SCF_SECLEVEL_ENC: 122 default: 123 return 0; 124 } 125} 126 127static inline int ieee802154_hdr_length(struct sk_buff *skb) 128{ 129 struct ieee802154_hdr hdr; 130 int len = ieee802154_hdr_pull(skb, &hdr); 131 132 if (len > 0) 133 skb_push(skb, len); 134 135 return len; 136} 137 138static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1, 139 const struct ieee802154_addr *a2) 140{ 141 if (a1->pan_id != a2->pan_id || a1->mode != a2->mode) 142 return false; 143 144 if ((a1->mode == IEEE802154_ADDR_LONG && 145 a1->extended_addr != a2->extended_addr) || 146 (a1->mode == IEEE802154_ADDR_SHORT && 147 a1->short_addr != a2->short_addr)) 148 return false; 149 150 return true; 151} 152 153static inline __le64 ieee802154_devaddr_from_raw(const void *raw) 154{ 155 u64 temp; 156 157 memcpy(&temp, raw, IEEE802154_ADDR_LEN); 158 return (__force __le64)swab64(temp); 159} 160 161static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr) 162{ 163 u64 temp = swab64((__force u64)addr); 164 165 memcpy(raw, &temp, IEEE802154_ADDR_LEN); 166} 167 168static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a, 169 const struct ieee802154_addr_sa *sa) 170{ 171 a->mode = sa->addr_type; 172 a->pan_id = cpu_to_le16(sa->pan_id); 173 174 switch (a->mode) { 175 case IEEE802154_ADDR_SHORT: 176 a->short_addr = cpu_to_le16(sa->short_addr); 177 break; 178 case IEEE802154_ADDR_LONG: 179 a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr); 180 break; 181 } 182} 183 184static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa, 185 const struct ieee802154_addr *a) 186{ 187 sa->addr_type = a->mode; 188 sa->pan_id = le16_to_cpu(a->pan_id); 189 190 switch (a->mode) { 191 case IEEE802154_ADDR_SHORT: 192 sa->short_addr = le16_to_cpu(a->short_addr); 193 break; 194 case IEEE802154_ADDR_LONG: 195 ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr); 196 break; 197 } 198} 199 200/* 201 * A control block of skb passed between the ARPHRD_IEEE802154 device 202 * and other stack parts. 203 */ 204struct ieee802154_mac_cb { 205 u8 lqi; 206 u8 type; 207 bool ackreq; 208 bool secen; 209 bool secen_override; 210 u8 seclevel; 211 bool seclevel_override; 212 struct ieee802154_addr source; 213 struct ieee802154_addr dest; 214}; 215 216static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb) 217{ 218 return (struct ieee802154_mac_cb *)skb->cb; 219} 220 221static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb) 222{ 223 BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb)); 224 225 memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb)); 226 return mac_cb(skb); 227} 228 229enum { 230 IEEE802154_LLSEC_DEVKEY_IGNORE, 231 IEEE802154_LLSEC_DEVKEY_RESTRICT, 232 IEEE802154_LLSEC_DEVKEY_RECORD, 233 234 __IEEE802154_LLSEC_DEVKEY_MAX, 235}; 236 237#define IEEE802154_MAC_SCAN_ED 0 238#define IEEE802154_MAC_SCAN_ACTIVE 1 239#define IEEE802154_MAC_SCAN_PASSIVE 2 240#define IEEE802154_MAC_SCAN_ORPHAN 3 241 242struct ieee802154_mac_params { 243 s8 transmit_power; 244 u8 min_be; 245 u8 max_be; 246 u8 csma_retries; 247 s8 frame_retries; 248 249 bool lbt; 250 struct wpan_phy_cca cca; 251 s32 cca_ed_level; 252}; 253 254struct wpan_phy; 255 256enum { 257 IEEE802154_LLSEC_PARAM_ENABLED = BIT(0), 258 IEEE802154_LLSEC_PARAM_FRAME_COUNTER = BIT(1), 259 IEEE802154_LLSEC_PARAM_OUT_LEVEL = BIT(2), 260 IEEE802154_LLSEC_PARAM_OUT_KEY = BIT(3), 261 IEEE802154_LLSEC_PARAM_KEY_SOURCE = BIT(4), 262 IEEE802154_LLSEC_PARAM_PAN_ID = BIT(5), 263 IEEE802154_LLSEC_PARAM_HWADDR = BIT(6), 264 IEEE802154_LLSEC_PARAM_COORD_HWADDR = BIT(7), 265 IEEE802154_LLSEC_PARAM_COORD_SHORTADDR = BIT(8), 266}; 267 268struct ieee802154_llsec_ops { 269 int (*get_params)(struct net_device *dev, 270 struct ieee802154_llsec_params *params); 271 int (*set_params)(struct net_device *dev, 272 const struct ieee802154_llsec_params *params, 273 int changed); 274 275 int (*add_key)(struct net_device *dev, 276 const struct ieee802154_llsec_key_id *id, 277 const struct ieee802154_llsec_key *key); 278 int (*del_key)(struct net_device *dev, 279 const struct ieee802154_llsec_key_id *id); 280 281 int (*add_dev)(struct net_device *dev, 282 const struct ieee802154_llsec_device *llsec_dev); 283 int (*del_dev)(struct net_device *dev, __le64 dev_addr); 284 285 int (*add_devkey)(struct net_device *dev, 286 __le64 device_addr, 287 const struct ieee802154_llsec_device_key *key); 288 int (*del_devkey)(struct net_device *dev, 289 __le64 device_addr, 290 const struct ieee802154_llsec_device_key *key); 291 292 int (*add_seclevel)(struct net_device *dev, 293 const struct ieee802154_llsec_seclevel *sl); 294 int (*del_seclevel)(struct net_device *dev, 295 const struct ieee802154_llsec_seclevel *sl); 296 297 void (*lock_table)(struct net_device *dev); 298 void (*get_table)(struct net_device *dev, 299 struct ieee802154_llsec_table **t); 300 void (*unlock_table)(struct net_device *dev); 301}; 302/* 303 * This should be located at net_device->ml_priv 304 * 305 * get_phy should increment the reference counting on returned phy. 306 * Use wpan_wpy_put to put that reference. 307 */ 308struct ieee802154_mlme_ops { 309 /* The following fields are optional (can be NULL). */ 310 311 int (*assoc_req)(struct net_device *dev, 312 struct ieee802154_addr *addr, 313 u8 channel, u8 page, u8 cap); 314 int (*assoc_resp)(struct net_device *dev, 315 struct ieee802154_addr *addr, 316 __le16 short_addr, u8 status); 317 int (*disassoc_req)(struct net_device *dev, 318 struct ieee802154_addr *addr, 319 u8 reason); 320 int (*start_req)(struct net_device *dev, 321 struct ieee802154_addr *addr, 322 u8 channel, u8 page, u8 bcn_ord, u8 sf_ord, 323 u8 pan_coord, u8 blx, u8 coord_realign); 324 int (*scan_req)(struct net_device *dev, 325 u8 type, u32 channels, u8 page, u8 duration); 326 327 int (*set_mac_params)(struct net_device *dev, 328 const struct ieee802154_mac_params *params); 329 void (*get_mac_params)(struct net_device *dev, 330 struct ieee802154_mac_params *params); 331 332 const struct ieee802154_llsec_ops *llsec; 333}; 334 335static inline struct ieee802154_mlme_ops * 336ieee802154_mlme_ops(const struct net_device *dev) 337{ 338 return dev->ml_priv; 339} 340 341#endif