enum ieee80211_smps_mode smps_mode,
                                    struct sk_buff *skb);
 u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef);
+u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef,
+                               const struct ieee80211_sta_eht_cap *eht_cap);
 int ieee80211_parse_bitrates(enum nl80211_chan_width width,
                             const struct ieee80211_supported_band *sband,
                             const u8 *srates, int srates_len, u32 *rates);
 
        ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info,
                                   ie->vht_operation, ie->ht_operation,
                                   &sta_chan_def);
-       ieee80211_chandef_he_6ghz_oper(sdata, ie->he_operation, NULL,
+       ieee80211_chandef_he_6ghz_oper(sdata, ie->he_operation, ie->eht_operation,
                                       &sta_chan_def);
 
        if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
        return 0;
 }
 
+int mesh_add_eht_cap_ie(struct ieee80211_sub_if_data *sdata,
+                       struct sk_buff *skb, u8 ie_len)
+{
+       const struct ieee80211_sta_he_cap *he_cap;
+       const struct ieee80211_sta_eht_cap *eht_cap;
+       struct ieee80211_supported_band *sband;
+       u8 *pos;
+
+       sband = ieee80211_get_sband(sdata);
+       if (!sband)
+               return -EINVAL;
+
+       he_cap = ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT);
+       eht_cap = ieee80211_get_eht_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT);
+       if (!he_cap || !eht_cap ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
+               return 0;
+
+       if (skb_tailroom(skb) < ie_len)
+               return -ENOMEM;
+
+       pos = skb_put(skb, ie_len);
+       ieee80211_ie_build_eht_cap(pos, he_cap, eht_cap, pos + ie_len, false);
+
+       return 0;
+}
+
+int mesh_add_eht_oper_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
+{
+       const struct ieee80211_sta_eht_cap *eht_cap;
+       struct ieee80211_supported_band *sband;
+       u32 len;
+       u8 *pos;
+
+       sband = ieee80211_get_sband(sdata);
+       if (!sband)
+               return -EINVAL;
+
+       eht_cap = ieee80211_get_eht_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT);
+       if (!eht_cap ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
+               return 0;
+
+       len = 2 + 1 + offsetof(struct ieee80211_eht_operation, optional) +
+                     offsetof(struct ieee80211_eht_operation_info, optional);
+
+       if (skb_tailroom(skb) < len)
+               return -ENOMEM;
+
+       pos = skb_put(skb, len);
+       ieee80211_ie_build_eht_oper(pos, &sdata->vif.bss_conf.chandef, eht_cap);
+
+       return 0;
+}
+
 static void ieee80211_mesh_path_timer(struct timer_list *t)
 {
        struct ieee80211_sub_if_data *sdata =
        if (he_oper)
                sdata->vif.bss_conf.he_oper.params =
                        __le32_to_cpu(he_oper->he_oper_params);
+
+       sdata->vif.bss_conf.eht_support =
+               !!ieee80211_get_eht_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT);
 }
 
 bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_chanctx_conf *chanctx_conf;
        struct mesh_csa_settings *csa;
        enum nl80211_band band;
-       u8 ie_len_he_cap;
+       u8 ie_len_he_cap, ie_len_eht_cap;
        u8 *pos;
        struct ieee80211_sub_if_data *sdata;
        int hdr_len = offsetofend(struct ieee80211_mgmt, u.beacon);
 
        ie_len_he_cap = ieee80211_ie_len_he_cap(sdata,
                                                NL80211_IFTYPE_MESH_POINT);
+       ie_len_eht_cap = ieee80211_ie_len_eht_cap(sdata,
+                                                 NL80211_IFTYPE_MESH_POINT);
        head_len = hdr_len +
                   2 + /* NULL SSID */
                   /* Channel Switch Announcement */
                   2 + 1 + sizeof(struct ieee80211_he_operation) +
                           sizeof(struct ieee80211_he_6ghz_oper) +
                   2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
+                  ie_len_eht_cap +
+                  2 + 1 + offsetof(struct ieee80211_eht_operation, optional) +
+                          offsetof(struct ieee80211_eht_operation_info, optional) +
                   ifmsh->ie_len;
 
        bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL);
            mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
            mesh_add_he_oper_ie(sdata, skb) ||
            mesh_add_he_6ghz_cap_ie(sdata, skb) ||
+           mesh_add_eht_cap_ie(sdata, skb, ie_len_eht_cap) ||
+           mesh_add_eht_oper_ie(sdata, skb) ||
            mesh_add_vendor_ies(sdata, skb))
                goto out_free;
 
 
                        struct sk_buff *skb);
 int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata,
                            struct sk_buff *skb);
+int mesh_add_eht_cap_ie(struct ieee80211_sub_if_data *sdata,
+                       struct sk_buff *skb, u8 ie_len);
+int mesh_add_eht_oper_ie(struct ieee80211_sub_if_data *sdata,
+                        struct sk_buff *skb);
 void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
 void ieee80211s_init(void);
 
        bool include_plid = false;
        u16 peering_proto = 0;
        u8 *pos, ie_len = 4;
-       u8 ie_len_he_cap;
+       u8 ie_len_he_cap, ie_len_eht_cap;
        int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot);
        int err = -ENOMEM;
 
        ie_len_he_cap = ieee80211_ie_len_he_cap(sdata,
                                                NL80211_IFTYPE_MESH_POINT);
+       ie_len_eht_cap = ieee80211_ie_len_eht_cap(sdata,
+                                                 NL80211_IFTYPE_MESH_POINT);
        skb = dev_alloc_skb(local->tx_headroom +
                            hdr_len +
                            2 + /* capability info */
                            2 + 1 + sizeof(struct ieee80211_he_operation) +
                                    sizeof(struct ieee80211_he_6ghz_oper) +
                            2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
+                           ie_len_eht_cap +
+                           2 + 1 + offsetof(struct ieee80211_eht_operation, optional) +
+                                   offsetof(struct ieee80211_eht_operation_info, optional) +
                            2 + 8 + /* peering IE */
                            sdata->u.mesh.ie_len);
        if (!skb)
                    mesh_add_vht_oper_ie(sdata, skb) ||
                    mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
                    mesh_add_he_oper_ie(sdata, skb) ||
-                   mesh_add_he_6ghz_cap_ie(sdata, skb))
+                   mesh_add_he_6ghz_cap_ie(sdata, skb) ||
+                   mesh_add_eht_cap_ie(sdata, skb, ie_len_eht_cap) ||
+                   mesh_add_eht_oper_ie(sdata, skb))
                        goto free;
        }
 
                                          elems->he_6ghz_capa,
                                          &sta->deflink);
 
+       ieee80211_eht_cap_ie_to_sta_eht_cap(sdata, sband, elems->he_cap,
+                                           elems->he_cap_len,
+                                           elems->eht_cap, elems->eht_cap_len,
+                                           &sta->deflink);
+
        if (bw != sta->sta.deflink.bandwidth)
                changed |= IEEE80211_RC_BW_CHANGED;
 
 
        return pos;
 }
 
+u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef,
+                               const struct ieee80211_sta_eht_cap *eht_cap)
+
+{
+       const struct ieee80211_eht_mcs_nss_supp_20mhz_only *eht_mcs_nss =
+                                       &eht_cap->eht_mcs_nss_supp.only_20mhz;
+       struct ieee80211_eht_operation *eht_oper;
+       struct ieee80211_eht_operation_info *eht_oper_info;
+       u8 eht_oper_len = offsetof(struct ieee80211_eht_operation, optional);
+       u8 eht_oper_info_len =
+               offsetof(struct ieee80211_eht_operation_info, optional);
+       u8 chan_width = 0;
+
+       *pos++ = WLAN_EID_EXTENSION;
+       *pos++ = 1 + eht_oper_len + eht_oper_info_len;
+       *pos++ = WLAN_EID_EXT_EHT_OPERATION;
+
+       eht_oper = (struct ieee80211_eht_operation *)pos;
+
+       memcpy(&eht_oper->basic_mcs_nss, eht_mcs_nss, sizeof(*eht_mcs_nss));
+       eht_oper->params |= IEEE80211_EHT_OPER_INFO_PRESENT;
+       pos += eht_oper_len;
+
+       eht_oper_info =
+               (struct ieee80211_eht_operation_info *)eht_oper->optional;
+
+       eht_oper_info->ccfs0 =
+               ieee80211_frequency_to_channel(chandef->center_freq1);
+       if (chandef->center_freq2)
+               eht_oper_info->ccfs1 =
+                       ieee80211_frequency_to_channel(chandef->center_freq2);
+       else
+               eht_oper_info->ccfs1 = 0;
+
+       switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_320:
+               chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ;
+               eht_oper_info->ccfs1 = eht_oper_info->ccfs0;
+               if (chandef->chan->center_freq < chandef->center_freq1)
+                       eht_oper_info->ccfs0 -= 16;
+               else
+                       eht_oper_info->ccfs0 += 16;
+               break;
+       case NL80211_CHAN_WIDTH_160:
+               eht_oper_info->ccfs1 = eht_oper_info->ccfs0;
+               if (chandef->chan->center_freq < chandef->center_freq1)
+                       eht_oper_info->ccfs0 -= 8;
+               else
+                       eht_oper_info->ccfs0 += 8;
+               fallthrough;
+       case NL80211_CHAN_WIDTH_80P80:
+               chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_160MHZ;
+               break;
+       case NL80211_CHAN_WIDTH_80:
+               chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ;
+               break;
+       case NL80211_CHAN_WIDTH_40:
+               chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_40MHZ;
+               break;
+       default:
+               chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_20MHZ;
+               break;
+       }
+       eht_oper_info->control = chan_width;
+       pos += eht_oper_info_len;
+
+       /* TODO: eht_oper_info->optional */
+
+       return pos;
+}
+
 bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
                               struct cfg80211_chan_def *chandef)
 {