diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index a737ed7..17f686f 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -332,6 +332,15 @@ fi.w1.wpa_supplicant1.CreateInterface.
 	  <dd>Invalid entries were found in the passed argument.</dd>
 	</dl>
        </li>
+       <li>
+	<h3>EnableHighBitrates ( ) --> nothing</h3>
+	<p>Enable high bitrates on this interface if currently disabled.</p>
+	<h4>Possible errors</h4>
+	<dl>
+	  <dt>fi.w1.wpa_supplicant1.UnknownError</dt>
+	  <dd>Enabling high bitrates failed for an unknown reason.</dd>
+	</dl>
+      </li>
     </ul>
 
 \subsection dbus_interface_properties Properties
@@ -431,6 +440,11 @@ fi.w1.wpa_supplicant1.CreateInterface.
 	<h3>ScanInterval - i - (read/write)</h3>
 	<p>Time (in seconds) between scans for a suitable AP. Must be >= 0.</p>
       </li>
+
+      <li>
+	<h3>DisableHighBitrates- b - (read/write)</h3>
+	<p>Identical to disable_high_bitrates entry in %wpa_supplicant configuration file.</p>
+      </li>
     </ul>
 
 \subsection dbus_interface_signals Signals
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index b981172..94cef9f 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -559,6 +559,13 @@ struct wpa_driver_associate_params {
 	 */
 	const u8 *htcaps;       /* struct ieee80211_ht_capabilities * */
 	const u8 *htcaps_mask;  /* struct ieee80211_ht_capabilities * */
+
+	/**
+	 * disable_high_bitrates - Disable high bitrates on an interface when
+	 * associating/associated with this SSID.  (e.g. legacy rates over
+	 * 11Mbps and all but the lowest two MCS rates)
+	 */
+	int disable_high_bitrates;
 };
 
 enum hide_ssid {
@@ -2612,6 +2619,18 @@ struct wpa_driver_ops {
 	 * avoid frequency conflict in single channel concurrency.
 	 */
 	int (*switch_channel)(void *priv, unsigned int freq);
+
+	/**
+	 * enable_high_bitrates - Request driver to enable high bitrates.
+	 * @priv: private driver interface data.
+	 *
+	 * Returns: 0 on success, -1 on failure
+	 *
+	 * This may be overwritten by future associations to the same SSID,
+	 * each of which will disable high bitrates again if
+	 * disable_high_bitrates is set in the association parameters.
+	 */
+	int (*enable_high_bitrates)(void *priv);
 };
 
 
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 6d2ed28..bfe419a 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -339,6 +339,8 @@ static inline int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
 static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
 static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
 				     int ifindex, int disabled);
+static int nl80211_disable_high_bitrates(struct wpa_driver_nl80211_data *drv,
+					 int ifindex, int disabled);
 
 static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
 static int wpa_driver_nl80211_authenticate_retry(
@@ -6971,9 +6973,21 @@ skip_auth_type:
 			   "(%s)", ret, strerror(-ret));
 		goto nla_put_failure;
 	}
-	ret = 0;
 	wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
 
+	ret = nl80211_disable_high_bitrates(drv, drv->ifindex,
+					    params->disable_high_bitrates);
+	if (ret) {
+		/*
+		 * Not all drivers with an nl80211 interface support this API.
+		 * Don't kill those association attempts because we've failed
+		 * to provide this functionality.
+		 */
+		wpa_printf(MSG_ERROR, "nl80211: Failed to disable high "
+			   "bitrates");
+	}
+	ret = 0;
+
 nla_put_failure:
 	nlmsg_free(msg);
 	return ret;
@@ -7158,10 +7172,22 @@ static int wpa_driver_nl80211_associate(
 		nl80211_dump_scan(drv);
 		goto nla_put_failure;
 	}
-	ret = 0;
 	wpa_printf(MSG_DEBUG, "nl80211: Association request send "
 		   "successfully");
 
+	ret = nl80211_disable_high_bitrates(drv, drv->ifindex,
+					    params->disable_high_bitrates);
+	if (ret) {
+		/*
+		 * Not all drivers with an nl80211 interface support this API.
+		 * Don't kill those association attempts because we've failed
+		 * to provide this functionality.
+		 */
+		wpa_printf(MSG_ERROR, "nl80211: Failed to disable high "
+			   "bitrates");
+	}
+	ret = 0;
+
 nla_put_failure:
 	nlmsg_free(msg);
 	return ret;
@@ -8533,13 +8559,25 @@ static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
 	return -1;
 }
 
-
-static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
-				     int ifindex, int disabled)
-{
-	struct nl_msg *msg;
+/**
+ * Enable or disable rates considered for use by the driver.  Passing NULL for
+ * a set of allowed bands enables all bitrates in that band.  This function
+ * completely overwrites previous calls, rather than adding or removing rates.
+ */
+static int nl80211_set_allowed_rates(struct wpa_driver_nl80211_data *drv,
+				     int ifindex,
+				     const char *legacy_2ghz_rates,
+				     int legacy_2ghz_rates_len,
+				     const char *legacy_5ghz_rates,
+				     int legacy_5ghz_rates_len,
+				     const char *mcs_2ghz_rates,
+				     int mcs_2ghz_rates_len,
+				     const char *mcs_5ghz_rates,
+				     int mcs_5ghz_rates_len)
+{
+	struct nl_msg *msg = NULL;
 	struct nlattr *bands, *band;
-	int ret;
+	int ret = -1;
 
 	msg = nlmsg_alloc();
 	if (!msg)
@@ -8552,19 +8590,41 @@ static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
 	if (!bands)
 		goto nla_put_failure;
 
-	/*
-	 * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
-	 * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
-	 * rates. All 5 GHz rates are left enabled.
-	 */
-	band = nla_nest_start(msg, NL80211_BAND_2GHZ);
-	if (!band)
-		goto nla_put_failure;
-	if (disabled) {
-		NLA_PUT(msg, NL80211_TXRATE_LEGACY, 8,
-			"\x0c\x12\x18\x24\x30\x48\x60\x6c");
+	if (legacy_2ghz_rates && legacy_2ghz_rates_len >= 0) {
+		band = nla_nest_start(msg, NL80211_BAND_2GHZ);
+		if (!band)
+			goto nla_put_failure;
+		NLA_PUT(msg, NL80211_TXRATE_LEGACY,
+			legacy_2ghz_rates_len, legacy_2ghz_rates);
+		nla_nest_end(msg, band);
+	}
+
+	if (legacy_5ghz_rates && legacy_5ghz_rates_len >= 0) {
+		band = nla_nest_start(msg, NL80211_BAND_5GHZ);
+		if (!band)
+			goto nla_put_failure;
+		NLA_PUT(msg, NL80211_TXRATE_LEGACY,
+			legacy_5ghz_rates_len, legacy_5ghz_rates);
+		nla_nest_end(msg, band);
+	}
+
+	if (mcs_2ghz_rates && mcs_2ghz_rates_len >= 0) {
+		band = nla_nest_start(msg, NL80211_BAND_2GHZ);
+		if (!band)
+			goto nla_put_failure;
+		NLA_PUT(msg, NL80211_TXRATE_MCS,
+			mcs_2ghz_rates_len, mcs_2ghz_rates);
+		nla_nest_end(msg, band);
+	}
+
+	if (mcs_5ghz_rates && mcs_5ghz_rates_len >= 0) {
+		band = nla_nest_start(msg, NL80211_BAND_5GHZ);
+		if (!band)
+			goto nla_put_failure;
+		NLA_PUT(msg, NL80211_TXRATE_MCS,
+			mcs_5ghz_rates_len, mcs_5ghz_rates);
+		nla_nest_end(msg, band);
 	}
-	nla_nest_end(msg, band);
 
 	nla_nest_end(msg, bands);
 
@@ -8573,14 +8633,53 @@ static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
 			   "(%s)", ret, strerror(-ret));
-	} else
-		drv->disabled_11b_rates = disabled;
-
-	return ret;
+	}
 
 nla_put_failure:
 	nlmsg_free(msg);
-	return -1;
+	return ret;
+}
+
+
+static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
+				     int ifindex, int disabled)
+{
+	/*
+	 * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
+	 * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
+	 * rates. All 5 GHz rates are left enabled.
+	 */
+	if (disabled) {
+		return nl80211_set_allowed_rates(drv, ifindex,
+						 "\x0c\x12\x18\x24\x30\x48\x60\x6c", 8,
+						 NULL, 0,
+						 NULL, 0,
+						 NULL, 0);
+	}
+	return nl80211_set_allowed_rates(drv, ifindex, NULL, 0, NULL, 0,
+					 NULL, 0, NULL, 0);
+}
+
+
+static int nl80211_disable_high_bitrates(struct wpa_driver_nl80211_data *drv,
+				     int ifindex, int disabled)
+{
+	/*
+	 * Allow only legacy bitrates less than 12 Mbps and the two slowest MCS
+	 * rates for outgoing traffic.
+	 */
+	if (disabled) {
+		wpa_printf(MSG_DEBUG, "nl80211: Disabling high bitrates");
+		return nl80211_set_allowed_rates(drv, ifindex,
+						 "\x02\x04\x0b\x0c\x16", 5,
+						 "\x02\x04\x0b\x0c\x16", 5,
+						 "\x00\x01", 2,
+						 "\x00\x01", 2);
+	}
+
+	wpa_printf(MSG_DEBUG, "nl80211: Enabling high bitrates");
+	return nl80211_set_allowed_rates(drv, ifindex, NULL, 0, NULL, 0,
+					 NULL, 0, NULL, 0);
 }
 
 
@@ -9016,6 +9115,14 @@ static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
 }
 
 
+static int nl80211_enable_high_bitrates(void *priv)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	return nl80211_disable_high_bitrates(drv, drv->ifindex, 0);
+}
+
+
 static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
 {
 	struct nl_msg *msg;
@@ -9352,4 +9459,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.send_tdls_mgmt = nl80211_send_tdls_mgmt,
 	.tdls_oper = nl80211_tdls_oper,
 #endif /* CONFIG_TDLS */
+	.enable_high_bitrates = nl80211_enable_high_bitrates,
 };
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 2c52c68..8db50c4 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2990,6 +2990,7 @@ static const struct global_parse_data global_fields[] = {
 	{ INT(okc), 0 },
 	{ INT(pmf), 0 },
 	{ FUNC(sae_groups), 0 },
+	{ INT_RANGE(disable_high_bitrates, 0, 1), 0 },
 };
 
 #undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 0c3cb9a..ef5c158 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -807,6 +807,16 @@ struct wpa_config {
 	 * groups will be tried in the indicated order.
 	 */
 	int *sae_groups;
+
+	/**
+	 * disable_high_bitrates - Disable high bitrates on new associations
+	 *
+	 * By default, we use all available bitrates negotiated with an AP
+	 * during association.  However, this flag can be set to disable the use
+	 * of high bitrates for frame transmission (if supported by the driver).
+	 * The user can later re-enable high bitrates via EnableHighBitrates().
+	 */
+	int disable_high_bitrates;
 };
 
 
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 8bc6618..ebe4d9d 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2649,6 +2649,12 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
 	  }
 	},
 #endif /* CONFIG_AP */
+	{ "EnableHighBitrates", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) &wpas_dbus_handler_enable_high_bitrates,
+	  {
+		  END_ARGS
+	  }
+	},
 	{ NULL, NULL, NULL, { END_ARGS } }
 };
 
@@ -2725,6 +2731,10 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
 	  wpas_dbus_getter_scan_interval,
 	  wpas_dbus_setter_scan_interval
 	},
+	{ "DisableHighBitrates", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
+	  wpas_dbus_getter_disable_high_bitrates,
+	  wpas_dbus_setter_disable_high_bitrates
+	},
 #ifdef CONFIG_WPS
 	{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
 	  wpas_dbus_getter_process_credentials,
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 5e06932..eaf2737 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1920,6 +1920,19 @@ DBusMessage * wpas_dbus_handler_autoscan(DBusMessage *message,
 #endif /* CONFIG_AUTOSCAN */
 
 
+DBusMessage * wpas_dbus_handler_enable_high_bitrates(DBusMessage *message,
+	struct wpa_supplicant *wpa_s)
+{
+	DBusMessage *reply = NULL;
+	if (wpa_supplicant_enable_high_bitrates(wpa_s)) {
+		reply = wpas_dbus_error_unknown_error(message,
+						      "Failed to enable high "
+						      "rates.");
+	}
+	return reply;
+}
+
+
 /**
  * wpas_dbus_getter_capabilities - Return interface capabilities
  * @iter: Pointer to incoming dbus message iter
@@ -2659,6 +2672,56 @@ dbus_bool_t wpas_dbus_setter_scan_interval(DBusMessageIter *iter,
 
 
 /**
+ * wpas_dbus_getter_disable_high_bitrates - Disable high bitrates for
+ * each association on this interface.
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Getter function for "DisableHighBitrates" property.
+ */
+dbus_bool_t wpas_dbus_getter_disable_high_bitrates(DBusMessageIter *iter,
+						   DBusError *error,
+						   void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_bool_t disable_high_bitrates = FALSE;
+	if (wpa_s->conf->disable_high_bitrates)
+		disable_high_bitrates = TRUE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&disable_high_bitrates, error);
+}
+
+
+/**
+ * wpas_dbus_setter_disable_high_bitrates - Disable high bitrates for
+ * each association on this interface.
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Setter function for "DisableHighBitrates" property.
+ */
+dbus_bool_t wpas_dbus_setter_disable_high_bitrates(DBusMessageIter *iter,
+						   DBusError *error,
+						   void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_bool_t disable_high_bitrates;
+
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+					      &disable_high_bitrates))
+		return FALSE;
+
+	wpa_s->conf->disable_high_bitrates = disable_high_bitrates;
+	return TRUE;
+}
+
+
+/**
  * wpas_dbus_getter_ifname - Get interface name
  * @iter: Pointer to incoming dbus message iter
  * @error: Location to store error on failure
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index aa56550..aa8f6fa 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -128,6 +128,9 @@ DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
 DBusMessage * wpas_dbus_handler_autoscan(DBusMessage *message,
 					 struct wpa_supplicant *wpa_s);
 
+DBusMessage * wpas_dbus_handler_enable_high_bitrates(
+	DBusMessage *message, struct wpa_supplicant *wpa_s);
+
 dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter,
 					  DBusError *error, void *user_data);
 
@@ -184,6 +187,14 @@ dbus_bool_t wpas_dbus_setter_scan_interval(DBusMessageIter *iter,
 					   DBusError *error,
 					   void *user_data);
 
+dbus_bool_t wpas_dbus_getter_disable_high_bitrates(DBusMessageIter *iter,
+						   DBusError *error,
+						   void *user_data);
+
+dbus_bool_t wpas_dbus_setter_disable_high_bitrates(DBusMessageIter *iter,
+						   DBusError *error,
+						   void *user_data);
+
 dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error,
 				    void *user_data);
 
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 847600d..88b2c56 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -689,4 +689,12 @@ static inline int wpa_drv_wnm_oper(struct wpa_supplicant *wpa_s,
 				       buf_len);
 }
 
+static inline int wpa_drv_enable_high_bitrates(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->driver->enable_high_bitrates) {
+		return wpa_s->driver->enable_high_bitrates(wpa_s->drv_priv);
+	}
+	return -1;
+}
+
 #endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 30f9779..a8a2d02 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -653,6 +653,7 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
 	params.htcaps_mask = (u8 *) &htcaps_mask;
 	wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, &params);
 #endif /* CONFIG_HT_OVERRIDES */
+	params.disable_high_bitrates = wpa_s->conf->disable_high_bitrates;
 #ifdef CONFIG_IEEE80211R
 	if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) {
 		params.wpa_ie = wpa_s->sme.ft_ies;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 64f5c1b..295802f 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1581,6 +1581,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 	wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
 #endif /* CONFIG_HT_OVERRIDES */
 
+	params.disable_high_bitrates = wpa_s->conf->disable_high_bitrates;
+
 	ret = wpa_drv_associate(wpa_s, &params);
 	if (ret < 0) {
 		wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
@@ -1883,6 +1885,20 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
 
 
 /**
+ * wpa_supplicant_enable_high_bitrates - Enable high bitrates on an interface.
+ * @wpa_s: wpa_supplicant structure for a network interface
+ *
+ * Enables high bitrates on the interface until the next association.  If
+ * disable_high_bitrates is set on the next association, high rates will be
+ * disabled again.
+ */
+int wpa_supplicant_enable_high_bitrates(struct wpa_supplicant *wpa_s)
+{
+	return wpa_drv_enable_high_bitrates(wpa_s);
+}
+
+
+/**
  * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
  * @wpa_s: wpa_supplicant structure for a network interface
  * @ap_scan: AP scan mode
