]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - net/mac802154/tx.c
Merge tag 'driver-core-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-hirsute-kernel.git] / net / mac802154 / tx.c
CommitLineData
1802d0be 1// SPDX-License-Identifier: GPL-2.0-only
5b641ebe 2/*
3 * Copyright 2007-2012 Siemens AG
4 *
5b641ebe 5 * Written by:
6 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
7 * Sergey Lapin <slapin@ossfans.org>
8 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
9 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
10 */
11
12#include <linux/netdevice.h>
13#include <linux/if_arp.h>
14#include <linux/crc-ccitt.h>
061ef8f9 15#include <asm/unaligned.h>
5b641ebe 16
6001d522 17#include <net/rtnetlink.h>
b5992fe9 18#include <net/ieee802154_netdev.h>
5b641ebe 19#include <net/mac802154.h>
5ad60d36 20#include <net/cfg802154.h>
5b641ebe 21
0f1556bc 22#include "ieee802154_i.h"
59cb300f 23#include "driver-ops.h"
5b641ebe 24
c22ff7b4 25void ieee802154_xmit_worker(struct work_struct *work)
5b641ebe 26{
c22ff7b4
LB
27 struct ieee802154_local *local =
28 container_of(work, struct ieee802154_local, tx_work);
29 struct sk_buff *skb = local->tx_skb;
409c3b0c 30 struct net_device *dev = skb->dev;
5b641ebe 31 int res;
32
59cb300f 33 res = drv_xmit_sync(local, skb);
6001d522
AA
34 if (res)
35 goto err_tx;
36
409c3b0c
AA
37 dev->stats.tx_packets++;
38 dev->stats.tx_bytes += skb->len;
39
0ff4628f
ED
40 ieee802154_xmit_complete(&local->hw, skb, false);
41
6001d522
AA
42 return;
43
44err_tx:
45 /* Restart the netif queue on each sub_if_data object. */
46 ieee802154_wake_queue(&local->hw);
6001d522 47 kfree_skb(skb);
409c3b0c 48 netdev_dbg(dev, "transmission failed\n");
5b641ebe 49}
50
dc67c6b3 51static netdev_tx_t
e5e584fc 52ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
5b641ebe 53{
409c3b0c 54 struct net_device *dev = skb->dev;
ed0a5dce 55 int ret;
5b641ebe 56
90386a7e 57 if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) {
f9c52831
AA
58 struct sk_buff *nskb;
59 u16 crc;
4710d806 60
f9c52831
AA
61 if (unlikely(skb_tailroom(skb) < IEEE802154_FCS_LEN)) {
62 nskb = skb_copy_expand(skb, 0, IEEE802154_FCS_LEN,
63 GFP_ATOMIC);
64 if (likely(nskb)) {
65 consume_skb(skb);
66 skb = nskb;
67 } else {
68 goto err_tx;
69 }
70 }
71
72 crc = crc_ccitt(0, skb->data, skb->len);
061ef8f9 73 put_unaligned_le16(crc, skb_put(skb, 2));
5b641ebe 74 }
75
b5992fe9 76 /* Stop the netif queue on each sub_if_data object. */
18d60a0d 77 ieee802154_stop_queue(&local->hw);
b5992fe9 78
ed0a5dce
AA
79 /* async is priority, otherwise sync is fallback */
80 if (local->ops->xmit_async) {
0ff4628f
ED
81 unsigned int len = skb->len;
82
59cb300f 83 ret = drv_xmit_async(local, skb);
ed0a5dce
AA
84 if (ret) {
85 ieee802154_wake_queue(&local->hw);
86 goto err_tx;
87 }
409c3b0c
AA
88
89 dev->stats.tx_packets++;
0ff4628f 90 dev->stats.tx_bytes += len;
ed0a5dce 91 } else {
c22ff7b4
LB
92 local->tx_skb = skb;
93 queue_work(local->workqueue, &local->tx_work);
ed0a5dce 94 }
5b641ebe 95
96 return NETDEV_TX_OK;
f5588912
VB
97
98err_tx:
99 kfree_skb(skb);
100 return NETDEV_TX_OK;
5b641ebe 101}
50c6fb99 102
e5e584fc
AA
103netdev_tx_t
104ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev)
50c6fb99
AA
105{
106 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
50c6fb99
AA
107
108 skb->skb_iif = dev->ifindex;
50c6fb99 109
e5e584fc 110 return ieee802154_tx(sdata->local, skb);
50c6fb99
AA
111}
112
e5e584fc
AA
113netdev_tx_t
114ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev)
50c6fb99
AA
115{
116 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
50c6fb99
AA
117 int rc;
118
d58a2fa9
AA
119 /* TODO we should move it to wpan_dev_hard_header and dev_hard_header
120 * functions. The reason is wireshark will show a mac header which is
121 * with security fields but the payload is not encrypted.
122 */
50c6fb99
AA
123 rc = mac802154_llsec_encrypt(&sdata->sec, skb);
124 if (rc) {
cfa626cb 125 netdev_warn(dev, "encryption failed: %i\n", rc);
50c6fb99
AA
126 kfree_skb(skb);
127 return NETDEV_TX_OK;
128 }
129
130 skb->skb_iif = dev->ifindex;
50c6fb99 131
e5e584fc 132 return ieee802154_tx(sdata->local, skb);
50c6fb99 133}