diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 8c9c781..be56787 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -13,6 +13,10 @@
 #include "hif.h"
 #include <linux/remoteproc.h>
 
+#define CORE_TOP_CSR_OFFSET		0x01900000
+#define CORE_TOP_CSR_SIZE		0x100000
+#define TCSR_SOC_HW_VERSION		0x4D000
+
 static const struct of_device_id ath11k_ahb_of_match[] = {
 	/* TODO: Should we change the compatible string to something similar
 	 * to one that ath10k uses?
@@ -650,6 +654,44 @@ static int ath11k_core_get_rproc(struct ath11k_base *ab)
 	return 0;
 }
 
+static int ath11k_check_hw_version(struct ath11k_base *ab)
+{
+	void __iomem *mem_core;
+	u32 soc_hw_version, soc_hw_version_major, soc_hw_version_minor;
+
+	switch (ab->hw_rev) {
+	case ATH11K_HW_IPQ8074:
+	case ATH11K_HW_IPQ6018_HW10:
+		/* CORE_TOP_CSR register is out of wcss */
+		mem_core = ioremap(CORE_TOP_CSR_OFFSET, CORE_TOP_CSR_SIZE);
+		if (IS_ERR(mem_core)) {
+			ath11k_err(ab, "core_top_csr ioremap error\n");
+			return -ENOMEM;
+		}
+		soc_hw_version = ioread32(mem_core + TCSR_SOC_HW_VERSION);
+		iounmap(mem_core);
+		soc_hw_version_major = FIELD_GET(TCSR_SOC_HW_VERSION_MAJOR_MASK,
+						 soc_hw_version);
+		soc_hw_version_minor = FIELD_GET(TCSR_SOC_HW_VERSION_MINOR_MASK,
+						 soc_hw_version);
+
+		ath11k_dbg(ab, ATH11K_DBG_AHB, "tcsr_soc_hw_version major %u minor %u\n",
+			   soc_hw_version_major,
+			   soc_hw_version_minor);
+
+		if (soc_hw_version_major != ath11k_hw_version[ab->hw_rev]) {
+			ath11k_err(ab, "Unsupported SOC hardware version: %u\n",
+				   soc_hw_version_major);
+			return -EOPNOTSUPP;
+		}
+		break;
+	default:
+		ath11k_err(ab, "Unknown hw_ver: %u\n", ab->hw_rev);
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
 static int ath11k_ahb_probe(struct platform_device *pdev)
 {
 	struct ath11k_base *ab;
@@ -691,6 +733,10 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
 	ab->mem_len = resource_size(mem_res);
 	platform_set_drvdata(pdev, ab);
 
+	ret = ath11k_check_hw_version(ab);
+	if (ret)
+		goto err_core_free;
+
 	ret = ath11k_core_pre_init(ab);
 	if (ret)
 		goto err_core_free;
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 2f1e10b..3b93a5d 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -916,6 +916,19 @@ struct ath11k_fw_stats_bcn {
 	u32 tx_bcn_outage_cnt;
 };
 
+#define TCSR_SOC_HW_VERSION_MAJOR_MASK	GENMASK(15, 8)
+#define TCSR_SOC_HW_VERSION_MINOR_MASK	GENMASK(7, 0)
+#define ATH11K_HW_VERSION_HW10		1
+#define ATH11K_HW_VERSION_HW20		2
+
+static const u32 ath11k_hw_version[] = {
+	[ATH11K_HW_IPQ8074] = ATH11K_HW_VERSION_HW20,
+	[ATH11K_HW_QCA6390_HW20] = ATH11K_HW_VERSION_HW20,
+	[ATH11K_HW_IPQ6018_HW10] = ATH11K_HW_VERSION_HW10,
+	[ATH11K_HW_QCN9074_HW10] = ATH11K_HW_VERSION_HW10,
+	[ATH11K_HW_WCN6855_HW20] = ATH11K_HW_VERSION_HW20,
+};
+
 extern const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq8074[];
 extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq8074[];
 extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq6018[];
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index 3d353e7..fb001b7 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -25,8 +25,7 @@
 #define WINDOW_RANGE_MASK		GENMASK(18, 0)
 
 #define TCSR_SOC_HW_VERSION		0x0224
-#define TCSR_SOC_HW_VERSION_MAJOR_MASK	GENMASK(16, 8)
-#define TCSR_SOC_HW_VERSION_MINOR_MASK	GENMASK(7, 0)
+#define QCN9074_TCSR_SOC_HW_VERSION	0x1B00000
 
 /* BAR0 + 4k is always accessible, and no
  * need to force wakeup.
@@ -1206,11 +1205,12 @@ static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
 	.get_ce_msi_idx = ath11k_pci_get_ce_msi_idx,
 };
 
-static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 *minor)
+static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 offset,
+				       u32 *major, u32 *minor)
 {
 	u32 soc_hw_version;
 
-	soc_hw_version = ath11k_pci_read32(ab, TCSR_SOC_HW_VERSION);
+	soc_hw_version = ath11k_pci_read32(ab, offset);
 	*major = FIELD_GET(TCSR_SOC_HW_VERSION_MAJOR_MASK,
 			   soc_hw_version);
 	*minor = FIELD_GET(TCSR_SOC_HW_VERSION_MINOR_MASK,
@@ -1253,10 +1253,11 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
 
 	switch (pci_dev->device) {
 	case QCA6390_DEVICE_ID:
-		ath11k_pci_read_hw_version(ab, &soc_hw_version_major,
+		ath11k_pci_read_hw_version(ab, TCSR_SOC_HW_VERSION,
+					   &soc_hw_version_major,
 					   &soc_hw_version_minor);
 		switch (soc_hw_version_major) {
-		case 2:
+		case ATH11K_HW_VERSION_HW20:
 			ab->hw_rev = ATH11K_HW_QCA6390_HW20;
 			break;
 		default:
@@ -1268,15 +1269,28 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
 		ab_pci->msi_config = &ath11k_msi_config[0];
 		break;
 	case QCN9074_DEVICE_ID:
+		ath11k_pci_read_hw_version(ab, QCN9074_TCSR_SOC_HW_VERSION,
+					   &soc_hw_version_major,
+					   &soc_hw_version_minor);
+		switch (soc_hw_version_major) {
+		case ATH11K_HW_VERSION_HW10:
+			ab->hw_rev = ATH11K_HW_QCN9074_HW10;
+			break;
+		default:
+			dev_err(&pdev->dev, "Unsupported QCN9074 SOC hardware version: %d %d\n",
+				soc_hw_version_major, soc_hw_version_minor);
+			ret = -EOPNOTSUPP;
+			goto err_pci_free_region;
+		}
 		ab_pci->msi_config = &ath11k_msi_config[1];
 		ab->bus_params.static_window_map = true;
-		ab->hw_rev = ATH11K_HW_QCN9074_HW10;
 		break;
 	case WCN6855_DEVICE_ID:
-		ath11k_pci_read_hw_version(ab, &soc_hw_version_major,
+		ath11k_pci_read_hw_version(ab, TCSR_SOC_HW_VERSION,
+					   &soc_hw_version_major,
 					   &soc_hw_version_minor);
 		switch (soc_hw_version_major) {
-		case 2:
+		case ATH11K_HW_VERSION_HW20:
 			ab->hw_rev = ATH11K_HW_WCN6855_HW20;
 			break;
 		default:
