summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2022-07-18 12:13:46 +0200
committerJohannes Berg <johannes.berg@intel.com>2022-07-22 14:28:33 +0200
commit95f498bb49f7030c1f40236107e5241e50f79ade (patch)
treedb02699411bf2d85d705e3a01cc96701d471469c
parent2ec833a5aafc49142a9b2988a3225ebfa47ccd27 (diff)
wifi: nl80211: add MLO link ID to the NL80211_CMD_FRAME TX API
Allow optionally specifying the link ID to transmit on, which can be done instead of the link frequency, on an MLD addressed frame. Both can also be omitted in which case the frame must be MLD addressed and link selection (and address translation) will be done on lower layers. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h4
-rw-r--r--include/uapi/linux/nl80211.h4
-rw-r--r--net/wireless/nl80211.c12
3 files changed, 20 insertions, 0 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8545ed098d90..908d58393484 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3411,6 +3411,9 @@ struct cfg80211_update_ft_ies_params {
* @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;
@@ -3422,6 +3425,7 @@ struct cfg80211_mgmt_tx_params {
bool dont_wait_for_ack;
int n_csa_offsets;
const u16 *csa_offsets;
+ int link_id;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 5275dcbc5ee8..ffb7c573e299 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -764,6 +764,10 @@
* %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.
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 60b8406b8d7e..2705e3ee8fc4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12256,6 +12256,18 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
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]);