aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac802154
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac802154')
-rw-r--r--net/mac802154/mac802154.h3
-rw-r--r--net/mac802154/mac_cmd.c1
-rw-r--r--net/mac802154/mib.c21
-rw-r--r--net/mac802154/tx.c29
-rw-r--r--net/mac802154/wpan.c4
5 files changed, 44 insertions, 14 deletions
diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h
index 703c1210d223..d48422e27110 100644
--- a/net/mac802154/mac802154.h
+++ b/net/mac802154/mac802154.h
@@ -88,8 +88,6 @@ struct mac802154_sub_if_data {
88 88
89#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw) 89#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw)
90 90
91#define MAC802154_MAX_XMIT_ATTEMPTS 3
92
93#define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ 91#define MAC802154_CHAN_NONE 0xff /* No channel is assigned */
94 92
95extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; 93extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced;
@@ -114,5 +112,6 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev);
114u16 mac802154_dev_get_pan_id(const struct net_device *dev); 112u16 mac802154_dev_get_pan_id(const struct net_device *dev);
115void mac802154_dev_set_pan_id(struct net_device *dev, u16 val); 113void mac802154_dev_set_pan_id(struct net_device *dev, u16 val);
116void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); 114void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan);
115u8 mac802154_dev_get_dsn(const struct net_device *dev);
117 116
118#endif /* MAC802154_H */ 117#endif /* MAC802154_H */
diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c
index d8d277006089..a99910d4d52f 100644
--- a/net/mac802154/mac_cmd.c
+++ b/net/mac802154/mac_cmd.c
@@ -73,4 +73,5 @@ struct ieee802154_mlme_ops mac802154_mlme_wpan = {
73 .start_req = mac802154_mlme_start_req, 73 .start_req = mac802154_mlme_start_req,
74 .get_pan_id = mac802154_dev_get_pan_id, 74 .get_pan_id = mac802154_dev_get_pan_id,
75 .get_short_addr = mac802154_dev_get_short_addr, 75 .get_short_addr = mac802154_dev_get_short_addr,
76 .get_dsn = mac802154_dev_get_dsn,
76}; 77};
diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c
index f47781ab0ccc..8ded97cf1c33 100644
--- a/net/mac802154/mib.c
+++ b/net/mac802154/mib.c
@@ -159,6 +159,15 @@ void mac802154_dev_set_pan_id(struct net_device *dev, u16 val)
159 } 159 }
160} 160}
161 161
162u8 mac802154_dev_get_dsn(const struct net_device *dev)
163{
164 struct mac802154_sub_if_data *priv = netdev_priv(dev);
165
166 BUG_ON(dev->type != ARPHRD_IEEE802154);
167
168 return priv->dsn++;
169}
170
162static void phy_chan_notify(struct work_struct *work) 171static void phy_chan_notify(struct work_struct *work)
163{ 172{
164 struct phy_chan_notify_work *nw = container_of(work, 173 struct phy_chan_notify_work *nw = container_of(work,
@@ -167,9 +176,15 @@ static void phy_chan_notify(struct work_struct *work)
167 struct mac802154_sub_if_data *priv = netdev_priv(nw->dev); 176 struct mac802154_sub_if_data *priv = netdev_priv(nw->dev);
168 int res; 177 int res;
169 178
179 mutex_lock(&priv->hw->phy->pib_lock);
170 res = hw->ops->set_channel(&hw->hw, priv->page, priv->chan); 180 res = hw->ops->set_channel(&hw->hw, priv->page, priv->chan);
171 if (res) 181 if (res)
172 pr_debug("set_channel failed\n"); 182 pr_debug("set_channel failed\n");
183 else {
184 priv->hw->phy->current_channel = priv->chan;
185 priv->hw->phy->current_page = priv->page;
186 }
187 mutex_unlock(&priv->hw->phy->pib_lock);
173 188
174 kfree(nw); 189 kfree(nw);
175} 190}
@@ -186,8 +201,11 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan)
186 priv->chan = chan; 201 priv->chan = chan;
187 spin_unlock_bh(&priv->mib_lock); 202 spin_unlock_bh(&priv->mib_lock);
188 203
204 mutex_lock(&priv->hw->phy->pib_lock);
189 if (priv->hw->phy->current_channel != priv->chan || 205 if (priv->hw->phy->current_channel != priv->chan ||
190 priv->hw->phy->current_page != priv->page) { 206 priv->hw->phy->current_page != priv->page) {
207 mutex_unlock(&priv->hw->phy->pib_lock);
208
191 work = kzalloc(sizeof(*work), GFP_ATOMIC); 209 work = kzalloc(sizeof(*work), GFP_ATOMIC);
192 if (!work) 210 if (!work)
193 return; 211 return;
@@ -195,5 +213,6 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan)
195 INIT_WORK(&work->work, phy_chan_notify); 213 INIT_WORK(&work->work, phy_chan_notify);
196 work->dev = dev; 214 work->dev = dev;
197 queue_work(priv->hw->dev_workqueue, &work->work); 215 queue_work(priv->hw->dev_workqueue, &work->work);
198 } 216 } else
217 mutex_unlock(&priv->hw->phy->pib_lock);
199} 218}
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 4e09d070995a..6d1647399d4f 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
@@ -39,12 +40,12 @@ struct xmit_work {
39 struct mac802154_priv *priv; 40 struct mac802154_priv *priv;
40 u8 chan; 41 u8 chan;
41 u8 page; 42 u8 page;
42 u8 xmit_attempts;
43}; 43};
44 44
45static void mac802154_xmit_worker(struct work_struct *work) 45static void mac802154_xmit_worker(struct work_struct *work)
46{ 46{
47 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;
48 int res; 49 int res;
49 50
50 mutex_lock(&xw->priv->phy->pib_lock); 51 mutex_lock(&xw->priv->phy->pib_lock);
@@ -57,21 +58,23 @@ static void mac802154_xmit_worker(struct work_struct *work)
57 pr_debug("set_channel failed\n"); 58 pr_debug("set_channel failed\n");
58 goto out; 59 goto out;
59 } 60 }
61
62 xw->priv->phy->current_channel = xw->chan;
63 xw->priv->phy->current_page = xw->page;
60 } 64 }
61 65
62 res = xw->priv->ops->xmit(&xw->priv->hw, xw->skb); 66 res = xw->priv->ops->xmit(&xw->priv->hw, xw->skb);
67 if (res)
68 pr_debug("transmission failed\n");
63 69
64out: 70out:
65 mutex_unlock(&xw->priv->phy->pib_lock); 71 mutex_unlock(&xw->priv->phy->pib_lock);
66 72
67 if (res) { 73 /* Restart the netif queue on each sub_if_data object. */
68 if (xw->xmit_attempts++ < MAC802154_MAX_XMIT_ATTEMPTS) { 74 rcu_read_lock();
69 queue_work(xw->priv->dev_workqueue, &xw->work); 75 list_for_each_entry_rcu(sdata, &xw->priv->slaves, list)
70 return; 76 netif_wake_queue(sdata->dev);
71 } else 77 rcu_read_unlock();
72 pr_debug("transmission failed for %d times",
73 MAC802154_MAX_XMIT_ATTEMPTS);
74 }
75 78
76 dev_kfree_skb(xw->skb); 79 dev_kfree_skb(xw->skb);
77 80
@@ -82,6 +85,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
82 u8 page, u8 chan) 85 u8 page, u8 chan)
83{ 86{
84 struct xmit_work *work; 87 struct xmit_work *work;
88 struct mac802154_sub_if_data *sdata;
85 89
86 if (!(priv->phy->channels_supported[page] & (1 << chan))) { 90 if (!(priv->phy->channels_supported[page] & (1 << chan))) {
87 WARN_ON(1); 91 WARN_ON(1);
@@ -109,12 +113,17 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
109 return NETDEV_TX_BUSY; 113 return NETDEV_TX_BUSY;
110 } 114 }
111 115
116 /* Stop the netif queue on each sub_if_data object. */
117 rcu_read_lock();
118 list_for_each_entry_rcu(sdata, &priv->slaves, list)
119 netif_stop_queue(sdata->dev);
120 rcu_read_unlock();
121
112 INIT_WORK(&work->work, mac802154_xmit_worker); 122 INIT_WORK(&work->work, mac802154_xmit_worker);
113 work->skb = skb; 123 work->skb = skb;
114 work->priv = priv; 124 work->priv = priv;
115 work->page = page; 125 work->page = page;
116 work->chan = chan; 126 work->chan = chan;
117 work->xmit_attempts = 0;
118 127
119 queue_work(priv->dev_workqueue, &work->work); 128 queue_work(priv->dev_workqueue, &work->work);
120 129
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
index d20c6d3c247d..2ca2f4dceab7 100644
--- a/net/mac802154/wpan.c
+++ b/net/mac802154/wpan.c
@@ -145,6 +145,8 @@ static int mac802154_header_create(struct sk_buff *skb,
145 145
146 head[pos++] = mac_cb(skb)->seq; /* DSN/BSN */ 146 head[pos++] = mac_cb(skb)->seq; /* DSN/BSN */
147 fc = mac_cb_type(skb); 147 fc = mac_cb_type(skb);
148 if (mac_cb_is_ackreq(skb))
149 fc |= IEEE802154_FC_ACK_REQ;
148 150
149 if (!saddr) { 151 if (!saddr) {
150 spin_lock_bh(&priv->mib_lock); 152 spin_lock_bh(&priv->mib_lock);
@@ -358,7 +360,7 @@ void mac802154_wpan_setup(struct net_device *dev)
358 dev->header_ops = &mac802154_header_ops; 360 dev->header_ops = &mac802154_header_ops;
359 dev->needed_tailroom = 2; /* FCS */ 361 dev->needed_tailroom = 2; /* FCS */
360 dev->mtu = IEEE802154_MTU; 362 dev->mtu = IEEE802154_MTU;
361 dev->tx_queue_len = 10; 363 dev->tx_queue_len = 300;
362 dev->type = ARPHRD_IEEE802154; 364 dev->type = ARPHRD_IEEE802154;
363 dev->flags = IFF_NOARP | IFF_BROADCAST; 365 dev->flags = IFF_NOARP | IFF_BROADCAST;
364 dev->watchdog_timeo = 0; 366 dev->watchdog_timeo = 0;