@@ -141,10 +141,16 @@ int ieee802154_mlme_op_pre(struct ieee802154_local *local);
int ieee802154_mlme_tx(struct ieee802154_local *local,
struct ieee802154_sub_if_data *sdata,
struct sk_buff *skb);
+int ieee802154_mlme_tx_locked(struct ieee802154_local *local,
+ struct ieee802154_sub_if_data *sdata,
+ struct sk_buff *skb);
void ieee802154_mlme_op_post(struct ieee802154_local *local);
int ieee802154_mlme_tx_one(struct ieee802154_local *local,
struct ieee802154_sub_if_data *sdata,
struct sk_buff *skb);
+int ieee802154_mlme_tx_one_locked(struct ieee802154_local *local,
+ struct ieee802154_sub_if_data *sdata,
+ struct sk_buff *skb);
netdev_tx_t
ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
netdev_tx_t
@@ -137,34 +137,37 @@ int ieee802154_mlme_op_pre(struct ieee802154_local *local)
return ieee802154_sync_and_hold_queue(local);
}
-int ieee802154_mlme_tx(struct ieee802154_local *local,
- struct ieee802154_sub_if_data *sdata,
- struct sk_buff *skb)
+int ieee802154_mlme_tx_locked(struct ieee802154_local *local,
+ struct ieee802154_sub_if_data *sdata,
+ struct sk_buff *skb)
{
- int ret;
-
/* Avoid possible calls to ->ndo_stop() when we asynchronously perform
* MLME transmissions.
*/
- rtnl_lock();
+ ASSERT_RTNL();
/* Ensure the device was not stopped, otherwise error out */
- if (!local->open_count) {
- rtnl_unlock();
+ if (!local->open_count)
return -ENETDOWN;
- }
/* Warn if the ieee802154 core thinks MLME frames can be sent while the
* net interface expects this cannot happen.
*/
- if (WARN_ON_ONCE(!netif_running(sdata->dev))) {
- rtnl_unlock();
+ if (WARN_ON_ONCE(!netif_running(sdata->dev)))
return -ENETDOWN;
- }
ieee802154_tx(local, skb);
- ret = ieee802154_sync_queue(local);
+ return ieee802154_sync_queue(local);
+}
+int ieee802154_mlme_tx(struct ieee802154_local *local,
+ struct ieee802154_sub_if_data *sdata,
+ struct sk_buff *skb)
+{
+ int ret;
+
+ rtnl_lock();
+ ret = ieee802154_mlme_tx_locked(local, sdata, skb);
rtnl_unlock();
return ret;
@@ -188,6 +191,19 @@ int ieee802154_mlme_tx_one(struct ieee802154_local *local,
return ret;
}
+int ieee802154_mlme_tx_one_locked(struct ieee802154_local *local,
+ struct ieee802154_sub_if_data *sdata,
+ struct sk_buff *skb)
+{
+ int ret;
+
+ ieee802154_mlme_op_pre(local);
+ ret = ieee802154_mlme_tx_locked(local, sdata, skb);
+ ieee802154_mlme_op_post(local);
+
+ return ret;
+}
+
static bool ieee802154_queue_is_stopped(struct ieee802154_local *local)
{
return test_bit(WPAN_PHY_FLAG_STATE_QUEUE_STOPPED, &local->phy->flags);
These have the exact same behavior as before, except they expect the rtnl to be already taken (and will complain otherwise). This allows performing MLME transmissions from different contexts. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- net/mac802154/ieee802154_i.h | 6 ++++++ net/mac802154/tx.c | 42 +++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 13 deletions(-)