diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c
index 3a9cc7b..5289536 100644
--- a/src/ap/pmksa_cache_auth.c
+++ b/src/ap/pmksa_cache_auth.c
@@ -32,6 +32,54 @@ struct rsn_pmksa_cache {
 };
 
 
+void pmksa_cache_dump(struct rsn_pmksa_cache *cache, const char *title)
+{
+	struct rsn_pmksa_cache_entry *e;
+	int i, count;
+	struct os_time now;
+
+	os_get_time(&now);
+	wpa_printf(MSG_INFO, "PMKSA cache %p (pmksa_count=%d) now=%d [%s]",
+		   cache, cache->pmksa_count, (int) now.sec, title);
+
+	count = 0;
+	for (e = cache->pmksa; e; e = e->next) {
+		count++;
+		wpa_printf(MSG_INFO, "entry %p " MACSTR " opportunistic=%d "
+			   "expiration=%d (next=%p hnext=%p)",
+			   e, MAC2STR(e->spa), e->opportunistic,
+			   (int) e->expiration, e->next, e->hnext);
+		wpa_hexdump(MSG_INFO, "pmkid", e->pmkid, PMKID_LEN);
+	}
+	if (count != cache->pmksa_count) {
+		wpa_printf(MSG_ERROR, "PMKSA cache count mismatch: list entry "
+			   "count %d pmksa_count=%d",
+			   count, cache->pmksa_count);
+		exit(1);
+	}
+
+	count = 0;
+	for (i = 0; i < PMKID_HASH_SIZE; i++) {
+		if (cache->pmkid[i] == NULL)
+			continue;
+		wpa_printf(MSG_INFO, "pmkid hash[%d]", i);
+		for (e = cache->pmkid[i]; e; e = e->hnext) {
+			count++;
+			wpa_printf(MSG_INFO, "entry %p " MACSTR
+				   " (next=%p hnext=%p)",
+				   e, MAC2STR(e->spa), e->next, e->hnext);
+		}
+	}
+	if (count != cache->pmksa_count) {
+		wpa_printf(MSG_ERROR, "PMKSA cache count mismatch: hash list "
+			   "entry count %d pmksa_count=%d",
+			   count, cache->pmksa_count);
+		exit(1);
+	}
+
+	wpa_printf(MSG_INFO, "PMKSA cache dump done [%s]", title);
+}
+
 static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa);
 
 
@@ -53,6 +101,7 @@ static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
 {
 	struct rsn_pmksa_cache_entry *pos, *prev;
 
+	pmksa_cache_dump(pmksa, "pre-pmksa_cache_free_entry");
 	pmksa->pmksa_count--;
 	pmksa->free_cb(entry, pmksa->ctx);
 	pos = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
@@ -85,6 +134,7 @@ static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
 		pos = pos->next;
 	}
 	_pmksa_cache_free_entry(entry);
+	pmksa_cache_dump(pmksa, "post-pmksa_cache_free_entry");
 }
 
 
@@ -241,6 +291,7 @@ pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa,
 	struct rsn_pmksa_cache_entry *entry, *pos;
 	struct os_time now;
 
+	pmksa_cache_dump(pmksa, "pre-pmksa_cache_auth_add");
 	if (pmk_len > PMK_LEN)
 		return NULL;
 
@@ -276,6 +327,7 @@ pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa,
 	}
 
 	pmksa_cache_link_entry(pmksa, entry);
+	pmksa_cache_dump(pmksa, "post-pmksa_cache_auth_add");
 
 	return entry;
 }
@@ -288,6 +340,7 @@ pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
 {
 	struct rsn_pmksa_cache_entry *entry;
 
+	pmksa_cache_dump(pmksa, "pre-pmksa_cache_add_okc");
 	entry = os_zalloc(sizeof(*entry));
 	if (entry == NULL)
 		return NULL;
@@ -316,6 +369,7 @@ pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
 	entry->opportunistic = 1;
 
 	pmksa_cache_link_entry(pmksa, entry);
+	pmksa_cache_dump(pmksa, "post-pmksa_cache_add_okc");
 
 	return entry;
 }
@@ -333,6 +387,7 @@ void pmksa_cache_auth_deinit(struct rsn_pmksa_cache *pmksa)
 	if (pmksa == NULL)
 		return;
 
+	pmksa_cache_dump(pmksa, __func__);
 	entry = pmksa->pmksa;
 	while (entry) {
 		prev = entry;
@@ -359,6 +414,7 @@ pmksa_cache_auth_get(struct rsn_pmksa_cache *pmksa,
 {
 	struct rsn_pmksa_cache_entry *entry;
 
+	pmksa_cache_dump(pmksa, __func__);
 	if (pmkid)
 		entry = pmksa->pmkid[PMKID_HASH(pmkid)];
 	else
@@ -392,6 +448,7 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_okc(
 	struct rsn_pmksa_cache_entry *entry;
 	u8 new_pmkid[PMKID_LEN];
 
+	pmksa_cache_dump(pmksa, __func__);
 	entry = pmksa->pmksa;
 	while (entry) {
 		if (os_memcmp(entry->spa, spa, ETH_ALEN) != 0)
diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h
index d473f3f..547d929 100644
--- a/src/ap/pmksa_cache_auth.h
+++ b/src/ap/pmksa_cache_auth.h
@@ -55,5 +55,6 @@ pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
 		    const u8 *aa, const u8 *pmkid);
 void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
 			       struct eapol_state_machine *eapol);
+void pmksa_cache_dump(struct rsn_pmksa_cache *cache, const char *title);
 
 #endif /* PMKSA_CACHE_H */
