diff options
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 2 | ||||
-rw-r--r-- | include/linux/ieee802154.h | 3 | ||||
-rw-r--r-- | include/net/cfg802154.h | 8 | ||||
-rw-r--r-- | include/net/mac802154.h | 3 | ||||
-rw-r--r-- | net/mac802154/ieee802154_i.h | 4 | ||||
-rw-r--r-- | net/mac802154/iface.c | 2 | ||||
-rw-r--r-- | net/mac802154/main.c | 17 | ||||
-rw-r--r-- | net/mac802154/tx.c | 2 | ||||
-rw-r--r-- | net/mac802154/util.c | 32 |
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 | ||
737 | static void | 737 | static 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 | ||
261 | void ieee802154_wake_queue(struct ieee802154_hw *hw); | 261 | void ieee802154_wake_queue(struct ieee802154_hw *hw); |
262 | void ieee802154_stop_queue(struct ieee802154_hw *hw); | 262 | void ieee802154_stop_queue(struct ieee802154_hw *hw); |
263 | void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb); | 263 | void 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); | |||
127 | void mac802154_wpan_setup(struct net_device *dev); | 130 | void mac802154_wpan_setup(struct net_device *dev); |
128 | netdev_tx_t | 131 | netdev_tx_t |
129 | ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); | 132 | ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); |
133 | enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer); | ||
130 | 134 | ||
131 | /* MIB callbacks */ | 135 | /* MIB callbacks */ |
132 | void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); | 136 | void 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 | } |
126 | EXPORT_SYMBOL(ieee802154_free_hw); | 126 | EXPORT_SYMBOL(ieee802154_free_hw); |
127 | 127 | ||
128 | static 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 | |||
128 | int ieee802154_register_hw(struct ieee802154_hw *hw) | 140 | int 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 | } |
51 | EXPORT_SYMBOL(ieee802154_stop_queue); | 51 | EXPORT_SYMBOL(ieee802154_stop_queue); |
52 | 52 | ||
53 | void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb) | 53 | enum 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 | |||
63 | void 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 | } |
58 | EXPORT_SYMBOL(ieee802154_xmit_complete); | 84 | EXPORT_SYMBOL(ieee802154_xmit_complete); |