#include "wilc_wlan.h"
 #include "wilc_wlan_cfg.h"
 #include "coreconfigurator.h"
+#include "wilc_wfi_netdevice.h"
 
 enum cfg_cmd_type {
        CFG_BYTE_CMD    = 0,
        CFG_BIN_CMD     = 4
 };
 
-struct wilc_mac_cfg {
-       u8 mac_address[7];
-       u8 firmware_version[129];
-       u8 assoc_rsp[256];
-};
-
-static struct wilc_mac_cfg g_mac;
-
-static struct wilc_cfg_byte g_cfg_byte[] = {
+static const struct wilc_cfg_byte g_cfg_byte[] = {
        {WID_STATUS, 0},
        {WID_RSSI, 0},
        {WID_LINKSPEED, 0},
        {WID_NIL, 0}
 };
 
-static struct wilc_cfg_hword g_cfg_hword[] = {
+static const struct wilc_cfg_hword g_cfg_hword[] = {
        {WID_NIL, 0}
 };
 
-static struct wilc_cfg_word g_cfg_word[] = {
+static const struct wilc_cfg_word g_cfg_word[] = {
        {WID_FAILED_COUNT, 0},
        {WID_RECEIVED_FRAGMENT_COUNT, 0},
        {WID_SUCCESS_FRAME_COUNT, 0},
 
 };
 
-static struct wilc_cfg_str g_cfg_str[] = {
-       {WID_FIRMWARE_VERSION, g_mac.firmware_version},
-       {WID_MAC_ADDR, g_mac.mac_address},
-       {WID_ASSOC_RES_INFO, g_mac.assoc_rsp},
+static const struct wilc_cfg_str g_cfg_str[] = {
+       {WID_FIRMWARE_VERSION, NULL},
+       {WID_MAC_ADDR, NULL},
+       {WID_ASSOC_RES_INFO, NULL},
        {WID_NIL, NULL}
 };
 
  ********************************************/
 
 #define GET_WID_TYPE(wid)              (((wid) >> 12) & 0x7)
-static void wilc_wlan_parse_response_frame(u8 *info, int size)
+static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
 {
        u16 wid;
        u32 len = 0, i = 0;
                switch (GET_WID_TYPE(wid)) {
                case WID_CHAR:
                        do {
-                               if (g_cfg_byte[i].id == WID_NIL)
+                               if (wl->cfg.b[i].id == WID_NIL)
                                        break;
 
-                               if (g_cfg_byte[i].id == wid) {
-                                       g_cfg_byte[i].val = info[4];
+                               if (wl->cfg.b[i].id == wid) {
+                                       wl->cfg.b[i].val = info[4];
                                        break;
                                }
                                i++;
 
                case WID_SHORT:
                        do {
-                               if (g_cfg_hword[i].id == WID_NIL)
+                               if (wl->cfg.hw[i].id == WID_NIL)
                                        break;
 
-                               if (g_cfg_hword[i].id == wid) {
-                                       g_cfg_hword[i].val = (info[4] |
-                                                             (info[5] << 8));
+                               if (wl->cfg.hw[i].id == wid) {
+                                       wl->cfg.hw[i].val = (info[4] |
+                                                            (info[5] << 8));
                                        break;
                                }
                                i++;
 
                case WID_INT:
                        do {
-                               if (g_cfg_word[i].id == WID_NIL)
+                               if (wl->cfg.w[i].id == WID_NIL)
                                        break;
 
-                               if (g_cfg_word[i].id == wid) {
-                                       g_cfg_word[i].val = (info[4] |
-                                                            (info[5] << 8) |
-                                                            (info[6] << 16) |
-                                                            (info[7] << 24));
+                               if (wl->cfg.w[i].id == wid) {
+                                       wl->cfg.w[i].val = (info[4] |
+                                                           (info[5] << 8) |
+                                                           (info[6] << 16) |
+                                                           (info[7] << 24));
                                        break;
                                }
                                i++;
 
                case WID_STR:
                        do {
-                               if (g_cfg_str[i].id == WID_NIL)
+                               if (wl->cfg.s[i].id == WID_NIL)
                                        break;
 
-                               if (g_cfg_str[i].id == wid) {
-                                       memcpy(g_cfg_str[i].str, &info[2],
+                               if (wl->cfg.s[i].id == wid) {
+                                       memcpy(wl->cfg.s[i].str, &info[2],
                                               (info[2] + 2));
                                        break;
                                }
        }
 }
 
-static void wilc_wlan_parse_info_frame(u8 *info)
+static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info)
 {
        u32 wid, len;
 
                int i = 0;
 
                do {
-                       if (g_cfg_byte[i].id == WID_NIL)
+                       if (wl->cfg.b[i].id == WID_NIL)
                                break;
 
-                       if (g_cfg_byte[i].id == wid) {
-                               g_cfg_byte[i].val = info[3];
+                       if (wl->cfg.b[i].id == wid) {
+                               wl->cfg.b[i].val = info[3];
                                break;
                        }
                        i++;
        return 2;
 }
 
-int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size)
+int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer,
+                               u32 buffer_size)
 {
        u32 type = (wid >> 12) & 0xf;
        int i, ret = 0;
        i = 0;
        if (type == CFG_BYTE_CMD) {
                do {
-                       if (g_cfg_byte[i].id == WID_NIL)
+                       if (wl->cfg.b[i].id == WID_NIL)
                                break;
 
-                       if (g_cfg_byte[i].id == wid) {
-                               memcpy(buffer,  &g_cfg_byte[i].val, 1);
+                       if (wl->cfg.b[i].id == wid) {
+                               memcpy(buffer, &wl->cfg.b[i].val, 1);
                                ret = 1;
                                break;
                        }
                } while (1);
        } else if (type == CFG_HWORD_CMD) {
                do {
-                       if (g_cfg_hword[i].id == WID_NIL)
+                       if (wl->cfg.hw[i].id == WID_NIL)
                                break;
 
-                       if (g_cfg_hword[i].id == wid) {
-                               memcpy(buffer,  &g_cfg_hword[i].val, 2);
+                       if (wl->cfg.hw[i].id == wid) {
+                               memcpy(buffer, &wl->cfg.hw[i].val, 2);
                                ret = 2;
                                break;
                        }
                } while (1);
        } else if (type == CFG_WORD_CMD) {
                do {
-                       if (g_cfg_word[i].id == WID_NIL)
+                       if (wl->cfg.w[i].id == WID_NIL)
                                break;
 
-                       if (g_cfg_word[i].id == wid) {
-                               memcpy(buffer,  &g_cfg_word[i].val, 4);
+                       if (wl->cfg.w[i].id == wid) {
+                               memcpy(buffer, &wl->cfg.w[i].val, 4);
                                ret = 4;
                                break;
                        }
                } while (1);
        } else if (type == CFG_STR_CMD) {
                do {
-                       u32 id = g_cfg_str[i].id;
+                       u32 id = wl->cfg.s[i].id;
 
                        if (id == WID_NIL)
                                break;
 
                        if (id == wid) {
-                               u32 size = g_cfg_str[i].str[0] |
-                                               (g_cfg_str[i].str[1] << 8);
+                               u32 size = (wl->cfg.s[i].str[0] |
+                                           (wl->cfg.s[i].str[1] << 8));
 
                                if (buffer_size >= size) {
-                                       memcpy(buffer,  &g_cfg_str[i].str[2],
+                                       memcpy(buffer, &wl->cfg.s[i].str[2],
                                               size);
                                        ret = size;
                                }
                        i++;
                } while (1);
        }
-
        return ret;
 }
 
 
        switch (msg_type) {
        case 'R':
-               wilc_wlan_parse_response_frame(frame, size);
+               wilc_wlan_parse_response_frame(wilc, frame, size);
                rsp->type = WILC_CFG_RSP;
                rsp->seq_no = msg_id;
                break;
 
        case 'I':
-               wilc_wlan_parse_info_frame(frame);
+               wilc_wlan_parse_info_frame(wilc, frame);
                rsp->type = WILC_CFG_RSP_STATUS;
                rsp->seq_no = msg_id;
                /*call host interface info parse as well*/
        }
 }
 
-int wilc_wlan_cfg_init(void)
+int wilc_wlan_cfg_init(struct wilc *wl)
+{
+       struct wilc_mac_cfg *mac_cfg;
+       int i = 0;
+
+       wl->cfg.b = kmemdup(g_cfg_byte, sizeof(g_cfg_byte), GFP_KERNEL);
+       if (!wl->cfg.b)
+               return -ENOMEM;
+
+       wl->cfg.hw = kmemdup(g_cfg_hword, sizeof(g_cfg_hword), GFP_KERNEL);
+       if (!wl->cfg.hw)
+               goto out_b;
+
+       wl->cfg.w = kmemdup(g_cfg_word, sizeof(g_cfg_word), GFP_KERNEL);
+       if (!wl->cfg.w)
+               goto out_hw;
+
+       wl->cfg.s = kmemdup(g_cfg_str, sizeof(g_cfg_str), GFP_KERNEL);
+       if (!wl->cfg.s)
+               goto out_w;
+
+       mac_cfg = kzalloc(sizeof(mac_cfg), GFP_KERNEL);
+       if (!mac_cfg)
+               goto out_s;
+
+       wl->cfg.str_vals = mac_cfg;
+       /* store the string cfg parameters */
+       wl->cfg.s[i].id = WID_FIRMWARE_VERSION;
+       wl->cfg.s[i].str = mac_cfg->firmware_version;
+       i++;
+       wl->cfg.s[i].id = WID_MAC_ADDR;
+       wl->cfg.s[i].str = mac_cfg->mac_address;
+       i++;
+       wl->cfg.s[i].id = WID_ASSOC_RES_INFO;
+       wl->cfg.s[i].str = mac_cfg->assoc_rsp;
+       i++;
+       wl->cfg.s[i].id = WID_NIL;
+       wl->cfg.s[i].str = NULL;
+       return 0;
+
+out_s:
+       kfree(wl->cfg.s);
+out_w:
+       kfree(wl->cfg.w);
+out_hw:
+       kfree(wl->cfg.hw);
+out_b:
+       kfree(wl->cfg.b);
+       return -ENOMEM;
+}
+
+void wilc_wlan_cfg_deinit(struct wilc *wl)
 {
-       memset((void *)&g_mac, 0, sizeof(struct wilc_mac_cfg));
-       return 1;
+       kfree(wl->cfg.b);
+       kfree(wl->cfg.hw);
+       kfree(wl->cfg.w);
+       kfree(wl->cfg.s);
+       kfree(wl->cfg.str_vals);
 }