summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/net/af_ieee802154.h4
-rw-r--r--include/net/ieee802154.h28
-rw-r--r--include/net/ieee802154_netdev.h181
-rw-r--r--include/net/mac802154.h6
-rw-r--r--include/net/nl802154.h6
5 files changed, 195 insertions, 30 deletions
diff --git a/include/net/af_ieee802154.h b/include/net/af_ieee802154.h
index 75e64c7a2960..f79ae2aa76d6 100644
--- a/include/net/af_ieee802154.h
+++ b/include/net/af_ieee802154.h
@@ -36,7 +36,7 @@ enum {
/* address length, octets */
#define IEEE802154_ADDR_LEN 8
-struct ieee802154_addr {
+struct ieee802154_addr_sa {
int addr_type;
u16 pan_id;
union {
@@ -51,7 +51,7 @@ struct ieee802154_addr {
struct sockaddr_ieee802154 {
sa_family_t family; /* AF_IEEE802154 */
- struct ieee802154_addr addr;
+ struct ieee802154_addr_sa addr;
};
/* get/setsockopt */
diff --git a/include/net/ieee802154.h b/include/net/ieee802154.h
index ee59f8b188dd..c7ae0ac528dc 100644
--- a/include/net/ieee802154.h
+++ b/include/net/ieee802154.h
@@ -42,22 +42,42 @@
(((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \
} while (0)
-#define IEEE802154_FC_SECEN (1 << 3)
-#define IEEE802154_FC_FRPEND (1 << 4)
-#define IEEE802154_FC_ACK_REQ (1 << 5)
-#define IEEE802154_FC_INTRA_PAN (1 << 6)
+#define IEEE802154_FC_SECEN_SHIFT 3
+#define IEEE802154_FC_SECEN (1 << IEEE802154_FC_SECEN_SHIFT)
+#define IEEE802154_FC_FRPEND_SHIFT 4
+#define IEEE802154_FC_FRPEND (1 << IEEE802154_FC_FRPEND_SHIFT)
+#define IEEE802154_FC_ACK_REQ_SHIFT 5
+#define IEEE802154_FC_ACK_REQ (1 << IEEE802154_FC_ACK_REQ_SHIFT)
+#define IEEE802154_FC_INTRA_PAN_SHIFT 6
+#define IEEE802154_FC_INTRA_PAN (1 << IEEE802154_FC_INTRA_PAN_SHIFT)
#define IEEE802154_FC_SAMODE_SHIFT 14
#define IEEE802154_FC_SAMODE_MASK (3 << IEEE802154_FC_SAMODE_SHIFT)
#define IEEE802154_FC_DAMODE_SHIFT 10
#define IEEE802154_FC_DAMODE_MASK (3 << IEEE802154_FC_DAMODE_SHIFT)
+#define IEEE802154_FC_VERSION_SHIFT 12
+#define IEEE802154_FC_VERSION_MASK (3 << IEEE802154_FC_VERSION_SHIFT)
+#define IEEE802154_FC_VERSION(x) ((x & IEEE802154_FC_VERSION_MASK) >> IEEE802154_FC_VERSION_SHIFT)
+
#define IEEE802154_FC_SAMODE(x) \
(((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT)
#define IEEE802154_FC_DAMODE(x) \
(((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT)
+#define IEEE802154_SCF_SECLEVEL_MASK 7
+#define IEEE802154_SCF_SECLEVEL_SHIFT 0
+#define IEEE802154_SCF_SECLEVEL(x) (x & IEEE802154_SCF_SECLEVEL_MASK)
+#define IEEE802154_SCF_KEY_ID_MODE_SHIFT 3
+#define IEEE802154_SCF_KEY_ID_MODE_MASK (3 << IEEE802154_SCF_KEY_ID_MODE_SHIFT)
+#define IEEE802154_SCF_KEY_ID_MODE(x) \
+ ((x & IEEE802154_SCF_KEY_ID_MODE_MASK) >> IEEE802154_SCF_KEY_ID_MODE_SHIFT)
+
+#define IEEE802154_SCF_KEY_IMPLICIT 0
+#define IEEE802154_SCF_KEY_INDEX 1
+#define IEEE802154_SCF_KEY_SHORT_INDEX 2
+#define IEEE802154_SCF_KEY_HW_INDEX 3
/* MAC footer size */
#define IEEE802154_MFR_SIZE 2 /* 2 octets */
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index 97b2e34d87f7..e1717cbf609b 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -28,24 +28,175 @@
#define IEEE802154_NETDEVICE_H
#include <net/af_ieee802154.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
-struct ieee802154_frag_info {
- __be16 d_tag;
- u16 d_size;
- u8 d_offset;
+struct ieee802154_sechdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 level:3,
+ key_id_mode:2,
+ reserved:3;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 reserved:3,
+ key_id_mode:2,
+ level:3;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ u8 key_id;
+ __le32 frame_counter;
+ union {
+ __le32 short_src;
+ __le64 extended_src;
+ };
+};
+
+struct ieee802154_addr {
+ u8 mode;
+ __le16 pan_id;
+ union {
+ __le16 short_addr;
+ __le64 extended_addr;
+ };
+};
+
+struct ieee802154_hdr_fc {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u16 type:3,
+ security_enabled:1,
+ frame_pending:1,
+ ack_request:1,
+ intra_pan:1,
+ reserved:3,
+ dest_addr_mode:2,
+ version:2,
+ source_addr_mode:2;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u16 reserved:1,
+ intra_pan:1,
+ ack_request:1,
+ frame_pending:1,
+ security_enabled:1,
+ type:3,
+ source_addr_mode:2,
+ version:2,
+ dest_addr_mode:2,
+ reserved2:2;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
};
+struct ieee802154_hdr {
+ struct ieee802154_hdr_fc fc;
+ u8 seq;
+ struct ieee802154_addr source;
+ struct ieee802154_addr dest;
+ struct ieee802154_sechdr sec;
+};
+
+/* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
+ * the contents of hdr will be, and the actual value of those bits in
+ * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
+ * version, if SECEN is set.
+ */
+int ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr);
+
+/* pulls the entire 802.15.4 header off of the skb, including the security
+ * header, and performs pan id decompression
+ */
+int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr);
+
+/* parses the frame control, sequence number of address fields in a given skb
+ * and stores them into hdr, performing pan id decompression and length checks
+ * to be suitable for use in header_ops.parse
+ */
+int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
+ struct ieee802154_hdr *hdr);
+
+static inline int ieee802154_hdr_length(struct sk_buff *skb)
+{
+ struct ieee802154_hdr hdr;
+ int len = ieee802154_hdr_pull(skb, &hdr);
+
+ if (len > 0)
+ skb_push(skb, len);
+
+ return len;
+}
+
+static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1,
+ const struct ieee802154_addr *a2)
+{
+ if (a1->pan_id != a2->pan_id || a1->mode != a2->mode)
+ return false;
+
+ if ((a1->mode == IEEE802154_ADDR_LONG &&
+ a1->extended_addr != a2->extended_addr) ||
+ (a1->mode == IEEE802154_ADDR_SHORT &&
+ a1->short_addr != a2->short_addr))
+ return false;
+
+ return true;
+}
+
+static inline __le64 ieee802154_devaddr_from_raw(const void *raw)
+{
+ u64 temp;
+
+ memcpy(&temp, raw, IEEE802154_ADDR_LEN);
+ return (__force __le64)swab64(temp);
+}
+
+static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr)
+{
+ u64 temp = swab64((__force u64)addr);
+
+ memcpy(raw, &temp, IEEE802154_ADDR_LEN);
+}
+
+static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
+ const struct ieee802154_addr_sa *sa)
+{
+ a->mode = sa->addr_type;
+ a->pan_id = cpu_to_le16(sa->pan_id);
+
+ switch (a->mode) {
+ case IEEE802154_ADDR_SHORT:
+ a->short_addr = cpu_to_le16(sa->short_addr);
+ break;
+ case IEEE802154_ADDR_LONG:
+ a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr);
+ break;
+ }
+}
+
+static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa,
+ const struct ieee802154_addr *a)
+{
+ sa->addr_type = a->mode;
+ sa->pan_id = le16_to_cpu(a->pan_id);
+
+ switch (a->mode) {
+ case IEEE802154_ADDR_SHORT:
+ sa->short_addr = le16_to_cpu(a->short_addr);
+ break;
+ case IEEE802154_ADDR_LONG:
+ ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr);
+ break;
+ }
+}
+
/*
* A control block of skb passed between the ARPHRD_IEEE802154 device
* and other stack parts.
*/
struct ieee802154_mac_cb {
u8 lqi;
- struct ieee802154_addr sa;
- struct ieee802154_addr da;
u8 flags;
u8 seq;
- struct ieee802154_frag_info frag_info;
+ struct ieee802154_addr source;
+ struct ieee802154_addr dest;
};
static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
@@ -57,23 +208,17 @@ static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
#define MAC_CB_FLAG_ACKREQ (1 << 3)
#define MAC_CB_FLAG_SECEN (1 << 4)
-#define MAC_CB_FLAG_INTRAPAN (1 << 5)
-static inline int mac_cb_is_ackreq(struct sk_buff *skb)
+static inline bool mac_cb_is_ackreq(struct sk_buff *skb)
{
return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ;
}
-static inline int mac_cb_is_secen(struct sk_buff *skb)
+static inline bool mac_cb_is_secen(struct sk_buff *skb)
{
return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN;
}
-static inline int mac_cb_is_intrapan(struct sk_buff *skb)
-{
- return mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN;
-}
-
static inline int mac_cb_type(struct sk_buff *skb)
{
return mac_cb(skb)->flags & MAC_CB_FLAG_TYPEMASK;
@@ -99,7 +244,7 @@ struct ieee802154_mlme_ops {
u8 channel, u8 page, u8 cap);
int (*assoc_resp)(struct net_device *dev,
struct ieee802154_addr *addr,
- u16 short_addr, u8 status);
+ __le16 short_addr, u8 status);
int (*disassoc_req)(struct net_device *dev,
struct ieee802154_addr *addr,
u8 reason);
@@ -118,8 +263,8 @@ struct ieee802154_mlme_ops {
* FIXME: these should become the part of PIB/MIB interface.
* However we still don't have IB interface of any kind
*/
- u16 (*get_pan_id)(const struct net_device *dev);
- u16 (*get_short_addr)(const struct net_device *dev);
+ __le16 (*get_pan_id)(const struct net_device *dev);
+ __le16 (*get_short_addr)(const struct net_device *dev);
u8 (*get_dsn)(const struct net_device *dev);
};
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 8ca3d04e7558..a591053cae63 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -20,6 +20,7 @@
#define NET_MAC802154_H
#include <net/af_ieee802154.h>
+#include <linux/skbuff.h>
/* General MAC frame format:
* 2 bytes: Frame Control
@@ -50,7 +51,7 @@ struct ieee802154_hw_addr_filt {
* devices across independent networks.
*/
__le16 short_addr;
- u8 ieee_addr[IEEE802154_ADDR_LEN];
+ __le64 ieee_addr;
u8 pan_coord;
};
@@ -153,8 +154,7 @@ struct ieee802154_ops {
int (*set_hw_addr_filt)(struct ieee802154_dev *dev,
struct ieee802154_hw_addr_filt *filt,
unsigned long changed);
- int (*ieee_addr)(struct ieee802154_dev *dev,
- u8 addr[IEEE802154_ADDR_LEN]);
+ int (*ieee_addr)(struct ieee802154_dev *dev, __le64 addr);
int (*set_txpower)(struct ieee802154_dev *dev, int db);
int (*set_lbt)(struct ieee802154_dev *dev, bool on);
int (*set_cca_mode)(struct ieee802154_dev *dev, u8 mode);
diff --git a/include/net/nl802154.h b/include/net/nl802154.h
index 99d2ba1c7e03..b23548e04098 100644
--- a/include/net/nl802154.h
+++ b/include/net/nl802154.h
@@ -52,7 +52,7 @@ int ieee802154_nl_assoc_indic(struct net_device *dev,
* Note: This is in section 7.3.2 of the IEEE 802.15.4 document.
*/
int ieee802154_nl_assoc_confirm(struct net_device *dev,
- u16 short_addr, u8 status);
+ __le16 short_addr, u8 status);
/**
* ieee802154_nl_disassoc_indic - Notify userland of disassociation.
@@ -111,8 +111,8 @@ int ieee802154_nl_scan_confirm(struct net_device *dev,
* Note: This API cannot indicate a beacon frame for a coordinator
* operating in long addressing mode.
*/
-int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid,
- u16 coord_addr);
+int ieee802154_nl_beacon_indic(struct net_device *dev, __le16 panid,
+ __le16 coord_addr);
/**
* ieee802154_nl_start_confirm - Notify userland of completion of start.