Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2007, 2008, 2009 Siemens AG
0004  *
0005  * Written by:
0006  * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
0007  */
0008 
0009 #ifndef __NET_CFG802154_H
0010 #define __NET_CFG802154_H
0011 
0012 #include <linux/ieee802154.h>
0013 #include <linux/netdevice.h>
0014 #include <linux/mutex.h>
0015 #include <linux/bug.h>
0016 
0017 #include <net/nl802154.h>
0018 
0019 struct wpan_phy;
0020 struct wpan_phy_cca;
0021 
0022 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
0023 struct ieee802154_llsec_device_key;
0024 struct ieee802154_llsec_seclevel;
0025 struct ieee802154_llsec_params;
0026 struct ieee802154_llsec_device;
0027 struct ieee802154_llsec_table;
0028 struct ieee802154_llsec_key_id;
0029 struct ieee802154_llsec_key;
0030 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
0031 
0032 struct cfg802154_ops {
0033     struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
0034                                const char *name,
0035                                unsigned char name_assign_type,
0036                                int type);
0037     void    (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
0038                            struct net_device *dev);
0039     int (*suspend)(struct wpan_phy *wpan_phy);
0040     int (*resume)(struct wpan_phy *wpan_phy);
0041     int (*add_virtual_intf)(struct wpan_phy *wpan_phy,
0042                     const char *name,
0043                     unsigned char name_assign_type,
0044                     enum nl802154_iftype type,
0045                     __le64 extended_addr);
0046     int (*del_virtual_intf)(struct wpan_phy *wpan_phy,
0047                     struct wpan_dev *wpan_dev);
0048     int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel);
0049     int (*set_cca_mode)(struct wpan_phy *wpan_phy,
0050                 const struct wpan_phy_cca *cca);
0051     int     (*set_cca_ed_level)(struct wpan_phy *wpan_phy, s32 ed_level);
0052     int     (*set_tx_power)(struct wpan_phy *wpan_phy, s32 power);
0053     int (*set_pan_id)(struct wpan_phy *wpan_phy,
0054                   struct wpan_dev *wpan_dev, __le16 pan_id);
0055     int (*set_short_addr)(struct wpan_phy *wpan_phy,
0056                   struct wpan_dev *wpan_dev, __le16 short_addr);
0057     int (*set_backoff_exponent)(struct wpan_phy *wpan_phy,
0058                     struct wpan_dev *wpan_dev, u8 min_be,
0059                     u8 max_be);
0060     int (*set_max_csma_backoffs)(struct wpan_phy *wpan_phy,
0061                      struct wpan_dev *wpan_dev,
0062                      u8 max_csma_backoffs);
0063     int (*set_max_frame_retries)(struct wpan_phy *wpan_phy,
0064                      struct wpan_dev *wpan_dev,
0065                      s8 max_frame_retries);
0066     int (*set_lbt_mode)(struct wpan_phy *wpan_phy,
0067                 struct wpan_dev *wpan_dev, bool mode);
0068     int (*set_ackreq_default)(struct wpan_phy *wpan_phy,
0069                       struct wpan_dev *wpan_dev, bool ackreq);
0070 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
0071     void    (*get_llsec_table)(struct wpan_phy *wpan_phy,
0072                    struct wpan_dev *wpan_dev,
0073                    struct ieee802154_llsec_table **table);
0074     void    (*lock_llsec_table)(struct wpan_phy *wpan_phy,
0075                     struct wpan_dev *wpan_dev);
0076     void    (*unlock_llsec_table)(struct wpan_phy *wpan_phy,
0077                       struct wpan_dev *wpan_dev);
0078     /* TODO remove locking/get table callbacks, this is part of the
0079      * nl802154 interface and should be accessible from ieee802154 layer.
0080      */
0081     int (*get_llsec_params)(struct wpan_phy *wpan_phy,
0082                     struct wpan_dev *wpan_dev,
0083                     struct ieee802154_llsec_params *params);
0084     int (*set_llsec_params)(struct wpan_phy *wpan_phy,
0085                     struct wpan_dev *wpan_dev,
0086                     const struct ieee802154_llsec_params *params,
0087                     int changed);
0088     int (*add_llsec_key)(struct wpan_phy *wpan_phy,
0089                  struct wpan_dev *wpan_dev,
0090                  const struct ieee802154_llsec_key_id *id,
0091                  const struct ieee802154_llsec_key *key);
0092     int (*del_llsec_key)(struct wpan_phy *wpan_phy,
0093                  struct wpan_dev *wpan_dev,
0094                  const struct ieee802154_llsec_key_id *id);
0095     int (*add_seclevel)(struct wpan_phy *wpan_phy,
0096                  struct wpan_dev *wpan_dev,
0097                  const struct ieee802154_llsec_seclevel *sl);
0098     int (*del_seclevel)(struct wpan_phy *wpan_phy,
0099                  struct wpan_dev *wpan_dev,
0100                  const struct ieee802154_llsec_seclevel *sl);
0101     int (*add_device)(struct wpan_phy *wpan_phy,
0102                   struct wpan_dev *wpan_dev,
0103                   const struct ieee802154_llsec_device *dev);
0104     int (*del_device)(struct wpan_phy *wpan_phy,
0105                   struct wpan_dev *wpan_dev, __le64 extended_addr);
0106     int (*add_devkey)(struct wpan_phy *wpan_phy,
0107                   struct wpan_dev *wpan_dev,
0108                   __le64 extended_addr,
0109                   const struct ieee802154_llsec_device_key *key);
0110     int (*del_devkey)(struct wpan_phy *wpan_phy,
0111                   struct wpan_dev *wpan_dev,
0112                   __le64 extended_addr,
0113                   const struct ieee802154_llsec_device_key *key);
0114 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
0115 };
0116 
0117 static inline bool
0118 wpan_phy_supported_bool(bool b, enum nl802154_supported_bool_states st)
0119 {
0120     switch (st) {
0121     case NL802154_SUPPORTED_BOOL_TRUE:
0122         return b;
0123     case NL802154_SUPPORTED_BOOL_FALSE:
0124         return !b;
0125     case NL802154_SUPPORTED_BOOL_BOTH:
0126         return true;
0127     default:
0128         WARN_ON(1);
0129     }
0130 
0131     return false;
0132 }
0133 
0134 struct wpan_phy_supported {
0135     u32 channels[IEEE802154_MAX_PAGE + 1],
0136         cca_modes, cca_opts, iftypes;
0137     enum nl802154_supported_bool_states lbt;
0138     u8 min_minbe, max_minbe, min_maxbe, max_maxbe,
0139        min_csma_backoffs, max_csma_backoffs;
0140     s8 min_frame_retries, max_frame_retries;
0141     size_t tx_powers_size, cca_ed_levels_size;
0142     const s32 *tx_powers, *cca_ed_levels;
0143 };
0144 
0145 struct wpan_phy_cca {
0146     enum nl802154_cca_modes mode;
0147     enum nl802154_cca_opts opt;
0148 };
0149 
0150 static inline bool
0151 wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
0152 {
0153     if (a->mode != b->mode)
0154         return false;
0155 
0156     if (a->mode == NL802154_CCA_ENERGY_CARRIER)
0157         return a->opt == b->opt;
0158 
0159     return true;
0160 }
0161 
0162 /**
0163  * @WPAN_PHY_FLAG_TRANSMIT_POWER: Indicates that transceiver will support
0164  *  transmit power setting.
0165  * @WPAN_PHY_FLAG_CCA_ED_LEVEL: Indicates that transceiver will support cca ed
0166  *  level setting.
0167  * @WPAN_PHY_FLAG_CCA_MODE: Indicates that transceiver will support cca mode
0168  *  setting.
0169  */
0170 enum wpan_phy_flags {
0171     WPAN_PHY_FLAG_TXPOWER       = BIT(1),
0172     WPAN_PHY_FLAG_CCA_ED_LEVEL  = BIT(2),
0173     WPAN_PHY_FLAG_CCA_MODE      = BIT(3),
0174 };
0175 
0176 struct wpan_phy {
0177     /* If multiple wpan_phys are registered and you're handed e.g.
0178      * a regular netdev with assigned ieee802154_ptr, you won't
0179      * know whether it points to a wpan_phy your driver has registered
0180      * or not. Assign this to something global to your driver to
0181      * help determine whether you own this wpan_phy or not.
0182      */
0183     const void *privid;
0184 
0185     u32 flags;
0186 
0187     /*
0188      * This is a PIB according to 802.15.4-2011.
0189      * We do not provide timing-related variables, as they
0190      * aren't used outside of driver
0191      */
0192     u8 current_channel;
0193     u8 current_page;
0194     struct wpan_phy_supported supported;
0195     /* current transmit_power in mBm */
0196     s32 transmit_power;
0197     struct wpan_phy_cca cca;
0198 
0199     __le64 perm_extended_addr;
0200 
0201     /* current cca ed threshold in mBm */
0202     s32 cca_ed_level;
0203 
0204     /* PHY depended MAC PIB values */
0205 
0206     /* 802.15.4 acronym: Tdsym in nsec */
0207     u32 symbol_duration;
0208     /* lifs and sifs periods timing */
0209     u16 lifs_period;
0210     u16 sifs_period;
0211 
0212     struct device dev;
0213 
0214     /* the network namespace this phy lives in currently */
0215     possible_net_t _net;
0216 
0217     char priv[] __aligned(NETDEV_ALIGN);
0218 };
0219 
0220 static inline struct net *wpan_phy_net(struct wpan_phy *wpan_phy)
0221 {
0222     return read_pnet(&wpan_phy->_net);
0223 }
0224 
0225 static inline void wpan_phy_net_set(struct wpan_phy *wpan_phy, struct net *net)
0226 {
0227     write_pnet(&wpan_phy->_net, net);
0228 }
0229 
0230 /**
0231  * struct ieee802154_addr - IEEE802.15.4 device address
0232  * @mode: Address mode from frame header. Can be one of:
0233  *        - @IEEE802154_ADDR_NONE
0234  *        - @IEEE802154_ADDR_SHORT
0235  *        - @IEEE802154_ADDR_LONG
0236  * @pan_id: The PAN ID this address belongs to
0237  * @short_addr: address if @mode is @IEEE802154_ADDR_SHORT
0238  * @extended_addr: address if @mode is @IEEE802154_ADDR_LONG
0239  */
0240 struct ieee802154_addr {
0241     u8 mode;
0242     __le16 pan_id;
0243     union {
0244         __le16 short_addr;
0245         __le64 extended_addr;
0246     };
0247 };
0248 
0249 struct ieee802154_llsec_key_id {
0250     u8 mode;
0251     u8 id;
0252     union {
0253         struct ieee802154_addr device_addr;
0254         __le32 short_source;
0255         __le64 extended_source;
0256     };
0257 };
0258 
0259 #define IEEE802154_LLSEC_KEY_SIZE 16
0260 
0261 struct ieee802154_llsec_key {
0262     u8 frame_types;
0263     u32 cmd_frame_ids;
0264     /* TODO replace with NL802154_KEY_SIZE */
0265     u8 key[IEEE802154_LLSEC_KEY_SIZE];
0266 };
0267 
0268 struct ieee802154_llsec_key_entry {
0269     struct list_head list;
0270 
0271     struct ieee802154_llsec_key_id id;
0272     struct ieee802154_llsec_key *key;
0273 };
0274 
0275 struct ieee802154_llsec_params {
0276     bool enabled;
0277 
0278     __be32 frame_counter;
0279     u8 out_level;
0280     struct ieee802154_llsec_key_id out_key;
0281 
0282     __le64 default_key_source;
0283 
0284     __le16 pan_id;
0285     __le64 hwaddr;
0286     __le64 coord_hwaddr;
0287     __le16 coord_shortaddr;
0288 };
0289 
0290 struct ieee802154_llsec_table {
0291     struct list_head keys;
0292     struct list_head devices;
0293     struct list_head security_levels;
0294 };
0295 
0296 struct ieee802154_llsec_seclevel {
0297     struct list_head list;
0298 
0299     u8 frame_type;
0300     u8 cmd_frame_id;
0301     bool device_override;
0302     u32 sec_levels;
0303 };
0304 
0305 struct ieee802154_llsec_device {
0306     struct list_head list;
0307 
0308     __le16 pan_id;
0309     __le16 short_addr;
0310     __le64 hwaddr;
0311     u32 frame_counter;
0312     bool seclevel_exempt;
0313 
0314     u8 key_mode;
0315     struct list_head keys;
0316 };
0317 
0318 struct ieee802154_llsec_device_key {
0319     struct list_head list;
0320 
0321     struct ieee802154_llsec_key_id key_id;
0322     u32 frame_counter;
0323 };
0324 
0325 struct wpan_dev_header_ops {
0326     /* TODO create callback currently assumes ieee802154_mac_cb inside
0327      * skb->cb. This should be changed to give these information as
0328      * parameter.
0329      */
0330     int (*create)(struct sk_buff *skb, struct net_device *dev,
0331               const struct ieee802154_addr *daddr,
0332               const struct ieee802154_addr *saddr,
0333               unsigned int len);
0334 };
0335 
0336 struct wpan_dev {
0337     struct wpan_phy *wpan_phy;
0338     int iftype;
0339 
0340     /* the remainder of this struct should be private to cfg802154 */
0341     struct list_head list;
0342     struct net_device *netdev;
0343 
0344     const struct wpan_dev_header_ops *header_ops;
0345 
0346     /* lowpan interface, set when the wpan_dev belongs to one lowpan_dev */
0347     struct net_device *lowpan_dev;
0348 
0349     u32 identifier;
0350 
0351     /* MAC PIB */
0352     __le16 pan_id;
0353     __le16 short_addr;
0354     __le64 extended_addr;
0355 
0356     /* MAC BSN field */
0357     atomic_t bsn;
0358     /* MAC DSN field */
0359     atomic_t dsn;
0360 
0361     u8 min_be;
0362     u8 max_be;
0363     u8 csma_retries;
0364     s8 frame_retries;
0365 
0366     bool lbt;
0367 
0368     bool promiscuous_mode;
0369 
0370     /* fallback for acknowledgment bit setting */
0371     bool ackreq;
0372 };
0373 
0374 #define to_phy(_dev)    container_of(_dev, struct wpan_phy, dev)
0375 
0376 #if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN)
0377 static inline int
0378 wpan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
0379              const struct ieee802154_addr *daddr,
0380              const struct ieee802154_addr *saddr,
0381              unsigned int len)
0382 {
0383     struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
0384 
0385     return wpan_dev->header_ops->create(skb, dev, daddr, saddr, len);
0386 }
0387 #endif
0388 
0389 struct wpan_phy *
0390 wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size);
0391 static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev)
0392 {
0393     phy->dev.parent = dev;
0394 }
0395 
0396 int wpan_phy_register(struct wpan_phy *phy);
0397 void wpan_phy_unregister(struct wpan_phy *phy);
0398 void wpan_phy_free(struct wpan_phy *phy);
0399 /* Same semantics as for class_for_each_device */
0400 int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), void *data);
0401 
0402 static inline void *wpan_phy_priv(struct wpan_phy *phy)
0403 {
0404     BUG_ON(!phy);
0405     return &phy->priv;
0406 }
0407 
0408 struct wpan_phy *wpan_phy_find(const char *str);
0409 
0410 static inline void wpan_phy_put(struct wpan_phy *phy)
0411 {
0412     put_device(&phy->dev);
0413 }
0414 
0415 static inline const char *wpan_phy_name(struct wpan_phy *phy)
0416 {
0417     return dev_name(&phy->dev);
0418 }
0419 
0420 void ieee802154_configure_durations(struct wpan_phy *phy);
0421 
0422 #endif /* __NET_CFG802154_H */