diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index b88aeb03c..9a311c5d3 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -32,7 +32,7 @@
 #include "dfs.h"
 #include "taxonomy.h"
 #include "ieee802_11_auth.h"
-
+#include "crypto/sha1.h"
 
 #ifdef NEED_AP_MLME
 
@@ -2026,6 +2026,17 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 	resp = hostapd_probe_resp_offloads(hapd, &resp_len);
 #endif /* NEED_AP_MLME */
 
+	/* If key mgmt offload is enabled, configure PSK  */
+	if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
+	    (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) {
+		if (hapd->conf->ssid.wpa_psk && hapd->conf->ssid.wpa_psk_set) {
+			os_memcpy(params->psk, hapd->conf->ssid.wpa_psk->psk, PMK_LEN);
+		} else if (hapd->conf->ssid.wpa_passphrase) {
+			pbkdf2_sha1(hapd->conf->ssid.wpa_passphrase, hapd->conf->ssid.ssid,
+				hapd->conf->ssid.ssid_len, 4096, params->psk, PMK_LEN);
+		}
+	}
+
 	params->head = (u8 *) head;
 	params->head_len = head_len;
 	params->tail = tail;
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index bc575e260..2cd7b5a58 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -2186,6 +2186,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 			  union wpa_event_data *data)
 {
 	struct hostapd_data *hapd = ctx;
+	struct sta_info *sta = NULL;
 #ifndef CONFIG_NO_STDOUT_DEBUG
 	int level = MSG_DEBUG;
 
@@ -2305,6 +2306,15 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 				    data->assoc_info.link_addr,
 				    data->assoc_info.reassoc);
 		break;
+	case EVENT_PORT_AUTHORIZED:
+		/* Port auth event from associated STA */
+		sta = ap_get_sta(hapd, data->port_authorized.sta_addr);
+		if (sta)
+			ap_sta_set_authorized(hapd, sta, 1);
+		else
+			wpa_printf(MSG_DEBUG, "sta info not found");
+		break;
+
 #ifdef CONFIG_OWE
 	case EVENT_UPDATE_DH:
 		if (!data)
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 966030d57..7b5050f32 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -3573,8 +3573,13 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
 		    sta->auth_alg != WLAN_AUTH_FILS_PK &&
 		    !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
 			wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
-	} else
+	} else if (!(hapd->iface->drv_flags2 &
+	    WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) {
+		/* 4way HS offloaded STA will have this handled from port auth
+		 * event
+		 */
 		wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
+	}
 
 	if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED) {
 		if (eloop_cancel_timeout(ap_handle_timer, hapd, sta) > 0) {
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 24016b344..c5ffe44a1 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1809,6 +1809,11 @@ struct wpa_driver_ap_params {
 	 * mld_link_id - Link id for MLD BSS's
 	 */
 	u8 mld_link_id;
+
+	/**
+	 * psk - PSK passed to driver for 4-way HS offload
+	 */
+	u8 psk[PMK_LEN];
 };
 
 struct wpa_driver_mesh_bss_params {
@@ -2281,6 +2286,8 @@ struct wpa_driver_capa {
 #define WPA_DRIVER_FLAGS2_SCAN_MIN_PREQ         0x0000000000008000ULL
 /** Driver supports SAE authentication offload in STA mode */
 #define WPA_DRIVER_FLAGS2_SAE_OFFLOAD_STA	0x0000000000010000ULL
+/** Driver support AP_PSK authentication offload */
+#define WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK	0x0000000000020000ULL
 	u64 flags2;
 
 #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
@@ -6668,11 +6675,16 @@ union wpa_event_data {
 	struct pasn_auth pasn_auth;
 
 	/**
-	 * struct port_authorized - Data for EVENT_PORT_AUTHORIZED
+	 * struct port_authorized - Data for EVENT_PORT_AUTHORIZED for STA or AP
+	 * to indicate that port is authorized and open for data.
+	 * td_bitmap, td_bitmap_len: STA event would indicate td_bitmap if peer AP
+	 * notifies the same in EAPOL 3/4.
+	 * sta_addr: For AP, this would be the associated STA's macaddr.
 	 */
 	struct port_authorized {
 		const u8 *td_bitmap;
 		size_t td_bitmap_len;
+		u8 sta_addr[ETH_ALEN];
 	} port_authorized;
 
 	/**
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 8b72d74c5..b7b123d24 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5110,6 +5110,11 @@ static int wpa_driver_nl80211_set_ap(void *priv,
 			 suites))
 		goto fail;
 
+	if ((params->key_mgmt_suites & WPA_KEY_MGMT_PSK) &&
+	    (drv->capa.flags & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK) &&
+	    (nla_put(msg, NL80211_ATTR_PMK, 32, params->psk)))
+		goto fail;
+
 	if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
 	    (!params->pairwise_ciphers ||
 	     params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40)) &&
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index b7d914140..6faeaa5f3 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -705,6 +705,11 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
 	if (ext_feature_isset(ext_features, len,
 			      NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
 		capa->flags2 |= WPA_DRIVER_FLAGS2_SCAN_MIN_PREQ;
+
+	if (ext_feature_isset(ext_features, len,
+			      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
+		capa->flags2 |= WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK;
+
 }
 
 
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 0297bffeb..1c56b81fd 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -3506,7 +3506,14 @@ static void nl80211_port_authorized(struct wpa_driver_nl80211_data *drv,
 	}
 
 	addr = nla_data(tb[NL80211_ATTR_MAC]);
-	if (os_memcmp(addr, drv->bssid, ETH_ALEN) != 0) {
+	if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
+		/* Update STA assoc address */
+		os_memcpy(event.port_authorized.sta_addr, addr, ETH_ALEN);
+		wpa_printf(MSG_DEBUG,
+			"nl80211: Port authorized for STA addr "  MACSTR,
+			MAC2STR(addr));
+	} else if (is_sta_interface(drv->nlmode) &&
+	    os_memcmp(addr, drv->bssid, ETH_ALEN) != 0) {
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: Ignore port authorized event for " MACSTR
 			   " (not the currently connected BSSID " MACSTR ")",
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 2fc9f453b..b6e666a7d 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -1058,6 +1058,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
 		return -1;
 	hapd_iface->owner = wpa_s;
 	hapd_iface->drv_flags = wpa_s->drv_flags;
+	hapd_iface->drv_flags2 = wpa_s->drv_flags2;
 	hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
 	hapd_iface->extended_capa = wpa_s->extended_capa;
 	hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 1f186eb67..63f6a4730 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -22,6 +22,7 @@
 #include "common/wpa_ctrl.h"
 #include "eap_peer/eap.h"
 #include "ap/hostapd.h"
+#include "ap/sta_info.h"
 #include "p2p/p2p.h"
 #include "fst/fst.h"
 #include "wnm_sta.h"
@@ -6416,7 +6417,20 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 				wpa_s, data->port_authorized.td_bitmap[0]);
 		}
 #endif /* CONFIG_NO_WPA */
-		wpa_supplicant_event_port_authorized(wpa_s);
+		if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) {
+			/* ap/p2p_go authorizing sta/p2p_gc */
+			struct sta_info *sta = NULL;
+
+			sta = ap_get_sta(wpa_s->ap_iface->bss[0],
+				data->port_authorized.sta_addr);
+			if (sta)
+				ap_sta_set_authorized(wpa_s->ap_iface->bss[0], sta, 1);
+			else
+				wpa_printf(MSG_ERROR, "sta info not found");
+		} else {
+			/* sta/p2p gc port authorized event handling */
+			wpa_supplicant_event_port_authorized(wpa_s);
+		}
 		break;
 	case EVENT_STATION_OPMODE_CHANGED:
 #ifdef CONFIG_AP
