linux/include/net/cfg802154.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2007, 2008, 2009 Siemens AG
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2
   6 * as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 * Written by:
  14 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
  15 */
  16
  17#ifndef __NET_CFG802154_H
  18#define __NET_CFG802154_H
  19
  20#include <linux/ieee802154.h>
  21#include <linux/netdevice.h>
  22#include <linux/mutex.h>
  23#include <linux/bug.h>
  24
  25#include <net/nl802154.h>
  26
  27struct wpan_phy;
  28struct wpan_phy_cca;
  29
  30#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
  31struct ieee802154_llsec_device_key;
  32struct ieee802154_llsec_seclevel;
  33struct ieee802154_llsec_params;
  34struct ieee802154_llsec_device;
  35struct ieee802154_llsec_table;
  36struct ieee802154_llsec_key_id;
  37struct ieee802154_llsec_key;
  38#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
  39
  40struct cfg802154_ops {
  41        struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
  42                                                           const char *name,
  43                                                           unsigned char name_assign_type,
  44                                                           int type);
  45        void    (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
  46                                               struct net_device *dev);
  47        int     (*suspend)(struct wpan_phy *wpan_phy);
  48        int     (*resume)(struct wpan_phy *wpan_phy);
  49        int     (*add_virtual_intf)(struct wpan_phy *wpan_phy,
  50                                    const char *name,
  51                                    unsigned char name_assign_type,
  52                                    enum nl802154_iftype type,
  53                                    __le64 extended_addr);
  54        int     (*del_virtual_intf)(struct wpan_phy *wpan_phy,
  55                                    struct wpan_dev *wpan_dev);
  56        int     (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel);
  57        int     (*set_cca_mode)(struct wpan_phy *wpan_phy,
  58                                const struct wpan_phy_cca *cca);
  59        int     (*set_cca_ed_level)(struct wpan_phy *wpan_phy, s32 ed_level);
  60        int     (*set_tx_power)(struct wpan_phy *wpan_phy, s32 power);
  61        int     (*set_pan_id)(struct wpan_phy *wpan_phy,
  62                              struct wpan_dev *wpan_dev, __le16 pan_id);
  63        int     (*set_short_addr)(struct wpan_phy *wpan_phy,
  64                                  struct wpan_dev *wpan_dev, __le16 short_addr);
  65        int     (*set_backoff_exponent)(struct wpan_phy *wpan_phy,
  66                                        struct wpan_dev *wpan_dev, u8 min_be,
  67                                        u8 max_be);
  68        int     (*set_max_csma_backoffs)(struct wpan_phy *wpan_phy,
  69                                         struct wpan_dev *wpan_dev,
  70                                         u8 max_csma_backoffs);
  71        int     (*set_max_frame_retries)(struct wpan_phy *wpan_phy,
  72                                         struct wpan_dev *wpan_dev,
  73                                         s8 max_frame_retries);
  74        int     (*set_lbt_mode)(struct wpan_phy *wpan_phy,
  75                                struct wpan_dev *wpan_dev, bool mode);
  76        int     (*set_ackreq_default)(struct wpan_phy *wpan_phy,
  77                                      struct wpan_dev *wpan_dev, bool ackreq);
  78#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
  79        void    (*get_llsec_table)(struct wpan_phy *wpan_phy,
  80                                   struct wpan_dev *wpan_dev,
  81                                   struct ieee802154_llsec_table **table);
  82        void    (*lock_llsec_table)(struct wpan_phy *wpan_phy,
  83                                    struct wpan_dev *wpan_dev);
  84        void    (*unlock_llsec_table)(struct wpan_phy *wpan_phy,
  85                                      struct wpan_dev *wpan_dev);
  86        /* TODO remove locking/get table callbacks, this is part of the
  87         * nl802154 interface and should be accessible from ieee802154 layer.
  88         */
  89        int     (*get_llsec_params)(struct wpan_phy *wpan_phy,
  90                                    struct wpan_dev *wpan_dev,
  91                                    struct ieee802154_llsec_params *params);
  92        int     (*set_llsec_params)(struct wpan_phy *wpan_phy,
  93                                    struct wpan_dev *wpan_dev,
  94                                    const struct ieee802154_llsec_params *params,
  95                                    int changed);
  96        int     (*add_llsec_key)(struct wpan_phy *wpan_phy,
  97                                 struct wpan_dev *wpan_dev,
  98                                 const struct ieee802154_llsec_key_id *id,
  99                                 const struct ieee802154_llsec_key *key);
 100        int     (*del_llsec_key)(struct wpan_phy *wpan_phy,
 101                                 struct wpan_dev *wpan_dev,
 102                                 const struct ieee802154_llsec_key_id *id);
 103        int     (*add_seclevel)(struct wpan_phy *wpan_phy,
 104                                 struct wpan_dev *wpan_dev,
 105                                 const struct ieee802154_llsec_seclevel *sl);
 106        int     (*del_seclevel)(struct wpan_phy *wpan_phy,
 107                                 struct wpan_dev *wpan_dev,
 108                                 const struct ieee802154_llsec_seclevel *sl);
 109        int     (*add_device)(struct wpan_phy *wpan_phy,
 110                              struct wpan_dev *wpan_dev,
 111                              const struct ieee802154_llsec_device *dev);
 112        int     (*del_device)(struct wpan_phy *wpan_phy,
 113                              struct wpan_dev *wpan_dev, __le64 extended_addr);
 114        int     (*add_devkey)(struct wpan_phy *wpan_phy,
 115                              struct wpan_dev *wpan_dev,
 116                              __le64 extended_addr,
 117                              const struct ieee802154_llsec_device_key *key);
 118        int     (*del_devkey)(struct wpan_phy *wpan_phy,
 119                              struct wpan_dev *wpan_dev,
 120                              __le64 extended_addr,
 121                              const struct ieee802154_llsec_device_key *key);
 122#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
 123};
 124
 125static inline bool
 126wpan_phy_supported_bool(bool b, enum nl802154_supported_bool_states st)
 127{
 128        switch (st) {
 129        case NL802154_SUPPORTED_BOOL_TRUE:
 130                return b;
 131        case NL802154_SUPPORTED_BOOL_FALSE:
 132                return !b;
 133        case NL802154_SUPPORTED_BOOL_BOTH:
 134                return true;
 135        default:
 136                WARN_ON(1);
 137        }
 138
 139        return false;
 140}
 141
 142struct wpan_phy_supported {
 143        u32 channels[IEEE802154_MAX_PAGE + 1],
 144            cca_modes, cca_opts, iftypes;
 145        enum nl802154_supported_bool_states lbt;
 146        u8 min_minbe, max_minbe, min_maxbe, max_maxbe,
 147           min_csma_backoffs, max_csma_backoffs;
 148        s8 min_frame_retries, max_frame_retries;
 149        size_t tx_powers_size, cca_ed_levels_size;
 150        const s32 *tx_powers, *cca_ed_levels;
 151};
 152
 153struct wpan_phy_cca {
 154        enum nl802154_cca_modes mode;
 155        enum nl802154_cca_opts opt;
 156};
 157
 158static inline bool
 159wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
 160{
 161        if (a->mode != b->mode)
 162                return false;
 163
 164        if (a->mode == NL802154_CCA_ENERGY_CARRIER)
 165                return a->opt == b->opt;
 166
 167        return true;
 168}
 169
 170/**
 171 * @WPAN_PHY_FLAG_TRANSMIT_POWER: Indicates that transceiver will support
 172 *      transmit power setting.
 173 * @WPAN_PHY_FLAG_CCA_ED_LEVEL: Indicates that transceiver will support cca ed
 174 *      level setting.
 175 * @WPAN_PHY_FLAG_CCA_MODE: Indicates that transceiver will support cca mode
 176 *      setting.
 177 */
 178enum wpan_phy_flags {
 179        WPAN_PHY_FLAG_TXPOWER           = BIT(1),
 180        WPAN_PHY_FLAG_CCA_ED_LEVEL      = BIT(2),
 181        WPAN_PHY_FLAG_CCA_MODE          = BIT(3),
 182};
 183
 184struct wpan_phy {
 185        /* If multiple wpan_phys are registered and you're handed e.g.
 186         * a regular netdev with assigned ieee802154_ptr, you won't
 187         * know whether it points to a wpan_phy your driver has registered
 188         * or not. Assign this to something global to your driver to
 189         * help determine whether you own this wpan_phy or not.
 190         */
 191        const void *privid;
 192
 193        u32 flags;
 194
 195        /*
 196         * This is a PIB according to 802.15.4-2011.
 197         * We do not provide timing-related variables, as they
 198         * aren't used outside of driver
 199         */
 200        u8 current_channel;
 201        u8 current_page;
 202        struct wpan_phy_supported supported;
 203        /* current transmit_power in mBm */
 204        s32 transmit_power;
 205        struct wpan_phy_cca cca;
 206
 207        __le64 perm_extended_addr;
 208
 209        /* current cca ed threshold in mBm */
 210        s32 cca_ed_level;
 211
 212        /* PHY depended MAC PIB values */
 213
 214        /* 802.15.4 acronym: Tdsym in usec */
 215        u8 symbol_duration;
 216        /* lifs and sifs periods timing */
 217        u16 lifs_period;
 218        u16 sifs_period;
 219
 220        struct device dev;
 221
 222        char priv[0] __aligned(NETDEV_ALIGN);
 223};
 224
 225struct ieee802154_addr {
 226        u8 mode;
 227        __le16 pan_id;
 228        union {
 229                __le16 short_addr;
 230                __le64 extended_addr;
 231        };
 232};
 233
 234struct ieee802154_llsec_key_id {
 235        u8 mode;
 236        u8 id;
 237        union {
 238                struct ieee802154_addr device_addr;
 239                __le32 short_source;
 240                __le64 extended_source;
 241        };
 242};
 243
 244#define IEEE802154_LLSEC_KEY_SIZE 16
 245
 246struct ieee802154_llsec_key {
 247        u8 frame_types;
 248        u32 cmd_frame_ids;
 249        /* TODO replace with NL802154_KEY_SIZE */
 250        u8 key[IEEE802154_LLSEC_KEY_SIZE];
 251};
 252
 253struct ieee802154_llsec_key_entry {
 254        struct list_head list;
 255
 256        struct ieee802154_llsec_key_id id;
 257        struct ieee802154_llsec_key *key;
 258};
 259
 260struct ieee802154_llsec_params {
 261        bool enabled;
 262
 263        __be32 frame_counter;
 264        u8 out_level;
 265        struct ieee802154_llsec_key_id out_key;
 266
 267        __le64 default_key_source;
 268
 269        __le16 pan_id;
 270        __le64 hwaddr;
 271        __le64 coord_hwaddr;
 272        __le16 coord_shortaddr;
 273};
 274
 275struct ieee802154_llsec_table {
 276        struct list_head keys;
 277        struct list_head devices;
 278        struct list_head security_levels;
 279};
 280
 281struct ieee802154_llsec_seclevel {
 282        struct list_head list;
 283
 284        u8 frame_type;
 285        u8 cmd_frame_id;
 286        bool device_override;
 287        u32 sec_levels;
 288};
 289
 290struct ieee802154_llsec_device {
 291        struct list_head list;
 292
 293        __le16 pan_id;
 294        __le16 short_addr;
 295        __le64 hwaddr;
 296        u32 frame_counter;
 297        bool seclevel_exempt;
 298
 299        u8 key_mode;
 300        struct list_head keys;
 301};
 302
 303struct ieee802154_llsec_device_key {
 304        struct list_head list;
 305
 306        struct ieee802154_llsec_key_id key_id;
 307        u32 frame_counter;
 308};
 309
 310struct wpan_dev_header_ops {
 311        /* TODO create callback currently assumes ieee802154_mac_cb inside
 312         * skb->cb. This should be changed to give these information as
 313         * parameter.
 314         */
 315        int     (*create)(struct sk_buff *skb, struct net_device *dev,
 316                          const struct ieee802154_addr *daddr,
 317                          const struct ieee802154_addr *saddr,
 318                          unsigned int len);
 319};
 320
 321struct wpan_dev {
 322        struct wpan_phy *wpan_phy;
 323        int iftype;
 324
 325        /* the remainder of this struct should be private to cfg802154 */
 326        struct list_head list;
 327        struct net_device *netdev;
 328
 329        const struct wpan_dev_header_ops *header_ops;
 330
 331        /* lowpan interface, set when the wpan_dev belongs to one lowpan_dev */
 332        struct net_device *lowpan_dev;
 333
 334        u32 identifier;
 335
 336        /* MAC PIB */
 337        __le16 pan_id;
 338        __le16 short_addr;
 339        __le64 extended_addr;
 340
 341        /* MAC BSN field */
 342        atomic_t bsn;
 343        /* MAC DSN field */
 344        atomic_t dsn;
 345
 346        u8 min_be;
 347        u8 max_be;
 348        u8 csma_retries;
 349        s8 frame_retries;
 350
 351        bool lbt;
 352
 353        bool promiscuous_mode;
 354
 355        /* fallback for acknowledgment bit setting */
 356        bool ackreq;
 357};
 358
 359#define to_phy(_dev)    container_of(_dev, struct wpan_phy, dev)
 360
 361static inline int
 362wpan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 363                     const struct ieee802154_addr *daddr,
 364                     const struct ieee802154_addr *saddr,
 365                     unsigned int len)
 366{
 367        struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
 368
 369        return wpan_dev->header_ops->create(skb, dev, daddr, saddr, len);
 370}
 371
 372struct wpan_phy *
 373wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size);
 374static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev)
 375{
 376        phy->dev.parent = dev;
 377}
 378
 379int wpan_phy_register(struct wpan_phy *phy);
 380void wpan_phy_unregister(struct wpan_phy *phy);
 381void wpan_phy_free(struct wpan_phy *phy);
 382/* Same semantics as for class_for_each_device */
 383int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), void *data);
 384
 385static inline void *wpan_phy_priv(struct wpan_phy *phy)
 386{
 387        BUG_ON(!phy);
 388        return &phy->priv;
 389}
 390
 391struct wpan_phy *wpan_phy_find(const char *str);
 392
 393static inline void wpan_phy_put(struct wpan_phy *phy)
 394{
 395        put_device(&phy->dev);
 396}
 397
 398static inline const char *wpan_phy_name(struct wpan_phy *phy)
 399{
 400        return dev_name(&phy->dev);
 401}
 402
 403#endif /* __NET_CFG802154_H */
 404