summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ieee802154/at86rf230.c2
-rw-r--r--include/linux/ieee802154.h3
-rw-r--r--include/net/cfg802154.h8
-rw-r--r--include/net/mac802154.h3
-rw-r--r--net/mac802154/ieee802154_i.h4
-rw-r--r--net/mac802154/iface.c2
-rw-r--r--net/mac802154/main.c17
-rw-r--r--net/mac802154/tx.c2
-rw-r--r--net/mac802154/util.c32
9 files changed, 67 insertions, 6 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 31d62f9c6ce8..46e50295710a 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -731,7 +731,7 @@ at86rf230_tx_complete(void *context)
731 udelay(lp->data->t_sifs); 731 udelay(lp->data->t_sifs);
732 } 732 }
733 733
734 ieee802154_xmit_complete(lp->hw, skb); 734 ieee802154_xmit_complete(lp->hw, skb, false);
735} 735}
736 736
737static void 737static void
diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
index ce0f96a55976..5a40c0418438 100644
--- a/include/linux/ieee802154.h
+++ b/include/linux/ieee802154.h
@@ -36,6 +36,9 @@
36 36
37#define IEEE802154_EXTENDED_ADDR_LEN 8 37#define IEEE802154_EXTENDED_ADDR_LEN 8
38 38
39#define IEEE802154_LIFS_PERIOD 40
40#define IEEE802154_SIFS_PERIOD 12
41
39#define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ 42#define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */
40#define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ 43#define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */
41#define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ 44#define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index fa0a9e519523..17b4fc0705b2 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -81,6 +81,14 @@ struct wpan_phy {
81 81
82 s32 cca_ed_level; 82 s32 cca_ed_level;
83 83
84 /* PHY depended MAC PIB values */
85
86 /* 802.15.4 acronym: Tdsym in usec */
87 u8 symbol_duration;
88 /* lifs and sifs periods timing */
89 u16 lifs_period;
90 u16 sifs_period;
91
84 struct device dev; 92 struct device dev;
85 93
86 char priv[0] __aligned(NETDEV_ALIGN); 94 char priv[0] __aligned(NETDEV_ALIGN);
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 632f6566adb5..c823d910b46c 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -260,6 +260,7 @@ void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb,
260 260
261void ieee802154_wake_queue(struct ieee802154_hw *hw); 261void ieee802154_wake_queue(struct ieee802154_hw *hw);
262void ieee802154_stop_queue(struct ieee802154_hw *hw); 262void ieee802154_stop_queue(struct ieee802154_hw *hw);
263void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb); 263void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
264 bool ifs_handling);
264 265
265#endif /* NET_MAC802154_H */ 266#endif /* NET_MAC802154_H */
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 69cb585e162f..c5b231047b60 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -20,6 +20,7 @@
20#define __IEEE802154_I_H 20#define __IEEE802154_I_H
21 21
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/hrtimer.h>
23#include <net/cfg802154.h> 24#include <net/cfg802154.h>
24#include <net/mac802154.h> 25#include <net/mac802154.h>
25#include <net/ieee802154_netdev.h> 26#include <net/ieee802154_netdev.h>
@@ -51,6 +52,8 @@ struct ieee802154_local {
51 */ 52 */
52 struct workqueue_struct *workqueue; 53 struct workqueue_struct *workqueue;
53 54
55 struct hrtimer ifs_timer;
56
54 bool started; 57 bool started;
55 58
56 struct tasklet_struct tasklet; 59 struct tasklet_struct tasklet;
@@ -127,6 +130,7 @@ ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
127void mac802154_wpan_setup(struct net_device *dev); 130void mac802154_wpan_setup(struct net_device *dev);
128netdev_tx_t 131netdev_tx_t
129ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); 132ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
133enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer);
130 134
131/* MIB callbacks */ 135/* MIB callbacks */
132void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); 136void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val);
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index ec92b48d1b0b..feb064715d1f 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -246,6 +246,8 @@ static int mac802154_slave_close(struct net_device *dev)
246 246
247 ASSERT_RTNL(); 247 ASSERT_RTNL();
248 248
249 hrtimer_cancel(&local->ifs_timer);
250
249 netif_stop_queue(dev); 251 netif_stop_queue(dev);
250 local->open_count--; 252 local->open_count--;
251 253
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index 46c76e005446..0af1be64e8ad 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -125,6 +125,18 @@ void ieee802154_free_hw(struct ieee802154_hw *hw)
125} 125}
126EXPORT_SYMBOL(ieee802154_free_hw); 126EXPORT_SYMBOL(ieee802154_free_hw);
127 127
128static void ieee802154_setup_wpan_phy_pib(struct wpan_phy *wpan_phy)
129{
130 /* TODO warn on empty symbol_duration
131 * Should be done when all drivers sets this value.
132 */
133
134 wpan_phy->lifs_period = IEEE802154_LIFS_PERIOD *
135 wpan_phy->symbol_duration;
136 wpan_phy->sifs_period = IEEE802154_SIFS_PERIOD *
137 wpan_phy->symbol_duration;
138}
139
128int ieee802154_register_hw(struct ieee802154_hw *hw) 140int ieee802154_register_hw(struct ieee802154_hw *hw)
129{ 141{
130 struct ieee802154_local *local = hw_to_local(hw); 142 struct ieee802154_local *local = hw_to_local(hw);
@@ -138,8 +150,13 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
138 goto out; 150 goto out;
139 } 151 }
140 152
153 hrtimer_init(&local->ifs_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
154 local->ifs_timer.function = ieee802154_xmit_ifs_timer;
155
141 wpan_phy_set_dev(local->phy, local->hw.parent); 156 wpan_phy_set_dev(local->phy, local->hw.parent);
142 157
158 ieee802154_setup_wpan_phy_pib(local->phy);
159
143 rc = wpan_phy_register(local->phy); 160 rc = wpan_phy_register(local->phy);
144 if (rc < 0) 161 if (rc < 0)
145 goto out_wq; 162 goto out_wq;
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index cc37b77f2632..c62e95695c78 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -60,7 +60,7 @@ static void ieee802154_xmit_worker(struct work_struct *work)
60 if (res) 60 if (res)
61 goto err_tx; 61 goto err_tx;
62 62
63 ieee802154_xmit_complete(&local->hw, skb); 63 ieee802154_xmit_complete(&local->hw, skb, false);
64 64
65 dev->stats.tx_packets++; 65 dev->stats.tx_packets++;
66 dev->stats.tx_bytes += skb->len; 66 dev->stats.tx_bytes += skb->len;
diff --git a/net/mac802154/util.c b/net/mac802154/util.c
index 9a04e4a8e50f..5fc979027919 100644
--- a/net/mac802154/util.c
+++ b/net/mac802154/util.c
@@ -50,9 +50,35 @@ void ieee802154_stop_queue(struct ieee802154_hw *hw)
50} 50}
51EXPORT_SYMBOL(ieee802154_stop_queue); 51EXPORT_SYMBOL(ieee802154_stop_queue);
52 52
53void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb) 53enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer)
54{ 54{
55 ieee802154_wake_queue(hw); 55 struct ieee802154_local *local =
56 consume_skb(skb); 56 container_of(timer, struct ieee802154_local, ifs_timer);
57
58 ieee802154_wake_queue(&local->hw);
59
60 return HRTIMER_NORESTART;
61}
62
63void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
64 bool ifs_handling)
65{
66 if (ifs_handling) {
67 struct ieee802154_local *local = hw_to_local(hw);
68
69 if (skb->len > 18)
70 hrtimer_start(&local->ifs_timer,
71 ktime_set(0, hw->phy->lifs_period * NSEC_PER_USEC),
72 HRTIMER_MODE_REL);
73 else
74 hrtimer_start(&local->ifs_timer,
75 ktime_set(0, hw->phy->sifs_period * NSEC_PER_USEC),
76 HRTIMER_MODE_REL);
77
78 consume_skb(skb);
79 } else {
80 ieee802154_wake_queue(hw);
81 consume_skb(skb);
82 }
57} 83}
58EXPORT_SYMBOL(ieee802154_xmit_complete); 84EXPORT_SYMBOL(ieee802154_xmit_complete);