ieee802154: introduce new interframe spacing time handling
Subsystems (3)
Alexander Aring
maintainercover ieee802154: introduce new interframe spacing time handling
This patch series contains patches for introducing and use of interframe spacing time handling. The interframe spacing time handling depends on transceiver if it's done at transceiver level or need to be done at SoftMAC (mac802154) level. On the at86rf2xx transceiver this is done at transceiver when max frame retries is above 0.
The mac802154 solution is to run a hrtimer which start at complete function. When the timer expires we wake the queue again. This stops the transmit queue after a transmit for a specific time.
Currently all drivers except the at86rf230 cares about interframe spacing time. I think nobody hit the issue because the latency of workqueue. If we don't making interframe spacing time with async xmit handler we run into fragmentation issues while 802.15.4 6LoWPAN.
Alexander Aring (2):
mac802154: add interframe spacing time handling
at86rf230: remove interframe spacing time workaround
drivers/net/ieee802154/at86rf230.c | 60 +++++++++++++++++++++++--------------- include/linux/ieee802154.h | 3 ++ include/net/cfg802154.h | 8 +++++ include/net/mac802154.h | 3 +- net/mac802154/ieee802154_i.h | 4 +++ net/mac802154/iface.c | 2 ++ net/mac802154/main.c | 17 +++++++++++ net/mac802154/tx.c | 2 +- net/mac802154/util.c | 32 ++++++++++++++++++-- 9 files changed, 103 insertions(+), 28 deletions(-)
Signature · 1 line
2.1.3
Alexander Aring
maintainerPATCH 1/2 mac802154: add interframe spacing time handling
This patch adds a new interframe spacing time handling into mac802154 layer. Interframe spacing time is a time period between each transmit. This patch adds a high resolution timer into mac802154 and starts on xmit complete with corresponding interframe spacing expire time if ifs_handling is true. We make it variable because it depends if interframe spacing time is handled by transceiver or mac802154. At the timer complete function we wake the netdev queue again. This avoids new frame transmit in range of interframe spacing time.
For synced driver we add no handling of interframe spacing time. This is currently a lack of support in all synced xmit drivers. I suppose it's working because the latency of workqueue which is needed to call spi_sync.
--- drivers/net/ieee802154/at86rf230.c | 2 +- include/linux/ieee802154.h | 3 +++ include/net/cfg802154.h | 8 ++++++++ include/net/mac802154.h | 3 ++- net/mac802154/ieee802154_i.h | 4 ++++ net/mac802154/iface.c | 2 ++ net/mac802154/main.c | 17 +++++++++++++++++ net/mac802154/tx.c | 2 +- net/mac802154/util.c | 32 +++++++++++++++++++++++++++++--- 9 files changed, 67 insertions(+), 6 deletions(-)
drivers/net/ieee802154/at86rf230.c +1 -1
@@ -731,7 +731,7 @@ at86rf230_tx_complete(void *context)udelay (lp->data->t_sifs); } -ieee802154_xmit_complete (lp->hw, skb); +ieee802154_xmit_complete (lp->hw, skb, false); } static void
include/linux/ieee802154.h +3 -0
@@ -36,6 +36,9 @@#define IEEE802154_EXTENDED_ADDR_LEN 8 +#define IEEE802154_LIFS_PERIOD 40 +#define IEEE802154_SIFS_PERIOD 12 +#define IEEE802154_FC_TYPE_BEACON 0x0/* Frame is beacon */ #define IEEE802154_FC_TYPE_DATA 0x1/* Frame is data */ #define IEEE802154_FC_TYPE_ACK 0x2/* Frame is acknowledgment */
include/net/cfg802154.h +8 -0
@@ -81,6 +81,14 @@ struct wpan_phy {s32 cca_ed_level; +/* PHY depended MAC PIB values */ + +/* 802.15.4 acronym: Tdsym in usec */ +u8 symbol_duration; +/* lifs and sifs periods timing */ +u16 lifs_period; +u16 sifs_period; +struct device dev;char priv[0 ]__aligned(NETDEV_ALIGN) ;
include/net/mac802154.h +2 -1
@@ -260,6 +260,7 @@ void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb,void ieee802154_wake_queue (struct ieee802154_hw *hw);void ieee802154_stop_queue (struct ieee802154_hw *hw); -void ieee802154_xmit_complete (struct ieee802154_hw *hw,struct sk_buff *skb); +void ieee802154_xmit_complete (struct ieee802154_hw *hw,struct sk_buff *skb, +bool ifs_handling);#endif /* NET_MAC802154_H */
net/mac802154/ieee802154_i.h +4 -0
@@ -20,6 +20,7 @@#define __IEEE802154_I_H#include <linux/mutex.h> +#include <linux/hrtimer.h> #include <net/cfg802154.h> #include <net/mac802154.h> #include <net/ieee802154_netdev.h>
@@ -51,6 +52,8 @@ struct ieee802154_local {*/ struct workqueue_struct *workqueue; +struct hrtimer ifs_timer; +bool started;struct tasklet_struct tasklet;
@@ -127,6 +130,7 @@ ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);void mac802154_wpan_setup (struct net_device *dev);netdev_tx_t ieee802154_subif_start_xmit (struct sk_buff *skb,struct net_device *dev); +enum hrtimer_restart ieee802154_xmit_ifs_timer (struct hrtimer *timer);/* MIB callbacks */ void mac802154_dev_set_short_addr (struct net_device *dev,__le16 val);
net/mac802154/iface.c +2 -0
@@ -246,6 +246,8 @@ static int mac802154_slave_close(struct net_device *dev)ASSERT_RTNL (); +hrtimer_cancel (&local->ifs_timer); +netif_stop_queue (dev); local->open_count--;
net/mac802154/main.c +17 -0
@@ -125,6 +125,18 @@ void ieee802154_free_hw(struct ieee802154_hw *hw) }EXPORT_SYMBOL (ieee802154_free_hw); +static void ieee802154_setup_wpan_phy_pib (struct wpan_phy *wpan_phy) +{ +/* TODO warn on empty symbol_duration +* Should be done when all drivers sets this value. +*/ + + wpan_phy->lifs_period =IEEE802154_LIFS_PERIOD * + wpan_phy->symbol_duration; + wpan_phy->sifs_period =IEEE802154_SIFS_PERIOD * + wpan_phy->symbol_duration; +} +int ieee802154_register_hw (struct ieee802154_hw *hw) {struct ieee802154_local *local =hw_to_local (hw);
@@ -138,8 +150,13 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) goto out; } +hrtimer_init (&local->ifs_timer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL ); + local->ifs_timer.function = ieee802154_xmit_ifs_timer; +wpan_phy_set_dev (local->phy, local->hw.parent); +ieee802154_setup_wpan_phy_pib (local->phy); + rc =wpan_phy_register (local->phy);if (rc <0 ) goto out_wq;
net/mac802154/tx.c +1 -1
@@ -60,7 +60,7 @@ static void ieee802154_xmit_worker(struct work_struct *work)if (res) goto err_tx; -ieee802154_xmit_complete (&local->hw, skb); +ieee802154_xmit_complete (&local->hw, skb, false); dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len;
net/mac802154/util.c +29 -3
@@ -50,9 +50,35 @@ void ieee802154_stop_queue(struct ieee802154_hw *hw) }EXPORT_SYMBOL (ieee802154_stop_queue); -void ieee802154_xmit_complete (struct ieee802154_hw *hw,struct sk_buff *skb) +enum hrtimer_restart ieee802154_xmit_ifs_timer (struct hrtimer *timer) { -ieee802154_wake_queue (hw); -consume_skb (skb); +struct ieee802154_local *local = + container_of(timer, struct ieee802154_local, ifs_timer); + +ieee802154_wake_queue (&local->hw); + +return HRTIMER_NORESTART ; +} + +void ieee802154_xmit_complete (struct ieee802154_hw *hw,struct sk_buff *skb, +bool ifs_handling) +{ +if (ifs_handling) { +struct ieee802154_local *local =hw_to_local (hw); + +if (skb->len >18 ) +hrtimer_start (&local->ifs_timer, +ktime_set (0 , hw->phy->lifs_period *NSEC_PER_USEC ), +HRTIMER_MODE_REL ); +else +hrtimer_start (&local->ifs_timer, +ktime_set (0 , hw->phy->sifs_period *NSEC_PER_USEC ), +HRTIMER_MODE_REL ); + +consume_skb (skb); + }else { +ieee802154_wake_queue (hw); +consume_skb (skb); + } }EXPORT_SYMBOL (ieee802154_xmit_complete);
Signature · 1 line
2.1.3
Alexander Aring
maintainerPATCH 2/2 at86rf230: remove interframe spacing time workaround
In reply to Alexander AringThis patch removes the interframe spacing time workaround from at86rf230 driver and use the mac802154 one. The interframe spacing time differs at at86rf212 and channel setting. This patch fix this handling which is also a new workaround and should be moved into mac802154 while channel setting.
--- drivers/net/ieee802154/at86rf230.c | 60 +++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 23 deletions(-)
drivers/net/ieee802154/at86rf230.c +37 -23
@@ -46,10 +46,6 @@ struct at86rf2xx_chip_data {u16 t_off_to_tx_on;u16 t_frame;u16 t_p_ack; -/* short interframe spacing time */ -u16 t_sifs; -/* long interframe spacing time */ -u16 t_lifs;/* completion timeout for tx in msecs */ u16 t_tx_timeout;int rssi_base_val;
@@ -719,19 +715,10 @@ at86rf230_tx_complete(void *context)enable_irq (lp->spi->irq); -if (lp->max_frame_retries <=0 ) { -/* Interfame spacing time, which is phy depend. -* TODO -* Move this handling in MAC 802.15.4 layer. -* This is currently a workaround to avoid fragmenation issues. -*/ -if (skb->len >18 ) -udelay (lp->data->t_lifs); -else -udelay (lp->data->t_sifs); - } - -ieee802154_xmit_complete (lp->hw, skb, false); +if (lp->max_frame_retries <=0 ) +ieee802154_xmit_complete (lp->hw, skb, true); +else +ieee802154_xmit_complete (lp->hw, skb, false); } static void
@@ -1038,6 +1025,36 @@ at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel)if (rc <0 )return rc; +/* This sets the symbol_duration according frequency on the 212. +* TODO move this handling while set channel and page in cfg802154. +* We can do that, this timings are according 802.15.4 standard. +* If we do that in cfg802154, this is a more generic calculation. +* +* This should also protected from ifs_timer. Means cancel timer and +* init with a new value. For now, this is okay. +*/ +if (channel ==0 ) { +if (page ==0 ) { +/* SUB:0 and BPSK:0 -> BPSK-20 */ + lp->hw->phy->symbol_duration =50 ; + }else { +/* SUB:1 and BPSK:0 -> BPSK-40 */ + lp->hw->phy->symbol_duration =25 ; + } + }else { +if (page ==0 ) +/* SUB:0 and BPSK:1 -> BPSK-20 */ + lp->hw->phy->symbol_duration =40 ; +else +/* SUB:1 and BPSK:1 -> BPSK-20 */ + lp->hw->phy->symbol_duration =16 ; + } + + lp->hw->phy->lifs_period =IEEE802154_LIFS_PERIOD * + lp->hw->phy->symbol_duration; + lp->hw->phy->sifs_period =IEEE802154_SIFS_PERIOD * + lp->hw->phy->symbol_duration; +return at86rf230_write_subreg (lp,SR_CHANNEL , channel); }
@@ -1245,8 +1262,6 @@ static struct at86rf2xx_chip_data at86rf233_data = { .t_off_to_tx_on = 80, .t_frame = 4096, .t_p_ack = 545, - .t_sifs = 192, - .t_lifs = 640, .t_tx_timeout = 2000, .rssi_base_val = -91, .set_channel = at86rf23x_set_channel,
@@ -1261,8 +1276,6 @@ static struct at86rf2xx_chip_data at86rf231_data = { .t_off_to_tx_on = 110, .t_frame = 4096, .t_p_ack = 545, - .t_sifs = 192, - .t_lifs = 640, .t_tx_timeout = 2000, .rssi_base_val = -91, .set_channel = at86rf23x_set_channel,
@@ -1277,8 +1290,6 @@ static struct at86rf2xx_chip_data at86rf212_data = { .t_off_to_tx_on = 200, .t_frame = 4096, .t_p_ack = 545, - .t_sifs = 192, - .t_lifs = 640, .t_tx_timeout = 2000, .rssi_base_val = -100, .set_channel = at86rf212_set_channel,
@@ -1414,6 +1425,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->data = &at86rf231_data; lp->hw->phy->channels_supported[0 ] =0x7FFF800 ; lp->hw->phy->current_channel =11 ; + lp->hw->phy->symbol_duration =16 ;break ;case 7 : chip ="at86rf212" ;
@@ -1423,6 +1435,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->phy->channels_supported[0 ] =0x00007FF ; lp->hw->phy->channels_supported[2 ] =0x00007FF ; lp->hw->phy->current_channel =5 ; + lp->hw->phy->symbol_duration =25 ; }else { rc = -ENOTSUPP ; }
@@ -1432,6 +1445,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->data = &at86rf233_data; lp->hw->phy->channels_supported[0 ] =0x7FFF800 ; lp->hw->phy->current_channel =13 ; + lp->hw->phy->symbol_duration =16 ;break ;default : chip ="unkown" ;
Signature · 1 line
2.1.3
Hi Alex,
Quoted 19 lines
This patch series contains patches for introducing and use of interframe spacing time handling. The interframe spacing time handling depends on transceiver if it's done at transceiver level or need to be done at SoftMAC (mac802154) level. On the at86rf2xx transceiver this is done at transceiver when max frame retries is above 0.
The mac802154 solution is to run a hrtimer which start at complete function. When the timer expires we wake the queue again. This stops the transmit queue after a transmit for a specific time.
Currently all drivers except the at86rf230 cares about interframe spacing time. I think nobody hit the issue because the latency of workqueue. If we don't making interframe spacing time with async xmit handler we run into fragmentation issues while 802.15.4 6LoWPAN.
Alexander Aring (2):
mac802154: add interframe spacing time handling
at86rf230: remove interframe spacing time workaround
Quoted 10 lines
drivers/net/ieee802154/at86rf230.c | 60 +++++++++++++++++++++++--------------- include/linux/ieee802154.h | 3 ++ include/net/cfg802154.h | 8 +++++ include/net/mac802154.h | 3 +- net/mac802154/ieee802154_i.h | 4 +++ net/mac802154/iface.c | 2 ++ net/mac802154/main.c | 17 +++++++++++ net/mac802154/tx.c | 2 +- net/mac802154/util.c | 32 ++++++++++++++++++-- 9 files changed, 103 insertions(+), 28 deletions(-)
both patches have been applied to bluetooth-next tree.
Regards
Marcel