diff options
author | Alan Ott <alan@signal11.us> | 2013-04-03 00:00:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-07 17:06:43 -0400 |
commit | b5992fe962b0c91880229ec31166517e4db2977b (patch) | |
tree | 7672154a4e1237d58c2e81c6674894d6410ddc91 | |
parent | 7dd43d356e739ea0fbeb832722fec36ba4e47540 (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.c | 14 |
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 { | |||
44 | static void mac802154_xmit_worker(struct work_struct *work) | 45 | static 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) | |||
65 | out: | 67 | out: |
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; |