Blame view
net/mac802154/tx.c
3.01 KB
1802d0bee treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
5b641ebee mac802154: TX dat... |
2 3 4 |
/* * Copyright 2007-2012 Siemens AG * |
5b641ebee mac802154: TX dat... |
5 6 7 8 9 10 11 12 13 14 |
* Written by: * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> * Sergey Lapin <slapin@ossfans.org> * Maxim Gorbachyov <maxim.gorbachev@siemens.com> * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> */ #include <linux/netdevice.h> #include <linux/if_arp.h> #include <linux/crc-ccitt.h> |
061ef8f91 mac802154: tx: us... |
15 |
#include <asm/unaligned.h> |
5b641ebee mac802154: TX dat... |
16 |
|
6001d5223 mac802154: tx: do... |
17 |
#include <net/rtnetlink.h> |
b5992fe96 mac802154: Use ne... |
18 |
#include <net/ieee802154_netdev.h> |
5b641ebee mac802154: TX dat... |
19 |
#include <net/mac802154.h> |
5ad60d369 ieee802154: move ... |
20 |
#include <net/cfg802154.h> |
5b641ebee mac802154: TX dat... |
21 |
|
0f1556bc2 mac802154: move m... |
22 |
#include "ieee802154_i.h" |
59cb300f2 mac802154: use dr... |
23 |
#include "driver-ops.h" |
5b641ebee mac802154: TX dat... |
24 |
|
c22ff7b4e mac802154: Fix me... |
25 |
void ieee802154_xmit_worker(struct work_struct *work) |
5b641ebee mac802154: TX dat... |
26 |
{ |
c22ff7b4e mac802154: Fix me... |
27 28 29 |
struct ieee802154_local *local = container_of(work, struct ieee802154_local, tx_work); struct sk_buff *skb = local->tx_skb; |
409c3b0c5 mac802154: tx: mo... |
30 |
struct net_device *dev = skb->dev; |
5b641ebee mac802154: TX dat... |
31 |
int res; |
59cb300f2 mac802154: use dr... |
32 |
res = drv_xmit_sync(local, skb); |
6001d5223 mac802154: tx: do... |
33 34 |
if (res) goto err_tx; |
409c3b0c5 mac802154: tx: mo... |
35 36 |
dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; |
0ff4628f4 mac802154: tx: fi... |
37 |
ieee802154_xmit_complete(&local->hw, skb, false); |
6001d5223 mac802154: tx: do... |
38 39 40 41 42 |
return; err_tx: /* Restart the netif queue on each sub_if_data object. */ ieee802154_wake_queue(&local->hw); |
6001d5223 mac802154: tx: do... |
43 |
kfree_skb(skb); |
409c3b0c5 mac802154: tx: mo... |
44 45 |
netdev_dbg(dev, "transmission failed "); |
5b641ebee mac802154: TX dat... |
46 |
} |
dc67c6b30 mac802154: tx: re... |
47 |
static netdev_tx_t |
e5e584fcc mac802154: tx: ch... |
48 |
ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) |
5b641ebee mac802154: TX dat... |
49 |
{ |
409c3b0c5 mac802154: tx: mo... |
50 |
struct net_device *dev = skb->dev; |
ed0a5dce0 mac802154: tx: ad... |
51 |
int ret; |
5b641ebee mac802154: TX dat... |
52 |
|
90386a7e3 mac802154: separa... |
53 |
if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) { |
f9c528311 net: mac802154: t... |
54 55 |
struct sk_buff *nskb; u16 crc; |
4710d806f 6lowpan: mac80215... |
56 |
|
f9c528311 net: mac802154: t... |
57 58 59 60 61 62 63 64 65 66 67 68 |
if (unlikely(skb_tailroom(skb) < IEEE802154_FCS_LEN)) { nskb = skb_copy_expand(skb, 0, IEEE802154_FCS_LEN, GFP_ATOMIC); if (likely(nskb)) { consume_skb(skb); skb = nskb; } else { goto err_tx; } } crc = crc_ccitt(0, skb->data, skb->len); |
061ef8f91 mac802154: tx: us... |
69 |
put_unaligned_le16(crc, skb_put(skb, 2)); |
5b641ebee mac802154: TX dat... |
70 |
} |
b5992fe96 mac802154: Use ne... |
71 |
/* Stop the netif queue on each sub_if_data object. */ |
18d60a0d4 mac802154: tx: us... |
72 |
ieee802154_stop_queue(&local->hw); |
b5992fe96 mac802154: Use ne... |
73 |
|
ed0a5dce0 mac802154: tx: ad... |
74 75 |
/* async is priority, otherwise sync is fallback */ if (local->ops->xmit_async) { |
0ff4628f4 mac802154: tx: fi... |
76 |
unsigned int len = skb->len; |
59cb300f2 mac802154: use dr... |
77 |
ret = drv_xmit_async(local, skb); |
ed0a5dce0 mac802154: tx: ad... |
78 79 80 81 |
if (ret) { ieee802154_wake_queue(&local->hw); goto err_tx; } |
409c3b0c5 mac802154: tx: mo... |
82 83 |
dev->stats.tx_packets++; |
0ff4628f4 mac802154: tx: fi... |
84 |
dev->stats.tx_bytes += len; |
ed0a5dce0 mac802154: tx: ad... |
85 |
} else { |
c22ff7b4e mac802154: Fix me... |
86 87 |
local->tx_skb = skb; queue_work(local->workqueue, &local->tx_work); |
ed0a5dce0 mac802154: tx: ad... |
88 |
} |
5b641ebee mac802154: TX dat... |
89 90 |
return NETDEV_TX_OK; |
f55889128 mac802154: common... |
91 92 93 94 |
err_tx: kfree_skb(skb); return NETDEV_TX_OK; |
5b641ebee mac802154: TX dat... |
95 |
} |
50c6fb996 mac802154: tx: mo... |
96 |
|
e5e584fcc mac802154: tx: ch... |
97 98 |
netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev) |
50c6fb996 mac802154: tx: mo... |
99 100 |
{ struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); |
50c6fb996 mac802154: tx: mo... |
101 102 |
skb->skb_iif = dev->ifindex; |
50c6fb996 mac802154: tx: mo... |
103 |
|
e5e584fcc mac802154: tx: ch... |
104 |
return ieee802154_tx(sdata->local, skb); |
50c6fb996 mac802154: tx: mo... |
105 |
} |
e5e584fcc mac802154: tx: ch... |
106 107 |
netdev_tx_t ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev) |
50c6fb996 mac802154: tx: mo... |
108 109 |
{ struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); |
50c6fb996 mac802154: tx: mo... |
110 |
int rc; |
d58a2fa90 mac802154: add co... |
111 112 113 114 |
/* TODO we should move it to wpan_dev_hard_header and dev_hard_header * functions. The reason is wireshark will show a mac header which is * with security fields but the payload is not encrypted. */ |
50c6fb996 mac802154: tx: mo... |
115 116 |
rc = mac802154_llsec_encrypt(&sdata->sec, skb); if (rc) { |
cfa626cb3 mac802154: tx: us... |
117 118 |
netdev_warn(dev, "encryption failed: %i ", rc); |
50c6fb996 mac802154: tx: mo... |
119 120 121 122 123 |
kfree_skb(skb); return NETDEV_TX_OK; } skb->skb_iif = dev->ifindex; |
50c6fb996 mac802154: tx: mo... |
124 |
|
e5e584fcc mac802154: tx: ch... |
125 |
return ieee802154_tx(sdata->local, skb); |
50c6fb996 mac802154: tx: mo... |
126 |
} |