* @dont_wait_for_ack: tells the low level not to wait for an ack
  * @n_csa_offsets: length of csa_offsets array
  * @csa_offsets: array of all the csa offsets in the frame
+ * @link_id: for MLO, the link ID to transmit on, -1 if not given; note
+ *     that the link ID isn't validated (much), it's in range but the
+ *     link might not exist (or be used by the receiver STA)
  */
 struct cfg80211_mgmt_tx_params {
        struct ieee80211_channel *chan;
        bool dont_wait_for_ack;
        int n_csa_offsets;
        const u16 *csa_offsets;
+       int link_id;
 };
 
 /**
 
  *     %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA
  *     counters which will be updated to the current value. This attribute
  *     is used during CSA period.
+ *     For TX on an MLD, the frequency can be omitted and the link ID be
+ *     specified, or if transmitting to a known peer MLD (with MLD addresses
+ *     in the frame) both can be omitted and the link will be selected by
+ *     lower layers.
  *     For RX notification, %NL80211_ATTR_RX_HW_TIMESTAMP may be included to
  *     indicate the frame RX timestamp and %NL80211_ATTR_TX_HW_TIMESTAMP may
  *     be included to indicate the ack TX timestamp.
 
                wdev_unlock(wdev);
                return -EBUSY;
        }
+
+       params.link_id = nl80211_link_id_or_invalid(info->attrs);
+       /*
+        * This now races due to the unlock, but we cannot check
+        * the valid links for the _station_ anyway, so that's up
+        * to the driver.
+        */
+       if (params.link_id >= 0 &&
+           !(wdev->valid_links & BIT(params.link_id))) {
+               wdev_unlock(wdev);
+               return -EINVAL;
+       }
        wdev_unlock(wdev);
 
        params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);