summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2014-10-26 09:37:08 +0100
committerMarcel Holtmann <marcel@holtmann.org>2014-10-26 17:24:04 +0100
commited0a5dce0c29f30ee53a87793206156cf38ae70d (patch)
treebb2f9e7a5c1017679f7918cd665b2c825550f6c7 /net
parentcdb66beaa0da7d326069b10bef090645d61d813f (diff)
mac802154: tx: add support for xmit_async callback
This 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. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Cc: Alan Ott <alan@signal11.us> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/mac802154/main.c4
-rw-r--r--net/mac802154/tx.c20
2 files changed, 17 insertions, 7 deletions
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index 0e9a6a203f7a..3c0a824d24ac 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -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;
}
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 23139cae0764..1a4f6d91ab8c 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -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;