diff options
Diffstat (limited to 'net/mac802154')
-rw-r--r-- | net/mac802154/mac802154.h | 3 | ||||
-rw-r--r-- | net/mac802154/mac_cmd.c | 1 | ||||
-rw-r--r-- | net/mac802154/mib.c | 21 | ||||
-rw-r--r-- | net/mac802154/tx.c | 29 | ||||
-rw-r--r-- | net/mac802154/wpan.c | 4 |
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 | ||
95 | extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; | 93 | extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; |
@@ -114,5 +112,6 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev); | |||
114 | u16 mac802154_dev_get_pan_id(const struct net_device *dev); | 112 | u16 mac802154_dev_get_pan_id(const struct net_device *dev); |
115 | void mac802154_dev_set_pan_id(struct net_device *dev, u16 val); | 113 | void mac802154_dev_set_pan_id(struct net_device *dev, u16 val); |
116 | void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); | 114 | void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); |
115 | u8 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 | ||
162 | u8 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 | |||
162 | static void phy_chan_notify(struct work_struct *work) | 171 | static 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 | ||
45 | static void mac802154_xmit_worker(struct work_struct *work) | 45 | static 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 | ||
64 | out: | 70 | out: |
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; |