diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index 3ec15a49ecc9..ee73b125ac0e 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -9,6 +9,7 @@
 #include "fw.h"
 #include "debug.h"
 #include "phy.h"
+#include "sar.h"
 
 #ifdef CONFIG_RTW88_DEBUGFS
 
@@ -696,6 +697,16 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v)
 	return 0;
 }
 
+static int rtw_debugfs_get_sar(struct seq_file *m, void *v)
+{
+	struct rtw_debugfs_priv *debugfs_priv = m->private;
+	struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+
+	rtw_sar_dump_via_debugfs(rtwdev, m);
+
+	return 0;
+}
+
 #define rtw_debug_impl_mac(page, addr)				\
 static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = {	\
 	.cb_read = rtw_debug_get_mac_page,			\
@@ -786,6 +797,10 @@ static struct rtw_debugfs_priv rtw_debug_priv_phy_info = {
 	.cb_read = rtw_debugfs_get_phy_info,
 };
 
+static struct rtw_debugfs_priv rtw_debug_priv_sar = {
+	.cb_read = rtw_debugfs_get_sar,
+};
+
 #define rtw_debugfs_add_core(name, mode, fopname, parent)		\
 	do {								\
 		rtw_debug_priv_ ##name.rtwdev = rtwdev;			\
@@ -816,6 +831,7 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
 	rtw_debugfs_add_rw(dump_cam);
 	rtw_debugfs_add_rw(rsvd_page);
 	rtw_debugfs_add_r(phy_info);
+	rtw_debugfs_add_r(sar);
 	rtw_debugfs_add_r(mac_0);
 	rtw_debugfs_add_r(mac_1);
 	rtw_debugfs_add_r(mac_2);
diff --git a/drivers/net/wireless/realtek/rtw88/sar.c b/drivers/net/wireless/realtek/rtw88/sar.c
index 2bc6da4e5fcf..62689c002e25 100644
--- a/drivers/net/wireless/realtek/rtw88/sar.c
+++ b/drivers/net/wireless/realtek/rtw88/sar.c
@@ -298,6 +298,7 @@ struct rtw_sar_read {
 	const struct rtw_sar_geo_map *gm, *gm_end;
 	int rwsi_sz;
 	int rwgs_sz;
+	int rwgs_geos;
 };
 
 static int rwsi_mode_hp(struct rtw_dev *rtwdev, int path)
@@ -333,6 +334,7 @@ static const struct rtw_sar_read sar_read_hp = {
 	.gm_end = geo_map_hp + ARRAY_SIZE(geo_map_hp),
 	.rwsi_sz = sizeof(struct rtw_sar_rwsi_hp),
 	.rwgs_sz = sizeof(struct rtw_sar_rwgs_hp),
+	.rwgs_geos = RTW_SAR_RWGS_HP_NR,
 };
 
 static int rwsi_mode_rt(struct rtw_dev *rtwdev, int path)
@@ -364,6 +366,7 @@ static const struct rtw_sar_read sar_read_rt = {
 	.gm_end = geo_map_rt + ARRAY_SIZE(geo_map_rt),
 	.rwsi_sz = sizeof(struct rtw_sar_rwsi_rt),
 	.rwgs_sz = sizeof(struct rtw_sar_rwgs_rt),
+	.rwgs_geos = RTW_SAR_RWGS_RT_NR,
 };
 
 static u8 *rtw_sar_get_raw_package(struct rtw_dev *rtwdev,
@@ -504,6 +507,88 @@ static bool is_valid_rwgs(struct rtw_dev *rtwdev, const struct rtw_sar_rwrd *rwr
 	return false;
 }
 
+#ifdef CONFIG_RTW88_DEBUGFS
+void rtw_sar_dump_via_debugfs(struct rtw_dev *rtwdev, struct seq_file *m)
+{
+#define q3_int(q3)	((q3) >> 3)
+#define q3_fra(q3)	(((q3) & 0x7) * 125)
+
+	const struct rtw_sar_rwrd *rwrd = rtwdev->sar.rwrd;
+	const union rtw_sar_rwsi *rwsi = rtwdev->sar.rwsi;
+	const union rtw_sar_rwgs *rwgs = rtwdev->sar.rwgs;
+	const struct rtw_sar_read *r = rtwdev->sar.read;
+	int q3;
+	int mode;
+	int path;
+	int chidx;
+	int gi;
+	int band;
+
+	if (!rwrd || !rwsi || !rwgs || !r) {
+		seq_puts(m, "(No SAR data)\n");
+		return;
+	}
+
+	seq_printf(m, "Customer ID: 0x%04x\n", rwrd->id);
+	seq_printf(m, "WiFiEnable: 0x%x\n", rwrd->en);
+	seq_printf(m, "Total SAR Table Count: %d\n", rwrd->count);
+	seq_printf(m, "Current SAR Table Index: (%*ph)\n", r->rwsi_sz, rwsi);
+	seq_puts(m, "\n");
+
+	seq_printf(m, "Dump RWRD SAR RAW DATA. (Total Count: %ld)\n",
+		   rwrd->count * sizeof(rwrd->mode[0]));
+	for (mode = 0; mode < rwrd->count; mode++)
+		seq_printf(m, "%02x: %20ph\n", mode + 1, &rwrd->mode[mode]);
+	seq_puts(m, "\n");
+
+	seq_puts(m, "Show SAR PowerLimit:\n");
+	for (path = 0; path < 2; path++) {
+		mode = r->rwsi_mode(rtwdev, path);
+		q3 = r->rwrd_base_q3(rtwdev, mode, path, RTW_SAR_LMT_CH1_14);
+		seq_printf(m, "2.4G Antenna %d: [%d.%d] dBm\n", path,
+			   q3_int(q3), q3_fra(q3));
+	}
+	seq_puts(m, "\n");
+
+	for (path = 0; path < 2; path++) {
+		mode = r->rwsi_mode(rtwdev, path);
+		seq_printf(m, "5G Antenna %d: [", path);
+		for (chidx = RTW_SAR_LMT_CH36_64; chidx <= RTW_SAR_LMT_CH149_165;
+		     chidx++) {
+			q3 = r->rwrd_base_q3(rtwdev, mode, path, chidx);
+			seq_printf(m, "%d.%d, ", q3_int(q3), q3_fra(q3));
+		}
+		seq_puts(m, "] dBm\n");
+	}
+	seq_puts(m, "\n");
+
+	seq_printf(m, "Dump Geo-SAR Table RAW DATA. (Total Count: %d)\n",
+		   r->rwgs_sz);
+	for (gi = 0; gi < r->rwgs_geos; gi++) {
+		seq_printf(m, "geo-%d: %*ph\n", gi, r->rwgs_sz / r->rwgs_geos,
+			   (u8 *)rwgs + gi * (r->rwgs_sz / r->rwgs_geos));
+	}
+	seq_puts(m, "\n");
+
+	gi = 1;	/* take index 1 as an example */
+	seq_puts(m, "Show Geo-SAR PowerLimit:\n");
+	seq_printf(m, "2G Geo Table Index: %d\n", gi);
+	seq_printf(m, "5G Geo Table Index: %d\n", gi);
+	for (band = RTW_SAR_RWGS_2G; band < RTW_SAR_RWGS_BAND_NR; band++) {
+		seq_puts(m, "\n");
+		seq_printf(m, "%dGHz:\n", band == 0 ? 2 : 5);
+		q3 = r->rwgs_max_q3(rtwdev, gi, band);
+		seq_printf(m, "Max Power: [%d.%d] dBm\n", q3_int(q3),
+			   q3_fra(q3));
+		for (path = 0; path < 2; path++) {
+			q3 = r->rwgs_delta_q3(rtwdev, gi, path, band);
+			seq_printf(m, "Ant-%d delta value: [%d.%d] dB\n", path,
+				   q3_int(q3), q3_fra(q3));
+		}
+	}
+}
+#endif
+
 static void rtw_sar_apply_dynamic_tables(struct rtw_dev *rtwdev)
 {
 	struct rtw_hal *hal = &rtwdev->hal;
@@ -653,6 +738,13 @@ static int rtw_sar_load_dynamic_tables(struct rtw_dev *rtwdev)
 {
 	return -ENOENT;
 }
+
+#ifdef CONFIG_RTW88_DEBUGFS
+void rtw_sar_dump_via_debugfs(struct rtw_dev *rtwdev, struct seq_file *m)
+{
+	seq_puts(m, "(No SAR data)\n");
+}
+#endif
 #endif /* CONFIG_ACPI */
 
 void rtw_sar_load_table(struct rtw_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw88/sar.h b/drivers/net/wireless/realtek/rtw88/sar.h
index 154f7bce6759..1f7d877a3797 100644
--- a/drivers/net/wireless/realtek/rtw88/sar.h
+++ b/drivers/net/wireless/realtek/rtw88/sar.h
@@ -8,6 +8,7 @@
 void rtw_sar_load_table(struct rtw_dev *rtwdev);
 void rtw_sar_release_table(struct rtw_dev *rtwdev);
 void rtw_sar_work(struct work_struct *work);
+void rtw_sar_dump_via_debugfs(struct rtw_dev *rtwdev, struct seq_file *m);
 
 #define RTW_SAR_DELAY_TIME	(10 * HZ)
 
