1/* 2 * Copyright 2007-2012 Siemens AG 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 6 * as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * Written by: 14 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 15 * Sergey Lapin <slapin@ossfans.org> 16 * Maxim Gorbachyov <maxim.gorbachev@siemens.com> 17 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> 18 */ 19 20#include <linux/netdevice.h> 21#include <linux/if_arp.h> 22#include <linux/crc-ccitt.h> 23#include <asm/unaligned.h> 24 25#include <net/rtnetlink.h> 26#include <net/ieee802154_netdev.h> 27#include <net/mac802154.h> 28#include <net/cfg802154.h> 29 30#include "ieee802154_i.h" 31#include "driver-ops.h" 32 33/* IEEE 802.15.4 transceivers can sleep during the xmit session, so process 34 * packets through the workqueue. 35 */ 36struct ieee802154_xmit_cb { 37 struct sk_buff *skb; 38 struct work_struct work; 39 struct ieee802154_local *local; 40}; 41 42static struct ieee802154_xmit_cb ieee802154_xmit_cb; 43 44static void ieee802154_xmit_worker(struct work_struct *work) 45{ 46 struct ieee802154_xmit_cb *cb = 47 container_of(work, struct ieee802154_xmit_cb, work); 48 struct ieee802154_local *local = cb->local; 49 struct sk_buff *skb = cb->skb; 50 struct net_device *dev = skb->dev; 51 int res; 52 53 rtnl_lock(); 54 55 /* check if ifdown occurred while schedule */ 56 if (!netif_running(dev)) 57 goto err_tx; 58 59 res = drv_xmit_sync(local, skb); 60 if (res) 61 goto err_tx; 62 63 ieee802154_xmit_complete(&local->hw, skb, false); 64 65 dev->stats.tx_packets++; 66 dev->stats.tx_bytes += skb->len; 67 68 rtnl_unlock(); 69 70 return; 71 72err_tx: 73 /* Restart the netif queue on each sub_if_data object. */ 74 ieee802154_wake_queue(&local->hw); 75 rtnl_unlock(); 76 kfree_skb(skb); 77 netdev_dbg(dev, "transmission failed\n"); 78} 79 80static netdev_tx_t 81ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) 82{ 83 struct net_device *dev = skb->dev; 84 int ret; 85 86 if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) { 87 u16 crc = crc_ccitt(0, skb->data, skb->len); 88 89 put_unaligned_le16(crc, skb_put(skb, 2)); 90 } 91 92 if (skb_cow_head(skb, local->hw.extra_tx_headroom)) 93 goto err_tx; 94 95 /* Stop the netif queue on each sub_if_data object. */ 96 ieee802154_stop_queue(&local->hw); 97 98 /* async is priority, otherwise sync is fallback */ 99 if (local->ops->xmit_async) { 100 ret = drv_xmit_async(local, skb); 101 if (ret) { 102 ieee802154_wake_queue(&local->hw); 103 goto err_tx; 104 } 105 106 dev->stats.tx_packets++; 107 dev->stats.tx_bytes += skb->len; 108 } else { 109 INIT_WORK(&ieee802154_xmit_cb.work, ieee802154_xmit_worker); 110 ieee802154_xmit_cb.skb = skb; 111 ieee802154_xmit_cb.local = local; 112 113 queue_work(local->workqueue, &ieee802154_xmit_cb.work); 114 } 115 116 return NETDEV_TX_OK; 117 118err_tx: 119 kfree_skb(skb); 120 return NETDEV_TX_OK; 121} 122 123netdev_tx_t 124ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev) 125{ 126 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 127 128 skb->skb_iif = dev->ifindex; 129 130 return ieee802154_tx(sdata->local, skb); 131} 132 133netdev_tx_t 134ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev) 135{ 136 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 137 int rc; 138 139 rc = mac802154_llsec_encrypt(&sdata->sec, skb); 140 if (rc) { 141 netdev_warn(dev, "encryption failed: %i\n", rc); 142 kfree_skb(skb); 143 return NETDEV_TX_OK; 144 } 145 146 skb->skb_iif = dev->ifindex; 147 148 return ieee802154_tx(sdata->local, skb); 149} 150