u32 link_id;
 };
 
+/**
+ * struct cfg80211_ttlm_params: TID to link mapping parameters
+ *
+ * Used for setting a TID to link mapping.
+ *
+ * @dlink: Downlink TID to link mapping, as defined in section 9.4.2.314
+ *     (TID-To-Link Mapping element) in Draft P802.11be_D4.0.
+ * @ulink: Uplink TID to link mapping, as defined in section 9.4.2.314
+ *     (TID-To-Link Mapping element) in Draft P802.11be_D4.0.
+ */
+struct cfg80211_ttlm_params {
+       u16 dlink[8];
+       u16 ulink[8];
+};
+
 /**
  * struct station_parameters - station parameters
  *
  * @del_link_station: Remove a link of a station.
  *
  * @set_hw_timestamp: Enable/disable HW timestamping of TM/FTM frames.
+ * @set_ttlm: set the TID to link mapping.
  */
 struct cfg80211_ops {
        int     (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
                                    struct link_station_del_parameters *params);
        int     (*set_hw_timestamp)(struct wiphy *wiphy, struct net_device *dev,
                                    struct cfg80211_set_hw_timestamp *hwts);
+       int     (*set_ttlm)(struct wiphy *wiphy, struct net_device *dev,
+                           struct cfg80211_ttlm_params *params);
 };
 
 /*
 
  *     Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide
  *     information about the removed STA MLD setup links.
  *
+ * @NL80211_CMD_SET_TID_TO_LINK_MAPPING: Set the TID to Link Mapping for a
+ *      non-AP MLD station. The %NL80211_ATTR_MLO_TTLM_DLINK and
+ *      %NL80211_ATTR_MLO_TTLM_ULINK attributes are used to specify the
+ *      TID to Link mapping for downlink/uplink traffic.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
 
        NL80211_CMD_LINKS_REMOVED,
 
+       NL80211_CMD_SET_TID_TO_LINK_MAPPING,
+
        /* add new commands above here */
 
        /* used to define NL80211_CMD_MAX below */
  *     include BSSes that can only be used in restricted scenarios and/or
  *     cannot be used at all.
  *
+ * @NL80211_ATTR_MLO_TTLM_DLINK: Binary attribute specifying the downlink TID to
+ *      link mapping. The length is 8 * sizeof(u16). For each TID the link
+ *      mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
+ *      in Draft P802.11be_D4.0.
+ * @NL80211_ATTR_MLO_TTLM_ULINK: Binary attribute specifying the uplink TID to
+ *      link mapping. The length is 8 * sizeof(u16). For each TID the link
+ *      mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
+ *      in Draft P802.11be_D4.0.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
 
        NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA,
 
+       NL80211_ATTR_MLO_TTLM_DLINK,
+       NL80211_ATTR_MLO_TTLM_ULINK,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
 
        [NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
        [NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG },
        [NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA] = { .type = NLA_FLAG },
+       [NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
+       [NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
 };
 
 /* policy for the key attributes */
        return rdev_set_hw_timestamp(rdev, dev, &hwts);
 }
 
+static int
+nl80211_set_ttlm(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_ttlm_params params = {};
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       if (wdev->iftype != NL80211_IFTYPE_STATION &&
+           wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+               return -EOPNOTSUPP;
+
+       if (!wdev->connected)
+               return -ENOLINK;
+
+       if (!info->attrs[NL80211_ATTR_MLO_TTLM_DLINK] ||
+           !info->attrs[NL80211_ATTR_MLO_TTLM_ULINK])
+               return -EINVAL;
+
+       nla_memcpy(params.dlink,
+                  info->attrs[NL80211_ATTR_MLO_TTLM_DLINK],
+                  sizeof(params.dlink));
+       nla_memcpy(params.ulink,
+                  info->attrs[NL80211_ATTR_MLO_TTLM_ULINK],
+                  sizeof(params.ulink));
+
+       return rdev_set_ttlm(rdev, dev, ¶ms);
+}
+
 #define NL80211_FLAG_NEED_WIPHY                0x01
 #define NL80211_FLAG_NEED_NETDEV       0x02
 #define NL80211_FLAG_NEED_RTNL         0x04
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
        },
+       {
+               .cmd = NL80211_CMD_SET_TID_TO_LINK_MAPPING,
+               .doit = nl80211_set_ttlm,
+               .flags = GENL_UNS_ADMIN_PERM,
+               .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+       },
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {
 
 
        return ret;
 }
+
+static inline int
+rdev_set_ttlm(struct cfg80211_registered_device *rdev,
+             struct net_device *dev,
+             struct cfg80211_ttlm_params *params)
+{
+       struct wiphy *wiphy = &rdev->wiphy;
+       int ret;
+
+       if (!rdev->ops->set_ttlm)
+               return -EOPNOTSUPP;
+
+       trace_rdev_set_ttlm(wiphy, dev, params);
+       ret = rdev->ops->set_ttlm(wiphy, dev, params);
+       trace_rdev_return_int(wiphy, ret);
+
+       return ret;
+}
 #endif /* __CFG80211_RDEV_OPS */
 
                  __entry->link_mask)
 );
 
+TRACE_EVENT(rdev_set_ttlm,
+       TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+                struct cfg80211_ttlm_params *params),
+       TP_ARGS(wiphy, netdev, params),
+       TP_STRUCT__entry(
+               WIPHY_ENTRY
+               NETDEV_ENTRY
+               __array(u8, dlink, sizeof(u16) * 8)
+               __array(u8, ulink, sizeof(u16) * 8)
+       ),
+       TP_fast_assign(
+               WIPHY_ASSIGN;
+               NETDEV_ASSIGN;
+               memcpy(__entry->dlink, params->dlink, sizeof(params->dlink));
+               memcpy(__entry->ulink, params->ulink, sizeof(params->ulink));
+       ),
+       TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
+                 WIPHY_PR_ARG, NETDEV_PR_ARG)
+);
+
 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH