ieee802154: rework transmit handling
Subsystems (5)
Alexander Aring
maintainerv2 cover ieee802154: rework transmit handling
This series contains patches for reworking tx handling. Also add a workaround to hold the xmit context when sending frames. Additional add support for asynchronous xmit handling and change the at86rf230 to do a asynchronous xmit handling.
Moving functions and renaming are necessary for the mac80211 naming convention.
changes since v2:
- remove whitespace in PATCH 14/15 ("mac802154: tx: add comment at sync xmit callback")
Alexander Aring (15):
mac802154: tx: move xmit callback to tx file
mac802154: tx: remove kmalloc in xmit hotpath
mac802154: tx: squash multiple dereferencing
mac802154: tx: remove xmit channel context switch
mac802154: add netdev qeue helpers
mac802154: tx: use queue helpers in xmit worker
mac802154: tx: fix error handling while xmit
mac802154: tx: add support for xmit_async callback
mac802154: tx: don't allow if down while sync tx
mac802154: tx: use netdev print helpers
mac802154: tx: cleanup crc calculation
mac802154: tx: move stats tx increment
mac802154: tx: change naming convention
mac802154: tx: add comment at sync xmit callback
at86rf230: asynchronous xmit handling
drivers/net/ieee802154/at86rf230.c | 42 +++++------ drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/mac802154.h | 28 +++++-- net/mac802154/Makefile | 2 +- net/mac802154/ieee802154_i.h | 7 +- net/mac802154/iface.c | 37 +--------- net/mac802154/main.c | 4 +- net/mac802154/monitor.c | 29 +------- net/mac802154/tx.c | 145 ++++++++++++++++++++++--------------- net/mac802154/util.c | 55 ++++++++++++++ 12 files changed, 193 insertions(+), 162 deletions(-) create mode 100644 net/mac802154/util.c
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 1/15 mac802154: tx: move xmit callback to tx file
This patch moves the netdev xmit callback functions into the tx.c file.
--- net/mac802154/ieee802154_i.h | 5 ++-- net/mac802154/iface.c | 35 -------------------------- net/mac802154/monitor.c | 27 -------------------- net/mac802154/tx.c | 59 ++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 67 deletions(-)
net/mac802154/ieee802154_i.h +2 -3
@@ -121,12 +121,11 @@ int mac802154_slave_close(struct net_device *dev);void mac802154_monitors_rx (struct ieee802154_local *local,struct sk_buff *skb);void mac802154_monitor_setup (struct net_device *dev); +netdev_tx_t mac802154_monitor_xmit (struct sk_buff *skb,struct net_device *dev);void mac802154_wpans_rx (struct ieee802154_local *local,struct sk_buff *skb);void mac802154_wpan_setup (struct net_device *dev); - -netdev_tx_t mac802154_tx (struct ieee802154_local *local,struct sk_buff *skb, -u8 page,u8 chan); +netdev_tx_t mac802154_wpan_xmit (struct sk_buff *skb,struct net_device *dev);/* MIB callbacks */ void mac802154_dev_set_short_addr (struct net_device *dev,__le16 val);
net/mac802154/iface.c +0 -35
@@ -307,41 +307,6 @@ mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr)return sizeof (*addr); } -static netdev_tx_t -mac802154_wpan_xmit (struct sk_buff *skb,struct net_device *dev) -{ -struct ieee802154_sub_if_data *sdata; -u8 chan, page; -int rc; - - sdata =IEEE802154_DEV_TO_SUB_IF (dev); - -spin_lock_bh (&sdata->mib_lock); - chan = sdata->chan; - page = sdata->page; -spin_unlock_bh (&sdata->mib_lock); - -if (chan ==MAC802154_CHAN_NONE || - page >=WPAN_NUM_PAGES || - chan >=WPAN_NUM_CHANNELS ) { -kfree_skb (skb); -return NETDEV_TX_OK ; - } - - rc =mac802154_llsec_encrypt (&sdata->sec, skb); -if (rc) { -pr_warn ("encryption failed: %i\n" , rc); -kfree_skb (skb); -return NETDEV_TX_OK ; - } - - skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - -return mac802154_tx (sdata->local, skb, page, chan); -} -static struct header_ops mac802154_header_ops = { .create = mac802154_header_create, .parse = mac802154_header_parse,
net/mac802154/monitor.c +0 -27
@@ -30,33 +30,6 @@#include "ieee802154_i.h" -static netdev_tx_t mac802154_monitor_xmit (struct sk_buff *skb, -struct net_device *dev) -{ -struct ieee802154_sub_if_data *sdata; -u8 chan, page; - - sdata =IEEE802154_DEV_TO_SUB_IF (dev); - -/* FIXME: locking */ - chan = sdata->local->phy->current_channel; - page = sdata->local->phy->current_page; - -if (chan ==MAC802154_CHAN_NONE )/* not initialized */ -return NETDEV_TX_OK ; - -if (WARN_ON (page >=WPAN_NUM_PAGES ) || -WARN_ON (chan >=WPAN_NUM_CHANNELS )) -return NETDEV_TX_OK ; - - skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - -return mac802154_tx (sdata->local, skb, page, chan); -} - -void mac802154_monitors_rx (struct ieee802154_local *local,struct sk_buff *skb) {struct sk_buff *skb2;
net/mac802154/tx.c +57 -2
68 lines not on this page · raw message
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 2/15 mac802154: tx: remove kmalloc in xmit hotpath
In reply to Alexander AringThis patch removes the kmalloc allocation for workqueue data. This patch replaces the kmalloc and uses the control block of skb. The control block has enough space and isn't use by any other layer in this case.
--- net/mac802154/tx.c | 56 ++++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 29 deletions(-)
net/mac802154/tx.c +27 -29
@@ -30,7 +30,7 @@/* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. */ -struct xmit_work { +struct wpan_xmit_cb {struct sk_buff *skb;struct work_struct work;struct ieee802154_local *local;
@@ -38,50 +38,54 @@ struct xmit_work {u8 page; }; +static inline struct wpan_xmit_cb *wpan_xmit_cb (const struct sk_buff *skb) +{ +BUILD_BUG_ON (sizeof (skb->cb) <sizeof (struct wpan_xmit_cb )); + +return (struct wpan_xmit_cb *)skb->cb; +} +static void mac802154_xmit_worker (struct work_struct *work) { - struct xmit_work *xw = container_of(work, struct xmit_work, work); + struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work);struct ieee802154_sub_if_data *sdata;int res; -mutex_lock (&xw->local->phy->pib_lock); -if (xw->local->phy->current_channel != xw->chan || - xw->local->phy->current_page != xw->page) { - res = xw->local->ops->set_channel (&xw->local->hw, - xw->page, - xw->chan); +mutex_lock (&cb->local->phy->pib_lock); +if (cb->local->phy->current_channel != cb->chan || + cb->local->phy->current_page != cb->page) { + res = cb->local->ops->set_channel (&cb->local->hw, cb->page, + cb->chan);if (res) {pr_debug ("set_channel failed\n" ); goto out; } - xw->local->phy->current_channel = xw->chan; - xw->local->phy->current_page = xw->page; + cb->local->phy->current_channel = cb->chan; + cb->local->phy->current_page = cb->page; } - res = xw->local->ops->xmit (&xw->local->hw, xw->skb); + res = cb->local->ops->xmit (&cb->local->hw, cb->skb);if (res)pr_debug ("transmission failed\n" ); out: -mutex_unlock (&xw->local->phy->pib_lock); +mutex_unlock (&cb->local->phy->pib_lock);/* Restart the netif queue on each sub_if_data object. */ rcu_read_lock (); -list_for_each_entry_rcu (sdata, &xw->local->interfaces, list) +list_for_each_entry_rcu (sdata, &cb->local->interfaces, list)netif_wake_queue (sdata->dev);rcu_read_unlock (); -dev_kfree_skb (xw->skb); - -kfree (xw); +dev_kfree_skb (cb->skb); }static netdev_tx_t mac802154_tx (struct ieee802154_local *local,struct sk_buff *skb,u8 page,u8 chan) { -struct xmit_work *work;struct ieee802154_sub_if_data *sdata; +struct wpan_xmit_cb *cb =wpan_xmit_cb (skb);if (!(local->phy->channels_supported[page] & (1 << chan))) {WARN_ON (1 );
@@ -101,25 +105,19 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local,if (skb_cow_head (skb, local->hw.extra_tx_headroom)) goto err_tx; - work =kzalloc (sizeof (*work),GFP_ATOMIC ); -if (!work) { -kfree_skb (skb); -return NETDEV_TX_BUSY ; - } -/* Stop the netif queue on each sub_if_data object. */ rcu_read_lock ();list_for_each_entry_rcu (sdata, &local->interfaces, list)netif_stop_queue (sdata->dev);rcu_read_unlock (); -INIT_WORK (&work->work, mac802154_xmit_worker); - work->skb = skb; - work->local = local; - work->page = page; - work->chan = chan; +INIT_WORK (&cb->work, mac802154_xmit_worker); + cb->skb = skb; + cb->local = local; + cb->page = page; + cb->chan = chan; -queue_work (local->workqueue, &work->work); +queue_work (local->workqueue, &cb->work);return NETDEV_TX_OK ;
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 3/15 mac802154: tx: squash multiple dereferencing
In reply to Alexander AringThis patch introduce some new stack variables to avoid multiple dereferencing inside the xmit worker function.
--- net/mac802154/tx.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
net/mac802154/tx.c +12 -11
@@ -48,37 +48,38 @@ static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb)static void mac802154_xmit_worker (struct work_struct *work) { struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); +struct ieee802154_local *local = cb->local;struct ieee802154_sub_if_data *sdata; +struct sk_buff *skb = cb->skb;int res; -mutex_lock (&cb->local->phy->pib_lock); -if (cb->local->phy->current_channel != cb->chan || - cb->local->phy->current_page != cb->page) { - res = cb->local->ops->set_channel (&cb->local->hw, cb->page, - cb->chan); +mutex_lock (&local->phy->pib_lock); +if (local->phy->current_channel != cb->chan || + local->phy->current_page != cb->page) { + res = local->ops->set_channel (&local->hw, cb->page, cb->chan);if (res) {pr_debug ("set_channel failed\n" ); goto out; } - cb->local->phy->current_channel = cb->chan; - cb->local->phy->current_page = cb->page; + local->phy->current_channel = cb->chan; + local->phy->current_page = cb->page; } - res = cb->local->ops->xmit (&cb->local->hw, cb->skb); + res = local->ops->xmit (&local->hw, skb);if (res)pr_debug ("transmission failed\n" ); out: -mutex_unlock (&cb->local->phy->pib_lock); +mutex_unlock (&local->phy->pib_lock);/* Restart the netif queue on each sub_if_data object. */ rcu_read_lock (); -list_for_each_entry_rcu (sdata, &cb->local->interfaces, list) +list_for_each_entry_rcu (sdata, &local->interfaces, list)netif_wake_queue (sdata->dev);rcu_read_unlock (); -dev_kfree_skb (cb->skb); +dev_kfree_skb (skb); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local,
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 4/15 mac802154: tx: remove xmit channel context switch
In reply to Alexander AringThis patch removes the channel hopping feature before xmit. There are several issues to provide a real channel hopping (timing requirements, etc...).
We don't have any known kernelspace protocol which really use this feature. And I don't know an real user of this feature. We simply drop this feature now.
This patch removes also the hold of pib lock which isn't needed by any real driver xmit callback implementation.
--- include/net/mac802154.h | 3 +-- net/mac802154/tx.c | 58 ++++--------------------------------------------- 2 files changed, 5 insertions(+), 56 deletions(-)
include/net/mac802154.h +1 -2
@@ -113,8 +113,7 @@ struct ieee802154_hw {* skb cntains the buffer starting from the IEEE 802.15.4 header. * The low-level driver should send the frame based on available * configuration. -* This function should return zero or negative errno. Called with -* pib_lock held. +* This function should return zero or negative errno. * * ed: Handler that 802.15.4 module calls for Energy Detection. * This function should place the value for detected energy
net/mac802154/tx.c +4 -54
112 lines not on this page · raw message
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 5/15 mac802154: add netdev qeue helpers
In reply to Alexander AringThis patch adds a new file net/mac802154/util.c which contains utility functions for drivers, etc. This file contains functions to start and stop queues for all virtual interfaces, this is useful for asynchronous handling by driver level.
--- include/net/mac802154.h | 4 ++++ net/mac802154/Makefile | 2 +- net/mac802154/util.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 net/mac802154/util.c
include/net/mac802154.h +4 -0
@@ -190,4 +190,8 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw);void ieee802154_rx_irqsafe (struct ieee802154_hw *hw,struct sk_buff *skb,u8 lqi); +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); +#endif /* NET_MAC802154_H */
net/mac802154/Makefile +1 -1
@@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - monitor.o iface.o llsec.o + monitor.o iface.o llsec.o util.o ccflags-y += -D__CHECK_ENDIAN__
net/mac802154/util.c new file +55 -0
55 lines not on this page · raw message
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 6/15 mac802154: tx: use queue helpers in xmit worker
In reply to Alexander AringThis patch uses the queue utility helpers inside the xmit worker of mac802154 subsystem.
--- net/mac802154/tx.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
net/mac802154/tx.c +2 -12
@@ -47,7 +47,6 @@ static void mac802154_xmit_worker(struct work_struct *work) { struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work);struct ieee802154_local *local = cb->local; -struct ieee802154_sub_if_data *sdata;struct sk_buff *skb = cb->skb;int res;
@@ -56,18 +55,12 @@ static void mac802154_xmit_worker(struct work_struct *work)pr_debug ("transmission failed\n" );/* Restart the netif queue on each sub_if_data object. */ -rcu_read_lock (); -list_for_each_entry_rcu (sdata, &local->interfaces, list) -netif_wake_queue (sdata->dev); -rcu_read_unlock (); - -dev_kfree_skb (skb); +ieee802154_xmit_complete (&local->hw, skb); }static netdev_tx_t mac802154_tx (struct ieee802154_local *local,struct sk_buff *skb) { -struct ieee802154_sub_if_data *sdata;struct wpan_xmit_cb *cb =wpan_xmit_cb (skb);mac802154_monitors_rx (local, skb);
@@ -84,10 +77,7 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) goto err_tx;/* Stop the netif queue on each sub_if_data object. */ -rcu_read_lock (); -list_for_each_entry_rcu (sdata, &local->interfaces, list) -netif_stop_queue (sdata->dev); -rcu_read_unlock (); +ieee802154_stop_queue (&local->hw);INIT_WORK (&cb->work, mac802154_xmit_worker); cb->skb = skb;
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 7/15 mac802154: tx: fix error handling while xmit
In reply to Alexander AringIn case of an error we should call kfree_skb instead of consume_skb which is called by ieee802154_xmit_complete function.
--- net/mac802154/tx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/mac802154/tx.c +8 -4
@@ -51,11 +51,15 @@ static void mac802154_xmit_worker(struct work_struct *work)int res; res = local->ops->xmit (&local->hw, skb); -if (res) +if (res) {pr_debug ("transmission failed\n" ); - -/* Restart the netif queue on each sub_if_data object. */ -ieee802154_xmit_complete (&local->hw, skb); +/* Restart the netif queue on each sub_if_data object. */ +ieee802154_wake_queue (&local->hw); +kfree_skb (skb); + }else { +/* Restart the netif queue on each sub_if_data object. */ +ieee802154_xmit_complete (&local->hw, skb); + } } static netdev_tx_t
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 8/15 mac802154: tx: add support for xmit_async callback
In reply to Alexander AringThis patch renames the existsing xmit callback to xmit_sync and introduces an asynchronous xmit_async function. If ieee802154_ops doesn't provide the xmit_async callback, then we have a fallback to the xmit_sync callback.
--- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/mac802154.h | 17 ++++++++++++++--- net/mac802154/main.c | 4 ++-- net/mac802154/tx.c | 20 +++++++++++++++----- 7 files changed, 35 insertions(+), 14 deletions(-)
drivers/net/ieee802154/at86rf230.c +1 -1
@@ -1237,7 +1237,7 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries)static struct ieee802154_ops at86rf230_ops = { .owner =THIS_MODULE , - .xmit = at86rf230_xmit, + .xmit_sync = at86rf230_xmit, .ed = at86rf230_ed, .set_channel = at86rf230_channel, .start = at86rf230_start,
drivers/net/ieee802154/cc2520.c +1 -1
@@ -635,7 +635,7 @@ static struct ieee802154_ops cc2520_ops = { .owner = THIS_MODULE, .start = cc2520_start, .stop = cc2520_stop, - .xmit = cc2520_tx, + .xmit_sync = cc2520_tx, .ed = cc2520_ed, .set_channel = cc2520_set_channel, .set_hw_addr_filt = cc2520_filter,
drivers/net/ieee802154/fakelb.c +1 -1
@@ -131,7 +131,7 @@ fakelb_hw_stop(struct ieee802154_hw *hw) {static struct ieee802154_ops fakelb_ops = { .owner =THIS_MODULE , - .xmit = fakelb_hw_xmit, + .xmit_sync = fakelb_hw_xmit, .ed = fakelb_hw_ed, .set_channel = fakelb_hw_channel, .start = fakelb_hw_start,
drivers/net/ieee802154/mrf24j40.c +1 -1
@@ -581,7 +581,7 @@ out:static struct ieee802154_ops mrf24j40_ops = { .owner =THIS_MODULE , - .xmit = mrf24j40_tx, + .xmit_sync = mrf24j40_tx, .ed = mrf24j40_ed, .start = mrf24j40_start, .stop = mrf24j40_stop,
include/net/mac802154.h +14 -3
@@ -109,7 +109,16 @@ struct ieee802154_hw {* stop: Handler that 802.15.4 module calls for device cleanup. * This function is called after the last interface is removed. * -* xmit: Handler that 802.15.4 module calls for each transmitted frame. +* xmit_sync: +* Handler that 802.15.4 module calls for each transmitted frame. +* skb cntains the buffer starting from the IEEE 802.15.4 header. +* The low-level driver should send the frame based on available +* configuration. This is called by a workqueue and useful for +* synchronous 802.15.4 drivers. +* This function should return zero or negative errno. +* +* xmit_async: +* Handler that 802.15.4 module calls for each transmitted frame. * skb cntains the buffer starting from the IEEE 802.15.4 header. * The low-level driver should send the frame based on available * configuration.
@@ -160,8 +169,10 @@ struct ieee802154_ops {struct module *owner;int (*start)(struct ieee802154_hw *hw);void (*stop)(struct ieee802154_hw *hw); -int (*xmit)(struct ieee802154_hw *hw, -struct sk_buff *skb); +int (*xmit_sync)(struct ieee802154_hw *hw, +struct sk_buff *skb); +int (*xmit_async)(struct ieee802154_hw *hw, +struct sk_buff *skb);int (*ed)(struct ieee802154_hw *hw,u8 *level); int (*set_channel)(struct ieee802154_hw *hw, int page,
net/mac802154/main.c +2 -2
@@ -229,8 +229,8 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops)struct ieee802154_local *local;size_t priv_size; -if (!ops || !ops->xmit || !ops->ed || !ops->start || - !ops->stop || !ops->set_channel) { +if (!ops || !(ops->xmit_async || ops->xmit_sync) || !ops->ed || + !ops->start || !ops->stop || !ops->set_channel) {pr_err ("undefined IEEE802.15.4 device operations\n" );return NULL ; }
net/mac802154/tx.c +15 -5
@@ -50,7 +50,7 @@ static void mac802154_xmit_worker(struct work_struct *work)struct sk_buff *skb = cb->skb;int res; - res = local->ops->xmit (&local->hw, skb); + res = local->ops->xmit_sync (&local->hw, skb);if (res) {pr_debug ("transmission failed\n" );/* Restart the netif queue on each sub_if_data object. */
@@ -66,6 +66,7 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); +int ret;mac802154_monitors_rx (local, skb);
@@ -83,11 +84,20 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb)/* Stop the netif queue on each sub_if_data object. */ ieee802154_stop_queue (&local->hw); -INIT_WORK (&cb->work, mac802154_xmit_worker); - cb->skb = skb; - cb->local = local; +/* async is priority, otherwise sync is fallback */ +if (local->ops->xmit_async) { + ret = local->ops->xmit_async (&local->hw, skb); +if (ret) { +ieee802154_wake_queue (&local->hw); + goto err_tx; + } + }else { +INIT_WORK (&cb->work, mac802154_xmit_worker); + cb->skb = skb; + cb->local = local; -queue_work (local->workqueue, &cb->work); +queue_work (local->workqueue, &cb->work); + }return NETDEV_TX_OK ;
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 9/15 mac802154: tx: don't allow if down while sync tx
In reply to Alexander AringThis patch holds rtnl lock while sync xmit inside of workqueue. Otherwise we could down the interface while worker xmit handling.
--- net/mac802154/tx.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
net/mac802154/tx.c +22 -9
@@ -21,6 +21,7 @@#include <linux/if_arp.h> #include <linux/crc-ccitt.h> +#include <net/rtnetlink.h> #include <net/ieee802154_netdev.h> #include <net/mac802154.h> #include <net/cfg802154.h>
@@ -50,16 +51,28 @@ static void mac802154_xmit_worker(struct work_struct *work)struct sk_buff *skb = cb->skb;int res; +rtnl_lock (); + +/* check if ifdown occurred while schedule */ +if (!netif_running (skb->dev)) + goto err_tx; + res = local->ops->xmit_sync (&local->hw, skb); -if (res) { -pr_debug ("transmission failed\n" ); -/* Restart the netif queue on each sub_if_data object. */ -ieee802154_wake_queue (&local->hw); -kfree_skb (skb); - }else { -/* Restart the netif queue on each sub_if_data object. */ -ieee802154_xmit_complete (&local->hw, skb); - } +if (res) + goto err_tx; + +ieee802154_xmit_complete (&local->hw, skb); + +rtnl_unlock (); + +return ; + +err_tx: +/* Restart the netif queue on each sub_if_data object. */ +ieee802154_wake_queue (&local->hw); +rtnl_unlock (); +kfree_skb (skb); +pr_debug ("transmission failed\n" ); } static netdev_tx_t
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 10/15 mac802154: tx: use netdev print helpers
In reply to Alexander AringThis patch replace the pr_foo printout function to netdev_foo printout function. Inside the xmit handling, the interface is already known.
--- net/mac802154/tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/mac802154/tx.c +2 -2
@@ -72,7 +72,7 @@ err_tx:ieee802154_wake_queue (&local->hw);rtnl_unlock ();kfree_skb (skb); -pr_debug ("transmission failed\n" ); +netdev_dbg (skb->dev,"transmission failed\n" ); } static netdev_tx_t
@@ -137,7 +137,7 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) rc =mac802154_llsec_encrypt (&sdata->sec, skb);if (rc) { -pr_warn ("encryption failed: %i\n" , rc); +netdev_warn (dev,"encryption failed: %i\n" , rc);kfree_skb (skb);return NETDEV_TX_OK ; }
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 11/15 mac802154: tx: cleanup crc calculation
In reply to Alexander Aring--- net/mac802154/tx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
net/mac802154/tx.c +2 -4
@@ -84,11 +84,9 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb)mac802154_monitors_rx (local, skb);if (!(local->hw.flags &IEEE802154_HW_OMIT_CKSUM )) { -u16 crc =crc_ccitt (0 , skb->data, skb->len); -u8 *data =skb_put (skb,2 ); +__le16 crc =cpu_to_le16 (crc_ccitt (0 , skb->data, skb->len)); - data[0 ] = crc &0xff ; - data[1 ] = crc >>8 ; +memcpy (skb_put (skb,2 ), &crc,2 ); }if (skb_cow_head (skb, local->hw.extra_tx_headroom))
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 12/15 mac802154: tx: move stats tx increment
In reply to Alexander AringThis patch moves the stats increment of successful transmitted packets in the right place when the skb was really successful transmitted.
--- net/mac802154/tx.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
net/mac802154/tx.c +10 -6
@@ -49,12 +49,13 @@ static void mac802154_xmit_worker(struct work_struct *work) struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work);struct ieee802154_local *local = cb->local;struct sk_buff *skb = cb->skb; +struct net_device *dev = skb->dev;int res;rtnl_lock ();/* check if ifdown occurred while schedule */ -if (!netif_running (skb->dev)) +if (!netif_running (dev)) goto err_tx; res = local->ops->xmit_sync (&local->hw, skb);
@@ -63,6 +64,9 @@ static void mac802154_xmit_worker(struct work_struct *work)ieee802154_xmit_complete (&local->hw, skb); + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; +rtnl_unlock ();return ;
@@ -72,13 +76,14 @@ err_tx:ieee802154_wake_queue (&local->hw);rtnl_unlock ();kfree_skb (skb); -netdev_dbg (skb->dev,"transmission failed\n" ); +netdev_dbg (dev,"transmission failed\n" ); }static netdev_tx_t mac802154_tx (struct ieee802154_local *local,struct sk_buff *skb) {struct wpan_xmit_cb *cb =wpan_xmit_cb (skb); +struct net_device *dev = skb->dev;int ret;mac802154_monitors_rx (local, skb);
@@ -102,6 +107,9 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb)ieee802154_wake_queue (&local->hw); goto err_tx; } + + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; }else {INIT_WORK (&cb->work, mac802154_xmit_worker); cb->skb = skb;
@@ -122,8 +130,6 @@ netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev)struct ieee802154_sub_if_data *sdata =IEEE802154_DEV_TO_SUB_IF (dev); skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len;return mac802154_tx (sdata->local, skb); }
@@ -141,8 +147,6 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) } skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len;return mac802154_tx (sdata->local, skb); }
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 13/15 mac802154: tx: change naming convention
In reply to Alexander AringThis patch changes the naming convention of the tx functions like mac80211. Just with an 802154 instead 80211 inside the name.
--- net/mac802154/ieee802154_i.h | 6 ++++-- net/mac802154/iface.c | 2 +- net/mac802154/monitor.c | 2 +- net/mac802154/tx.c | 30 +++++++++++++++++------------- 4 files changed, 23 insertions(+), 17 deletions(-)
net/mac802154/ieee802154_i.h +4 -2
@@ -121,11 +121,13 @@ int mac802154_slave_close(struct net_device *dev);void mac802154_monitors_rx (struct ieee802154_local *local,struct sk_buff *skb);void mac802154_monitor_setup (struct net_device *dev); -netdev_tx_t mac802154_monitor_xmit (struct sk_buff *skb,struct net_device *dev); +netdev_tx_t +ieee802154_monitor_start_xmit (struct sk_buff *skb,struct net_device *dev);void mac802154_wpans_rx (struct ieee802154_local *local,struct sk_buff *skb);void mac802154_wpan_setup (struct net_device *dev); -netdev_tx_t mac802154_wpan_xmit (struct sk_buff *skb,struct net_device *dev); +netdev_tx_t +ieee802154_subif_start_xmit (struct sk_buff *skb,struct net_device *dev);/* MIB callbacks */ void mac802154_dev_set_short_addr (struct net_device *dev,__le16 val);
net/mac802154/iface.c +1 -1
@@ -315,7 +315,7 @@ static struct header_ops mac802154_header_ops = {static const struct net_device_ops mac802154_wpan_ops = { .ndo_open = mac802154_wpan_open, .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = mac802154_wpan_xmit, + .ndo_start_xmit = ieee802154_subif_start_xmit, .ndo_do_ioctl = mac802154_wpan_ioctl, .ndo_set_mac_address = mac802154_wpan_mac_addr, };
net/mac802154/monitor.c +1 -1
@@ -58,7 +58,7 @@ void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)static const struct net_device_ops mac802154_monitor_ops = { .ndo_open = mac802154_slave_open, .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = mac802154_monitor_xmit, + .ndo_start_xmit = ieee802154_monitor_start_xmit, };void mac802154_monitor_setup (struct net_device *dev)
net/mac802154/tx.c +17 -13
@@ -31,22 +31,24 @@/* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. */ -struct wpan_xmit_cb { +struct ieee802154_xmit_cb {struct sk_buff *skb;struct work_struct work;struct ieee802154_local *local; }; -static inline struct wpan_xmit_cb *wpan_xmit_cb (const struct sk_buff *skb) +static inline struct ieee802154_xmit_cb * +ieee802154_xmit_cb (const struct sk_buff *skb) { -BUILD_BUG_ON (sizeof (skb->cb) <sizeof (struct wpan_xmit_cb )); +BUILD_BUG_ON (sizeof (skb->cb) <sizeof (struct ieee802154_xmit_cb )); -return (struct wpan_xmit_cb *)skb->cb; +return (struct ieee802154_xmit_cb *)skb->cb; } -static void mac802154_xmit_worker (struct work_struct *work) +static void ieee802154_xmit_worker (struct work_struct *work) { - struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); +struct ieee802154_xmit_cb *cb = + container_of(work, struct ieee802154_xmit_cb, work);struct ieee802154_local *local = cb->local;struct sk_buff *skb = cb->skb;struct net_device *dev = skb->dev;
@@ -80,9 +82,9 @@ err_tx: }static netdev_tx_t -mac802154_tx (struct ieee802154_local *local,struct sk_buff *skb) +ieee802154_tx (struct ieee802154_local *local,struct sk_buff *skb) { -struct wpan_xmit_cb *cb =wpan_xmit_cb (skb); +struct ieee802154_xmit_cb *cb =ieee802154_xmit_cb (skb);struct net_device *dev = skb->dev;int ret;
@@ -111,7 +113,7 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; }else { -INIT_WORK (&cb->work, mac802154_xmit_worker); +INIT_WORK (&cb->work, ieee802154_xmit_worker); cb->skb = skb; cb->local = local;
@@ -125,16 +127,18 @@ err_tx:return NETDEV_TX_OK ; } -netdev_tx_t mac802154_monitor_xmit (struct sk_buff *skb,struct net_device *dev) +netdev_tx_t +ieee802154_monitor_start_xmit (struct sk_buff *skb,struct net_device *dev) {struct ieee802154_sub_if_data *sdata =IEEE802154_DEV_TO_SUB_IF (dev); skb->skb_iif = dev->ifindex; -return mac802154_tx (sdata->local, skb); +return ieee802154_tx (sdata->local, skb); } -netdev_tx_t mac802154_wpan_xmit (struct sk_buff *skb,struct net_device *dev) +netdev_tx_t +ieee802154_subif_start_xmit (struct sk_buff *skb,struct net_device *dev) {struct ieee802154_sub_if_data *sdata =IEEE802154_DEV_TO_SUB_IF (dev);int rc;
@@ -148,5 +152,5 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) skb->skb_iif = dev->ifindex; -return mac802154_tx (sdata->local, skb); +return ieee802154_tx (sdata->local, skb); }
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 14/15 mac802154: tx: add comment at sync xmit callback
In reply to Alexander AringThis patch adds a warning that xmit_sync callback is deprecated and should be removed soon. The 802.15.4 subsystem will not accept synced drivers anymore.
--- include/net/mac802154.h | 4 ++++ 1 file changed, 4 insertions(+)
include/net/mac802154.h +4 -0
@@ -117,6 +117,10 @@ struct ieee802154_hw {* synchronous 802.15.4 drivers. * This function should return zero or negative errno. * +* WARNING: +* This will be deprecated soon. We don't accept synced xmit callbacks +* drivers anymore. +* * xmit_async: * Handler that 802.15.4 module calls for each transmitted frame. * skb cntains the buffer starting from the IEEE 802.15.4 header.
Signature · 1 line
2.1.2
Alexander Aring
maintainerPATCH v2 15/15 at86rf230: asynchronous xmit handling
In reply to Alexander AringThis patch converts the sync xmit handling into an async xmit handling. The driver was already prepared for this step, all other drivers need more work to implement a xmit_async function.
--- drivers/net/ieee802154/at86rf230.c | 42 +++++++++++++++----------------------- 1 file changed, 17 insertions(+), 25 deletions(-)
drivers/net/ieee802154/at86rf230.c +17 -25
@@ -91,7 +91,6 @@ struct at86rf230_local {bool is_tx;/* spinlock for is_tx protection */ spinlock_t lock; -struct completion tx_complete;struct sk_buff *tx_skb;struct at86rf230_state_change tx; };
@@ -452,6 +451,7 @@ at86rf230_async_error_recover(void *context)struct at86rf230_local *lp = ctx->lp;at86rf230_async_state_change (lp, ctx,STATE_RX_AACK_ON ,NULL , false); +ieee802154_wake_queue (lp->hw); } static void
@@ -715,9 +715,23 @@ at86rf230_tx_complete(void *context) {struct at86rf230_state_change *ctx = context;struct at86rf230_local *lp = ctx->lp; +struct sk_buff *skb = lp->tx_skb;enable_irq (lp->spi->irq); -complete (&lp->tx_complete); + +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); } static void
@@ -975,7 +989,6 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)struct at86rf230_state_change *ctx = &lp->tx;void (*tx_complete)(void *context) = at86rf230_write_frame; -int rc; lp->tx_skb = skb;
@@ -988,26 +1001,6 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)at86rf230_async_state_change (lp, ctx,STATE_TX_ON , tx_complete, false); - rc =wait_for_completion_interruptible_timeout (&lp->tx_complete, -msecs_to_jiffies (lp->data->t_tx_timeout)); -if (!rc) { -at86rf230_async_error (lp, ctx, -ETIMEDOUT ); -return -ETIMEDOUT ; - } - -if (lp->max_frame_retries >0 ) -return 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 ) -usleep_range (lp->data->t_lifs, lp->data->t_lifs +10 ); -else -usleep_range (lp->data->t_sifs, lp->data->t_sifs +10 ); -return 0 ; }
@@ -1237,7 +1230,7 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries)static struct ieee802154_ops at86rf230_ops = { .owner =THIS_MODULE , - .xmit_sync = at86rf230_xmit, + .xmit_async = at86rf230_xmit, .ed = at86rf230_ed, .set_channel = at86rf230_channel, .start = at86rf230_start,
@@ -1541,7 +1534,6 @@ static int at86rf230_probe(struct spi_device *spi) goto free_dev;spin_lock_init (&lp->lock); -init_completion (&lp->tx_complete);init_completion (&lp->state_complete);spi_set_drvdata (spi, lp);
Signature · 1 line
2.1.2
Hi Alex,
Quoted 42 lines
This series contains patches for reworking tx handling. Also add a workaround to hold the xmit context when sending frames. Additional add support for asynchronous xmit handling and change the at86rf230 to do a asynchronous xmit handling.
Moving functions and renaming are necessary for the mac80211 naming convention.
changes since v2:
- remove whitespace in PATCH 14/15 ("mac802154: tx: add comment at sync xmit callback")Alexander Aring (15):
mac802154: tx: move xmit callback to tx file
mac802154: tx: remove kmalloc in xmit hotpath
mac802154: tx: squash multiple dereferencing
mac802154: tx: remove xmit channel context switch
mac802154: add netdev qeue helpers
mac802154: tx: use queue helpers in xmit worker
mac802154: tx: fix error handling while xmit
mac802154: tx: add support forxmit_asynccallback
mac802154: tx: don't allow if down while sync tx
mac802154: tx: use netdev print helpers
mac802154: tx: cleanup crc calculation
mac802154: tx: move stats tx increment
mac802154: tx: change naming convention
mac802154: tx: add comment at sync xmit callback
at86rf230: asynchronous xmit handlingdrivers/net/ieee802154/at86rf230.c | 42 +++++------ drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/mac802154.h | 28 +++++-- net/mac802154/Makefile | 2 +- net/mac802154/ieee802154_i.h | 7 +- net/mac802154/iface.c | 37 +--------- net/mac802154/main.c | 4 +- net/mac802154/monitor.c | 29 +------- net/mac802154/tx.c | 145 ++++++++++++++++++++++--------------- net/mac802154/util.c | 55 ++++++++++++++ 12 files changed, 193 insertions(+), 162 deletions(-)
Quoted 1 line
create mode 100644
net/mac802154/util.c
all 15 patches have been applied to bluetooth-next tree.
Regards
Marcel