diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 0d340d2..88b5a99 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3112,6 +3112,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 			conf->hw_mode = HOSTAPD_MODE_IEEE80211AD;
 		else if (os_strcmp(pos, "any") == 0)
 			conf->hw_mode = HOSTAPD_MODE_IEEE80211ANY;
+		else if (os_strcmp(pos, "ag") == 0)
+			conf->hw_mode = HOSTAPD_MODE_IEEE80211AG;
 		else {
 			wpa_printf(MSG_ERROR, "Line %d: unknown hw_mode '%s'",
 				   line, pos);
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index c1f19e2..285ccfe 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -832,6 +832,30 @@ int hostapd_acs_completed(struct hostapd_iface *iface, int err)
 			hostapd_hw_get_freq(iface->bss[0],
 					    iface->conf->channel),
 			iface->conf->channel);
+		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AG) {
+			int i;
+			enum hostapd_hw_mode target_mode;
+
+			if (iface->conf->channel<=14)
+				target_mode = HOSTAPD_MODE_IEEE80211G;
+			else
+				target_mode = HOSTAPD_MODE_IEEE80211A;
+
+			for (i = 0; i < iface->num_hw_features; i++) {
+				struct hostapd_hw_modes *mode = &iface->hw_features[i];
+				if (mode->mode == target_mode) {
+					iface->current_mode = mode;
+					break;
+				}
+			}
+
+			if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AG) {
+				wpa_printf(MSG_ERROR, "ACS error - can not decide A band or G band");
+				wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
+				hostapd_notify_bad_chans(iface);
+				goto out;
+			}
+		}
 		break;
 	case HOSTAPD_CHAN_ACS:
 		wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available");
diff --git a/src/common/defs.h b/src/common/defs.h
index 4faf1c8..b531bc0 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -349,6 +349,7 @@ enum hostapd_hw_mode {
 	HOSTAPD_MODE_IEEE80211A,
 	HOSTAPD_MODE_IEEE80211AD,
 	HOSTAPD_MODE_IEEE80211ANY,
+	HOSTAPD_MODE_IEEE80211AG,
 	NUM_HOSTAPD_MODES
 };
 
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index 8318b10..afc1570 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -1743,6 +1743,43 @@ static int phy_info_handler(struct nl_msg *msg, void *arg)
 	return NL_SKIP;
 }
 
+static int
+wpa_driver_nl80211_hw_mode_append(struct hostapd_hw_modes *mode,
+				  struct hostapd_hw_modes *mode11)
+{
+	struct hostapd_channel_data *new_channels;
+	int *new_rates;
+
+	if ((mode11->num_channels == 0) || (mode11->num_rates == 0)) {
+		wpa_printf(MSG_ERROR, "%s: num_channels or num_rates is 0", __func__);
+		return -1;
+	}
+
+	new_channels = os_realloc_array(mode->channels,
+					mode->num_channels + mode11->num_channels,
+					sizeof(struct hostapd_channel_data));
+	if (new_channels == NULL)
+		return -1;
+
+	memcpy(&new_channels[mode->num_channels], mode11->channels,
+		mode11->num_channels * sizeof(struct hostapd_channel_data));
+	mode->channels = new_channels;
+	mode->num_channels += mode11->num_channels;
+
+	new_rates = os_realloc_array(mode->rates, mode->num_rates + mode11->num_rates,
+				     sizeof(int));
+	if ( new_rates == NULL) {
+		os_free(mode->channels);
+		return -1;
+	}
+
+	memcpy(&new_rates[mode->num_rates], mode11->rates,
+		mode11->num_rates * sizeof(int));
+	mode->rates = new_rates;
+	mode->num_rates += mode11->num_rates;
+
+	return 0;
+}
 
 static struct hostapd_hw_modes *
 wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
@@ -1751,6 +1788,8 @@ wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
 	u16 m;
 	struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
 	int i, mode11g_idx = -1;
+	struct hostapd_hw_modes *mode11a = NULL;
+	int mode11a_idx = -1;
 
 	/* heuristic to set up modes */
 	for (m = 0; m < *num_modes; m++) {
@@ -1778,6 +1817,8 @@ wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
 			return modes; /* 802.11b already included */
 		if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
 			mode11g_idx = m;
+		if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
+			mode11a_idx = m;
 	}
 
 	if (mode11g_idx < 0)
@@ -1832,6 +1873,36 @@ wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
 	wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
 		   "information");
 
+	if (mode11a_idx < 0) {
+		wpa_printf(MSG_DEBUG, "nl80211: NO 5G band");
+		return modes; /* 5GHz band not supported at all */
+	}
+
+	/* add AG mode if 2.4GHz and 5GHz are all supported */
+	nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
+	if (nmodes == NULL)
+		return modes; /* Could not add 802.11b mode */
+
+	mode = &nmodes[*num_modes];
+	os_memset(mode, 0, sizeof(*mode));
+	(*num_modes)++;
+	modes = nmodes;
+	mode11g = &modes[mode11g_idx];
+	mode11a = &modes[mode11a_idx];
+
+	mode->mode = HOSTAPD_MODE_IEEE80211AG;
+	mode->num_channels = 0;
+	mode->num_rates = 0;
+        if ((wpa_driver_nl80211_hw_mode_append(mode, mode11g) < 0) ||
+	    (wpa_driver_nl80211_hw_mode_append(mode, mode11a) < 0)) {
+		wpa_printf(MSG_ERROR, "nl80211: Added 802.11a+g failed");
+		(*num_modes)--;
+		return modes; /* Could not add 802.11g mode */
+	}
+
+	wpa_printf(MSG_DEBUG, "nl80211: Added 802.11a+g mode based on 802.11g/a "
+		   "information");
+
 	return modes;
 }
 
