diff --git a/drivers/net/wireless/celeno/cl8k/power_table.c b/drivers/net/wireless/celeno/cl8k/power_table.c
new file mode 100644
index 000000000000..27cbe5596af0
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/power_table.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: MIT
+/* Copyright(c) 2019-2021, Celeno Communications Ltd. */
+
+#include "power_table.h"
+#include "chip.h"
+#include "e2p.h"
+#include "debug.h"
+#include "band.h"
+
+/*
+ * How to fill power table:
+ * Set 81 values in the range of 100 - 180 according to the Excel file.
+ * 100 corresponds to power of -10dBm (Pout Ant).
+ * 180 corresponds to power of +30dBm (Pout Ant).
+ * All values between 0 - 99 should be same as the value of 100.
+ * All values between 181 - 255 should be same as the value of 180.
+ */
+
+static const u8 power_to_powerword_conv_table_id_0[NUM_POWER_WORDS] = {
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 0 - 7 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 8 - 15 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 16 - 23 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 24 - 31 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 32 - 39 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 40 - 47 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 48 - 55 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 56 - 63 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 64 - 71 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 72 - 79 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 80 - 87 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 88 - 95 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x10, 0x11, /* 96 - 103 */
+       0x12, 0x13, 0x14, 0x40, 0x41, 0x42, 0x43, 0x44, /* 104 - 111 */
+       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, /* 112 - 119 */
+       0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, /* 120 - 127 */
+       0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, /* 128 - 135 */
+       0x5D, 0x5E, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, /* 136 - 143 */
+       0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, /* 144 - 151 */
+       0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* 152 - 159 */
+       0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, /* 160 - 167 */
+       0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xF9, 0xFA, 0xFB, /* 168 - 175 */
+       0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 176 - 183 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 184 - 191 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 192 - 199 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 200 - 207 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 208 - 215 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 216 - 223 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 224 - 231 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 232 - 239 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, /* 240 - 247 */
+       0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD  /* 248 - 255 */
+};
+
+static const u8 power_to_powerword_conv_table_id_1[NUM_POWER_WORDS] = {
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 0 - 7 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 8 - 15 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 16 - 23 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 24 - 31 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 32 - 39 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 40 - 47 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 48 - 55 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 56 - 63 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 64 - 71 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 72 - 79 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 80 - 87 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* 88 - 95 */
+       0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x05, 0x06, /* 96 - 103 */
+       0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, /* 104 - 111 */
+       0x0F, 0x10, 0x11, 0x12, 0x40, 0x41, 0x42, 0x43, /* 112 - 119 */
+       0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, /* 120 - 127 */
+       0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, /* 128 - 135 */
+       0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, /* 136 - 143 */
+       0x5C, 0x5D, 0x5E, 0x60, 0x61, 0x62, 0x63, 0x64, /* 144 - 151 */
+       0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, /* 152 - 159 */
+       0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, /* 160 - 167 */
+       0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, /* 168 - 175 */
+       0x7D, 0xB9, 0xBA, 0xBB, 0xBC, 0xBC, 0xBC, 0xBC, /* 176 - 183 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, /* 184 - 191 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, /* 192 - 199 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, /* 200 - 207 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, /* 208 - 215 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, /* 216 - 223 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, /* 224 - 231 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, /* 232 - 239 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, /* 240 - 247 */
+       0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC  /* 248 - 255 */
+};
+
+static const u8 power_to_powerword_conv_table_id_2[NUM_POWER_WORDS] = {
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 0 - 7 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 8 - 15 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 16 - 23 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 24 - 31 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 32 - 39 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 40 - 47 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 48 - 55 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 56 - 63 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 64 - 71 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 72 - 79 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 80 - 87 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 88 - 95 */
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x10, 0x11, /* 96 - 103 */
+       0x12, 0x13, 0x14, 0x40, 0x41, 0x42, 0x43, 0x44, /* 104 - 111 */
+       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, /* 112 - 119 */
+       0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, /* 120 - 127 */
+       0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, /* 128 - 135 */
+       0x5D, 0x5E, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, /* 136 - 143 */
+       0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, /* 144 - 151 */
+       0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* 152 - 159 */
+       0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, /* 160 - 167 */
+       0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBD, 0xBD, 0xBD, /* 168 - 175 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 176 - 183 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 184 - 191 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 192 - 199 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 200 - 207 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 208 - 215 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 216 - 223 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 224 - 231 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 232 - 239 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, /* 240 - 247 */
+       0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD  /* 248 - 255 */
+};
+
+static u8 cl_power_table_read(struct cl_hw *cl_hw)
+{
+       u8 pwr_table_id = 0;
+
+       if (cl_e2p_read(cl_hw->chip, &pwr_table_id, 1, ADDR_GEN_PWR_TABLE_ID + cl_hw->tcv_idx))
+               return U8_MAX;
+
+       return pwr_table_id;
+}
+
+static int cl_power_table_fill(struct cl_hw *cl_hw)
+{
+       u8 pwr_table_id = cl_power_table_read(cl_hw);
+
+       switch (pwr_table_id) {
+       case 0:
+               if (cl_band_is_5g(cl_hw)) {
+                       memcpy(cl_hw->power_table_info.data->conv_table,
+                              power_to_powerword_conv_table_id_0, NUM_POWER_WORDS);
+                       cl_hw->tx_power_version = 5;
+               } else {
+                       CL_DBG_ERROR(cl_hw, "Power table ID (%u) is valid for 5g only\n",
+                                    pwr_table_id);
+
+                       if (!cl_hw->chip->conf->ce_production_mode)
+                               return -1;
+               }
+               break;
+       case 1:
+               if (cl_band_is_24g(cl_hw)) {
+                       memcpy(cl_hw->power_table_info.data->conv_table,
+                              power_to_powerword_conv_table_id_1, NUM_POWER_WORDS);
+                       cl_hw->tx_power_version = 25;
+               } else {
+                       CL_DBG_ERROR(cl_hw, "Power table ID (%u) is valid for 2.4g only\n",
+                                    pwr_table_id);
+
+                       if (!cl_hw->chip->conf->ce_production_mode)
+                               return -1;
+               }
+               break;
+       case 2:
+               if (cl_band_is_6g(cl_hw)) {
+                       memcpy(cl_hw->power_table_info.data->conv_table,
+                              power_to_powerword_conv_table_id_2, NUM_POWER_WORDS);
+                       cl_hw->tx_power_version = 1;
+               } else {
+                       CL_DBG_ERROR(cl_hw, "Power table ID (%u) is valid for 6g only\n",
+                                    pwr_table_id);
+
+                       if (!cl_hw->chip->conf->ce_production_mode)
+                               return -1;
+               }
+               break;
+       default:
+               CL_DBG_ERROR(cl_hw, "Power table ID is not configured in EEPROM\n");
+
+               if (!cl_hw->chip->conf->ce_production_mode)
+                       return -1;
+       }
+
+       cl_dbg_verbose(cl_hw, "Power table ID %u (V%u)\n", pwr_table_id, cl_hw->tx_power_version);
+
+       return 0;
+}
+
+int cl_power_table_alloc(struct cl_hw *cl_hw)
+{
+       struct cl_power_table_data *buf = NULL;
+       u32 len = sizeof(struct cl_power_table_data);
+       dma_addr_t phys_dma_addr;
+
+       buf = dma_alloc_coherent(cl_hw->chip->dev, len, &phys_dma_addr, GFP_KERNEL);
+
+       if (!buf)
+               return -1;
+
+       cl_hw->power_table_info.data = buf;
+       cl_hw->power_table_info.dma_addr = cpu_to_le32(phys_dma_addr);
+
+       return cl_power_table_fill(cl_hw);
+}
+
+void cl_power_table_free(struct cl_hw *cl_hw)
+{
+       struct cl_power_table_info *power_table_info = &cl_hw->power_table_info;
+       u32 len = sizeof(struct cl_power_table_data);
+       dma_addr_t phys_dma_addr = le32_to_cpu(power_table_info->dma_addr);
+
+       if (!power_table_info->data)
+               return;
+
+       dma_free_coherent(cl_hw->chip->dev, len, (void *)power_table_info->data, phys_dma_addr);
+       power_table_info->data = NULL;
+}
