Blame view
net/mac802154/tx.c
3.37 KB
5b641ebee mac802154: TX dat... |
1 2 3 4 5 6 7 8 9 10 11 12 |
/* * Copyright 2007-2012 Siemens AG * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * |
5b641ebee mac802154: TX dat... |
13 14 15 16 17 18 19 20 21 22 |
* 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... |
23 |
#include <asm/unaligned.h> |
5b641ebee mac802154: TX dat... |
24 |
|
6001d5223 mac802154: tx: do... |
25 |
#include <net/rtnetlink.h> |
b5992fe96 mac802154: Use ne... |
26 |
#include <net/ieee802154_netdev.h> |
5b641ebee mac802154: TX dat... |
27 |
#include <net/mac802154.h> |
5ad60d369 ieee802154: move ... |
28 |
#include <net/cfg802154.h> |
5b641ebee mac802154: TX dat... |
29 |
|
0f1556bc2 mac802154: move m... |
30 |
#include "ieee802154_i.h" |
59cb300f2 mac802154: use dr... |
31 |
#include "driver-ops.h" |
5b641ebee mac802154: TX dat... |
32 |
|
c22ff7b4e mac802154: Fix me... |
33 |
void ieee802154_xmit_worker(struct work_struct *work) |
5b641ebee mac802154: TX dat... |
34 |
{ |
c22ff7b4e mac802154: Fix me... |
35 36 37 |
struct ieee802154_local *local = container_of(work, struct ieee802154_local, tx_work); struct sk_buff *skb = local->tx_skb; |
409c3b0c5 mac802154: tx: mo... |
38 |
struct net_device *dev = skb->dev; |
5b641ebee mac802154: TX dat... |
39 |
int res; |
59cb300f2 mac802154: use dr... |
40 |
res = drv_xmit_sync(local, skb); |
6001d5223 mac802154: tx: do... |
41 42 |
if (res) goto err_tx; |
61f2dcba9 mac802154: add in... |
43 |
ieee802154_xmit_complete(&local->hw, skb, false); |
6001d5223 mac802154: tx: do... |
44 |
|
409c3b0c5 mac802154: tx: mo... |
45 46 |
dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; |
6001d5223 mac802154: tx: do... |
47 48 49 50 51 |
return; err_tx: /* Restart the netif queue on each sub_if_data object. */ ieee802154_wake_queue(&local->hw); |
6001d5223 mac802154: tx: do... |
52 |
kfree_skb(skb); |
409c3b0c5 mac802154: tx: mo... |
53 54 |
netdev_dbg(dev, "transmission failed "); |
5b641ebee mac802154: TX dat... |
55 |
} |
dc67c6b30 mac802154: tx: re... |
56 |
static netdev_tx_t |
e5e584fcc mac802154: tx: ch... |
57 |
ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) |
5b641ebee mac802154: TX dat... |
58 |
{ |
409c3b0c5 mac802154: tx: mo... |
59 |
struct net_device *dev = skb->dev; |
ed0a5dce0 mac802154: tx: ad... |
60 |
int ret; |
5b641ebee mac802154: TX dat... |
61 |
|
90386a7e3 mac802154: separa... |
62 |
if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) { |
4a2262972 net: mac802154: t... |
63 64 |
struct sk_buff *nskb; u16 crc; |
4710d806f 6lowpan: mac80215... |
65 |
|
4a2262972 net: mac802154: t... |
66 67 68 69 70 71 72 73 74 75 76 77 |
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... |
78 |
put_unaligned_le16(crc, skb_put(skb, 2)); |
5b641ebee mac802154: TX dat... |
79 |
} |
b5992fe96 mac802154: Use ne... |
80 |
/* Stop the netif queue on each sub_if_data object. */ |
18d60a0d4 mac802154: tx: us... |
81 |
ieee802154_stop_queue(&local->hw); |
b5992fe96 mac802154: Use ne... |
82 |
|
ed0a5dce0 mac802154: tx: ad... |
83 84 |
/* async is priority, otherwise sync is fallback */ if (local->ops->xmit_async) { |
59cb300f2 mac802154: use dr... |
85 |
ret = drv_xmit_async(local, skb); |
ed0a5dce0 mac802154: tx: ad... |
86 87 88 89 |
if (ret) { ieee802154_wake_queue(&local->hw); goto err_tx; } |
409c3b0c5 mac802154: tx: mo... |
90 91 92 |
dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; |
ed0a5dce0 mac802154: tx: ad... |
93 |
} else { |
c22ff7b4e mac802154: Fix me... |
94 95 |
local->tx_skb = skb; queue_work(local->workqueue, &local->tx_work); |
ed0a5dce0 mac802154: tx: ad... |
96 |
} |
5b641ebee mac802154: TX dat... |
97 98 |
return NETDEV_TX_OK; |
f55889128 mac802154: common... |
99 100 101 102 |
err_tx: kfree_skb(skb); return NETDEV_TX_OK; |
5b641ebee mac802154: TX dat... |
103 |
} |
50c6fb996 mac802154: tx: mo... |
104 |
|
e5e584fcc mac802154: tx: ch... |
105 106 |
netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev) |
50c6fb996 mac802154: tx: mo... |
107 108 |
{ struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); |
50c6fb996 mac802154: tx: mo... |
109 110 |
skb->skb_iif = dev->ifindex; |
50c6fb996 mac802154: tx: mo... |
111 |
|
e5e584fcc mac802154: tx: ch... |
112 |
return ieee802154_tx(sdata->local, skb); |
50c6fb996 mac802154: tx: mo... |
113 |
} |
e5e584fcc mac802154: tx: ch... |
114 115 |
netdev_tx_t ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev) |
50c6fb996 mac802154: tx: mo... |
116 117 |
{ struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); |
50c6fb996 mac802154: tx: mo... |
118 |
int rc; |
d58a2fa90 mac802154: add co... |
119 120 121 122 |
/* 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... |
123 124 |
rc = mac802154_llsec_encrypt(&sdata->sec, skb); if (rc) { |
cfa626cb3 mac802154: tx: us... |
125 126 |
netdev_warn(dev, "encryption failed: %i ", rc); |
50c6fb996 mac802154: tx: mo... |
127 128 129 130 131 |
kfree_skb(skb); return NETDEV_TX_OK; } skb->skb_iif = dev->ifindex; |
50c6fb996 mac802154: tx: mo... |
132 |
|
e5e584fcc mac802154: tx: ch... |
133 |
return ieee802154_tx(sdata->local, skb); |
50c6fb996 mac802154: tx: mo... |
134 |
} |