Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * An interface between IEEE802.15.4 device and rest of the kernel.
0004  *
0005  * Copyright (C) 2007-2012 Siemens AG
0006  *
0007  * Written by:
0008  * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
0009  * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
0010  * Maxim Osipov <maxim.osipov@siemens.com>
0011  * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
0012  * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
0013  */
0014 
0015 #ifndef IEEE802154_NETDEVICE_H
0016 #define IEEE802154_NETDEVICE_H
0017 
0018 #define IEEE802154_REQUIRED_SIZE(struct_type, member) \
0019     (offsetof(typeof(struct_type), member) + \
0020     sizeof(((typeof(struct_type) *)(NULL))->member))
0021 
0022 #define IEEE802154_ADDR_OFFSET \
0023     offsetof(typeof(struct sockaddr_ieee802154), addr)
0024 
0025 #define IEEE802154_MIN_NAMELEN (IEEE802154_ADDR_OFFSET + \
0026     IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, addr_type))
0027 
0028 #define IEEE802154_NAMELEN_SHORT (IEEE802154_ADDR_OFFSET + \
0029     IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, short_addr))
0030 
0031 #define IEEE802154_NAMELEN_LONG (IEEE802154_ADDR_OFFSET + \
0032     IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, hwaddr))
0033 
0034 #include <net/af_ieee802154.h>
0035 #include <linux/netdevice.h>
0036 #include <linux/skbuff.h>
0037 #include <linux/ieee802154.h>
0038 
0039 #include <net/cfg802154.h>
0040 
0041 struct ieee802154_sechdr {
0042 #if defined(__LITTLE_ENDIAN_BITFIELD)
0043     u8 level:3,
0044        key_id_mode:2,
0045        reserved:3;
0046 #elif defined(__BIG_ENDIAN_BITFIELD)
0047     u8 reserved:3,
0048        key_id_mode:2,
0049        level:3;
0050 #else
0051 #error  "Please fix <asm/byteorder.h>"
0052 #endif
0053     u8 key_id;
0054     __le32 frame_counter;
0055     union {
0056         __le32 short_src;
0057         __le64 extended_src;
0058     };
0059 };
0060 
0061 struct ieee802154_hdr_fc {
0062 #if defined(__LITTLE_ENDIAN_BITFIELD)
0063     u16 type:3,
0064         security_enabled:1,
0065         frame_pending:1,
0066         ack_request:1,
0067         intra_pan:1,
0068         reserved:3,
0069         dest_addr_mode:2,
0070         version:2,
0071         source_addr_mode:2;
0072 #elif defined(__BIG_ENDIAN_BITFIELD)
0073     u16 reserved:1,
0074         intra_pan:1,
0075         ack_request:1,
0076         frame_pending:1,
0077         security_enabled:1,
0078         type:3,
0079         source_addr_mode:2,
0080         version:2,
0081         dest_addr_mode:2,
0082         reserved2:2;
0083 #else
0084 #error  "Please fix <asm/byteorder.h>"
0085 #endif
0086 };
0087 
0088 struct ieee802154_hdr {
0089     struct ieee802154_hdr_fc fc;
0090     u8 seq;
0091     struct ieee802154_addr source;
0092     struct ieee802154_addr dest;
0093     struct ieee802154_sechdr sec;
0094 };
0095 
0096 /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
0097  * the contents of hdr will be, and the actual value of those bits in
0098  * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
0099  * version, if SECEN is set.
0100  */
0101 int ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr);
0102 
0103 /* pulls the entire 802.15.4 header off of the skb, including the security
0104  * header, and performs pan id decompression
0105  */
0106 int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr);
0107 
0108 /* parses the frame control, sequence number of address fields in a given skb
0109  * and stores them into hdr, performing pan id decompression and length checks
0110  * to be suitable for use in header_ops.parse
0111  */
0112 int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
0113                   struct ieee802154_hdr *hdr);
0114 
0115 /* parses the full 802.15.4 header a given skb and stores them into hdr,
0116  * performing pan id decompression and length checks to be suitable for use in
0117  * header_ops.parse
0118  */
0119 int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
0120 
0121 int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
0122 
0123 static inline int
0124 ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec)
0125 {
0126     switch (sec->level) {
0127     case IEEE802154_SCF_SECLEVEL_MIC32:
0128     case IEEE802154_SCF_SECLEVEL_ENC_MIC32:
0129         return 4;
0130     case IEEE802154_SCF_SECLEVEL_MIC64:
0131     case IEEE802154_SCF_SECLEVEL_ENC_MIC64:
0132         return 8;
0133     case IEEE802154_SCF_SECLEVEL_MIC128:
0134     case IEEE802154_SCF_SECLEVEL_ENC_MIC128:
0135         return 16;
0136     case IEEE802154_SCF_SECLEVEL_NONE:
0137     case IEEE802154_SCF_SECLEVEL_ENC:
0138     default:
0139         return 0;
0140     }
0141 }
0142 
0143 static inline int ieee802154_hdr_length(struct sk_buff *skb)
0144 {
0145     struct ieee802154_hdr hdr;
0146     int len = ieee802154_hdr_pull(skb, &hdr);
0147 
0148     if (len > 0)
0149         skb_push(skb, len);
0150 
0151     return len;
0152 }
0153 
0154 static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1,
0155                      const struct ieee802154_addr *a2)
0156 {
0157     if (a1->pan_id != a2->pan_id || a1->mode != a2->mode)
0158         return false;
0159 
0160     if ((a1->mode == IEEE802154_ADDR_LONG &&
0161          a1->extended_addr != a2->extended_addr) ||
0162         (a1->mode == IEEE802154_ADDR_SHORT &&
0163          a1->short_addr != a2->short_addr))
0164         return false;
0165 
0166     return true;
0167 }
0168 
0169 static inline __le64 ieee802154_devaddr_from_raw(const void *raw)
0170 {
0171     u64 temp;
0172 
0173     memcpy(&temp, raw, IEEE802154_ADDR_LEN);
0174     return (__force __le64)swab64(temp);
0175 }
0176 
0177 static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr)
0178 {
0179     u64 temp = swab64((__force u64)addr);
0180 
0181     memcpy(raw, &temp, IEEE802154_ADDR_LEN);
0182 }
0183 
0184 static inline int
0185 ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len)
0186 {
0187     struct ieee802154_addr_sa *sa;
0188 
0189     sa = &daddr->addr;
0190     if (len < IEEE802154_MIN_NAMELEN)
0191         return -EINVAL;
0192     switch (sa->addr_type) {
0193     case IEEE802154_ADDR_SHORT:
0194         if (len < IEEE802154_NAMELEN_SHORT)
0195             return -EINVAL;
0196         break;
0197     case IEEE802154_ADDR_LONG:
0198         if (len < IEEE802154_NAMELEN_LONG)
0199             return -EINVAL;
0200         break;
0201     }
0202     return 0;
0203 }
0204 
0205 static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
0206                        const struct ieee802154_addr_sa *sa)
0207 {
0208     a->mode = sa->addr_type;
0209     a->pan_id = cpu_to_le16(sa->pan_id);
0210 
0211     switch (a->mode) {
0212     case IEEE802154_ADDR_SHORT:
0213         a->short_addr = cpu_to_le16(sa->short_addr);
0214         break;
0215     case IEEE802154_ADDR_LONG:
0216         a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr);
0217         break;
0218     }
0219 }
0220 
0221 static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa,
0222                      const struct ieee802154_addr *a)
0223 {
0224     sa->addr_type = a->mode;
0225     sa->pan_id = le16_to_cpu(a->pan_id);
0226 
0227     switch (a->mode) {
0228     case IEEE802154_ADDR_SHORT:
0229         sa->short_addr = le16_to_cpu(a->short_addr);
0230         break;
0231     case IEEE802154_ADDR_LONG:
0232         ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr);
0233         break;
0234     }
0235 }
0236 
0237 /*
0238  * A control block of skb passed between the ARPHRD_IEEE802154 device
0239  * and other stack parts.
0240  */
0241 struct ieee802154_mac_cb {
0242     u8 lqi;
0243     u8 type;
0244     bool ackreq;
0245     bool secen;
0246     bool secen_override;
0247     u8 seclevel;
0248     bool seclevel_override;
0249     struct ieee802154_addr source;
0250     struct ieee802154_addr dest;
0251 };
0252 
0253 static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
0254 {
0255     return (struct ieee802154_mac_cb *)skb->cb;
0256 }
0257 
0258 static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb)
0259 {
0260     BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb));
0261 
0262     memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb));
0263     return mac_cb(skb);
0264 }
0265 
0266 enum {
0267     IEEE802154_LLSEC_DEVKEY_IGNORE,
0268     IEEE802154_LLSEC_DEVKEY_RESTRICT,
0269     IEEE802154_LLSEC_DEVKEY_RECORD,
0270 
0271     __IEEE802154_LLSEC_DEVKEY_MAX,
0272 };
0273 
0274 #define IEEE802154_MAC_SCAN_ED      0
0275 #define IEEE802154_MAC_SCAN_ACTIVE  1
0276 #define IEEE802154_MAC_SCAN_PASSIVE 2
0277 #define IEEE802154_MAC_SCAN_ORPHAN  3
0278 
0279 struct ieee802154_mac_params {
0280     s8 transmit_power;
0281     u8 min_be;
0282     u8 max_be;
0283     u8 csma_retries;
0284     s8 frame_retries;
0285 
0286     bool lbt;
0287     struct wpan_phy_cca cca;
0288     s32 cca_ed_level;
0289 };
0290 
0291 struct wpan_phy;
0292 
0293 enum {
0294     IEEE802154_LLSEC_PARAM_ENABLED      = BIT(0),
0295     IEEE802154_LLSEC_PARAM_FRAME_COUNTER    = BIT(1),
0296     IEEE802154_LLSEC_PARAM_OUT_LEVEL    = BIT(2),
0297     IEEE802154_LLSEC_PARAM_OUT_KEY      = BIT(3),
0298     IEEE802154_LLSEC_PARAM_KEY_SOURCE   = BIT(4),
0299     IEEE802154_LLSEC_PARAM_PAN_ID       = BIT(5),
0300     IEEE802154_LLSEC_PARAM_HWADDR       = BIT(6),
0301     IEEE802154_LLSEC_PARAM_COORD_HWADDR = BIT(7),
0302     IEEE802154_LLSEC_PARAM_COORD_SHORTADDR  = BIT(8),
0303 };
0304 
0305 struct ieee802154_llsec_ops {
0306     int (*get_params)(struct net_device *dev,
0307               struct ieee802154_llsec_params *params);
0308     int (*set_params)(struct net_device *dev,
0309               const struct ieee802154_llsec_params *params,
0310               int changed);
0311 
0312     int (*add_key)(struct net_device *dev,
0313                const struct ieee802154_llsec_key_id *id,
0314                const struct ieee802154_llsec_key *key);
0315     int (*del_key)(struct net_device *dev,
0316                const struct ieee802154_llsec_key_id *id);
0317 
0318     int (*add_dev)(struct net_device *dev,
0319                const struct ieee802154_llsec_device *llsec_dev);
0320     int (*del_dev)(struct net_device *dev, __le64 dev_addr);
0321 
0322     int (*add_devkey)(struct net_device *dev,
0323               __le64 device_addr,
0324               const struct ieee802154_llsec_device_key *key);
0325     int (*del_devkey)(struct net_device *dev,
0326               __le64 device_addr,
0327               const struct ieee802154_llsec_device_key *key);
0328 
0329     int (*add_seclevel)(struct net_device *dev,
0330                 const struct ieee802154_llsec_seclevel *sl);
0331     int (*del_seclevel)(struct net_device *dev,
0332                 const struct ieee802154_llsec_seclevel *sl);
0333 
0334     void (*lock_table)(struct net_device *dev);
0335     void (*get_table)(struct net_device *dev,
0336               struct ieee802154_llsec_table **t);
0337     void (*unlock_table)(struct net_device *dev);
0338 };
0339 /*
0340  * This should be located at net_device->ml_priv
0341  *
0342  * get_phy should increment the reference counting on returned phy.
0343  * Use wpan_wpy_put to put that reference.
0344  */
0345 struct ieee802154_mlme_ops {
0346     /* The following fields are optional (can be NULL). */
0347 
0348     int (*assoc_req)(struct net_device *dev,
0349             struct ieee802154_addr *addr,
0350             u8 channel, u8 page, u8 cap);
0351     int (*assoc_resp)(struct net_device *dev,
0352             struct ieee802154_addr *addr,
0353             __le16 short_addr, u8 status);
0354     int (*disassoc_req)(struct net_device *dev,
0355             struct ieee802154_addr *addr,
0356             u8 reason);
0357     int (*start_req)(struct net_device *dev,
0358             struct ieee802154_addr *addr,
0359             u8 channel, u8 page, u8 bcn_ord, u8 sf_ord,
0360             u8 pan_coord, u8 blx, u8 coord_realign);
0361     int (*scan_req)(struct net_device *dev,
0362             u8 type, u32 channels, u8 page, u8 duration);
0363 
0364     int (*set_mac_params)(struct net_device *dev,
0365                   const struct ieee802154_mac_params *params);
0366     void (*get_mac_params)(struct net_device *dev,
0367                    struct ieee802154_mac_params *params);
0368 
0369     const struct ieee802154_llsec_ops *llsec;
0370 };
0371 
0372 static inline struct ieee802154_mlme_ops *
0373 ieee802154_mlme_ops(const struct net_device *dev)
0374 {
0375     return dev->ml_priv;
0376 }
0377 
0378 #endif