linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [wpan-next 00/14] ieee802154: Synchronous Tx API
@ 2022-01-20  0:51 Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 01/14] net: ieee802154: Move the logic restarting the queue upon transmission Miquel Raynal
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

The idea here is to provide a fully synchronous Tx API and also be able
to be sure that a transfer as finished. This will be used later by
another series.

The first patches create an error helper and then use it in order to
have only two "end of transmission" helpers that are always called.

Then, a bit of cleanup regarding the naming and the locations of certain
peaces of code is done.

Finally, we create a hot and a slow path, add the necessary logic to be
able to track ongoing transfers and when the queue must be kept on hold,
until we finally create a helper to stop emitting after the last
transfer, which we then use to create a synchronous MLME API.

(Caution: I haven't fully tested that part yet, but as Alexander and me
are on very different time slots I prefer to provide this tonight and
eventually fix it tomorrow)

Miquel Raynal (14):
  net: ieee802154: Move the logic restarting the queue upon transmission
  net: mac802154: Create a transmit error helper
  net: ieee802154: at86rf230: Call _xmit_error() when a transmission
    fails
  net: ieee802154: atusb: Call _xmit_error() when a transmission fails
  net: ieee802154: ca8210: Call _xmit_error() when a transmission fails
  net: mac802154: Stop exporting ieee802154_wake/stop_queue()
  net: mac802154: Rename the synchronous xmit worker
  net: mac802154: Rename the main tx_work struct
  net: mac802154: Follow the count of ongoing transmissions
  net: mac802154: Hold the transmit queue when relevant
  net: mac802154: Create a hot tx path
  net: mac802154: Add a warning in the hot path
  net: mac802154: Introduce a tx queue flushing mechanism
  net: mac802154: Introduce a synchronous API for MLME commands

 drivers/net/ieee802154/at86rf230.c |  3 +-
 drivers/net/ieee802154/atusb.c     |  4 +--
 drivers/net/ieee802154/ca8210.c    | 12 ++++----
 include/net/cfg802154.h            |  5 ++++
 include/net/mac802154.h            | 37 +++++++----------------
 net/ieee802154/core.c              |  1 +
 net/mac802154/cfg.c                |  5 ++--
 net/mac802154/ieee802154_i.h       | 35 ++++++++++++++++++++--
 net/mac802154/main.c               |  2 +-
 net/mac802154/tx.c                 | 48 +++++++++++++++++++++++++-----
 net/mac802154/util.c               | 34 ++++++++++++++++++---
 11 files changed, 132 insertions(+), 54 deletions(-)

-- 
2.27.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [wpan-next 01/14] net: ieee802154: Move the logic restarting the queue upon transmission
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 02/14] net: mac802154: Create a transmit error helper Miquel Raynal
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

Create a new helper with the logic restarting the queue upon
transmission, so that we can create a second path for error conditions
which can reuse that code easily.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/mac802154/util.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/mac802154/util.c b/net/mac802154/util.c
index f2078238718b..4c06a6bd391a 100644
--- a/net/mac802154/util.c
+++ b/net/mac802154/util.c
@@ -55,8 +55,9 @@ enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer)
 	return HRTIMER_NORESTART;
 }
 
-void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
-			      bool ifs_handling)
+static void
+ieee802154_wakeup_after_xmit_done(struct ieee802154_hw *hw, struct sk_buff *skb,
+				  bool ifs_handling)
 {
 	if (ifs_handling) {
 		struct ieee802154_local *local = hw_to_local(hw);
@@ -83,7 +84,12 @@ void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
 	} else {
 		ieee802154_wake_queue(hw);
 	}
+}
 
+void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
+			      bool ifs_handling)
+{
+	ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
 	dev_consume_skb_any(skb);
 }
 EXPORT_SYMBOL(ieee802154_xmit_complete);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 02/14] net: mac802154: Create a transmit error helper
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 01/14] net: ieee802154: Move the logic restarting the queue upon transmission Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 03/14] net: ieee802154: at86rf230: Call _xmit_error() when a transmission fails Miquel Raynal
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

So far there is only a helper for successful transmission, which led
device drivers to implement their own handling in case of
error. Unfortunately, we really need all the drivers to give the hand
back to the core once they are done in order to be able to build a
proper synchronous API. So let's create a _xmit_error() helper.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/mac802154.h | 10 ++++++++++
 net/mac802154/util.c    |  9 +++++++++
 2 files changed, 19 insertions(+)

diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 94b2e3008e77..e7443e1acde8 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -498,4 +498,14 @@ void ieee802154_stop_queue(struct ieee802154_hw *hw);
 void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
 			      bool ifs_handling);
 
+/**
+ * ieee802154_xmit_error - frame transmission failed
+ *
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ * @skb: buffer for transmission
+ * @ifs_handling: indicate interframe space handling
+ */
+void ieee802154_xmit_error(struct ieee802154_hw *hw, struct sk_buff *skb,
+			   bool ifs_handling);
+
 #endif /* NET_MAC802154_H */
diff --git a/net/mac802154/util.c b/net/mac802154/util.c
index 4c06a6bd391a..8e7e4cf16fc3 100644
--- a/net/mac802154/util.c
+++ b/net/mac802154/util.c
@@ -94,6 +94,15 @@ void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
 }
 EXPORT_SYMBOL(ieee802154_xmit_complete);
 
+
+void ieee802154_xmit_error(struct ieee802154_hw *hw, struct sk_buff *skb,
+			   bool ifs_handling)
+{
+	ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
+	dev_kfree_skb_any(skb);
+}
+EXPORT_SYMBOL(ieee802154_xmit_error);
+
 void ieee802154_stop_device(struct ieee802154_local *local)
 {
 	flush_workqueue(local->workqueue);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 03/14] net: ieee802154: at86rf230: Call _xmit_error() when a transmission fails
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 01/14] net: ieee802154: Move the logic restarting the queue upon transmission Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 02/14] net: mac802154: Create a transmit error helper Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 04/14] net: ieee802154: atusb: " Miquel Raynal
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

ieee802154_xmit_error() is the right helper to call when a transmission
has failed. Let's use it instead of open-coding it.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/net/ieee802154/at86rf230.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index ee75505477e8..a39d314fff7e 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -343,8 +343,7 @@ at86rf230_async_error_recover_complete(void *context)
 	if (ctx->free)
 		kfree(ctx);
 
-	ieee802154_wake_queue(lp->hw);
-	dev_kfree_skb_any(lp->tx_skb);
+	ieee802154_xmit_error(lp->hw, lp->tx_skb, false);
 }
 
 static void
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 04/14] net: ieee802154: atusb: Call _xmit_error() when a transmission fails
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (2 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 03/14] net: ieee802154: at86rf230: Call _xmit_error() when a transmission fails Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 05/14] net: ieee802154: ca8210: " Miquel Raynal
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

ieee802154_xmit_error() is the right helper to call when a transmission
has failed. Let's use it instead of open-coding it.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/net/ieee802154/atusb.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
index 1a56073c1c52..c9664a57e2f0 100644
--- a/drivers/net/ieee802154/atusb.c
+++ b/drivers/net/ieee802154/atusb.c
@@ -271,9 +271,7 @@ static void atusb_tx_done(struct atusb *atusb, u8 seq)
 		 * unlikely case now that seq == expect is then true, but can
 		 * happen and fail with a tx_skb = NULL;
 		 */
-		ieee802154_wake_queue(atusb->hw);
-		if (atusb->tx_skb)
-			dev_kfree_skb_irq(atusb->tx_skb);
+		ieee802154_xmit_error(atusb->hw, atusb->tx_skb, false);
 	}
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 05/14] net: ieee802154: ca8210: Call _xmit_error() when a transmission fails
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (3 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 04/14] net: ieee802154: atusb: " Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 06/14] net: mac802154: Stop exporting ieee802154_wake/stop_queue() Miquel Raynal
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

ieee802154_xmit_error() is the right helper to call when a transmission
has failed. Let's use it instead of open-coding it.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/net/ieee802154/ca8210.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c
index 91456c5e5691..2830e6fdd0fd 100644
--- a/drivers/net/ieee802154/ca8210.c
+++ b/drivers/net/ieee802154/ca8210.c
@@ -1765,17 +1765,19 @@ static int ca8210_async_xmit_complete(
 	priv->nextmsduhandle++;
 
 	if (status) {
+		bool ifs_handling =
+			status == MAC_TRANSACTION_OVERFLOW ? true : false;
+
 		dev_err(
 			&priv->spi->dev,
 			"Link transmission unsuccessful, status = %d\n",
 			status
 		);
-		if (status != MAC_TRANSACTION_OVERFLOW) {
-			ieee802154_wake_queue(priv->hw);
-			dev_kfree_skb_any(atusb->tx_skb);
-			return 0;
-		}
+
+		ieee802154_xmit_error(priv->hw, priv->tx_skb, ifs_handling);
+		return 0;
 	}
+
 	ieee802154_xmit_complete(priv->hw, priv->tx_skb, true);
 
 	return 0;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 06/14] net: mac802154: Stop exporting ieee802154_wake/stop_queue()
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (4 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 05/14] net: ieee802154: ca8210: " Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 07/14] net: mac802154: Rename the synchronous xmit worker Miquel Raynal
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

Individual drivers do not necessarily need to call these helpers
manually. There are other functions, more suited for this purpose, that
will do that for them. The advantage is that, as no more drivers call
these, it eases the tracking of the ongoing transfers that we are about
to introduce while keeping the possibility to bypass thse counters from
core code.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/mac802154.h      | 27 ---------------------------
 net/mac802154/ieee802154_i.h | 24 ++++++++++++++++++++++++
 net/mac802154/util.c         |  2 --
 3 files changed, 24 insertions(+), 29 deletions(-)

diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index e7443e1acde8..9e2e2b2cd65e 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -460,33 +460,6 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw);
  */
 void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb,
 			   u8 lqi);
-/**
- * ieee802154_wake_queue - wake ieee802154 queue
- * @hw: pointer as obtained from ieee802154_alloc_hw().
- *
- * Tranceivers have either one transmit framebuffer or one framebuffer for both
- * transmitting and receiving. Hence, the core only handles one frame at a time
- * for each phy, which means we had to stop the queue to avoid new skb to come
- * during the transmission. The queue then needs to be woken up after the
- * operation.
- *
- * Drivers should use this function instead of netif_wake_queue.
- */
-void ieee802154_wake_queue(struct ieee802154_hw *hw);
-
-/**
- * ieee802154_stop_queue - stop ieee802154 queue
- * @hw: pointer as obtained from ieee802154_alloc_hw().
- *
- * Tranceivers have either one transmit framebuffer or one framebuffer for both
- * transmitting and receiving. Hence, the core only handles one frame at a time
- * for each phy, which means we need to tell upper layers to stop giving us new
- * skbs while we are busy with the transmitted one. The queue must then be
- * stopped before transmitting.
- *
- * Drivers should use this function instead of netif_stop_queue.
- */
-void ieee802154_stop_queue(struct ieee802154_hw *hw);
 
 /**
  * ieee802154_xmit_complete - frame transmission complete
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 702560acc8ce..97b66088532b 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -128,6 +128,30 @@ 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);
 
+/**
+ * ieee802154_wake_queue - wake ieee802154 queue
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ *
+ * Tranceivers have either one transmit framebuffer or one framebuffer for both
+ * transmitting and receiving. Hence, the core only handles one frame at a time
+ * for each phy, which means we had to stop the queue to avoid new skb to come
+ * during the transmission. The queue then needs to be woken up after the
+ * operation.
+ */
+void ieee802154_wake_queue(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_stop_queue - stop ieee802154 queue
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ *
+ * Tranceivers have either one transmit framebuffer or one framebuffer for both
+ * transmitting and receiving. Hence, the core only handles one frame at a time
+ * for each phy, which means we need to tell upper layers to stop giving us new
+ * skbs while we are busy with the transmitted one. The queue must then be
+ * stopped before transmitting.
+ */
+void ieee802154_stop_queue(struct ieee802154_hw *hw);
+
 /* MIB callbacks */
 void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan);
 
diff --git a/net/mac802154/util.c b/net/mac802154/util.c
index 8e7e4cf16fc3..a5424b559239 100644
--- a/net/mac802154/util.c
+++ b/net/mac802154/util.c
@@ -27,7 +27,6 @@ void ieee802154_wake_queue(struct ieee802154_hw *hw)
 	}
 	rcu_read_unlock();
 }
-EXPORT_SYMBOL(ieee802154_wake_queue);
 
 void ieee802154_stop_queue(struct ieee802154_hw *hw)
 {
@@ -43,7 +42,6 @@ void ieee802154_stop_queue(struct ieee802154_hw *hw)
 	}
 	rcu_read_unlock();
 }
-EXPORT_SYMBOL(ieee802154_stop_queue);
 
 enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer)
 {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 07/14] net: mac802154: Rename the synchronous xmit worker
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (5 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 06/14] net: mac802154: Stop exporting ieee802154_wake/stop_queue() Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 08/14] net: mac802154: Rename the main tx_work struct Miquel Raynal
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

There are currently two driver hooks: one is synchronous, the other is
not. We cannot rely on driver implementations to provide a synchronous
API (which is related to the bus medium more than a wish to have a
synchronized implementation) so we are going to introduce a sync API
above any kind of driver transmit function. In order to clarify what
this worker is for (synchronous driver implementation), let's rename it
so that people don't get bothered by the fact that their driver does not
make use of the "xmit worker" which is a too generic name.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/mac802154/ieee802154_i.h | 2 +-
 net/mac802154/main.c         | 2 +-
 net/mac802154/tx.c           | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 97b66088532b..b4882b2d7688 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -121,7 +121,7 @@ ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata)
 extern struct ieee802154_mlme_ops mac802154_mlme_wpan;
 
 void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb);
-void ieee802154_xmit_worker(struct work_struct *work);
+void ieee802154_xmit_sync_worker(struct work_struct *work);
 netdev_tx_t
 ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
 netdev_tx_t
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index f08c34c27ea9..bfd7c431cdea 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -95,7 +95,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 
 	skb_queue_head_init(&local->skb_queue);
 
-	INIT_WORK(&local->tx_work, ieee802154_xmit_worker);
+	INIT_WORK(&local->tx_work, ieee802154_xmit_sync_worker);
 
 	/* init supported flags with 802.15.4 default ranges */
 	phy->supported.max_minbe = 8;
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index c829e4a75325..97df5985b830 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -22,7 +22,7 @@
 #include "ieee802154_i.h"
 #include "driver-ops.h"
 
-void ieee802154_xmit_worker(struct work_struct *work)
+void ieee802154_xmit_sync_worker(struct work_struct *work)
 {
 	struct ieee802154_local *local =
 		container_of(work, struct ieee802154_local, tx_work);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 08/14] net: mac802154: Rename the main tx_work struct
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (6 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 07/14] net: mac802154: Rename the synchronous xmit worker Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 09/14] net: mac802154: Follow the count of ongoing transmissions Miquel Raynal
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

This entry is dedicated to synchronous transmissions done by drivers
without async hook. Make this clearer that this is not a work that any
driver can use by at least prefixing it with "sync_". While at it, let's
enhance the comment explaining why we choose one or the other.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/mac802154/ieee802154_i.h | 2 +-
 net/mac802154/main.c         | 2 +-
 net/mac802154/tx.c           | 9 ++++++---
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index b4882b2d7688..18d1f6804810 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -55,7 +55,7 @@ struct ieee802154_local {
 	struct sk_buff_head skb_queue;
 
 	struct sk_buff *tx_skb;
-	struct work_struct tx_work;
+	struct work_struct sync_tx_work;
 };
 
 enum {
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index bfd7c431cdea..0023c6e80725 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -95,7 +95,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 
 	skb_queue_head_init(&local->skb_queue);
 
-	INIT_WORK(&local->tx_work, ieee802154_xmit_sync_worker);
+	INIT_WORK(&local->sync_tx_work, ieee802154_xmit_sync_worker);
 
 	/* init supported flags with 802.15.4 default ranges */
 	phy->supported.max_minbe = 8;
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 97df5985b830..a01689ddd547 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -25,7 +25,7 @@
 void ieee802154_xmit_sync_worker(struct work_struct *work)
 {
 	struct ieee802154_local *local =
-		container_of(work, struct ieee802154_local, tx_work);
+		container_of(work, struct ieee802154_local, sync_tx_work);
 	struct sk_buff *skb = local->tx_skb;
 	struct net_device *dev = skb->dev;
 	int res;
@@ -76,7 +76,10 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
 	/* Stop the netif queue on each sub_if_data object. */
 	ieee802154_stop_queue(&local->hw);
 
-	/* async is priority, otherwise sync is fallback */
+	/* Drivers should preferably implement the async callback. In some rare
+	 * cases they only provide a sync callback which we will use as a
+	 * fallback.
+	 */
 	if (local->ops->xmit_async) {
 		unsigned int len = skb->len;
 
@@ -90,7 +93,7 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
 		dev->stats.tx_bytes += len;
 	} else {
 		local->tx_skb = skb;
-		queue_work(local->workqueue, &local->tx_work);
+		queue_work(local->workqueue, &local->sync_tx_work);
 	}
 
 	return NETDEV_TX_OK;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 09/14] net: mac802154: Follow the count of ongoing transmissions
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (7 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 08/14] net: mac802154: Rename the main tx_work struct Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 10/14] net: mac802154: Hold the transmit queue when relevant Miquel Raynal
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

In order to create a synchronous API for MLME command purposes, we need
to be able to track the end of the ongoing transmissions. Let's
introduce an atomic variable which is incremented and decremented when
relevant and now at any moment if a there is an ongoing transmission.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/cfg802154.h | 3 +++
 net/mac802154/tx.c      | 3 +++
 net/mac802154/util.c    | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 0b8b1812cea1..969cae56b000 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -283,6 +283,9 @@ struct wpan_phy {
 	/* the network namespace this phy lives in currently */
 	possible_net_t _net;
 
+	/* Transmission monitoring */
+	atomic_t ongoing_txs;
+
 	char priv[] __aligned(NETDEV_ALIGN);
 };
 
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index a01689ddd547..731e86bfe73f 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -45,6 +45,7 @@ void ieee802154_xmit_sync_worker(struct work_struct *work)
 	/* Restart the netif queue on each sub_if_data object. */
 	ieee802154_wake_queue(&local->hw);
 	kfree_skb(skb);
+	atomic_dec(&local->phy->ongoing_txs);
 	netdev_dbg(dev, "transmission failed\n");
 }
 
@@ -80,6 +81,7 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
 	 * cases they only provide a sync callback which we will use as a
 	 * fallback.
 	 */
+	atomic_inc(&local->phy->ongoing_txs);
 	if (local->ops->xmit_async) {
 		unsigned int len = skb->len;
 
@@ -99,6 +101,7 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
 	return NETDEV_TX_OK;
 
 err_tx:
+	atomic_dec(&local->phy->ongoing_txs);
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
 }
diff --git a/net/mac802154/util.c b/net/mac802154/util.c
index a5424b559239..ae405d995868 100644
--- a/net/mac802154/util.c
+++ b/net/mac802154/util.c
@@ -89,6 +89,7 @@ void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
 {
 	ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
 	dev_consume_skb_any(skb);
+	atomic_dec(&hw->phy->ongoing_txs);
 }
 EXPORT_SYMBOL(ieee802154_xmit_complete);
 
@@ -98,6 +99,7 @@ void ieee802154_xmit_error(struct ieee802154_hw *hw, struct sk_buff *skb,
 {
 	ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
 	dev_kfree_skb_any(skb);
+	atomic_dec(&hw->phy->ongoing_txs);
 }
 EXPORT_SYMBOL(ieee802154_xmit_error);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 10/14] net: mac802154: Hold the transmit queue when relevant
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (8 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 09/14] net: mac802154: Follow the count of ongoing transmissions Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 11/14] net: mac802154: Create a hot tx path Miquel Raynal
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

Let's create a hold_txs atomic variable and increment/decrement it when
relevant. A current use is during a suspend. Very soon we will also use
this feature during scans.

When the variable is incremented, any further call to helpers usually
waking up the queue will skip this part because it is the core
responsibility to wake up the queue when relevant.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/cfg802154.h      |  3 ++-
 net/mac802154/cfg.c          |  4 +++-
 net/mac802154/ieee802154_i.h |  5 +++++
 net/mac802154/tx.c           |  7 +++++--
 net/mac802154/util.c         | 14 ++++++++++++--
 5 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 969cae56b000..56aa672e1912 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -283,8 +283,9 @@ struct wpan_phy {
 	/* the network namespace this phy lives in currently */
 	possible_net_t _net;
 
-	/* Transmission monitoring */
+	/* Transmission monitoring and control */
 	atomic_t ongoing_txs;
+	atomic_t hold_txs;
 
 	char priv[] __aligned(NETDEV_ALIGN);
 };
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index 1e4a9f74ed43..e8aabf215286 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -46,6 +46,7 @@ static int ieee802154_suspend(struct wpan_phy *wpan_phy)
 	if (!local->open_count)
 		goto suspend;
 
+	atomic_inc(&wpan_phy->hold_txs);
 	ieee802154_stop_queue(&local->hw);
 	synchronize_net();
 
@@ -72,7 +73,8 @@ static int ieee802154_resume(struct wpan_phy *wpan_phy)
 		return ret;
 
 wake_up:
-	ieee802154_wake_queue(&local->hw);
+	if (!atomic_dec_and_test(&wpan_phy->hold_txs))
+		ieee802154_wake_queue(&local->hw);
 	local->suspended = false;
 	return 0;
 }
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 18d1f6804810..0291e49058f2 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -190,6 +190,11 @@ void mac802154_unlock_table(struct net_device *dev);
 
 int mac802154_wpan_update_llsec(struct net_device *dev);
 
+static inline bool mac802154_queue_is_stopped(struct ieee802154_local *local)
+{
+	return atomic_read(&local->phy->hold_txs);
+}
+
 /* interface handling */
 int ieee802154_iface_init(void);
 void ieee802154_iface_exit(void);
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 731e86bfe73f..a8d4d5e175b6 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -43,7 +43,9 @@ void ieee802154_xmit_sync_worker(struct work_struct *work)
 
 err_tx:
 	/* Restart the netif queue on each sub_if_data object. */
-	ieee802154_wake_queue(&local->hw);
+	if (!mac802154_queue_is_stopped(local))
+		ieee802154_wake_queue(&local->hw);
+
 	kfree_skb(skb);
 	atomic_dec(&local->phy->ongoing_txs);
 	netdev_dbg(dev, "transmission failed\n");
@@ -87,7 +89,8 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
 
 		ret = drv_xmit_async(local, skb);
 		if (ret) {
-			ieee802154_wake_queue(&local->hw);
+			if (!mac802154_queue_is_stopped(local))
+				ieee802154_wake_queue(&local->hw);
 			goto err_tx;
 		}
 
diff --git a/net/mac802154/util.c b/net/mac802154/util.c
index ae405d995868..e9c8542cfec6 100644
--- a/net/mac802154/util.c
+++ b/net/mac802154/util.c
@@ -87,7 +87,12 @@ ieee802154_wakeup_after_xmit_done(struct ieee802154_hw *hw, struct sk_buff *skb,
 void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
 			      bool ifs_handling)
 {
-	ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
+	struct ieee802154_local *local = hw_to_local(hw);
+
+	/* Avoid waking-up a queue which needs to remain stopped */
+	if (!mac802154_queue_is_stopped(local))
+		ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
+
 	dev_consume_skb_any(skb);
 	atomic_dec(&hw->phy->ongoing_txs);
 }
@@ -97,7 +102,12 @@ EXPORT_SYMBOL(ieee802154_xmit_complete);
 void ieee802154_xmit_error(struct ieee802154_hw *hw, struct sk_buff *skb,
 			   bool ifs_handling)
 {
-	ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
+	struct ieee802154_local *local = hw_to_local(hw);
+
+	/* Avoid waking-up a queue which needs to remain stopped */
+	if (!mac802154_queue_is_stopped(local))
+		ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
+
 	dev_kfree_skb_any(skb);
 	atomic_dec(&hw->phy->ongoing_txs);
 }
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 11/14] net: mac802154: Create a hot tx path
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (9 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 10/14] net: mac802154: Hold the transmit queue when relevant Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 12/14] net: mac802154: Add a warning in the hot path Miquel Raynal
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

Let's rename the current tx path to show that this is the "hot" path. We
will soon introduce a slower path for MLME commands.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/mac802154/tx.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index a8d4d5e175b6..18ee6fcfcd7f 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -109,6 +109,12 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
 	return NETDEV_TX_OK;
 }
 
+static netdev_tx_t
+ieee802154_hot_tx(struct ieee802154_local *local, struct sk_buff *skb)
+{
+	return ieee802154_tx(local, skb);
+}
+
 netdev_tx_t
 ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
@@ -116,7 +122,7 @@ ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	skb->skb_iif = dev->ifindex;
 
-	return ieee802154_tx(sdata->local, skb);
+	return ieee802154_hot_tx(sdata->local, skb);
 }
 
 netdev_tx_t
@@ -138,5 +144,5 @@ ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	skb->skb_iif = dev->ifindex;
 
-	return ieee802154_tx(sdata->local, skb);
+	return ieee802154_hot_tx(sdata->local, skb);
 }
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 12/14] net: mac802154: Add a warning in the hot path
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (10 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 11/14] net: mac802154: Create a hot tx path Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 13/14] net: mac802154: Introduce a tx queue flushing mechanism Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 14/14] net: mac802154: Introduce a synchronous API for MLME commands Miquel Raynal
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

We should never start a transmission after the queue has been stopped.

But because it might work we don't kill the function here but rather
warn loudly the user that something is wrong.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/mac802154/tx.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 18ee6fcfcd7f..abd9a057521e 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -112,6 +112,8 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
 static netdev_tx_t
 ieee802154_hot_tx(struct ieee802154_local *local, struct sk_buff *skb)
 {
+	WARN_ON_ONCE(mac802154_queue_is_stopped(local));
+
 	return ieee802154_tx(local, skb);
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 13/14] net: mac802154: Introduce a tx queue flushing mechanism
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (11 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 12/14] net: mac802154: Add a warning in the hot path Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  2022-01-20  0:51 ` [wpan-next 14/14] net: mac802154: Introduce a synchronous API for MLME commands Miquel Raynal
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

Right now we are able to stop a queue but we have no indication if a
transmission is ongoing or not.

Thanks to recent additions, we can track the number of ongoing
transmissions so we know if the last transmission is over. Adding on top
of it an internal wait queue also allows to be woken up asynchronously
when this happens. If, beforehands, we marked the queue to be held and
stopped it, we end up flushing and stopping the tx queue.

Thanks to this feature, we will soon be able to introduce a synchronous
transmit API.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/cfg802154.h      |  1 +
 net/ieee802154/core.c        |  1 +
 net/mac802154/cfg.c          |  5 ++---
 net/mac802154/ieee802154_i.h |  1 +
 net/mac802154/tx.c           | 11 ++++++++++-
 net/mac802154/util.c         |  3 ++-
 6 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 56aa672e1912..0848896120fa 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -286,6 +286,7 @@ struct wpan_phy {
 	/* Transmission monitoring and control */
 	atomic_t ongoing_txs;
 	atomic_t hold_txs;
+	wait_queue_head_t sync_txq;
 
 	char priv[] __aligned(NETDEV_ALIGN);
 };
diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c
index de259b5170ab..0953cacafbff 100644
--- a/net/ieee802154/core.c
+++ b/net/ieee802154/core.c
@@ -129,6 +129,7 @@ wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size)
 	wpan_phy_net_set(&rdev->wpan_phy, &init_net);
 
 	init_waitqueue_head(&rdev->dev_wait);
+	init_waitqueue_head(&rdev->wpan_phy.sync_txq);
 
 	return &rdev->wpan_phy;
 }
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index e8aabf215286..da94aaa32fcb 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -46,8 +46,7 @@ static int ieee802154_suspend(struct wpan_phy *wpan_phy)
 	if (!local->open_count)
 		goto suspend;
 
-	atomic_inc(&wpan_phy->hold_txs);
-	ieee802154_stop_queue(&local->hw);
+	ieee802154_sync_and_stop_tx(local);
 	synchronize_net();
 
 	/* stop hardware - this must stop RX */
@@ -73,7 +72,7 @@ static int ieee802154_resume(struct wpan_phy *wpan_phy)
 		return ret;
 
 wake_up:
-	if (!atomic_dec_and_test(&wpan_phy->hold_txs))
+	if (!atomic_read(&wpan_phy->hold_txs))
 		ieee802154_wake_queue(&local->hw);
 	local->suspended = false;
 	return 0;
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 0291e49058f2..d9433e07906e 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -122,6 +122,7 @@ extern struct ieee802154_mlme_ops mac802154_mlme_wpan;
 
 void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb);
 void ieee802154_xmit_sync_worker(struct work_struct *work);
+void ieee802154_sync_and_stop_tx(struct ieee802154_local *local);
 netdev_tx_t
 ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
 netdev_tx_t
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index abd9a057521e..06ae2e6cea43 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -47,7 +47,8 @@ void ieee802154_xmit_sync_worker(struct work_struct *work)
 		ieee802154_wake_queue(&local->hw);
 
 	kfree_skb(skb);
-	atomic_dec(&local->phy->ongoing_txs);
+	if (!atomic_dec_and_test(&local->phy->ongoing_txs))
+		wake_up(&local->phy->sync_txq);
 	netdev_dbg(dev, "transmission failed\n");
 }
 
@@ -117,6 +118,14 @@ ieee802154_hot_tx(struct ieee802154_local *local, struct sk_buff *skb)
 	return ieee802154_tx(local, skb);
 }
 
+void ieee802154_sync_and_stop_tx(struct ieee802154_local *local)
+{
+	atomic_inc(&local->phy->hold_txs);
+	ieee802154_stop_queue(&local->hw);
+	wait_event(local->phy->sync_txq, !atomic_read(&local->phy->ongoing_txs));
+	atomic_dec(&local->phy->hold_txs);
+}
+
 netdev_tx_t
 ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
diff --git a/net/mac802154/util.c b/net/mac802154/util.c
index e9c8542cfec6..949c5035cb07 100644
--- a/net/mac802154/util.c
+++ b/net/mac802154/util.c
@@ -94,7 +94,8 @@ void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
 		ieee802154_wakeup_after_xmit_done(hw, skb, ifs_handling);
 
 	dev_consume_skb_any(skb);
-	atomic_dec(&hw->phy->ongoing_txs);
+	if (!atomic_dec_and_test(&hw->phy->ongoing_txs))
+		wake_up(&hw->phy->sync_txq);
 }
 EXPORT_SYMBOL(ieee802154_xmit_complete);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [wpan-next 14/14] net: mac802154: Introduce a synchronous API for MLME commands
  2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
                   ` (12 preceding siblings ...)
  2022-01-20  0:51 ` [wpan-next 13/14] net: mac802154: Introduce a tx queue flushing mechanism Miquel Raynal
@ 2022-01-20  0:51 ` Miquel Raynal
  13 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2022-01-20  0:51 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, netdev, linux-wireless,
	David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Thomas Petazzoni, Miquel Raynal

This is the slow path, we need to wait for each command to be processed
before continuing so let's introduce an helper which does the
transmission and blocks until it gets notified of its asynchronous
completion. This helper is going to be used when introducing scan
support.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/mac802154/ieee802154_i.h | 1 +
 net/mac802154/tx.c           | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index d9433e07906e..bdec3b9229e4 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -123,6 +123,7 @@ extern struct ieee802154_mlme_ops mac802154_mlme_wpan;
 void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb);
 void ieee802154_xmit_sync_worker(struct work_struct *work);
 void ieee802154_sync_and_stop_tx(struct ieee802154_local *local);
+void ieee802154_mlme_tx(struct ieee802154_local *local, struct sk_buff *skb);
 netdev_tx_t
 ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
 netdev_tx_t
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 06ae2e6cea43..7c281458942e 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -126,6 +126,12 @@ void ieee802154_sync_and_stop_tx(struct ieee802154_local *local)
 	atomic_dec(&local->phy->hold_txs);
 }
 
+void ieee802154_mlme_tx(struct ieee802154_local *local, struct sk_buff *skb)
+{
+	ieee802154_tx(local, skb);
+	ieee802154_sync_and_stop_tx(local);
+}
+
 netdev_tx_t
 ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-01-20  0:51 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-20  0:51 [wpan-next 00/14] ieee802154: Synchronous Tx API Miquel Raynal
2022-01-20  0:51 ` [wpan-next 01/14] net: ieee802154: Move the logic restarting the queue upon transmission Miquel Raynal
2022-01-20  0:51 ` [wpan-next 02/14] net: mac802154: Create a transmit error helper Miquel Raynal
2022-01-20  0:51 ` [wpan-next 03/14] net: ieee802154: at86rf230: Call _xmit_error() when a transmission fails Miquel Raynal
2022-01-20  0:51 ` [wpan-next 04/14] net: ieee802154: atusb: " Miquel Raynal
2022-01-20  0:51 ` [wpan-next 05/14] net: ieee802154: ca8210: " Miquel Raynal
2022-01-20  0:51 ` [wpan-next 06/14] net: mac802154: Stop exporting ieee802154_wake/stop_queue() Miquel Raynal
2022-01-20  0:51 ` [wpan-next 07/14] net: mac802154: Rename the synchronous xmit worker Miquel Raynal
2022-01-20  0:51 ` [wpan-next 08/14] net: mac802154: Rename the main tx_work struct Miquel Raynal
2022-01-20  0:51 ` [wpan-next 09/14] net: mac802154: Follow the count of ongoing transmissions Miquel Raynal
2022-01-20  0:51 ` [wpan-next 10/14] net: mac802154: Hold the transmit queue when relevant Miquel Raynal
2022-01-20  0:51 ` [wpan-next 11/14] net: mac802154: Create a hot tx path Miquel Raynal
2022-01-20  0:51 ` [wpan-next 12/14] net: mac802154: Add a warning in the hot path Miquel Raynal
2022-01-20  0:51 ` [wpan-next 13/14] net: mac802154: Introduce a tx queue flushing mechanism Miquel Raynal
2022-01-20  0:51 ` [wpan-next 14/14] net: mac802154: Introduce a synchronous API for MLME commands Miquel Raynal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).