sta->plink_retries = 0;
 }
 
+/*
+ * mesh_set_short_slot_time - enable / disable ERP short slot time.
+ *
+ * The standard indirectly mandates mesh STAs to turn off short slot time by
+ * disallowing advertising this (802.11-2012 8.4.1.4), but that doesn't mean we
+ * can't be sneaky about it. Enable short slot time if all mesh STAs in the
+ * MBSS support ERP rates.
+ *
+ * Returns BSS_CHANGED_ERP_SLOT or 0 for no change.
+ */
+static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_local *local = sdata->local;
+       enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
+       struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
+       struct sta_info *sta;
+       u32 erp_rates = 0, changed = 0;
+       int i;
+       bool short_slot = false;
+
+       if (band == IEEE80211_BAND_5GHZ) {
+               /* (IEEE 802.11-2012 19.4.5) */
+               short_slot = true;
+               goto out;
+       } else if (band != IEEE80211_BAND_2GHZ ||
+                  (band == IEEE80211_BAND_2GHZ &&
+                   local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
+               goto out;
+
+       for (i = 0; i < sband->n_bitrates; i++)
+               if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)
+                       erp_rates |= BIT(i);
+
+       if (!erp_rates)
+               goto out;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(sta, &local->sta_list, list) {
+               if (sdata != sta->sdata ||
+                   sta->plink_state != NL80211_PLINK_ESTAB)
+                       continue;
+
+               short_slot = false;
+               if (erp_rates & sta->sta.supp_rates[band])
+                       short_slot = true;
+                else
+                       break;
+       }
+       rcu_read_unlock();
+
+out:
+       if (sdata->vif.bss_conf.use_short_slot != short_slot) {
+               sdata->vif.bss_conf.use_short_slot = short_slot;
+               changed = BSS_CHANGED_ERP_SLOT;
+               mpl_dbg(sdata, "mesh_plink %pM: ERP short slot time %d\n",
+                       sdata->vif.addr, short_slot);
+       }
+       return changed;
+}
+
 /**
  * mesh_set_ht_prot_mode - set correct HT protection mode
  *
                        spin_unlock_bh(&sta->lock);
                        changed |= mesh_plink_inc_estab_count(sdata);
                        changed |= mesh_set_ht_prot_mode(sdata);
+                       changed |= mesh_set_short_slot_time(sdata);
                        mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
                                sta->sta.addr);
                        break;
                        spin_unlock_bh(&sta->lock);
                        changed |= mesh_plink_inc_estab_count(sdata);
                        changed |= mesh_set_ht_prot_mode(sdata);
+                       changed |= mesh_set_short_slot_time(sdata);
                        mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
                                sta->sta.addr);
                        mesh_plink_frame_tx(sdata,
                        mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
                        spin_unlock_bh(&sta->lock);
                        changed |= mesh_set_ht_prot_mode(sdata);
+                       changed |= mesh_set_short_slot_time(sdata);
                        mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
                                            sta->sta.addr, llid, plid, reason);
                        break;