1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * IEEE802.15.4-2003 specification 4 * 5 * Copyright (C) 2007-2012 Siemens AG 6 */ 7 #ifndef NET_MAC802154_H 8 #define NET_MAC802154_H 9 10 #include <linux/unaligned.h> 11 #include <net/af_ieee802154.h> 12 #include <linux/ieee802154.h> 13 #include <linux/skbuff.h> 14 15 #include <net/cfg802154.h> 16 17 /** 18 * enum ieee802154_hw_addr_filt_flags - hardware address filtering flags 19 * 20 * The following flags are used to indicate changed address settings from 21 * the stack to the hardware. 22 * 23 * @IEEE802154_AFILT_SADDR_CHANGED: Indicates that the short address will be 24 * change. 25 * 26 * @IEEE802154_AFILT_IEEEADDR_CHANGED: Indicates that the extended address 27 * will be change. 28 * 29 * @IEEE802154_AFILT_PANID_CHANGED: Indicates that the pan id will be change. 30 * 31 * @IEEE802154_AFILT_PANC_CHANGED: Indicates that the address filter will 32 * do frame address filtering as a pan coordinator. 33 */ 34 enum ieee802154_hw_addr_filt_flags { 35 IEEE802154_AFILT_SADDR_CHANGED = BIT(0), 36 IEEE802154_AFILT_IEEEADDR_CHANGED = BIT(1), 37 IEEE802154_AFILT_PANID_CHANGED = BIT(2), 38 IEEE802154_AFILT_PANC_CHANGED = BIT(3), 39 }; 40 41 /** 42 * struct ieee802154_hw_addr_filt - hardware address filtering settings 43 * 44 * @pan_id: pan_id which should be set to the hardware address filter. 45 * 46 * @short_addr: short_addr which should be set to the hardware address filter. 47 * 48 * @ieee_addr: extended address which should be set to the hardware address 49 * filter. 50 * 51 * @pan_coord: boolean if hardware filtering should be operate as coordinator. 52 */ 53 struct ieee802154_hw_addr_filt { 54 __le16 pan_id; 55 __le16 short_addr; 56 __le64 ieee_addr; 57 bool pan_coord; 58 }; 59 60 /** 61 * struct ieee802154_hw - ieee802154 hardware 62 * 63 * @extra_tx_headroom: headroom to reserve in each transmit skb for use by the 64 * driver (e.g. for transmit headers.) 65 * 66 * @flags: hardware flags, see &enum ieee802154_hw_flags 67 * 68 * @parent: parent device of the hardware. 69 * 70 * @priv: pointer to private area that was allocated for driver use along with 71 * this structure. 72 * 73 * @phy: This points to the &struct wpan_phy allocated for this 802.15.4 PHY. 74 */ 75 struct ieee802154_hw { 76 /* filled by the driver */ 77 int extra_tx_headroom; 78 u32 flags; 79 struct device *parent; 80 void *priv; 81 82 /* filled by mac802154 core */ 83 struct wpan_phy *phy; 84 }; 85 86 /** 87 * enum ieee802154_hw_flags - hardware flags 88 * 89 * These flags are used to indicate hardware capabilities to 90 * the stack. Generally, flags here should have their meaning 91 * done in a way that the simplest hardware doesn't need setting 92 * any particular flags. There are some exceptions to this rule, 93 * however, so you are advised to review these flags carefully. 94 * 95 * @IEEE802154_HW_TX_OMIT_CKSUM: Indicates that xmitter will add FCS on it's 96 * own. 97 * 98 * @IEEE802154_HW_LBT: Indicates that transceiver will support listen before 99 * transmit. 100 * 101 * @IEEE802154_HW_CSMA_PARAMS: Indicates that transceiver will support csma 102 * parameters (max_be, min_be, backoff exponents). 103 * 104 * @IEEE802154_HW_FRAME_RETRIES: Indicates that transceiver will support ARET 105 * frame retries setting. 106 * 107 * @IEEE802154_HW_AFILT: Indicates that transceiver will support hardware 108 * address filter setting. 109 * 110 * @IEEE802154_HW_PROMISCUOUS: Indicates that transceiver will support 111 * promiscuous mode setting. 112 * 113 * @IEEE802154_HW_RX_OMIT_CKSUM: Indicates that receiver omits FCS. 114 */ 115 enum ieee802154_hw_flags { 116 IEEE802154_HW_TX_OMIT_CKSUM = BIT(0), 117 IEEE802154_HW_LBT = BIT(1), 118 IEEE802154_HW_CSMA_PARAMS = BIT(2), 119 IEEE802154_HW_FRAME_RETRIES = BIT(3), 120 IEEE802154_HW_AFILT = BIT(4), 121 IEEE802154_HW_PROMISCUOUS = BIT(5), 122 IEEE802154_HW_RX_OMIT_CKSUM = BIT(6), 123 }; 124 125 /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ 126 #define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ 127 IEEE802154_HW_RX_OMIT_CKSUM) 128 129 /* struct ieee802154_ops - callbacks from mac802154 to the driver 130 * 131 * This structure contains various callbacks that the driver may 132 * handle or, in some cases, must handle, for example to transmit 133 * a frame. 134 * 135 * start: Handler that 802.15.4 module calls for device initialization. 136 * This function is called before the first interface is attached. 137 * 138 * stop: Handler that 802.15.4 module calls for device cleanup. 139 * This function is called after the last interface is removed. 140 * 141 * xmit_sync: 142 * Handler that 802.15.4 module calls for each transmitted frame. 143 * skb contains the buffer starting from the IEEE 802.15.4 header. 144 * The low-level driver should send the frame based on available 145 * configuration. This is called by a workqueue and useful for 146 * synchronous 802.15.4 drivers. 147 * This function should return zero or negative errno. 148 * 149 * WARNING: 150 * This will be deprecated soon. We don't accept synced xmit callbacks 151 * drivers anymore. 152 * 153 * xmit_async: 154 * Handler that 802.15.4 module calls for each transmitted frame. 155 * skb contains the buffer starting from the IEEE 802.15.4 header. 156 * The low-level driver should send the frame based on available 157 * configuration. 158 * This function should return zero or negative errno. 159 * 160 * ed: Handler that 802.15.4 module calls for Energy Detection. 161 * This function should place the value for detected energy 162 * (usually device-dependant) in the level pointer and return 163 * either zero or negative errno. Called with pib_lock held. 164 * 165 * set_channel: 166 * Set radio for listening on specific channel. 167 * Set the device for listening on specified channel. 168 * Returns either zero, or negative errno. Called with pib_lock held. 169 * 170 * set_hw_addr_filt: 171 * Set radio for listening on specific address. 172 * Set the device for listening on specified address. 173 * Returns either zero, or negative errno. 174 * 175 * set_txpower: 176 * Set radio transmit power in mBm. Called with pib_lock held. 177 * Returns either zero, or negative errno. 178 * 179 * set_lbt 180 * Enables or disables listen before talk on the device. Called with 181 * pib_lock held. 182 * Returns either zero, or negative errno. 183 * 184 * set_cca_mode 185 * Sets the CCA mode used by the device. Called with pib_lock held. 186 * Returns either zero, or negative errno. 187 * 188 * set_cca_ed_level 189 * Sets the CCA energy detection threshold in mBm. Called with pib_lock 190 * held. 191 * Returns either zero, or negative errno. 192 * 193 * set_csma_params 194 * Sets the CSMA parameter set for the PHY. Called with pib_lock held. 195 * Returns either zero, or negative errno. 196 * 197 * set_frame_retries 198 * Sets the retransmission attempt limit. Called with pib_lock held. 199 * Returns either zero, or negative errno. 200 * 201 * set_promiscuous_mode 202 * Enables or disable promiscuous mode. 203 */ 204 struct ieee802154_ops { 205 struct module *owner; 206 int (*start)(struct ieee802154_hw *hw); 207 void (*stop)(struct ieee802154_hw *hw); 208 int (*xmit_sync)(struct ieee802154_hw *hw, 209 struct sk_buff *skb); 210 int (*xmit_async)(struct ieee802154_hw *hw, 211 struct sk_buff *skb); 212 int (*ed)(struct ieee802154_hw *hw, u8 *level); 213 int (*set_channel)(struct ieee802154_hw *hw, u8 page, 214 u8 channel); 215 int (*set_hw_addr_filt)(struct ieee802154_hw *hw, 216 struct ieee802154_hw_addr_filt *filt, 217 unsigned long changed); 218 int (*set_txpower)(struct ieee802154_hw *hw, s32 mbm); 219 int (*set_lbt)(struct ieee802154_hw *hw, bool on); 220 int (*set_cca_mode)(struct ieee802154_hw *hw, 221 const struct wpan_phy_cca *cca); 222 int (*set_cca_ed_level)(struct ieee802154_hw *hw, s32 mbm); 223 int (*set_csma_params)(struct ieee802154_hw *hw, 224 u8 min_be, u8 max_be, u8 retries); 225 int (*set_frame_retries)(struct ieee802154_hw *hw, 226 s8 retries); 227 int (*set_promiscuous_mode)(struct ieee802154_hw *hw, 228 const bool on); 229 }; 230 231 /** 232 * ieee802154_get_fc_from_skb - get the frame control field from an skb 233 * @skb: skb where the frame control field will be get from 234 */ 235 static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb) 236 { 237 __le16 fc; 238 239 /* check if we can fc at skb_mac_header of sk buffer */ 240 if (WARN_ON(!skb_mac_header_was_set(skb) || 241 (skb_tail_pointer(skb) - 242 skb_mac_header(skb)) < IEEE802154_FC_LEN)) 243 return cpu_to_le16(0); 244 245 memcpy(&fc, skb_mac_header(skb), IEEE802154_FC_LEN); 246 return fc; 247 } 248 249 /** 250 * ieee802154_skb_dst_pan - get the pointer to destination pan field 251 * @fc: mac header frame control field 252 * @skb: skb where the destination pan pointer will be get from 253 */ 254 static inline unsigned char *ieee802154_skb_dst_pan(__le16 fc, 255 const struct sk_buff *skb) 256 { 257 unsigned char *dst_pan; 258 259 switch (ieee802154_daddr_mode(fc)) { 260 case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE): 261 dst_pan = NULL; 262 break; 263 case cpu_to_le16(IEEE802154_FCTL_DADDR_SHORT): 264 case cpu_to_le16(IEEE802154_FCTL_DADDR_EXTENDED): 265 dst_pan = skb_mac_header(skb) + 266 IEEE802154_FC_LEN + 267 IEEE802154_SEQ_LEN; 268 break; 269 default: 270 WARN_ONCE(1, "invalid addr mode detected"); 271 dst_pan = NULL; 272 break; 273 } 274 275 return dst_pan; 276 } 277 278 /** 279 * ieee802154_skb_src_pan - get the pointer to source pan field 280 * @fc: mac header frame control field 281 * @skb: skb where the source pan pointer will be get from 282 */ 283 static inline unsigned char *ieee802154_skb_src_pan(__le16 fc, 284 const struct sk_buff *skb) 285 { 286 unsigned char *src_pan; 287 288 switch (ieee802154_saddr_mode(fc)) { 289 case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE): 290 src_pan = NULL; 291 break; 292 case cpu_to_le16(IEEE802154_FCTL_SADDR_SHORT): 293 case cpu_to_le16(IEEE802154_FCTL_SADDR_EXTENDED): 294 /* if intra-pan and source addr mode is non none, 295 * then source pan id is equal destination pan id. 296 */ 297 if (ieee802154_is_intra_pan(fc)) { 298 src_pan = ieee802154_skb_dst_pan(fc, skb); 299 break; 300 } 301 302 switch (ieee802154_daddr_mode(fc)) { 303 case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE): 304 src_pan = skb_mac_header(skb) + 305 IEEE802154_FC_LEN + 306 IEEE802154_SEQ_LEN; 307 break; 308 case cpu_to_le16(IEEE802154_FCTL_DADDR_SHORT): 309 src_pan = skb_mac_header(skb) + 310 IEEE802154_FC_LEN + 311 IEEE802154_SEQ_LEN + 312 IEEE802154_PAN_ID_LEN + 313 IEEE802154_SHORT_ADDR_LEN; 314 break; 315 case cpu_to_le16(IEEE802154_FCTL_DADDR_EXTENDED): 316 src_pan = skb_mac_header(skb) + 317 IEEE802154_FC_LEN + 318 IEEE802154_SEQ_LEN + 319 IEEE802154_PAN_ID_LEN + 320 IEEE802154_EXTENDED_ADDR_LEN; 321 break; 322 default: 323 WARN_ONCE(1, "invalid addr mode detected"); 324 src_pan = NULL; 325 break; 326 } 327 break; 328 default: 329 WARN_ONCE(1, "invalid addr mode detected"); 330 src_pan = NULL; 331 break; 332 } 333 334 return src_pan; 335 } 336 337 /** 338 * ieee802154_skb_is_intra_pan_addressing - checks whenever the mac addressing 339 * is an intra pan communication 340 * @fc: mac header frame control field 341 * @skb: skb where the source and destination pan should be get from 342 */ 343 static inline bool ieee802154_skb_is_intra_pan_addressing(__le16 fc, 344 const struct sk_buff *skb) 345 { 346 unsigned char *dst_pan = ieee802154_skb_dst_pan(fc, skb), 347 *src_pan = ieee802154_skb_src_pan(fc, skb); 348 349 /* if one is NULL is no intra pan addressing */ 350 if (!dst_pan || !src_pan) 351 return false; 352 353 return !memcmp(dst_pan, src_pan, IEEE802154_PAN_ID_LEN); 354 } 355 356 /** 357 * ieee802154_be64_to_le64 - copies and convert be64 to le64 358 * @le64_dst: le64 destination pointer 359 * @be64_src: be64 source pointer 360 */ 361 static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src) 362 { 363 put_unaligned_le64(get_unaligned_be64(be64_src), le64_dst); 364 } 365 366 /** 367 * ieee802154_le64_to_be64 - copies and convert le64 to be64 368 * @be64_dst: be64 destination pointer 369 * @le64_src: le64 source pointer 370 */ 371 static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src) 372 { 373 put_unaligned_be64(get_unaligned_le64(le64_src), be64_dst); 374 } 375 376 /** 377 * ieee802154_le16_to_be16 - copies and convert le16 to be16 378 * @be16_dst: be16 destination pointer 379 * @le16_src: le16 source pointer 380 */ 381 static inline void ieee802154_le16_to_be16(void *be16_dst, const void *le16_src) 382 { 383 put_unaligned_be16(get_unaligned_le16(le16_src), be16_dst); 384 } 385 386 /** 387 * ieee802154_be16_to_le16 - copies and convert be16 to le16 388 * @le16_dst: le16 destination pointer 389 * @be16_src: be16 source pointer 390 */ 391 static inline void ieee802154_be16_to_le16(void *le16_dst, const void *be16_src) 392 { 393 put_unaligned_le16(get_unaligned_be16(be16_src), le16_dst); 394 } 395 396 /** 397 * ieee802154_alloc_hw - Allocate a new hardware device 398 * 399 * This must be called once for each hardware device. The returned pointer 400 * must be used to refer to this device when calling other functions. 401 * mac802154 allocates a private data area for the driver pointed to by 402 * @priv in &struct ieee802154_hw, the size of this area is given as 403 * @priv_data_len. 404 * 405 * @priv_data_len: length of private data 406 * @ops: callbacks for this device 407 * 408 * Return: A pointer to the new hardware device, or %NULL on error. 409 */ 410 struct ieee802154_hw * 411 ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops); 412 413 /** 414 * ieee802154_free_hw - free hardware descriptor 415 * 416 * This function frees everything that was allocated, including the 417 * private data for the driver. You must call ieee802154_unregister_hw() 418 * before calling this function. 419 * 420 * @hw: the hardware to free 421 */ 422 void ieee802154_free_hw(struct ieee802154_hw *hw); 423 424 /** 425 * ieee802154_register_hw - Register hardware device 426 * 427 * You must call this function before any other functions in 428 * mac802154. Note that before a hardware can be registered, you 429 * need to fill the contained wpan_phy's information. 430 * 431 * @hw: the device to register as returned by ieee802154_alloc_hw() 432 * 433 * Return: 0 on success. An error code otherwise. 434 */ 435 int ieee802154_register_hw(struct ieee802154_hw *hw); 436 437 /** 438 * ieee802154_unregister_hw - Unregister a hardware device 439 * 440 * This function instructs mac802154 to free allocated resources 441 * and unregister netdevices from the networking subsystem. 442 * 443 * @hw: the hardware to unregister 444 */ 445 void ieee802154_unregister_hw(struct ieee802154_hw *hw); 446 447 /** 448 * ieee802154_rx_irqsafe - receive frame 449 * 450 * Like ieee802154_rx() but can be called in IRQ context 451 * (internally defers to a tasklet.) 452 * 453 * @hw: the hardware this frame came in on 454 * @skb: the buffer to receive, owned by mac802154 after this call 455 * @lqi: link quality indicator 456 */ 457 void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, 458 u8 lqi); 459 460 /** 461 * ieee802154_xmit_complete - frame transmission complete 462 * 463 * @hw: pointer as obtained from ieee802154_alloc_hw(). 464 * @skb: buffer for transmission 465 * @ifs_handling: indicate interframe space handling 466 */ 467 void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb, 468 bool ifs_handling); 469 470 /** 471 * ieee802154_xmit_error - offloaded frame transmission failed 472 * 473 * @hw: pointer as obtained from ieee802154_alloc_hw(). 474 * @skb: buffer for transmission 475 * @reason: error code 476 */ 477 void ieee802154_xmit_error(struct ieee802154_hw *hw, struct sk_buff *skb, 478 int reason); 479 480 /** 481 * ieee802154_xmit_hw_error - frame could not be offloaded to the transmitter 482 * because of a hardware error (bus error, timeout, etc) 483 * 484 * @hw: pointer as obtained from ieee802154_alloc_hw(). 485 * @skb: buffer for transmission 486 */ 487 void ieee802154_xmit_hw_error(struct ieee802154_hw *hw, struct sk_buff *skb); 488 489 #endif /* NET_MAC802154_H */ 490