diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index bdf8799..33353a3 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -2193,6 +2193,49 @@ struct mlx5_ifc_cqc_bits {
 	u8 dbr_addr[0x40];
 };
 
+struct mlx5_ifc_health_buffer_bits {
+	u8         reserved_0[0x100];
+	u8         assert_existptr[0x20];
+	u8         assert_callra[0x20];
+	u8         reserved_1[0x40];
+	u8         fw_version[0x20];
+	u8         hw_id[0x20];
+	u8         reserved_2[0x20];
+	u8         irisc_index[0x8];
+	u8         synd[0x8];
+	u8         ext_synd[0x10];
+};
+
+struct mlx5_ifc_initial_seg_bits {
+	u8         fw_rev_minor[0x10];
+	u8         fw_rev_major[0x10];
+	u8         cmd_interface_rev[0x10];
+	u8         fw_rev_subminor[0x10];
+	u8         reserved_0[0x40];
+	u8         cmdq_phy_addr_63_32[0x20];
+	u8         cmdq_phy_addr_31_12[0x14];
+	u8         reserved_1[0x2];
+	u8         nic_interface[0x2];
+	u8         log_cmdq_size[0x4];
+	u8         log_cmdq_stride[0x4];
+	u8         command_doorbell_vector[0x20];
+	u8         reserved_2[0xf00];
+	u8         initializing[0x1];
+	u8         nic_interface_supported[0x7];
+	u8         reserved_4[0x18];
+	struct mlx5_ifc_health_buffer_bits health_buffer;
+	u8         no_dram_nic_offset[0x20];
+	u8         reserved_5[0x6de0];
+	u8         internal_timer_h[0x20];
+	u8         internal_timer_l[0x20];
+	u8         reserved_6[0x20];
+	u8         reserved_7[0x1f];
+	u8         clear_int[0x1];
+	u8         health_syndrome[0x8];
+	u8         health_counter[0x18];
+	u8         reserved_8[0x17fc0];
+};
+
 struct mlx5_ifc_create_cq_out_bits {
 	u8 status[0x8];
 	u8 reserved_at_8[0x18];
diff --git a/drivers/net/mlx5/windows/meson.build b/drivers/net/mlx5/windows/meson.build
new file mode 100644
index 0000000..2ea0792
--- /dev/null
+++ b/drivers/net/mlx5/windows/meson.build
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2020 Mellanox Technologies, Ltd
+
+includes += include_directories('.')
+sources += files(
+	'mlx5_os.c',
+)
+
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
new file mode 100644
index 0000000..e064667
--- /dev/null
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2020 Mellanox Technologies, Ltd
+ */
+
+#include <errno.h>
+#include <stdalign.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <rte_windows.h>
+
+#include <mlx5_glue.h>
+#include <mlx5_devx_cmds.h>
+#include <mlx5_common.h>
+
+#include "mlx5_defs.h"
+#include "mlx5.h"
+#include "mlx5_autoconf.h"
+
+/**
+ * Get mlx5 device attributes.
+ *
+ * @param ctx
+ *   Pointer to device context.
+ *
+ * @param device_attr
+ *   Pointer to mlx5 device attributes.
+ *
+ * @return
+ *   0 on success, non zero error number otherwise
+ */
+int
+mlx5_os_get_dev_attr(void *ctx, struct mlx5_dev_attr *device_attr)
+{
+	struct mlx5_context *mlx5_ctx;
+	struct mlx5_hca_attr hca_attr;
+	void *pv_iseg = NULL;
+	u32 cb_iseg = 0;
+	int err = 0;
+
+	if (!ctx)
+		return -EINVAL;
+	mlx5_ctx = (struct mlx5_context *)ctx;
+	memset(device_attr, 0, sizeof(*device_attr));
+	err = mlx5_devx_cmd_query_hca_attr(mlx5_ctx, &hca_attr);
+	if (err) {
+		DRV_LOG(ERR, "Failed to get device hca_cap");
+		return err;
+	}
+	device_attr->max_cq = 1 << hca_attr.log_max_cq;
+	device_attr->max_qp = 1 << hca_attr.log_max_qp;
+	device_attr->max_qp_wr = 1 << hca_attr.log_max_qp_sz;
+	device_attr->max_cqe = 1 << hca_attr.log_max_cq_sz;
+	device_attr->max_mr = 1 << hca_attr.log_max_mrw_sz;
+	device_attr->max_pd = 1 << hca_attr.log_max_pd;
+	device_attr->max_srq = 1 << hca_attr.log_max_srq;
+	device_attr->max_srq_wr = 1 << hca_attr.log_max_srq_sz;
+	if (hca_attr.rss_ind_tbl_cap) {
+		device_attr->max_rwq_indirection_table_size =
+			1 << hca_attr.rss_ind_tbl_cap;
+	}
+	pv_iseg = mlx5_glue->query_hca_iseg(mlx5_ctx, &cb_iseg);
+	if (pv_iseg == NULL) {
+		DRV_LOG(ERR, "Failed to get device hca_iseg");
+		return errno;
+	}
+	if (!err) {
+		snprintf(device_attr->fw_ver, 64, "%x.%x.%04x",
+			MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
+			MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
+			MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
+	}
+	return err;
+}
