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>
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 23139ca..1a4f6d9 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -50,7 +50,7 @@
 	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 @@
 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 @@
 	/* 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;