Blame view

net/mac802154/tx.c 3.37 KB
5b641ebee   alex.bluesman.smirnov@gmail.com   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   alex.bluesman.smirnov@gmail.com   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   Alexander Aring   mac802154: tx: us...
23
  #include <asm/unaligned.h>
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
24

6001d5223   Alexander Aring   mac802154: tx: do...
25
  #include <net/rtnetlink.h>
b5992fe96   Alan Ott   mac802154: Use ne...
26
  #include <net/ieee802154_netdev.h>
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
27
  #include <net/mac802154.h>
5ad60d369   Alexander Aring   ieee802154: move ...
28
  #include <net/cfg802154.h>
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
29

0f1556bc2   Alexander Aring   mac802154: move m...
30
  #include "ieee802154_i.h"
59cb300f2   Alexander Aring   mac802154: use dr...
31
  #include "driver-ops.h"
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
32

c22ff7b4e   Lennert Buytenhek   mac802154: Fix me...
33
  void ieee802154_xmit_worker(struct work_struct *work)
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
34
  {
c22ff7b4e   Lennert Buytenhek   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   Alexander Aring   mac802154: tx: mo...
38
  	struct net_device *dev = skb->dev;
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
39
  	int res;
59cb300f2   Alexander Aring   mac802154: use dr...
40
  	res = drv_xmit_sync(local, skb);
6001d5223   Alexander Aring   mac802154: tx: do...
41
42
  	if (res)
  		goto err_tx;
61f2dcba9   Alexander Aring   mac802154: add in...
43
  	ieee802154_xmit_complete(&local->hw, skb, false);
6001d5223   Alexander Aring   mac802154: tx: do...
44

409c3b0c5   Alexander Aring   mac802154: tx: mo...
45
46
  	dev->stats.tx_packets++;
  	dev->stats.tx_bytes += skb->len;
6001d5223   Alexander Aring   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   Alexander Aring   mac802154: tx: do...
52
  	kfree_skb(skb);
409c3b0c5   Alexander Aring   mac802154: tx: mo...
53
54
  	netdev_dbg(dev, "transmission failed
  ");
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
55
  }
dc67c6b30   Alexander Aring   mac802154: tx: re...
56
  static netdev_tx_t
e5e584fcc   Alexander Aring   mac802154: tx: ch...
57
  ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
58
  {
409c3b0c5   Alexander Aring   mac802154: tx: mo...
59
  	struct net_device *dev = skb->dev;
ed0a5dce0   Alexander Aring   mac802154: tx: ad...
60
  	int ret;
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
61

90386a7e3   Alexander Aring   mac802154: separa...
62
  	if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) {
4a2262972   Alexander Aring   net: mac802154: t...
63
64
  		struct sk_buff *nskb;
  		u16 crc;
4710d806f   Varka Bhadram   6lowpan: mac80215...
65

4a2262972   Alexander Aring   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   Alexander Aring   mac802154: tx: us...
78
  		put_unaligned_le16(crc, skb_put(skb, 2));
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
79
  	}
b5992fe96   Alan Ott   mac802154: Use ne...
80
  	/* Stop the netif queue on each sub_if_data object. */
18d60a0d4   Alexander Aring   mac802154: tx: us...
81
  	ieee802154_stop_queue(&local->hw);
b5992fe96   Alan Ott   mac802154: Use ne...
82

ed0a5dce0   Alexander Aring   mac802154: tx: ad...
83
84
  	/* async is priority, otherwise sync is fallback */
  	if (local->ops->xmit_async) {
59cb300f2   Alexander Aring   mac802154: use dr...
85
  		ret = drv_xmit_async(local, skb);
ed0a5dce0   Alexander Aring   mac802154: tx: ad...
86
87
88
89
  		if (ret) {
  			ieee802154_wake_queue(&local->hw);
  			goto err_tx;
  		}
409c3b0c5   Alexander Aring   mac802154: tx: mo...
90
91
92
  
  		dev->stats.tx_packets++;
  		dev->stats.tx_bytes += skb->len;
ed0a5dce0   Alexander Aring   mac802154: tx: ad...
93
  	} else {
c22ff7b4e   Lennert Buytenhek   mac802154: Fix me...
94
95
  		local->tx_skb = skb;
  		queue_work(local->workqueue, &local->tx_work);
ed0a5dce0   Alexander Aring   mac802154: tx: ad...
96
  	}
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
97
98
  
  	return NETDEV_TX_OK;
f55889128   Varka Bhadram   mac802154: common...
99
100
101
102
  
  err_tx:
  	kfree_skb(skb);
  	return NETDEV_TX_OK;
5b641ebee   alex.bluesman.smirnov@gmail.com   mac802154: TX dat...
103
  }
50c6fb996   Alexander Aring   mac802154: tx: mo...
104

e5e584fcc   Alexander Aring   mac802154: tx: ch...
105
106
  netdev_tx_t
  ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev)
50c6fb996   Alexander Aring   mac802154: tx: mo...
107
108
  {
  	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
50c6fb996   Alexander Aring   mac802154: tx: mo...
109
110
  
  	skb->skb_iif = dev->ifindex;
50c6fb996   Alexander Aring   mac802154: tx: mo...
111

e5e584fcc   Alexander Aring   mac802154: tx: ch...
112
  	return ieee802154_tx(sdata->local, skb);
50c6fb996   Alexander Aring   mac802154: tx: mo...
113
  }
e5e584fcc   Alexander Aring   mac802154: tx: ch...
114
115
  netdev_tx_t
  ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev)
50c6fb996   Alexander Aring   mac802154: tx: mo...
116
117
  {
  	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
50c6fb996   Alexander Aring   mac802154: tx: mo...
118
  	int rc;
d58a2fa90   Alexander Aring   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   Alexander Aring   mac802154: tx: mo...
123
124
  	rc = mac802154_llsec_encrypt(&sdata->sec, skb);
  	if (rc) {
cfa626cb3   Alexander Aring   mac802154: tx: us...
125
126
  		netdev_warn(dev, "encryption failed: %i
  ", rc);
50c6fb996   Alexander Aring   mac802154: tx: mo...
127
128
129
130
131
  		kfree_skb(skb);
  		return NETDEV_TX_OK;
  	}
  
  	skb->skb_iif = dev->ifindex;
50c6fb996   Alexander Aring   mac802154: tx: mo...
132

e5e584fcc   Alexander Aring   mac802154: tx: ch...
133
  	return ieee802154_tx(sdata->local, skb);
50c6fb996   Alexander Aring   mac802154: tx: mo...
134
  }