diff --git a/drivers/net/wireless/celeno/cl8k/version.c b/drivers/net/wireless/celeno/cl8k/version.c
new file mode 100644
index 000000000000..1965190a833a
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/version.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/* Copyright(c) 2019-2022, Celeno Communications Ltd. */
+
+#include "debug.h"
+#include "chip.h"
+#include "rfic.h"
+#include "debug.h"
+#include "version.h"
+
+static int cl_version_request(struct cl_hw *cl_hw)
+{
+	struct mm_version_cfm *cfm = NULL;
+	struct cl_version_db *vd = &cl_hw->version_db;
+	int ret = 0;
+
+	ret = cl_msg_tx_version(cl_hw);
+	if (ret)
+		return ret;
+
+	cfm = (struct mm_version_cfm *)cl_hw->msg_cfm_params[MM_VERSION_CFM];
+	if (!cfm)
+		return -ENOMSG;
+
+	vd->last_update = jiffies;
+	vd->dsp = le32_to_cpu(cfm->versions.dsp);
+	vd->rfic_sw = le32_to_cpu(cfm->versions.rfic_sw);
+	vd->rfic_hw = le32_to_cpu(cfm->versions.rfic_hw);
+	vd->agcram = le32_to_cpu(cfm->versions.agcram);
+
+	cl_hw->rf_crystal_mhz = cfm->rf_crystal_mhz;
+
+	strncpy(vd->fw, cfm->versions.fw, sizeof(vd->fw));
+	vd->fw[sizeof(vd->fw) - 1] = '\0';
+
+	strncpy(vd->drv, CONFIG_CL8K_VERSION, sizeof(vd->drv));
+	vd->drv[sizeof(vd->drv) - 1] = '\0';
+
+	cl_msg_tx_free_cfm_params(cl_hw, MM_VERSION_CFM);
+
+	return ret;
+}
+
+int cl_version_read(struct cl_hw *cl_hw, char *buf, ssize_t buf_size, ssize_t *total_len)
+{
+	struct cl_chip *chip = cl_hw->chip;
+	struct cl_version_db *vd = &cl_hw->version_db;
+	struct cl_agc_profile *agc_profile1 = &cl_hw->phy_data_info.data->agc_params.profile1;
+	struct cl_agc_profile *agc_profile2 = &cl_hw->phy_data_info.data->agc_params.profile2;
+	ssize_t len = 0;
+	int ret = 0;
+	u32 version_agcram = 0;
+	u32 major = 0;
+	u32 minor = 0;
+	u32 internal = 0;
+
+	/* Request data if existing is not actual */
+	if (!vd->last_update) {
+		ret = cl_version_request(cl_hw);
+		if (ret)
+			return ret;
+	}
+
+	/* PHY components specifics */
+	len += scnprintf(buf + len, buf_size - len, "DRV VERSION: %s\n", vd->drv);
+	len += scnprintf(buf + len, buf_size - len, "FW VERSION: %s\n", vd->fw);
+	len += scnprintf(buf + len, buf_size - len, "DSP VERSION: 0x%-.8X\n", vd->dsp);
+	len += scnprintf(buf + len, buf_size - len, "RFIC SW VERSION: %u\n", vd->rfic_sw);
+	len += scnprintf(buf + len, buf_size - len, "RFIC HW VERSION: 0x%X\n", vd->rfic_hw);
+
+	version_agcram = vd->agcram;
+	major = (version_agcram >> 16) & 0xffff;
+	minor = (version_agcram >> 8) & 0xff;
+	internal = version_agcram & 0xff;
+
+	len += scnprintf(buf + len, buf_size - len,
+			 "AGC RAM VERSION: B.%x.%x.%x\n", major, minor, internal);
+
+	if (agc_profile1)
+		cl_agc_params_dump_profile_id(buf, buf_size, &len, agc_profile1->id,
+					      "AGC PARAMS PROFILE:");
+	if (agc_profile2)
+		cl_agc_params_dump_profile_id(buf, buf_size, &len, agc_profile2->id,
+					      "AGC PARAMS PROFILE (Elastic):");
+
+	len += scnprintf(buf + len, buf_size - len,
+			 "TX POWER VERSION: %u\n", cl_hw->tx_power_version);
+
+	switch (chip->conf->ci_phy_dev) {
+	case PHY_DEV_OLYMPUS:
+		len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: OLYMPUS\n");
+		break;
+	case PHY_DEV_ATHOS:
+		len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: %s\n",
+				 (cl_hw->chip->rfic_version == ATHOS_A_VER) ? "ATHOS" : "ATHOS B");
+		break;
+	case PHY_DEV_DUMMY:
+		len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: DUMMY\n");
+		break;
+	case PHY_DEV_FRU:
+		len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: FRU\n");
+		break;
+	case PHY_DEV_LOOPBACK:
+		len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: LOOPBACK\n");
+		break;
+	}
+
+	len += scnprintf(buf + len, buf_size - len,
+			 "RF CRYSTAL: %uMHz\n", cl_hw->rf_crystal_mhz);
+	len += scnprintf(buf + len, buf_size - len,
+			 "CHIP ID: 0X%x\n", cl_chip_get_device_id(cl_hw->chip));
+	*total_len = len;
+
+	return 0;
+}
+
+int cl_version_update(struct cl_hw *cl_hw)
+{
+	char *buf = NULL;
+	ssize_t buf_size = PAGE_SIZE;
+	ssize_t len = 0;
+	int ret = 0;
+
+	buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	/* Force logic to update versions */
+	cl_hw->version_db.last_update = 0;
+
+	ret = cl_version_read(cl_hw, buf, buf_size, &len);
+
+	if (ret == 0) {
+		pr_debug("%s\n", buf);
+		/* Share version info */
+		cl_version_sync_wiphy(cl_hw, cl_hw->hw->wiphy);
+	}
+
+	kfree(buf);
+
+	return ret;
+}
+
+void cl_version_sync_wiphy(struct cl_hw *cl_hw, struct wiphy *wiphy)
+{
+	strncpy(wiphy->fw_version, cl_hw->version_db.fw, sizeof(wiphy->fw_version));
+}
+
