0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/netdevice.h>
0013 #include <linux/if_arp.h>
0014 #include <linux/crc-ccitt.h>
0015 #include <asm/unaligned.h>
0016
0017 #include <net/rtnetlink.h>
0018 #include <net/ieee802154_netdev.h>
0019 #include <net/mac802154.h>
0020 #include <net/cfg802154.h>
0021
0022 #include "ieee802154_i.h"
0023 #include "driver-ops.h"
0024
0025 void ieee802154_xmit_worker(struct work_struct *work)
0026 {
0027 struct ieee802154_local *local =
0028 container_of(work, struct ieee802154_local, tx_work);
0029 struct sk_buff *skb = local->tx_skb;
0030 struct net_device *dev = skb->dev;
0031 int res;
0032
0033 res = drv_xmit_sync(local, skb);
0034 if (res)
0035 goto err_tx;
0036
0037 dev->stats.tx_packets++;
0038 dev->stats.tx_bytes += skb->len;
0039
0040 ieee802154_xmit_complete(&local->hw, skb, false);
0041
0042 return;
0043
0044 err_tx:
0045
0046 ieee802154_wake_queue(&local->hw);
0047 kfree_skb(skb);
0048 netdev_dbg(dev, "transmission failed\n");
0049 }
0050
0051 static netdev_tx_t
0052 ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
0053 {
0054 struct net_device *dev = skb->dev;
0055 int ret;
0056
0057 if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) {
0058 struct sk_buff *nskb;
0059 u16 crc;
0060
0061 if (unlikely(skb_tailroom(skb) < IEEE802154_FCS_LEN)) {
0062 nskb = skb_copy_expand(skb, 0, IEEE802154_FCS_LEN,
0063 GFP_ATOMIC);
0064 if (likely(nskb)) {
0065 consume_skb(skb);
0066 skb = nskb;
0067 } else {
0068 goto err_tx;
0069 }
0070 }
0071
0072 crc = crc_ccitt(0, skb->data, skb->len);
0073 put_unaligned_le16(crc, skb_put(skb, 2));
0074 }
0075
0076
0077 ieee802154_stop_queue(&local->hw);
0078
0079
0080 if (local->ops->xmit_async) {
0081 unsigned int len = skb->len;
0082
0083 ret = drv_xmit_async(local, skb);
0084 if (ret) {
0085 ieee802154_wake_queue(&local->hw);
0086 goto err_tx;
0087 }
0088
0089 dev->stats.tx_packets++;
0090 dev->stats.tx_bytes += len;
0091 } else {
0092 local->tx_skb = skb;
0093 queue_work(local->workqueue, &local->tx_work);
0094 }
0095
0096 return NETDEV_TX_OK;
0097
0098 err_tx:
0099 kfree_skb(skb);
0100 return NETDEV_TX_OK;
0101 }
0102
0103 netdev_tx_t
0104 ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev)
0105 {
0106 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
0107
0108 skb->skb_iif = dev->ifindex;
0109
0110 return ieee802154_tx(sdata->local, skb);
0111 }
0112
0113 netdev_tx_t
0114 ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev)
0115 {
0116 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
0117 int rc;
0118
0119
0120
0121
0122
0123 rc = mac802154_llsec_encrypt(&sdata->sec, skb);
0124 if (rc) {
0125 netdev_warn(dev, "encryption failed: %i\n", rc);
0126 kfree_skb(skb);
0127 return NETDEV_TX_OK;
0128 }
0129
0130 skb->skb_iif = dev->ifindex;
0131
0132 return ieee802154_tx(sdata->local, skb);
0133 }