}
 
 static struct sk_buff *
-ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
-                       struct ieee80211_vif *vif,
-                       struct ieee80211_link_data *link,
-                       struct ieee80211_mutable_offsets *offs,
-                       bool is_template,
-                       struct beacon_data *beacon,
-                       struct ieee80211_chanctx_conf *chanctx_conf,
-                       u8 ema_index)
+__ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
+                         struct ieee80211_vif *vif,
+                         struct ieee80211_link_data *link,
+                         struct ieee80211_mutable_offsets *offs,
+                         bool is_template,
+                         struct beacon_data *beacon,
+                         struct ieee80211_chanctx_conf *chanctx_conf,
+                         u8 ema_index)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
        return skb;
 }
 
+static bool ieee80211_s1g_need_long_beacon(struct ieee80211_sub_if_data *sdata,
+                                          struct ieee80211_link_data *link)
+{
+       struct ps_data *ps = &sdata->u.ap.ps;
+
+       if (ps->sb_count == 0)
+               ps->sb_count = link->conf->s1g_long_beacon_period - 1;
+       else
+               ps->sb_count--;
+
+       return ps->sb_count == 0;
+}
+
+static struct sk_buff *
+ieee80211_s1g_short_beacon_get(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *vif,
+                              struct ieee80211_link_data *link,
+                              struct ieee80211_chanctx_conf *chanctx_conf,
+                              struct s1g_short_beacon_data *sb,
+                              bool is_template)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       struct ieee80211_if_ap *ap = &sdata->u.ap;
+       struct sk_buff *skb;
+
+       skb = dev_alloc_skb(local->tx_headroom + sb->short_head_len +
+                           sb->short_tail_len + 256 +
+                           local->hw.extra_beacon_tailroom);
+       if (!skb)
+               return NULL;
+
+       skb_reserve(skb, local->tx_headroom);
+       skb_put_data(skb, sb->short_head, sb->short_head_len);
+
+       ieee80211_beacon_add_tim(sdata, link, &ap->ps, skb, is_template);
+
+       if (sb->short_tail)
+               skb_put_data(skb, sb->short_tail, sb->short_tail_len);
+
+       ieee80211_beacon_get_finish(hw, vif, link, NULL, NULL, skb,
+                                   chanctx_conf, 0);
+       return skb;
+}
+
+static struct sk_buff *
+ieee80211_beacon_get_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                       struct ieee80211_link_data *link,
+                       struct ieee80211_mutable_offsets *offs,
+                       bool is_template, struct beacon_data *beacon,
+                       struct ieee80211_chanctx_conf *chanctx_conf,
+                       u8 ema_index, struct s1g_short_beacon_data *s1g_sb)
+{
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+
+       if (!sdata->vif.cfg.s1g || !s1g_sb ||
+           ieee80211_s1g_need_long_beacon(sdata, link))
+               return __ieee80211_beacon_get_ap(hw, vif, link, offs,
+                                                is_template, beacon,
+                                                chanctx_conf, ema_index);
+
+       return ieee80211_s1g_short_beacon_get(hw, vif, link, chanctx_conf,
+                                             s1g_sb, is_template);
+}
+
 static struct ieee80211_ema_beacons *
 ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw,
                                 struct ieee80211_vif *vif,
                        ieee80211_beacon_get_ap(hw, vif, link,
                                                &ema->bcn[ema->cnt].offs,
                                                is_template, beacon,
-                                               chanctx_conf, ema->cnt);
+                                               chanctx_conf, ema->cnt, NULL);
                if (!ema->bcn[ema->cnt].skb)
                        break;
        }
        struct ieee80211_sub_if_data *sdata = NULL;
        struct ieee80211_chanctx_conf *chanctx_conf;
        struct ieee80211_link_data *link;
+       struct s1g_short_beacon_data *s1g_short_bcn = NULL;
 
        rcu_read_lock();
 
                if (!beacon)
                        goto out;
 
+               if (vif->cfg.s1g && link->u.ap.s1g_short_beacon) {
+                       s1g_short_bcn =
+                               rcu_dereference(link->u.ap.s1g_short_beacon);
+                       if (!s1g_short_bcn)
+                               goto out;
+               }
+
                if (ema_beacons) {
                        *ema_beacons =
                                ieee80211_beacon_get_ap_ema_list(hw, vif, link,
 
                        skb = ieee80211_beacon_get_ap(hw, vif, link, offs,
                                                      is_template, beacon,
-                                                     chanctx_conf,
-                                                     ema_index);
+                                                     chanctx_conf, ema_index,
+                                                     s1g_short_bcn);
                }
        } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
                struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;