static int mac802154_header_create(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *_daddr, const void *_saddr, unsigned len) { const struct ieee802154_addr *saddr = _saddr; const struct ieee802154_addr *daddr = _daddr; struct ieee802154_addr dev_addr; struct mac802154_sub_if_data *priv = netdev_priv(dev); int pos = 2; u8 head[MAC802154_FRAME_HARD_HEADER_LEN]; u16 fc; if (!daddr) return -EINVAL; head[pos++] = mac_cb(skb)->seq; /* DSN/BSN */ fc = mac_cb_type(skb); if (mac_cb_is_ackreq(skb)) fc |= IEEE802154_FC_ACK_REQ; if (!saddr) { spin_lock_bh(&priv->mib_lock); if (priv->short_addr == IEEE802154_ADDR_BROADCAST || priv->short_addr == IEEE802154_ADDR_UNDEF || priv->pan_id == IEEE802154_PANID_BROADCAST) { dev_addr.addr_type = IEEE802154_ADDR_LONG; memcpy(dev_addr.hwaddr, dev->dev_addr, IEEE802154_ADDR_LEN); } else { dev_addr.addr_type = IEEE802154_ADDR_SHORT; dev_addr.short_addr = priv->short_addr; } dev_addr.pan_id = priv->pan_id; saddr = &dev_addr; spin_unlock_bh(&priv->mib_lock); } if (daddr->addr_type != IEEE802154_ADDR_NONE) { fc |= (daddr->addr_type << IEEE802154_FC_DAMODE_SHIFT); head[pos++] = daddr->pan_id & 0xff; head[pos++] = daddr->pan_id >> 8; if (daddr->addr_type == IEEE802154_ADDR_SHORT) { head[pos++] = daddr->short_addr & 0xff; head[pos++] = daddr->short_addr >> 8; } else {
static int mac802154_header_create(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *daddr, const void *saddr, unsigned len) { struct ieee802154_hdr hdr; struct mac802154_sub_if_data *priv = netdev_priv(dev); int hlen; if (!daddr) return -EINVAL; memset(&hdr.fc, 0, sizeof(hdr.fc)); hdr.fc.type = mac_cb_type(skb); hdr.fc.security_enabled = mac_cb_is_secen(skb); hdr.fc.ack_request = mac_cb_is_ackreq(skb); if (!saddr) { spin_lock_bh(&priv->mib_lock); if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { hdr.source.mode = IEEE802154_ADDR_LONG; hdr.source.extended_addr = priv->extended_addr; } else { hdr.source.mode = IEEE802154_ADDR_SHORT; hdr.source.short_addr = priv->short_addr; } hdr.source.pan_id = priv->pan_id; spin_unlock_bh(&priv->mib_lock); } else { hdr.source = *(const struct ieee802154_addr *)saddr; } hdr.dest = *(const struct ieee802154_addr *)daddr; hlen = ieee802154_hdr_push(skb, &hdr); if (hlen < 0) return -EINVAL; skb_reset_mac_header(skb); skb->mac_len = hlen; if (hlen + len + 2 > dev->mtu) return -EMSGSIZE; return hlen; }