![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-only */ 0002 /* 0003 * IEEE802.15.4-2003 specification 0004 * 0005 * Copyright (C) 2007-2012 Siemens AG 0006 */ 0007 #ifndef NET_MAC802154_H 0008 #define NET_MAC802154_H 0009 0010 #include <asm/unaligned.h> 0011 #include <net/af_ieee802154.h> 0012 #include <linux/ieee802154.h> 0013 #include <linux/skbuff.h> 0014 0015 #include <net/cfg802154.h> 0016 0017 /** 0018 * enum ieee802154_hw_addr_filt_flags - hardware address filtering flags 0019 * 0020 * The following flags are used to indicate changed address settings from 0021 * the stack to the hardware. 0022 * 0023 * @IEEE802154_AFILT_SADDR_CHANGED: Indicates that the short address will be 0024 * change. 0025 * 0026 * @IEEE802154_AFILT_IEEEADDR_CHANGED: Indicates that the extended address 0027 * will be change. 0028 * 0029 * @IEEE802154_AFILT_PANID_CHANGED: Indicates that the pan id will be change. 0030 * 0031 * @IEEE802154_AFILT_PANC_CHANGED: Indicates that the address filter will 0032 * do frame address filtering as a pan coordinator. 0033 */ 0034 enum ieee802154_hw_addr_filt_flags { 0035 IEEE802154_AFILT_SADDR_CHANGED = BIT(0), 0036 IEEE802154_AFILT_IEEEADDR_CHANGED = BIT(1), 0037 IEEE802154_AFILT_PANID_CHANGED = BIT(2), 0038 IEEE802154_AFILT_PANC_CHANGED = BIT(3), 0039 }; 0040 0041 /** 0042 * struct ieee802154_hw_addr_filt - hardware address filtering settings 0043 * 0044 * @pan_id: pan_id which should be set to the hardware address filter. 0045 * 0046 * @short_addr: short_addr which should be set to the hardware address filter. 0047 * 0048 * @ieee_addr: extended address which should be set to the hardware address 0049 * filter. 0050 * 0051 * @pan_coord: boolean if hardware filtering should be operate as coordinator. 0052 */ 0053 struct ieee802154_hw_addr_filt { 0054 __le16 pan_id; 0055 __le16 short_addr; 0056 __le64 ieee_addr; 0057 bool pan_coord; 0058 }; 0059 0060 /** 0061 * struct ieee802154_hw - ieee802154 hardware 0062 * 0063 * @extra_tx_headroom: headroom to reserve in each transmit skb for use by the 0064 * driver (e.g. for transmit headers.) 0065 * 0066 * @flags: hardware flags, see &enum ieee802154_hw_flags 0067 * 0068 * @parent: parent device of the hardware. 0069 * 0070 * @priv: pointer to private area that was allocated for driver use along with 0071 * this structure. 0072 * 0073 * @phy: This points to the &struct wpan_phy allocated for this 802.15.4 PHY. 0074 */ 0075 struct ieee802154_hw { 0076 /* filled by the driver */ 0077 int extra_tx_headroom; 0078 u32 flags; 0079 struct device *parent; 0080 void *priv; 0081 0082 /* filled by mac802154 core */ 0083 struct wpan_phy *phy; 0084 }; 0085 0086 /** 0087 * enum ieee802154_hw_flags - hardware flags 0088 * 0089 * These flags are used to indicate hardware capabilities to 0090 * the stack. Generally, flags here should have their meaning 0091 * done in a way that the simplest hardware doesn't need setting 0092 * any particular flags. There are some exceptions to this rule, 0093 * however, so you are advised to review these flags carefully. 0094 * 0095 * @IEEE802154_HW_TX_OMIT_CKSUM: Indicates that xmitter will add FCS on it's 0096 * own. 0097 * 0098 * @IEEE802154_HW_LBT: Indicates that transceiver will support listen before 0099 * transmit. 0100 * 0101 * @IEEE802154_HW_CSMA_PARAMS: Indicates that transceiver will support csma 0102 * parameters (max_be, min_be, backoff exponents). 0103 * 0104 * @IEEE802154_HW_FRAME_RETRIES: Indicates that transceiver will support ARET 0105 * frame retries setting. 0106 * 0107 * @IEEE802154_HW_AFILT: Indicates that transceiver will support hardware 0108 * address filter setting. 0109 * 0110 * @IEEE802154_HW_PROMISCUOUS: Indicates that transceiver will support 0111 * promiscuous mode setting. 0112 * 0113 * @IEEE802154_HW_RX_OMIT_CKSUM: Indicates that receiver omits FCS. 0114 * 0115 * @IEEE802154_HW_RX_DROP_BAD_CKSUM: Indicates that receiver will not filter 0116 * frames with bad checksum. 0117 */ 0118 enum ieee802154_hw_flags { 0119 IEEE802154_HW_TX_OMIT_CKSUM = BIT(0), 0120 IEEE802154_HW_LBT = BIT(1), 0121 IEEE802154_HW_CSMA_PARAMS = BIT(2), 0122 IEEE802154_HW_FRAME_RETRIES = BIT(3), 0123 IEEE802154_HW_AFILT = BIT(4), 0124 IEEE802154_HW_PROMISCUOUS = BIT(5), 0125 IEEE802154_HW_RX_OMIT_CKSUM = BIT(6), 0126 IEEE802154_HW_RX_DROP_BAD_CKSUM = BIT(7), 0127 }; 0128 0129 /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ 0130 #define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ 0131 IEEE802154_HW_RX_OMIT_CKSUM) 0132 0133 /* struct ieee802154_ops - callbacks from mac802154 to the driver 0134 * 0135 * This structure contains various callbacks that the driver may 0136 * handle or, in some cases, must handle, for example to transmit 0137 * a frame. 0138 * 0139 * start: Handler that 802.15.4 module calls for device initialization. 0140 * This function is called before the first interface is attached. 0141 * 0142 * stop: Handler that 802.15.4 module calls for device cleanup. 0143 * This function is called after the last interface is removed. 0144 * 0145 * xmit_sync: 0146 * Handler that 802.15.4 module calls for each transmitted frame. 0147 * skb cntains the buffer starting from the IEEE 802.15.4 header. 0148 * The low-level driver should send the frame based on available 0149 * configuration. This is called by a workqueue and useful for 0150 * synchronous 802.15.4 drivers. 0151 * This function should return zero or negative errno. 0152 * 0153 * WARNING: 0154 * This will be deprecated soon. We don't accept synced xmit callbacks 0155 * drivers anymore. 0156 * 0157 * xmit_async: 0158 * Handler that 802.15.4 module calls for each transmitted frame. 0159 * skb cntains the buffer starting from the IEEE 802.15.4 header. 0160 * The low-level driver should send the frame based on available 0161 * configuration. 0162 * This function should return zero or negative errno. 0163 * 0164 * ed: Handler that 802.15.4 module calls for Energy Detection. 0165 * This function should place the value for detected energy 0166 * (usually device-dependant) in the level pointer and return 0167 * either zero or negative errno. Called with pib_lock held. 0168 * 0169 * set_channel: 0170 * Set radio for listening on specific channel. 0171 * Set the device for listening on specified channel. 0172 * Returns either zero, or negative errno. Called with pib_lock held. 0173 * 0174 * set_hw_addr_filt: 0175 * Set radio for listening on specific address. 0176 * Set the device for listening on specified address. 0177 * Returns either zero, or negative errno. 0178 * 0179 * set_txpower: 0180 * Set radio transmit power in mBm. Called with pib_lock held. 0181 * Returns either zero, or negative errno. 0182 * 0183 * set_lbt 0184 * Enables or disables listen before talk on the device. Called with 0185 * pib_lock held. 0186 * Returns either zero, or negative errno. 0187 * 0188 * set_cca_mode 0189 * Sets the CCA mode used by the device. Called with pib_lock held. 0190 * Returns either zero, or negative errno. 0191 * 0192 * set_cca_ed_level 0193 * Sets the CCA energy detection threshold in mBm. Called with pib_lock 0194 * held. 0195 * Returns either zero, or negative errno. 0196 * 0197 * set_csma_params 0198 * Sets the CSMA parameter set for the PHY. Called with pib_lock held. 0199 * Returns either zero, or negative errno. 0200 * 0201 * set_frame_retries 0202 * Sets the retransmission attempt limit. Called with pib_lock held. 0203 * Returns either zero, or negative errno. 0204 * 0205 * set_promiscuous_mode 0206 * Enables or disable promiscuous mode. 0207 */ 0208 struct ieee802154_ops { 0209 struct module *owner; 0210 int (*start)(struct ieee802154_hw *hw); 0211 void (*stop)(struct ieee802154_hw *hw); 0212 int (*xmit_sync)(struct ieee802154_hw *hw, 0213 struct sk_buff *skb); 0214 int (*xmit_async)(struct ieee802154_hw *hw, 0215 struct sk_buff *skb); 0216 int (*ed)(struct ieee802154_hw *hw, u8 *level); 0217 int (*set_channel)(struct ieee802154_hw *hw, u8 page, 0218 u8 channel); 0219 int (*set_hw_addr_filt)(struct ieee802154_hw *hw, 0220 struct ieee802154_hw_addr_filt *filt, 0221 unsigned long changed); 0222 int (*set_txpower)(struct ieee802154_hw *hw, s32 mbm); 0223 int (*set_lbt)(struct ieee802154_hw *hw, bool on); 0224 int (*set_cca_mode)(struct ieee802154_hw *hw, 0225 const struct wpan_phy_cca *cca); 0226 int (*set_cca_ed_level)(struct ieee802154_hw *hw, s32 mbm); 0227 int (*set_csma_params)(struct ieee802154_hw *hw, 0228 u8 min_be, u8 max_be, u8 retries); 0229 int (*set_frame_retries)(struct ieee802154_hw *hw, 0230 s8 retries); 0231 int (*set_promiscuous_mode)(struct ieee802154_hw *hw, 0232 const bool on); 0233 }; 0234 0235 /** 0236 * ieee802154_get_fc_from_skb - get the frame control field from an skb 0237 * @skb: skb where the frame control field will be get from 0238 */ 0239 static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb) 0240 { 0241 __le16 fc; 0242 0243 /* check if we can fc at skb_mac_header of sk buffer */ 0244 if (WARN_ON(!skb_mac_header_was_set(skb) || 0245 (skb_tail_pointer(skb) - 0246 skb_mac_header(skb)) < IEEE802154_FC_LEN)) 0247 return cpu_to_le16(0); 0248 0249 memcpy(&fc, skb_mac_header(skb), IEEE802154_FC_LEN); 0250 return fc; 0251 } 0252 0253 /** 0254 * ieee802154_skb_dst_pan - get the pointer to destination pan field 0255 * @fc: mac header frame control field 0256 * @skb: skb where the destination pan pointer will be get from 0257 */ 0258 static inline unsigned char *ieee802154_skb_dst_pan(__le16 fc, 0259 const struct sk_buff *skb) 0260 { 0261 unsigned char *dst_pan; 0262 0263 switch (ieee802154_daddr_mode(fc)) { 0264 case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE): 0265 dst_pan = NULL; 0266 break; 0267 case cpu_to_le16(IEEE802154_FCTL_DADDR_SHORT): 0268 case cpu_to_le16(IEEE802154_FCTL_DADDR_EXTENDED): 0269 dst_pan = skb_mac_header(skb) + 0270 IEEE802154_FC_LEN + 0271 IEEE802154_SEQ_LEN; 0272 break; 0273 default: 0274 WARN_ONCE(1, "invalid addr mode detected"); 0275 dst_pan = NULL; 0276 break; 0277 } 0278 0279 return dst_pan; 0280 } 0281 0282 /** 0283 * ieee802154_skb_src_pan - get the pointer to source pan field 0284 * @fc: mac header frame control field 0285 * @skb: skb where the source pan pointer will be get from 0286 */ 0287 static inline unsigned char *ieee802154_skb_src_pan(__le16 fc, 0288 const struct sk_buff *skb) 0289 { 0290 unsigned char *src_pan; 0291 0292 switch (ieee802154_saddr_mode(fc)) { 0293 case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE): 0294 src_pan = NULL; 0295 break; 0296 case cpu_to_le16(IEEE802154_FCTL_SADDR_SHORT): 0297 case cpu_to_le16(IEEE802154_FCTL_SADDR_EXTENDED): 0298 /* if intra-pan and source addr mode is non none, 0299 * then source pan id is equal destination pan id. 0300 */ 0301 if (ieee802154_is_intra_pan(fc)) { 0302 src_pan = ieee802154_skb_dst_pan(fc, skb); 0303 break; 0304 } 0305 0306 switch (ieee802154_daddr_mode(fc)) { 0307 case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE): 0308 src_pan = skb_mac_header(skb) + 0309 IEEE802154_FC_LEN + 0310 IEEE802154_SEQ_LEN; 0311 break; 0312 case cpu_to_le16(IEEE802154_FCTL_DADDR_SHORT): 0313 src_pan = skb_mac_header(skb) + 0314 IEEE802154_FC_LEN + 0315 IEEE802154_SEQ_LEN + 0316 IEEE802154_PAN_ID_LEN + 0317 IEEE802154_SHORT_ADDR_LEN; 0318 break; 0319 case cpu_to_le16(IEEE802154_FCTL_DADDR_EXTENDED): 0320 src_pan = skb_mac_header(skb) + 0321 IEEE802154_FC_LEN + 0322 IEEE802154_SEQ_LEN + 0323 IEEE802154_PAN_ID_LEN + 0324 IEEE802154_EXTENDED_ADDR_LEN; 0325 break; 0326 default: 0327 WARN_ONCE(1, "invalid addr mode detected"); 0328 src_pan = NULL; 0329 break; 0330 } 0331 break; 0332 default: 0333 WARN_ONCE(1, "invalid addr mode detected"); 0334 src_pan = NULL; 0335 break; 0336 } 0337 0338 return src_pan; 0339 } 0340 0341 /** 0342 * ieee802154_skb_is_intra_pan_addressing - checks whenever the mac addressing 0343 * is an intra pan communication 0344 * @fc: mac header frame control field 0345 * @skb: skb where the source and destination pan should be get from 0346 */ 0347 static inline bool ieee802154_skb_is_intra_pan_addressing(__le16 fc, 0348 const struct sk_buff *skb) 0349 { 0350 unsigned char *dst_pan = ieee802154_skb_dst_pan(fc, skb), 0351 *src_pan = ieee802154_skb_src_pan(fc, skb); 0352 0353 /* if one is NULL is no intra pan addressing */ 0354 if (!dst_pan || !src_pan) 0355 return false; 0356 0357 return !memcmp(dst_pan, src_pan, IEEE802154_PAN_ID_LEN); 0358 } 0359 0360 /** 0361 * ieee802154_be64_to_le64 - copies and convert be64 to le64 0362 * @le64_dst: le64 destination pointer 0363 * @be64_src: be64 source pointer 0364 */ 0365 static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src) 0366 { 0367 put_unaligned_le64(get_unaligned_be64(be64_src), le64_dst); 0368 } 0369 0370 /** 0371 * ieee802154_le64_to_be64 - copies and convert le64 to be64 0372 * @be64_dst: be64 destination pointer 0373 * @le64_src: le64 source pointer 0374 */ 0375 static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src) 0376 { 0377 put_unaligned_be64(get_unaligned_le64(le64_src), be64_dst); 0378 } 0379 0380 /** 0381 * ieee802154_le16_to_be16 - copies and convert le16 to be16 0382 * @be16_dst: be16 destination pointer 0383 * @le16_src: le16 source pointer 0384 */ 0385 static inline void ieee802154_le16_to_be16(void *be16_dst, const void *le16_src) 0386 { 0387 put_unaligned_be16(get_unaligned_le16(le16_src), be16_dst); 0388 } 0389 0390 /** 0391 * ieee802154_be16_to_le16 - copies and convert be16 to le16 0392 * @le16_dst: le16 destination pointer 0393 * @be16_src: be16 source pointer 0394 */ 0395 static inline void ieee802154_be16_to_le16(void *le16_dst, const void *be16_src) 0396 { 0397 put_unaligned_le16(get_unaligned_be16(be16_src), le16_dst); 0398 } 0399 0400 /** 0401 * ieee802154_alloc_hw - Allocate a new hardware device 0402 * 0403 * This must be called once for each hardware device. The returned pointer 0404 * must be used to refer to this device when calling other functions. 0405 * mac802154 allocates a private data area for the driver pointed to by 0406 * @priv in &struct ieee802154_hw, the size of this area is given as 0407 * @priv_data_len. 0408 * 0409 * @priv_data_len: length of private data 0410 * @ops: callbacks for this device 0411 * 0412 * Return: A pointer to the new hardware device, or %NULL on error. 0413 */ 0414 struct ieee802154_hw * 0415 ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops); 0416 0417 /** 0418 * ieee802154_free_hw - free hardware descriptor 0419 * 0420 * This function frees everything that was allocated, including the 0421 * private data for the driver. You must call ieee802154_unregister_hw() 0422 * before calling this function. 0423 * 0424 * @hw: the hardware to free 0425 */ 0426 void ieee802154_free_hw(struct ieee802154_hw *hw); 0427 0428 /** 0429 * ieee802154_register_hw - Register hardware device 0430 * 0431 * You must call this function before any other functions in 0432 * mac802154. Note that before a hardware can be registered, you 0433 * need to fill the contained wpan_phy's information. 0434 * 0435 * @hw: the device to register as returned by ieee802154_alloc_hw() 0436 * 0437 * Return: 0 on success. An error code otherwise. 0438 */ 0439 int ieee802154_register_hw(struct ieee802154_hw *hw); 0440 0441 /** 0442 * ieee802154_unregister_hw - Unregister a hardware device 0443 * 0444 * This function instructs mac802154 to free allocated resources 0445 * and unregister netdevices from the networking subsystem. 0446 * 0447 * @hw: the hardware to unregister 0448 */ 0449 void ieee802154_unregister_hw(struct ieee802154_hw *hw); 0450 0451 /** 0452 * ieee802154_rx_irqsafe - receive frame 0453 * 0454 * Like ieee802154_rx() but can be called in IRQ context 0455 * (internally defers to a tasklet.) 0456 * 0457 * @hw: the hardware this frame came in on 0458 * @skb: the buffer to receive, owned by mac802154 after this call 0459 * @lqi: link quality indicator 0460 */ 0461 void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, 0462 u8 lqi); 0463 /** 0464 * ieee802154_wake_queue - wake ieee802154 queue 0465 * @hw: pointer as obtained from ieee802154_alloc_hw(). 0466 * 0467 * Tranceivers usually have either one transmit framebuffer or one framebuffer 0468 * for both transmitting and receiving. Hence, the core currently only handles 0469 * one frame at a time for each phy, which means we had to stop the queue to 0470 * avoid new skb to come during the transmission. The queue then needs to be 0471 * woken up after the operation. 0472 * 0473 * Drivers should use this function instead of netif_wake_queue. 0474 */ 0475 void ieee802154_wake_queue(struct ieee802154_hw *hw); 0476 0477 /** 0478 * ieee802154_stop_queue - stop ieee802154 queue 0479 * @hw: pointer as obtained from ieee802154_alloc_hw(). 0480 * 0481 * Tranceivers usually have either one transmit framebuffer or one framebuffer 0482 * for both transmitting and receiving. Hence, the core currently only handles 0483 * one frame at a time for each phy, which means we need to tell upper layers to 0484 * stop giving us new skbs while we are busy with the transmitted one. The queue 0485 * must then be stopped before transmitting. 0486 * 0487 * Drivers should use this function instead of netif_stop_queue. 0488 */ 0489 void ieee802154_stop_queue(struct ieee802154_hw *hw); 0490 0491 /** 0492 * ieee802154_xmit_complete - frame transmission complete 0493 * 0494 * @hw: pointer as obtained from ieee802154_alloc_hw(). 0495 * @skb: buffer for transmission 0496 * @ifs_handling: indicate interframe space handling 0497 */ 0498 void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb, 0499 bool ifs_handling); 0500 0501 /** 0502 * ieee802154_xmit_error - offloaded frame transmission failed 0503 * 0504 * @hw: pointer as obtained from ieee802154_alloc_hw(). 0505 * @skb: buffer for transmission 0506 * @reason: error code 0507 */ 0508 void ieee802154_xmit_error(struct ieee802154_hw *hw, struct sk_buff *skb, 0509 int reason); 0510 0511 /** 0512 * ieee802154_xmit_hw_error - frame could not be offloaded to the transmitter 0513 * because of a hardware error (bus error, timeout, etc) 0514 * 0515 * @hw: pointer as obtained from ieee802154_alloc_hw(). 0516 * @skb: buffer for transmission 0517 */ 0518 void ieee802154_xmit_hw_error(struct ieee802154_hw *hw, struct sk_buff *skb); 0519 0520 #endif /* NET_MAC802154_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |