aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Ott <alan@signal11.us>2013-04-03 00:00:56 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-07 17:06:43 -0400
commitb5992fe962b0c91880229ec31166517e4db2977b (patch)
tree7672154a4e1237d58c2e81c6674894d6410ddc91
parent7dd43d356e739ea0fbeb832722fec36ba4e47540 (diff)
mac802154: Use netif flow control
Use netif_stop_queue() and netif_wake_queue() to control the flow of packets to mac802154 devices. Since many IEEE 802.15.4 devices have no output buffer, and since the mac802154 xmit() function is designed to block, netif_stop_queue() is called after each packet. Signed-off-by: Alan Ott <alan@signal11.us> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/mac802154/tx.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 726487493e5c..3fd3e07ec599 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -25,6 +25,7 @@
25#include <linux/if_arp.h> 25#include <linux/if_arp.h>
26#include <linux/crc-ccitt.h> 26#include <linux/crc-ccitt.h>
27 27
28#include <net/ieee802154_netdev.h>
28#include <net/mac802154.h> 29#include <net/mac802154.h>
29#include <net/wpan-phy.h> 30#include <net/wpan-phy.h>
30 31
@@ -44,6 +45,7 @@ struct xmit_work {
44static void mac802154_xmit_worker(struct work_struct *work) 45static void mac802154_xmit_worker(struct work_struct *work)
45{ 46{
46 struct xmit_work *xw = container_of(work, struct xmit_work, work); 47 struct xmit_work *xw = container_of(work, struct xmit_work, work);
48 struct mac802154_sub_if_data *sdata;
47 int res; 49 int res;
48 50
49 mutex_lock(&xw->priv->phy->pib_lock); 51 mutex_lock(&xw->priv->phy->pib_lock);
@@ -65,6 +67,11 @@ static void mac802154_xmit_worker(struct work_struct *work)
65out: 67out:
66 mutex_unlock(&xw->priv->phy->pib_lock); 68 mutex_unlock(&xw->priv->phy->pib_lock);
67 69
70 /* Restart the netif queue on each sub_if_data object. */
71 rcu_read_lock();
72 list_for_each_entry_rcu(sdata, &xw->priv->slaves, list)
73 netif_wake_queue(sdata->dev);
74 rcu_read_unlock();
68 75
69 dev_kfree_skb(xw->skb); 76 dev_kfree_skb(xw->skb);
70 77
@@ -75,6 +82,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
75 u8 page, u8 chan) 82 u8 page, u8 chan)
76{ 83{
77 struct xmit_work *work; 84 struct xmit_work *work;
85 struct mac802154_sub_if_data *sdata;
78 86
79 if (!(priv->phy->channels_supported[page] & (1 << chan))) { 87 if (!(priv->phy->channels_supported[page] & (1 << chan))) {
80 WARN_ON(1); 88 WARN_ON(1);
@@ -102,6 +110,12 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
102 return NETDEV_TX_BUSY; 110 return NETDEV_TX_BUSY;
103 } 111 }
104 112
113 /* Stop the netif queue on each sub_if_data object. */
114 rcu_read_lock();
115 list_for_each_entry_rcu(sdata, &priv->slaves, list)
116 netif_stop_queue(sdata->dev);
117 rcu_read_unlock();
118
105 INIT_WORK(&work->work, mac802154_xmit_worker); 119 INIT_WORK(&work->work, mac802154_xmit_worker);
106 work->skb = skb; 120 work->skb = skb;
107 work->priv = priv; 121 work->priv = priv;