Back to home page

OSCL-LXR

 
 

    


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 */