Merge branch 'wilc1000-move-out-of-staging'
authorKalle Valo <kvalo@codeaurora.org>
Thu, 2 Jul 2020 06:49:56 +0000 (09:49 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 2 Jul 2020 06:49:56 +0000 (09:49 +0300)
This is an immutable branch shared between wireless-drivers-next and
staging-next for moving wilc1000 driver out of staging to drivers/net/wireless
directory.

43 files changed:
Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml [new file with mode: 0644]
MAINTAINERS
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/microchip/Kconfig [new file with mode: 0644]
drivers/net/wireless/microchip/Makefile [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/Kconfig [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/Makefile [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/cfg80211.c [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/cfg80211.h [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/fw.h [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/hif.c [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/hif.h [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/mon.c [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/netdev.c [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/netdev.h [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/sdio.c [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/spi.c [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/wlan.c [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/wlan.h [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/wlan_cfg.c [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/wlan_cfg.h [new file with mode: 0644]
drivers/net/wireless/microchip/wilc1000/wlan_if.h [new file with mode: 0644]
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/wilc1000/Kconfig [deleted file]
drivers/staging/wilc1000/Makefile [deleted file]
drivers/staging/wilc1000/cfg80211.c [deleted file]
drivers/staging/wilc1000/cfg80211.h [deleted file]
drivers/staging/wilc1000/fw.h [deleted file]
drivers/staging/wilc1000/hif.c [deleted file]
drivers/staging/wilc1000/hif.h [deleted file]
drivers/staging/wilc1000/microchip,wilc1000.yaml [deleted file]
drivers/staging/wilc1000/mon.c [deleted file]
drivers/staging/wilc1000/netdev.c [deleted file]
drivers/staging/wilc1000/netdev.h [deleted file]
drivers/staging/wilc1000/sdio.c [deleted file]
drivers/staging/wilc1000/spi.c [deleted file]
drivers/staging/wilc1000/wlan.c [deleted file]
drivers/staging/wilc1000/wlan.h [deleted file]
drivers/staging/wilc1000/wlan_cfg.c [deleted file]
drivers/staging/wilc1000/wlan_cfg.h [deleted file]
drivers/staging/wilc1000/wlan_if.h [deleted file]

diff --git a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml
new file mode 100644 (file)
index 0000000..2c320eb
--- /dev/null
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/wireless/microchip,wilc1000.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip WILC wireless devicetree bindings
+
+maintainers:
+  - Adham Abozaeid <adham.abozaeid@microchip.com>
+  - Ajay Singh <ajay.kathat@microchip.com>
+
+description:
+  The wilc1000 chips can be connected via SPI or SDIO. This document
+  describes the binding to connect wilc devices.
+
+properties:
+  compatible:
+    const: microchip,wilc1000
+
+  spi-max-frequency: true
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    description: phandle to the clock connected on rtc clock line.
+    maxItems: 1
+
+  clock-names:
+    const: rtc
+
+required:
+  - compatible
+  - interrupts
+
+examples:
+  - |
+    spi {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      wifi@0 {
+        compatible = "microchip,wilc1000";
+        spi-max-frequency = <48000000>;
+        reg = <0>;
+        interrupt-parent = <&pioC>;
+        interrupts = <27 0>;
+        clocks = <&pck1>;
+        clock-names = "rtc";
+      };
+    };
+
+  - |
+    mmc {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      pinctrl-names = "default";
+      pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
+      non-removable;
+      vmmc-supply = <&vcc_mmc1_reg>;
+      vqmmc-supply = <&vcc_3v3_reg>;
+      bus-width = <4>;
+      wifi@0 {
+        compatible = "microchip,wilc1000";
+        reg = <0>;
+        interrupt-parent = <&pioC>;
+        interrupts = <27 0>;
+        clocks = <&pck1>;
+        clock-names = "rtc";
+      };
+    };
index 68f21d4..7dae51e 100644 (file)
@@ -11362,6 +11362,13 @@ L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 F:     drivers/usb/gadget/udc/atmel_usba_udc.*
 
+MICROCHIP WILC1000 WIFI DRIVER
+M:     Adham Abozaeid <adham.abozaeid@microchip.com>
+M:     Ajay Singh <ajay.kathat@microchip.com>
+L:     linux-wireless@vger.kernel.org
+S:     Supported
+F:     drivers/net/wireless/microchip/wilc1000/
+
 MICROCHIP XDMA DRIVER
 M:     Ludovic Desroches <ludovic.desroches@microchip.com>
 L:     linux-arm-kernel@lists.infradead.org
@@ -16251,13 +16258,6 @@ M:     Forest Bond <forest@alittletooquiet.net>
 S:     Odd Fixes
 F:     drivers/staging/vt665?/
 
-STAGING - WILC1000 WIFI DRIVER
-M:     Adham Abozaeid <adham.abozaeid@microchip.com>
-M:     Ajay Singh <ajay.kathat@microchip.com>
-L:     linux-wireless@vger.kernel.org
-S:     Supported
-F:     drivers/staging/wilc1000/
-
 STAGING SUBSYSTEM
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     devel@driverdev.osuosl.org
index 8ab62bb..75f18c1 100644 (file)
@@ -40,6 +40,7 @@ source "drivers/net/wireless/intel/Kconfig"
 source "drivers/net/wireless/intersil/Kconfig"
 source "drivers/net/wireless/marvell/Kconfig"
 source "drivers/net/wireless/mediatek/Kconfig"
+source "drivers/net/wireless/microchip/Kconfig"
 source "drivers/net/wireless/ralink/Kconfig"
 source "drivers/net/wireless/realtek/Kconfig"
 source "drivers/net/wireless/rsi/Kconfig"
index 6cfe745..80b3244 100644 (file)
@@ -12,6 +12,7 @@ obj-$(CONFIG_WLAN_VENDOR_INTEL) += intel/
 obj-$(CONFIG_WLAN_VENDOR_INTERSIL) += intersil/
 obj-$(CONFIG_WLAN_VENDOR_MARVELL) += marvell/
 obj-$(CONFIG_WLAN_VENDOR_MEDIATEK) += mediatek/
+obj-$(CONFIG_WLAN_VENDOR_MICROCHIP) += microchip/
 obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/
 obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/
 obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/
diff --git a/drivers/net/wireless/microchip/Kconfig b/drivers/net/wireless/microchip/Kconfig
new file mode 100644 (file)
index 0000000..a6b46fb
--- /dev/null
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+config WLAN_VENDOR_MICROCHIP
+       bool "Microchip devices"
+       default y
+       help
+       If you have a wireless card belonging to this class, say Y.
+
+       Note that the answer to this question doesn't directly affect the
+       kernel: saying N will just cause the configurator to skip all the
+       questions about these cards. If you say Y, you will be asked for
+       your specific card in the following questions.
+
+if WLAN_VENDOR_MICROCHIP
+source "drivers/net/wireless/microchip/wilc1000/Kconfig"
+endif # WLAN_VENDOR_MICROCHIP
diff --git a/drivers/net/wireless/microchip/Makefile b/drivers/net/wireless/microchip/Makefile
new file mode 100644 (file)
index 0000000..73b763c
--- /dev/null
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_WILC1000)         += wilc1000/
diff --git a/drivers/net/wireless/microchip/wilc1000/Kconfig b/drivers/net/wireless/microchip/wilc1000/Kconfig
new file mode 100644 (file)
index 0000000..80c92e8
--- /dev/null
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0
+config WILC1000
+       tristate
+       help
+         Add support for the Atmel WILC1000 802.11 b/g/n SoC.
+         This provides Wi-FI over an SDIO or SPI interface, and
+         is usually found in IoT devices.
+
+         This module only support IEEE 802.11n WiFi.
+
+config WILC1000_SDIO
+       tristate "Atmel WILC1000 SDIO (WiFi only)"
+       depends on CFG80211 && INET && MMC
+       select WILC1000
+       help
+         This module adds support for the SDIO interface of adapters using
+         WILC1000 chipset. The Atmel WILC1000 SDIO is a full speed interface.
+         It meets SDIO card specification version 2.0. The interface supports
+         the 1-bit/4-bit SD transfer mode at the clock range of 0-50 MHz.
+         The host can use this interface to read and write from any register
+         within the chip as well as configure the WILC1000 for data DMA.
+         To use this interface, pin9 (SDIO_SPI_CFG) must be grounded. Select
+         this if your platform is using the SDIO bus.
+
+config WILC1000_SPI
+       tristate "Atmel WILC1000 SPI (WiFi only)"
+       depends on CFG80211 && INET && SPI
+       select WILC1000
+       select CRC7
+       help
+         This module adds support for the SPI interface of adapters using
+         WILC1000 chipset. The Atmel WILC1000 has a Serial Peripheral
+         Interface (SPI) that operates as a SPI slave. This SPI interface can
+         be used for control and for serial I/O of 802.11 data. The SPI is a
+         full-duplex slave synchronous serial interface that is available
+         immediately following reset when pin 9 (SDIO_SPI_CFG) is tied to
+         VDDIO. Select this if your platform is using the SPI bus.
+
+config WILC1000_HW_OOB_INTR
+       bool "WILC1000 out of band interrupt"
+       depends on WILC1000_SDIO
+       help
+         This option enables out-of-band interrupt support for the WILC1000
+         chipset. This OOB interrupt is intended to provide a faster interrupt
+         mechanism for SDIO host controllers that don't support SDIO interrupt.
+         Select this option If the SDIO host controller in your platform
+         doesn't support SDIO time devision interrupt.
diff --git a/drivers/net/wireless/microchip/wilc1000/Makefile b/drivers/net/wireless/microchip/wilc1000/Makefile
new file mode 100644 (file)
index 0000000..a3305a0
--- /dev/null
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_WILC1000) += wilc1000.o
+
+ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
+               -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\"
+
+wilc1000-objs := cfg80211.o netdev.o mon.o \
+                       hif.o wlan_cfg.o wlan.o
+
+obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o
+wilc1000-sdio-objs += sdio.o
+
+obj-$(CONFIG_WILC1000_SPI) += wilc1000-spi.o
+wilc1000-spi-objs += spi.o
diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
new file mode 100644 (file)
index 0000000..b6065a0
--- /dev/null
@@ -0,0 +1,1847 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#include "cfg80211.h"
+
+#define GO_NEG_REQ                     0x00
+#define GO_NEG_RSP                     0x01
+#define GO_NEG_CONF                    0x02
+#define P2P_INV_REQ                    0x03
+#define P2P_INV_RSP                    0x04
+
+#define WILC_INVALID_CHANNEL           0
+
+/* Operation at 2.4 GHz with channels 1-13 */
+#define WILC_WLAN_OPERATING_CLASS_2_4GHZ               0x51
+
+static const struct ieee80211_txrx_stypes
+       wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
+       [NL80211_IFTYPE_STATION] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+       },
+       [NL80211_IFTYPE_AP] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+                       BIT(IEEE80211_STYPE_AUTH >> 4) |
+                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+                       BIT(IEEE80211_STYPE_ACTION >> 4)
+       },
+       [NL80211_IFTYPE_P2P_CLIENT] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+                       BIT(IEEE80211_STYPE_AUTH >> 4) |
+                       BIT(IEEE80211_STYPE_DEAUTH >> 4)
+       }
+};
+
+static const struct wiphy_wowlan_support wowlan_support = {
+       .flags = WIPHY_WOWLAN_ANY
+};
+
+struct wilc_p2p_mgmt_data {
+       int size;
+       u8 *buff;
+};
+
+struct wilc_p2p_pub_act_frame {
+       u8 category;
+       u8 action;
+       u8 oui[3];
+       u8 oui_type;
+       u8 oui_subtype;
+       u8 dialog_token;
+       u8 elem[];
+} __packed;
+
+struct wilc_vendor_specific_ie {
+       u8 tag_number;
+       u8 tag_len;
+       u8 oui[3];
+       u8 oui_type;
+       u8 attr[];
+} __packed;
+
+struct wilc_attr_entry {
+       u8  attr_type;
+       __le16 attr_len;
+       u8 val[];
+} __packed;
+
+struct wilc_attr_oper_ch {
+       u8 attr_type;
+       __le16 attr_len;
+       u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+       u8 op_class;
+       u8 op_channel;
+} __packed;
+
+struct wilc_attr_ch_list {
+       u8 attr_type;
+       __le16 attr_len;
+       u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+       u8 elem[];
+} __packed;
+
+struct wilc_ch_list_elem {
+       u8 op_class;
+       u8 no_of_channels;
+       u8 ch_list[];
+} __packed;
+
+static void cfg_scan_result(enum scan_event scan_event,
+                           struct wilc_rcvd_net_info *info, void *user_void)
+{
+       struct wilc_priv *priv = user_void;
+
+       if (!priv->cfg_scanning)
+               return;
+
+       if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
+               s32 freq;
+               struct ieee80211_channel *channel;
+               struct cfg80211_bss *bss;
+               struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
+
+               if (!wiphy || !info)
+                       return;
+
+               freq = ieee80211_channel_to_frequency((s32)info->ch,
+                                                     NL80211_BAND_2GHZ);
+               channel = ieee80211_get_channel(wiphy, freq);
+               if (!channel)
+                       return;
+
+               bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt,
+                                               info->frame_len,
+                                               (s32)info->rssi * 100,
+                                               GFP_KERNEL);
+               if (!bss)
+                       cfg80211_put_bss(wiphy, bss);
+       } else if (scan_event == SCAN_EVENT_DONE) {
+               mutex_lock(&priv->scan_req_lock);
+
+               if (priv->scan_req) {
+                       struct cfg80211_scan_info info = {
+                               .aborted = false,
+                       };
+
+                       cfg80211_scan_done(priv->scan_req, &info);
+                       priv->cfg_scanning = false;
+                       priv->scan_req = NULL;
+               }
+               mutex_unlock(&priv->scan_req_lock);
+       } else if (scan_event == SCAN_EVENT_ABORTED) {
+               mutex_lock(&priv->scan_req_lock);
+
+               if (priv->scan_req) {
+                       struct cfg80211_scan_info info = {
+                               .aborted = false,
+                       };
+
+                       cfg80211_scan_done(priv->scan_req, &info);
+                       priv->cfg_scanning = false;
+                       priv->scan_req = NULL;
+               }
+               mutex_unlock(&priv->scan_req_lock);
+       }
+}
+
+static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
+                              void *priv_data)
+{
+       struct wilc_priv *priv = priv_data;
+       struct net_device *dev = priv->dev;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wl = vif->wilc;
+       struct host_if_drv *wfi_drv = priv->hif_drv;
+       struct wilc_conn_info *conn_info = &wfi_drv->conn_info;
+       struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+
+       vif->connecting = false;
+
+       if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
+               u16 connect_status = conn_info->status;
+
+               if (mac_status == WILC_MAC_STATUS_DISCONNECTED &&
+                   connect_status == WLAN_STATUS_SUCCESS) {
+                       connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+                       wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
+
+                       if (vif->iftype != WILC_CLIENT_MODE)
+                               wl->sta_ch = WILC_INVALID_CHANNEL;
+
+                       netdev_err(dev, "Unspecified failure\n");
+               }
+
+               if (connect_status == WLAN_STATUS_SUCCESS)
+                       memcpy(priv->associated_bss, conn_info->bssid,
+                              ETH_ALEN);
+
+               cfg80211_ref_bss(wiphy, vif->bss);
+               cfg80211_connect_bss(dev, conn_info->bssid, vif->bss,
+                                    conn_info->req_ies,
+                                    conn_info->req_ies_len,
+                                    conn_info->resp_ies,
+                                    conn_info->resp_ies_len,
+                                    connect_status, GFP_KERNEL,
+                                    NL80211_TIMEOUT_UNSPECIFIED);
+
+               vif->bss = NULL;
+       } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
+               u16 reason = 0;
+
+               eth_zero_addr(priv->associated_bss);
+               wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
+
+               if (vif->iftype != WILC_CLIENT_MODE) {
+                       wl->sta_ch = WILC_INVALID_CHANNEL;
+               } else {
+                       if (wfi_drv->ifc_up)
+                               reason = 3;
+                       else
+                               reason = 1;
+               }
+
+               cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
+       }
+}
+
+struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
+{
+       struct wilc_vif *vif;
+
+       vif = list_first_or_null_rcu(&wl->vif_list, typeof(*vif), list);
+       if (!vif)
+               return ERR_PTR(-EINVAL);
+
+       return vif;
+}
+
+static int set_channel(struct wiphy *wiphy,
+                      struct cfg80211_chan_def *chandef)
+{
+       struct wilc *wl = wiphy_priv(wiphy);
+       struct wilc_vif *vif;
+       u32 channelnum;
+       int result;
+       int srcu_idx;
+
+       srcu_idx = srcu_read_lock(&wl->srcu);
+       vif = wilc_get_wl_to_vif(wl);
+       if (IS_ERR(vif)) {
+               srcu_read_unlock(&wl->srcu, srcu_idx);
+               return PTR_ERR(vif);
+       }
+
+       channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
+
+       wl->op_ch = channelnum;
+       result = wilc_set_mac_chnl_num(vif, channelnum);
+       if (result)
+               netdev_err(vif->ndev, "Error in setting channel\n");
+
+       srcu_read_unlock(&wl->srcu, srcu_idx);
+       return result;
+}
+
+static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
+{
+       struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
+       struct wilc_priv *priv = &vif->priv;
+       u32 i;
+       int ret = 0;
+       u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
+       u8 scan_type;
+
+       if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
+               netdev_err(vif->ndev, "Requested scanned channels over\n");
+               return -EINVAL;
+       }
+
+       priv->scan_req = request;
+       priv->cfg_scanning = true;
+       for (i = 0; i < request->n_channels; i++) {
+               u16 freq = request->channels[i]->center_freq;
+
+               scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
+       }
+
+       if (request->n_ssids)
+               scan_type = WILC_FW_ACTIVE_SCAN;
+       else
+               scan_type = WILC_FW_PASSIVE_SCAN;
+
+       ret = wilc_scan(vif, WILC_FW_USER_SCAN, scan_type, scan_ch_list,
+                       request->n_channels, cfg_scan_result, (void *)priv,
+                       request);
+
+       if (ret) {
+               priv->scan_req = NULL;
+               priv->cfg_scanning = false;
+       }
+
+       return ret;
+}
+
+static int connect(struct wiphy *wiphy, struct net_device *dev,
+                  struct cfg80211_connect_params *sme)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc_priv *priv = &vif->priv;
+       struct host_if_drv *wfi_drv = priv->hif_drv;
+       int ret;
+       u32 i;
+       u8 security = WILC_FW_SEC_NO;
+       enum authtype auth_type = WILC_FW_AUTH_ANY;
+       u32 cipher_group;
+       struct cfg80211_bss *bss;
+       void *join_params;
+       u8 ch;
+
+       vif->connecting = true;
+
+       memset(priv->wep_key, 0, sizeof(priv->wep_key));
+       memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
+
+       cipher_group = sme->crypto.cipher_group;
+       if (cipher_group != 0) {
+               if (cipher_group == WLAN_CIPHER_SUITE_WEP40) {
+                       security = WILC_FW_SEC_WEP;
+
+                       priv->wep_key_len[sme->key_idx] = sme->key_len;
+                       memcpy(priv->wep_key[sme->key_idx], sme->key,
+                              sme->key_len);
+
+                       wilc_set_wep_default_keyid(vif, sme->key_idx);
+                       wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
+                                                sme->key_idx);
+               } else if (cipher_group == WLAN_CIPHER_SUITE_WEP104) {
+                       security = WILC_FW_SEC_WEP_EXTENDED;
+
+                       priv->wep_key_len[sme->key_idx] = sme->key_len;
+                       memcpy(priv->wep_key[sme->key_idx], sme->key,
+                              sme->key_len);
+
+                       wilc_set_wep_default_keyid(vif, sme->key_idx);
+                       wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
+                                                sme->key_idx);
+               } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
+                       if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
+                               security = WILC_FW_SEC_WPA2_TKIP;
+                       else
+                               security = WILC_FW_SEC_WPA2_AES;
+               } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
+                       if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
+                               security = WILC_FW_SEC_WPA_TKIP;
+                       else
+                               security = WILC_FW_SEC_WPA_AES;
+               } else {
+                       ret = -ENOTSUPP;
+                       netdev_err(dev, "%s: Unsupported cipher\n",
+                                  __func__);
+                       goto out_error;
+               }
+       }
+
+       if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
+           (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
+               for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
+                       u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];
+
+                       if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
+                               security |= WILC_FW_TKIP;
+                       else
+                               security |= WILC_FW_AES;
+               }
+       }
+
+       switch (sme->auth_type) {
+       case NL80211_AUTHTYPE_OPEN_SYSTEM:
+               auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
+               break;
+
+       case NL80211_AUTHTYPE_SHARED_KEY:
+               auth_type = WILC_FW_AUTH_SHARED_KEY;
+               break;
+
+       default:
+               break;
+       }
+
+       if (sme->crypto.n_akm_suites) {
+               if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
+                       auth_type = WILC_FW_AUTH_IEEE8021;
+       }
+
+       if (wfi_drv->usr_scan_req.scan_result) {
+               netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
+               ret = -EBUSY;
+               goto out_error;
+       }
+
+       bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid,
+                              sme->ssid_len, IEEE80211_BSS_TYPE_ANY,
+                              IEEE80211_PRIVACY(sme->privacy));
+       if (!bss) {
+               ret = -EINVAL;
+               goto out_error;
+       }
+
+       if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) {
+               ret = -EALREADY;
+               goto out_put_bss;
+       }
+
+       join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
+       if (!join_params) {
+               netdev_err(dev, "%s: failed to construct join param\n",
+                          __func__);
+               ret = -EINVAL;
+               goto out_put_bss;
+       }
+
+       ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
+       vif->wilc->op_ch = ch;
+       if (vif->iftype != WILC_CLIENT_MODE)
+               vif->wilc->sta_ch = ch;
+
+       wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE);
+
+       wfi_drv->conn_info.security = security;
+       wfi_drv->conn_info.auth_type = auth_type;
+       wfi_drv->conn_info.ch = ch;
+       wfi_drv->conn_info.conn_result = cfg_connect_result;
+       wfi_drv->conn_info.arg = priv;
+       wfi_drv->conn_info.param = join_params;
+
+       ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
+       if (ret) {
+               netdev_err(dev, "wilc_set_join_req(): Error\n");
+               ret = -ENOENT;
+               if (vif->iftype != WILC_CLIENT_MODE)
+                       vif->wilc->sta_ch = WILC_INVALID_CHANNEL;
+               wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE);
+               wfi_drv->conn_info.conn_result = NULL;
+               kfree(join_params);
+               goto out_put_bss;
+       }
+       kfree(join_params);
+       vif->bss = bss;
+       cfg80211_put_bss(wiphy, bss);
+       return 0;
+
+out_put_bss:
+       cfg80211_put_bss(wiphy, bss);
+
+out_error:
+       vif->connecting = false;
+       return ret;
+}
+
+static int disconnect(struct wiphy *wiphy, struct net_device *dev,
+                     u16 reason_code)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc_priv *priv = &vif->priv;
+       struct wilc *wilc = vif->wilc;
+       int ret;
+
+       vif->connecting = false;
+
+       if (!wilc)
+               return -EIO;
+
+       if (wilc->close) {
+               /* already disconnected done */
+               cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
+               return 0;
+       }
+
+       if (vif->iftype != WILC_CLIENT_MODE)
+               wilc->sta_ch = WILC_INVALID_CHANNEL;
+       wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
+
+       priv->hif_drv->p2p_timeout = 0;
+
+       ret = wilc_disconnect(vif);
+       if (ret != 0) {
+               netdev_err(priv->dev, "Error in disconnecting\n");
+               ret = -EINVAL;
+       }
+
+       vif->bss = NULL;
+
+       return ret;
+}
+
+static inline void wilc_wfi_cfg_copy_wep_info(struct wilc_priv *priv,
+                                             u8 key_index,
+                                             struct key_params *params)
+{
+       priv->wep_key_len[key_index] = params->key_len;
+       memcpy(priv->wep_key[key_index], params->key, params->key_len);
+}
+
+static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
+{
+       if (!priv->wilc_gtk[idx]) {
+               priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
+                                             GFP_KERNEL);
+               if (!priv->wilc_gtk[idx])
+                       return -ENOMEM;
+       }
+
+       if (!priv->wilc_ptk[idx]) {
+               priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
+                                             GFP_KERNEL);
+               if (!priv->wilc_ptk[idx])
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
+                                     struct key_params *params)
+{
+       kfree(key_info->key);
+
+       key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
+       if (!key_info->key)
+               return -ENOMEM;
+
+       kfree(key_info->seq);
+
+       if (params->seq_len > 0) {
+               key_info->seq = kmemdup(params->seq, params->seq_len,
+                                       GFP_KERNEL);
+               if (!key_info->seq)
+                       return -ENOMEM;
+       }
+
+       key_info->cipher = params->cipher;
+       key_info->key_len = params->key_len;
+       key_info->seq_len = params->seq_len;
+
+       return 0;
+}
+
+static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
+                  bool pairwise, const u8 *mac_addr, struct key_params *params)
+
+{
+       int ret = 0, keylen = params->key_len;
+       const u8 *rx_mic = NULL;
+       const u8 *tx_mic = NULL;
+       u8 mode = WILC_FW_SEC_NO;
+       u8 op_mode;
+       struct wilc_vif *vif = netdev_priv(netdev);
+       struct wilc_priv *priv = &vif->priv;
+
+       switch (params->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+               if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
+                       wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
+
+                       if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
+                               mode = WILC_FW_SEC_WEP;
+                       else
+                               mode = WILC_FW_SEC_WEP_EXTENDED;
+
+                       ret = wilc_add_wep_key_bss_ap(vif, params->key,
+                                                     params->key_len,
+                                                     key_index, mode,
+                                                     WILC_FW_AUTH_OPEN_SYSTEM);
+                       break;
+               }
+               if (memcmp(params->key, priv->wep_key[key_index],
+                          params->key_len)) {
+                       wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
+
+                       ret = wilc_add_wep_key_bss_sta(vif, params->key,
+                                                      params->key_len,
+                                                      key_index);
+               }
+
+               break;
+
+       case WLAN_CIPHER_SUITE_TKIP:
+       case WLAN_CIPHER_SUITE_CCMP:
+               if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
+                   priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
+                       struct wilc_wfi_key *key;
+
+                       ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
+                       if (ret)
+                               return -ENOMEM;
+
+                       if (params->key_len > 16 &&
+                           params->cipher == WLAN_CIPHER_SUITE_TKIP) {
+                               tx_mic = params->key + 24;
+                               rx_mic = params->key + 16;
+                               keylen = params->key_len - 16;
+                       }
+
+                       if (!pairwise) {
+                               if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
+                                       mode = WILC_FW_SEC_WPA_TKIP;
+                               else
+                                       mode = WILC_FW_SEC_WPA2_AES;
+
+                               priv->wilc_groupkey = mode;
+
+                               key = priv->wilc_gtk[key_index];
+                       } else {
+                               if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
+                                       mode = WILC_FW_SEC_WPA_TKIP;
+                               else
+                                       mode = priv->wilc_groupkey | WILC_FW_AES;
+
+                               key = priv->wilc_ptk[key_index];
+                       }
+                       ret = wilc_wfi_cfg_copy_wpa_info(key, params);
+                       if (ret)
+                               return -ENOMEM;
+
+                       op_mode = WILC_AP_MODE;
+               } else {
+                       if (params->key_len > 16 &&
+                           params->cipher == WLAN_CIPHER_SUITE_TKIP) {
+                               rx_mic = params->key + 24;
+                               tx_mic = params->key + 16;
+                               keylen = params->key_len - 16;
+                       }
+
+                       op_mode = WILC_STATION_MODE;
+               }
+
+               if (!pairwise)
+                       ret = wilc_add_rx_gtk(vif, params->key, keylen,
+                                             key_index, params->seq_len,
+                                             params->seq, rx_mic, tx_mic,
+                                             op_mode, mode);
+               else
+                       ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
+                                          rx_mic, tx_mic, op_mode, mode,
+                                          key_index);
+
+               break;
+
+       default:
+               netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
+               ret = -ENOTSUPP;
+       }
+
+       return ret;
+}
+
+static int del_key(struct wiphy *wiphy, struct net_device *netdev,
+                  u8 key_index,
+                  bool pairwise,
+                  const u8 *mac_addr)
+{
+       struct wilc_vif *vif = netdev_priv(netdev);
+       struct wilc_priv *priv = &vif->priv;
+
+       if (priv->wilc_gtk[key_index]) {
+               kfree(priv->wilc_gtk[key_index]->key);
+               priv->wilc_gtk[key_index]->key = NULL;
+               kfree(priv->wilc_gtk[key_index]->seq);
+               priv->wilc_gtk[key_index]->seq = NULL;
+
+               kfree(priv->wilc_gtk[key_index]);
+               priv->wilc_gtk[key_index] = NULL;
+       }
+
+       if (priv->wilc_ptk[key_index]) {
+               kfree(priv->wilc_ptk[key_index]->key);
+               priv->wilc_ptk[key_index]->key = NULL;
+               kfree(priv->wilc_ptk[key_index]->seq);
+               priv->wilc_ptk[key_index]->seq = NULL;
+               kfree(priv->wilc_ptk[key_index]);
+               priv->wilc_ptk[key_index] = NULL;
+       }
+
+       if (key_index <= 3 && priv->wep_key_len[key_index]) {
+               memset(priv->wep_key[key_index], 0,
+                      priv->wep_key_len[key_index]);
+               priv->wep_key_len[key_index] = 0;
+               wilc_remove_wep_key(vif, key_index);
+       }
+
+       return 0;
+}
+
+static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
+                  bool pairwise, const u8 *mac_addr, void *cookie,
+                  void (*callback)(void *cookie, struct key_params *))
+{
+       struct wilc_vif *vif = netdev_priv(netdev);
+       struct wilc_priv *priv = &vif->priv;
+       struct  key_params key_params;
+
+       if (!pairwise) {
+               key_params.key = priv->wilc_gtk[key_index]->key;
+               key_params.cipher = priv->wilc_gtk[key_index]->cipher;
+               key_params.key_len = priv->wilc_gtk[key_index]->key_len;
+               key_params.seq = priv->wilc_gtk[key_index]->seq;
+               key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
+       } else {
+               key_params.key = priv->wilc_ptk[key_index]->key;
+               key_params.cipher = priv->wilc_ptk[key_index]->cipher;
+               key_params.key_len = priv->wilc_ptk[key_index]->key_len;
+               key_params.seq = priv->wilc_ptk[key_index]->seq;
+               key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
+       }
+
+       callback(cookie, &key_params);
+
+       return 0;
+}
+
+static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
+                          u8 key_index, bool unicast, bool multicast)
+{
+       struct wilc_vif *vif = netdev_priv(netdev);
+
+       wilc_set_wep_default_keyid(vif, key_index);
+
+       return 0;
+}
+
+static int get_station(struct wiphy *wiphy, struct net_device *dev,
+                      const u8 *mac, struct station_info *sinfo)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc_priv *priv = &vif->priv;
+       u32 i = 0;
+       u32 associatedsta = ~0;
+       u32 inactive_time = 0;
+
+       if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
+               for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
+                       if (!(memcmp(mac,
+                                    priv->assoc_stainfo.sta_associated_bss[i],
+                                    ETH_ALEN))) {
+                               associatedsta = i;
+                               break;
+                       }
+               }
+
+               if (associatedsta == ~0) {
+                       netdev_err(dev, "sta required is not associated\n");
+                       return -ENOENT;
+               }
+
+               sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
+
+               wilc_get_inactive_time(vif, mac, &inactive_time);
+               sinfo->inactive_time = 1000 * inactive_time;
+       } else if (vif->iftype == WILC_STATION_MODE) {
+               struct rf_info stats;
+
+               wilc_get_statistics(vif, &stats);
+
+               sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
+                                BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
+                                BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
+                                BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
+                                BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+
+               sinfo->signal = stats.rssi;
+               sinfo->rx_packets = stats.rx_cnt;
+               sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
+               sinfo->tx_failed = stats.tx_fail_cnt;
+               sinfo->txrate.legacy = stats.link_speed * 10;
+
+               if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
+                   stats.link_speed != DEFAULT_LINK_SPEED)
+                       wilc_enable_tcp_ack_filter(vif, true);
+               else if (stats.link_speed != DEFAULT_LINK_SPEED)
+                       wilc_enable_tcp_ack_filter(vif, false);
+       }
+       return 0;
+}
+
+static int change_bss(struct wiphy *wiphy, struct net_device *dev,
+                     struct bss_parameters *params)
+{
+       return 0;
+}
+
+static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+       int ret = -EINVAL;
+       struct cfg_param_attr cfg_param_val;
+       struct wilc *wl = wiphy_priv(wiphy);
+       struct wilc_vif *vif;
+       struct wilc_priv *priv;
+       int srcu_idx;
+
+       srcu_idx = srcu_read_lock(&wl->srcu);
+       vif = wilc_get_wl_to_vif(wl);
+       if (IS_ERR(vif))
+               goto out;
+
+       priv = &vif->priv;
+       cfg_param_val.flag = 0;
+
+       if (changed & WIPHY_PARAM_RETRY_SHORT) {
+               netdev_dbg(vif->ndev,
+                          "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
+                          wiphy->retry_short);
+               cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
+               cfg_param_val.short_retry_limit = wiphy->retry_short;
+       }
+       if (changed & WIPHY_PARAM_RETRY_LONG) {
+               netdev_dbg(vif->ndev,
+                          "Setting WIPHY_PARAM_RETRY_LONG %d\n",
+                          wiphy->retry_long);
+               cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
+               cfg_param_val.long_retry_limit = wiphy->retry_long;
+       }
+       if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
+               if (wiphy->frag_threshold > 255 &&
+                   wiphy->frag_threshold < 7937) {
+                       netdev_dbg(vif->ndev,
+                                  "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
+                                  wiphy->frag_threshold);
+                       cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
+                       cfg_param_val.frag_threshold = wiphy->frag_threshold;
+               } else {
+                       netdev_err(vif->ndev,
+                                  "Fragmentation threshold out of range\n");
+                       goto out;
+               }
+       }
+
+       if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+               if (wiphy->rts_threshold > 255) {
+                       netdev_dbg(vif->ndev,
+                                  "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
+                                  wiphy->rts_threshold);
+                       cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
+                       cfg_param_val.rts_threshold = wiphy->rts_threshold;
+               } else {
+                       netdev_err(vif->ndev, "RTS threshold out of range\n");
+                       goto out;
+               }
+       }
+
+       ret = wilc_hif_set_cfg(vif, &cfg_param_val);
+       if (ret)
+               netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
+
+out:
+       srcu_read_unlock(&wl->srcu, srcu_idx);
+       return ret;
+}
+
+static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+                    struct cfg80211_pmksa *pmksa)
+{
+       struct wilc_vif *vif = netdev_priv(netdev);
+       struct wilc_priv *priv = &vif->priv;
+       u32 i;
+       int ret = 0;
+       u8 flag = 0;
+
+       for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
+               if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
+                           ETH_ALEN)) {
+                       flag = PMKID_FOUND;
+                       break;
+               }
+       }
+       if (i < WILC_MAX_NUM_PMKIDS) {
+               memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
+                      ETH_ALEN);
+               memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
+                      WLAN_PMKID_LEN);
+               if (!(flag == PMKID_FOUND))
+                       priv->pmkid_list.numpmkid++;
+       } else {
+               netdev_err(netdev, "Invalid PMKID index\n");
+               ret = -EINVAL;
+       }
+
+       if (!ret)
+               ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
+
+       return ret;
+}
+
+static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+                    struct cfg80211_pmksa *pmksa)
+{
+       u32 i;
+       struct wilc_vif *vif = netdev_priv(netdev);
+       struct wilc_priv *priv = &vif->priv;
+
+       for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
+               if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
+                           ETH_ALEN)) {
+                       memset(&priv->pmkid_list.pmkidlist[i], 0,
+                              sizeof(struct wilc_pmkid));
+                       break;
+               }
+       }
+
+       if (i == priv->pmkid_list.numpmkid)
+               return -EINVAL;
+
+       for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
+               memcpy(priv->pmkid_list.pmkidlist[i].bssid,
+                      priv->pmkid_list.pmkidlist[i + 1].bssid,
+                      ETH_ALEN);
+               memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
+                      priv->pmkid_list.pmkidlist[i + 1].pmkid,
+                      WLAN_PMKID_LEN);
+       }
+       priv->pmkid_list.numpmkid--;
+
+       return 0;
+}
+
+static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
+{
+       struct wilc_vif *vif = netdev_priv(netdev);
+
+       memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
+
+       return 0;
+}
+
+static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
+{
+       struct wilc_attr_entry *e;
+       struct wilc_attr_ch_list *ch_list;
+       struct wilc_attr_oper_ch *op_ch;
+       u32 index = 0;
+       u8 ch_list_idx = 0;
+       u8 op_ch_idx = 0;
+
+       if (sta_ch == WILC_INVALID_CHANNEL)
+               return;
+
+       while (index + sizeof(*e) <= len) {
+               e = (struct wilc_attr_entry *)&buf[index];
+               if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
+                       ch_list_idx = index;
+               else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
+                       op_ch_idx = index;
+               if (ch_list_idx && op_ch_idx)
+                       break;
+               index += le16_to_cpu(e->attr_len) + sizeof(*e);
+       }
+
+       if (ch_list_idx) {
+               u16 attr_size;
+               struct wilc_ch_list_elem *e;
+               int i;
+
+               ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
+               attr_size = le16_to_cpu(ch_list->attr_len);
+               for (i = 0; i < attr_size;) {
+                       e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
+                       if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
+                               memset(e->ch_list, sta_ch, e->no_of_channels);
+                               break;
+                       }
+                       i += e->no_of_channels;
+               }
+       }
+
+       if (op_ch_idx) {
+               op_ch = (struct wilc_attr_oper_ch *)&buf[op_ch_idx];
+               op_ch->op_class = WILC_WLAN_OPERATING_CLASS_2_4GHZ;
+               op_ch->op_channel = sta_ch;
+       }
+}
+
+void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
+{
+       struct wilc *wl = vif->wilc;
+       struct wilc_priv *priv = &vif->priv;
+       struct host_if_drv *wfi_drv = priv->hif_drv;
+       struct ieee80211_mgmt *mgmt;
+       struct wilc_vendor_specific_ie *p;
+       struct wilc_p2p_pub_act_frame *d;
+       int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
+       const u8 *vendor_ie;
+       u32 header, pkt_offset;
+       s32 freq;
+
+       header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
+       pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
+
+       if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
+               bool ack = false;
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buff;
+
+               if (ieee80211_is_probe_resp(hdr->frame_control) ||
+                   pkt_offset & IS_MGMT_STATUS_SUCCES)
+                       ack = true;
+
+               cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
+                                       size, ack, GFP_KERNEL);
+               return;
+       }
+
+       freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
+
+       mgmt = (struct ieee80211_mgmt *)buff;
+       if (!ieee80211_is_action(mgmt->frame_control))
+               goto out_rx_mgmt;
+
+       if (priv->cfg_scanning &&
+           time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
+               netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
+               return;
+       }
+
+       if (!ieee80211_is_public_action((struct ieee80211_hdr *)buff, size))
+               goto out_rx_mgmt;
+
+       d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
+       if (d->oui_subtype != GO_NEG_REQ && d->oui_subtype != GO_NEG_RSP &&
+           d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
+               goto out_rx_mgmt;
+
+       vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
+                                           buff + ie_offset, size - ie_offset);
+       if (!vendor_ie)
+               goto out_rx_mgmt;
+
+       p = (struct wilc_vendor_specific_ie *)vendor_ie;
+       wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
+
+out_rx_mgmt:
+       cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
+}
+
+static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
+{
+       struct wilc_p2p_mgmt_data *pv_data = priv;
+
+       kfree(pv_data->buff);
+       kfree(pv_data);
+}
+
+static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
+{
+       struct wilc_vif *vif = data;
+       struct wilc_priv *priv = &vif->priv;
+       struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
+
+       if (cookie != params->listen_cookie)
+               return;
+
+       priv->p2p_listen_state = false;
+
+       cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
+                                          params->listen_ch, GFP_KERNEL);
+}
+
+static int remain_on_channel(struct wiphy *wiphy,
+                            struct wireless_dev *wdev,
+                            struct ieee80211_channel *chan,
+                            unsigned int duration, u64 *cookie)
+{
+       int ret = 0;
+       struct wilc_vif *vif = netdev_priv(wdev->netdev);
+       struct wilc_priv *priv = &vif->priv;
+       u64 id;
+
+       if (wdev->iftype == NL80211_IFTYPE_AP) {
+               netdev_dbg(vif->ndev, "Required while in AP mode\n");
+               return ret;
+       }
+
+       id = ++priv->inc_roc_cookie;
+       if (id == 0)
+               id = ++priv->inc_roc_cookie;
+
+       ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
+                                    wilc_wfi_remain_on_channel_expired,
+                                    (void *)vif);
+       if (ret)
+               return ret;
+
+       vif->wilc->op_ch = chan->hw_value;
+
+       priv->remain_on_ch_params.listen_ch = chan;
+       priv->remain_on_ch_params.listen_cookie = id;
+       *cookie = id;
+       priv->p2p_listen_state = true;
+       priv->remain_on_ch_params.listen_duration = duration;
+
+       cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
+       mod_timer(&vif->hif_drv->remain_on_ch_timer,
+                 jiffies + msecs_to_jiffies(duration + 1000));
+
+       return ret;
+}
+
+static int cancel_remain_on_channel(struct wiphy *wiphy,
+                                   struct wireless_dev *wdev,
+                                   u64 cookie)
+{
+       struct wilc_vif *vif = netdev_priv(wdev->netdev);
+       struct wilc_priv *priv = &vif->priv;
+
+       if (cookie != priv->remain_on_ch_params.listen_cookie)
+               return -ENOENT;
+
+       return wilc_listen_state_expired(vif, cookie);
+}
+
+static int mgmt_tx(struct wiphy *wiphy,
+                  struct wireless_dev *wdev,
+                  struct cfg80211_mgmt_tx_params *params,
+                  u64 *cookie)
+{
+       struct ieee80211_channel *chan = params->chan;
+       unsigned int wait = params->wait;
+       const u8 *buf = params->buf;
+       size_t len = params->len;
+       const struct ieee80211_mgmt *mgmt;
+       struct wilc_p2p_mgmt_data *mgmt_tx;
+       struct wilc_vif *vif = netdev_priv(wdev->netdev);
+       struct wilc_priv *priv = &vif->priv;
+       struct host_if_drv *wfi_drv = priv->hif_drv;
+       struct wilc_vendor_specific_ie *p;
+       struct wilc_p2p_pub_act_frame *d;
+       int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
+       const u8 *vendor_ie;
+       int ret = 0;
+
+       *cookie = prandom_u32();
+       priv->tx_cookie = *cookie;
+       mgmt = (const struct ieee80211_mgmt *)buf;
+
+       if (!ieee80211_is_mgmt(mgmt->frame_control))
+               goto out;
+
+       mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
+       if (!mgmt_tx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       mgmt_tx->buff = kmemdup(buf, len, GFP_KERNEL);
+       if (!mgmt_tx->buff) {
+               ret = -ENOMEM;
+               kfree(mgmt_tx);
+               goto out;
+       }
+
+       mgmt_tx->size = len;
+
+       if (ieee80211_is_probe_resp(mgmt->frame_control)) {
+               wilc_set_mac_chnl_num(vif, chan->hw_value);
+               vif->wilc->op_ch = chan->hw_value;
+               goto out_txq_add_pkt;
+       }
+
+       if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len))
+               goto out_set_timeout;
+
+       d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
+       if (d->oui_type != WLAN_OUI_TYPE_WFA_P2P ||
+           d->oui_subtype != GO_NEG_CONF) {
+               wilc_set_mac_chnl_num(vif, chan->hw_value);
+               vif->wilc->op_ch = chan->hw_value;
+       }
+
+       if (d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
+               goto out_set_timeout;
+
+       vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
+                                           mgmt_tx->buff + ie_offset,
+                                           len - ie_offset);
+       if (!vendor_ie)
+               goto out_set_timeout;
+
+       p = (struct wilc_vendor_specific_ie *)vendor_ie;
+       wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
+
+out_set_timeout:
+       wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
+
+out_txq_add_pkt:
+
+       wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
+                                  mgmt_tx->buff, mgmt_tx->size,
+                                  wilc_wfi_mgmt_tx_complete);
+
+out:
+
+       return ret;
+}
+
+static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
+                              struct wireless_dev *wdev,
+                              u64 cookie)
+{
+       struct wilc_vif *vif = netdev_priv(wdev->netdev);
+       struct wilc_priv *priv = &vif->priv;
+       struct host_if_drv *wfi_drv = priv->hif_drv;
+
+       wfi_drv->p2p_timeout = jiffies;
+
+       if (!priv->p2p_listen_state) {
+               struct wilc_wfi_p2p_listen_params *params;
+
+               params = &priv->remain_on_ch_params;
+
+               cfg80211_remain_on_channel_expired(wdev,
+                                                  params->listen_cookie,
+                                                  params->listen_ch,
+                                                  GFP_KERNEL);
+       }
+
+       return 0;
+}
+
+void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
+                                         struct wireless_dev *wdev,
+                                         struct mgmt_frame_regs *upd)
+{
+       struct wilc *wl = wiphy_priv(wiphy);
+       struct wilc_vif *vif = netdev_priv(wdev->netdev);
+       u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
+       u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4);
+
+       if (wl->initialized) {
+               bool prev = vif->mgmt_reg_stypes & presp_bit;
+               bool now = upd->interface_stypes & presp_bit;
+
+               if (now != prev)
+                       wilc_frame_register(vif, IEEE80211_STYPE_PROBE_REQ, now);
+
+               prev = vif->mgmt_reg_stypes & action_bit;
+               now = upd->interface_stypes & action_bit;
+
+               if (now != prev)
+                       wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now);
+       }
+
+       vif->mgmt_reg_stypes =
+               upd->interface_stypes & (presp_bit | action_bit);
+}
+
+static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
+                              s32 rssi_thold, u32 rssi_hyst)
+{
+       return 0;
+}
+
+static int dump_station(struct wiphy *wiphy, struct net_device *dev,
+                       int idx, u8 *mac, struct station_info *sinfo)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       int ret;
+
+       if (idx != 0)
+               return -ENOENT;
+
+       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
+
+       ret = wilc_get_rssi(vif, &sinfo->signal);
+       if (ret)
+               return ret;
+
+       memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
+       return 0;
+}
+
+static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+                         bool enabled, int timeout)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc_priv *priv = &vif->priv;
+
+       if (!priv->hif_drv)
+               return -EIO;
+
+       wilc_set_power_mgmt(vif, enabled, timeout);
+
+       return 0;
+}
+
+static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
+                              enum nl80211_iftype type,
+                              struct vif_params *params)
+{
+       struct wilc *wl = wiphy_priv(wiphy);
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc_priv *priv = &vif->priv;
+
+       switch (type) {
+       case NL80211_IFTYPE_STATION:
+               vif->connecting = false;
+               dev->ieee80211_ptr->iftype = type;
+               priv->wdev.iftype = type;
+               vif->monitor_flag = 0;
+               if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
+                       wilc_wfi_deinit_mon_interface(wl, true);
+               vif->iftype = WILC_STATION_MODE;
+
+               if (wl->initialized)
+                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
+                                               WILC_STATION_MODE, vif->idx);
+
+               memset(priv->assoc_stainfo.sta_associated_bss, 0,
+                      WILC_MAX_NUM_STA * ETH_ALEN);
+               break;
+
+       case NL80211_IFTYPE_P2P_CLIENT:
+               vif->connecting = false;
+               dev->ieee80211_ptr->iftype = type;
+               priv->wdev.iftype = type;
+               vif->monitor_flag = 0;
+               vif->iftype = WILC_CLIENT_MODE;
+
+               if (wl->initialized)
+                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
+                                               WILC_STATION_MODE, vif->idx);
+               break;
+
+       case NL80211_IFTYPE_AP:
+               dev->ieee80211_ptr->iftype = type;
+               priv->wdev.iftype = type;
+               vif->iftype = WILC_AP_MODE;
+
+               if (wl->initialized)
+                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
+                                               WILC_AP_MODE, vif->idx);
+               break;
+
+       case NL80211_IFTYPE_P2P_GO:
+               dev->ieee80211_ptr->iftype = type;
+               priv->wdev.iftype = type;
+               vif->iftype = WILC_GO_MODE;
+
+               if (wl->initialized)
+                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
+                                               WILC_AP_MODE, vif->idx);
+               break;
+
+       default:
+               netdev_err(dev, "Unknown interface type= %d\n", type);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int start_ap(struct wiphy *wiphy, struct net_device *dev,
+                   struct cfg80211_ap_settings *settings)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       int ret;
+
+       ret = set_channel(wiphy, &settings->chandef);
+       if (ret != 0)
+               netdev_err(dev, "Error in setting channel\n");
+
+       wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
+
+       return wilc_add_beacon(vif, settings->beacon_interval,
+                                  settings->dtim_period, &settings->beacon);
+}
+
+static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
+                        struct cfg80211_beacon_data *beacon)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+
+       return wilc_add_beacon(vif, 0, 0, beacon);
+}
+
+static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
+{
+       int ret;
+       struct wilc_vif *vif = netdev_priv(dev);
+
+       wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
+
+       ret = wilc_del_beacon(vif);
+
+       if (ret)
+               netdev_err(dev, "Host delete beacon fail\n");
+
+       return ret;
+}
+
+static int add_station(struct wiphy *wiphy, struct net_device *dev,
+                      const u8 *mac, struct station_parameters *params)
+{
+       int ret = 0;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc_priv *priv = &vif->priv;
+
+       if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
+               memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
+                      ETH_ALEN);
+
+               ret = wilc_add_station(vif, mac, params);
+               if (ret)
+                       netdev_err(dev, "Host add station fail\n");
+       }
+
+       return ret;
+}
+
+static int del_station(struct wiphy *wiphy, struct net_device *dev,
+                      struct station_del_parameters *params)
+{
+       const u8 *mac = params->mac;
+       int ret = 0;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc_priv *priv = &vif->priv;
+       struct sta_info *info;
+
+       if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
+               return ret;
+
+       info = &priv->assoc_stainfo;
+
+       if (!mac)
+               ret = wilc_del_allstation(vif, info->sta_associated_bss);
+
+       ret = wilc_del_station(vif, mac);
+       if (ret)
+               netdev_err(dev, "Host delete station fail\n");
+       return ret;
+}
+
+static int change_station(struct wiphy *wiphy, struct net_device *dev,
+                         const u8 *mac, struct station_parameters *params)
+{
+       int ret = 0;
+       struct wilc_vif *vif = netdev_priv(dev);
+
+       if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
+               ret = wilc_edit_station(vif, mac, params);
+               if (ret)
+                       netdev_err(dev, "Host edit station fail\n");
+       }
+       return ret;
+}
+
+static struct wilc_vif *wilc_get_vif_from_type(struct wilc *wl, int type)
+{
+       struct wilc_vif *vif;
+
+       list_for_each_entry_rcu(vif, &wl->vif_list, list) {
+               if (vif->iftype == type)
+                       return vif;
+       }
+
+       return NULL;
+}
+
+static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
+                                            const char *name,
+                                            unsigned char name_assign_type,
+                                            enum nl80211_iftype type,
+                                            struct vif_params *params)
+{
+       struct wilc *wl = wiphy_priv(wiphy);
+       struct wilc_vif *vif;
+       struct wireless_dev *wdev;
+       int iftype;
+
+       if (type == NL80211_IFTYPE_MONITOR) {
+               struct net_device *ndev;
+               int srcu_idx;
+
+               srcu_idx = srcu_read_lock(&wl->srcu);
+               vif = wilc_get_vif_from_type(wl, WILC_AP_MODE);
+               if (!vif) {
+                       vif = wilc_get_vif_from_type(wl, WILC_GO_MODE);
+                       if (!vif) {
+                               srcu_read_unlock(&wl->srcu, srcu_idx);
+                               goto validate_interface;
+                       }
+               }
+
+               if (vif->monitor_flag) {
+                       srcu_read_unlock(&wl->srcu, srcu_idx);
+                       goto validate_interface;
+               }
+
+               ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
+               if (ndev) {
+                       vif->monitor_flag = 1;
+               } else {
+                       srcu_read_unlock(&wl->srcu, srcu_idx);
+                       return ERR_PTR(-EINVAL);
+               }
+
+               wdev = &vif->priv.wdev;
+               srcu_read_unlock(&wl->srcu, srcu_idx);
+               return wdev;
+       }
+
+validate_interface:
+       mutex_lock(&wl->vif_mutex);
+       if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
+               pr_err("Reached maximum number of interface\n");
+               mutex_unlock(&wl->vif_mutex);
+               return ERR_PTR(-EINVAL);
+       }
+       mutex_unlock(&wl->vif_mutex);
+
+       switch (type) {
+       case NL80211_IFTYPE_STATION:
+               iftype = WILC_STATION_MODE;
+               break;
+       case NL80211_IFTYPE_AP:
+               iftype = WILC_AP_MODE;
+               break;
+       default:
+               return ERR_PTR(-EOPNOTSUPP);
+       }
+
+       vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
+       if (IS_ERR(vif))
+               return ERR_CAST(vif);
+
+       return &vif->priv.wdev;
+}
+
+static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
+{
+       struct wilc *wl = wiphy_priv(wiphy);
+       struct wilc_vif *vif;
+
+       if (wdev->iftype == NL80211_IFTYPE_AP ||
+           wdev->iftype == NL80211_IFTYPE_P2P_GO)
+               wilc_wfi_deinit_mon_interface(wl, true);
+       vif = netdev_priv(wdev->netdev);
+       cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
+       unregister_netdevice(vif->ndev);
+       vif->monitor_flag = 0;
+
+       wilc_set_operation_mode(vif, 0, 0, 0);
+       mutex_lock(&wl->vif_mutex);
+       list_del_rcu(&vif->list);
+       wl->vif_num--;
+       mutex_unlock(&wl->vif_mutex);
+       synchronize_srcu(&wl->srcu);
+       return 0;
+}
+
+static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
+{
+       struct wilc *wl = wiphy_priv(wiphy);
+
+       if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
+               wl->suspend_event = true;
+       else
+               wl->suspend_event = false;
+
+       return 0;
+}
+
+static int wilc_resume(struct wiphy *wiphy)
+{
+       return 0;
+}
+
+static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
+{
+       struct wilc *wl = wiphy_priv(wiphy);
+       struct wilc_vif *vif;
+       int srcu_idx;
+
+       srcu_idx = srcu_read_lock(&wl->srcu);
+       vif = wilc_get_wl_to_vif(wl);
+       if (IS_ERR(vif)) {
+               srcu_read_unlock(&wl->srcu, srcu_idx);
+               return;
+       }
+
+       netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
+       srcu_read_unlock(&wl->srcu, srcu_idx);
+}
+
+static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+                       enum nl80211_tx_power_setting type, int mbm)
+{
+       int ret;
+       int srcu_idx;
+       s32 tx_power = MBM_TO_DBM(mbm);
+       struct wilc *wl = wiphy_priv(wiphy);
+       struct wilc_vif *vif;
+
+       if (!wl->initialized)
+               return -EIO;
+
+       srcu_idx = srcu_read_lock(&wl->srcu);
+       vif = wilc_get_wl_to_vif(wl);
+       if (IS_ERR(vif)) {
+               srcu_read_unlock(&wl->srcu, srcu_idx);
+               return -EINVAL;
+       }
+
+       netdev_info(vif->ndev, "Setting tx power %d\n", tx_power);
+       if (tx_power < 0)
+               tx_power = 0;
+       else if (tx_power > 18)
+               tx_power = 18;
+       ret = wilc_set_tx_power(vif, tx_power);
+       if (ret)
+               netdev_err(vif->ndev, "Failed to set tx power\n");
+       srcu_read_unlock(&wl->srcu, srcu_idx);
+
+       return ret;
+}
+
+static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+                       int *dbm)
+{
+       int ret;
+       struct wilc_vif *vif = netdev_priv(wdev->netdev);
+       struct wilc *wl = vif->wilc;
+
+       /* If firmware is not started, return. */
+       if (!wl->initialized)
+               return -EIO;
+
+       ret = wilc_get_tx_power(vif, (u8 *)dbm);
+       if (ret)
+               netdev_err(vif->ndev, "Failed to get tx power\n");
+
+       return ret;
+}
+
+static const struct cfg80211_ops wilc_cfg80211_ops = {
+       .set_monitor_channel = set_channel,
+       .scan = scan,
+       .connect = connect,
+       .disconnect = disconnect,
+       .add_key = add_key,
+       .del_key = del_key,
+       .get_key = get_key,
+       .set_default_key = set_default_key,
+       .add_virtual_intf = add_virtual_intf,
+       .del_virtual_intf = del_virtual_intf,
+       .change_virtual_intf = change_virtual_intf,
+
+       .start_ap = start_ap,
+       .change_beacon = change_beacon,
+       .stop_ap = stop_ap,
+       .add_station = add_station,
+       .del_station = del_station,
+       .change_station = change_station,
+       .get_station = get_station,
+       .dump_station = dump_station,
+       .change_bss = change_bss,
+       .set_wiphy_params = set_wiphy_params,
+
+       .set_pmksa = set_pmksa,
+       .del_pmksa = del_pmksa,
+       .flush_pmksa = flush_pmksa,
+       .remain_on_channel = remain_on_channel,
+       .cancel_remain_on_channel = cancel_remain_on_channel,
+       .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
+       .mgmt_tx = mgmt_tx,
+       .update_mgmt_frame_registrations = wilc_update_mgmt_frame_registrations,
+       .set_power_mgmt = set_power_mgmt,
+       .set_cqm_rssi_config = set_cqm_rssi_config,
+
+       .suspend = wilc_suspend,
+       .resume = wilc_resume,
+       .set_wakeup = wilc_set_wakeup,
+       .set_tx_power = set_tx_power,
+       .get_tx_power = get_tx_power,
+
+};
+
+static void wlan_init_locks(struct wilc *wl)
+{
+       mutex_init(&wl->hif_cs);
+       mutex_init(&wl->rxq_cs);
+       mutex_init(&wl->cfg_cmd_lock);
+       mutex_init(&wl->vif_mutex);
+
+       spin_lock_init(&wl->txq_spinlock);
+       mutex_init(&wl->txq_add_to_head_cs);
+
+       init_completion(&wl->txq_event);
+       init_completion(&wl->cfg_event);
+       init_completion(&wl->sync_event);
+       init_completion(&wl->txq_thread_started);
+       init_srcu_struct(&wl->srcu);
+}
+
+void wlan_deinit_locks(struct wilc *wilc)
+{
+       mutex_destroy(&wilc->hif_cs);
+       mutex_destroy(&wilc->rxq_cs);
+       mutex_destroy(&wilc->cfg_cmd_lock);
+       mutex_destroy(&wilc->txq_add_to_head_cs);
+       mutex_destroy(&wilc->vif_mutex);
+       cleanup_srcu_struct(&wilc->srcu);
+}
+
+int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
+                      const struct wilc_hif_func *ops)
+{
+       struct wilc *wl;
+       struct wilc_vif *vif;
+       int ret;
+
+       wl = wilc_create_wiphy(dev);
+       if (!wl)
+               return -EINVAL;
+
+       wlan_init_locks(wl);
+
+       ret = wilc_wlan_cfg_init(wl);
+       if (ret)
+               goto free_wl;
+
+       *wilc = wl;
+       wl->io_type = io_type;
+       wl->hif_func = ops;
+       wl->chip_ps_state = WILC_CHIP_WAKEDUP;
+       INIT_LIST_HEAD(&wl->txq_head.list);
+       INIT_LIST_HEAD(&wl->rxq_head.list);
+       INIT_LIST_HEAD(&wl->vif_list);
+
+       wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
+       if (!wl->hif_workqueue) {
+               ret = -ENOMEM;
+               goto free_cfg;
+       }
+       vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
+                                  NL80211_IFTYPE_STATION, false);
+       if (IS_ERR(vif)) {
+               ret = PTR_ERR(vif);
+               goto free_hq;
+       }
+
+       return 0;
+
+free_hq:
+       destroy_workqueue(wl->hif_workqueue);
+
+free_cfg:
+       wilc_wlan_cfg_deinit(wl);
+
+free_wl:
+       wlan_deinit_locks(wl);
+       wiphy_unregister(wl->wiphy);
+       wiphy_free(wl->wiphy);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
+
+struct wilc *wilc_create_wiphy(struct device *dev)
+{
+       struct wiphy *wiphy;
+       struct wilc *wl;
+       int ret;
+
+       wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
+       if (!wiphy)
+               return NULL;
+
+       wl = wiphy_priv(wiphy);
+
+       memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
+       memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
+       wl->band.bitrates = wl->bitrates;
+       wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
+       wl->band.channels = wl->channels;
+       wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
+
+       wl->band.ht_cap.ht_supported = 1;
+       wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+       wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
+       wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
+       wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
+
+       wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
+
+       wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
+#ifdef CONFIG_PM
+       wiphy->wowlan = &wowlan_support;
+#endif
+       wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
+       wiphy->max_scan_ie_len = 1000;
+       wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+       memcpy(wl->cipher_suites, wilc_cipher_suites,
+              sizeof(wilc_cipher_suites));
+       wiphy->cipher_suites = wl->cipher_suites;
+       wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
+       wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
+
+       wiphy->max_remain_on_channel_duration = 500;
+       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                               BIT(NL80211_IFTYPE_AP) |
+                               BIT(NL80211_IFTYPE_MONITOR) |
+                               BIT(NL80211_IFTYPE_P2P_GO) |
+                               BIT(NL80211_IFTYPE_P2P_CLIENT);
+       wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+
+       set_wiphy_dev(wiphy, dev);
+       wl->wiphy = wiphy;
+       ret = wiphy_register(wiphy);
+       if (ret) {
+               wiphy_free(wiphy);
+               return NULL;
+       }
+       return wl;
+}
+
+int wilc_init_host_int(struct net_device *net)
+{
+       int ret;
+       struct wilc_vif *vif = netdev_priv(net);
+       struct wilc_priv *priv = &vif->priv;
+
+       priv->p2p_listen_state = false;
+
+       mutex_init(&priv->scan_req_lock);
+       ret = wilc_init(net, &priv->hif_drv);
+       if (ret)
+               netdev_err(net, "Error while initializing hostinterface\n");
+
+       return ret;
+}
+
+void wilc_deinit_host_int(struct net_device *net)
+{
+       int ret;
+       struct wilc_vif *vif = netdev_priv(net);
+       struct wilc_priv *priv = &vif->priv;
+
+       priv->p2p_listen_state = false;
+
+       flush_workqueue(vif->wilc->hif_workqueue);
+       mutex_destroy(&priv->scan_req_lock);
+       ret = wilc_deinit(vif);
+
+       if (ret)
+               netdev_err(net, "Error while deinitializing host interface\n");
+}
+
diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.h b/drivers/net/wireless/microchip/wilc1000/cfg80211.h
new file mode 100644 (file)
index 0000000..37b294c
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#ifndef WILC_CFG80211_H
+#define WILC_CFG80211_H
+#include "netdev.h"
+
+struct wiphy *wilc_cfg_alloc(void);
+int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
+                      const struct wilc_hif_func *ops);
+struct wilc *wilc_create_wiphy(struct device *dev);
+void wilc_deinit_host_int(struct net_device *net);
+int wilc_init_host_int(struct net_device *net);
+void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size);
+struct wilc_vif *wilc_netdev_interface(struct wilc *wl, const char *name,
+                                      enum nl80211_iftype type);
+void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked);
+struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
+                                              const char *name,
+                                              struct net_device *real_dev);
+void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
+                                         struct wireless_dev *wdev,
+                                         struct mgmt_frame_regs *upd);
+struct wilc_vif *wilc_get_interface(struct wilc *wl);
+struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl);
+void wlan_deinit_locks(struct wilc *wilc);
+#endif
diff --git a/drivers/net/wireless/microchip/wilc1000/fw.h b/drivers/net/wireless/microchip/wilc1000/fw.h
new file mode 100644 (file)
index 0000000..a76e1de
--- /dev/null
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#ifndef WILC_FW_H
+#define WILC_FW_H
+
+#include <linux/ieee80211.h>
+
+#define WILC_MAX_NUM_STA                       9
+#define WILC_MAX_RATES_SUPPORTED               12
+#define WILC_MAX_NUM_PMKIDS                    16
+#define WILC_MAX_NUM_SCANNED_CH                        14
+
+struct wilc_assoc_resp {
+       __le16 capab_info;
+       __le16 status_code;
+       __le16 aid;
+} __packed;
+
+struct wilc_pmkid {
+       u8 bssid[ETH_ALEN];
+       u8 pmkid[WLAN_PMKID_LEN];
+} __packed;
+
+struct wilc_pmkid_attr {
+       u8 numpmkid;
+       struct wilc_pmkid pmkidlist[WILC_MAX_NUM_PMKIDS];
+} __packed;
+
+struct wilc_reg_frame {
+       u8 reg;
+       u8 reg_id;
+       __le16 frame_type;
+} __packed;
+
+struct wilc_drv_handler {
+       __le32 handler;
+       u8 mode;
+} __packed;
+
+struct wilc_wep_key {
+       u8 index;
+       u8 key_len;
+       u8 key[0];
+} __packed;
+
+struct wilc_sta_wpa_ptk {
+       u8 mac_addr[ETH_ALEN];
+       u8 key_len;
+       u8 key[0];
+} __packed;
+
+struct wilc_ap_wpa_ptk {
+       u8 mac_addr[ETH_ALEN];
+       u8 index;
+       u8 key_len;
+       u8 key[0];
+} __packed;
+
+struct wilc_gtk_key {
+       u8 mac_addr[ETH_ALEN];
+       u8 rsc[8];
+       u8 index;
+       u8 key_len;
+       u8 key[0];
+} __packed;
+
+struct wilc_op_mode {
+       __le32 mode;
+} __packed;
+
+struct wilc_noa_opp_enable {
+       u8 ct_window;
+       u8 cnt;
+       __le32 duration;
+       __le32 interval;
+       __le32 start_time;
+} __packed;
+
+struct wilc_noa_opp_disable {
+       u8 cnt;
+       __le32 duration;
+       __le32 interval;
+       __le32 start_time;
+} __packed;
+
+struct wilc_join_bss_param {
+       char ssid[IEEE80211_MAX_SSID_LEN];
+       u8 ssid_terminator;
+       u8 bss_type;
+       u8 ch;
+       __le16 cap_info;
+       u8 sa[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+       __le16 beacon_period;
+       u8 dtim_period;
+       u8 supp_rates[WILC_MAX_RATES_SUPPORTED + 1];
+       u8 wmm_cap;
+       u8 uapsd_cap;
+       u8 ht_capable;
+       u8 rsn_found;
+       u8 rsn_grp_policy;
+       u8 mode_802_11i;
+       u8 p_suites[3];
+       u8 akm_suites[3];
+       u8 rsn_cap[2];
+       u8 noa_enabled;
+       __le32 tsf_lo;
+       u8 idx;
+       u8 opp_enabled;
+       union {
+               struct wilc_noa_opp_disable opp_dis;
+               struct wilc_noa_opp_enable opp_en;
+       };
+} __packed;
+#endif
diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
new file mode 100644 (file)
index 0000000..d025a30
--- /dev/null
@@ -0,0 +1,1961 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#include "netdev.h"
+
+#define WILC_HIF_SCAN_TIMEOUT_MS                5000
+#define WILC_HIF_CONNECT_TIMEOUT_MS             9500
+
+#define WILC_FALSE_FRMWR_CHANNEL               100
+
+#define WILC_SCAN_WID_LIST_SIZE                6
+
+struct wilc_rcvd_mac_info {
+       u8 status;
+};
+
+struct wilc_set_multicast {
+       u32 enabled;
+       u32 cnt;
+       u8 *mc_list;
+};
+
+struct wilc_del_all_sta {
+       u8 assoc_sta;
+       u8 mac[WILC_MAX_NUM_STA][ETH_ALEN];
+};
+
+union wilc_message_body {
+       struct wilc_rcvd_net_info net_info;
+       struct wilc_rcvd_mac_info mac_info;
+       struct wilc_set_multicast mc_info;
+       struct wilc_remain_ch remain_on_ch;
+       char *data;
+};
+
+struct host_if_msg {
+       union wilc_message_body body;
+       struct wilc_vif *vif;
+       struct work_struct work;
+       void (*fn)(struct work_struct *ws);
+       struct completion work_comp;
+       bool is_sync;
+};
+
+/* 'msg' should be free by the caller for syc */
+static struct host_if_msg*
+wilc_alloc_work(struct wilc_vif *vif, void (*work_fun)(struct work_struct *),
+               bool is_sync)
+{
+       struct host_if_msg *msg;
+
+       if (!work_fun)
+               return ERR_PTR(-EINVAL);
+
+       msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
+       if (!msg)
+               return ERR_PTR(-ENOMEM);
+       msg->fn = work_fun;
+       msg->vif = vif;
+       msg->is_sync = is_sync;
+       if (is_sync)
+               init_completion(&msg->work_comp);
+
+       return msg;
+}
+
+static int wilc_enqueue_work(struct host_if_msg *msg)
+{
+       INIT_WORK(&msg->work, msg->fn);
+
+       if (!msg->vif || !msg->vif->wilc || !msg->vif->wilc->hif_workqueue)
+               return -EINVAL;
+
+       if (!queue_work(msg->vif->wilc->hif_workqueue, &msg->work))
+               return -EINVAL;
+
+       return 0;
+}
+
+/* The idx starts from 0 to (NUM_CONCURRENT_IFC - 1), but 0 index used as
+ * special purpose in wilc device, so we add 1 to the index to starts from 1.
+ * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
+ */
+int wilc_get_vif_idx(struct wilc_vif *vif)
+{
+       return vif->idx + 1;
+}
+
+/* We need to minus 1 from idx which is from wilc device to get real index
+ * of wilc->vif[], because we add 1 when pass to wilc device in the function
+ * wilc_get_vif_idx.
+ * As a result, the index should be between 0 and (NUM_CONCURRENT_IFC - 1).
+ */
+static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
+{
+       int index = idx - 1;
+       struct wilc_vif *vif;
+
+       if (index < 0 || index >= WILC_NUM_CONCURRENT_IFC)
+               return NULL;
+
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+               if (vif->idx == index)
+                       return vif;
+       }
+
+       return NULL;
+}
+
+static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
+{
+       int result = 0;
+       u8 abort_running_scan;
+       struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+       struct wilc_user_scan_req *scan_req;
+
+       if (evt == SCAN_EVENT_ABORTED) {
+               abort_running_scan = 1;
+               wid.id = WID_ABORT_RUNNING_SCAN;
+               wid.type = WID_CHAR;
+               wid.val = (s8 *)&abort_running_scan;
+               wid.size = sizeof(char);
+
+               result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+               if (result) {
+                       netdev_err(vif->ndev, "Failed to set abort running\n");
+                       result = -EFAULT;
+               }
+       }
+
+       if (!hif_drv) {
+               netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
+               return result;
+       }
+
+       scan_req = &hif_drv->usr_scan_req;
+       if (scan_req->scan_result) {
+               scan_req->scan_result(evt, NULL, scan_req->arg);
+               scan_req->scan_result = NULL;
+       }
+
+       return result;
+}
+
+int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
+             u8 *ch_freq_list, u8 ch_list_len,
+             void (*scan_result_fn)(enum scan_event,
+                                    struct wilc_rcvd_net_info *, void *),
+             void *user_arg, struct cfg80211_scan_request *request)
+{
+       int result = 0;
+       struct wid wid_list[WILC_SCAN_WID_LIST_SIZE];
+       u32 index = 0;
+       u32 i, scan_timeout;
+       u8 *buffer;
+       u8 valuesize = 0;
+       u8 *search_ssid_vals = NULL;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+
+       if (hif_drv->hif_state >= HOST_IF_SCANNING &&
+           hif_drv->hif_state < HOST_IF_CONNECTED) {
+               netdev_err(vif->ndev, "Already scan\n");
+               result = -EBUSY;
+               goto error;
+       }
+
+       if (vif->connecting) {
+               netdev_err(vif->ndev, "Don't do obss scan\n");
+               result = -EBUSY;
+               goto error;
+       }
+
+       hif_drv->usr_scan_req.ch_cnt = 0;
+
+       if (request->n_ssids) {
+               for (i = 0; i < request->n_ssids; i++)
+                       valuesize += ((request->ssids[i].ssid_len) + 1);
+               search_ssid_vals = kmalloc(valuesize + 1, GFP_KERNEL);
+               if (search_ssid_vals) {
+                       wid_list[index].id = WID_SSID_PROBE_REQ;
+                       wid_list[index].type = WID_STR;
+                       wid_list[index].val = search_ssid_vals;
+                       buffer = wid_list[index].val;
+
+                       *buffer++ = request->n_ssids;
+
+                       for (i = 0; i < request->n_ssids; i++) {
+                               *buffer++ = request->ssids[i].ssid_len;
+                               memcpy(buffer, request->ssids[i].ssid,
+                                      request->ssids[i].ssid_len);
+                               buffer += request->ssids[i].ssid_len;
+                       }
+                       wid_list[index].size = (s32)(valuesize + 1);
+                       index++;
+               }
+       }
+
+       wid_list[index].id = WID_INFO_ELEMENT_PROBE;
+       wid_list[index].type = WID_BIN_DATA;
+       wid_list[index].val = (s8 *)request->ie;
+       wid_list[index].size = request->ie_len;
+       index++;
+
+       wid_list[index].id = WID_SCAN_TYPE;
+       wid_list[index].type = WID_CHAR;
+       wid_list[index].size = sizeof(char);
+       wid_list[index].val = (s8 *)&scan_type;
+       index++;
+
+       if (scan_type == WILC_FW_PASSIVE_SCAN && request->duration) {
+               wid_list[index].id = WID_PASSIVE_SCAN_TIME;
+               wid_list[index].type = WID_SHORT;
+               wid_list[index].size = sizeof(u16);
+               wid_list[index].val = (s8 *)&request->duration;
+               index++;
+
+               scan_timeout = (request->duration * ch_list_len) + 500;
+       } else {
+               scan_timeout = WILC_HIF_SCAN_TIMEOUT_MS;
+       }
+
+       wid_list[index].id = WID_SCAN_CHANNEL_LIST;
+       wid_list[index].type = WID_BIN_DATA;
+
+       if (ch_freq_list && ch_list_len > 0) {
+               for (i = 0; i < ch_list_len; i++) {
+                       if (ch_freq_list[i] > 0)
+                               ch_freq_list[i] -= 1;
+               }
+       }
+
+       wid_list[index].val = ch_freq_list;
+       wid_list[index].size = ch_list_len;
+       index++;
+
+       wid_list[index].id = WID_START_SCAN_REQ;
+       wid_list[index].type = WID_CHAR;
+       wid_list[index].size = sizeof(char);
+       wid_list[index].val = (s8 *)&scan_source;
+       index++;
+
+       hif_drv->usr_scan_req.scan_result = scan_result_fn;
+       hif_drv->usr_scan_req.arg = user_arg;
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, index);
+       if (result) {
+               netdev_err(vif->ndev, "Failed to send scan parameters\n");
+               goto error;
+       }
+
+       hif_drv->scan_timer_vif = vif;
+       mod_timer(&hif_drv->scan_timer,
+                 jiffies + msecs_to_jiffies(scan_timeout));
+
+error:
+
+       kfree(search_ssid_vals);
+
+       return result;
+}
+
+static int wilc_send_connect_wid(struct wilc_vif *vif)
+{
+       int result = 0;
+       struct wid wid_list[4];
+       u32 wid_cnt = 0;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+       struct wilc_conn_info *conn_attr = &hif_drv->conn_info;
+       struct wilc_join_bss_param *bss_param = conn_attr->param;
+
+       wid_list[wid_cnt].id = WID_INFO_ELEMENT_ASSOCIATE;
+       wid_list[wid_cnt].type = WID_BIN_DATA;
+       wid_list[wid_cnt].val = conn_attr->req_ies;
+       wid_list[wid_cnt].size = conn_attr->req_ies_len;
+       wid_cnt++;
+
+       wid_list[wid_cnt].id = WID_11I_MODE;
+       wid_list[wid_cnt].type = WID_CHAR;
+       wid_list[wid_cnt].size = sizeof(char);
+       wid_list[wid_cnt].val = (s8 *)&conn_attr->security;
+       wid_cnt++;
+
+       wid_list[wid_cnt].id = WID_AUTH_TYPE;
+       wid_list[wid_cnt].type = WID_CHAR;
+       wid_list[wid_cnt].size = sizeof(char);
+       wid_list[wid_cnt].val = (s8 *)&conn_attr->auth_type;
+       wid_cnt++;
+
+       wid_list[wid_cnt].id = WID_JOIN_REQ_EXTENDED;
+       wid_list[wid_cnt].type = WID_STR;
+       wid_list[wid_cnt].size = sizeof(*bss_param);
+       wid_list[wid_cnt].val = (u8 *)bss_param;
+       wid_cnt++;
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, wid_cnt);
+       if (result) {
+               netdev_err(vif->ndev, "failed to send config packet\n");
+               goto error;
+       } else {
+               hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
+       }
+
+       return 0;
+
+error:
+
+       kfree(conn_attr->req_ies);
+       conn_attr->req_ies = NULL;
+
+       return result;
+}
+
+static void handle_connect_timeout(struct work_struct *work)
+{
+       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+       struct wilc_vif *vif = msg->vif;
+       int result;
+       struct wid wid;
+       u16 dummy_reason_code = 0;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+
+       if (!hif_drv) {
+               netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
+               goto out;
+       }
+
+       hif_drv->hif_state = HOST_IF_IDLE;
+
+       if (hif_drv->conn_info.conn_result) {
+               hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
+                                              WILC_MAC_STATUS_DISCONNECTED,
+                                              hif_drv->conn_info.arg);
+
+       } else {
+               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
+       }
+
+       wid.id = WID_DISCONNECT;
+       wid.type = WID_CHAR;
+       wid.val = (s8 *)&dummy_reason_code;
+       wid.size = sizeof(char);
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to send disconnect\n");
+
+       hif_drv->conn_info.req_ies_len = 0;
+       kfree(hif_drv->conn_info.req_ies);
+       hif_drv->conn_info.req_ies = NULL;
+
+out:
+       kfree(msg);
+}
+
+void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+                               struct cfg80211_crypto_settings *crypto)
+{
+       struct wilc_join_bss_param *param;
+       struct ieee80211_p2p_noa_attr noa_attr;
+       u8 rates_len = 0;
+       const u8 *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie;
+       const u8 *ht_ie, *wpa_ie, *wmm_ie, *rsn_ie;
+       int ret;
+       const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies);
+
+       param = kzalloc(sizeof(*param), GFP_KERNEL);
+       if (!param)
+               return NULL;
+
+       param->beacon_period = cpu_to_le16(bss->beacon_interval);
+       param->cap_info = cpu_to_le16(bss->capability);
+       param->bss_type = WILC_FW_BSS_TYPE_INFRA;
+       param->ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
+       ether_addr_copy(param->bssid, bss->bssid);
+
+       ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
+       if (ssid_elm) {
+               if (ssid_elm[1] <= IEEE80211_MAX_SSID_LEN)
+                       memcpy(param->ssid, ssid_elm + 2, ssid_elm[1]);
+       }
+
+       tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len);
+       if (tim_elm && tim_elm[1] >= 2)
+               param->dtim_period = tim_elm[3];
+
+       memset(param->p_suites, 0xFF, 3);
+       memset(param->akm_suites, 0xFF, 3);
+
+       rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies->data, ies->len);
+       if (rates_ie) {
+               rates_len = rates_ie[1];
+               if (rates_len > WILC_MAX_RATES_SUPPORTED)
+                       rates_len = WILC_MAX_RATES_SUPPORTED;
+               param->supp_rates[0] = rates_len;
+               memcpy(&param->supp_rates[1], rates_ie + 2, rates_len);
+       }
+
+       if (rates_len < WILC_MAX_RATES_SUPPORTED) {
+               supp_rates_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES,
+                                                ies->data, ies->len);
+               if (supp_rates_ie) {
+                       u8 ext_rates = supp_rates_ie[1];
+
+                       if (ext_rates > (WILC_MAX_RATES_SUPPORTED - rates_len))
+                               param->supp_rates[0] = WILC_MAX_RATES_SUPPORTED;
+                       else
+                               param->supp_rates[0] += ext_rates;
+
+                       memcpy(&param->supp_rates[rates_len + 1],
+                              supp_rates_ie + 2,
+                              (param->supp_rates[0] - rates_len));
+               }
+       }
+
+       ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies->data, ies->len);
+       if (ht_ie)
+               param->ht_capable = true;
+
+       ret = cfg80211_get_p2p_attr(ies->data, ies->len,
+                                   IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
+                                   (u8 *)&noa_attr, sizeof(noa_attr));
+       if (ret > 0) {
+               param->tsf_lo = cpu_to_le32(ies->tsf);
+               param->noa_enabled = 1;
+               param->idx = noa_attr.index;
+               if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) {
+                       param->opp_enabled = 1;
+                       param->opp_en.ct_window = noa_attr.oppps_ctwindow;
+                       param->opp_en.cnt = noa_attr.desc[0].count;
+                       param->opp_en.duration = noa_attr.desc[0].duration;
+                       param->opp_en.interval = noa_attr.desc[0].interval;
+                       param->opp_en.start_time = noa_attr.desc[0].start_time;
+               } else {
+                       param->opp_enabled = 0;
+                       param->opp_dis.cnt = noa_attr.desc[0].count;
+                       param->opp_dis.duration = noa_attr.desc[0].duration;
+                       param->opp_dis.interval = noa_attr.desc[0].interval;
+                       param->opp_dis.start_time = noa_attr.desc[0].start_time;
+               }
+       }
+       wmm_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+                                        WLAN_OUI_TYPE_MICROSOFT_WMM,
+                                        ies->data, ies->len);
+       if (wmm_ie) {
+               struct ieee80211_wmm_param_ie *ie;
+
+               ie = (struct ieee80211_wmm_param_ie *)wmm_ie;
+               if ((ie->oui_subtype == 0 || ie->oui_subtype == 1) &&
+                   ie->version == 1) {
+                       param->wmm_cap = true;
+                       if (ie->qos_info & BIT(7))
+                               param->uapsd_cap = true;
+               }
+       }
+
+       wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+                                        WLAN_OUI_TYPE_MICROSOFT_WPA,
+                                        ies->data, ies->len);
+       if (wpa_ie) {
+               param->mode_802_11i = 1;
+               param->rsn_found = true;
+       }
+
+       rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
+       if (rsn_ie) {
+               int offset = 8;
+
+               param->mode_802_11i = 2;
+               param->rsn_found = true;
+               /* extract RSN capabilities */
+               offset += (rsn_ie[offset] * 4) + 2;
+               offset += (rsn_ie[offset] * 4) + 2;
+               memcpy(param->rsn_cap, &rsn_ie[offset], 2);
+       }
+
+       if (param->rsn_found) {
+               int i;
+
+               param->rsn_grp_policy = crypto->cipher_group & 0xFF;
+               for (i = 0; i < crypto->n_ciphers_pairwise && i < 3; i++)
+                       param->p_suites[i] = crypto->ciphers_pairwise[i] & 0xFF;
+
+               for (i = 0; i < crypto->n_akm_suites && i < 3; i++)
+                       param->akm_suites[i] = crypto->akm_suites[i] & 0xFF;
+       }
+
+       return (void *)param;
+}
+
+static void handle_rcvd_ntwrk_info(struct work_struct *work)
+{
+       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+       struct wilc_rcvd_net_info *rcvd_info = &msg->body.net_info;
+       struct wilc_user_scan_req *scan_req = &msg->vif->hif_drv->usr_scan_req;
+       const u8 *ch_elm;
+       u8 *ies;
+       int ies_len;
+       size_t offset;
+
+       if (ieee80211_is_probe_resp(rcvd_info->mgmt->frame_control))
+               offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
+       else if (ieee80211_is_beacon(rcvd_info->mgmt->frame_control))
+               offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
+       else
+               goto done;
+
+       ies = rcvd_info->mgmt->u.beacon.variable;
+       ies_len = rcvd_info->frame_len - offset;
+       if (ies_len <= 0)
+               goto done;
+
+       ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len);
+       if (ch_elm && ch_elm[1] > 0)
+               rcvd_info->ch = ch_elm[2];
+
+       if (scan_req->scan_result)
+               scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, rcvd_info,
+                                     scan_req->arg);
+
+done:
+       kfree(rcvd_info->mgmt);
+       kfree(msg);
+}
+
+static void host_int_get_assoc_res_info(struct wilc_vif *vif,
+                                       u8 *assoc_resp_info,
+                                       u32 max_assoc_resp_info_len,
+                                       u32 *rcvd_assoc_resp_info_len)
+{
+       int result;
+       struct wid wid;
+
+       wid.id = WID_ASSOC_RES_INFO;
+       wid.type = WID_STR;
+       wid.val = assoc_resp_info;
+       wid.size = max_assoc_resp_info_len;
+
+       result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
+       if (result) {
+               *rcvd_assoc_resp_info_len = 0;
+               netdev_err(vif->ndev, "Failed to send association response\n");
+               return;
+       }
+
+       *rcvd_assoc_resp_info_len = wid.size;
+}
+
+static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len,
+                                     struct wilc_conn_info *ret_conn_info)
+{
+       u8 *ies;
+       u16 ies_len;
+       struct wilc_assoc_resp *res = (struct wilc_assoc_resp *)buffer;
+
+       ret_conn_info->status = le16_to_cpu(res->status_code);
+       if (ret_conn_info->status == WLAN_STATUS_SUCCESS) {
+               ies = &buffer[sizeof(*res)];
+               ies_len = buffer_len - sizeof(*res);
+
+               ret_conn_info->resp_ies = kmemdup(ies, ies_len, GFP_KERNEL);
+               if (!ret_conn_info->resp_ies)
+                       return -ENOMEM;
+
+               ret_conn_info->resp_ies_len = ies_len;
+       }
+
+       return 0;
+}
+
+static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
+                                                 u8 mac_status)
+{
+       struct host_if_drv *hif_drv = vif->hif_drv;
+       struct wilc_conn_info *conn_info = &hif_drv->conn_info;
+
+       if (mac_status == WILC_MAC_STATUS_CONNECTED) {
+               u32 assoc_resp_info_len;
+
+               memset(hif_drv->assoc_resp, 0, WILC_MAX_ASSOC_RESP_FRAME_SIZE);
+
+               host_int_get_assoc_res_info(vif, hif_drv->assoc_resp,
+                                           WILC_MAX_ASSOC_RESP_FRAME_SIZE,
+                                           &assoc_resp_info_len);
+
+               if (assoc_resp_info_len != 0) {
+                       s32 err = 0;
+
+                       err = wilc_parse_assoc_resp_info(hif_drv->assoc_resp,
+                                                        assoc_resp_info_len,
+                                                        conn_info);
+                       if (err)
+                               netdev_err(vif->ndev,
+                                          "wilc_parse_assoc_resp_info() returned error %d\n",
+                                          err);
+               }
+       }
+
+       del_timer(&hif_drv->connect_timer);
+       conn_info->conn_result(CONN_DISCONN_EVENT_CONN_RESP, mac_status,
+                              hif_drv->conn_info.arg);
+
+       if (mac_status == WILC_MAC_STATUS_CONNECTED &&
+           conn_info->status == WLAN_STATUS_SUCCESS) {
+               ether_addr_copy(hif_drv->assoc_bssid, conn_info->bssid);
+               hif_drv->hif_state = HOST_IF_CONNECTED;
+       } else {
+               hif_drv->hif_state = HOST_IF_IDLE;
+       }
+
+       kfree(conn_info->resp_ies);
+       conn_info->resp_ies = NULL;
+       conn_info->resp_ies_len = 0;
+
+       kfree(conn_info->req_ies);
+       conn_info->req_ies = NULL;
+       conn_info->req_ies_len = 0;
+}
+
+static inline void host_int_handle_disconnect(struct wilc_vif *vif)
+{
+       struct host_if_drv *hif_drv = vif->hif_drv;
+
+       if (hif_drv->usr_scan_req.scan_result) {
+               del_timer(&hif_drv->scan_timer);
+               handle_scan_done(vif, SCAN_EVENT_ABORTED);
+       }
+
+       if (hif_drv->conn_info.conn_result)
+               hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
+                                              0, hif_drv->conn_info.arg);
+       else
+               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
+
+       eth_zero_addr(hif_drv->assoc_bssid);
+
+       hif_drv->conn_info.req_ies_len = 0;
+       kfree(hif_drv->conn_info.req_ies);
+       hif_drv->conn_info.req_ies = NULL;
+       hif_drv->hif_state = HOST_IF_IDLE;
+}
+
+static void handle_rcvd_gnrl_async_info(struct work_struct *work)
+{
+       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+       struct wilc_vif *vif = msg->vif;
+       struct wilc_rcvd_mac_info *mac_info = &msg->body.mac_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+
+       if (!hif_drv) {
+               netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
+               goto free_msg;
+       }
+
+       if (!hif_drv->conn_info.conn_result) {
+               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
+               goto free_msg;
+       }
+
+       if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
+               host_int_parse_assoc_resp_info(vif, mac_info->status);
+       } else if (mac_info->status == WILC_MAC_STATUS_DISCONNECTED) {
+               if (hif_drv->hif_state == HOST_IF_CONNECTED) {
+                       host_int_handle_disconnect(vif);
+               } else if (hif_drv->usr_scan_req.scan_result) {
+                       del_timer(&hif_drv->scan_timer);
+                       handle_scan_done(vif, SCAN_EVENT_ABORTED);
+               }
+       }
+
+free_msg:
+       kfree(msg);
+}
+
+int wilc_disconnect(struct wilc_vif *vif)
+{
+       struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+       struct wilc_user_scan_req *scan_req;
+       struct wilc_conn_info *conn_info;
+       int result;
+       u16 dummy_reason_code = 0;
+
+       wid.id = WID_DISCONNECT;
+       wid.type = WID_CHAR;
+       wid.val = (s8 *)&dummy_reason_code;
+       wid.size = sizeof(char);
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result) {
+               netdev_err(vif->ndev, "Failed to send disconnect\n");
+               return result;
+       }
+
+       scan_req = &hif_drv->usr_scan_req;
+       conn_info = &hif_drv->conn_info;
+
+       if (scan_req->scan_result) {
+               del_timer(&hif_drv->scan_timer);
+               scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg);
+               scan_req->scan_result = NULL;
+       }
+
+       if (conn_info->conn_result) {
+               if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
+                       del_timer(&hif_drv->connect_timer);
+
+               conn_info->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, 0,
+                                      conn_info->arg);
+       } else {
+               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
+       }
+
+       hif_drv->hif_state = HOST_IF_IDLE;
+
+       eth_zero_addr(hif_drv->assoc_bssid);
+
+       conn_info->req_ies_len = 0;
+       kfree(conn_info->req_ies);
+       conn_info->req_ies = NULL;
+
+       return 0;
+}
+
+int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
+{
+       struct wid wid_list[5];
+       u32 wid_cnt = 0, result;
+
+       wid_list[wid_cnt].id = WID_LINKSPEED;
+       wid_list[wid_cnt].type = WID_CHAR;
+       wid_list[wid_cnt].size = sizeof(char);
+       wid_list[wid_cnt].val = (s8 *)&stats->link_speed;
+       wid_cnt++;
+
+       wid_list[wid_cnt].id = WID_RSSI;
+       wid_list[wid_cnt].type = WID_CHAR;
+       wid_list[wid_cnt].size = sizeof(char);
+       wid_list[wid_cnt].val = (s8 *)&stats->rssi;
+       wid_cnt++;
+
+       wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT;
+       wid_list[wid_cnt].type = WID_INT;
+       wid_list[wid_cnt].size = sizeof(u32);
+       wid_list[wid_cnt].val = (s8 *)&stats->tx_cnt;
+       wid_cnt++;
+
+       wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT;
+       wid_list[wid_cnt].type = WID_INT;
+       wid_list[wid_cnt].size = sizeof(u32);
+       wid_list[wid_cnt].val = (s8 *)&stats->rx_cnt;
+       wid_cnt++;
+
+       wid_list[wid_cnt].id = WID_FAILED_COUNT;
+       wid_list[wid_cnt].type = WID_INT;
+       wid_list[wid_cnt].size = sizeof(u32);
+       wid_list[wid_cnt].val = (s8 *)&stats->tx_fail_cnt;
+       wid_cnt++;
+
+       result = wilc_send_config_pkt(vif, WILC_GET_CFG, wid_list, wid_cnt);
+       if (result) {
+               netdev_err(vif->ndev, "Failed to send scan parameters\n");
+               return result;
+       }
+
+       if (stats->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
+           stats->link_speed != DEFAULT_LINK_SPEED)
+               wilc_enable_tcp_ack_filter(vif, true);
+       else if (stats->link_speed != DEFAULT_LINK_SPEED)
+               wilc_enable_tcp_ack_filter(vif, false);
+
+       return result;
+}
+
+static void handle_get_statistics(struct work_struct *work)
+{
+       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+       struct wilc_vif *vif = msg->vif;
+       struct rf_info *stats = (struct rf_info *)msg->body.data;
+
+       wilc_get_statistics(vif, stats);
+
+       kfree(msg);
+}
+
+static void wilc_hif_pack_sta_param(u8 *cur_byte, const u8 *mac,
+                                   struct station_parameters *params)
+{
+       ether_addr_copy(cur_byte, mac);
+       cur_byte += ETH_ALEN;
+
+       put_unaligned_le16(params->aid, cur_byte);
+       cur_byte += 2;
+
+       *cur_byte++ = params->supported_rates_len;
+       if (params->supported_rates_len > 0)
+               memcpy(cur_byte, params->supported_rates,
+                      params->supported_rates_len);
+       cur_byte += params->supported_rates_len;
+
+       if (params->ht_capa) {
+               *cur_byte++ = true;
+               memcpy(cur_byte, params->ht_capa,
+                      sizeof(struct ieee80211_ht_cap));
+       } else {
+               *cur_byte++ = false;
+       }
+       cur_byte += sizeof(struct ieee80211_ht_cap);
+
+       put_unaligned_le16(params->sta_flags_mask, cur_byte);
+       cur_byte += 2;
+       put_unaligned_le16(params->sta_flags_set, cur_byte);
+}
+
+static int handle_remain_on_chan(struct wilc_vif *vif,
+                                struct wilc_remain_ch *hif_remain_ch)
+{
+       int result;
+       u8 remain_on_chan_flag;
+       struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+
+       if (hif_drv->usr_scan_req.scan_result)
+               return -EBUSY;
+
+       if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
+               return -EBUSY;
+
+       if (vif->connecting)
+               return -EBUSY;
+
+       remain_on_chan_flag = true;
+       wid.id = WID_REMAIN_ON_CHAN;
+       wid.type = WID_STR;
+       wid.size = 2;
+       wid.val = kmalloc(wid.size, GFP_KERNEL);
+       if (!wid.val)
+               return -ENOMEM;
+
+       wid.val[0] = remain_on_chan_flag;
+       wid.val[1] = (s8)hif_remain_ch->ch;
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       kfree(wid.val);
+       if (result)
+               return -EBUSY;
+
+       hif_drv->remain_on_ch.arg = hif_remain_ch->arg;
+       hif_drv->remain_on_ch.expired = hif_remain_ch->expired;
+       hif_drv->remain_on_ch.ch = hif_remain_ch->ch;
+       hif_drv->remain_on_ch.cookie = hif_remain_ch->cookie;
+       hif_drv->remain_on_ch_timer_vif = vif;
+
+       return 0;
+}
+
+static int wilc_handle_roc_expired(struct wilc_vif *vif, u64 cookie)
+{
+       u8 remain_on_chan_flag;
+       struct wid wid;
+       int result;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+
+       if (vif->priv.p2p_listen_state) {
+               remain_on_chan_flag = false;
+               wid.id = WID_REMAIN_ON_CHAN;
+               wid.type = WID_STR;
+               wid.size = 2;
+
+               wid.val = kmalloc(wid.size, GFP_KERNEL);
+               if (!wid.val)
+                       return -ENOMEM;
+
+               wid.val[0] = remain_on_chan_flag;
+               wid.val[1] = WILC_FALSE_FRMWR_CHANNEL;
+
+               result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+               kfree(wid.val);
+               if (result != 0) {
+                       netdev_err(vif->ndev, "Failed to set remain channel\n");
+                       return -EINVAL;
+               }
+
+               if (hif_drv->remain_on_ch.expired) {
+                       hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
+                                                     cookie);
+               }
+       } else {
+               netdev_dbg(vif->ndev, "Not in listen state\n");
+       }
+
+       return 0;
+}
+
+static void wilc_handle_listen_state_expired(struct work_struct *work)
+{
+       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+
+       wilc_handle_roc_expired(msg->vif, msg->body.remain_on_ch.cookie);
+       kfree(msg);
+}
+
+static void listen_timer_cb(struct timer_list *t)
+{
+       struct host_if_drv *hif_drv = from_timer(hif_drv, t,
+                                                     remain_on_ch_timer);
+       struct wilc_vif *vif = hif_drv->remain_on_ch_timer_vif;
+       int result;
+       struct host_if_msg *msg;
+
+       del_timer(&vif->hif_drv->remain_on_ch_timer);
+
+       msg = wilc_alloc_work(vif, wilc_handle_listen_state_expired, false);
+       if (IS_ERR(msg))
+               return;
+
+       msg->body.remain_on_ch.cookie = vif->hif_drv->remain_on_ch.cookie;
+
+       result = wilc_enqueue_work(msg);
+       if (result) {
+               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
+               kfree(msg);
+       }
+}
+
+static void handle_set_mcast_filter(struct work_struct *work)
+{
+       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+       struct wilc_vif *vif = msg->vif;
+       struct wilc_set_multicast *set_mc = &msg->body.mc_info;
+       int result;
+       struct wid wid;
+       u8 *cur_byte;
+
+       wid.id = WID_SETUP_MULTICAST_FILTER;
+       wid.type = WID_BIN;
+       wid.size = sizeof(struct wilc_set_multicast) + (set_mc->cnt * ETH_ALEN);
+       wid.val = kmalloc(wid.size, GFP_KERNEL);
+       if (!wid.val)
+               goto error;
+
+       cur_byte = wid.val;
+       put_unaligned_le32(set_mc->enabled, cur_byte);
+       cur_byte += 4;
+
+       put_unaligned_le32(set_mc->cnt, cur_byte);
+       cur_byte += 4;
+
+       if (set_mc->cnt > 0 && set_mc->mc_list)
+               memcpy(cur_byte, set_mc->mc_list, set_mc->cnt * ETH_ALEN);
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to send setup multicast\n");
+
+error:
+       kfree(set_mc->mc_list);
+       kfree(wid.val);
+       kfree(msg);
+}
+
+static void handle_scan_timer(struct work_struct *work)
+{
+       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+
+       handle_scan_done(msg->vif, SCAN_EVENT_ABORTED);
+       kfree(msg);
+}
+
+static void handle_scan_complete(struct work_struct *work)
+{
+       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+
+       del_timer(&msg->vif->hif_drv->scan_timer);
+
+       handle_scan_done(msg->vif, SCAN_EVENT_DONE);
+
+       kfree(msg);
+}
+
+static void timer_scan_cb(struct timer_list *t)
+{
+       struct host_if_drv *hif_drv = from_timer(hif_drv, t, scan_timer);
+       struct wilc_vif *vif = hif_drv->scan_timer_vif;
+       struct host_if_msg *msg;
+       int result;
+
+       msg = wilc_alloc_work(vif, handle_scan_timer, false);
+       if (IS_ERR(msg))
+               return;
+
+       result = wilc_enqueue_work(msg);
+       if (result)
+               kfree(msg);
+}
+
+static void timer_connect_cb(struct timer_list *t)
+{
+       struct host_if_drv *hif_drv = from_timer(hif_drv, t,
+                                                     connect_timer);
+       struct wilc_vif *vif = hif_drv->connect_timer_vif;
+       struct host_if_msg *msg;
+       int result;
+
+       msg = wilc_alloc_work(vif, handle_connect_timeout, false);
+       if (IS_ERR(msg))
+               return;
+
+       result = wilc_enqueue_work(msg);
+       if (result)
+               kfree(msg);
+}
+
+int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
+{
+       struct wid wid;
+       int result;
+
+       wid.id = WID_REMOVE_WEP_KEY;
+       wid.type = WID_STR;
+       wid.size = sizeof(char);
+       wid.val = &index;
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev,
+                          "Failed to send remove wep key config packet\n");
+       return result;
+}
+
+int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
+{
+       struct wid wid;
+       int result;
+
+       wid.id = WID_KEY_ID;
+       wid.type = WID_CHAR;
+       wid.size = sizeof(char);
+       wid.val = &index;
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev,
+                          "Failed to send wep default key config packet\n");
+
+       return result;
+}
+
+int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
+                            u8 index)
+{
+       struct wid wid;
+       int result;
+       struct wilc_wep_key *wep_key;
+
+       wid.id = WID_ADD_WEP_KEY;
+       wid.type = WID_STR;
+       wid.size = sizeof(*wep_key) + len;
+       wep_key = kzalloc(wid.size, GFP_KERNEL);
+       if (!wep_key)
+               return -ENOMEM;
+
+       wid.val = (u8 *)wep_key;
+
+       wep_key->index = index;
+       wep_key->key_len = len;
+       memcpy(wep_key->key, key, len);
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev,
+                          "Failed to add wep key config packet\n");
+
+       kfree(wep_key);
+       return result;
+}
+
+int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
+                           u8 index, u8 mode, enum authtype auth_type)
+{
+       struct wid wid_list[3];
+       int result;
+       struct wilc_wep_key *wep_key;
+
+       wid_list[0].id = WID_11I_MODE;
+       wid_list[0].type = WID_CHAR;
+       wid_list[0].size = sizeof(char);
+       wid_list[0].val = &mode;
+
+       wid_list[1].id = WID_AUTH_TYPE;
+       wid_list[1].type = WID_CHAR;
+       wid_list[1].size = sizeof(char);
+       wid_list[1].val = (s8 *)&auth_type;
+
+       wid_list[2].id = WID_WEP_KEY_VALUE;
+       wid_list[2].type = WID_STR;
+       wid_list[2].size = sizeof(*wep_key) + len;
+       wep_key = kzalloc(wid_list[2].size, GFP_KERNEL);
+       if (!wep_key)
+               return -ENOMEM;
+
+       wid_list[2].val = (u8 *)wep_key;
+
+       wep_key->index = index;
+       wep_key->key_len = len;
+       memcpy(wep_key->key, key, len);
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
+                                     ARRAY_SIZE(wid_list));
+       if (result)
+               netdev_err(vif->ndev,
+                          "Failed to add wep ap key config packet\n");
+
+       kfree(wep_key);
+       return result;
+}
+
+int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
+                const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
+                u8 mode, u8 cipher_mode, u8 index)
+{
+       int result = 0;
+       u8 t_key_len  = ptk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN;
+
+       if (mode == WILC_AP_MODE) {
+               struct wid wid_list[2];
+               struct wilc_ap_wpa_ptk *key_buf;
+
+               wid_list[0].id = WID_11I_MODE;
+               wid_list[0].type = WID_CHAR;
+               wid_list[0].size = sizeof(char);
+               wid_list[0].val = (s8 *)&cipher_mode;
+
+               key_buf = kzalloc(sizeof(*key_buf) + t_key_len, GFP_KERNEL);
+               if (!key_buf)
+                       return -ENOMEM;
+
+               ether_addr_copy(key_buf->mac_addr, mac_addr);
+               key_buf->index = index;
+               key_buf->key_len = t_key_len;
+               memcpy(&key_buf->key[0], ptk, ptk_key_len);
+
+               if (rx_mic)
+                       memcpy(&key_buf->key[ptk_key_len], rx_mic,
+                              WILC_RX_MIC_KEY_LEN);
+
+               if (tx_mic)
+                       memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN],
+                              tx_mic, WILC_TX_MIC_KEY_LEN);
+
+               wid_list[1].id = WID_ADD_PTK;
+               wid_list[1].type = WID_STR;
+               wid_list[1].size = sizeof(*key_buf) + t_key_len;
+               wid_list[1].val = (u8 *)key_buf;
+               result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
+                                             ARRAY_SIZE(wid_list));
+               kfree(key_buf);
+       } else if (mode == WILC_STATION_MODE) {
+               struct wid wid;
+               struct wilc_sta_wpa_ptk *key_buf;
+
+               key_buf = kzalloc(sizeof(*key_buf) + t_key_len, GFP_KERNEL);
+               if (!key_buf)
+                       return -ENOMEM;
+
+               ether_addr_copy(key_buf->mac_addr, mac_addr);
+               key_buf->key_len = t_key_len;
+               memcpy(&key_buf->key[0], ptk, ptk_key_len);
+
+               if (rx_mic)
+                       memcpy(&key_buf->key[ptk_key_len], rx_mic,
+                              WILC_RX_MIC_KEY_LEN);
+
+               if (tx_mic)
+                       memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN],
+                              tx_mic, WILC_TX_MIC_KEY_LEN);
+
+               wid.id = WID_ADD_PTK;
+               wid.type = WID_STR;
+               wid.size = sizeof(*key_buf) + t_key_len;
+               wid.val = (s8 *)key_buf;
+               result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+               kfree(key_buf);
+       }
+
+       return result;
+}
+
+int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
+                   u8 index, u32 key_rsc_len, const u8 *key_rsc,
+                   const u8 *rx_mic, const u8 *tx_mic, u8 mode,
+                   u8 cipher_mode)
+{
+       int result = 0;
+       struct wilc_gtk_key *gtk_key;
+       int t_key_len = gtk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN;
+
+       gtk_key = kzalloc(sizeof(*gtk_key) + t_key_len, GFP_KERNEL);
+       if (!gtk_key)
+               return -ENOMEM;
+
+       /* fill bssid value only in station mode */
+       if (mode == WILC_STATION_MODE &&
+           vif->hif_drv->hif_state == HOST_IF_CONNECTED)
+               memcpy(gtk_key->mac_addr, vif->hif_drv->assoc_bssid, ETH_ALEN);
+
+       if (key_rsc)
+               memcpy(gtk_key->rsc, key_rsc, 8);
+       gtk_key->index = index;
+       gtk_key->key_len = t_key_len;
+       memcpy(&gtk_key->key[0], rx_gtk, gtk_key_len);
+
+       if (rx_mic)
+               memcpy(&gtk_key->key[gtk_key_len], rx_mic, WILC_RX_MIC_KEY_LEN);
+
+       if (tx_mic)
+               memcpy(&gtk_key->key[gtk_key_len + WILC_RX_MIC_KEY_LEN],
+                      tx_mic, WILC_TX_MIC_KEY_LEN);
+
+       if (mode == WILC_AP_MODE) {
+               struct wid wid_list[2];
+
+               wid_list[0].id = WID_11I_MODE;
+               wid_list[0].type = WID_CHAR;
+               wid_list[0].size = sizeof(char);
+               wid_list[0].val = (s8 *)&cipher_mode;
+
+               wid_list[1].id = WID_ADD_RX_GTK;
+               wid_list[1].type = WID_STR;
+               wid_list[1].size = sizeof(*gtk_key) + t_key_len;
+               wid_list[1].val = (u8 *)gtk_key;
+
+               result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
+                                             ARRAY_SIZE(wid_list));
+       } else if (mode == WILC_STATION_MODE) {
+               struct wid wid;
+
+               wid.id = WID_ADD_RX_GTK;
+               wid.type = WID_STR;
+               wid.size = sizeof(*gtk_key) + t_key_len;
+               wid.val = (u8 *)gtk_key;
+               result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       }
+
+       kfree(gtk_key);
+       return result;
+}
+
+int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid)
+{
+       struct wid wid;
+
+       wid.id = WID_PMKID_INFO;
+       wid.type = WID_STR;
+       wid.size = (pmkid->numpmkid * sizeof(struct wilc_pmkid)) + 1;
+       wid.val = (u8 *)pmkid;
+
+       return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+}
+
+int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
+{
+       int result;
+       struct wid wid;
+
+       wid.id = WID_MAC_ADDR;
+       wid.type = WID_STR;
+       wid.size = ETH_ALEN;
+       wid.val = mac_addr;
+
+       result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to get mac address\n");
+
+       return result;
+}
+
+int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies,
+                     size_t ies_len)
+{
+       int result;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+       struct wilc_conn_info *conn_info = &hif_drv->conn_info;
+
+       if (bssid)
+               ether_addr_copy(conn_info->bssid, bssid);
+
+       if (ies) {
+               conn_info->req_ies_len = ies_len;
+               conn_info->req_ies = kmemdup(ies, ies_len, GFP_KERNEL);
+               if (!conn_info->req_ies)
+                       return -ENOMEM;
+       }
+
+       result = wilc_send_connect_wid(vif);
+       if (result)
+               goto free_ies;
+
+       hif_drv->connect_timer_vif = vif;
+       mod_timer(&hif_drv->connect_timer,
+                 jiffies + msecs_to_jiffies(WILC_HIF_CONNECT_TIMEOUT_MS));
+
+       return 0;
+
+free_ies:
+       kfree(conn_info->req_ies);
+
+       return result;
+}
+
+int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
+{
+       struct wid wid;
+       int result;
+
+       wid.id = WID_CURRENT_CHANNEL;
+       wid.type = WID_CHAR;
+       wid.size = sizeof(char);
+       wid.val = &channel;
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to set channel\n");
+
+       return result;
+}
+
+int wilc_set_operation_mode(struct wilc_vif *vif, int index, u8 mode,
+                           u8 ifc_id)
+{
+       struct wid wid;
+       int result;
+       struct wilc_drv_handler drv;
+
+       wid.id = WID_SET_OPERATION_MODE;
+       wid.type = WID_STR;
+       wid.size = sizeof(drv);
+       wid.val = (u8 *)&drv;
+
+       drv.handler = cpu_to_le32(index);
+       drv.mode = (ifc_id | (mode << 1));
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to set driver handler\n");
+
+       return result;
+}
+
+s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val)
+{
+       struct wid wid;
+       s32 result;
+
+       wid.id = WID_SET_STA_MAC_INACTIVE_TIME;
+       wid.type = WID_STR;
+       wid.size = ETH_ALEN;
+       wid.val = kzalloc(wid.size, GFP_KERNEL);
+       if (!wid.val)
+               return -ENOMEM;
+
+       ether_addr_copy(wid.val, mac);
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       kfree(wid.val);
+       if (result) {
+               netdev_err(vif->ndev, "Failed to set inactive mac\n");
+               return result;
+       }
+
+       wid.id = WID_GET_INACTIVE_TIME;
+       wid.type = WID_INT;
+       wid.val = (s8 *)out_val;
+       wid.size = sizeof(u32);
+       result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to get inactive time\n");
+
+       return result;
+}
+
+int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
+{
+       struct wid wid;
+       int result;
+
+       if (!rssi_level) {
+               netdev_err(vif->ndev, "%s: RSSI level is NULL\n", __func__);
+               return -EFAULT;
+       }
+
+       wid.id = WID_RSSI;
+       wid.type = WID_CHAR;
+       wid.size = sizeof(char);
+       wid.val = rssi_level;
+       result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to get RSSI value\n");
+
+       return result;
+}
+
+static int wilc_get_stats_async(struct wilc_vif *vif, struct rf_info *stats)
+{
+       int result;
+       struct host_if_msg *msg;
+
+       msg = wilc_alloc_work(vif, handle_get_statistics, false);
+       if (IS_ERR(msg))
+               return PTR_ERR(msg);
+
+       msg->body.data = (char *)stats;
+
+       result = wilc_enqueue_work(msg);
+       if (result) {
+               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
+               kfree(msg);
+               return result;
+       }
+
+       return result;
+}
+
+int wilc_hif_set_cfg(struct wilc_vif *vif, struct cfg_param_attr *param)
+{
+       struct wid wid_list[4];
+       int i = 0;
+
+       if (param->flag & WILC_CFG_PARAM_RETRY_SHORT) {
+               wid_list[i].id = WID_SHORT_RETRY_LIMIT;
+               wid_list[i].val = (s8 *)&param->short_retry_limit;
+               wid_list[i].type = WID_SHORT;
+               wid_list[i].size = sizeof(u16);
+               i++;
+       }
+       if (param->flag & WILC_CFG_PARAM_RETRY_LONG) {
+               wid_list[i].id = WID_LONG_RETRY_LIMIT;
+               wid_list[i].val = (s8 *)&param->long_retry_limit;
+               wid_list[i].type = WID_SHORT;
+               wid_list[i].size = sizeof(u16);
+               i++;
+       }
+       if (param->flag & WILC_CFG_PARAM_FRAG_THRESHOLD) {
+               wid_list[i].id = WID_FRAG_THRESHOLD;
+               wid_list[i].val = (s8 *)&param->frag_threshold;
+               wid_list[i].type = WID_SHORT;
+               wid_list[i].size = sizeof(u16);
+               i++;
+       }
+       if (param->flag & WILC_CFG_PARAM_RTS_THRESHOLD) {
+               wid_list[i].id = WID_RTS_THRESHOLD;
+               wid_list[i].val = (s8 *)&param->rts_threshold;
+               wid_list[i].type = WID_SHORT;
+               wid_list[i].size = sizeof(u16);
+               i++;
+       }
+
+       return wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, i);
+}
+
+static void get_periodic_rssi(struct timer_list *t)
+{
+       struct wilc_vif *vif = from_timer(vif, t, periodic_rssi);
+
+       if (!vif->hif_drv) {
+               netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
+               return;
+       }
+
+       if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
+               wilc_get_stats_async(vif, &vif->periodic_stat);
+
+       mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
+}
+
+int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
+{
+       struct host_if_drv *hif_drv;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+
+       hif_drv  = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
+       if (!hif_drv)
+               return -ENOMEM;
+
+       *hif_drv_handler = hif_drv;
+
+       vif->hif_drv = hif_drv;
+
+       if (wilc->clients_count == 0)
+               mutex_init(&wilc->deinit_lock);
+
+       timer_setup(&vif->periodic_rssi, get_periodic_rssi, 0);
+       mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
+
+       timer_setup(&hif_drv->scan_timer, timer_scan_cb, 0);
+       timer_setup(&hif_drv->connect_timer, timer_connect_cb, 0);
+       timer_setup(&hif_drv->remain_on_ch_timer, listen_timer_cb, 0);
+
+       hif_drv->hif_state = HOST_IF_IDLE;
+
+       hif_drv->p2p_timeout = 0;
+
+       wilc->clients_count++;
+
+       return 0;
+}
+
+int wilc_deinit(struct wilc_vif *vif)
+{
+       int result = 0;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+
+       if (!hif_drv) {
+               netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
+               return -EFAULT;
+       }
+
+       mutex_lock(&vif->wilc->deinit_lock);
+
+       del_timer_sync(&hif_drv->scan_timer);
+       del_timer_sync(&hif_drv->connect_timer);
+       del_timer_sync(&vif->periodic_rssi);
+       del_timer_sync(&hif_drv->remain_on_ch_timer);
+
+       if (hif_drv->usr_scan_req.scan_result) {
+               hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
+                                                 hif_drv->usr_scan_req.arg);
+               hif_drv->usr_scan_req.scan_result = NULL;
+       }
+
+       hif_drv->hif_state = HOST_IF_IDLE;
+
+       kfree(hif_drv);
+       vif->hif_drv = NULL;
+       vif->wilc->clients_count--;
+       mutex_unlock(&vif->wilc->deinit_lock);
+       return result;
+}
+
+void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
+{
+       int result;
+       struct host_if_msg *msg;
+       int id;
+       struct host_if_drv *hif_drv;
+       struct wilc_vif *vif;
+
+       id = get_unaligned_le32(&buffer[length - 4]);
+       vif = wilc_get_vif_from_idx(wilc, id);
+       if (!vif)
+               return;
+       hif_drv = vif->hif_drv;
+
+       if (!hif_drv) {
+               netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
+               return;
+       }
+
+       msg = wilc_alloc_work(vif, handle_rcvd_ntwrk_info, false);
+       if (IS_ERR(msg))
+               return;
+
+       msg->body.net_info.frame_len = get_unaligned_le16(&buffer[6]) - 1;
+       msg->body.net_info.rssi = buffer[8];
+       msg->body.net_info.mgmt = kmemdup(&buffer[9],
+                                         msg->body.net_info.frame_len,
+                                         GFP_KERNEL);
+       if (!msg->body.net_info.mgmt) {
+               kfree(msg);
+               return;
+       }
+
+       result = wilc_enqueue_work(msg);
+       if (result) {
+               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
+               kfree(msg->body.net_info.mgmt);
+               kfree(msg);
+       }
+}
+
+void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length)
+{
+       int result;
+       struct host_if_msg *msg;
+       int id;
+       struct host_if_drv *hif_drv;
+       struct wilc_vif *vif;
+
+       mutex_lock(&wilc->deinit_lock);
+
+       id = get_unaligned_le32(&buffer[length - 4]);
+       vif = wilc_get_vif_from_idx(wilc, id);
+       if (!vif) {
+               mutex_unlock(&wilc->deinit_lock);
+               return;
+       }
+
+       hif_drv = vif->hif_drv;
+
+       if (!hif_drv) {
+               mutex_unlock(&wilc->deinit_lock);
+               return;
+       }
+
+       if (!hif_drv->conn_info.conn_result) {
+               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
+               mutex_unlock(&wilc->deinit_lock);
+               return;
+       }
+
+       msg = wilc_alloc_work(vif, handle_rcvd_gnrl_async_info, false);
+       if (IS_ERR(msg)) {
+               mutex_unlock(&wilc->deinit_lock);
+               return;
+       }
+
+       msg->body.mac_info.status = buffer[7];
+       result = wilc_enqueue_work(msg);
+       if (result) {
+               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
+               kfree(msg);
+       }
+
+       mutex_unlock(&wilc->deinit_lock);
+}
+
+void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length)
+{
+       int result;
+       int id;
+       struct host_if_drv *hif_drv;
+       struct wilc_vif *vif;
+
+       id = get_unaligned_le32(&buffer[length - 4]);
+       vif = wilc_get_vif_from_idx(wilc, id);
+       if (!vif)
+               return;
+       hif_drv = vif->hif_drv;
+
+       if (!hif_drv)
+               return;
+
+       if (hif_drv->usr_scan_req.scan_result) {
+               struct host_if_msg *msg;
+
+               msg = wilc_alloc_work(vif, handle_scan_complete, false);
+               if (IS_ERR(msg))
+                       return;
+
+               result = wilc_enqueue_work(msg);
+               if (result) {
+                       netdev_err(vif->ndev, "%s: enqueue work failed\n",
+                                  __func__);
+                       kfree(msg);
+               }
+       }
+}
+
+int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
+                          u32 duration, u16 chan,
+                          void (*expired)(void *, u64),
+                          void *user_arg)
+{
+       struct wilc_remain_ch roc;
+       int result;
+
+       roc.ch = chan;
+       roc.expired = expired;
+       roc.arg = user_arg;
+       roc.duration = duration;
+       roc.cookie = cookie;
+       result = handle_remain_on_chan(vif, &roc);
+       if (result)
+               netdev_err(vif->ndev, "%s: failed to set remain on channel\n",
+                          __func__);
+
+       return result;
+}
+
+int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie)
+{
+       if (!vif->hif_drv) {
+               netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
+               return -EFAULT;
+       }
+
+       del_timer(&vif->hif_drv->remain_on_ch_timer);
+
+       return wilc_handle_roc_expired(vif, cookie);
+}
+
+void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
+{
+       struct wid wid;
+       int result;
+       struct wilc_reg_frame reg_frame;
+
+       wid.id = WID_REGISTER_FRAME;
+       wid.type = WID_STR;
+       wid.size = sizeof(reg_frame);
+       wid.val = (u8 *)&reg_frame;
+
+       memset(&reg_frame, 0x0, sizeof(reg_frame));
+
+       if (reg)
+               reg_frame.reg = 1;
+
+       switch (frame_type) {
+       case IEEE80211_STYPE_ACTION:
+               reg_frame.reg_id = WILC_FW_ACTION_FRM_IDX;
+               break;
+
+       case IEEE80211_STYPE_PROBE_REQ:
+               reg_frame.reg_id = WILC_FW_PROBE_REQ_IDX;
+               break;
+
+       default:
+               break;
+       }
+       reg_frame.frame_type = cpu_to_le16(frame_type);
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to frame register\n");
+}
+
+int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
+                   struct cfg80211_beacon_data *params)
+{
+       struct wid wid;
+       int result;
+       u8 *cur_byte;
+
+       wid.id = WID_ADD_BEACON;
+       wid.type = WID_BIN;
+       wid.size = params->head_len + params->tail_len + 16;
+       wid.val = kzalloc(wid.size, GFP_KERNEL);
+       if (!wid.val)
+               return -ENOMEM;
+
+       cur_byte = wid.val;
+       put_unaligned_le32(interval, cur_byte);
+       cur_byte += 4;
+       put_unaligned_le32(dtim_period, cur_byte);
+       cur_byte += 4;
+       put_unaligned_le32(params->head_len, cur_byte);
+       cur_byte += 4;
+
+       if (params->head_len > 0)
+               memcpy(cur_byte, params->head, params->head_len);
+       cur_byte += params->head_len;
+
+       put_unaligned_le32(params->tail_len, cur_byte);
+       cur_byte += 4;
+
+       if (params->tail_len > 0)
+               memcpy(cur_byte, params->tail, params->tail_len);
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to send add beacon\n");
+
+       kfree(wid.val);
+
+       return result;
+}
+
+int wilc_del_beacon(struct wilc_vif *vif)
+{
+       int result;
+       struct wid wid;
+       u8 del_beacon = 0;
+
+       wid.id = WID_DEL_BEACON;
+       wid.type = WID_CHAR;
+       wid.size = sizeof(char);
+       wid.val = &del_beacon;
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to send delete beacon\n");
+
+       return result;
+}
+
+int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
+                    struct station_parameters *params)
+{
+       struct wid wid;
+       int result;
+       u8 *cur_byte;
+
+       wid.id = WID_ADD_STA;
+       wid.type = WID_BIN;
+       wid.size = WILC_ADD_STA_LENGTH + params->supported_rates_len;
+       wid.val = kmalloc(wid.size, GFP_KERNEL);
+       if (!wid.val)
+               return -ENOMEM;
+
+       cur_byte = wid.val;
+       wilc_hif_pack_sta_param(cur_byte, mac, params);
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result != 0)
+               netdev_err(vif->ndev, "Failed to send add station\n");
+
+       kfree(wid.val);
+
+       return result;
+}
+
+int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
+{
+       struct wid wid;
+       int result;
+
+       wid.id = WID_REMOVE_STA;
+       wid.type = WID_BIN;
+       wid.size = ETH_ALEN;
+       wid.val = kzalloc(wid.size, GFP_KERNEL);
+       if (!wid.val)
+               return -ENOMEM;
+
+       if (!mac_addr)
+               eth_broadcast_addr(wid.val);
+       else
+               ether_addr_copy(wid.val, mac_addr);
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to del station\n");
+
+       kfree(wid.val);
+
+       return result;
+}
+
+int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
+{
+       struct wid wid;
+       int result;
+       int i;
+       u8 assoc_sta = 0;
+       struct wilc_del_all_sta del_sta;
+
+       memset(&del_sta, 0x0, sizeof(del_sta));
+       for (i = 0; i < WILC_MAX_NUM_STA; i++) {
+               if (!is_zero_ether_addr(mac_addr[i])) {
+                       assoc_sta++;
+                       ether_addr_copy(del_sta.mac[i], mac_addr[i]);
+               }
+       }
+
+       if (!assoc_sta)
+               return 0;
+
+       del_sta.assoc_sta = assoc_sta;
+
+       wid.id = WID_DEL_ALL_STA;
+       wid.type = WID_STR;
+       wid.size = (assoc_sta * ETH_ALEN) + 1;
+       wid.val = (u8 *)&del_sta;
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to send delete all station\n");
+
+       return result;
+}
+
+int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
+                     struct station_parameters *params)
+{
+       struct wid wid;
+       int result;
+       u8 *cur_byte;
+
+       wid.id = WID_EDIT_STA;
+       wid.type = WID_BIN;
+       wid.size = WILC_ADD_STA_LENGTH + params->supported_rates_len;
+       wid.val = kmalloc(wid.size, GFP_KERNEL);
+       if (!wid.val)
+               return -ENOMEM;
+
+       cur_byte = wid.val;
+       wilc_hif_pack_sta_param(cur_byte, mac, params);
+
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to send edit station\n");
+
+       kfree(wid.val);
+       return result;
+}
+
+int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
+{
+       struct wid wid;
+       int result;
+       s8 power_mode;
+
+       if (enabled)
+               power_mode = WILC_FW_MIN_FAST_PS;
+       else
+               power_mode = WILC_FW_NO_POWERSAVE;
+
+       wid.id = WID_POWER_MANAGEMENT;
+       wid.val = &power_mode;
+       wid.size = sizeof(char);
+       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+       if (result)
+               netdev_err(vif->ndev, "Failed to send power management\n");
+
+       return result;
+}
+
+int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count,
+                               u8 *mc_list)
+{
+       int result;
+       struct host_if_msg *msg;
+
+       msg = wilc_alloc_work(vif, handle_set_mcast_filter, false);
+       if (IS_ERR(msg))
+               return PTR_ERR(msg);
+
+       msg->body.mc_info.enabled = enabled;
+       msg->body.mc_info.cnt = count;
+       msg->body.mc_info.mc_list = mc_list;
+
+       result = wilc_enqueue_work(msg);
+       if (result) {
+               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
+               kfree(msg);
+       }
+       return result;
+}
+
+int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
+{
+       struct wid wid;
+
+       wid.id = WID_TX_POWER;
+       wid.type = WID_CHAR;
+       wid.val = &tx_power;
+       wid.size = sizeof(char);
+
+       return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
+}
+
+int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
+{
+       struct wid wid;
+
+       wid.id = WID_TX_POWER;
+       wid.type = WID_CHAR;
+       wid.val = tx_power;
+       wid.size = sizeof(char);
+
+       return wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
+}
diff --git a/drivers/net/wireless/microchip/wilc1000/hif.h b/drivers/net/wireless/microchip/wilc1000/hif.h
new file mode 100644 (file)
index 0000000..db91791
--- /dev/null
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries
+ * All rights reserved.
+ */
+
+#ifndef WILC_HIF_H
+#define WILC_HIF_H
+#include <linux/ieee80211.h>
+#include "wlan_if.h"
+
+enum {
+       WILC_IDLE_MODE = 0x0,
+       WILC_AP_MODE = 0x1,
+       WILC_STATION_MODE = 0x2,
+       WILC_GO_MODE = 0x3,
+       WILC_CLIENT_MODE = 0x4
+};
+
+#define WILC_MAX_NUM_PROBED_SSID               10
+
+#define WILC_TX_MIC_KEY_LEN                    8
+#define WILC_RX_MIC_KEY_LEN                    8
+
+#define WILC_ADD_STA_LENGTH                    40
+#define WILC_NUM_CONCURRENT_IFC                        2
+
+enum {
+       WILC_SET_CFG = 0,
+       WILC_GET_CFG
+};
+
+#define WILC_MAX_ASSOC_RESP_FRAME_SIZE   256
+
+struct rf_info {
+       u8 link_speed;
+       s8 rssi;
+       u32 tx_cnt;
+       u32 rx_cnt;
+       u32 tx_fail_cnt;
+};
+
+enum host_if_state {
+       HOST_IF_IDLE                    = 0,
+       HOST_IF_SCANNING                = 1,
+       HOST_IF_CONNECTING              = 2,
+       HOST_IF_WAITING_CONN_RESP       = 3,
+       HOST_IF_CONNECTED               = 4,
+       HOST_IF_P2P_LISTEN              = 5,
+       HOST_IF_FORCE_32BIT             = 0xFFFFFFFF
+};
+
+struct cfg_param_attr {
+       u32 flag;
+       u16 short_retry_limit;
+       u16 long_retry_limit;
+       u16 frag_threshold;
+       u16 rts_threshold;
+};
+
+enum cfg_param {
+       WILC_CFG_PARAM_RETRY_SHORT = BIT(0),
+       WILC_CFG_PARAM_RETRY_LONG = BIT(1),
+       WILC_CFG_PARAM_FRAG_THRESHOLD = BIT(2),
+       WILC_CFG_PARAM_RTS_THRESHOLD = BIT(3)
+};
+
+enum scan_event {
+       SCAN_EVENT_NETWORK_FOUND        = 0,
+       SCAN_EVENT_DONE                 = 1,
+       SCAN_EVENT_ABORTED              = 2,
+       SCAN_EVENT_FORCE_32BIT          = 0xFFFFFFFF
+};
+
+enum conn_event {
+       CONN_DISCONN_EVENT_CONN_RESP            = 0,
+       CONN_DISCONN_EVENT_DISCONN_NOTIF        = 1,
+       CONN_DISCONN_EVENT_FORCE_32BIT          = 0xFFFFFFFF
+};
+
+enum {
+       WILC_HIF_SDIO = 0,
+       WILC_HIF_SPI = BIT(0)
+};
+
+enum {
+       WILC_MAC_STATUS_INIT = -1,
+       WILC_MAC_STATUS_DISCONNECTED = 0,
+       WILC_MAC_STATUS_CONNECTED = 1
+};
+
+struct wilc_rcvd_net_info {
+       s8 rssi;
+       u8 ch;
+       u16 frame_len;
+       struct ieee80211_mgmt *mgmt;
+};
+
+struct wilc_user_scan_req {
+       void (*scan_result)(enum scan_event evt,
+                           struct wilc_rcvd_net_info *info, void *priv);
+       void *arg;
+       u32 ch_cnt;
+};
+
+struct wilc_conn_info {
+       u8 bssid[ETH_ALEN];
+       u8 security;
+       enum authtype auth_type;
+       u8 ch;
+       u8 *req_ies;
+       size_t req_ies_len;
+       u8 *resp_ies;
+       u16 resp_ies_len;
+       u16 status;
+       void (*conn_result)(enum conn_event evt, u8 status, void *priv_data);
+       void *arg;
+       void *param;
+};
+
+struct wilc_remain_ch {
+       u16 ch;
+       u32 duration;
+       void (*expired)(void *priv, u64 cookie);
+       void *arg;
+       u32 cookie;
+};
+
+struct wilc;
+struct host_if_drv {
+       struct wilc_user_scan_req usr_scan_req;
+       struct wilc_conn_info conn_info;
+       struct wilc_remain_ch remain_on_ch;
+       u64 p2p_timeout;
+
+       enum host_if_state hif_state;
+
+       u8 assoc_bssid[ETH_ALEN];
+
+       struct timer_list scan_timer;
+       struct wilc_vif *scan_timer_vif;
+
+       struct timer_list connect_timer;
+       struct wilc_vif *connect_timer_vif;
+
+       struct timer_list remain_on_ch_timer;
+       struct wilc_vif *remain_on_ch_timer_vif;
+
+       bool ifc_up;
+       u8 assoc_resp[WILC_MAX_ASSOC_RESP_FRAME_SIZE];
+};
+
+struct wilc_vif;
+int wilc_remove_wep_key(struct wilc_vif *vif, u8 index);
+int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index);
+int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
+                            u8 index);
+int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
+                           u8 index, u8 mode, enum authtype auth_type);
+int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
+                const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
+                u8 mode, u8 cipher_mode, u8 index);
+s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
+                          u32 *out_val);
+int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
+                   u8 index, u32 key_rsc_len, const u8 *key_rsc,
+                   const u8 *rx_mic, const u8 *tx_mic, u8 mode,
+                   u8 cipher_mode);
+int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid);
+int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr);
+int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies,
+                     size_t ies_len);
+int wilc_disconnect(struct wilc_vif *vif);
+int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel);
+int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level);
+int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
+             u8 *ch_freq_list, u8 ch_list_len,
+             void (*scan_result_fn)(enum scan_event,
+                                    struct wilc_rcvd_net_info *, void *),
+             void *user_arg, struct cfg80211_scan_request *request);
+int wilc_hif_set_cfg(struct wilc_vif *vif,
+                    struct cfg_param_attr *cfg_param);
+int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler);
+int wilc_deinit(struct wilc_vif *vif);
+int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
+                   struct cfg80211_beacon_data *params);
+int wilc_del_beacon(struct wilc_vif *vif);
+int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
+                    struct station_parameters *params);
+int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN]);
+int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr);
+int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
+                     struct station_parameters *params);
+int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout);
+int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count,
+                               u8 *mc_list);
+int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
+                          u32 duration, u16 chan,
+                          void (*expired)(void *, u64),
+                          void *user_arg);
+int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie);
+void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg);
+int wilc_set_operation_mode(struct wilc_vif *vif, int index, u8 mode,
+                           u8 ifc_id);
+int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats);
+int wilc_get_vif_idx(struct wilc_vif *vif);
+int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power);
+int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power);
+void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length);
+void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length);
+void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length);
+void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+                               struct cfg80211_crypto_settings *crypto);
+#endif
diff --git a/drivers/net/wireless/microchip/wilc1000/mon.c b/drivers/net/wireless/microchip/wilc1000/mon.c
new file mode 100644 (file)
index 0000000..6033141
--- /dev/null
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#include "cfg80211.h"
+
+struct wilc_wfi_radiotap_hdr {
+       struct ieee80211_radiotap_header hdr;
+       u8 rate;
+} __packed;
+
+struct wilc_wfi_radiotap_cb_hdr {
+       struct ieee80211_radiotap_header hdr;
+       u8 rate;
+       u8 dump;
+       u16 tx_flags;
+} __packed;
+
+#define TX_RADIOTAP_PRESENT ((1 << IEEE80211_RADIOTAP_RATE) |  \
+                            (1 << IEEE80211_RADIOTAP_TX_FLAGS))
+
+void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size)
+{
+       u32 header, pkt_offset;
+       struct sk_buff *skb = NULL;
+       struct wilc_wfi_radiotap_hdr *hdr;
+       struct wilc_wfi_radiotap_cb_hdr *cb_hdr;
+
+       if (!mon_dev)
+               return;
+
+       if (!netif_running(mon_dev))
+               return;
+
+       /* Get WILC header */
+       header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
+       /*
+        * The packet offset field contain info about what type of management
+        * the frame we are dealing with and ack status
+        */
+       pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
+
+       if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
+               /* hostapd callback mgmt frame */
+
+               skb = dev_alloc_skb(size + sizeof(*cb_hdr));
+               if (!skb)
+                       return;
+
+               skb_put_data(skb, buff, size);
+
+               cb_hdr = skb_push(skb, sizeof(*cb_hdr));
+               memset(cb_hdr, 0, sizeof(*cb_hdr));
+
+               cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
+
+               cb_hdr->hdr.it_len = cpu_to_le16(sizeof(*cb_hdr));
+
+               cb_hdr->hdr.it_present = cpu_to_le32(TX_RADIOTAP_PRESENT);
+
+               cb_hdr->rate = 5;
+
+               if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
+                       /* success */
+                       cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS;
+               } else {
+                       cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL;
+               }
+
+       } else {
+               skb = dev_alloc_skb(size + sizeof(*hdr));
+
+               if (!skb)
+                       return;
+
+               skb_put_data(skb, buff, size);
+               hdr = skb_push(skb, sizeof(*hdr));
+               memset(hdr, 0, sizeof(struct wilc_wfi_radiotap_hdr));
+               hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
+               hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
+               hdr->hdr.it_present = cpu_to_le32
+                               (1 << IEEE80211_RADIOTAP_RATE);
+               hdr->rate = 5;
+       }
+
+       skb->dev = mon_dev;
+       skb_reset_mac_header(skb);
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
+       skb->pkt_type = PACKET_OTHERHOST;
+       skb->protocol = htons(ETH_P_802_2);
+       memset(skb->cb, 0, sizeof(skb->cb));
+
+       netif_rx(skb);
+}
+
+struct tx_complete_mon_data {
+       int size;
+       void *buff;
+};
+
+static void mgmt_tx_complete(void *priv, int status)
+{
+       struct tx_complete_mon_data *pv_data = priv;
+       /*
+        * in case of fully hosting mode, the freeing will be done
+        * in response to the cfg packet
+        */
+       kfree(pv_data->buff);
+
+       kfree(pv_data);
+}
+
+static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len)
+{
+       struct tx_complete_mon_data *mgmt_tx = NULL;
+
+       if (!dev)
+               return -EFAULT;
+
+       netif_stop_queue(dev);
+       mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_ATOMIC);
+       if (!mgmt_tx)
+               return -ENOMEM;
+
+       mgmt_tx->buff = kmemdup(buf, len, GFP_ATOMIC);
+       if (!mgmt_tx->buff) {
+               kfree(mgmt_tx);
+               return -ENOMEM;
+       }
+
+       mgmt_tx->size = len;
+
+       wilc_wlan_txq_add_mgmt_pkt(dev, mgmt_tx, mgmt_tx->buff, mgmt_tx->size,
+                                  mgmt_tx_complete);
+
+       netif_wake_queue(dev);
+       return 0;
+}
+
+static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb,
+                                    struct net_device *dev)
+{
+       u32 rtap_len, ret = 0;
+       struct wilc_wfi_mon_priv  *mon_priv;
+       struct sk_buff *skb2;
+       struct wilc_wfi_radiotap_cb_hdr *cb_hdr;
+       u8 srcadd[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+
+       mon_priv = netdev_priv(dev);
+       if (!mon_priv)
+               return -EFAULT;
+
+       rtap_len = ieee80211_get_radiotap_len(skb->data);
+       if (skb->len < rtap_len)
+               return -1;
+
+       skb_pull(skb, rtap_len);
+
+       if (skb->data[0] == 0xc0 && is_broadcast_ether_addr(&skb->data[4])) {
+               skb2 = dev_alloc_skb(skb->len + sizeof(*cb_hdr));
+               if (!skb2)
+                       return -ENOMEM;
+
+               skb_put_data(skb2, skb->data, skb->len);
+
+               cb_hdr = skb_push(skb2, sizeof(*cb_hdr));
+               memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr));
+
+               cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
+
+               cb_hdr->hdr.it_len = cpu_to_le16(sizeof(*cb_hdr));
+
+               cb_hdr->hdr.it_present = cpu_to_le32(TX_RADIOTAP_PRESENT);
+
+               cb_hdr->rate = 5;
+               cb_hdr->tx_flags = 0x0004;
+
+               skb2->dev = dev;
+               skb_reset_mac_header(skb2);
+               skb2->ip_summed = CHECKSUM_UNNECESSARY;
+               skb2->pkt_type = PACKET_OTHERHOST;
+               skb2->protocol = htons(ETH_P_802_2);
+               memset(skb2->cb, 0, sizeof(skb2->cb));
+
+               netif_rx(skb2);
+
+               return 0;
+       }
+       skb->dev = mon_priv->real_ndev;
+
+       ether_addr_copy(srcadd, &skb->data[10]);
+       ether_addr_copy(bssid, &skb->data[16]);
+       /*
+        * Identify if data or mgmt packet, if source address and bssid
+        * fields are equal send it to mgmt frames handler
+        */
+       if (!(memcmp(srcadd, bssid, 6))) {
+               ret = mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len);
+               if (ret)
+                       netdev_err(dev, "fail to mgmt tx\n");
+               dev_kfree_skb(skb);
+       } else {
+               ret = wilc_mac_xmit(skb, mon_priv->real_ndev);
+       }
+
+       return ret;
+}
+
+static const struct net_device_ops wilc_wfi_netdev_ops = {
+       .ndo_start_xmit         = wilc_wfi_mon_xmit,
+
+};
+
+struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
+                                              const char *name,
+                                              struct net_device *real_dev)
+{
+       struct wilc_wfi_mon_priv *priv;
+
+       /* If monitor interface is already initialized, return it */
+       if (wl->monitor_dev)
+               return wl->monitor_dev;
+
+       wl->monitor_dev = alloc_etherdev(sizeof(struct wilc_wfi_mon_priv));
+       if (!wl->monitor_dev)
+               return NULL;
+
+       wl->monitor_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+       strncpy(wl->monitor_dev->name, name, IFNAMSIZ);
+       wl->monitor_dev->name[IFNAMSIZ - 1] = 0;
+       wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops;
+       wl->monitor_dev->needs_free_netdev = true;
+
+       if (register_netdevice(wl->monitor_dev)) {
+               netdev_err(real_dev, "register_netdevice failed\n");
+               return NULL;
+       }
+       priv = netdev_priv(wl->monitor_dev);
+       if (!priv)
+               return NULL;
+
+       priv->real_ndev = real_dev;
+
+       return wl->monitor_dev;
+}
+
+void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked)
+{
+       if (!wl->monitor_dev)
+               return;
+
+       if (rtnl_locked)
+               unregister_netdevice(wl->monitor_dev);
+       else
+               unregister_netdev(wl->monitor_dev);
+       wl->monitor_dev = NULL;
+}
diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
new file mode 100644 (file)
index 0000000..fda0ab9
--- /dev/null
@@ -0,0 +1,931 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#include <linux/irq.h>
+#include <linux/kthread.h>
+#include <linux/firmware.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+
+#include "cfg80211.h"
+#include "wlan_cfg.h"
+
+#define WILC_MULTICAST_TABLE_SIZE      8
+
+static irqreturn_t isr_uh_routine(int irq, void *user_data)
+{
+       struct net_device *dev = user_data;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+
+       if (wilc->close) {
+               netdev_err(dev, "Can't handle UH interrupt\n");
+               return IRQ_HANDLED;
+       }
+       return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t isr_bh_routine(int irq, void *userdata)
+{
+       struct net_device *dev = userdata;
+       struct wilc_vif *vif = netdev_priv(userdata);
+       struct wilc *wilc = vif->wilc;
+
+       if (wilc->close) {
+               netdev_err(dev, "Can't handle BH interrupt\n");
+               return IRQ_HANDLED;
+       }
+
+       wilc_handle_isr(wilc);
+
+       return IRQ_HANDLED;
+}
+
+static int init_irq(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wl = vif->wilc;
+       int ret;
+
+       ret = request_threaded_irq(wl->dev_irq_num, isr_uh_routine,
+                                  isr_bh_routine,
+                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                  "WILC_IRQ", dev);
+       if (ret) {
+               netdev_err(dev, "Failed to request IRQ [%d]\n", ret);
+               return ret;
+       }
+       netdev_dbg(dev, "IRQ request succeeded IRQ-NUM= %d\n", wl->dev_irq_num);
+
+       return 0;
+}
+
+static void deinit_irq(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+
+       /* Deinitialize IRQ */
+       if (wilc->dev_irq_num)
+               free_irq(wilc->dev_irq_num, wilc);
+}
+
+void wilc_mac_indicate(struct wilc *wilc)
+{
+       s8 status;
+
+       wilc_wlan_cfg_get_val(wilc, WID_STATUS, &status, 1);
+       if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
+               wilc->mac_status = status;
+               complete(&wilc->sync_event);
+       } else {
+               wilc->mac_status = status;
+       }
+}
+
+static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
+{
+       struct net_device *ndev = NULL;
+       struct wilc_vif *vif;
+       struct ieee80211_hdr *h = (struct ieee80211_hdr *)mac_header;
+
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+               if (vif->mode == WILC_STATION_MODE)
+                       if (ether_addr_equal_unaligned(h->addr2, vif->bssid)) {
+                               ndev = vif->ndev;
+                               goto out;
+                       }
+               if (vif->mode == WILC_AP_MODE)
+                       if (ether_addr_equal_unaligned(h->addr1, vif->bssid)) {
+                               ndev = vif->ndev;
+                               goto out;
+                       }
+       }
+out:
+       return ndev;
+}
+
+void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode)
+{
+       struct wilc_vif *vif = netdev_priv(wilc_netdev);
+
+       if (bssid)
+               ether_addr_copy(vif->bssid, bssid);
+       else
+               eth_zero_addr(vif->bssid);
+
+       vif->mode = mode;
+}
+
+int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
+{
+       int srcu_idx;
+       u8 ret_val = 0;
+       struct wilc_vif *vif;
+
+       srcu_idx = srcu_read_lock(&wilc->srcu);
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+               if (!is_zero_ether_addr(vif->bssid))
+                       ret_val++;
+       }
+       srcu_read_unlock(&wilc->srcu, srcu_idx);
+       return ret_val;
+}
+
+static int wilc_txq_task(void *vp)
+{
+       int ret;
+       u32 txq_count;
+       struct wilc *wl = vp;
+
+       complete(&wl->txq_thread_started);
+       while (1) {
+               wait_for_completion(&wl->txq_event);
+
+               if (wl->close) {
+                       complete(&wl->txq_thread_started);
+
+                       while (!kthread_should_stop())
+                               schedule();
+                       break;
+               }
+               do {
+                       ret = wilc_wlan_handle_txq(wl, &txq_count);
+                       if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
+                               int srcu_idx;
+                               struct wilc_vif *ifc;
+
+                               srcu_idx = srcu_read_lock(&wl->srcu);
+                               list_for_each_entry_rcu(ifc, &wl->vif_list,
+                                                       list) {
+                                       if (ifc->mac_opened && ifc->ndev)
+                                               netif_wake_queue(ifc->ndev);
+                               }
+                               srcu_read_unlock(&wl->srcu, srcu_idx);
+                       }
+               } while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close);
+       }
+       return 0;
+}
+
+static int wilc_wlan_get_firmware(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+       int chip_id;
+       const struct firmware *wilc_firmware;
+       char *firmware;
+
+       chip_id = wilc_get_chipid(wilc, false);
+
+       if (chip_id < 0x1003a0)
+               firmware = FIRMWARE_1002;
+       else
+               firmware = FIRMWARE_1003;
+
+       netdev_info(dev, "loading firmware %s\n", firmware);
+
+       if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
+               netdev_err(dev, "%s - firmware not available\n", firmware);
+               return -EINVAL;
+       }
+       wilc->firmware = wilc_firmware;
+
+       return 0;
+}
+
+static int wilc_start_firmware(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+       int ret = 0;
+
+       ret = wilc_wlan_start(wilc);
+       if (ret)
+               return ret;
+
+       if (!wait_for_completion_timeout(&wilc->sync_event,
+                                        msecs_to_jiffies(5000)))
+               return -ETIME;
+
+       return 0;
+}
+
+static int wilc1000_firmware_download(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+       int ret = 0;
+
+       if (!wilc->firmware) {
+               netdev_err(dev, "Firmware buffer is NULL\n");
+               return -ENOBUFS;
+       }
+
+       ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data,
+                                         wilc->firmware->size);
+       if (ret)
+               return ret;
+
+       release_firmware(wilc->firmware);
+       wilc->firmware = NULL;
+
+       netdev_dbg(dev, "Download Succeeded\n");
+
+       return 0;
+}
+
+static int wilc_init_fw_config(struct net_device *dev, struct wilc_vif *vif)
+{
+       struct wilc_priv *priv = &vif->priv;
+       struct host_if_drv *hif_drv;
+       u8 b;
+       u16 hw;
+       u32 w;
+
+       netdev_dbg(dev, "Start configuring Firmware\n");
+       hif_drv = (struct host_if_drv *)priv->hif_drv;
+       netdev_dbg(dev, "Host = %p\n", hif_drv);
+
+       w = vif->iftype;
+       cpu_to_le32s(&w);
+       if (!wilc_wlan_cfg_set(vif, 1, WID_SET_OPERATION_MODE, (u8 *)&w, 4,
+                              0, 0))
+               goto fail;
+
+       b = WILC_FW_BSS_TYPE_INFRA;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_BSS_TYPE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_TX_RATE_AUTO;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_TX_RATE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_OPER_MODE_G_MIXED_11B_2;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11G_OPERATING_MODE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_PREAMBLE_SHORT;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_PREAMBLE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_11N_PROT_AUTO;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_PROT_MECH, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_ACTIVE_SCAN;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_SCAN_TYPE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_SITE_SURVEY_OFF;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_SITE_SURVEY, &b, 1, 0, 0))
+               goto fail;
+
+       hw = 0xffff;
+       cpu_to_le16s(&hw);
+       if (!wilc_wlan_cfg_set(vif, 0, WID_RTS_THRESHOLD, (u8 *)&hw, 2, 0, 0))
+               goto fail;
+
+       hw = 2346;
+       cpu_to_le16s(&hw);
+       if (!wilc_wlan_cfg_set(vif, 0, WID_FRAG_THRESHOLD, (u8 *)&hw, 2, 0, 0))
+               goto fail;
+
+       b = 0;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_BCAST_SSID, &b, 1, 0, 0))
+               goto fail;
+
+       b = 1;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_QOS_ENABLE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_NO_POWERSAVE;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_POWER_MANAGEMENT, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_SEC_NO;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11I_MODE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_AUTH_OPEN_SYSTEM;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_AUTH_TYPE, &b, 1, 0, 0))
+               goto fail;
+
+       b = 3;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_LISTEN_INTERVAL, &b, 1, 0, 0))
+               goto fail;
+
+       b = 3;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_DTIM_PERIOD, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_ACK_POLICY_NORMAL;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_ACK_POLICY, &b, 1, 0, 0))
+               goto fail;
+
+       b = 0;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_USER_CONTROL_ON_TX_POWER, &b, 1,
+                              0, 0))
+               goto fail;
+
+       b = 48;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11A, &b, 1, 0, 0))
+               goto fail;
+
+       b = 28;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11B, &b, 1, 0, 0))
+               goto fail;
+
+       hw = 100;
+       cpu_to_le16s(&hw);
+       if (!wilc_wlan_cfg_set(vif, 0, WID_BEACON_INTERVAL, (u8 *)&hw, 2, 0, 0))
+               goto fail;
+
+       b = WILC_FW_REKEY_POLICY_DISABLE;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_POLICY, &b, 1, 0, 0))
+               goto fail;
+
+       w = 84600;
+       cpu_to_le32s(&w);
+       if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PERIOD, (u8 *)&w, 4, 0, 0))
+               goto fail;
+
+       w = 500;
+       cpu_to_le32s(&w);
+       if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PACKET_COUNT, (u8 *)&w, 4, 0,
+                              0))
+               goto fail;
+
+       b = 1;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_SHORT_SLOT_ALLOWED, &b, 1, 0,
+                              0))
+               goto fail;
+
+       b = WILC_FW_ERP_PROT_SELF_CTS;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ERP_PROT_TYPE, &b, 1, 0, 0))
+               goto fail;
+
+       b = 1;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ENABLE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_11N_OP_MODE_HT_MIXED;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OPERATING_MODE, &b, 1, 0, 0))
+               goto fail;
+
+       b = 1;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_TXOP_PROT_DISABLE, &b, 1, 0, 0))
+               goto fail;
+
+       b = WILC_FW_OBBS_NONHT_DETECT_PROTECT_REPORT;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OBSS_NONHT_DETECTION, &b, 1,
+                              0, 0))
+               goto fail;
+
+       b = WILC_FW_HT_PROT_RTS_CTS_NONHT;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_HT_PROT_TYPE, &b, 1, 0, 0))
+               goto fail;
+
+       b = 0;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_RIFS_PROT_ENABLE, &b, 1, 0,
+                              0))
+               goto fail;
+
+       b = 7;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_CURRENT_TX_MCS, &b, 1, 0, 0))
+               goto fail;
+
+       b = 1;
+       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_IMMEDIATE_BA_ENABLED, &b, 1,
+                              1, 1))
+               goto fail;
+
+       return 0;
+
+fail:
+       return -EINVAL;
+}
+
+static void wlan_deinitialize_threads(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wl = vif->wilc;
+
+       wl->close = 1;
+
+       complete(&wl->txq_event);
+
+       if (wl->txq_thread) {
+               kthread_stop(wl->txq_thread);
+               wl->txq_thread = NULL;
+       }
+}
+
+static void wilc_wlan_deinitialize(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wl = vif->wilc;
+
+       if (!wl) {
+               netdev_err(dev, "wl is NULL\n");
+               return;
+       }
+
+       if (wl->initialized) {
+               netdev_info(dev, "Deinitializing wilc1000...\n");
+
+               if (!wl->dev_irq_num &&
+                   wl->hif_func->disable_interrupt) {
+                       mutex_lock(&wl->hif_cs);
+                       wl->hif_func->disable_interrupt(wl);
+                       mutex_unlock(&wl->hif_cs);
+               }
+               complete(&wl->txq_event);
+
+               wlan_deinitialize_threads(dev);
+               deinit_irq(dev);
+
+               wilc_wlan_stop(wl, vif);
+               wilc_wlan_cleanup(dev);
+
+               wl->initialized = false;
+
+               netdev_dbg(dev, "wilc1000 deinitialization Done\n");
+       } else {
+               netdev_dbg(dev, "wilc1000 is not initialized\n");
+       }
+}
+
+static int wlan_initialize_threads(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+
+       wilc->txq_thread = kthread_run(wilc_txq_task, (void *)wilc,
+                                      "K_TXQ_TASK");
+       if (IS_ERR(wilc->txq_thread)) {
+               netdev_err(dev, "couldn't create TXQ thread\n");
+               wilc->close = 0;
+               return PTR_ERR(wilc->txq_thread);
+       }
+       wait_for_completion(&wilc->txq_thread_started);
+
+       return 0;
+}
+
+static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
+{
+       int ret = 0;
+       struct wilc *wl = vif->wilc;
+
+       if (!wl->initialized) {
+               wl->mac_status = WILC_MAC_STATUS_INIT;
+               wl->close = 0;
+
+               ret = wilc_wlan_init(dev);
+               if (ret)
+                       return ret;
+
+               ret = wlan_initialize_threads(dev);
+               if (ret)
+                       goto fail_wilc_wlan;
+
+               if (wl->dev_irq_num && init_irq(dev)) {
+                       ret = -EIO;
+                       goto fail_threads;
+               }
+
+               if (!wl->dev_irq_num &&
+                   wl->hif_func->enable_interrupt &&
+                   wl->hif_func->enable_interrupt(wl)) {
+                       ret = -EIO;
+                       goto fail_irq_init;
+               }
+
+               ret = wilc_wlan_get_firmware(dev);
+               if (ret)
+                       goto fail_irq_enable;
+
+               ret = wilc1000_firmware_download(dev);
+               if (ret)
+                       goto fail_irq_enable;
+
+               ret = wilc_start_firmware(dev);
+               if (ret)
+                       goto fail_irq_enable;
+
+               if (wilc_wlan_cfg_get(vif, 1, WID_FIRMWARE_VERSION, 1, 0)) {
+                       int size;
+                       char firmware_ver[20];
+
+                       size = wilc_wlan_cfg_get_val(wl, WID_FIRMWARE_VERSION,
+                                                    firmware_ver,
+                                                    sizeof(firmware_ver));
+                       firmware_ver[size] = '\0';
+                       netdev_dbg(dev, "Firmware Ver = %s\n", firmware_ver);
+               }
+
+               ret = wilc_init_fw_config(dev, vif);
+               if (ret) {
+                       netdev_err(dev, "Failed to configure firmware\n");
+                       goto fail_fw_start;
+               }
+               wl->initialized = true;
+               return 0;
+
+fail_fw_start:
+               wilc_wlan_stop(wl, vif);
+
+fail_irq_enable:
+               if (!wl->dev_irq_num &&
+                   wl->hif_func->disable_interrupt)
+                       wl->hif_func->disable_interrupt(wl);
+fail_irq_init:
+               if (wl->dev_irq_num)
+                       deinit_irq(dev);
+fail_threads:
+               wlan_deinitialize_threads(dev);
+fail_wilc_wlan:
+               wilc_wlan_cleanup(dev);
+               netdev_err(dev, "WLAN initialization FAILED\n");
+       } else {
+               netdev_dbg(dev, "wilc1000 already initialized\n");
+       }
+       return ret;
+}
+
+static int mac_init_fn(struct net_device *ndev)
+{
+       netif_start_queue(ndev);
+       netif_stop_queue(ndev);
+
+       return 0;
+}
+
+static int wilc_mac_open(struct net_device *ndev)
+{
+       struct wilc_vif *vif = netdev_priv(ndev);
+       struct wilc *wl = vif->wilc;
+       unsigned char mac_add[ETH_ALEN] = {0};
+       int ret = 0;
+       struct mgmt_frame_regs mgmt_regs = {};
+
+       if (!wl || !wl->dev) {
+               netdev_err(ndev, "device not ready\n");
+               return -ENODEV;
+       }
+
+       netdev_dbg(ndev, "MAC OPEN[%p]\n", ndev);
+
+       ret = wilc_init_host_int(ndev);
+       if (ret)
+               return ret;
+
+       ret = wilc_wlan_initialize(ndev, vif);
+       if (ret) {
+               wilc_deinit_host_int(ndev);
+               return ret;
+       }
+
+       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype,
+                               vif->idx);
+       wilc_get_mac_address(vif, mac_add);
+       netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
+       ether_addr_copy(ndev->dev_addr, mac_add);
+
+       if (!is_valid_ether_addr(ndev->dev_addr)) {
+               netdev_err(ndev, "Wrong MAC address\n");
+               wilc_deinit_host_int(ndev);
+               wilc_wlan_deinitialize(ndev);
+               return -EINVAL;
+       }
+
+       mgmt_regs.interface_stypes = vif->mgmt_reg_stypes;
+       /* so we detect a change */
+       vif->mgmt_reg_stypes = 0;
+       wilc_update_mgmt_frame_registrations(vif->ndev->ieee80211_ptr->wiphy,
+                                            vif->ndev->ieee80211_ptr,
+                                            &mgmt_regs);
+       netif_wake_queue(ndev);
+       wl->open_ifcs++;
+       vif->mac_opened = 1;
+       return 0;
+}
+
+static struct net_device_stats *mac_stats(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+
+       return &vif->netstats;
+}
+
+static void wilc_set_multicast_list(struct net_device *dev)
+{
+       struct netdev_hw_addr *ha;
+       struct wilc_vif *vif = netdev_priv(dev);
+       int i;
+       u8 *mc_list;
+       u8 *cur_mc;
+
+       if (dev->flags & IFF_PROMISC)
+               return;
+
+       if (dev->flags & IFF_ALLMULTI ||
+           dev->mc.count > WILC_MULTICAST_TABLE_SIZE) {
+               wilc_setup_multicast_filter(vif, 0, 0, NULL);
+               return;
+       }
+
+       if (dev->mc.count == 0) {
+               wilc_setup_multicast_filter(vif, 1, 0, NULL);
+               return;
+       }
+
+       mc_list = kmalloc_array(dev->mc.count, ETH_ALEN, GFP_ATOMIC);
+       if (!mc_list)
+               return;
+
+       cur_mc = mc_list;
+       i = 0;
+       netdev_for_each_mc_addr(ha, dev) {
+               memcpy(cur_mc, ha->addr, ETH_ALEN);
+               netdev_dbg(dev, "Entry[%d]: %pM\n", i, cur_mc);
+               i++;
+               cur_mc += ETH_ALEN;
+       }
+
+       if (wilc_setup_multicast_filter(vif, 1, dev->mc.count, mc_list))
+               kfree(mc_list);
+}
+
+static void wilc_tx_complete(void *priv, int status)
+{
+       struct tx_complete_data *pv_data = priv;
+
+       dev_kfree_skb(pv_data->skb);
+       kfree(pv_data);
+}
+
+netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+       struct wilc_vif *vif = netdev_priv(ndev);
+       struct wilc *wilc = vif->wilc;
+       struct tx_complete_data *tx_data = NULL;
+       int queue_count;
+
+       if (skb->dev != ndev) {
+               netdev_err(ndev, "Packet not destined to this device\n");
+               return 0;
+       }
+
+       tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
+       if (!tx_data) {
+               dev_kfree_skb(skb);
+               netif_wake_queue(ndev);
+               return 0;
+       }
+
+       tx_data->buff = skb->data;
+       tx_data->size = skb->len;
+       tx_data->skb  = skb;
+
+       vif->netstats.tx_packets++;
+       vif->netstats.tx_bytes += tx_data->size;
+       queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
+                                               tx_data->buff, tx_data->size,
+                                               wilc_tx_complete);
+
+       if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
+               int srcu_idx;
+               struct wilc_vif *vif;
+
+               srcu_idx = srcu_read_lock(&wilc->srcu);
+               list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+                       if (vif->mac_opened)
+                               netif_stop_queue(vif->ndev);
+               }
+               srcu_read_unlock(&wilc->srcu, srcu_idx);
+       }
+
+       return 0;
+}
+
+static int wilc_mac_close(struct net_device *ndev)
+{
+       struct wilc_vif *vif = netdev_priv(ndev);
+       struct wilc *wl = vif->wilc;
+
+       netdev_dbg(ndev, "Mac close\n");
+
+       if (wl->open_ifcs > 0)
+               wl->open_ifcs--;
+       else
+               return 0;
+
+       if (vif->ndev) {
+               netif_stop_queue(vif->ndev);
+
+               wilc_deinit_host_int(vif->ndev);
+       }
+
+       if (wl->open_ifcs == 0) {
+               netdev_dbg(ndev, "Deinitializing wilc1000\n");
+               wl->close = 1;
+               wilc_wlan_deinitialize(ndev);
+       }
+
+       vif->mac_opened = 0;
+
+       return 0;
+}
+
+void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size,
+                      u32 pkt_offset)
+{
+       unsigned int frame_len = 0;
+       int stats;
+       unsigned char *buff_to_send = NULL;
+       struct sk_buff *skb;
+       struct net_device *wilc_netdev;
+       struct wilc_vif *vif;
+
+       if (!wilc)
+               return;
+
+       wilc_netdev = get_if_handler(wilc, buff);
+       if (!wilc_netdev)
+               return;
+
+       buff += pkt_offset;
+       vif = netdev_priv(wilc_netdev);
+
+       if (size > 0) {
+               frame_len = size;
+               buff_to_send = buff;
+
+               skb = dev_alloc_skb(frame_len);
+               if (!skb)
+                       return;
+
+               skb->dev = wilc_netdev;
+
+               skb_put_data(skb, buff_to_send, frame_len);
+
+               skb->protocol = eth_type_trans(skb, wilc_netdev);
+               vif->netstats.rx_packets++;
+               vif->netstats.rx_bytes += frame_len;
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               stats = netif_rx(skb);
+               netdev_dbg(wilc_netdev, "netif_rx ret value is: %d\n", stats);
+       }
+}
+
+void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
+{
+       int srcu_idx;
+       struct wilc_vif *vif;
+
+       srcu_idx = srcu_read_lock(&wilc->srcu);
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+               u16 type = le16_to_cpup((__le16 *)buff);
+               u32 type_bit = BIT(type >> 4);
+
+               if (vif->priv.p2p_listen_state &&
+                   vif->mgmt_reg_stypes & type_bit)
+                       wilc_wfi_p2p_rx(vif, buff, size);
+
+               if (vif->monitor_flag)
+                       wilc_wfi_monitor_rx(wilc->monitor_dev, buff, size);
+       }
+       srcu_read_unlock(&wilc->srcu, srcu_idx);
+}
+
+static const struct net_device_ops wilc_netdev_ops = {
+       .ndo_init = mac_init_fn,
+       .ndo_open = wilc_mac_open,
+       .ndo_stop = wilc_mac_close,
+       .ndo_start_xmit = wilc_mac_xmit,
+       .ndo_get_stats = mac_stats,
+       .ndo_set_rx_mode  = wilc_set_multicast_list,
+};
+
+void wilc_netdev_cleanup(struct wilc *wilc)
+{
+       struct wilc_vif *vif;
+       int srcu_idx, ifc_cnt = 0;
+
+       if (!wilc)
+               return;
+
+       if (wilc->firmware) {
+               release_firmware(wilc->firmware);
+               wilc->firmware = NULL;
+       }
+
+       srcu_idx = srcu_read_lock(&wilc->srcu);
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+               if (vif->ndev)
+                       unregister_netdev(vif->ndev);
+       }
+       srcu_read_unlock(&wilc->srcu, srcu_idx);
+
+       wilc_wfi_deinit_mon_interface(wilc, false);
+       flush_workqueue(wilc->hif_workqueue);
+       destroy_workqueue(wilc->hif_workqueue);
+
+       while (ifc_cnt < WILC_NUM_CONCURRENT_IFC) {
+               mutex_lock(&wilc->vif_mutex);
+               if (wilc->vif_num <= 0) {
+                       mutex_unlock(&wilc->vif_mutex);
+                       break;
+               }
+               vif = wilc_get_wl_to_vif(wilc);
+               if (!IS_ERR(vif))
+                       list_del_rcu(&vif->list);
+
+               wilc->vif_num--;
+               mutex_unlock(&wilc->vif_mutex);
+               synchronize_srcu(&wilc->srcu);
+               ifc_cnt++;
+       }
+
+       wilc_wlan_cfg_deinit(wilc);
+       wlan_deinit_locks(wilc);
+       kfree(wilc->bus_data);
+       wiphy_unregister(wilc->wiphy);
+       wiphy_free(wilc->wiphy);
+}
+EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
+
+static u8 wilc_get_available_idx(struct wilc *wl)
+{
+       int idx = 0;
+       struct wilc_vif *vif;
+       int srcu_idx;
+
+       srcu_idx = srcu_read_lock(&wl->srcu);
+       list_for_each_entry_rcu(vif, &wl->vif_list, list) {
+               if (vif->idx == 0)
+                       idx = 1;
+               else
+                       idx = 0;
+       }
+       srcu_read_unlock(&wl->srcu, srcu_idx);
+       return idx;
+}
+
+struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
+                                     int vif_type, enum nl80211_iftype type,
+                                     bool rtnl_locked)
+{
+       struct net_device *ndev;
+       struct wilc_vif *vif;
+       int ret;
+
+       ndev = alloc_etherdev(sizeof(*vif));
+       if (!ndev)
+               return ERR_PTR(-ENOMEM);
+
+       vif = netdev_priv(ndev);
+       ndev->ieee80211_ptr = &vif->priv.wdev;
+       strcpy(ndev->name, name);
+       vif->wilc = wl;
+       vif->ndev = ndev;
+       ndev->ml_priv = vif;
+
+       ndev->netdev_ops = &wilc_netdev_ops;
+
+       SET_NETDEV_DEV(ndev, wiphy_dev(wl->wiphy));
+
+       vif->priv.wdev.wiphy = wl->wiphy;
+       vif->priv.wdev.netdev = ndev;
+       vif->priv.wdev.iftype = type;
+       vif->priv.dev = ndev;
+
+       if (rtnl_locked)
+               ret = register_netdevice(ndev);
+       else
+               ret = register_netdev(ndev);
+
+       if (ret) {
+               free_netdev(ndev);
+               return ERR_PTR(-EFAULT);
+       }
+
+       ndev->needs_free_netdev = true;
+       vif->iftype = vif_type;
+       vif->idx = wilc_get_available_idx(wl);
+       vif->mac_opened = 0;
+       mutex_lock(&wl->vif_mutex);
+       list_add_tail_rcu(&vif->list, &wl->vif_list);
+       wl->vif_num += 1;
+       mutex_unlock(&wl->vif_mutex);
+       synchronize_srcu(&wl->srcu);
+
+       return vif;
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.h b/drivers/net/wireless/microchip/wilc1000/netdev.h
new file mode 100644 (file)
index 0000000..d0a006b
--- /dev/null
@@ -0,0 +1,287 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#ifndef WILC_NETDEV_H
+#define WILC_NETDEV_H
+
+#include <linux/tcp.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+#include <net/ieee80211_radiotap.h>
+#include <linux/if_arp.h>
+#include <linux/gpio/consumer.h>
+
+#include "hif.h"
+#include "wlan.h"
+#include "wlan_cfg.h"
+
+#define FLOW_CONTROL_LOWER_THRESHOLD           128
+#define FLOW_CONTROL_UPPER_THRESHOLD           256
+
+#define PMKID_FOUND                            1
+#define NUM_STA_ASSOCIATED                     8
+
+#define TCP_ACK_FILTER_LINK_SPEED_THRESH       54
+#define DEFAULT_LINK_SPEED                     72
+
+struct wilc_wfi_stats {
+       unsigned long rx_packets;
+       unsigned long tx_packets;
+       unsigned long rx_bytes;
+       unsigned long tx_bytes;
+       u64 rx_time;
+       u64 tx_time;
+
+};
+
+struct wilc_wfi_key {
+       u8 *key;
+       u8 *seq;
+       int key_len;
+       int seq_len;
+       u32 cipher;
+};
+
+struct wilc_wfi_wep_key {
+       u8 *key;
+       u8 key_len;
+       u8 key_idx;
+};
+
+struct sta_info {
+       u8 sta_associated_bss[WILC_MAX_NUM_STA][ETH_ALEN];
+};
+
+/* Parameters needed for host interface for remaining on channel */
+struct wilc_wfi_p2p_listen_params {
+       struct ieee80211_channel *listen_ch;
+       u32 listen_duration;
+       u64 listen_cookie;
+};
+
+static const u32 wilc_cipher_suites[] = {
+       WLAN_CIPHER_SUITE_WEP40,
+       WLAN_CIPHER_SUITE_WEP104,
+       WLAN_CIPHER_SUITE_TKIP,
+       WLAN_CIPHER_SUITE_CCMP,
+       WLAN_CIPHER_SUITE_AES_CMAC
+};
+
+#define CHAN2G(_channel, _freq, _flags) {       \
+       .band             = NL80211_BAND_2GHZ, \
+       .center_freq      = (_freq),             \
+       .hw_value         = (_channel),          \
+       .flags            = (_flags),            \
+       .max_antenna_gain = 0,                   \
+       .max_power        = 30,                  \
+}
+
+static const struct ieee80211_channel wilc_2ghz_channels[] = {
+       CHAN2G(1,  2412, 0),
+       CHAN2G(2,  2417, 0),
+       CHAN2G(3,  2422, 0),
+       CHAN2G(4,  2427, 0),
+       CHAN2G(5,  2432, 0),
+       CHAN2G(6,  2437, 0),
+       CHAN2G(7,  2442, 0),
+       CHAN2G(8,  2447, 0),
+       CHAN2G(9,  2452, 0),
+       CHAN2G(10, 2457, 0),
+       CHAN2G(11, 2462, 0),
+       CHAN2G(12, 2467, 0),
+       CHAN2G(13, 2472, 0),
+       CHAN2G(14, 2484, 0)
+};
+
+#define RATETAB_ENT(_rate, _hw_value, _flags) {        \
+       .bitrate  = (_rate),                    \
+       .hw_value = (_hw_value),                \
+       .flags    = (_flags),                   \
+}
+
+static struct ieee80211_rate wilc_bitrates[] = {
+       RATETAB_ENT(10,  0,  0),
+       RATETAB_ENT(20,  1,  0),
+       RATETAB_ENT(55,  2,  0),
+       RATETAB_ENT(110, 3,  0),
+       RATETAB_ENT(60,  9,  0),
+       RATETAB_ENT(90,  6,  0),
+       RATETAB_ENT(120, 7,  0),
+       RATETAB_ENT(180, 8,  0),
+       RATETAB_ENT(240, 9,  0),
+       RATETAB_ENT(360, 10, 0),
+       RATETAB_ENT(480, 11, 0),
+       RATETAB_ENT(540, 12, 0)
+};
+
+struct wilc_priv {
+       struct wireless_dev wdev;
+       struct cfg80211_scan_request *scan_req;
+
+       struct wilc_wfi_p2p_listen_params remain_on_ch_params;
+       u64 tx_cookie;
+
+       bool cfg_scanning;
+
+       u8 associated_bss[ETH_ALEN];
+       struct sta_info assoc_stainfo;
+       struct sk_buff *skb;
+       struct net_device *dev;
+       struct host_if_drv *hif_drv;
+       struct wilc_pmkid_attr pmkid_list;
+       u8 wep_key[4][WLAN_KEY_LEN_WEP104];
+       u8 wep_key_len[4];
+
+       /* The real interface that the monitor is on */
+       struct net_device *real_ndev;
+       struct wilc_wfi_key *wilc_gtk[WILC_MAX_NUM_STA];
+       struct wilc_wfi_key *wilc_ptk[WILC_MAX_NUM_STA];
+       u8 wilc_groupkey;
+
+       /* mutexes */
+       struct mutex scan_req_lock;
+       bool p2p_listen_state;
+       int scanned_cnt;
+
+       u64 inc_roc_cookie;
+};
+
+#define MAX_TCP_SESSION                25
+#define MAX_PENDING_ACKS               256
+
+struct ack_session_info {
+       u32 seq_num;
+       u32 bigger_ack_num;
+       u16 src_port;
+       u16 dst_port;
+       u16 status;
+};
+
+struct pending_acks {
+       u32 ack_num;
+       u32 session_index;
+       struct txq_entry_t  *txqe;
+};
+
+struct tcp_ack_filter {
+       struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
+       struct pending_acks pending_acks[MAX_PENDING_ACKS];
+       u32 pending_base;
+       u32 tcp_session;
+       u32 pending_acks_idx;
+       bool enabled;
+};
+
+struct wilc_vif {
+       u8 idx;
+       u8 iftype;
+       int monitor_flag;
+       int mac_opened;
+       u32 mgmt_reg_stypes;
+       struct net_device_stats netstats;
+       struct wilc *wilc;
+       u8 bssid[ETH_ALEN];
+       struct host_if_drv *hif_drv;
+       struct net_device *ndev;
+       u8 mode;
+       struct timer_list during_ip_timer;
+       struct timer_list periodic_rssi;
+       struct rf_info periodic_stat;
+       struct tcp_ack_filter ack_filter;
+       bool connecting;
+       struct wilc_priv priv;
+       struct list_head list;
+       struct cfg80211_bss *bss;
+};
+
+struct wilc {
+       struct wiphy *wiphy;
+       const struct wilc_hif_func *hif_func;
+       int io_type;
+       s8 mac_status;
+       struct clk *rtc_clk;
+       bool initialized;
+       int dev_irq_num;
+       int close;
+       u8 vif_num;
+       struct list_head vif_list;
+
+       /* protect vif list */
+       struct mutex vif_mutex;
+       struct srcu_struct srcu;
+       u8 open_ifcs;
+
+       /* protect head of transmit queue */
+       struct mutex txq_add_to_head_cs;
+
+       /* protect txq_entry_t transmit queue */
+       spinlock_t txq_spinlock;
+
+       /* protect rxq_entry_t receiver queue */
+       struct mutex rxq_cs;
+
+       /* lock to protect hif access */
+       struct mutex hif_cs;
+
+       struct completion cfg_event;
+       struct completion sync_event;
+       struct completion txq_event;
+       struct completion txq_thread_started;
+
+       struct task_struct *txq_thread;
+
+       int quit;
+
+       /* lock to protect issue of wid command to firmware */
+       struct mutex cfg_cmd_lock;
+       struct wilc_cfg_frame cfg_frame;
+       u32 cfg_frame_offset;
+       u8 cfg_seq_no;
+
+       u8 *rx_buffer;
+       u32 rx_buffer_offset;
+       u8 *tx_buffer;
+
+       struct txq_entry_t txq_head;
+       int txq_entries;
+
+       struct rxq_entry_t rxq_head;
+
+       const struct firmware *firmware;
+
+       struct device *dev;
+       bool suspend_event;
+
+       int clients_count;
+       struct workqueue_struct *hif_workqueue;
+       enum chip_ps_states chip_ps_state;
+       struct wilc_cfg cfg;
+       void *bus_data;
+       struct net_device *monitor_dev;
+
+       /* deinit lock */
+       struct mutex deinit_lock;
+       u8 sta_ch;
+       u8 op_ch;
+       struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
+       struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
+       struct ieee80211_supported_band band;
+       u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
+};
+
+struct wilc_wfi_mon_priv {
+       struct net_device *real_ndev;
+};
+
+void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
+void wilc_mac_indicate(struct wilc *wilc);
+void wilc_netdev_cleanup(struct wilc *wilc);
+void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size);
+void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode);
+struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
+                                     int vif_type, enum nl80211_iftype type,
+                                     bool rtnl_locked);
+#endif
diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c
new file mode 100644 (file)
index 0000000..36eb589
--- /dev/null
@@ -0,0 +1,1023 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio.h>
+#include <linux/of_irq.h>
+
+#include "netdev.h"
+#include "cfg80211.h"
+
+#define SDIO_MODALIAS "wilc1000_sdio"
+
+#define SDIO_VENDOR_ID_WILC 0x0296
+#define SDIO_DEVICE_ID_WILC 0x5347
+
+static const struct sdio_device_id wilc_sdio_ids[] = {
+       { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
+       { },
+};
+
+#define WILC_SDIO_BLOCK_SIZE 512
+
+struct wilc_sdio {
+       bool irq_gpio;
+       u32 block_size;
+       int has_thrpt_enh3;
+};
+
+struct sdio_cmd52 {
+       u32 read_write:         1;
+       u32 function:           3;
+       u32 raw:                1;
+       u32 address:            17;
+       u32 data:               8;
+};
+
+struct sdio_cmd53 {
+       u32 read_write:         1;
+       u32 function:           3;
+       u32 block_mode:         1;
+       u32 increment:          1;
+       u32 address:            17;
+       u32 count:              9;
+       u8 *buffer;
+       u32 block_size;
+};
+
+static const struct wilc_hif_func wilc_hif_sdio;
+
+static void wilc_sdio_interrupt(struct sdio_func *func)
+{
+       sdio_release_host(func);
+       wilc_handle_isr(sdio_get_drvdata(func));
+       sdio_claim_host(func);
+}
+
+static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd)
+{
+       struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
+       int ret;
+       u8 data;
+
+       sdio_claim_host(func);
+
+       func->num = cmd->function;
+       if (cmd->read_write) {  /* write */
+               if (cmd->raw) {
+                       sdio_writeb(func, cmd->data, cmd->address, &ret);
+                       data = sdio_readb(func, cmd->address, &ret);
+                       cmd->data = data;
+               } else {
+                       sdio_writeb(func, cmd->data, cmd->address, &ret);
+               }
+       } else {        /* read */
+               data = sdio_readb(func, cmd->address, &ret);
+               cmd->data = data;
+       }
+
+       sdio_release_host(func);
+
+       if (ret)
+               dev_err(&func->dev, "%s..failed, err(%d)\n", __func__, ret);
+       return ret;
+}
+
+static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd)
+{
+       struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
+       int size, ret;
+
+       sdio_claim_host(func);
+
+       func->num = cmd->function;
+       func->cur_blksize = cmd->block_size;
+       if (cmd->block_mode)
+               size = cmd->count * cmd->block_size;
+       else
+               size = cmd->count;
+
+       if (cmd->read_write) {  /* write */
+               ret = sdio_memcpy_toio(func, cmd->address,
+                                      (void *)cmd->buffer, size);
+       } else {        /* read */
+               ret = sdio_memcpy_fromio(func, (void *)cmd->buffer,
+                                        cmd->address,  size);
+       }
+
+       sdio_release_host(func);
+
+       if (ret)
+               dev_err(&func->dev, "%s..failed, err(%d)\n", __func__,  ret);
+
+       return ret;
+}
+
+static int wilc_sdio_probe(struct sdio_func *func,
+                          const struct sdio_device_id *id)
+{
+       struct wilc *wilc;
+       int ret;
+       struct wilc_sdio *sdio_priv;
+
+       sdio_priv = kzalloc(sizeof(*sdio_priv), GFP_KERNEL);
+       if (!sdio_priv)
+               return -ENOMEM;
+
+       ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO,
+                                &wilc_hif_sdio);
+       if (ret) {
+               kfree(sdio_priv);
+               return ret;
+       }
+
+       if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) {
+               struct device_node *np = func->card->dev.of_node;
+               int irq_num = of_irq_get(np, 0);
+
+               if (irq_num > 0) {
+                       wilc->dev_irq_num = irq_num;
+                       sdio_priv->irq_gpio = true;
+               }
+       }
+
+       sdio_set_drvdata(func, wilc);
+       wilc->bus_data = sdio_priv;
+       wilc->dev = &func->dev;
+
+       wilc->rtc_clk = devm_clk_get(&func->card->dev, "rtc");
+       if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+       else if (!IS_ERR(wilc->rtc_clk))
+               clk_prepare_enable(wilc->rtc_clk);
+
+       dev_info(&func->dev, "Driver Initializing success\n");
+       return 0;
+}
+
+static void wilc_sdio_remove(struct sdio_func *func)
+{
+       struct wilc *wilc = sdio_get_drvdata(func);
+
+       if (!IS_ERR(wilc->rtc_clk))
+               clk_disable_unprepare(wilc->rtc_clk);
+
+       wilc_netdev_cleanup(wilc);
+}
+
+static int wilc_sdio_reset(struct wilc *wilc)
+{
+       struct sdio_cmd52 cmd;
+       int ret;
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+
+       cmd.read_write = 1;
+       cmd.function = 0;
+       cmd.raw = 0;
+       cmd.address = SDIO_CCCR_ABORT;
+       cmd.data = WILC_SDIO_CCCR_ABORT_RESET;
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Fail cmd 52, reset cmd ...\n");
+               return ret;
+       }
+       return 0;
+}
+
+static int wilc_sdio_suspend(struct device *dev)
+{
+       struct sdio_func *func = dev_to_sdio_func(dev);
+       struct wilc *wilc = sdio_get_drvdata(func);
+       int ret;
+
+       dev_info(dev, "sdio suspend\n");
+       chip_wakeup(wilc);
+
+       if (!IS_ERR(wilc->rtc_clk))
+               clk_disable_unprepare(wilc->rtc_clk);
+
+       if (wilc->suspend_event) {
+               host_sleep_notify(wilc);
+               chip_allow_sleep(wilc);
+       }
+
+       ret = wilc_sdio_reset(wilc);
+       if (ret) {
+               dev_err(&func->dev, "Fail reset sdio\n");
+               return ret;
+       }
+       sdio_claim_host(func);
+
+       return 0;
+}
+
+static int wilc_sdio_enable_interrupt(struct wilc *dev)
+{
+       struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
+       int ret = 0;
+
+       sdio_claim_host(func);
+       ret = sdio_claim_irq(func, wilc_sdio_interrupt);
+       sdio_release_host(func);
+
+       if (ret < 0) {
+               dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret);
+               ret = -EIO;
+       }
+       return ret;
+}
+
+static void wilc_sdio_disable_interrupt(struct wilc *dev)
+{
+       struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
+       int ret;
+
+       sdio_claim_host(func);
+       ret = sdio_release_irq(func);
+       if (ret < 0)
+               dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret);
+       sdio_release_host(func);
+}
+
+/********************************************
+ *
+ *      Function 0
+ *
+ ********************************************/
+
+static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct sdio_cmd52 cmd;
+       int ret;
+
+       /**
+        *      Review: BIG ENDIAN
+        **/
+       cmd.read_write = 1;
+       cmd.function = 0;
+       cmd.raw = 0;
+       cmd.address = WILC_SDIO_FBR_CSA_REG;
+       cmd.data = (u8)adr;
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
+                       cmd.address);
+               return ret;
+       }
+
+       cmd.address = WILC_SDIO_FBR_CSA_REG + 1;
+       cmd.data = (u8)(adr >> 8);
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
+                       cmd.address);
+               return ret;
+       }
+
+       cmd.address = WILC_SDIO_FBR_CSA_REG + 2;
+       cmd.data = (u8)(adr >> 16);
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
+                       cmd.address);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int wilc_sdio_set_block_size(struct wilc *wilc, u8 func_num,
+                                   u32 block_size)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct sdio_cmd52 cmd;
+       int ret;
+
+       cmd.read_write = 1;
+       cmd.function = 0;
+       cmd.raw = 0;
+       cmd.address = SDIO_FBR_BASE(func_num) + SDIO_CCCR_BLKSIZE;
+       cmd.data = (u8)block_size;
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
+                       cmd.address);
+               return ret;
+       }
+
+       cmd.address = SDIO_FBR_BASE(func_num) + SDIO_CCCR_BLKSIZE +  1;
+       cmd.data = (u8)(block_size >> 8);
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
+                       cmd.address);
+               return ret;
+       }
+
+       return 0;
+}
+
+/********************************************
+ *
+ *      Sdio interfaces
+ *
+ ********************************************/
+static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       int ret;
+
+       cpu_to_le32s(&data);
+
+       if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */
+               struct sdio_cmd52 cmd;
+
+               cmd.read_write = 1;
+               cmd.function = 0;
+               cmd.raw = 0;
+               cmd.address = addr;
+               cmd.data = data;
+               ret = wilc_sdio_cmd52(wilc, &cmd);
+               if (ret)
+                       dev_err(&func->dev,
+                               "Failed cmd 52, read reg (%08x) ...\n", addr);
+       } else {
+               struct sdio_cmd53 cmd;
+
+               /**
+                *      set the AHB address
+                **/
+               ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+               if (ret)
+                       return ret;
+
+               cmd.read_write = 1;
+               cmd.function = 0;
+               cmd.address = WILC_SDIO_FBR_DATA_REG;
+               cmd.block_mode = 0;
+               cmd.increment = 1;
+               cmd.count = 4;
+               cmd.buffer = (u8 *)&data;
+               cmd.block_size = sdio_priv->block_size;
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret)
+                       dev_err(&func->dev,
+                               "Failed cmd53, write reg (%08x)...\n", addr);
+       }
+
+       return ret;
+}
+
+static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       u32 block_size = sdio_priv->block_size;
+       struct sdio_cmd53 cmd;
+       int nblk, nleft, ret;
+
+       cmd.read_write = 1;
+       if (addr > 0) {
+               /**
+                *      func 0 access
+                **/
+               cmd.function = 0;
+               cmd.address = WILC_SDIO_FBR_DATA_REG;
+       } else {
+               /**
+                *      func 1 access
+                **/
+               cmd.function = 1;
+               cmd.address = WILC_SDIO_F1_DATA_REG;
+       }
+
+       size = ALIGN(size, 4);
+       nblk = size / block_size;
+       nleft = size % block_size;
+
+       if (nblk > 0) {
+               cmd.block_mode = 1;
+               cmd.increment = 1;
+               cmd.count = nblk;
+               cmd.buffer = buf;
+               cmd.block_size = block_size;
+               if (addr > 0) {
+                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+                       if (ret)
+                               return ret;
+               }
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53 [%x], block send...\n", addr);
+                       return ret;
+               }
+               if (addr > 0)
+                       addr += nblk * block_size;
+               buf += nblk * block_size;
+       }
+
+       if (nleft > 0) {
+               cmd.block_mode = 0;
+               cmd.increment = 1;
+               cmd.count = nleft;
+               cmd.buffer = buf;
+
+               cmd.block_size = block_size;
+
+               if (addr > 0) {
+                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+                       if (ret)
+                               return ret;
+               }
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53 [%x], bytes send...\n", addr);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       int ret;
+
+       if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */
+               struct sdio_cmd52 cmd;
+
+               cmd.read_write = 0;
+               cmd.function = 0;
+               cmd.raw = 0;
+               cmd.address = addr;
+               ret = wilc_sdio_cmd52(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd 52, read reg (%08x) ...\n", addr);
+                       return ret;
+               }
+               *data = cmd.data;
+       } else {
+               struct sdio_cmd53 cmd;
+
+               ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+               if (ret)
+                       return ret;
+
+               cmd.read_write = 0;
+               cmd.function = 0;
+               cmd.address = WILC_SDIO_FBR_DATA_REG;
+               cmd.block_mode = 0;
+               cmd.increment = 1;
+               cmd.count = 4;
+               cmd.buffer = (u8 *)data;
+
+               cmd.block_size = sdio_priv->block_size;
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53, read reg (%08x)...\n", addr);
+                       return ret;
+               }
+       }
+
+       le32_to_cpus(data);
+       return 0;
+}
+
+static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       u32 block_size = sdio_priv->block_size;
+       struct sdio_cmd53 cmd;
+       int nblk, nleft, ret;
+
+       cmd.read_write = 0;
+       if (addr > 0) {
+               /**
+                *      func 0 access
+                **/
+               cmd.function = 0;
+               cmd.address = WILC_SDIO_FBR_DATA_REG;
+       } else {
+               /**
+                *      func 1 access
+                **/
+               cmd.function = 1;
+               cmd.address = WILC_SDIO_F1_DATA_REG;
+       }
+
+       size = ALIGN(size, 4);
+       nblk = size / block_size;
+       nleft = size % block_size;
+
+       if (nblk > 0) {
+               cmd.block_mode = 1;
+               cmd.increment = 1;
+               cmd.count = nblk;
+               cmd.buffer = buf;
+               cmd.block_size = block_size;
+               if (addr > 0) {
+                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+                       if (ret)
+                               return ret;
+               }
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53 [%x], block read...\n", addr);
+                       return ret;
+               }
+               if (addr > 0)
+                       addr += nblk * block_size;
+               buf += nblk * block_size;
+       }       /* if (nblk > 0) */
+
+       if (nleft > 0) {
+               cmd.block_mode = 0;
+               cmd.increment = 1;
+               cmd.count = nleft;
+               cmd.buffer = buf;
+
+               cmd.block_size = block_size;
+
+               if (addr > 0) {
+                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+                       if (ret)
+                               return ret;
+               }
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53 [%x], bytes read...\n", addr);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/********************************************
+ *
+ *      Bus interfaces
+ *
+ ********************************************/
+
+static int wilc_sdio_deinit(struct wilc *wilc)
+{
+       return 0;
+}
+
+static int wilc_sdio_init(struct wilc *wilc, bool resume)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       struct sdio_cmd52 cmd;
+       int loop, ret;
+       u32 chipid;
+
+       /**
+        *      function 0 csa enable
+        **/
+       cmd.read_write = 1;
+       cmd.function = 0;
+       cmd.raw = 1;
+       cmd.address = SDIO_FBR_BASE(func->num);
+       cmd.data = SDIO_FBR_ENABLE_CSA;
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Fail cmd 52, enable csa...\n");
+               return ret;
+       }
+
+       /**
+        *      function 0 block size
+        **/
+       ret = wilc_sdio_set_block_size(wilc, 0, WILC_SDIO_BLOCK_SIZE);
+       if (ret) {
+               dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");
+               return ret;
+       }
+       sdio_priv->block_size = WILC_SDIO_BLOCK_SIZE;
+
+       /**
+        *      enable func1 IO
+        **/
+       cmd.read_write = 1;
+       cmd.function = 0;
+       cmd.raw = 1;
+       cmd.address = SDIO_CCCR_IOEx;
+       cmd.data = WILC_SDIO_CCCR_IO_EN_FUNC1;
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev,
+                       "Fail cmd 52, set IOE register...\n");
+               return ret;
+       }
+
+       /**
+        *      make sure func 1 is up
+        **/
+       cmd.read_write = 0;
+       cmd.function = 0;
+       cmd.raw = 0;
+       cmd.address = SDIO_CCCR_IORx;
+       loop = 3;
+       do {
+               cmd.data = 0;
+               ret = wilc_sdio_cmd52(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Fail cmd 52, get IOR register...\n");
+                       return ret;
+               }
+               if (cmd.data == WILC_SDIO_CCCR_IO_EN_FUNC1)
+                       break;
+       } while (loop--);
+
+       if (loop <= 0) {
+               dev_err(&func->dev, "Fail func 1 is not ready...\n");
+               return -EINVAL;
+       }
+
+       /**
+        *      func 1 is ready, set func 1 block size
+        **/
+       ret = wilc_sdio_set_block_size(wilc, 1, WILC_SDIO_BLOCK_SIZE);
+       if (ret) {
+               dev_err(&func->dev, "Fail set func 1 block size...\n");
+               return ret;
+       }
+
+       /**
+        *      func 1 interrupt enable
+        **/
+       cmd.read_write = 1;
+       cmd.function = 0;
+       cmd.raw = 1;
+       cmd.address = SDIO_CCCR_IENx;
+       cmd.data = WILC_SDIO_CCCR_IEN_MASTER | WILC_SDIO_CCCR_IEN_FUNC1;
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Fail cmd 52, set IEN register...\n");
+               return ret;
+       }
+
+       /**
+        *      make sure can read back chip id correctly
+        **/
+       if (!resume) {
+               int rev;
+
+               ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid);
+               if (ret) {
+                       dev_err(&func->dev, "Fail cmd read chip id...\n");
+                       return ret;
+               }
+               dev_err(&func->dev, "chipid (%08x)\n", chipid);
+               rev = FIELD_GET(WILC_CHIP_REV_FIELD, chipid);
+               if (rev > FIELD_GET(WILC_CHIP_REV_FIELD, WILC_1000_BASE_ID_2A))
+                       sdio_priv->has_thrpt_enh3 = 1;
+               else
+                       sdio_priv->has_thrpt_enh3 = 0;
+               dev_info(&func->dev, "has_thrpt_enh3 = %d...\n",
+                        sdio_priv->has_thrpt_enh3);
+       }
+
+       return 0;
+}
+
+static int wilc_sdio_read_size(struct wilc *wilc, u32 *size)
+{
+       u32 tmp;
+       struct sdio_cmd52 cmd;
+
+       /**
+        *      Read DMA count in words
+        **/
+       cmd.read_write = 0;
+       cmd.function = 0;
+       cmd.raw = 0;
+       cmd.address = WILC_SDIO_INTERRUPT_DATA_SZ_REG;
+       cmd.data = 0;
+       wilc_sdio_cmd52(wilc, &cmd);
+       tmp = cmd.data;
+
+       cmd.address = WILC_SDIO_INTERRUPT_DATA_SZ_REG + 1;
+       cmd.data = 0;
+       wilc_sdio_cmd52(wilc, &cmd);
+       tmp |= (cmd.data << 8);
+
+       *size = tmp;
+       return 0;
+}
+
+static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       u32 tmp;
+       u8 irq_flags;
+       struct sdio_cmd52 cmd;
+
+       wilc_sdio_read_size(wilc, &tmp);
+
+       /**
+        *      Read IRQ flags
+        **/
+       if (!sdio_priv->irq_gpio) {
+               cmd.function = 1;
+               cmd.address = WILC_SDIO_EXT_IRQ_FLAG_REG;
+       } else {
+               cmd.function = 0;
+               cmd.address = WILC_SDIO_IRQ_FLAG_REG;
+       }
+       cmd.raw = 0;
+       cmd.read_write = 0;
+       cmd.data = 0;
+       wilc_sdio_cmd52(wilc, &cmd);
+       irq_flags = cmd.data;
+       tmp |= FIELD_PREP(IRG_FLAGS_MASK, cmd.data);
+
+       if (FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags))
+               dev_err(&func->dev, "Unexpected interrupt (1) int=%lx\n",
+                       FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags));
+
+       *int_status = tmp;
+
+       return 0;
+}
+
+static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       int ret;
+       int vmm_ctl;
+
+       if (sdio_priv->has_thrpt_enh3) {
+               u32 reg = 0;
+
+               if (sdio_priv->irq_gpio)
+                       reg = val & (BIT(MAX_NUM_INT) - 1);
+
+               /* select VMM table 0 */
+               if (val & SEL_VMM_TBL0)
+                       reg |= BIT(5);
+               /* select VMM table 1 */
+               if (val & SEL_VMM_TBL1)
+                       reg |= BIT(6);
+               /* enable VMM */
+               if (val & EN_VMM)
+                       reg |= BIT(7);
+               if (reg) {
+                       struct sdio_cmd52 cmd;
+
+                       cmd.read_write = 1;
+                       cmd.function = 0;
+                       cmd.raw = 0;
+                       cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;
+                       cmd.data = reg;
+
+                       ret = wilc_sdio_cmd52(wilc, &cmd);
+                       if (ret) {
+                               dev_err(&func->dev,
+                                       "Failed cmd52, set (%02x) data (%d) ...\n",
+                                       cmd.address, __LINE__);
+                               return ret;
+                       }
+               }
+               return 0;
+       }
+       if (sdio_priv->irq_gpio) {
+               /* has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
+               /*
+                * Cannot clear multiple interrupts.
+                * Must clear each interrupt individually.
+                */
+               u32 flags;
+               int i;
+
+               flags = val & (BIT(MAX_NUM_INT) - 1);
+               for (i = 0; i < NUM_INT_EXT && flags; i++) {
+                       if (flags & BIT(i)) {
+                               struct sdio_cmd52 cmd;
+
+                               cmd.read_write = 1;
+                               cmd.function = 0;
+                               cmd.raw = 0;
+                               cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;
+                               cmd.data = BIT(i);
+
+                               ret = wilc_sdio_cmd52(wilc, &cmd);
+                               if (ret) {
+                                       dev_err(&func->dev,
+                                               "Failed cmd52, set (%02x) data (%d) ...\n",
+                                               cmd.address, __LINE__);
+                                       return ret;
+                               }
+                               flags &= ~BIT(i);
+                       }
+               }
+
+               for (i = NUM_INT_EXT; i < MAX_NUM_INT && flags; i++) {
+                       if (flags & BIT(i)) {
+                               dev_err(&func->dev,
+                                       "Unexpected interrupt cleared %d...\n",
+                                       i);
+                               flags &= ~BIT(i);
+                       }
+               }
+       }
+
+       vmm_ctl = 0;
+       /* select VMM table 0 */
+       if (val & SEL_VMM_TBL0)
+               vmm_ctl |= BIT(0);
+       /* select VMM table 1 */
+       if (val & SEL_VMM_TBL1)
+               vmm_ctl |= BIT(1);
+       /* enable VMM */
+       if (val & EN_VMM)
+               vmm_ctl |= BIT(2);
+
+       if (vmm_ctl) {
+               struct sdio_cmd52 cmd;
+
+               cmd.read_write = 1;
+               cmd.function = 0;
+               cmd.raw = 0;
+               cmd.address = WILC_SDIO_VMM_TBL_CTRL_REG;
+               cmd.data = vmm_ctl;
+               ret = wilc_sdio_cmd52(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd52, set (%02x) data (%d) ...\n",
+                               cmd.address, __LINE__);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)
+{
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       u32 reg;
+
+       if (nint > MAX_NUM_INT) {
+               dev_err(&func->dev, "Too many interrupts (%d)...\n", nint);
+               return -EINVAL;
+       }
+
+       /**
+        *      Disable power sequencer
+        **/
+       if (wilc_sdio_read_reg(wilc, WILC_MISC, &reg)) {
+               dev_err(&func->dev, "Failed read misc reg...\n");
+               return -EINVAL;
+       }
+
+       reg &= ~BIT(8);
+       if (wilc_sdio_write_reg(wilc, WILC_MISC, reg)) {
+               dev_err(&func->dev, "Failed write misc reg...\n");
+               return -EINVAL;
+       }
+
+       if (sdio_priv->irq_gpio) {
+               u32 reg;
+               int ret, i;
+
+               /**
+                *      interrupt pin mux select
+                **/
+               ret = wilc_sdio_read_reg(wilc, WILC_PIN_MUX_0, &reg);
+               if (ret) {
+                       dev_err(&func->dev, "Failed read reg (%08x)...\n",
+                               WILC_PIN_MUX_0);
+                       return ret;
+               }
+               reg |= BIT(8);
+               ret = wilc_sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);
+               if (ret) {
+                       dev_err(&func->dev, "Failed write reg (%08x)...\n",
+                               WILC_PIN_MUX_0);
+                       return ret;
+               }
+
+               /**
+                *      interrupt enable
+                **/
+               ret = wilc_sdio_read_reg(wilc, WILC_INTR_ENABLE, &reg);
+               if (ret) {
+                       dev_err(&func->dev, "Failed read reg (%08x)...\n",
+                               WILC_INTR_ENABLE);
+                       return ret;
+               }
+
+               for (i = 0; (i < 5) && (nint > 0); i++, nint--)
+                       reg |= BIT((27 + i));
+               ret = wilc_sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);
+               if (ret) {
+                       dev_err(&func->dev, "Failed write reg (%08x)...\n",
+                               WILC_INTR_ENABLE);
+                       return ret;
+               }
+               if (nint) {
+                       ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
+                       if (ret) {
+                               dev_err(&func->dev,
+                                       "Failed read reg (%08x)...\n",
+                                       WILC_INTR2_ENABLE);
+                               return ret;
+                       }
+
+                       for (i = 0; (i < 3) && (nint > 0); i++, nint--)
+                               reg |= BIT(i);
+
+                       ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
+                       if (ret) {
+                               dev_err(&func->dev,
+                                       "Failed write reg (%08x)...\n",
+                                       WILC_INTR2_ENABLE);
+                               return ret;
+                       }
+               }
+       }
+       return 0;
+}
+
+/* Global sdio HIF function table */
+static const struct wilc_hif_func wilc_hif_sdio = {
+       .hif_init = wilc_sdio_init,
+       .hif_deinit = wilc_sdio_deinit,
+       .hif_read_reg = wilc_sdio_read_reg,
+       .hif_write_reg = wilc_sdio_write_reg,
+       .hif_block_rx = wilc_sdio_read,
+       .hif_block_tx = wilc_sdio_write,
+       .hif_read_int = wilc_sdio_read_int,
+       .hif_clear_int_ext = wilc_sdio_clear_int_ext,
+       .hif_read_size = wilc_sdio_read_size,
+       .hif_block_tx_ext = wilc_sdio_write,
+       .hif_block_rx_ext = wilc_sdio_read,
+       .hif_sync_ext = wilc_sdio_sync_ext,
+       .enable_interrupt = wilc_sdio_enable_interrupt,
+       .disable_interrupt = wilc_sdio_disable_interrupt,
+};
+
+static int wilc_sdio_resume(struct device *dev)
+{
+       struct sdio_func *func = dev_to_sdio_func(dev);
+       struct wilc *wilc = sdio_get_drvdata(func);
+
+       dev_info(dev, "sdio resume\n");
+       sdio_release_host(func);
+       chip_wakeup(wilc);
+       wilc_sdio_init(wilc, true);
+
+       if (wilc->suspend_event)
+               host_wakeup_notify(wilc);
+
+       chip_allow_sleep(wilc);
+
+       return 0;
+}
+
+static const struct of_device_id wilc_of_match[] = {
+       { .compatible = "microchip,wilc1000", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, wilc_of_match);
+
+static const struct dev_pm_ops wilc_sdio_pm_ops = {
+       .suspend = wilc_sdio_suspend,
+       .resume = wilc_sdio_resume,
+};
+
+static struct sdio_driver wilc_sdio_driver = {
+       .name           = SDIO_MODALIAS,
+       .id_table       = wilc_sdio_ids,
+       .probe          = wilc_sdio_probe,
+       .remove         = wilc_sdio_remove,
+       .drv = {
+               .pm = &wilc_sdio_pm_ops,
+               .of_match_table = wilc_of_match,
+       }
+};
+module_driver(wilc_sdio_driver,
+             sdio_register_driver,
+             sdio_unregister_driver);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c
new file mode 100644 (file)
index 0000000..3f19e3f
--- /dev/null
@@ -0,0 +1,945 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/crc7.h>
+
+#include "netdev.h"
+#include "cfg80211.h"
+
+struct wilc_spi {
+       int crc_off;
+};
+
+static const struct wilc_hif_func wilc_hif_spi;
+
+/********************************************
+ *
+ *      Spi protocol Function
+ *
+ ********************************************/
+
+#define CMD_DMA_WRITE                          0xc1
+#define CMD_DMA_READ                           0xc2
+#define CMD_INTERNAL_WRITE                     0xc3
+#define CMD_INTERNAL_READ                      0xc4
+#define CMD_TERMINATE                          0xc5
+#define CMD_REPEAT                             0xc6
+#define CMD_DMA_EXT_WRITE                      0xc7
+#define CMD_DMA_EXT_READ                       0xc8
+#define CMD_SINGLE_WRITE                       0xc9
+#define CMD_SINGLE_READ                                0xca
+#define CMD_RESET                              0xcf
+
+#define DATA_PKT_SZ_256                                256
+#define DATA_PKT_SZ_512                                512
+#define DATA_PKT_SZ_1K                         1024
+#define DATA_PKT_SZ_4K                         (4 * 1024)
+#define DATA_PKT_SZ_8K                         (8 * 1024)
+#define DATA_PKT_SZ                            DATA_PKT_SZ_8K
+
+#define USE_SPI_DMA                            0
+
+#define WILC_SPI_COMMAND_STAT_SUCCESS          0
+#define WILC_GET_RESP_HDR_START(h)             (((h) >> 4) & 0xf)
+
+struct wilc_spi_cmd {
+       u8 cmd_type;
+       union {
+               struct {
+                       u8 addr[3];
+                       u8 crc[];
+               } __packed simple_cmd;
+               struct {
+                       u8 addr[3];
+                       u8 size[2];
+                       u8 crc[];
+               } __packed dma_cmd;
+               struct {
+                       u8 addr[3];
+                       u8 size[3];
+                       u8 crc[];
+               } __packed dma_cmd_ext;
+               struct {
+                       u8 addr[2];
+                       __be32 data;
+                       u8 crc[];
+               } __packed internal_w_cmd;
+               struct {
+                       u8 addr[3];
+                       __be32 data;
+                       u8 crc[];
+               } __packed w_cmd;
+       } u;
+} __packed;
+
+struct wilc_spi_read_rsp_data {
+       u8 rsp_cmd_type;
+       u8 status;
+       u8 resp_header;
+       u8 resp_data[4];
+       u8 crc[];
+} __packed;
+
+struct wilc_spi_rsp_data {
+       u8 rsp_cmd_type;
+       u8 status;
+} __packed;
+
+static int wilc_bus_probe(struct spi_device *spi)
+{
+       int ret;
+       struct wilc *wilc;
+       struct wilc_spi *spi_priv;
+
+       spi_priv = kzalloc(sizeof(*spi_priv), GFP_KERNEL);
+       if (!spi_priv)
+               return -ENOMEM;
+
+       ret = wilc_cfg80211_init(&wilc, &spi->dev, WILC_HIF_SPI, &wilc_hif_spi);
+       if (ret) {
+               kfree(spi_priv);
+               return ret;
+       }
+
+       spi_set_drvdata(spi, wilc);
+       wilc->dev = &spi->dev;
+       wilc->bus_data = spi_priv;
+       wilc->dev_irq_num = spi->irq;
+
+       wilc->rtc_clk = devm_clk_get(&spi->dev, "rtc_clk");
+       if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+       else if (!IS_ERR(wilc->rtc_clk))
+               clk_prepare_enable(wilc->rtc_clk);
+
+       return 0;
+}
+
+static int wilc_bus_remove(struct spi_device *spi)
+{
+       struct wilc *wilc = spi_get_drvdata(spi);
+
+       if (!IS_ERR(wilc->rtc_clk))
+               clk_disable_unprepare(wilc->rtc_clk);
+
+       wilc_netdev_cleanup(wilc);
+       return 0;
+}
+
+static const struct of_device_id wilc_of_match[] = {
+       { .compatible = "microchip,wilc1000", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, wilc_of_match);
+
+static struct spi_driver wilc_spi_driver = {
+       .driver = {
+               .name = MODALIAS,
+               .of_match_table = wilc_of_match,
+       },
+       .probe =  wilc_bus_probe,
+       .remove = wilc_bus_remove,
+};
+module_spi_driver(wilc_spi_driver);
+MODULE_LICENSE("GPL");
+
+static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int ret;
+       struct spi_message msg;
+
+       if (len > 0 && b) {
+               struct spi_transfer tr = {
+                       .tx_buf = b,
+                       .len = len,
+                       .delay = {
+                               .value = 0,
+                               .unit = SPI_DELAY_UNIT_USECS
+                       },
+               };
+               char *r_buffer = kzalloc(len, GFP_KERNEL);
+
+               if (!r_buffer)
+                       return -ENOMEM;
+
+               tr.rx_buf = r_buffer;
+               dev_dbg(&spi->dev, "Request writing %d bytes\n", len);
+
+               memset(&msg, 0, sizeof(msg));
+               spi_message_init(&msg);
+               msg.spi = spi;
+               msg.is_dma_mapped = USE_SPI_DMA;
+               spi_message_add_tail(&tr, &msg);
+
+               ret = spi_sync(spi, &msg);
+               if (ret < 0)
+                       dev_err(&spi->dev, "SPI transaction failed\n");
+
+               kfree(r_buffer);
+       } else {
+               dev_err(&spi->dev,
+                       "can't write data with the following length: %d\n",
+                       len);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int ret;
+
+       if (rlen > 0) {
+               struct spi_message msg;
+               struct spi_transfer tr = {
+                       .rx_buf = rb,
+                       .len = rlen,
+                       .delay = {
+                               .value = 0,
+                               .unit = SPI_DELAY_UNIT_USECS
+                       },
+
+               };
+               char *t_buffer = kzalloc(rlen, GFP_KERNEL);
+
+               if (!t_buffer)
+                       return -ENOMEM;
+
+               tr.tx_buf = t_buffer;
+
+               memset(&msg, 0, sizeof(msg));
+               spi_message_init(&msg);
+               msg.spi = spi;
+               msg.is_dma_mapped = USE_SPI_DMA;
+               spi_message_add_tail(&tr, &msg);
+
+               ret = spi_sync(spi, &msg);
+               if (ret < 0)
+                       dev_err(&spi->dev, "SPI transaction failed\n");
+               kfree(t_buffer);
+       } else {
+               dev_err(&spi->dev,
+                       "can't read data with the following length: %u\n",
+                       rlen);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int ret;
+
+       if (rlen > 0) {
+               struct spi_message msg;
+               struct spi_transfer tr = {
+                       .rx_buf = rb,
+                       .tx_buf = wb,
+                       .len = rlen,
+                       .bits_per_word = 8,
+                       .delay = {
+                               .value = 0,
+                               .unit = SPI_DELAY_UNIT_USECS
+                       },
+
+               };
+
+               memset(&msg, 0, sizeof(msg));
+               spi_message_init(&msg);
+               msg.spi = spi;
+               msg.is_dma_mapped = USE_SPI_DMA;
+
+               spi_message_add_tail(&tr, &msg);
+               ret = spi_sync(spi, &msg);
+               if (ret < 0)
+                       dev_err(&spi->dev, "SPI transaction failed\n");
+       } else {
+               dev_err(&spi->dev,
+                       "can't read data with the following length: %u\n",
+                       rlen);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
+       int ix, nbytes;
+       int result = 0;
+       u8 cmd, order, crc[2] = {0};
+
+       /*
+        * Data
+        */
+       ix = 0;
+       do {
+               if (sz <= DATA_PKT_SZ) {
+                       nbytes = sz;
+                       order = 0x3;
+               } else {
+                       nbytes = DATA_PKT_SZ;
+                       if (ix == 0)
+                               order = 0x1;
+                       else
+                               order = 0x02;
+               }
+
+               /*
+                * Write command
+                */
+               cmd = 0xf0;
+               cmd |= order;
+
+               if (wilc_spi_tx(wilc, &cmd, 1)) {
+                       dev_err(&spi->dev,
+                               "Failed data block cmd write, bus error...\n");
+                       result = -EINVAL;
+                       break;
+               }
+
+               /*
+                * Write data
+                */
+               if (wilc_spi_tx(wilc, &b[ix], nbytes)) {
+                       dev_err(&spi->dev,
+                               "Failed data block write, bus error...\n");
+                       result = -EINVAL;
+                       break;
+               }
+
+               /*
+                * Write Crc
+                */
+               if (!spi_priv->crc_off) {
+                       if (wilc_spi_tx(wilc, crc, 2)) {
+                               dev_err(&spi->dev, "Failed data block crc write, bus error...\n");
+                               result = -EINVAL;
+                               break;
+                       }
+               }
+
+               /*
+                * No need to wait for response
+                */
+               ix += nbytes;
+               sz -= nbytes;
+       } while (sz);
+
+       return result;
+}
+
+/********************************************
+ *
+ *      Spi Internal Read/Write Function
+ *
+ ********************************************/
+static u8 wilc_get_crc7(u8 *buffer, u32 len)
+{
+       return crc7_be(0xfe, buffer, len);
+}
+
+static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
+                               u8 clockless)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
+       u8 wb[32], rb[32];
+       int cmd_len, resp_len;
+       u8 crc[2];
+       struct wilc_spi_cmd *c;
+       struct wilc_spi_read_rsp_data *r;
+
+       memset(wb, 0x0, sizeof(wb));
+       memset(rb, 0x0, sizeof(rb));
+       c = (struct wilc_spi_cmd *)wb;
+       c->cmd_type = cmd;
+       if (cmd == CMD_SINGLE_READ) {
+               c->u.simple_cmd.addr[0] = adr >> 16;
+               c->u.simple_cmd.addr[1] = adr >> 8;
+               c->u.simple_cmd.addr[2] = adr;
+       } else if (cmd == CMD_INTERNAL_READ) {
+               c->u.simple_cmd.addr[0] = adr >> 8;
+               if (clockless == 1)
+                       c->u.simple_cmd.addr[0] |= BIT(7);
+               c->u.simple_cmd.addr[1] = adr;
+               c->u.simple_cmd.addr[2] = 0x0;
+       } else {
+               dev_err(&spi->dev, "cmd [%x] not supported\n", cmd);
+               return -EINVAL;
+       }
+
+       cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);
+       resp_len = sizeof(*r);
+       if (!spi_priv->crc_off) {
+               c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
+               cmd_len += 1;
+               resp_len += 2;
+       }
+
+       if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
+               dev_err(&spi->dev,
+                       "spi buffer size too small (%d) (%d) (%zu)\n",
+                       cmd_len, resp_len, ARRAY_SIZE(wb));
+               return -EINVAL;
+       }
+
+       if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
+               dev_err(&spi->dev, "Failed cmd write, bus error...\n");
+               return -EINVAL;
+       }
+
+       r = (struct wilc_spi_read_rsp_data *)&rb[cmd_len];
+       if (r->rsp_cmd_type != cmd) {
+               dev_err(&spi->dev,
+                       "Failed cmd response, cmd (%02x), resp (%02x)\n",
+                       cmd, r->rsp_cmd_type);
+               return -EINVAL;
+       }
+
+       if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
+               dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
+                       r->status);
+               return -EINVAL;
+       }
+
+       if (WILC_GET_RESP_HDR_START(r->resp_header) != 0xf) {
+               dev_err(&spi->dev, "Error, data read response (%02x)\n",
+                       r->resp_header);
+               return -EINVAL;
+       }
+
+       if (b)
+               memcpy(b, r->resp_data, 4);
+
+       if (!spi_priv->crc_off)
+               memcpy(crc, r->crc, 2);
+
+       return 0;
+}
+
+static int wilc_spi_write_cmd(struct wilc *wilc, u8 cmd, u32 adr, u32 data,
+                             u8 clockless)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
+       u8 wb[32], rb[32];
+       int cmd_len, resp_len;
+       struct wilc_spi_cmd *c;
+       struct wilc_spi_rsp_data *r;
+
+       memset(wb, 0x0, sizeof(wb));
+       memset(rb, 0x0, sizeof(rb));
+       c = (struct wilc_spi_cmd *)wb;
+       c->cmd_type = cmd;
+       if (cmd == CMD_INTERNAL_WRITE) {
+               c->u.internal_w_cmd.addr[0] = adr >> 8;
+               if (clockless == 1)
+                       c->u.internal_w_cmd.addr[0] |= BIT(7);
+
+               c->u.internal_w_cmd.addr[1] = adr;
+               c->u.internal_w_cmd.data = cpu_to_be32(data);
+               cmd_len = offsetof(struct wilc_spi_cmd, u.internal_w_cmd.crc);
+               if (!spi_priv->crc_off)
+                       c->u.internal_w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
+       } else if (cmd == CMD_SINGLE_WRITE) {
+               c->u.w_cmd.addr[0] = adr >> 16;
+               c->u.w_cmd.addr[1] = adr >> 8;
+               c->u.w_cmd.addr[2] = adr;
+               c->u.w_cmd.data = cpu_to_be32(data);
+               cmd_len = offsetof(struct wilc_spi_cmd, u.w_cmd.crc);
+               if (!spi_priv->crc_off)
+                       c->u.w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
+       } else {
+               dev_err(&spi->dev, "write cmd [%x] not supported\n", cmd);
+               return -EINVAL;
+       }
+
+       if (!spi_priv->crc_off)
+               cmd_len += 1;
+
+       resp_len = sizeof(*r);
+
+       if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
+               dev_err(&spi->dev,
+                       "spi buffer size too small (%d) (%d) (%zu)\n",
+                       cmd_len, resp_len, ARRAY_SIZE(wb));
+               return -EINVAL;
+       }
+
+       if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
+               dev_err(&spi->dev, "Failed cmd write, bus error...\n");
+               return -EINVAL;
+       }
+
+       r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
+       if (r->rsp_cmd_type != cmd) {
+               dev_err(&spi->dev,
+                       "Failed cmd response, cmd (%02x), resp (%02x)\n",
+                       cmd, r->rsp_cmd_type);
+               return -EINVAL;
+       }
+
+       if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
+               dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
+                       r->status);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int wilc_spi_dma_rw(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
+       u8 wb[32], rb[32];
+       int cmd_len, resp_len;
+       int retry, ix = 0;
+       u8 crc[2];
+       struct wilc_spi_cmd *c;
+       struct wilc_spi_rsp_data *r;
+
+       memset(wb, 0x0, sizeof(wb));
+       memset(rb, 0x0, sizeof(rb));
+       c = (struct wilc_spi_cmd *)wb;
+       c->cmd_type = cmd;
+       if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_READ) {
+               c->u.dma_cmd.addr[0] = adr >> 16;
+               c->u.dma_cmd.addr[1] = adr >> 8;
+               c->u.dma_cmd.addr[2] = adr;
+               c->u.dma_cmd.size[0] = sz >> 8;
+               c->u.dma_cmd.size[1] = sz;
+               cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd.crc);
+               if (!spi_priv->crc_off)
+                       c->u.dma_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
+       } else if (cmd == CMD_DMA_EXT_WRITE || cmd == CMD_DMA_EXT_READ) {
+               c->u.dma_cmd_ext.addr[0] = adr >> 16;
+               c->u.dma_cmd_ext.addr[1] = adr >> 8;
+               c->u.dma_cmd_ext.addr[2] = adr;
+               c->u.dma_cmd_ext.size[0] = sz >> 16;
+               c->u.dma_cmd_ext.size[1] = sz >> 8;
+               c->u.dma_cmd_ext.size[2] = sz;
+               cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd_ext.crc);
+               if (!spi_priv->crc_off)
+                       c->u.dma_cmd_ext.crc[0] = wilc_get_crc7(wb, cmd_len);
+       } else {
+               dev_err(&spi->dev, "dma read write cmd [%x] not supported\n",
+                       cmd);
+               return -EINVAL;
+       }
+       if (!spi_priv->crc_off)
+               cmd_len += 1;
+
+       resp_len = sizeof(*r);
+
+       if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
+               dev_err(&spi->dev, "spi buffer size too small (%d)(%d) (%zu)\n",
+                       cmd_len, resp_len, ARRAY_SIZE(wb));
+               return -EINVAL;
+       }
+
+       if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
+               dev_err(&spi->dev, "Failed cmd write, bus error...\n");
+               return -EINVAL;
+       }
+
+       r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
+       if (r->rsp_cmd_type != cmd) {
+               dev_err(&spi->dev,
+                       "Failed cmd response, cmd (%02x), resp (%02x)\n",
+                       cmd, r->rsp_cmd_type);
+               return -EINVAL;
+       }
+
+       if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
+               dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
+                       r->status);
+               return -EINVAL;
+       }
+
+       if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_EXT_WRITE)
+               return 0;
+
+       while (sz > 0) {
+               int nbytes;
+               u8 rsp;
+
+               if (sz <= DATA_PKT_SZ)
+                       nbytes = sz;
+               else
+                       nbytes = DATA_PKT_SZ;
+
+               /*
+                * Data Response header
+                */
+               retry = 100;
+               do {
+                       if (wilc_spi_rx(wilc, &rsp, 1)) {
+                               dev_err(&spi->dev,
+                                       "Failed resp read, bus err\n");
+                               return -EINVAL;
+                       }
+                       if (WILC_GET_RESP_HDR_START(rsp) == 0xf)
+                               break;
+               } while (retry--);
+
+               /*
+                * Read bytes
+                */
+               if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
+                       dev_err(&spi->dev,
+                               "Failed block read, bus err\n");
+                       return -EINVAL;
+               }
+
+               /*
+                * Read Crc
+                */
+               if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) {
+                       dev_err(&spi->dev,
+                               "Failed block crc read, bus err\n");
+                       return -EINVAL;
+               }
+
+               ix += nbytes;
+               sz -= nbytes;
+       }
+       return 0;
+}
+
+static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int result;
+       u8 cmd = CMD_SINGLE_READ;
+       u8 clockless = 0;
+
+       if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) {
+               /* Clockless register */
+               cmd = CMD_INTERNAL_READ;
+               clockless = 1;
+       }
+
+       result = wilc_spi_single_read(wilc, cmd, addr, data, clockless);
+       if (result) {
+               dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr);
+               return result;
+       }
+
+       le32_to_cpus(data);
+
+       return 0;
+}
+
+static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int result;
+
+       if (size <= 4)
+               return -EINVAL;
+
+       result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_READ, addr, buf, size);
+       if (result) {
+               dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr);
+               return result;
+       }
+
+       return 0;
+}
+
+static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int result;
+
+       result = wilc_spi_write_cmd(wilc, CMD_INTERNAL_WRITE, adr, dat, 0);
+       if (result) {
+               dev_err(&spi->dev, "Failed internal write cmd...\n");
+               return result;
+       }
+
+       return 0;
+}
+
+static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int result;
+
+       result = wilc_spi_single_read(wilc, CMD_INTERNAL_READ, adr, data, 0);
+       if (result) {
+               dev_err(&spi->dev, "Failed internal read cmd...\n");
+               return result;
+       }
+
+       le32_to_cpus(data);
+
+       return 0;
+}
+
+/********************************************
+ *
+ *      Spi interfaces
+ *
+ ********************************************/
+
+static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int result;
+       u8 cmd = CMD_SINGLE_WRITE;
+       u8 clockless = 0;
+
+       if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) {
+               /* Clockless register */
+               cmd = CMD_INTERNAL_WRITE;
+               clockless = 1;
+       }
+
+       result = wilc_spi_write_cmd(wilc, cmd, addr, data, clockless);
+       if (result) {
+               dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr);
+               return result;
+       }
+
+       return 0;
+}
+
+static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int result;
+
+       /*
+        * has to be greated than 4
+        */
+       if (size <= 4)
+               return -EINVAL;
+
+       result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_WRITE, addr, NULL, size);
+       if (result) {
+               dev_err(&spi->dev,
+                       "Failed cmd, write block (%08x)...\n", addr);
+               return result;
+       }
+
+       /*
+        * Data
+        */
+       result = spi_data_write(wilc, buf, size);
+       if (result) {
+               dev_err(&spi->dev, "Failed block data write...\n");
+               return result;
+       }
+
+       return 0;
+}
+
+/********************************************
+ *
+ *      Bus interfaces
+ *
+ ********************************************/
+
+static int wilc_spi_deinit(struct wilc *wilc)
+{
+       /*
+        * TODO:
+        */
+       return 0;
+}
+
+static int wilc_spi_init(struct wilc *wilc, bool resume)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
+       u32 reg;
+       u32 chipid;
+       static int isinit;
+       int ret;
+
+       if (isinit) {
+               ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
+               if (ret)
+                       dev_err(&spi->dev, "Fail cmd read chip id...\n");
+
+               return ret;
+       }
+
+       /*
+        * configure protocol
+        */
+
+       /*
+        * TODO: We can remove the CRC trials if there is a definite
+        * way to reset
+        */
+       /* the SPI to it's initial value. */
+       ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg);
+       if (ret) {
+               /*
+                * Read failed. Try with CRC off. This might happen when module
+                * is removed but chip isn't reset
+                */
+               spi_priv->crc_off = 1;
+               dev_err(&spi->dev,
+                       "Failed read with CRC on, retrying with CRC off\n");
+               ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg);
+               if (ret) {
+                       /*
+                        * Read failed with both CRC on and off,
+                        * something went bad
+                        */
+                       dev_err(&spi->dev, "Failed internal read protocol\n");
+                       return ret;
+               }
+       }
+       if (spi_priv->crc_off == 0) {
+               reg &= ~0xc; /* disable crc checking */
+               reg &= ~0x70;
+               reg |= (0x5 << 4);
+               ret = spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg);
+               if (ret) {
+                       dev_err(&spi->dev,
+                               "[wilc spi %d]: Failed internal write reg\n",
+                               __LINE__);
+                       return ret;
+               }
+               spi_priv->crc_off = 1;
+       }
+
+       /*
+        * make sure can read back chip id correctly
+        */
+       ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
+       if (ret) {
+               dev_err(&spi->dev, "Fail cmd read chip id...\n");
+               return ret;
+       }
+
+       isinit = 1;
+
+       return 0;
+}
+
+static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
+{
+       int ret;
+
+       ret = spi_internal_read(wilc,
+                               WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE, size);
+       *size = FIELD_GET(IRQ_DMA_WD_CNT_MASK, *size);
+
+       return ret;
+}
+
+static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
+{
+       return spi_internal_read(wilc, WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE,
+                                int_status);
+}
+
+static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
+{
+       return spi_internal_write(wilc, WILC_SPI_INT_CLEAR - WILC_SPI_REG_BASE,
+                                 val);
+}
+
+static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       u32 reg;
+       int ret, i;
+
+       if (nint > MAX_NUM_INT) {
+               dev_err(&spi->dev, "Too many interrupts (%d)...\n", nint);
+               return -EINVAL;
+       }
+
+       /*
+        * interrupt pin mux select
+        */
+       ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, &reg);
+       if (ret) {
+               dev_err(&spi->dev, "Failed read reg (%08x)...\n",
+                       WILC_PIN_MUX_0);
+               return ret;
+       }
+       reg |= BIT(8);
+       ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg);
+       if (ret) {
+               dev_err(&spi->dev, "Failed write reg (%08x)...\n",
+                       WILC_PIN_MUX_0);
+               return ret;
+       }
+
+       /*
+        * interrupt enable
+        */
+       ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, &reg);
+       if (ret) {
+               dev_err(&spi->dev, "Failed read reg (%08x)...\n",
+                       WILC_INTR_ENABLE);
+               return ret;
+       }
+
+       for (i = 0; (i < 5) && (nint > 0); i++, nint--)
+               reg |= (BIT((27 + i)));
+
+       ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg);
+       if (ret) {
+               dev_err(&spi->dev, "Failed write reg (%08x)...\n",
+                       WILC_INTR_ENABLE);
+               return ret;
+       }
+       if (nint) {
+               ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
+               if (ret) {
+                       dev_err(&spi->dev, "Failed read reg (%08x)...\n",
+                               WILC_INTR2_ENABLE);
+                       return ret;
+               }
+
+               for (i = 0; (i < 3) && (nint > 0); i++, nint--)
+                       reg |= BIT(i);
+
+               ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
+               if (ret) {
+                       dev_err(&spi->dev, "Failed write reg (%08x)...\n",
+                               WILC_INTR2_ENABLE);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/* Global spi HIF function table */
+static const struct wilc_hif_func wilc_hif_spi = {
+       .hif_init = wilc_spi_init,
+       .hif_deinit = wilc_spi_deinit,
+       .hif_read_reg = wilc_spi_read_reg,
+       .hif_write_reg = wilc_spi_write_reg,
+       .hif_block_rx = wilc_spi_read,
+       .hif_block_tx = wilc_spi_write,
+       .hif_read_int = wilc_spi_read_int,
+       .hif_clear_int_ext = wilc_spi_clear_int_ext,
+       .hif_read_size = wilc_spi_read_size,
+       .hif_block_tx_ext = wilc_spi_write,
+       .hif_block_rx_ext = wilc_spi_read,
+       .hif_sync_ext = wilc_spi_sync_ext,
+};
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
new file mode 100644 (file)
index 0000000..6a82fb2
--- /dev/null
@@ -0,0 +1,1238 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include "cfg80211.h"
+#include "wlan_cfg.h"
+
+static inline bool is_wilc1000(u32 id)
+{
+       return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
+}
+
+static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
+{
+       mutex_lock(&wilc->hif_cs);
+       if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP)
+               chip_wakeup(wilc);
+}
+
+static inline void release_bus(struct wilc *wilc, enum bus_release release)
+{
+       if (release == WILC_BUS_RELEASE_ALLOW_SLEEP)
+               chip_allow_sleep(wilc);
+       mutex_unlock(&wilc->hif_cs);
+}
+
+static void wilc_wlan_txq_remove(struct wilc *wilc, struct txq_entry_t *tqe)
+{
+       list_del(&tqe->list);
+       wilc->txq_entries -= 1;
+}
+
+static struct txq_entry_t *
+wilc_wlan_txq_remove_from_head(struct net_device *dev)
+{
+       struct txq_entry_t *tqe = NULL;
+       unsigned long flags;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
+
+       if (!list_empty(&wilc->txq_head.list)) {
+               tqe = list_first_entry(&wilc->txq_head.list, struct txq_entry_t,
+                                      list);
+               list_del(&tqe->list);
+               wilc->txq_entries -= 1;
+       }
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+       return tqe;
+}
+
+static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
+                                     struct txq_entry_t *tqe)
+{
+       unsigned long flags;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
+
+       list_add_tail(&tqe->list, &wilc->txq_head.list);
+       wilc->txq_entries += 1;
+
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+
+       complete(&wilc->txq_event);
+}
+
+static void wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
+                                     struct txq_entry_t *tqe)
+{
+       unsigned long flags;
+       struct wilc *wilc = vif->wilc;
+
+       mutex_lock(&wilc->txq_add_to_head_cs);
+
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
+
+       list_add(&tqe->list, &wilc->txq_head.list);
+       wilc->txq_entries += 1;
+
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+       mutex_unlock(&wilc->txq_add_to_head_cs);
+       complete(&wilc->txq_event);
+}
+
+#define NOT_TCP_ACK                    (-1)
+
+static inline void add_tcp_session(struct wilc_vif *vif, u32 src_prt,
+                                  u32 dst_prt, u32 seq)
+{
+       struct tcp_ack_filter *f = &vif->ack_filter;
+
+       if (f->tcp_session < 2 * MAX_TCP_SESSION) {
+               f->ack_session_info[f->tcp_session].seq_num = seq;
+               f->ack_session_info[f->tcp_session].bigger_ack_num = 0;
+               f->ack_session_info[f->tcp_session].src_port = src_prt;
+               f->ack_session_info[f->tcp_session].dst_port = dst_prt;
+               f->tcp_session++;
+       }
+}
+
+static inline void update_tcp_session(struct wilc_vif *vif, u32 index, u32 ack)
+{
+       struct tcp_ack_filter *f = &vif->ack_filter;
+
+       if (index < 2 * MAX_TCP_SESSION &&
+           ack > f->ack_session_info[index].bigger_ack_num)
+               f->ack_session_info[index].bigger_ack_num = ack;
+}
+
+static inline void add_tcp_pending_ack(struct wilc_vif *vif, u32 ack,
+                                      u32 session_index,
+                                      struct txq_entry_t *txqe)
+{
+       struct tcp_ack_filter *f = &vif->ack_filter;
+       u32 i = f->pending_base + f->pending_acks_idx;
+
+       if (i < MAX_PENDING_ACKS) {
+               f->pending_acks[i].ack_num = ack;
+               f->pending_acks[i].txqe = txqe;
+               f->pending_acks[i].session_index = session_index;
+               txqe->ack_idx = i;
+               f->pending_acks_idx++;
+       }
+}
+
+static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
+{
+       void *buffer = tqe->buffer;
+       const struct ethhdr *eth_hdr_ptr = buffer;
+       int i;
+       unsigned long flags;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+       struct tcp_ack_filter *f = &vif->ack_filter;
+       const struct iphdr *ip_hdr_ptr;
+       const struct tcphdr *tcp_hdr_ptr;
+       u32 ihl, total_length, data_offset;
+
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
+
+       if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
+               goto out;
+
+       ip_hdr_ptr = buffer + ETH_HLEN;
+
+       if (ip_hdr_ptr->protocol != IPPROTO_TCP)
+               goto out;
+
+       ihl = ip_hdr_ptr->ihl << 2;
+       tcp_hdr_ptr = buffer + ETH_HLEN + ihl;
+       total_length = ntohs(ip_hdr_ptr->tot_len);
+
+       data_offset = tcp_hdr_ptr->doff << 2;
+       if (total_length == (ihl + data_offset)) {
+               u32 seq_no, ack_no;
+
+               seq_no = ntohl(tcp_hdr_ptr->seq);
+               ack_no = ntohl(tcp_hdr_ptr->ack_seq);
+               for (i = 0; i < f->tcp_session; i++) {
+                       u32 j = f->ack_session_info[i].seq_num;
+
+                       if (i < 2 * MAX_TCP_SESSION &&
+                           j == seq_no) {
+                               update_tcp_session(vif, i, ack_no);
+                               break;
+                       }
+               }
+               if (i == f->tcp_session)
+                       add_tcp_session(vif, 0, 0, seq_no);
+
+               add_tcp_pending_ack(vif, ack_no, i, tqe);
+       }
+
+out:
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+}
+
+static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
+{
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+       struct tcp_ack_filter *f = &vif->ack_filter;
+       u32 i = 0;
+       u32 dropped = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
+       for (i = f->pending_base;
+            i < (f->pending_base + f->pending_acks_idx); i++) {
+               u32 index;
+               u32 bigger_ack_num;
+
+               if (i >= MAX_PENDING_ACKS)
+                       break;
+
+               index = f->pending_acks[i].session_index;
+
+               if (index >= 2 * MAX_TCP_SESSION)
+                       break;
+
+               bigger_ack_num = f->ack_session_info[index].bigger_ack_num;
+
+               if (f->pending_acks[i].ack_num < bigger_ack_num) {
+                       struct txq_entry_t *tqe;
+
+                       tqe = f->pending_acks[i].txqe;
+                       if (tqe) {
+                               wilc_wlan_txq_remove(wilc, tqe);
+                               tqe->status = 1;
+                               if (tqe->tx_complete_func)
+                                       tqe->tx_complete_func(tqe->priv,
+                                                             tqe->status);
+                               kfree(tqe);
+                               dropped++;
+                       }
+               }
+       }
+       f->pending_acks_idx = 0;
+       f->tcp_session = 0;
+
+       if (f->pending_base == 0)
+               f->pending_base = MAX_TCP_SESSION;
+       else
+               f->pending_base = 0;
+
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+
+       while (dropped > 0) {
+               wait_for_completion_timeout(&wilc->txq_event,
+                                           msecs_to_jiffies(1));
+               dropped--;
+       }
+}
+
+void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
+{
+       vif->ack_filter.enabled = value;
+}
+
+static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
+                                    u32 buffer_size)
+{
+       struct txq_entry_t *tqe;
+       struct wilc *wilc = vif->wilc;
+
+       netdev_dbg(vif->ndev, "Adding config packet ...\n");
+       if (wilc->quit) {
+               netdev_dbg(vif->ndev, "Return due to clear function\n");
+               complete(&wilc->cfg_event);
+               return 0;
+       }
+
+       tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
+       if (!tqe)
+               return 0;
+
+       tqe->type = WILC_CFG_PKT;
+       tqe->buffer = buffer;
+       tqe->buffer_size = buffer_size;
+       tqe->tx_complete_func = NULL;
+       tqe->priv = NULL;
+       tqe->ack_idx = NOT_TCP_ACK;
+       tqe->vif = vif;
+
+       wilc_wlan_txq_add_to_head(vif, tqe);
+
+       return 1;
+}
+
+int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
+                             u32 buffer_size,
+                             void (*tx_complete_fn)(void *, int))
+{
+       struct txq_entry_t *tqe;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc;
+
+       wilc = vif->wilc;
+
+       if (wilc->quit)
+               return 0;
+
+       tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
+
+       if (!tqe)
+               return 0;
+       tqe->type = WILC_NET_PKT;
+       tqe->buffer = buffer;
+       tqe->buffer_size = buffer_size;
+       tqe->tx_complete_func = tx_complete_fn;
+       tqe->priv = priv;
+       tqe->vif = vif;
+
+       tqe->ack_idx = NOT_TCP_ACK;
+       if (vif->ack_filter.enabled)
+               tcp_process(dev, tqe);
+       wilc_wlan_txq_add_to_tail(dev, tqe);
+       return wilc->txq_entries;
+}
+
+int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
+                              u32 buffer_size,
+                              void (*tx_complete_fn)(void *, int))
+{
+       struct txq_entry_t *tqe;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc;
+
+       wilc = vif->wilc;
+
+       if (wilc->quit)
+               return 0;
+
+       tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
+
+       if (!tqe)
+               return 0;
+       tqe->type = WILC_MGMT_PKT;
+       tqe->buffer = buffer;
+       tqe->buffer_size = buffer_size;
+       tqe->tx_complete_func = tx_complete_fn;
+       tqe->priv = priv;
+       tqe->ack_idx = NOT_TCP_ACK;
+       tqe->vif = vif;
+       wilc_wlan_txq_add_to_tail(dev, tqe);
+       return 1;
+}
+
+static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc)
+{
+       struct txq_entry_t *tqe = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
+
+       if (!list_empty(&wilc->txq_head.list))
+               tqe = list_first_entry(&wilc->txq_head.list, struct txq_entry_t,
+                                      list);
+
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+
+       return tqe;
+}
+
+static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
+                                                 struct txq_entry_t *tqe)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
+
+       if (!list_is_last(&tqe->list, &wilc->txq_head.list))
+               tqe = list_next_entry(tqe, list);
+       else
+               tqe = NULL;
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+
+       return tqe;
+}
+
+static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
+{
+       if (wilc->quit)
+               return;
+
+       mutex_lock(&wilc->rxq_cs);
+       list_add_tail(&rqe->list, &wilc->rxq_head.list);
+       mutex_unlock(&wilc->rxq_cs);
+}
+
+static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
+{
+       struct rxq_entry_t *rqe = NULL;
+
+       mutex_lock(&wilc->rxq_cs);
+       if (!list_empty(&wilc->rxq_head.list)) {
+               rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t,
+                                      list);
+               list_del(&rqe->list);
+       }
+       mutex_unlock(&wilc->rxq_cs);
+       return rqe;
+}
+
+void chip_allow_sleep(struct wilc *wilc)
+{
+       u32 reg = 0;
+
+       wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
+
+       wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
+                                     reg & ~WILC_SDIO_WAKEUP_BIT);
+       wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0);
+}
+EXPORT_SYMBOL_GPL(chip_allow_sleep);
+
+void chip_wakeup(struct wilc *wilc)
+{
+       u32 reg, clk_status_reg;
+       const struct wilc_hif_func *h = wilc->hif_func;
+
+       if (wilc->io_type == WILC_HIF_SPI) {
+               do {
+                       h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, &reg);
+                       h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
+                                        reg | WILC_SPI_WAKEUP_BIT);
+                       h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
+                                        reg & ~WILC_SPI_WAKEUP_BIT);
+
+                       do {
+                               usleep_range(2000, 2500);
+                               wilc_get_chipid(wilc, true);
+                       } while (wilc_get_chipid(wilc, true) == 0);
+               } while (wilc_get_chipid(wilc, true) == 0);
+       } else if (wilc->io_type == WILC_HIF_SDIO) {
+               h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG,
+                                WILC_SDIO_HOST_TO_FW_BIT);
+               usleep_range(200, 400);
+               h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
+               do {
+                       h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
+                                        reg | WILC_SDIO_WAKEUP_BIT);
+                       h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
+                                       &clk_status_reg);
+
+                       while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
+                               usleep_range(2000, 2500);
+
+                               h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
+                                               &clk_status_reg);
+                       }
+                       if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
+                               h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
+                                                reg & ~WILC_SDIO_WAKEUP_BIT);
+                       }
+               } while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT));
+       }
+
+       if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) {
+               if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) {
+                       u32 val32;
+
+                       h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32);
+                       val32 |= BIT(6);
+                       h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32);
+
+                       h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32);
+                       val32 |= BIT(6);
+                       h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32);
+               }
+       }
+       wilc->chip_ps_state = WILC_CHIP_WAKEDUP;
+}
+EXPORT_SYMBOL_GPL(chip_wakeup);
+
+void host_wakeup_notify(struct wilc *wilc)
+{
+       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+       wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
+       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+}
+EXPORT_SYMBOL_GPL(host_wakeup_notify);
+
+void host_sleep_notify(struct wilc *wilc)
+{
+       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+       wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
+       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+}
+EXPORT_SYMBOL_GPL(host_sleep_notify);
+
+int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
+{
+       int i, entries = 0;
+       u32 sum;
+       u32 reg;
+       u32 offset = 0;
+       int vmm_sz = 0;
+       struct txq_entry_t *tqe;
+       int ret = 0;
+       int counter;
+       int timeout;
+       u32 vmm_table[WILC_VMM_TBL_SIZE];
+       const struct wilc_hif_func *func;
+       u8 *txb = wilc->tx_buffer;
+       struct net_device *dev;
+       struct wilc_vif *vif;
+
+       if (wilc->quit)
+               goto out_update_cnt;
+
+       mutex_lock(&wilc->txq_add_to_head_cs);
+       tqe = wilc_wlan_txq_get_first(wilc);
+       if (!tqe)
+               goto out_unlock;
+       dev = tqe->vif->ndev;
+       wilc_wlan_txq_filter_dup_tcp_ack(dev);
+       i = 0;
+       sum = 0;
+       while (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) {
+               if (tqe->type == WILC_CFG_PKT)
+                       vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
+               else if (tqe->type == WILC_NET_PKT)
+                       vmm_sz = ETH_ETHERNET_HDR_OFFSET;
+               else
+                       vmm_sz = HOST_HDR_OFFSET;
+
+               vmm_sz += tqe->buffer_size;
+               vmm_sz = ALIGN(vmm_sz, 4);
+
+               if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE)
+                       break;
+
+               vmm_table[i] = vmm_sz / 4;
+               if (tqe->type == WILC_CFG_PKT)
+                       vmm_table[i] |= BIT(10);
+               cpu_to_le32s(&vmm_table[i]);
+
+               i++;
+               sum += vmm_sz;
+               tqe = wilc_wlan_txq_get_next(wilc, tqe);
+       }
+
+       if (i == 0)
+               goto out_unlock;
+       vmm_table[i] = 0x0;
+
+       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       counter = 0;
+       func = wilc->hif_func;
+       do {
+               ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
+               if (ret)
+                       break;
+
+               if ((reg & 0x1) == 0)
+                       break;
+
+               counter++;
+               if (counter > 200) {
+                       counter = 0;
+                       ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
+                       break;
+               }
+       } while (!wilc->quit);
+
+       if (ret)
+               goto out_release_bus;
+
+       timeout = 200;
+       do {
+               ret = func->hif_block_tx(wilc,
+                                        WILC_VMM_TBL_RX_SHADOW_BASE,
+                                        (u8 *)vmm_table,
+                                        ((i + 1) * 4));
+               if (ret)
+                       break;
+
+               ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
+               if (ret)
+                       break;
+
+               do {
+                       ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
+                       if (ret)
+                               break;
+                       if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
+                               entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
+                               break;
+                       }
+               } while (--timeout);
+               if (timeout <= 0) {
+                       ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
+                       break;
+               }
+
+               if (ret)
+                       break;
+
+               if (entries == 0) {
+                       ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
+                       if (ret)
+                               break;
+                       reg &= ~BIT(0);
+                       ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
+               }
+       } while (0);
+
+       if (ret)
+               goto out_release_bus;
+
+       if (entries == 0) {
+               /*
+                * No VMM space available in firmware so retry to transmit
+                * the packet from tx queue.
+                */
+               ret = WILC_VMM_ENTRY_FULL_RETRY;
+               goto out_release_bus;
+       }
+
+       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+
+       offset = 0;
+       i = 0;
+       do {
+               u32 header, buffer_offset;
+               char *bssid;
+               u8 mgmt_ptk = 0;
+
+               tqe = wilc_wlan_txq_remove_from_head(dev);
+               if (!tqe)
+                       break;
+
+               vif = tqe->vif;
+               if (vmm_table[i] == 0)
+                       break;
+
+               le32_to_cpus(&vmm_table[i]);
+               vmm_sz = FIELD_GET(WILC_VMM_BUFFER_SIZE, vmm_table[i]);
+               vmm_sz *= 4;
+
+               if (tqe->type == WILC_MGMT_PKT)
+                       mgmt_ptk = 1;
+
+               header = (FIELD_PREP(WILC_VMM_HDR_TYPE, tqe->type) |
+                         FIELD_PREP(WILC_VMM_HDR_MGMT_FIELD, mgmt_ptk) |
+                         FIELD_PREP(WILC_VMM_HDR_PKT_SIZE, tqe->buffer_size) |
+                         FIELD_PREP(WILC_VMM_HDR_BUFF_SIZE, vmm_sz));
+
+               cpu_to_le32s(&header);
+               memcpy(&txb[offset], &header, 4);
+               if (tqe->type == WILC_CFG_PKT) {
+                       buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
+               } else if (tqe->type == WILC_NET_PKT) {
+                       bssid = tqe->vif->bssid;
+                       buffer_offset = ETH_ETHERNET_HDR_OFFSET;
+                       memcpy(&txb[offset + 8], bssid, 6);
+               } else {
+                       buffer_offset = HOST_HDR_OFFSET;
+               }
+
+               memcpy(&txb[offset + buffer_offset],
+                      tqe->buffer, tqe->buffer_size);
+               offset += vmm_sz;
+               i++;
+               tqe->status = 1;
+               if (tqe->tx_complete_func)
+                       tqe->tx_complete_func(tqe->priv, tqe->status);
+               if (tqe->ack_idx != NOT_TCP_ACK &&
+                   tqe->ack_idx < MAX_PENDING_ACKS)
+                       vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL;
+               kfree(tqe);
+       } while (--entries);
+
+       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+
+       ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
+       if (ret)
+               goto out_release_bus;
+
+       ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
+
+out_release_bus:
+       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+
+out_unlock:
+       mutex_unlock(&wilc->txq_add_to_head_cs);
+
+out_update_cnt:
+       *txq_count = wilc->txq_entries;
+       return ret;
+}
+
+static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
+{
+       int offset = 0;
+       u32 header;
+       u32 pkt_len, pkt_offset, tp_len;
+       int is_cfg_packet;
+       u8 *buff_ptr;
+
+       do {
+               buff_ptr = buffer + offset;
+               header = get_unaligned_le32(buff_ptr);
+
+               is_cfg_packet = FIELD_GET(WILC_PKT_HDR_CONFIG_FIELD, header);
+               pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
+               tp_len = FIELD_GET(WILC_PKT_HDR_TOTAL_LEN_FIELD, header);
+               pkt_len = FIELD_GET(WILC_PKT_HDR_LEN_FIELD, header);
+
+               if (pkt_len == 0 || tp_len == 0)
+                       break;
+
+               if (pkt_offset & IS_MANAGMEMENT) {
+                       buff_ptr += HOST_HDR_OFFSET;
+                       wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len);
+               } else {
+                       if (!is_cfg_packet) {
+                               wilc_frmw_to_host(wilc, buff_ptr, pkt_len,
+                                                 pkt_offset);
+                       } else {
+                               struct wilc_cfg_rsp rsp;
+
+                               buff_ptr += pkt_offset;
+
+                               wilc_wlan_cfg_indicate_rx(wilc, buff_ptr,
+                                                         pkt_len,
+                                                         &rsp);
+                               if (rsp.type == WILC_CFG_RSP) {
+                                       if (wilc->cfg_seq_no == rsp.seq_no)
+                                               complete(&wilc->cfg_event);
+                               } else if (rsp.type == WILC_CFG_RSP_STATUS) {
+                                       wilc_mac_indicate(wilc);
+                               }
+                       }
+               }
+               offset += tp_len;
+       } while (offset < size);
+}
+
+static void wilc_wlan_handle_rxq(struct wilc *wilc)
+{
+       int size;
+       u8 *buffer;
+       struct rxq_entry_t *rqe;
+
+       while (!wilc->quit) {
+               rqe = wilc_wlan_rxq_remove(wilc);
+               if (!rqe)
+                       break;
+
+               buffer = rqe->buffer;
+               size = rqe->buffer_size;
+               wilc_wlan_handle_rx_buff(wilc, buffer, size);
+
+               kfree(rqe);
+       }
+       if (wilc->quit)
+               complete(&wilc->cfg_event);
+}
+
+static void wilc_unknown_isr_ext(struct wilc *wilc)
+{
+       wilc->hif_func->hif_clear_int_ext(wilc, 0);
+}
+
+static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
+{
+       u32 offset = wilc->rx_buffer_offset;
+       u8 *buffer = NULL;
+       u32 size;
+       u32 retries = 0;
+       int ret = 0;
+       struct rxq_entry_t *rqe;
+
+       size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, int_status) << 2;
+
+       while (!size && retries < 10) {
+               wilc->hif_func->hif_read_size(wilc, &size);
+               size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, size) << 2;
+               retries++;
+       }
+
+       if (size <= 0)
+               return;
+
+       if (WILC_RX_BUFF_SIZE - offset < size)
+               offset = 0;
+
+       buffer = &wilc->rx_buffer[offset];
+
+       wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM);
+       ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
+       if (ret)
+               return;
+
+       offset += size;
+       wilc->rx_buffer_offset = offset;
+       rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
+       if (!rqe)
+               return;
+
+       rqe->buffer = buffer;
+       rqe->buffer_size = size;
+       wilc_wlan_rxq_add(wilc, rqe);
+       wilc_wlan_handle_rxq(wilc);
+}
+
+void wilc_handle_isr(struct wilc *wilc)
+{
+       u32 int_status;
+
+       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       wilc->hif_func->hif_read_int(wilc, &int_status);
+
+       if (int_status & DATA_INT_EXT)
+               wilc_wlan_handle_isr_ext(wilc, int_status);
+
+       if (!(int_status & (ALL_INT_EXT)))
+               wilc_unknown_isr_ext(wilc);
+
+       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+}
+EXPORT_SYMBOL_GPL(wilc_handle_isr);
+
+int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
+                               u32 buffer_size)
+{
+       u32 offset;
+       u32 addr, size, size2, blksz;
+       u8 *dma_buffer;
+       int ret = 0;
+
+       blksz = BIT(12);
+
+       dma_buffer = kmalloc(blksz, GFP_KERNEL);
+       if (!dma_buffer)
+               return -EIO;
+
+       offset = 0;
+       do {
+               addr = get_unaligned_le32(&buffer[offset]);
+               size = get_unaligned_le32(&buffer[offset + 4]);
+               acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+               offset += 8;
+               while (((int)size) && (offset < buffer_size)) {
+                       if (size <= blksz)
+                               size2 = size;
+                       else
+                               size2 = blksz;
+
+                       memcpy(dma_buffer, &buffer[offset], size2);
+                       ret = wilc->hif_func->hif_block_tx(wilc, addr,
+                                                          dma_buffer, size2);
+                       if (ret)
+                               break;
+
+                       addr += size2;
+                       offset += size2;
+                       size -= size2;
+               }
+               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+
+               if (ret)
+                       goto fail;
+       } while (offset < buffer_size);
+
+fail:
+
+       kfree(dma_buffer);
+
+       return ret;
+}
+
+int wilc_wlan_start(struct wilc *wilc)
+{
+       u32 reg = 0;
+       int ret;
+       u32 chipid;
+
+       if (wilc->io_type == WILC_HIF_SDIO) {
+               reg = 0;
+               reg |= BIT(3);
+       } else if (wilc->io_type == WILC_HIF_SPI) {
+               reg = 1;
+       }
+       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
+       if (ret) {
+               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+               return ret;
+       }
+       reg = 0;
+       if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
+               reg |= WILC_HAVE_SDIO_IRQ_GPIO;
+
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
+       if (ret) {
+               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+               return ret;
+       }
+
+       wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
+
+       ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
+       if (ret) {
+               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+               return ret;
+       }
+
+       wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
+       if ((reg & BIT(10)) == BIT(10)) {
+               reg &= ~BIT(10);
+               wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
+               wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
+       }
+
+       reg |= BIT(10);
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
+       wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
+       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+
+       return ret;
+}
+
+int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
+{
+       u32 reg = 0;
+       int ret;
+
+       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+
+       ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
+       if (ret) {
+               netdev_err(vif->ndev, "Error while reading reg\n");
+               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+               return ret;
+       }
+
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
+                                       (reg | WILC_ABORT_REQ_BIT));
+       if (ret) {
+               netdev_err(vif->ndev, "Error while writing reg\n");
+               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+               return ret;
+       }
+
+       ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, &reg);
+       if (ret) {
+               netdev_err(vif->ndev, "Error while reading reg\n");
+               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+               return ret;
+       }
+       reg = BIT(0);
+
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg);
+       if (ret) {
+               netdev_err(vif->ndev, "Error while writing reg\n");
+               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+               return ret;
+       }
+
+       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+
+       return 0;
+}
+
+void wilc_wlan_cleanup(struct net_device *dev)
+{
+       struct txq_entry_t *tqe;
+       struct rxq_entry_t *rqe;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+
+       wilc->quit = 1;
+       while ((tqe = wilc_wlan_txq_remove_from_head(dev))) {
+               if (tqe->tx_complete_func)
+                       tqe->tx_complete_func(tqe->priv, 0);
+               kfree(tqe);
+       }
+
+       while ((rqe = wilc_wlan_rxq_remove(wilc)))
+               kfree(rqe);
+
+       kfree(wilc->rx_buffer);
+       wilc->rx_buffer = NULL;
+       kfree(wilc->tx_buffer);
+       wilc->tx_buffer = NULL;
+       wilc->hif_func->hif_deinit(NULL);
+}
+
+static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
+                               u32 drv_handler)
+{
+       struct wilc *wilc = vif->wilc;
+       struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
+       int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr);
+
+       if (type == WILC_CFG_SET)
+               cfg->hdr.cmd_type = 'W';
+       else
+               cfg->hdr.cmd_type = 'Q';
+
+       cfg->hdr.seq_no = wilc->cfg_seq_no % 256;
+       cfg->hdr.total_len = cpu_to_le16(t_len);
+       cfg->hdr.driver_handler = cpu_to_le32(drv_handler);
+       wilc->cfg_seq_no = cfg->hdr.seq_no;
+
+       if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len))
+               return -1;
+
+       return 0;
+}
+
+int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
+                     u32 buffer_size, int commit, u32 drv_handler)
+{
+       u32 offset;
+       int ret_size;
+       struct wilc *wilc = vif->wilc;
+
+       mutex_lock(&wilc->cfg_cmd_lock);
+
+       if (start)
+               wilc->cfg_frame_offset = 0;
+
+       offset = wilc->cfg_frame_offset;
+       ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
+                                        wid, buffer, buffer_size);
+       offset += ret_size;
+       wilc->cfg_frame_offset = offset;
+
+       if (!commit) {
+               mutex_unlock(&wilc->cfg_cmd_lock);
+               return ret_size;
+       }
+
+       netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no);
+
+       if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
+               ret_size = 0;
+
+       if (!wait_for_completion_timeout(&wilc->cfg_event,
+                                        WILC_CFG_PKTS_TIMEOUT)) {
+               netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
+               ret_size = 0;
+       }
+
+       wilc->cfg_frame_offset = 0;
+       wilc->cfg_seq_no += 1;
+       mutex_unlock(&wilc->cfg_cmd_lock);
+
+       return ret_size;
+}
+
+int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
+                     u32 drv_handler)
+{
+       u32 offset;
+       int ret_size;
+       struct wilc *wilc = vif->wilc;
+
+       mutex_lock(&wilc->cfg_cmd_lock);
+
+       if (start)
+               wilc->cfg_frame_offset = 0;
+
+       offset = wilc->cfg_frame_offset;
+       ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid);
+       offset += ret_size;
+       wilc->cfg_frame_offset = offset;
+
+       if (!commit) {
+               mutex_unlock(&wilc->cfg_cmd_lock);
+               return ret_size;
+       }
+
+       if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
+               ret_size = 0;
+
+       if (!wait_for_completion_timeout(&wilc->cfg_event,
+                                        WILC_CFG_PKTS_TIMEOUT)) {
+               netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
+               ret_size = 0;
+       }
+       wilc->cfg_frame_offset = 0;
+       wilc->cfg_seq_no += 1;
+       mutex_unlock(&wilc->cfg_cmd_lock);
+
+       return ret_size;
+}
+
+int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
+                        u32 count)
+{
+       int i;
+       int ret = 0;
+       u32 drv = wilc_get_vif_idx(vif);
+
+       if (mode == WILC_GET_CFG) {
+               for (i = 0; i < count; i++) {
+                       if (!wilc_wlan_cfg_get(vif, !i,
+                                              wids[i].id,
+                                              (i == count - 1),
+                                              drv)) {
+                               ret = -ETIMEDOUT;
+                               break;
+                       }
+               }
+               for (i = 0; i < count; i++) {
+                       wids[i].size = wilc_wlan_cfg_get_val(vif->wilc,
+                                                            wids[i].id,
+                                                            wids[i].val,
+                                                            wids[i].size);
+               }
+       } else if (mode == WILC_SET_CFG) {
+               for (i = 0; i < count; i++) {
+                       if (!wilc_wlan_cfg_set(vif, !i,
+                                              wids[i].id,
+                                              wids[i].val,
+                                              wids[i].size,
+                                              (i == count - 1),
+                                              drv)) {
+                               ret = -ETIMEDOUT;
+                               break;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+static int init_chip(struct net_device *dev)
+{
+       u32 chipid;
+       u32 reg;
+       int ret = 0;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc = vif->wilc;
+
+       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+
+       chipid = wilc_get_chipid(wilc, true);
+
+       if ((chipid & 0xfff) != 0xa0) {
+               ret = wilc->hif_func->hif_read_reg(wilc,
+                                                  WILC_CORTUS_RESET_MUX_SEL,
+                                                  &reg);
+               if (ret) {
+                       netdev_err(dev, "fail read reg 0x1118\n");
+                       goto release;
+               }
+               reg |= BIT(0);
+               ret = wilc->hif_func->hif_write_reg(wilc,
+                                                   WILC_CORTUS_RESET_MUX_SEL,
+                                                   reg);
+               if (ret) {
+                       netdev_err(dev, "fail write reg 0x1118\n");
+                       goto release;
+               }
+               ret = wilc->hif_func->hif_write_reg(wilc,
+                                                   WILC_CORTUS_BOOT_REGISTER,
+                                                   WILC_CORTUS_BOOT_FROM_IRAM);
+               if (ret) {
+                       netdev_err(dev, "fail write reg 0xc0000\n");
+                       goto release;
+               }
+       }
+
+release:
+       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+
+       return ret;
+}
+
+u32 wilc_get_chipid(struct wilc *wilc, bool update)
+{
+       static u32 chipid;
+       u32 tempchipid = 0;
+       u32 rfrevid = 0;
+
+       if (chipid == 0 || update) {
+               wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &tempchipid);
+               wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
+                                            &rfrevid);
+               if (!is_wilc1000(tempchipid)) {
+                       chipid = 0;
+                       return chipid;
+               }
+               if (tempchipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
+                       if (rfrevid != 0x1)
+                               tempchipid = WILC_1000_BASE_ID_2A_REV1;
+               } else if (tempchipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
+                       if (rfrevid == 0x4)
+                               tempchipid = WILC_1000_BASE_ID_2B_REV1;
+                       else if (rfrevid != 0x3)
+                               tempchipid = WILC_1000_BASE_ID_2B_REV2;
+               }
+
+               chipid = tempchipid;
+       }
+       return chipid;
+}
+
+int wilc_wlan_init(struct net_device *dev)
+{
+       int ret = 0;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc;
+
+       wilc = vif->wilc;
+
+       wilc->quit = 0;
+
+       if (wilc->hif_func->hif_init(wilc, false)) {
+               ret = -EIO;
+               goto fail;
+       }
+
+       if (!wilc->tx_buffer)
+               wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL);
+
+       if (!wilc->tx_buffer) {
+               ret = -ENOBUFS;
+               goto fail;
+       }
+
+       if (!wilc->rx_buffer)
+               wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL);
+
+       if (!wilc->rx_buffer) {
+               ret = -ENOBUFS;
+               goto fail;
+       }
+
+       if (init_chip(dev)) {
+               ret = -EIO;
+               goto fail;
+       }
+
+       return 0;
+
+fail:
+
+       kfree(wilc->rx_buffer);
+       wilc->rx_buffer = NULL;
+       kfree(wilc->tx_buffer);
+       wilc->tx_buffer = NULL;
+
+       return ret;
+}
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h
new file mode 100644 (file)
index 0000000..7689569
--- /dev/null
@@ -0,0 +1,397 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#ifndef WILC_WLAN_H
+#define WILC_WLAN_H
+
+#include <linux/types.h>
+#include <linux/bitfield.h>
+
+/********************************************
+ *
+ *      Mac eth header length
+ *
+ ********************************************/
+#define MAX_MAC_HDR_LEN                        26 /* QOS_MAC_HDR_LEN */
+#define SUB_MSDU_HEADER_LENGTH         14
+#define SNAP_HDR_LEN                   8
+#define ETHERNET_HDR_LEN               14
+#define WORD_ALIGNMENT_PAD             0
+
+#define ETH_ETHERNET_HDR_OFFSET                (MAX_MAC_HDR_LEN + \
+                                        SUB_MSDU_HEADER_LENGTH + \
+                                        SNAP_HDR_LEN - \
+                                        ETHERNET_HDR_LEN + \
+                                        WORD_ALIGNMENT_PAD)
+
+#define HOST_HDR_OFFSET                        4
+#define ETHERNET_HDR_LEN               14
+#define IP_HDR_LEN                     20
+#define IP_HDR_OFFSET                  ETHERNET_HDR_LEN
+#define UDP_HDR_OFFSET                 (IP_HDR_LEN + IP_HDR_OFFSET)
+#define UDP_HDR_LEN                    8
+#define UDP_DATA_OFFSET                        (UDP_HDR_OFFSET + UDP_HDR_LEN)
+#define ETH_CONFIG_PKT_HDR_LEN         UDP_DATA_OFFSET
+
+#define ETH_CONFIG_PKT_HDR_OFFSET      (ETH_ETHERNET_HDR_OFFSET + \
+                                        ETH_CONFIG_PKT_HDR_LEN)
+
+/********************************************
+ *
+ *      Register Defines
+ *
+ ********************************************/
+#define WILC_PERIPH_REG_BASE           0x1000
+#define WILC_CHANGING_VIR_IF           0x108c
+#define WILC_CHIPID                    WILC_PERIPH_REG_BASE
+#define WILC_GLB_RESET_0               (WILC_PERIPH_REG_BASE + 0x400)
+#define WILC_PIN_MUX_0                 (WILC_PERIPH_REG_BASE + 0x408)
+#define WILC_HOST_TX_CTRL              (WILC_PERIPH_REG_BASE + 0x6c)
+#define WILC_HOST_RX_CTRL_0            (WILC_PERIPH_REG_BASE + 0x70)
+#define WILC_HOST_RX_CTRL_1            (WILC_PERIPH_REG_BASE + 0x74)
+#define WILC_HOST_VMM_CTL              (WILC_PERIPH_REG_BASE + 0x78)
+#define WILC_HOST_RX_CTRL              (WILC_PERIPH_REG_BASE + 0x80)
+#define WILC_HOST_RX_EXTRA_SIZE                (WILC_PERIPH_REG_BASE + 0x84)
+#define WILC_HOST_TX_CTRL_1            (WILC_PERIPH_REG_BASE + 0x88)
+#define WILC_MISC                      (WILC_PERIPH_REG_BASE + 0x428)
+#define WILC_INTR_REG_BASE             (WILC_PERIPH_REG_BASE + 0xa00)
+#define WILC_INTR_ENABLE               WILC_INTR_REG_BASE
+#define WILC_INTR2_ENABLE              (WILC_INTR_REG_BASE + 4)
+
+#define WILC_INTR_POLARITY             (WILC_INTR_REG_BASE + 0x10)
+#define WILC_INTR_TYPE                 (WILC_INTR_REG_BASE + 0x20)
+#define WILC_INTR_CLEAR                        (WILC_INTR_REG_BASE + 0x30)
+#define WILC_INTR_STATUS               (WILC_INTR_REG_BASE + 0x40)
+
+#define WILC_RF_REVISION_ID            0x13f4
+
+#define WILC_VMM_TBL_SIZE              64
+#define WILC_VMM_TX_TBL_BASE           0x150400
+#define WILC_VMM_RX_TBL_BASE           0x150500
+
+#define WILC_VMM_BASE                  0x150000
+#define WILC_VMM_CORE_CTL              WILC_VMM_BASE
+#define WILC_VMM_TBL_CTL               (WILC_VMM_BASE + 0x4)
+#define WILC_VMM_TBL_ENTRY             (WILC_VMM_BASE + 0x8)
+#define WILC_VMM_TBL0_SIZE             (WILC_VMM_BASE + 0xc)
+#define WILC_VMM_TO_HOST_SIZE          (WILC_VMM_BASE + 0x10)
+#define WILC_VMM_CORE_CFG              (WILC_VMM_BASE + 0x14)
+#define WILC_VMM_TBL_ACTIVE            (WILC_VMM_BASE + 040)
+#define WILC_VMM_TBL_STATUS            (WILC_VMM_BASE + 0x44)
+
+#define WILC_SPI_REG_BASE              0xe800
+#define WILC_SPI_CTL                   WILC_SPI_REG_BASE
+#define WILC_SPI_MASTER_DMA_ADDR       (WILC_SPI_REG_BASE + 0x4)
+#define WILC_SPI_MASTER_DMA_COUNT      (WILC_SPI_REG_BASE + 0x8)
+#define WILC_SPI_SLAVE_DMA_ADDR                (WILC_SPI_REG_BASE + 0xc)
+#define WILC_SPI_SLAVE_DMA_COUNT       (WILC_SPI_REG_BASE + 0x10)
+#define WILC_SPI_TX_MODE               (WILC_SPI_REG_BASE + 0x20)
+#define WILC_SPI_PROTOCOL_CONFIG       (WILC_SPI_REG_BASE + 0x24)
+#define WILC_SPI_INTR_CTL              (WILC_SPI_REG_BASE + 0x2c)
+#define WILC_SPI_INT_STATUS            (WILC_SPI_REG_BASE + 0x40)
+#define WILC_SPI_INT_CLEAR             (WILC_SPI_REG_BASE + 0x44)
+
+#define WILC_SPI_WAKEUP_REG            0x1
+#define WILC_SPI_WAKEUP_BIT            BIT(1)
+
+#define WILC_SPI_PROTOCOL_OFFSET       (WILC_SPI_PROTOCOL_CONFIG - \
+                                        WILC_SPI_REG_BASE)
+
+#define WILC_SPI_CLOCKLESS_ADDR_LIMIT  0x30
+
+/* Functions IO enables bits */
+#define WILC_SDIO_CCCR_IO_EN_FUNC1     BIT(1)
+
+/* Function/Interrupt enables bits */
+#define WILC_SDIO_CCCR_IEN_MASTER      BIT(0)
+#define WILC_SDIO_CCCR_IEN_FUNC1       BIT(1)
+
+/* Abort CCCR register bits */
+#define WILC_SDIO_CCCR_ABORT_RESET     BIT(3)
+
+/* Vendor specific CCCR registers */
+#define WILC_SDIO_WAKEUP_REG           0xf0
+#define WILC_SDIO_WAKEUP_BIT           BIT(0)
+
+#define WILC_SDIO_CLK_STATUS_REG       0xf1
+#define WILC_SDIO_CLK_STATUS_BIT       BIT(0)
+
+#define WILC_SDIO_INTERRUPT_DATA_SZ_REG        0xf2 /* Read size (2 bytes) */
+
+#define WILC_SDIO_VMM_TBL_CTRL_REG     0xf6
+#define WILC_SDIO_IRQ_FLAG_REG         0xf7
+#define WILC_SDIO_IRQ_CLEAR_FLAG_REG   0xf8
+
+#define WILC_SDIO_HOST_TO_FW_REG       0xfa
+#define WILC_SDIO_HOST_TO_FW_BIT       BIT(0)
+
+#define WILC_SDIO_FW_TO_HOST_REG       0xfc
+#define WILC_SDIO_FW_TO_HOST_BIT       BIT(0)
+
+/* Function 1 specific FBR register */
+#define WILC_SDIO_FBR_CSA_REG          0x10C /* CSA pointer (3 bytes) */
+#define WILC_SDIO_FBR_DATA_REG         0x10F
+
+#define WILC_SDIO_F1_DATA_REG          0x0
+#define WILC_SDIO_EXT_IRQ_FLAG_REG     0x4
+
+#define WILC_AHB_DATA_MEM_BASE         0x30000
+#define WILC_AHB_SHARE_MEM_BASE                0xd0000
+
+#define WILC_VMM_TBL_RX_SHADOW_BASE    WILC_AHB_SHARE_MEM_BASE
+#define WILC_VMM_TBL_RX_SHADOW_SIZE    256
+
+#define WILC_FW_HOST_COMM              0x13c0
+#define WILC_GP_REG_0                  0x149c
+#define WILC_GP_REG_1                  0x14a0
+
+#define WILC_HAVE_SDIO_IRQ_GPIO                BIT(0)
+#define WILC_HAVE_USE_PMU              BIT(1)
+#define WILC_HAVE_SLEEP_CLK_SRC_RTC    BIT(2)
+#define WILC_HAVE_SLEEP_CLK_SRC_XO     BIT(3)
+#define WILC_HAVE_EXT_PA_INV_TX_RX     BIT(4)
+#define WILC_HAVE_LEGACY_RF_SETTINGS   BIT(5)
+#define WILC_HAVE_XTAL_24              BIT(6)
+#define WILC_HAVE_DISABLE_WILC_UART    BIT(7)
+#define WILC_HAVE_USE_IRQ_AS_HOST_WAKE BIT(8)
+
+#define WILC_CORTUS_INTERRUPT_BASE     0x10A8
+#define WILC_CORTUS_INTERRUPT_1                (WILC_CORTUS_INTERRUPT_BASE + 0x4)
+#define WILC_CORTUS_INTERRUPT_2                (WILC_CORTUS_INTERRUPT_BASE + 0x8)
+
+/* tx control register 1 to 4 for RX */
+#define WILC_REG_4_TO_1_RX             0x1e1c
+
+/* tx control register 1 to 4 for TX Bank_0 */
+#define WILC_REG_4_TO_1_TX_BANK0       0x1e9c
+
+#define WILC_CORTUS_RESET_MUX_SEL      0x1118
+#define WILC_CORTUS_BOOT_REGISTER      0xc0000
+
+#define WILC_CORTUS_BOOT_FROM_IRAM     0x71
+
+#define WILC_1000_BASE_ID              0x100000
+
+#define WILC_1000_BASE_ID_2A           0x1002A0
+#define WILC_1000_BASE_ID_2A_REV1      (WILC_1000_BASE_ID_2A + 1)
+
+#define WILC_1000_BASE_ID_2B           0x1002B0
+#define WILC_1000_BASE_ID_2B_REV1      (WILC_1000_BASE_ID_2B + 1)
+#define WILC_1000_BASE_ID_2B_REV2      (WILC_1000_BASE_ID_2B + 2)
+
+#define WILC_CHIP_REV_FIELD            GENMASK(11, 0)
+
+/********************************************
+ *
+ *      Wlan Defines
+ *
+ ********************************************/
+#define WILC_CFG_PKT           1
+#define WILC_NET_PKT           0
+#define WILC_MGMT_PKT          2
+
+#define WILC_CFG_SET           1
+#define WILC_CFG_QUERY         0
+
+#define WILC_CFG_RSP           1
+#define WILC_CFG_RSP_STATUS    2
+#define WILC_CFG_RSP_SCAN      3
+
+#define WILC_ABORT_REQ_BIT             BIT(31)
+
+#define WILC_RX_BUFF_SIZE      (96 * 1024)
+#define WILC_TX_BUFF_SIZE      (64 * 1024)
+
+#define MODALIAS               "WILC_SPI"
+
+#define WILC_PKT_HDR_CONFIG_FIELD      BIT(31)
+#define WILC_PKT_HDR_OFFSET_FIELD      GENMASK(30, 22)
+#define WILC_PKT_HDR_TOTAL_LEN_FIELD   GENMASK(21, 11)
+#define WILC_PKT_HDR_LEN_FIELD         GENMASK(10, 0)
+
+#define WILC_INTERRUPT_DATA_SIZE       GENMASK(14, 0)
+
+#define WILC_VMM_BUFFER_SIZE           GENMASK(9, 0)
+
+#define WILC_VMM_HDR_TYPE              BIT(31)
+#define WILC_VMM_HDR_MGMT_FIELD                BIT(30)
+#define WILC_VMM_HDR_PKT_SIZE          GENMASK(29, 15)
+#define WILC_VMM_HDR_BUFF_SIZE         GENMASK(14, 0)
+
+#define WILC_VMM_ENTRY_COUNT           GENMASK(8, 3)
+#define WILC_VMM_ENTRY_AVAILABLE       BIT(2)
+/*******************************************/
+/*        E0 and later Interrupt flags.    */
+/*******************************************/
+/*******************************************/
+/*        E0 and later Interrupt flags.    */
+/*           IRQ Status word               */
+/* 15:0 = DMA count in words.              */
+/* 16: INT0 flag                           */
+/* 17: INT1 flag                           */
+/* 18: INT2 flag                           */
+/* 19: INT3 flag                           */
+/* 20: INT4 flag                           */
+/* 21: INT5 flag                           */
+/*******************************************/
+#define IRG_FLAGS_OFFSET       16
+#define IRQ_DMA_WD_CNT_MASK    GENMASK(IRG_FLAGS_OFFSET - 1, 0)
+#define INT_0                  BIT(IRG_FLAGS_OFFSET)
+#define INT_1                  BIT(IRG_FLAGS_OFFSET + 1)
+#define INT_2                  BIT(IRG_FLAGS_OFFSET + 2)
+#define INT_3                  BIT(IRG_FLAGS_OFFSET + 3)
+#define INT_4                  BIT(IRG_FLAGS_OFFSET + 4)
+#define INT_5                  BIT(IRG_FLAGS_OFFSET + 5)
+#define MAX_NUM_INT            5
+#define IRG_FLAGS_MASK         GENMASK(IRG_FLAGS_OFFSET + MAX_NUM_INT, \
+                                       IRG_FLAGS_OFFSET)
+
+/*******************************************/
+/*        E0 and later Interrupt flags.    */
+/*           IRQ Clear word                */
+/* 0: Clear INT0                           */
+/* 1: Clear INT1                           */
+/* 2: Clear INT2                           */
+/* 3: Clear INT3                           */
+/* 4: Clear INT4                           */
+/* 5: Clear INT5                           */
+/* 6: Select VMM table 1                   */
+/* 7: Select VMM table 2                   */
+/* 8: Enable VMM                           */
+/*******************************************/
+#define CLR_INT0               BIT(0)
+#define CLR_INT1               BIT(1)
+#define CLR_INT2               BIT(2)
+#define CLR_INT3               BIT(3)
+#define CLR_INT4               BIT(4)
+#define CLR_INT5               BIT(5)
+#define SEL_VMM_TBL0           BIT(6)
+#define SEL_VMM_TBL1           BIT(7)
+#define EN_VMM                 BIT(8)
+
+#define DATA_INT_EXT           INT_0
+#define ALL_INT_EXT            DATA_INT_EXT
+#define NUM_INT_EXT            1
+#define UNHANDLED_IRQ_MASK     GENMASK(MAX_NUM_INT - 1, NUM_INT_EXT)
+
+#define DATA_INT_CLR           CLR_INT0
+
+#define ENABLE_RX_VMM          (SEL_VMM_TBL1 | EN_VMM)
+#define ENABLE_TX_VMM          (SEL_VMM_TBL0 | EN_VMM)
+/* time for expiring the completion of cfg packets */
+#define WILC_CFG_PKTS_TIMEOUT  msecs_to_jiffies(2000)
+
+#define IS_MANAGMEMENT         0x100
+#define IS_MANAGMEMENT_CALLBACK        0x080
+#define IS_MGMT_STATUS_SUCCES  0x040
+
+#define WILC_WID_TYPE          GENMASK(15, 12)
+#define WILC_VMM_ENTRY_FULL_RETRY      1
+/********************************************
+ *
+ *      Tx/Rx Queue Structure
+ *
+ ********************************************/
+
+struct txq_entry_t {
+       struct list_head list;
+       int type;
+       int ack_idx;
+       u8 *buffer;
+       int buffer_size;
+       void *priv;
+       int status;
+       struct wilc_vif *vif;
+       void (*tx_complete_func)(void *priv, int status);
+};
+
+struct rxq_entry_t {
+       struct list_head list;
+       u8 *buffer;
+       int buffer_size;
+};
+
+/********************************************
+ *
+ *      Host IF Structure
+ *
+ ********************************************/
+struct wilc;
+struct wilc_hif_func {
+       int (*hif_init)(struct wilc *wilc, bool resume);
+       int (*hif_deinit)(struct wilc *wilc);
+       int (*hif_read_reg)(struct wilc *wilc, u32 addr, u32 *data);
+       int (*hif_write_reg)(struct wilc *wilc, u32 addr, u32 data);
+       int (*hif_block_rx)(struct wilc *wilc, u32 addr, u8 *buf, u32 size);
+       int (*hif_block_tx)(struct wilc *wilc, u32 addr, u8 *buf, u32 size);
+       int (*hif_read_int)(struct wilc *wilc, u32 *int_status);
+       int (*hif_clear_int_ext)(struct wilc *wilc, u32 val);
+       int (*hif_read_size)(struct wilc *wilc, u32 *size);
+       int (*hif_block_tx_ext)(struct wilc *wilc, u32 addr, u8 *buf, u32 size);
+       int (*hif_block_rx_ext)(struct wilc *wilc, u32 addr, u8 *buf, u32 size);
+       int (*hif_sync_ext)(struct wilc *wilc, int nint);
+       int (*enable_interrupt)(struct wilc *nic);
+       void (*disable_interrupt)(struct wilc *nic);
+};
+
+#define WILC_MAX_CFG_FRAME_SIZE                1468
+
+struct tx_complete_data {
+       int size;
+       void *buff;
+       struct sk_buff *skb;
+};
+
+struct wilc_cfg_cmd_hdr {
+       u8 cmd_type;
+       u8 seq_no;
+       __le16 total_len;
+       __le32 driver_handler;
+};
+
+struct wilc_cfg_frame {
+       struct wilc_cfg_cmd_hdr hdr;
+       u8 frame[WILC_MAX_CFG_FRAME_SIZE];
+};
+
+struct wilc_cfg_rsp {
+       u8 type;
+       u8 seq_no;
+};
+
+struct wilc;
+struct wilc_vif;
+
+int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
+                               u32 buffer_size);
+int wilc_wlan_start(struct wilc *wilc);
+int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif);
+int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
+                             u32 buffer_size,
+                             void (*tx_complete_fn)(void *, int));
+int wilc_wlan_handle_txq(struct wilc *wl, u32 *txq_count);
+void wilc_handle_isr(struct wilc *wilc);
+void wilc_wlan_cleanup(struct net_device *dev);
+int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
+                     u32 buffer_size, int commit, u32 drv_handler);
+int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
+                     u32 drv_handler);
+int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
+                              u32 buffer_size, void (*func)(void *, int));
+void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value);
+int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc);
+netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
+
+void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size);
+void host_wakeup_notify(struct wilc *wilc);
+void host_sleep_notify(struct wilc *wilc);
+void chip_allow_sleep(struct wilc *wilc);
+void chip_wakeup(struct wilc *wilc);
+int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
+                        u32 count);
+int wilc_wlan_init(struct net_device *dev);
+u32 wilc_get_chipid(struct wilc *wilc, bool update);
+#endif
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
new file mode 100644 (file)
index 0000000..fe2a7ed
--- /dev/null
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#include <linux/bitfield.h>
+#include "wlan_if.h"
+#include "wlan.h"
+#include "wlan_cfg.h"
+#include "netdev.h"
+
+enum cfg_cmd_type {
+       CFG_BYTE_CMD    = 0,
+       CFG_HWORD_CMD   = 1,
+       CFG_WORD_CMD    = 2,
+       CFG_STR_CMD     = 3,
+       CFG_BIN_CMD     = 4
+};
+
+static const struct wilc_cfg_byte g_cfg_byte[] = {
+       {WID_STATUS, 0},
+       {WID_RSSI, 0},
+       {WID_LINKSPEED, 0},
+       {WID_NIL, 0}
+};
+
+static const struct wilc_cfg_hword g_cfg_hword[] = {
+       {WID_NIL, 0}
+};
+
+static const struct wilc_cfg_word g_cfg_word[] = {
+       {WID_FAILED_COUNT, 0},
+       {WID_RECEIVED_FRAGMENT_COUNT, 0},
+       {WID_SUCCESS_FRAME_COUNT, 0},
+       {WID_GET_INACTIVE_TIME, 0},
+       {WID_NIL, 0}
+
+};
+
+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 WILC_RESP_MSG_TYPE_CONFIG_REPLY                'R'
+#define WILC_RESP_MSG_TYPE_STATUS_INFO         'I'
+#define WILC_RESP_MSG_TYPE_NETWORK_INFO                'N'
+#define WILC_RESP_MSG_TYPE_SCAN_COMPLETE       'S'
+
+/********************************************
+ *
+ *      Configuration Functions
+ *
+ ********************************************/
+
+static int wilc_wlan_cfg_set_byte(u8 *frame, u32 offset, u16 id, u8 val8)
+{
+       if ((offset + 4) >= WILC_MAX_CFG_FRAME_SIZE)
+               return 0;
+
+       put_unaligned_le16(id, &frame[offset]);
+       put_unaligned_le16(1, &frame[offset + 2]);
+       frame[offset + 4] = val8;
+       return 5;
+}
+
+static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, u16 id, u16 val16)
+{
+       if ((offset + 5) >= WILC_MAX_CFG_FRAME_SIZE)
+               return 0;
+
+       put_unaligned_le16(id, &frame[offset]);
+       put_unaligned_le16(2, &frame[offset + 2]);
+       put_unaligned_le16(val16, &frame[offset + 4]);
+
+       return 6;
+}
+
+static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32)
+{
+       if ((offset + 7) >= WILC_MAX_CFG_FRAME_SIZE)
+               return 0;
+
+       put_unaligned_le16(id, &frame[offset]);
+       put_unaligned_le16(4, &frame[offset + 2]);
+       put_unaligned_le32(val32, &frame[offset + 4]);
+
+       return 8;
+}
+
+static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str,
+                                u32 size)
+{
+       if ((offset + size + 4) >= WILC_MAX_CFG_FRAME_SIZE)
+               return 0;
+
+       put_unaligned_le16(id, &frame[offset]);
+       put_unaligned_le16(size, &frame[offset + 2]);
+       if (str && size != 0)
+               memcpy(&frame[offset + 4], str, size);
+
+       return (size + 4);
+}
+
+static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size)
+{
+       u32 i;
+       u8 checksum = 0;
+
+       if ((offset + size + 5) >= WILC_MAX_CFG_FRAME_SIZE)
+               return 0;
+
+       put_unaligned_le16(id, &frame[offset]);
+       put_unaligned_le16(size, &frame[offset + 2]);
+
+       if ((b) && size != 0) {
+               memcpy(&frame[offset + 4], b, size);
+               for (i = 0; i < size; i++)
+                       checksum += frame[offset + i + 4];
+       }
+
+       frame[offset + size + 4] = checksum;
+
+       return (size + 5);
+}
+
+/********************************************
+ *
+ *      Configuration Response Functions
+ *
+ ********************************************/
+
+static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
+{
+       u16 wid;
+       u32 len = 0, i = 0;
+       struct wilc_cfg *cfg = &wl->cfg;
+
+       while (size > 0) {
+               i = 0;
+               wid = get_unaligned_le16(info);
+
+               switch (FIELD_GET(WILC_WID_TYPE, wid)) {
+               case WID_CHAR:
+                       while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
+                               i++;
+
+                       if (cfg->b[i].id == wid)
+                               cfg->b[i].val = info[4];
+
+                       len = 3;
+                       break;
+
+               case WID_SHORT:
+                       while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
+                               i++;
+
+                       if (cfg->hw[i].id == wid)
+                               cfg->hw[i].val = get_unaligned_le16(&info[4]);
+
+                       len = 4;
+                       break;
+
+               case WID_INT:
+                       while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
+                               i++;
+
+                       if (cfg->w[i].id == wid)
+                               cfg->w[i].val = get_unaligned_le32(&info[4]);
+
+                       len = 6;
+                       break;
+
+               case WID_STR:
+                       while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
+                               i++;
+
+                       if (cfg->s[i].id == wid)
+                               memcpy(cfg->s[i].str, &info[2], info[2] + 2);
+
+                       len = 2 + info[2];
+                       break;
+
+               default:
+                       break;
+               }
+               size -= (2 + len);
+               info += (2 + len);
+       }
+}
+
+static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info)
+{
+       u32 wid, len;
+
+       wid = get_unaligned_le16(info);
+
+       len = info[2];
+
+       if (len == 1 && wid == WID_STATUS) {
+               int i = 0;
+
+               while (wl->cfg.b[i].id != WID_NIL &&
+                      wl->cfg.b[i].id != wid)
+                       i++;
+
+               if (wl->cfg.b[i].id == wid)
+                       wl->cfg.b[i].val = info[3];
+       }
+}
+
+/********************************************
+ *
+ *      Configuration Exported Functions
+ *
+ ********************************************/
+
+int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size)
+{
+       u8 type = FIELD_GET(WILC_WID_TYPE, id);
+       int ret = 0;
+
+       switch (type) {
+       case CFG_BYTE_CMD:
+               if (size >= 1)
+                       ret = wilc_wlan_cfg_set_byte(frame, offset, id, *buf);
+               break;
+
+       case CFG_HWORD_CMD:
+               if (size >= 2)
+                       ret = wilc_wlan_cfg_set_hword(frame, offset, id,
+                                                     *((u16 *)buf));
+               break;
+
+       case CFG_WORD_CMD:
+               if (size >= 4)
+                       ret = wilc_wlan_cfg_set_word(frame, offset, id,
+                                                    *((u32 *)buf));
+               break;
+
+       case CFG_STR_CMD:
+               ret = wilc_wlan_cfg_set_str(frame, offset, id, buf, size);
+               break;
+
+       case CFG_BIN_CMD:
+               ret = wilc_wlan_cfg_set_bin(frame, offset, id, buf, size);
+               break;
+       }
+
+       return ret;
+}
+
+int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id)
+{
+       if ((offset + 2) >= WILC_MAX_CFG_FRAME_SIZE)
+               return 0;
+
+       put_unaligned_le16(id, &frame[offset]);
+
+       return 2;
+}
+
+int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer,
+                         u32 buffer_size)
+{
+       u8 type = FIELD_GET(WILC_WID_TYPE, wid);
+       int i, ret = 0;
+       struct wilc_cfg *cfg = &wl->cfg;
+
+       i = 0;
+       if (type == CFG_BYTE_CMD) {
+               while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
+                       i++;
+
+               if (cfg->b[i].id == wid) {
+                       memcpy(buffer, &cfg->b[i].val, 1);
+                       ret = 1;
+               }
+       } else if (type == CFG_HWORD_CMD) {
+               while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
+                       i++;
+
+               if (cfg->hw[i].id == wid) {
+                       memcpy(buffer, &cfg->hw[i].val, 2);
+                       ret = 2;
+               }
+       } else if (type == CFG_WORD_CMD) {
+               while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
+                       i++;
+
+               if (cfg->w[i].id == wid) {
+                       memcpy(buffer, &cfg->w[i].val, 4);
+                       ret = 4;
+               }
+       } else if (type == CFG_STR_CMD) {
+               while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
+                       i++;
+
+               if (cfg->s[i].id == wid) {
+                       u16 size = get_unaligned_le16(cfg->s[i].str);
+
+                       if (buffer_size >= size) {
+                               memcpy(buffer, &cfg->s[i].str[2], size);
+                               ret = size;
+                       }
+               }
+       }
+       return ret;
+}
+
+void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
+                              struct wilc_cfg_rsp *rsp)
+{
+       u8 msg_type;
+       u8 msg_id;
+
+       msg_type = frame[0];
+       msg_id = frame[1];      /* seq no */
+       frame += 4;
+       size -= 4;
+       rsp->type = 0;
+
+       switch (msg_type) {
+       case WILC_RESP_MSG_TYPE_CONFIG_REPLY:
+               wilc_wlan_parse_response_frame(wilc, frame, size);
+               rsp->type = WILC_CFG_RSP;
+               rsp->seq_no = msg_id;
+               break;
+
+       case WILC_RESP_MSG_TYPE_STATUS_INFO:
+               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 */
+               wilc_gnrl_async_info_received(wilc, frame - 4, size + 4);
+               break;
+
+       case WILC_RESP_MSG_TYPE_NETWORK_INFO:
+               wilc_network_info_received(wilc, frame - 4, size + 4);
+               break;
+
+       case WILC_RESP_MSG_TYPE_SCAN_COMPLETE:
+               wilc_scan_complete_received(wilc, frame - 4, size + 4);
+               break;
+
+       default:
+               rsp->seq_no = msg_id;
+               break;
+       }
+}
+
+int wilc_wlan_cfg_init(struct wilc *wl)
+{
+       struct wilc_cfg_str_vals *str_vals;
+       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;
+
+       str_vals = kzalloc(sizeof(*str_vals), GFP_KERNEL);
+       if (!str_vals)
+               goto out_s;
+
+       wl->cfg.str_vals = str_vals;
+       /* store the string cfg parameters */
+       wl->cfg.s[i].id = WID_FIRMWARE_VERSION;
+       wl->cfg.s[i].str = str_vals->firmware_version;
+       i++;
+       wl->cfg.s[i].id = WID_MAC_ADDR;
+       wl->cfg.s[i].str = str_vals->mac_address;
+       i++;
+       wl->cfg.s[i].id = WID_ASSOC_RES_INFO;
+       wl->cfg.s[i].str = str_vals->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)
+{
+       kfree(wl->cfg.b);
+       kfree(wl->cfg.hw);
+       kfree(wl->cfg.w);
+       kfree(wl->cfg.s);
+       kfree(wl->cfg.str_vals);
+}
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
new file mode 100644 (file)
index 0000000..614c567
--- /dev/null
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#ifndef WILC_WLAN_CFG_H
+#define WILC_WLAN_CFG_H
+
+struct wilc_cfg_byte {
+       u16 id;
+       u8 val;
+};
+
+struct wilc_cfg_hword {
+       u16 id;
+       u16 val;
+};
+
+struct wilc_cfg_word {
+       u16 id;
+       u32 val;
+};
+
+struct wilc_cfg_str {
+       u16 id;
+       u8 *str;
+};
+
+struct wilc_cfg_str_vals {
+       u8 mac_address[7];
+       u8 firmware_version[129];
+       u8 assoc_rsp[256];
+};
+
+struct wilc_cfg {
+       struct wilc_cfg_byte *b;
+       struct wilc_cfg_hword *hw;
+       struct wilc_cfg_word *w;
+       struct wilc_cfg_str *s;
+       struct wilc_cfg_str_vals *str_vals;
+};
+
+struct wilc;
+int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size);
+int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id);
+int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer,
+                         u32 buffer_size);
+void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
+                              struct wilc_cfg_rsp *rsp);
+int wilc_wlan_cfg_init(struct wilc *wl);
+void wilc_wlan_cfg_deinit(struct wilc *wl);
+
+#endif
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan_if.h b/drivers/net/wireless/microchip/wilc1000/wlan_if.h
new file mode 100644 (file)
index 0000000..f85fd57
--- /dev/null
@@ -0,0 +1,803 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#ifndef WILC_WLAN_IF_H
+#define WILC_WLAN_IF_H
+
+#include <linux/netdevice.h>
+#include "fw.h"
+
+/********************************************
+ *
+ *      Wlan Configuration ID
+ *
+ ********************************************/
+
+enum bss_types {
+       WILC_FW_BSS_TYPE_INFRA = 0,
+       WILC_FW_BSS_TYPE_INDEPENDENT,
+       WILC_FW_BSS_TYPE_AP,
+};
+
+enum {
+       WILC_FW_OPER_MODE_B_ONLY = 0,    /* 1, 2 M, otherwise 5, 11 M */
+       WILC_FW_OPER_MODE_G_ONLY,        /* 6,12,24 otherwise 9,18,36,48,54 */
+       WILC_FW_OPER_MODE_G_MIXED_11B_1, /* 1,2,5.5,11 otherwise all on */
+       WILC_FW_OPER_MODE_G_MIXED_11B_2, /* 1,2,5,11,6,12,24 otherwise all on */
+};
+
+enum {
+       WILC_FW_PREAMBLE_SHORT = 0,     /* Short Preamble */
+       WILC_FW_PREAMBLE_LONG = 1,      /* Long Preamble */
+       WILC_FW_PREAMBLE_AUTO = 2,      /* Auto Preamble Selection */
+};
+
+enum {
+       WILC_FW_PASSIVE_SCAN = 0,
+       WILC_FW_ACTIVE_SCAN = 1,
+};
+
+enum {
+       WILC_FW_NO_POWERSAVE = 0,
+       WILC_FW_MIN_FAST_PS = 1,
+       WILC_FW_MAX_FAST_PS = 2,
+       WILC_FW_MIN_PSPOLL_PS = 3,
+       WILC_FW_MAX_PSPOLL_PS = 4
+};
+
+enum chip_ps_states {
+       WILC_CHIP_WAKEDUP = 0,
+       WILC_CHIP_SLEEPING_AUTO = 1,
+       WILC_CHIP_SLEEPING_MANUAL = 2
+};
+
+enum bus_acquire {
+       WILC_BUS_ACQUIRE_ONLY = 0,
+       WILC_BUS_ACQUIRE_AND_WAKEUP = 1,
+};
+
+enum bus_release {
+       WILC_BUS_RELEASE_ONLY = 0,
+       WILC_BUS_RELEASE_ALLOW_SLEEP = 1,
+};
+
+enum {
+       WILC_FW_NO_ENCRYPT = 0,
+       WILC_FW_ENCRYPT_ENABLED = BIT(0),
+       WILC_FW_WEP = BIT(1),
+       WILC_FW_WEP_EXTENDED = BIT(2),
+       WILC_FW_WPA = BIT(3),
+       WILC_FW_WPA2 = BIT(4),
+       WILC_FW_AES = BIT(5),
+       WILC_FW_TKIP = BIT(6)
+};
+
+enum {
+       WILC_FW_SEC_NO = WILC_FW_NO_ENCRYPT,
+       WILC_FW_SEC_WEP = WILC_FW_WEP | WILC_FW_ENCRYPT_ENABLED,
+       WILC_FW_SEC_WEP_EXTENDED = WILC_FW_WEP_EXTENDED | WILC_FW_SEC_WEP,
+       WILC_FW_SEC_WPA = WILC_FW_WPA | WILC_FW_ENCRYPT_ENABLED,
+       WILC_FW_SEC_WPA_AES = WILC_FW_AES | WILC_FW_SEC_WPA,
+       WILC_FW_SEC_WPA_TKIP = WILC_FW_TKIP | WILC_FW_SEC_WPA,
+       WILC_FW_SEC_WPA2 = WILC_FW_WPA2 | WILC_FW_ENCRYPT_ENABLED,
+       WILC_FW_SEC_WPA2_AES = WILC_FW_AES | WILC_FW_SEC_WPA2,
+       WILC_FW_SEC_WPA2_TKIP = WILC_FW_TKIP | WILC_FW_SEC_WPA2
+};
+
+enum authtype {
+       WILC_FW_AUTH_OPEN_SYSTEM = 1,
+       WILC_FW_AUTH_SHARED_KEY = 2,
+       WILC_FW_AUTH_ANY = 3,
+       WILC_FW_AUTH_IEEE8021 = 5
+};
+
+enum site_survey {
+       WILC_FW_SITE_SURVEY_1CH = 0,
+       WILC_FW_SITE_SURVEY_ALL_CH = 1,
+       WILC_FW_SITE_SURVEY_OFF = 2
+};
+
+enum {
+       WILC_FW_ACK_POLICY_NORMAL = 0,
+       WILC_FW_ACK_NO_POLICY,
+};
+
+enum {
+       WILC_FW_REKEY_POLICY_DISABLE = 1,
+       WILC_FW_REKEY_POLICY_TIME_BASE,
+       WILC_FW_REKEY_POLICY_PKT_BASE,
+       WILC_FW_REKEY_POLICY_TIME_PKT_BASE
+};
+
+enum {
+       WILC_FW_FILTER_NO = 0x00,
+       WILC_FW_FILTER_AP_ONLY = 0x01,
+       WILC_FW_FILTER_STA_ONLY = 0x02
+};
+
+enum {
+       WILC_FW_11N_PROT_AUTO = 0,      /* Auto */
+       WILC_FW_11N_NO_PROT,            /* Do not use any protection */
+       WILC_FW_11N_PROT_ERP,           /* Protect all ERP frame exchanges */
+       WILC_FW_11N_PROT_HT,            /* Protect all HT frame exchanges  */
+       WILC_FW_11N_PROT_GF             /* Protect all GF frame exchanges  */
+};
+
+enum {
+       WILC_FW_ERP_PROT_SELF_CTS,
+       WILC_FW_ERP_PROT_RTS_CTS,
+};
+
+enum {
+       WILC_FW_11N_OP_MODE_HT_MIXED = 1,
+       WILC_FW_11N_OP_MODE_HT_ONLY_20MHZ,
+       WILC_FW_11N_OP_MODE_HT_ONLY_20_40MHZ,
+};
+
+enum {
+       WILC_FW_OBBS_NONHT_NO_DETECT = 0,
+       WILC_FW_OBBS_NONHT_DETECT_ONLY = 1,
+       WILC_FW_OBBS_NONHT_DETECT_PROTECT = 2,
+       WILC_FW_OBBS_NONHT_DETECT_PROTECT_REPORT = 3,
+};
+
+enum {
+       WILC_FW_HT_PROT_RTS_CTS_NONHT = 0,  /* RTS-CTS at non-HT rate */
+       WILC_FW_HT_PROT_FIRST_FRAME_NONHT,  /* First frame at non-HT rate */
+       WILC_FW_HT_PROT_LSIG_TXOP,          /* LSIG TXOP Protection */
+       WILC_FW_HT_PROT_FIRST_FRAME_MIXED,  /* First frame at Mixed format */
+};
+
+enum {
+       WILC_FW_SMPS_MODE_STATIC = 1,
+       WILC_FW_SMPS_MODE_DYNAMIC = 2,
+       WILC_FW_SMPS_MODE_MIMO = 3,     /* power save disable */
+};
+
+enum {
+       WILC_FW_TX_RATE_AUTO = 0,
+       WILC_FW_TX_RATE_MBPS_1 = 1,
+       WILC_FW_TX_RATE_MBPS_2 = 2,
+       WILC_FW_TX_RATE_MBPS_5_5 = 5,
+       WILC_FW_TX_RATE_MBPS_11 = 11,
+       WILC_FW_TX_RATE_MBPS_6 = 6,
+       WILC_FW_TX_RATE_MBPS_9 = 9,
+       WILC_FW_TX_RATE_MBPS_12 = 12,
+       WILC_FW_TX_RATE_MBPS_18 = 18,
+       WILC_FW_TX_RATE_MBPS_24 = 24,
+       WILC_FW_TX_RATE_MBPS_36 = 36,
+       WILC_FW_TX_RATE_MBPS_48 = 48,
+       WILC_FW_TX_RATE_MBPS_54 = 54
+};
+
+enum {
+       WILC_FW_DEFAULT_SCAN = 0,
+       WILC_FW_USER_SCAN = BIT(0),
+       WILC_FW_OBSS_PERIODIC_SCAN = BIT(1),
+       WILC_FW_OBSS_ONETIME_SCAN = BIT(2)
+};
+
+enum {
+       WILC_FW_ACTION_FRM_IDX = 0,
+       WILC_FW_PROBE_REQ_IDX = 1
+};
+
+enum wid_type {
+       WID_CHAR                = 0,
+       WID_SHORT               = 1,
+       WID_INT                 = 2,
+       WID_STR                 = 3,
+       WID_BIN_DATA            = 4,
+       WID_BIN                 = 5,
+};
+
+struct wid {
+       u16 id;
+       enum wid_type type;
+       s32 size;
+       s8 *val;
+};
+
+enum {
+       WID_NIL                         = 0xffff,
+
+       /*
+        *  BSS Type
+        *  -----------------------------------------------------------
+        *  Configuration : Infrastructure   Independent   Access Point
+        *  Values to set :         0               1            2
+        *  -----------------------------------------------------------
+        */
+       WID_BSS_TYPE                    = 0x0000,
+
+       /*
+        *  Transmit Rate
+        *  -----------------------------------------------------------
+        *  Configuration : 1  2  5.5  11  6  9  12  18  24  36  48  54
+        *  Values to set : 1  2    5  11  6  9  12  18  24  36  48  54
+        *  -----------------------------------------------------------
+        */
+       WID_CURRENT_TX_RATE             = 0x0001,
+
+       /*
+        *  Channel
+        *  -----------------------------------------------------------
+        *  Configuration(g) : 1  2  3  4  5  6  7  8  9 10 11 12 13 14
+        *  Values to set    : 1  2  3  4  5  6  7  8  9 10 11 12 13 14
+        *  -----------------------------------------------------------
+        */
+       WID_CURRENT_CHANNEL             = 0x0002,
+
+       /*
+        *  Preamble
+        *  -----------------------------------------------------------
+        *  Configuration :    short    long      Auto
+        *  Values to set :       0       1         2
+        *  -----------------------------------------------------------
+        */
+       WID_PREAMBLE                    = 0x0003,
+
+       /*
+        * 11g operating mode (ignored if 11g not present)
+        *  -----------------------------------------------------------
+        *  Configuration :   HighPerf  Compat(RSet #1) Compat(RSet #2)
+        *  Values to set :          1               2               3
+        *  -----------------------------------------------------------
+        */
+       WID_11G_OPERATING_MODE          = 0x0004,
+
+       /*
+        *  Mac status (response only)
+        *  -----------------------------------------------------------
+        *  Configuration :   disconnect  connect
+        *  Values to get :          0       1
+        *  -----------------------------------------------------------
+        */
+       WID_STATUS                      = 0x0005,
+
+       /*
+        *  Scan type
+        *  -----------------------------------------------------------
+        *  Configuration :   Passive Scanning   Active Scanning
+        *  Values to set :                  0                 1
+        *  -----------------------------------------------------------
+        */
+       WID_SCAN_TYPE                   = 0x0007,
+
+       /*
+        *  Key Id (WEP default key Id)
+        *  -----------------------------------------------------------
+        *  Configuration :   Any value between 0 to 3
+        *  Values to set :   Same value. Default is 0
+        *  -----------------------------------------------------------
+        */
+       WID_KEY_ID                      = 0x0009,
+
+       /*
+        *  QoS Enable
+        *  -----------------------------------------------------------
+        *  Configuration :   QoS Disable   WMM Enable
+        *  Values to set :   0             1
+        *  -----------------------------------------------------------
+        */
+       WID_QOS_ENABLE                  = 0x000A,
+
+       /*
+        *  Power Management
+        *  -----------------------------------------------------------
+        *  Configuration : NO_POWERSAVE MIN_POWERSAVE MAX_POWERSAVE
+        *  Values to set : 0            1             2
+        *  -----------------------------------------------------------
+        */
+       WID_POWER_MANAGEMENT            = 0x000B,
+
+       /*
+        *  WEP/802 11I Configuration
+        *  -----------------------------------------------------------
+        *  Configuration:Disable WP40 WP104 WPA-AES WPA-TKIP RSN-AES RSN-TKIP
+        *  Values (0x)  :   00     03   07     29       49       31      51
+        *  Configuration:WPA-AES+TKIP RSN-AES+TKIP
+        *  Values (0x)  :      69        71
+        *  -----------------------------------------------------------
+        */
+       WID_11I_MODE                    = 0x000C,
+
+       /*
+        *  WEP Configuration: Used in BSS STA mode only when WEP is enabled
+        *  -----------------------------------------------------------
+        *  Configuration : Open System Shared Key Any Type | 802.1x Auth
+        *  Values (0x)   :    01             02         03 |    BIT2
+        *  -----------------------------------------------------------
+        */
+       WID_AUTH_TYPE                   = 0x000D,
+
+       /*
+        *  Site Survey Type
+        *  -----------------------------------------------------------
+        *  Configuration       :  Values to set
+        *  Survey 1 Channel    :  0
+        *  survey all Channels :  1
+        *  Disable Site Survey :  2
+        *  -----------------------------------------------------------
+        */
+       WID_SITE_SURVEY                 = 0x000E,
+
+       /*
+        *  Listen Interval
+        *  -----------------------------------------------------------
+        *  Configuration :   Any value between 1 to 255
+        *  Values to set :   Same value. Default is 3
+        *  -----------------------------------------------------------
+        */
+       WID_LISTEN_INTERVAL             = 0x000F,
+
+       /*
+        *  DTIM Period
+        *  -----------------------------------------------------------
+        *  Configuration :   Any value between 1 to 255
+        *  Values to set :   Same value. Default is 3
+        *  -----------------------------------------------------------
+        */
+       WID_DTIM_PERIOD                 = 0x0010,
+
+       /*
+        *  ACK Policy
+        *  -----------------------------------------------------------
+        *  Configuration :   Normal Ack            No Ack
+        *  Values to set :       0                   1
+        *  -----------------------------------------------------------
+        */
+       WID_ACK_POLICY                  = 0x0011,
+
+       /*
+        *  Reset MAC (Set only)
+        *  -----------------------------------------------------------
+        *  Configuration :   Don't Reset       Reset   No Request
+        *  Values to set :       0               1         2
+        *  -----------------------------------------------------------
+        */
+       WID_RESET                       = 0x0012,
+
+       /*
+        *  Broadcast SSID Option: Setting this will adhere to "" SSID element
+        *  -----------------------------------------------------------
+        *  Configuration :   Enable             Disable
+        *  Values to set :   1                  0
+        *  -----------------------------------------------------------
+        */
+       WID_BCAST_SSID                  = 0x0015,
+
+       /*
+        *  Disconnect (Station)
+        *  -----------------------------------------------------------
+        *  Configuration :   Association ID
+        *  Values to set :   Association ID
+        *  -----------------------------------------------------------
+        */
+       WID_DISCONNECT                  = 0x0016,
+
+       /*
+        *  11a Tx Power Level
+        *  -----------------------------------------------------------
+        *  Configuration : Sets TX Power (Higher the value greater the power)
+        *  Values to set : Any value between 0 and 63 (inclusive Default 48)
+        *  -----------------------------------------------------------
+        */
+       WID_TX_POWER_LEVEL_11A          = 0x0018,
+
+       /*
+        *  Group Key Update Policy Selection
+        *  -----------------------------------------------------------
+        *  Configuration : Disabled timeBased packetBased timePacketBased
+        *  Values to set :   1            2          3              4
+        *  -----------------------------------------------------------
+        */
+       WID_REKEY_POLICY                = 0x0019,
+
+       /*
+        *  Allow Short Slot
+        *  -----------------------------------------------------------
+        *  Configuration : Disallow Short Slot      Allow Short Slot
+        *          (Enable Only Long Slot) (Enable Short Slot if applicable)
+        *  Values to set :    0         1
+        *  -----------------------------------------------------------
+        */
+       WID_SHORT_SLOT_ALLOWED          = 0x001A,
+
+       WID_PHY_ACTIVE_REG              = 0x001B,
+
+       /*
+        *  11b Tx Power Level
+        *  -----------------------------------------------------------
+        *  Configuration : Sets TX Power (Higher the value greater the power)
+        *  Values to set : Any value between 0 and 63 (inclusive Default 48)
+        *  -----------------------------------------------------------
+        */
+       WID_TX_POWER_LEVEL_11B          = 0x001D,
+
+       /*
+        *  Scan Request
+        *  -----------------------------------------------------------
+        *  Configuration : Request default scan
+        *  Values to set : 0
+        *  -----------------------------------------------------------
+        */
+       WID_START_SCAN_REQ              = 0x001E,
+
+       /*
+        *  Rssi (get only)
+        *  -----------------------------------------------------------
+        *  Configuration :
+        *  Values to get : Rssi value
+        *  -----------------------------------------------------------
+        */
+       WID_RSSI                        = 0x001F,
+
+       /*
+        * Join Request
+        *  -----------------------------------------------------------
+        *  Configuration : Request to join
+        *  Values to set : index of scan result
+        *  -----------------------------------------------------------
+        */
+       WID_JOIN_REQ                    = 0x0020,
+
+       WID_LINKSPEED                   = 0x0026,
+
+       /*
+        *  Enable User Control of TX Power
+        *  -----------------------------------------------------------
+        *  Configuration : Disable                  Enable
+        *  Values to set :    0                       1
+        *  -----------------------------------------------------------
+        */
+       WID_USER_CONTROL_ON_TX_POWER    = 0x0027,
+
+       WID_MEMORY_ACCESS_8BIT          = 0x0029,
+
+       /*
+        *  Enable Auto RX Sensitivity feature
+        *  -----------------------------------------------------------
+        *  Configuration : Disable                  Enable
+        *  Values to set :    0                       1
+        *  -----------------------------------------------------------
+        */
+       WID_AUTO_RX_SENSITIVITY         = 0x0032,
+
+       /*
+        *  Receive Buffer Based Ack
+        *  -----------------------------------------------------------
+        *  Configuration : Disable                  Enable
+        *  Values to set :    0                       1
+        *  -----------------------------------------------------------
+        */
+       WID_DATAFLOW_CONTROL            = 0x0033,
+
+       /*
+        *  Scan Filter
+        *  -----------------------------------------------------------
+        *  Configuration : Class       No filter   AP only   Station Only
+        *  Values to set :                0           1           2
+        *  Configuration : Priority    High Rssi   Low Rssi     Detect
+        *  Values to set :                0          0x4         0x0
+        *  Configuration : Channel     filter off  filter on
+        *  Values to set :                0          0x10
+        *  -----------------------------------------------------------
+        */
+       WID_SCAN_FILTER                 = 0x0036,
+
+       /*
+        *  Link Loss Threshold (measure in the beacon period)
+        *  -----------------------------------------------------------
+        *  Configuration : Any value between 10 and 254(Set to 255 disable)
+        *  Values to set : Same value. Default is 10
+        *  -----------------------------------------------------------
+        */
+       WID_LINK_LOSS_THRESHOLD         = 0x0037,
+
+       WID_ABORT_RUNNING_SCAN          = 0x003E,
+
+       /* NMAC Character WID list */
+       WID_WPS_START                   = 0x0043,
+
+       /*
+        *  Protection mode for MAC
+        *  -----------------------------------------------------------
+        *  Configuration :  Auto  No protection  ERP    HT    GF
+        *  Values to set :  0     1              2      3     4
+        *  -----------------------------------------------------------
+        */
+       WID_11N_PROT_MECH               = 0x0080,
+
+       /*
+        *  ERP Protection type for MAC
+        *  -----------------------------------------------------------
+        *  Configuration :  Self-CTS   RTS-CTS
+        *  Values to set :  0          1
+        *  -----------------------------------------------------------
+        */
+       WID_11N_ERP_PROT_TYPE           = 0x0081,
+
+       /*
+        *  HT Option Enable
+        *  -----------------------------------------------------------
+        *  Configuration :   HT Enable          HT Disable
+        *  Values to set :   1                  0
+        *  -----------------------------------------------------------
+        */
+       WID_11N_ENABLE                  = 0x0082,
+
+       /*
+        *  11n Operating mode (Note that 11g operating mode will also be
+        *  used in addition to this, if this is set to HT Mixed mode)
+        *  -----------------------------------------------------------
+        *   Configuration :  HT Mixed  HT Only-20MHz   HT Only-20/40MHz
+        *  Values to set :     1         2               3
+        *  -----------------------------------------------------------
+        */
+       WID_11N_OPERATING_MODE          = 0x0083,
+
+       /*
+        *  11n OBSS non-HT STA Detection flag
+        *  -----------------------------------------------------------
+        *  Configuration :  Do not detect
+        *  Values to set :  0
+        *  Configuration :  Detect, do not protect or report
+        *  Values to set :  1
+        *  Configuration :  Detect, protect and do not report
+        *  Values to set :  2
+        *  Configuration :  Detect, protect and report to other BSS
+        *  Values to set :  3
+        *  -----------------------------------------------------------
+        */
+       WID_11N_OBSS_NONHT_DETECTION    = 0x0084,
+
+       /*
+        *  11n HT Protection Type
+        *  -----------------------------------------------------------
+        *  Configuration :  RTS-CTS   First Frame Exchange at non-HT-rate
+        *  Values to set :  0         1
+        *  Configuration :  LSIG TXOP First Frame Exchange in Mixed Fmt
+        *  Values to set :  2         3
+        *  -----------------------------------------------------------
+        */
+       WID_11N_HT_PROT_TYPE            = 0x0085,
+
+       /*
+        *  11n RIFS Protection Enable Flag
+        *  -----------------------------------------------------------
+        *  Configuration :  Disable    Enable
+        *  Values to set :  0          1
+        *  -----------------------------------------------------------
+        */
+       WID_11N_RIFS_PROT_ENABLE        = 0x0086,
+
+       /*
+        *  SMPS Mode
+        *  -----------------------------------------------------------
+        *  Configuration :  Static   Dynamic   MIMO (Power Save Disabled)
+        *  Values to set :  1        2         3
+        *  -----------------------------------------------------------
+        */
+       WID_11N_SMPS_MODE               = 0x0087,
+
+       /*
+        *  Current transmit MCS
+        *  -----------------------------------------------------------
+        *  Configuration :  MCS Index for data rate
+        *  Values to set :  0 to 7
+        *  -----------------------------------------------------------
+        */
+       WID_11N_CURRENT_TX_MCS          = 0x0088,
+
+       WID_11N_PRINT_STATS             = 0x0089,
+
+       /*
+        *  11n Short GI Enable Flag
+        *  -----------------------------------------------------------
+        *  Configuration :  Disable    Enable
+        *  Values to set :  0          1
+        *  -----------------------------------------------------------
+        */
+       WID_11N_SHORT_GI_ENABLE         = 0x008D,
+
+       /*
+        *  11n RIFS Enable Flag
+        *  -----------------------------------------------------------
+        *  Configuration :  Disable    Enable
+        *  Values to set :  0          1
+        *  -----------------------------------------------------------
+        */
+       WID_RIFS_MODE                   = 0x0094,
+
+       /*
+        *  TX Abort Feature
+        *  -----------------------------------------------------------
+        *  Configuration :  Disable Self CTS    Enable Self CTS
+        *  Values to set :             0                      1
+        *  Configuration :  Disable TX Abort    Enable TX Abort
+        *  Values to set :             2                      3
+        *  Configuration :  Enable HW TX Abort Enable SW TX Abort
+        *  Values to set :             4                      5
+        *  -----------------------------------------------------------
+        */
+       WID_TX_ABORT_CONFIG             = 0x00A1,
+
+       WID_REG_TSSI_11B_VALUE          = 0x00A6,
+       WID_REG_TSSI_11G_VALUE          = 0x00A7,
+       WID_REG_TSSI_11N_VALUE          = 0x00A8,
+       WID_TX_CALIBRATION              = 0x00A9,
+       WID_DSCR_TSSI_11B_VALUE         = 0x00AA,
+       WID_DSCR_TSSI_11G_VALUE         = 0x00AB,
+       WID_DSCR_TSSI_11N_VALUE         = 0x00AC,
+
+       /*
+        *  Immediate Block-Ack Support
+        *  -----------------------------------------------------------
+        *  Configuration : Disable                  Enable
+        *  Values to set :    0                       1
+        *  -----------------------------------------------------------
+        */
+       WID_11N_IMMEDIATE_BA_ENABLED    = 0x00AF,
+
+       /*
+        *  TXOP Disable Flag
+        *  -----------------------------------------------------------
+        *  Configuration : Disable                  Enable
+        *  Values to set :    1                        0
+        *  -----------------------------------------------------------
+        */
+       WID_11N_TXOP_PROT_DISABLE       = 0x00B0,
+
+       WID_TX_POWER_LEVEL_11N          = 0x00B1,
+
+       /* Custom Character WID list */
+       /* SCAN Complete notification WID*/
+       WID_SCAN_COMPLETE               = 0x00C9,
+
+       WID_DEL_BEACON                  = 0x00CA,
+
+       WID_LOG_TERMINAL_SWITCH         = 0x00CD,
+       WID_TX_POWER                    = 0x00CE,
+       /*  EMAC Short WID list */
+       /*  RTS Threshold */
+       /*
+        *  -----------------------------------------------------------
+        *  Configuration :   Any value between 256 to 2347
+        *  Values to set :   Same value. Default is 2347
+        *  -----------------------------------------------------------
+        */
+       WID_RTS_THRESHOLD               = 0x1000,
+
+       /*
+        *  Fragmentation Threshold
+        *  -----------------------------------------------------------
+        *  Configuration :   Any value between 256 to 2346
+        *  Values to set :   Same value. Default is 2346
+        *  -----------------------------------------------------------
+        */
+       WID_FRAG_THRESHOLD              = 0x1001,
+
+       WID_SHORT_RETRY_LIMIT           = 0x1002,
+       WID_LONG_RETRY_LIMIT            = 0x1003,
+       WID_BEACON_INTERVAL             = 0x1006,
+       WID_MEMORY_ACCESS_16BIT         = 0x1008,
+       WID_PASSIVE_SCAN_TIME           = 0x100D,
+       WID_JOIN_START_TIMEOUT          = 0x100F,
+       WID_ASOC_TIMEOUT                = 0x1011,
+       WID_11I_PROTOCOL_TIMEOUT        = 0x1012,
+       WID_EAPOL_RESPONSE_TIMEOUT      = 0x1013,
+
+       /* NMAC Short WID list */
+       WID_11N_SIG_QUAL_VAL            = 0x1085,
+       WID_CCA_THRESHOLD               = 0x1087,
+
+       /* Custom Short WID list */
+
+       /* EMAC Integer WID list */
+       WID_FAILED_COUNT                = 0x2000,
+       WID_RETRY_COUNT                 = 0x2001,
+       WID_MULTIPLE_RETRY_COUNT        = 0x2002,
+       WID_FRAME_DUPLICATE_COUNT       = 0x2003,
+       WID_ACK_FAILURE_COUNT           = 0x2004,
+       WID_RECEIVED_FRAGMENT_COUNT     = 0x2005,
+       WID_MCAST_RECEIVED_FRAME_COUNT  = 0x2006,
+       WID_FCS_ERROR_COUNT             = 0x2007,
+       WID_SUCCESS_FRAME_COUNT         = 0x2008,
+       WID_HUT_TX_COUNT                = 0x200A,
+       WID_TX_FRAGMENT_COUNT           = 0x200B,
+       WID_TX_MULTICAST_FRAME_COUNT    = 0x200C,
+       WID_RTS_SUCCESS_COUNT           = 0x200D,
+       WID_RTS_FAILURE_COUNT           = 0x200E,
+       WID_WEP_UNDECRYPTABLE_COUNT     = 0x200F,
+       WID_REKEY_PERIOD                = 0x2010,
+       WID_REKEY_PACKET_COUNT          = 0x2011,
+       WID_1X_SERV_ADDR                = 0x2012,
+       WID_STACK_IP_ADDR               = 0x2013,
+       WID_STACK_NETMASK_ADDR          = 0x2014,
+       WID_HW_RX_COUNT                 = 0x2015,
+       WID_MEMORY_ADDRESS              = 0x201E,
+       WID_MEMORY_ACCESS_32BIT         = 0x201F,
+
+       /* NMAC Integer WID list */
+       /* Custom Integer WID list */
+       WID_GET_INACTIVE_TIME           = 0x2084,
+       /* EMAC String WID list */
+       WID_SSID                        = 0x3000,
+       WID_FIRMWARE_VERSION            = 0x3001,
+       WID_OPERATIONAL_RATE_SET        = 0x3002,
+       WID_BSSID                       = 0x3003,
+       WID_WEP_KEY_VALUE               = 0x3004,
+       WID_11I_PSK                     = 0x3008,
+       WID_11E_P_ACTION_REQ            = 0x3009,
+       WID_1X_KEY                      = 0x300A,
+       WID_HARDWARE_VERSION            = 0x300B,
+       WID_MAC_ADDR                    = 0x300C,
+       WID_HUT_DEST_ADDR               = 0x300D,
+       WID_PHY_VERSION                 = 0x300F,
+       WID_SUPP_USERNAME               = 0x3010,
+       WID_SUPP_PASSWORD               = 0x3011,
+       WID_SITE_SURVEY_RESULTS         = 0x3012,
+       WID_RX_POWER_LEVEL              = 0x3013,
+       WID_SET_STA_MAC_INACTIVE_TIME   = 0x3017,
+       WID_ADD_WEP_KEY                 = 0x3019,
+       WID_REMOVE_WEP_KEY              = 0x301A,
+       WID_ADD_PTK                     = 0x301B,
+       WID_ADD_RX_GTK                  = 0x301C,
+       WID_ADD_TX_GTK                  = 0x301D,
+       WID_REMOVE_KEY                  = 0x301E,
+       WID_ASSOC_REQ_INFO              = 0x301F,
+       WID_ASSOC_RES_INFO              = 0x3020,
+       WID_MANUFACTURER                = 0x3026, /* Added for CAPI tool */
+       WID_MODEL_NAME                  = 0x3027, /* Added for CAPI tool */
+       WID_MODEL_NUM                   = 0x3028, /* Added for CAPI tool */
+       WID_DEVICE_NAME                 = 0x3029, /* Added for CAPI tool */
+
+       /* NMAC String WID list */
+       WID_SET_OPERATION_MODE          = 0x3079,
+       WID_11N_P_ACTION_REQ            = 0x3080,
+       WID_HUT_TEST_ID                 = 0x3081,
+       WID_PMKID_INFO                  = 0x3082,
+       WID_FIRMWARE_INFO               = 0x3083,
+       WID_REGISTER_FRAME              = 0x3084,
+       WID_DEL_ALL_STA                 = 0x3085,
+       WID_REMAIN_ON_CHAN              = 0x3996,
+       WID_SSID_PROBE_REQ              = 0x3997,
+       WID_JOIN_REQ_EXTENDED           = 0x3998,
+
+       WID_IP_ADDRESS                  = 0x3999,
+
+       /* Custom String WID list */
+
+       /* EMAC Binary WID list */
+       WID_UAPSD_CONFIG                = 0x4001,
+       WID_UAPSD_STATUS                = 0x4002,
+       WID_WMM_AP_AC_PARAMS            = 0x4003,
+       WID_WMM_STA_AC_PARAMS           = 0x4004,
+       WID_NETWORK_INFO                = 0x4005,
+       WID_STA_JOIN_INFO               = 0x4006,
+       WID_CONNECTED_STA_LIST          = 0x4007,
+
+       /* NMAC Binary WID list */
+       WID_11N_AUTORATE_TABLE          = 0x4080,
+
+       WID_SCAN_CHANNEL_LIST           = 0x4084,
+
+       WID_INFO_ELEMENT_PROBE          = 0x4085,
+       WID_INFO_ELEMENT_ASSOCIATE      = 0x4086,
+       WID_ADD_STA                     = 0X4087,
+       WID_REMOVE_STA                  = 0X4088,
+       WID_EDIT_STA                    = 0X4089,
+       WID_ADD_BEACON                  = 0x408a,
+
+       WID_SETUP_MULTICAST_FILTER      = 0x408b,
+
+       /* Miscellaneous WIDs */
+       WID_ALL                         = 0x7FFE,
+       WID_MAX                         = 0xFFFF
+};
+
+#endif
index 4ec5528..b3fb4d4 100644 (file)
@@ -84,8 +84,6 @@ source "drivers/staging/fbtft/Kconfig"
 
 source "drivers/staging/fsl-dpaa2/Kconfig"
 
-source "drivers/staging/wilc1000/Kconfig"
-
 source "drivers/staging/most/Kconfig"
 
 source "drivers/staging/ks7010/Kconfig"
index 4d34198..3d8c7ea 100644 (file)
@@ -32,7 +32,6 @@ obj-$(CONFIG_UNISYSSPAR)      += unisys/
 obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clocking-wizard/
 obj-$(CONFIG_FB_TFT)           += fbtft/
 obj-$(CONFIG_FSL_DPAA2)                += fsl-dpaa2/
-obj-$(CONFIG_WILC1000)         += wilc1000/
 obj-$(CONFIG_MOST)             += most/
 obj-$(CONFIG_KS7010)           += ks7010/
 obj-$(CONFIG_GREYBUS)          += greybus/
diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig
deleted file mode 100644 (file)
index 80c92e8..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config WILC1000
-       tristate
-       help
-         Add support for the Atmel WILC1000 802.11 b/g/n SoC.
-         This provides Wi-FI over an SDIO or SPI interface, and
-         is usually found in IoT devices.
-
-         This module only support IEEE 802.11n WiFi.
-
-config WILC1000_SDIO
-       tristate "Atmel WILC1000 SDIO (WiFi only)"
-       depends on CFG80211 && INET && MMC
-       select WILC1000
-       help
-         This module adds support for the SDIO interface of adapters using
-         WILC1000 chipset. The Atmel WILC1000 SDIO is a full speed interface.
-         It meets SDIO card specification version 2.0. The interface supports
-         the 1-bit/4-bit SD transfer mode at the clock range of 0-50 MHz.
-         The host can use this interface to read and write from any register
-         within the chip as well as configure the WILC1000 for data DMA.
-         To use this interface, pin9 (SDIO_SPI_CFG) must be grounded. Select
-         this if your platform is using the SDIO bus.
-
-config WILC1000_SPI
-       tristate "Atmel WILC1000 SPI (WiFi only)"
-       depends on CFG80211 && INET && SPI
-       select WILC1000
-       select CRC7
-       help
-         This module adds support for the SPI interface of adapters using
-         WILC1000 chipset. The Atmel WILC1000 has a Serial Peripheral
-         Interface (SPI) that operates as a SPI slave. This SPI interface can
-         be used for control and for serial I/O of 802.11 data. The SPI is a
-         full-duplex slave synchronous serial interface that is available
-         immediately following reset when pin 9 (SDIO_SPI_CFG) is tied to
-         VDDIO. Select this if your platform is using the SPI bus.
-
-config WILC1000_HW_OOB_INTR
-       bool "WILC1000 out of band interrupt"
-       depends on WILC1000_SDIO
-       help
-         This option enables out-of-band interrupt support for the WILC1000
-         chipset. This OOB interrupt is intended to provide a faster interrupt
-         mechanism for SDIO host controllers that don't support SDIO interrupt.
-         Select this option If the SDIO host controller in your platform
-         doesn't support SDIO time devision interrupt.
diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile
deleted file mode 100644 (file)
index a3305a0..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_WILC1000) += wilc1000.o
-
-ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
-               -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\"
-
-wilc1000-objs := cfg80211.o netdev.o mon.o \
-                       hif.o wlan_cfg.o wlan.o
-
-obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o
-wilc1000-sdio-objs += sdio.o
-
-obj-$(CONFIG_WILC1000_SPI) += wilc1000-spi.o
-wilc1000-spi-objs += spi.o
diff --git a/drivers/staging/wilc1000/cfg80211.c b/drivers/staging/wilc1000/cfg80211.c
deleted file mode 100644 (file)
index b6065a0..0000000
+++ /dev/null
@@ -1,1847 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#include "cfg80211.h"
-
-#define GO_NEG_REQ                     0x00
-#define GO_NEG_RSP                     0x01
-#define GO_NEG_CONF                    0x02
-#define P2P_INV_REQ                    0x03
-#define P2P_INV_RSP                    0x04
-
-#define WILC_INVALID_CHANNEL           0
-
-/* Operation at 2.4 GHz with channels 1-13 */
-#define WILC_WLAN_OPERATING_CLASS_2_4GHZ               0x51
-
-static const struct ieee80211_txrx_stypes
-       wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
-       [NL80211_IFTYPE_STATION] = {
-               .tx = 0xffff,
-               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
-       },
-       [NL80211_IFTYPE_AP] = {
-               .tx = 0xffff,
-               .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
-                       BIT(IEEE80211_STYPE_AUTH >> 4) |
-                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
-                       BIT(IEEE80211_STYPE_ACTION >> 4)
-       },
-       [NL80211_IFTYPE_P2P_CLIENT] = {
-               .tx = 0xffff,
-               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
-                       BIT(IEEE80211_STYPE_AUTH >> 4) |
-                       BIT(IEEE80211_STYPE_DEAUTH >> 4)
-       }
-};
-
-static const struct wiphy_wowlan_support wowlan_support = {
-       .flags = WIPHY_WOWLAN_ANY
-};
-
-struct wilc_p2p_mgmt_data {
-       int size;
-       u8 *buff;
-};
-
-struct wilc_p2p_pub_act_frame {
-       u8 category;
-       u8 action;
-       u8 oui[3];
-       u8 oui_type;
-       u8 oui_subtype;
-       u8 dialog_token;
-       u8 elem[];
-} __packed;
-
-struct wilc_vendor_specific_ie {
-       u8 tag_number;
-       u8 tag_len;
-       u8 oui[3];
-       u8 oui_type;
-       u8 attr[];
-} __packed;
-
-struct wilc_attr_entry {
-       u8  attr_type;
-       __le16 attr_len;
-       u8 val[];
-} __packed;
-
-struct wilc_attr_oper_ch {
-       u8 attr_type;
-       __le16 attr_len;
-       u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
-       u8 op_class;
-       u8 op_channel;
-} __packed;
-
-struct wilc_attr_ch_list {
-       u8 attr_type;
-       __le16 attr_len;
-       u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
-       u8 elem[];
-} __packed;
-
-struct wilc_ch_list_elem {
-       u8 op_class;
-       u8 no_of_channels;
-       u8 ch_list[];
-} __packed;
-
-static void cfg_scan_result(enum scan_event scan_event,
-                           struct wilc_rcvd_net_info *info, void *user_void)
-{
-       struct wilc_priv *priv = user_void;
-
-       if (!priv->cfg_scanning)
-               return;
-
-       if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
-               s32 freq;
-               struct ieee80211_channel *channel;
-               struct cfg80211_bss *bss;
-               struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
-
-               if (!wiphy || !info)
-                       return;
-
-               freq = ieee80211_channel_to_frequency((s32)info->ch,
-                                                     NL80211_BAND_2GHZ);
-               channel = ieee80211_get_channel(wiphy, freq);
-               if (!channel)
-                       return;
-
-               bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt,
-                                               info->frame_len,
-                                               (s32)info->rssi * 100,
-                                               GFP_KERNEL);
-               if (!bss)
-                       cfg80211_put_bss(wiphy, bss);
-       } else if (scan_event == SCAN_EVENT_DONE) {
-               mutex_lock(&priv->scan_req_lock);
-
-               if (priv->scan_req) {
-                       struct cfg80211_scan_info info = {
-                               .aborted = false,
-                       };
-
-                       cfg80211_scan_done(priv->scan_req, &info);
-                       priv->cfg_scanning = false;
-                       priv->scan_req = NULL;
-               }
-               mutex_unlock(&priv->scan_req_lock);
-       } else if (scan_event == SCAN_EVENT_ABORTED) {
-               mutex_lock(&priv->scan_req_lock);
-
-               if (priv->scan_req) {
-                       struct cfg80211_scan_info info = {
-                               .aborted = false,
-                       };
-
-                       cfg80211_scan_done(priv->scan_req, &info);
-                       priv->cfg_scanning = false;
-                       priv->scan_req = NULL;
-               }
-               mutex_unlock(&priv->scan_req_lock);
-       }
-}
-
-static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
-                              void *priv_data)
-{
-       struct wilc_priv *priv = priv_data;
-       struct net_device *dev = priv->dev;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wl = vif->wilc;
-       struct host_if_drv *wfi_drv = priv->hif_drv;
-       struct wilc_conn_info *conn_info = &wfi_drv->conn_info;
-       struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
-
-       vif->connecting = false;
-
-       if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
-               u16 connect_status = conn_info->status;
-
-               if (mac_status == WILC_MAC_STATUS_DISCONNECTED &&
-                   connect_status == WLAN_STATUS_SUCCESS) {
-                       connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
-                       wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
-
-                       if (vif->iftype != WILC_CLIENT_MODE)
-                               wl->sta_ch = WILC_INVALID_CHANNEL;
-
-                       netdev_err(dev, "Unspecified failure\n");
-               }
-
-               if (connect_status == WLAN_STATUS_SUCCESS)
-                       memcpy(priv->associated_bss, conn_info->bssid,
-                              ETH_ALEN);
-
-               cfg80211_ref_bss(wiphy, vif->bss);
-               cfg80211_connect_bss(dev, conn_info->bssid, vif->bss,
-                                    conn_info->req_ies,
-                                    conn_info->req_ies_len,
-                                    conn_info->resp_ies,
-                                    conn_info->resp_ies_len,
-                                    connect_status, GFP_KERNEL,
-                                    NL80211_TIMEOUT_UNSPECIFIED);
-
-               vif->bss = NULL;
-       } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
-               u16 reason = 0;
-
-               eth_zero_addr(priv->associated_bss);
-               wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
-
-               if (vif->iftype != WILC_CLIENT_MODE) {
-                       wl->sta_ch = WILC_INVALID_CHANNEL;
-               } else {
-                       if (wfi_drv->ifc_up)
-                               reason = 3;
-                       else
-                               reason = 1;
-               }
-
-               cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
-       }
-}
-
-struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
-{
-       struct wilc_vif *vif;
-
-       vif = list_first_or_null_rcu(&wl->vif_list, typeof(*vif), list);
-       if (!vif)
-               return ERR_PTR(-EINVAL);
-
-       return vif;
-}
-
-static int set_channel(struct wiphy *wiphy,
-                      struct cfg80211_chan_def *chandef)
-{
-       struct wilc *wl = wiphy_priv(wiphy);
-       struct wilc_vif *vif;
-       u32 channelnum;
-       int result;
-       int srcu_idx;
-
-       srcu_idx = srcu_read_lock(&wl->srcu);
-       vif = wilc_get_wl_to_vif(wl);
-       if (IS_ERR(vif)) {
-               srcu_read_unlock(&wl->srcu, srcu_idx);
-               return PTR_ERR(vif);
-       }
-
-       channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
-
-       wl->op_ch = channelnum;
-       result = wilc_set_mac_chnl_num(vif, channelnum);
-       if (result)
-               netdev_err(vif->ndev, "Error in setting channel\n");
-
-       srcu_read_unlock(&wl->srcu, srcu_idx);
-       return result;
-}
-
-static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
-{
-       struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
-       struct wilc_priv *priv = &vif->priv;
-       u32 i;
-       int ret = 0;
-       u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
-       u8 scan_type;
-
-       if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
-               netdev_err(vif->ndev, "Requested scanned channels over\n");
-               return -EINVAL;
-       }
-
-       priv->scan_req = request;
-       priv->cfg_scanning = true;
-       for (i = 0; i < request->n_channels; i++) {
-               u16 freq = request->channels[i]->center_freq;
-
-               scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
-       }
-
-       if (request->n_ssids)
-               scan_type = WILC_FW_ACTIVE_SCAN;
-       else
-               scan_type = WILC_FW_PASSIVE_SCAN;
-
-       ret = wilc_scan(vif, WILC_FW_USER_SCAN, scan_type, scan_ch_list,
-                       request->n_channels, cfg_scan_result, (void *)priv,
-                       request);
-
-       if (ret) {
-               priv->scan_req = NULL;
-               priv->cfg_scanning = false;
-       }
-
-       return ret;
-}
-
-static int connect(struct wiphy *wiphy, struct net_device *dev,
-                  struct cfg80211_connect_params *sme)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc_priv *priv = &vif->priv;
-       struct host_if_drv *wfi_drv = priv->hif_drv;
-       int ret;
-       u32 i;
-       u8 security = WILC_FW_SEC_NO;
-       enum authtype auth_type = WILC_FW_AUTH_ANY;
-       u32 cipher_group;
-       struct cfg80211_bss *bss;
-       void *join_params;
-       u8 ch;
-
-       vif->connecting = true;
-
-       memset(priv->wep_key, 0, sizeof(priv->wep_key));
-       memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
-
-       cipher_group = sme->crypto.cipher_group;
-       if (cipher_group != 0) {
-               if (cipher_group == WLAN_CIPHER_SUITE_WEP40) {
-                       security = WILC_FW_SEC_WEP;
-
-                       priv->wep_key_len[sme->key_idx] = sme->key_len;
-                       memcpy(priv->wep_key[sme->key_idx], sme->key,
-                              sme->key_len);
-
-                       wilc_set_wep_default_keyid(vif, sme->key_idx);
-                       wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
-                                                sme->key_idx);
-               } else if (cipher_group == WLAN_CIPHER_SUITE_WEP104) {
-                       security = WILC_FW_SEC_WEP_EXTENDED;
-
-                       priv->wep_key_len[sme->key_idx] = sme->key_len;
-                       memcpy(priv->wep_key[sme->key_idx], sme->key,
-                              sme->key_len);
-
-                       wilc_set_wep_default_keyid(vif, sme->key_idx);
-                       wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
-                                                sme->key_idx);
-               } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
-                       if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
-                               security = WILC_FW_SEC_WPA2_TKIP;
-                       else
-                               security = WILC_FW_SEC_WPA2_AES;
-               } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
-                       if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
-                               security = WILC_FW_SEC_WPA_TKIP;
-                       else
-                               security = WILC_FW_SEC_WPA_AES;
-               } else {
-                       ret = -ENOTSUPP;
-                       netdev_err(dev, "%s: Unsupported cipher\n",
-                                  __func__);
-                       goto out_error;
-               }
-       }
-
-       if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
-           (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
-               for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
-                       u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];
-
-                       if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
-                               security |= WILC_FW_TKIP;
-                       else
-                               security |= WILC_FW_AES;
-               }
-       }
-
-       switch (sme->auth_type) {
-       case NL80211_AUTHTYPE_OPEN_SYSTEM:
-               auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
-               break;
-
-       case NL80211_AUTHTYPE_SHARED_KEY:
-               auth_type = WILC_FW_AUTH_SHARED_KEY;
-               break;
-
-       default:
-               break;
-       }
-
-       if (sme->crypto.n_akm_suites) {
-               if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
-                       auth_type = WILC_FW_AUTH_IEEE8021;
-       }
-
-       if (wfi_drv->usr_scan_req.scan_result) {
-               netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
-               ret = -EBUSY;
-               goto out_error;
-       }
-
-       bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid,
-                              sme->ssid_len, IEEE80211_BSS_TYPE_ANY,
-                              IEEE80211_PRIVACY(sme->privacy));
-       if (!bss) {
-               ret = -EINVAL;
-               goto out_error;
-       }
-
-       if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) {
-               ret = -EALREADY;
-               goto out_put_bss;
-       }
-
-       join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
-       if (!join_params) {
-               netdev_err(dev, "%s: failed to construct join param\n",
-                          __func__);
-               ret = -EINVAL;
-               goto out_put_bss;
-       }
-
-       ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
-       vif->wilc->op_ch = ch;
-       if (vif->iftype != WILC_CLIENT_MODE)
-               vif->wilc->sta_ch = ch;
-
-       wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE);
-
-       wfi_drv->conn_info.security = security;
-       wfi_drv->conn_info.auth_type = auth_type;
-       wfi_drv->conn_info.ch = ch;
-       wfi_drv->conn_info.conn_result = cfg_connect_result;
-       wfi_drv->conn_info.arg = priv;
-       wfi_drv->conn_info.param = join_params;
-
-       ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
-       if (ret) {
-               netdev_err(dev, "wilc_set_join_req(): Error\n");
-               ret = -ENOENT;
-               if (vif->iftype != WILC_CLIENT_MODE)
-                       vif->wilc->sta_ch = WILC_INVALID_CHANNEL;
-               wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE);
-               wfi_drv->conn_info.conn_result = NULL;
-               kfree(join_params);
-               goto out_put_bss;
-       }
-       kfree(join_params);
-       vif->bss = bss;
-       cfg80211_put_bss(wiphy, bss);
-       return 0;
-
-out_put_bss:
-       cfg80211_put_bss(wiphy, bss);
-
-out_error:
-       vif->connecting = false;
-       return ret;
-}
-
-static int disconnect(struct wiphy *wiphy, struct net_device *dev,
-                     u16 reason_code)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc_priv *priv = &vif->priv;
-       struct wilc *wilc = vif->wilc;
-       int ret;
-
-       vif->connecting = false;
-
-       if (!wilc)
-               return -EIO;
-
-       if (wilc->close) {
-               /* already disconnected done */
-               cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
-               return 0;
-       }
-
-       if (vif->iftype != WILC_CLIENT_MODE)
-               wilc->sta_ch = WILC_INVALID_CHANNEL;
-       wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
-
-       priv->hif_drv->p2p_timeout = 0;
-
-       ret = wilc_disconnect(vif);
-       if (ret != 0) {
-               netdev_err(priv->dev, "Error in disconnecting\n");
-               ret = -EINVAL;
-       }
-
-       vif->bss = NULL;
-
-       return ret;
-}
-
-static inline void wilc_wfi_cfg_copy_wep_info(struct wilc_priv *priv,
-                                             u8 key_index,
-                                             struct key_params *params)
-{
-       priv->wep_key_len[key_index] = params->key_len;
-       memcpy(priv->wep_key[key_index], params->key, params->key_len);
-}
-
-static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
-{
-       if (!priv->wilc_gtk[idx]) {
-               priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
-                                             GFP_KERNEL);
-               if (!priv->wilc_gtk[idx])
-                       return -ENOMEM;
-       }
-
-       if (!priv->wilc_ptk[idx]) {
-               priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
-                                             GFP_KERNEL);
-               if (!priv->wilc_ptk[idx])
-                       return -ENOMEM;
-       }
-
-       return 0;
-}
-
-static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
-                                     struct key_params *params)
-{
-       kfree(key_info->key);
-
-       key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
-       if (!key_info->key)
-               return -ENOMEM;
-
-       kfree(key_info->seq);
-
-       if (params->seq_len > 0) {
-               key_info->seq = kmemdup(params->seq, params->seq_len,
-                                       GFP_KERNEL);
-               if (!key_info->seq)
-                       return -ENOMEM;
-       }
-
-       key_info->cipher = params->cipher;
-       key_info->key_len = params->key_len;
-       key_info->seq_len = params->seq_len;
-
-       return 0;
-}
-
-static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
-                  bool pairwise, const u8 *mac_addr, struct key_params *params)
-
-{
-       int ret = 0, keylen = params->key_len;
-       const u8 *rx_mic = NULL;
-       const u8 *tx_mic = NULL;
-       u8 mode = WILC_FW_SEC_NO;
-       u8 op_mode;
-       struct wilc_vif *vif = netdev_priv(netdev);
-       struct wilc_priv *priv = &vif->priv;
-
-       switch (params->cipher) {
-       case WLAN_CIPHER_SUITE_WEP40:
-       case WLAN_CIPHER_SUITE_WEP104:
-               if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
-                       wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
-
-                       if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
-                               mode = WILC_FW_SEC_WEP;
-                       else
-                               mode = WILC_FW_SEC_WEP_EXTENDED;
-
-                       ret = wilc_add_wep_key_bss_ap(vif, params->key,
-                                                     params->key_len,
-                                                     key_index, mode,
-                                                     WILC_FW_AUTH_OPEN_SYSTEM);
-                       break;
-               }
-               if (memcmp(params->key, priv->wep_key[key_index],
-                          params->key_len)) {
-                       wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
-
-                       ret = wilc_add_wep_key_bss_sta(vif, params->key,
-                                                      params->key_len,
-                                                      key_index);
-               }
-
-               break;
-
-       case WLAN_CIPHER_SUITE_TKIP:
-       case WLAN_CIPHER_SUITE_CCMP:
-               if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
-                   priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
-                       struct wilc_wfi_key *key;
-
-                       ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
-                       if (ret)
-                               return -ENOMEM;
-
-                       if (params->key_len > 16 &&
-                           params->cipher == WLAN_CIPHER_SUITE_TKIP) {
-                               tx_mic = params->key + 24;
-                               rx_mic = params->key + 16;
-                               keylen = params->key_len - 16;
-                       }
-
-                       if (!pairwise) {
-                               if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
-                                       mode = WILC_FW_SEC_WPA_TKIP;
-                               else
-                                       mode = WILC_FW_SEC_WPA2_AES;
-
-                               priv->wilc_groupkey = mode;
-
-                               key = priv->wilc_gtk[key_index];
-                       } else {
-                               if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
-                                       mode = WILC_FW_SEC_WPA_TKIP;
-                               else
-                                       mode = priv->wilc_groupkey | WILC_FW_AES;
-
-                               key = priv->wilc_ptk[key_index];
-                       }
-                       ret = wilc_wfi_cfg_copy_wpa_info(key, params);
-                       if (ret)
-                               return -ENOMEM;
-
-                       op_mode = WILC_AP_MODE;
-               } else {
-                       if (params->key_len > 16 &&
-                           params->cipher == WLAN_CIPHER_SUITE_TKIP) {
-                               rx_mic = params->key + 24;
-                               tx_mic = params->key + 16;
-                               keylen = params->key_len - 16;
-                       }
-
-                       op_mode = WILC_STATION_MODE;
-               }
-
-               if (!pairwise)
-                       ret = wilc_add_rx_gtk(vif, params->key, keylen,
-                                             key_index, params->seq_len,
-                                             params->seq, rx_mic, tx_mic,
-                                             op_mode, mode);
-               else
-                       ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
-                                          rx_mic, tx_mic, op_mode, mode,
-                                          key_index);
-
-               break;
-
-       default:
-               netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
-               ret = -ENOTSUPP;
-       }
-
-       return ret;
-}
-
-static int del_key(struct wiphy *wiphy, struct net_device *netdev,
-                  u8 key_index,
-                  bool pairwise,
-                  const u8 *mac_addr)
-{
-       struct wilc_vif *vif = netdev_priv(netdev);
-       struct wilc_priv *priv = &vif->priv;
-
-       if (priv->wilc_gtk[key_index]) {
-               kfree(priv->wilc_gtk[key_index]->key);
-               priv->wilc_gtk[key_index]->key = NULL;
-               kfree(priv->wilc_gtk[key_index]->seq);
-               priv->wilc_gtk[key_index]->seq = NULL;
-
-               kfree(priv->wilc_gtk[key_index]);
-               priv->wilc_gtk[key_index] = NULL;
-       }
-
-       if (priv->wilc_ptk[key_index]) {
-               kfree(priv->wilc_ptk[key_index]->key);
-               priv->wilc_ptk[key_index]->key = NULL;
-               kfree(priv->wilc_ptk[key_index]->seq);
-               priv->wilc_ptk[key_index]->seq = NULL;
-               kfree(priv->wilc_ptk[key_index]);
-               priv->wilc_ptk[key_index] = NULL;
-       }
-
-       if (key_index <= 3 && priv->wep_key_len[key_index]) {
-               memset(priv->wep_key[key_index], 0,
-                      priv->wep_key_len[key_index]);
-               priv->wep_key_len[key_index] = 0;
-               wilc_remove_wep_key(vif, key_index);
-       }
-
-       return 0;
-}
-
-static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
-                  bool pairwise, const u8 *mac_addr, void *cookie,
-                  void (*callback)(void *cookie, struct key_params *))
-{
-       struct wilc_vif *vif = netdev_priv(netdev);
-       struct wilc_priv *priv = &vif->priv;
-       struct  key_params key_params;
-
-       if (!pairwise) {
-               key_params.key = priv->wilc_gtk[key_index]->key;
-               key_params.cipher = priv->wilc_gtk[key_index]->cipher;
-               key_params.key_len = priv->wilc_gtk[key_index]->key_len;
-               key_params.seq = priv->wilc_gtk[key_index]->seq;
-               key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
-       } else {
-               key_params.key = priv->wilc_ptk[key_index]->key;
-               key_params.cipher = priv->wilc_ptk[key_index]->cipher;
-               key_params.key_len = priv->wilc_ptk[key_index]->key_len;
-               key_params.seq = priv->wilc_ptk[key_index]->seq;
-               key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
-       }
-
-       callback(cookie, &key_params);
-
-       return 0;
-}
-
-static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
-                          u8 key_index, bool unicast, bool multicast)
-{
-       struct wilc_vif *vif = netdev_priv(netdev);
-
-       wilc_set_wep_default_keyid(vif, key_index);
-
-       return 0;
-}
-
-static int get_station(struct wiphy *wiphy, struct net_device *dev,
-                      const u8 *mac, struct station_info *sinfo)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc_priv *priv = &vif->priv;
-       u32 i = 0;
-       u32 associatedsta = ~0;
-       u32 inactive_time = 0;
-
-       if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
-               for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
-                       if (!(memcmp(mac,
-                                    priv->assoc_stainfo.sta_associated_bss[i],
-                                    ETH_ALEN))) {
-                               associatedsta = i;
-                               break;
-                       }
-               }
-
-               if (associatedsta == ~0) {
-                       netdev_err(dev, "sta required is not associated\n");
-                       return -ENOENT;
-               }
-
-               sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
-
-               wilc_get_inactive_time(vif, mac, &inactive_time);
-               sinfo->inactive_time = 1000 * inactive_time;
-       } else if (vif->iftype == WILC_STATION_MODE) {
-               struct rf_info stats;
-
-               wilc_get_statistics(vif, &stats);
-
-               sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
-                                BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
-                                BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
-                                BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
-                                BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
-
-               sinfo->signal = stats.rssi;
-               sinfo->rx_packets = stats.rx_cnt;
-               sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
-               sinfo->tx_failed = stats.tx_fail_cnt;
-               sinfo->txrate.legacy = stats.link_speed * 10;
-
-               if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
-                   stats.link_speed != DEFAULT_LINK_SPEED)
-                       wilc_enable_tcp_ack_filter(vif, true);
-               else if (stats.link_speed != DEFAULT_LINK_SPEED)
-                       wilc_enable_tcp_ack_filter(vif, false);
-       }
-       return 0;
-}
-
-static int change_bss(struct wiphy *wiphy, struct net_device *dev,
-                     struct bss_parameters *params)
-{
-       return 0;
-}
-
-static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
-{
-       int ret = -EINVAL;
-       struct cfg_param_attr cfg_param_val;
-       struct wilc *wl = wiphy_priv(wiphy);
-       struct wilc_vif *vif;
-       struct wilc_priv *priv;
-       int srcu_idx;
-
-       srcu_idx = srcu_read_lock(&wl->srcu);
-       vif = wilc_get_wl_to_vif(wl);
-       if (IS_ERR(vif))
-               goto out;
-
-       priv = &vif->priv;
-       cfg_param_val.flag = 0;
-
-       if (changed & WIPHY_PARAM_RETRY_SHORT) {
-               netdev_dbg(vif->ndev,
-                          "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
-                          wiphy->retry_short);
-               cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
-               cfg_param_val.short_retry_limit = wiphy->retry_short;
-       }
-       if (changed & WIPHY_PARAM_RETRY_LONG) {
-               netdev_dbg(vif->ndev,
-                          "Setting WIPHY_PARAM_RETRY_LONG %d\n",
-                          wiphy->retry_long);
-               cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
-               cfg_param_val.long_retry_limit = wiphy->retry_long;
-       }
-       if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
-               if (wiphy->frag_threshold > 255 &&
-                   wiphy->frag_threshold < 7937) {
-                       netdev_dbg(vif->ndev,
-                                  "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
-                                  wiphy->frag_threshold);
-                       cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
-                       cfg_param_val.frag_threshold = wiphy->frag_threshold;
-               } else {
-                       netdev_err(vif->ndev,
-                                  "Fragmentation threshold out of range\n");
-                       goto out;
-               }
-       }
-
-       if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
-               if (wiphy->rts_threshold > 255) {
-                       netdev_dbg(vif->ndev,
-                                  "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
-                                  wiphy->rts_threshold);
-                       cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
-                       cfg_param_val.rts_threshold = wiphy->rts_threshold;
-               } else {
-                       netdev_err(vif->ndev, "RTS threshold out of range\n");
-                       goto out;
-               }
-       }
-
-       ret = wilc_hif_set_cfg(vif, &cfg_param_val);
-       if (ret)
-               netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
-
-out:
-       srcu_read_unlock(&wl->srcu, srcu_idx);
-       return ret;
-}
-
-static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
-                    struct cfg80211_pmksa *pmksa)
-{
-       struct wilc_vif *vif = netdev_priv(netdev);
-       struct wilc_priv *priv = &vif->priv;
-       u32 i;
-       int ret = 0;
-       u8 flag = 0;
-
-       for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
-               if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
-                           ETH_ALEN)) {
-                       flag = PMKID_FOUND;
-                       break;
-               }
-       }
-       if (i < WILC_MAX_NUM_PMKIDS) {
-               memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
-                      ETH_ALEN);
-               memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
-                      WLAN_PMKID_LEN);
-               if (!(flag == PMKID_FOUND))
-                       priv->pmkid_list.numpmkid++;
-       } else {
-               netdev_err(netdev, "Invalid PMKID index\n");
-               ret = -EINVAL;
-       }
-
-       if (!ret)
-               ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
-
-       return ret;
-}
-
-static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
-                    struct cfg80211_pmksa *pmksa)
-{
-       u32 i;
-       struct wilc_vif *vif = netdev_priv(netdev);
-       struct wilc_priv *priv = &vif->priv;
-
-       for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
-               if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
-                           ETH_ALEN)) {
-                       memset(&priv->pmkid_list.pmkidlist[i], 0,
-                              sizeof(struct wilc_pmkid));
-                       break;
-               }
-       }
-
-       if (i == priv->pmkid_list.numpmkid)
-               return -EINVAL;
-
-       for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
-               memcpy(priv->pmkid_list.pmkidlist[i].bssid,
-                      priv->pmkid_list.pmkidlist[i + 1].bssid,
-                      ETH_ALEN);
-               memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
-                      priv->pmkid_list.pmkidlist[i + 1].pmkid,
-                      WLAN_PMKID_LEN);
-       }
-       priv->pmkid_list.numpmkid--;
-
-       return 0;
-}
-
-static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
-{
-       struct wilc_vif *vif = netdev_priv(netdev);
-
-       memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
-
-       return 0;
-}
-
-static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
-{
-       struct wilc_attr_entry *e;
-       struct wilc_attr_ch_list *ch_list;
-       struct wilc_attr_oper_ch *op_ch;
-       u32 index = 0;
-       u8 ch_list_idx = 0;
-       u8 op_ch_idx = 0;
-
-       if (sta_ch == WILC_INVALID_CHANNEL)
-               return;
-
-       while (index + sizeof(*e) <= len) {
-               e = (struct wilc_attr_entry *)&buf[index];
-               if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
-                       ch_list_idx = index;
-               else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
-                       op_ch_idx = index;
-               if (ch_list_idx && op_ch_idx)
-                       break;
-               index += le16_to_cpu(e->attr_len) + sizeof(*e);
-       }
-
-       if (ch_list_idx) {
-               u16 attr_size;
-               struct wilc_ch_list_elem *e;
-               int i;
-
-               ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
-               attr_size = le16_to_cpu(ch_list->attr_len);
-               for (i = 0; i < attr_size;) {
-                       e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
-                       if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
-                               memset(e->ch_list, sta_ch, e->no_of_channels);
-                               break;
-                       }
-                       i += e->no_of_channels;
-               }
-       }
-
-       if (op_ch_idx) {
-               op_ch = (struct wilc_attr_oper_ch *)&buf[op_ch_idx];
-               op_ch->op_class = WILC_WLAN_OPERATING_CLASS_2_4GHZ;
-               op_ch->op_channel = sta_ch;
-       }
-}
-
-void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
-{
-       struct wilc *wl = vif->wilc;
-       struct wilc_priv *priv = &vif->priv;
-       struct host_if_drv *wfi_drv = priv->hif_drv;
-       struct ieee80211_mgmt *mgmt;
-       struct wilc_vendor_specific_ie *p;
-       struct wilc_p2p_pub_act_frame *d;
-       int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
-       const u8 *vendor_ie;
-       u32 header, pkt_offset;
-       s32 freq;
-
-       header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
-       pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
-
-       if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
-               bool ack = false;
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buff;
-
-               if (ieee80211_is_probe_resp(hdr->frame_control) ||
-                   pkt_offset & IS_MGMT_STATUS_SUCCES)
-                       ack = true;
-
-               cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
-                                       size, ack, GFP_KERNEL);
-               return;
-       }
-
-       freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
-
-       mgmt = (struct ieee80211_mgmt *)buff;
-       if (!ieee80211_is_action(mgmt->frame_control))
-               goto out_rx_mgmt;
-
-       if (priv->cfg_scanning &&
-           time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
-               netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
-               return;
-       }
-
-       if (!ieee80211_is_public_action((struct ieee80211_hdr *)buff, size))
-               goto out_rx_mgmt;
-
-       d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
-       if (d->oui_subtype != GO_NEG_REQ && d->oui_subtype != GO_NEG_RSP &&
-           d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
-               goto out_rx_mgmt;
-
-       vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
-                                           buff + ie_offset, size - ie_offset);
-       if (!vendor_ie)
-               goto out_rx_mgmt;
-
-       p = (struct wilc_vendor_specific_ie *)vendor_ie;
-       wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
-
-out_rx_mgmt:
-       cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
-}
-
-static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
-{
-       struct wilc_p2p_mgmt_data *pv_data = priv;
-
-       kfree(pv_data->buff);
-       kfree(pv_data);
-}
-
-static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
-{
-       struct wilc_vif *vif = data;
-       struct wilc_priv *priv = &vif->priv;
-       struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
-
-       if (cookie != params->listen_cookie)
-               return;
-
-       priv->p2p_listen_state = false;
-
-       cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
-                                          params->listen_ch, GFP_KERNEL);
-}
-
-static int remain_on_channel(struct wiphy *wiphy,
-                            struct wireless_dev *wdev,
-                            struct ieee80211_channel *chan,
-                            unsigned int duration, u64 *cookie)
-{
-       int ret = 0;
-       struct wilc_vif *vif = netdev_priv(wdev->netdev);
-       struct wilc_priv *priv = &vif->priv;
-       u64 id;
-
-       if (wdev->iftype == NL80211_IFTYPE_AP) {
-               netdev_dbg(vif->ndev, "Required while in AP mode\n");
-               return ret;
-       }
-
-       id = ++priv->inc_roc_cookie;
-       if (id == 0)
-               id = ++priv->inc_roc_cookie;
-
-       ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
-                                    wilc_wfi_remain_on_channel_expired,
-                                    (void *)vif);
-       if (ret)
-               return ret;
-
-       vif->wilc->op_ch = chan->hw_value;
-
-       priv->remain_on_ch_params.listen_ch = chan;
-       priv->remain_on_ch_params.listen_cookie = id;
-       *cookie = id;
-       priv->p2p_listen_state = true;
-       priv->remain_on_ch_params.listen_duration = duration;
-
-       cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
-       mod_timer(&vif->hif_drv->remain_on_ch_timer,
-                 jiffies + msecs_to_jiffies(duration + 1000));
-
-       return ret;
-}
-
-static int cancel_remain_on_channel(struct wiphy *wiphy,
-                                   struct wireless_dev *wdev,
-                                   u64 cookie)
-{
-       struct wilc_vif *vif = netdev_priv(wdev->netdev);
-       struct wilc_priv *priv = &vif->priv;
-
-       if (cookie != priv->remain_on_ch_params.listen_cookie)
-               return -ENOENT;
-
-       return wilc_listen_state_expired(vif, cookie);
-}
-
-static int mgmt_tx(struct wiphy *wiphy,
-                  struct wireless_dev *wdev,
-                  struct cfg80211_mgmt_tx_params *params,
-                  u64 *cookie)
-{
-       struct ieee80211_channel *chan = params->chan;
-       unsigned int wait = params->wait;
-       const u8 *buf = params->buf;
-       size_t len = params->len;
-       const struct ieee80211_mgmt *mgmt;
-       struct wilc_p2p_mgmt_data *mgmt_tx;
-       struct wilc_vif *vif = netdev_priv(wdev->netdev);
-       struct wilc_priv *priv = &vif->priv;
-       struct host_if_drv *wfi_drv = priv->hif_drv;
-       struct wilc_vendor_specific_ie *p;
-       struct wilc_p2p_pub_act_frame *d;
-       int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
-       const u8 *vendor_ie;
-       int ret = 0;
-
-       *cookie = prandom_u32();
-       priv->tx_cookie = *cookie;
-       mgmt = (const struct ieee80211_mgmt *)buf;
-
-       if (!ieee80211_is_mgmt(mgmt->frame_control))
-               goto out;
-
-       mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
-       if (!mgmt_tx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       mgmt_tx->buff = kmemdup(buf, len, GFP_KERNEL);
-       if (!mgmt_tx->buff) {
-               ret = -ENOMEM;
-               kfree(mgmt_tx);
-               goto out;
-       }
-
-       mgmt_tx->size = len;
-
-       if (ieee80211_is_probe_resp(mgmt->frame_control)) {
-               wilc_set_mac_chnl_num(vif, chan->hw_value);
-               vif->wilc->op_ch = chan->hw_value;
-               goto out_txq_add_pkt;
-       }
-
-       if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len))
-               goto out_set_timeout;
-
-       d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
-       if (d->oui_type != WLAN_OUI_TYPE_WFA_P2P ||
-           d->oui_subtype != GO_NEG_CONF) {
-               wilc_set_mac_chnl_num(vif, chan->hw_value);
-               vif->wilc->op_ch = chan->hw_value;
-       }
-
-       if (d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
-               goto out_set_timeout;
-
-       vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
-                                           mgmt_tx->buff + ie_offset,
-                                           len - ie_offset);
-       if (!vendor_ie)
-               goto out_set_timeout;
-
-       p = (struct wilc_vendor_specific_ie *)vendor_ie;
-       wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
-
-out_set_timeout:
-       wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
-
-out_txq_add_pkt:
-
-       wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
-                                  mgmt_tx->buff, mgmt_tx->size,
-                                  wilc_wfi_mgmt_tx_complete);
-
-out:
-
-       return ret;
-}
-
-static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
-                              struct wireless_dev *wdev,
-                              u64 cookie)
-{
-       struct wilc_vif *vif = netdev_priv(wdev->netdev);
-       struct wilc_priv *priv = &vif->priv;
-       struct host_if_drv *wfi_drv = priv->hif_drv;
-
-       wfi_drv->p2p_timeout = jiffies;
-
-       if (!priv->p2p_listen_state) {
-               struct wilc_wfi_p2p_listen_params *params;
-
-               params = &priv->remain_on_ch_params;
-
-               cfg80211_remain_on_channel_expired(wdev,
-                                                  params->listen_cookie,
-                                                  params->listen_ch,
-                                                  GFP_KERNEL);
-       }
-
-       return 0;
-}
-
-void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
-                                         struct wireless_dev *wdev,
-                                         struct mgmt_frame_regs *upd)
-{
-       struct wilc *wl = wiphy_priv(wiphy);
-       struct wilc_vif *vif = netdev_priv(wdev->netdev);
-       u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
-       u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4);
-
-       if (wl->initialized) {
-               bool prev = vif->mgmt_reg_stypes & presp_bit;
-               bool now = upd->interface_stypes & presp_bit;
-
-               if (now != prev)
-                       wilc_frame_register(vif, IEEE80211_STYPE_PROBE_REQ, now);
-
-               prev = vif->mgmt_reg_stypes & action_bit;
-               now = upd->interface_stypes & action_bit;
-
-               if (now != prev)
-                       wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now);
-       }
-
-       vif->mgmt_reg_stypes =
-               upd->interface_stypes & (presp_bit | action_bit);
-}
-
-static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
-                              s32 rssi_thold, u32 rssi_hyst)
-{
-       return 0;
-}
-
-static int dump_station(struct wiphy *wiphy, struct net_device *dev,
-                       int idx, u8 *mac, struct station_info *sinfo)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       int ret;
-
-       if (idx != 0)
-               return -ENOENT;
-
-       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
-
-       ret = wilc_get_rssi(vif, &sinfo->signal);
-       if (ret)
-               return ret;
-
-       memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
-       return 0;
-}
-
-static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
-                         bool enabled, int timeout)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc_priv *priv = &vif->priv;
-
-       if (!priv->hif_drv)
-               return -EIO;
-
-       wilc_set_power_mgmt(vif, enabled, timeout);
-
-       return 0;
-}
-
-static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
-                              enum nl80211_iftype type,
-                              struct vif_params *params)
-{
-       struct wilc *wl = wiphy_priv(wiphy);
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc_priv *priv = &vif->priv;
-
-       switch (type) {
-       case NL80211_IFTYPE_STATION:
-               vif->connecting = false;
-               dev->ieee80211_ptr->iftype = type;
-               priv->wdev.iftype = type;
-               vif->monitor_flag = 0;
-               if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
-                       wilc_wfi_deinit_mon_interface(wl, true);
-               vif->iftype = WILC_STATION_MODE;
-
-               if (wl->initialized)
-                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
-                                               WILC_STATION_MODE, vif->idx);
-
-               memset(priv->assoc_stainfo.sta_associated_bss, 0,
-                      WILC_MAX_NUM_STA * ETH_ALEN);
-               break;
-
-       case NL80211_IFTYPE_P2P_CLIENT:
-               vif->connecting = false;
-               dev->ieee80211_ptr->iftype = type;
-               priv->wdev.iftype = type;
-               vif->monitor_flag = 0;
-               vif->iftype = WILC_CLIENT_MODE;
-
-               if (wl->initialized)
-                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
-                                               WILC_STATION_MODE, vif->idx);
-               break;
-
-       case NL80211_IFTYPE_AP:
-               dev->ieee80211_ptr->iftype = type;
-               priv->wdev.iftype = type;
-               vif->iftype = WILC_AP_MODE;
-
-               if (wl->initialized)
-                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
-                                               WILC_AP_MODE, vif->idx);
-               break;
-
-       case NL80211_IFTYPE_P2P_GO:
-               dev->ieee80211_ptr->iftype = type;
-               priv->wdev.iftype = type;
-               vif->iftype = WILC_GO_MODE;
-
-               if (wl->initialized)
-                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
-                                               WILC_AP_MODE, vif->idx);
-               break;
-
-       default:
-               netdev_err(dev, "Unknown interface type= %d\n", type);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int start_ap(struct wiphy *wiphy, struct net_device *dev,
-                   struct cfg80211_ap_settings *settings)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       int ret;
-
-       ret = set_channel(wiphy, &settings->chandef);
-       if (ret != 0)
-               netdev_err(dev, "Error in setting channel\n");
-
-       wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
-
-       return wilc_add_beacon(vif, settings->beacon_interval,
-                                  settings->dtim_period, &settings->beacon);
-}
-
-static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
-                        struct cfg80211_beacon_data *beacon)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-
-       return wilc_add_beacon(vif, 0, 0, beacon);
-}
-
-static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
-{
-       int ret;
-       struct wilc_vif *vif = netdev_priv(dev);
-
-       wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
-
-       ret = wilc_del_beacon(vif);
-
-       if (ret)
-               netdev_err(dev, "Host delete beacon fail\n");
-
-       return ret;
-}
-
-static int add_station(struct wiphy *wiphy, struct net_device *dev,
-                      const u8 *mac, struct station_parameters *params)
-{
-       int ret = 0;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc_priv *priv = &vif->priv;
-
-       if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
-               memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
-                      ETH_ALEN);
-
-               ret = wilc_add_station(vif, mac, params);
-               if (ret)
-                       netdev_err(dev, "Host add station fail\n");
-       }
-
-       return ret;
-}
-
-static int del_station(struct wiphy *wiphy, struct net_device *dev,
-                      struct station_del_parameters *params)
-{
-       const u8 *mac = params->mac;
-       int ret = 0;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc_priv *priv = &vif->priv;
-       struct sta_info *info;
-
-       if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
-               return ret;
-
-       info = &priv->assoc_stainfo;
-
-       if (!mac)
-               ret = wilc_del_allstation(vif, info->sta_associated_bss);
-
-       ret = wilc_del_station(vif, mac);
-       if (ret)
-               netdev_err(dev, "Host delete station fail\n");
-       return ret;
-}
-
-static int change_station(struct wiphy *wiphy, struct net_device *dev,
-                         const u8 *mac, struct station_parameters *params)
-{
-       int ret = 0;
-       struct wilc_vif *vif = netdev_priv(dev);
-
-       if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
-               ret = wilc_edit_station(vif, mac, params);
-               if (ret)
-                       netdev_err(dev, "Host edit station fail\n");
-       }
-       return ret;
-}
-
-static struct wilc_vif *wilc_get_vif_from_type(struct wilc *wl, int type)
-{
-       struct wilc_vif *vif;
-
-       list_for_each_entry_rcu(vif, &wl->vif_list, list) {
-               if (vif->iftype == type)
-                       return vif;
-       }
-
-       return NULL;
-}
-
-static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
-                                            const char *name,
-                                            unsigned char name_assign_type,
-                                            enum nl80211_iftype type,
-                                            struct vif_params *params)
-{
-       struct wilc *wl = wiphy_priv(wiphy);
-       struct wilc_vif *vif;
-       struct wireless_dev *wdev;
-       int iftype;
-
-       if (type == NL80211_IFTYPE_MONITOR) {
-               struct net_device *ndev;
-               int srcu_idx;
-
-               srcu_idx = srcu_read_lock(&wl->srcu);
-               vif = wilc_get_vif_from_type(wl, WILC_AP_MODE);
-               if (!vif) {
-                       vif = wilc_get_vif_from_type(wl, WILC_GO_MODE);
-                       if (!vif) {
-                               srcu_read_unlock(&wl->srcu, srcu_idx);
-                               goto validate_interface;
-                       }
-               }
-
-               if (vif->monitor_flag) {
-                       srcu_read_unlock(&wl->srcu, srcu_idx);
-                       goto validate_interface;
-               }
-
-               ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
-               if (ndev) {
-                       vif->monitor_flag = 1;
-               } else {
-                       srcu_read_unlock(&wl->srcu, srcu_idx);
-                       return ERR_PTR(-EINVAL);
-               }
-
-               wdev = &vif->priv.wdev;
-               srcu_read_unlock(&wl->srcu, srcu_idx);
-               return wdev;
-       }
-
-validate_interface:
-       mutex_lock(&wl->vif_mutex);
-       if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
-               pr_err("Reached maximum number of interface\n");
-               mutex_unlock(&wl->vif_mutex);
-               return ERR_PTR(-EINVAL);
-       }
-       mutex_unlock(&wl->vif_mutex);
-
-       switch (type) {
-       case NL80211_IFTYPE_STATION:
-               iftype = WILC_STATION_MODE;
-               break;
-       case NL80211_IFTYPE_AP:
-               iftype = WILC_AP_MODE;
-               break;
-       default:
-               return ERR_PTR(-EOPNOTSUPP);
-       }
-
-       vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
-       if (IS_ERR(vif))
-               return ERR_CAST(vif);
-
-       return &vif->priv.wdev;
-}
-
-static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
-{
-       struct wilc *wl = wiphy_priv(wiphy);
-       struct wilc_vif *vif;
-
-       if (wdev->iftype == NL80211_IFTYPE_AP ||
-           wdev->iftype == NL80211_IFTYPE_P2P_GO)
-               wilc_wfi_deinit_mon_interface(wl, true);
-       vif = netdev_priv(wdev->netdev);
-       cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
-       unregister_netdevice(vif->ndev);
-       vif->monitor_flag = 0;
-
-       wilc_set_operation_mode(vif, 0, 0, 0);
-       mutex_lock(&wl->vif_mutex);
-       list_del_rcu(&vif->list);
-       wl->vif_num--;
-       mutex_unlock(&wl->vif_mutex);
-       synchronize_srcu(&wl->srcu);
-       return 0;
-}
-
-static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
-{
-       struct wilc *wl = wiphy_priv(wiphy);
-
-       if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
-               wl->suspend_event = true;
-       else
-               wl->suspend_event = false;
-
-       return 0;
-}
-
-static int wilc_resume(struct wiphy *wiphy)
-{
-       return 0;
-}
-
-static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
-{
-       struct wilc *wl = wiphy_priv(wiphy);
-       struct wilc_vif *vif;
-       int srcu_idx;
-
-       srcu_idx = srcu_read_lock(&wl->srcu);
-       vif = wilc_get_wl_to_vif(wl);
-       if (IS_ERR(vif)) {
-               srcu_read_unlock(&wl->srcu, srcu_idx);
-               return;
-       }
-
-       netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
-       srcu_read_unlock(&wl->srcu, srcu_idx);
-}
-
-static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
-                       enum nl80211_tx_power_setting type, int mbm)
-{
-       int ret;
-       int srcu_idx;
-       s32 tx_power = MBM_TO_DBM(mbm);
-       struct wilc *wl = wiphy_priv(wiphy);
-       struct wilc_vif *vif;
-
-       if (!wl->initialized)
-               return -EIO;
-
-       srcu_idx = srcu_read_lock(&wl->srcu);
-       vif = wilc_get_wl_to_vif(wl);
-       if (IS_ERR(vif)) {
-               srcu_read_unlock(&wl->srcu, srcu_idx);
-               return -EINVAL;
-       }
-
-       netdev_info(vif->ndev, "Setting tx power %d\n", tx_power);
-       if (tx_power < 0)
-               tx_power = 0;
-       else if (tx_power > 18)
-               tx_power = 18;
-       ret = wilc_set_tx_power(vif, tx_power);
-       if (ret)
-               netdev_err(vif->ndev, "Failed to set tx power\n");
-       srcu_read_unlock(&wl->srcu, srcu_idx);
-
-       return ret;
-}
-
-static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
-                       int *dbm)
-{
-       int ret;
-       struct wilc_vif *vif = netdev_priv(wdev->netdev);
-       struct wilc *wl = vif->wilc;
-
-       /* If firmware is not started, return. */
-       if (!wl->initialized)
-               return -EIO;
-
-       ret = wilc_get_tx_power(vif, (u8 *)dbm);
-       if (ret)
-               netdev_err(vif->ndev, "Failed to get tx power\n");
-
-       return ret;
-}
-
-static const struct cfg80211_ops wilc_cfg80211_ops = {
-       .set_monitor_channel = set_channel,
-       .scan = scan,
-       .connect = connect,
-       .disconnect = disconnect,
-       .add_key = add_key,
-       .del_key = del_key,
-       .get_key = get_key,
-       .set_default_key = set_default_key,
-       .add_virtual_intf = add_virtual_intf,
-       .del_virtual_intf = del_virtual_intf,
-       .change_virtual_intf = change_virtual_intf,
-
-       .start_ap = start_ap,
-       .change_beacon = change_beacon,
-       .stop_ap = stop_ap,
-       .add_station = add_station,
-       .del_station = del_station,
-       .change_station = change_station,
-       .get_station = get_station,
-       .dump_station = dump_station,
-       .change_bss = change_bss,
-       .set_wiphy_params = set_wiphy_params,
-
-       .set_pmksa = set_pmksa,
-       .del_pmksa = del_pmksa,
-       .flush_pmksa = flush_pmksa,
-       .remain_on_channel = remain_on_channel,
-       .cancel_remain_on_channel = cancel_remain_on_channel,
-       .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
-       .mgmt_tx = mgmt_tx,
-       .update_mgmt_frame_registrations = wilc_update_mgmt_frame_registrations,
-       .set_power_mgmt = set_power_mgmt,
-       .set_cqm_rssi_config = set_cqm_rssi_config,
-
-       .suspend = wilc_suspend,
-       .resume = wilc_resume,
-       .set_wakeup = wilc_set_wakeup,
-       .set_tx_power = set_tx_power,
-       .get_tx_power = get_tx_power,
-
-};
-
-static void wlan_init_locks(struct wilc *wl)
-{
-       mutex_init(&wl->hif_cs);
-       mutex_init(&wl->rxq_cs);
-       mutex_init(&wl->cfg_cmd_lock);
-       mutex_init(&wl->vif_mutex);
-
-       spin_lock_init(&wl->txq_spinlock);
-       mutex_init(&wl->txq_add_to_head_cs);
-
-       init_completion(&wl->txq_event);
-       init_completion(&wl->cfg_event);
-       init_completion(&wl->sync_event);
-       init_completion(&wl->txq_thread_started);
-       init_srcu_struct(&wl->srcu);
-}
-
-void wlan_deinit_locks(struct wilc *wilc)
-{
-       mutex_destroy(&wilc->hif_cs);
-       mutex_destroy(&wilc->rxq_cs);
-       mutex_destroy(&wilc->cfg_cmd_lock);
-       mutex_destroy(&wilc->txq_add_to_head_cs);
-       mutex_destroy(&wilc->vif_mutex);
-       cleanup_srcu_struct(&wilc->srcu);
-}
-
-int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
-                      const struct wilc_hif_func *ops)
-{
-       struct wilc *wl;
-       struct wilc_vif *vif;
-       int ret;
-
-       wl = wilc_create_wiphy(dev);
-       if (!wl)
-               return -EINVAL;
-
-       wlan_init_locks(wl);
-
-       ret = wilc_wlan_cfg_init(wl);
-       if (ret)
-               goto free_wl;
-
-       *wilc = wl;
-       wl->io_type = io_type;
-       wl->hif_func = ops;
-       wl->chip_ps_state = WILC_CHIP_WAKEDUP;
-       INIT_LIST_HEAD(&wl->txq_head.list);
-       INIT_LIST_HEAD(&wl->rxq_head.list);
-       INIT_LIST_HEAD(&wl->vif_list);
-
-       wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
-       if (!wl->hif_workqueue) {
-               ret = -ENOMEM;
-               goto free_cfg;
-       }
-       vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
-                                  NL80211_IFTYPE_STATION, false);
-       if (IS_ERR(vif)) {
-               ret = PTR_ERR(vif);
-               goto free_hq;
-       }
-
-       return 0;
-
-free_hq:
-       destroy_workqueue(wl->hif_workqueue);
-
-free_cfg:
-       wilc_wlan_cfg_deinit(wl);
-
-free_wl:
-       wlan_deinit_locks(wl);
-       wiphy_unregister(wl->wiphy);
-       wiphy_free(wl->wiphy);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
-
-struct wilc *wilc_create_wiphy(struct device *dev)
-{
-       struct wiphy *wiphy;
-       struct wilc *wl;
-       int ret;
-
-       wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
-       if (!wiphy)
-               return NULL;
-
-       wl = wiphy_priv(wiphy);
-
-       memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
-       memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
-       wl->band.bitrates = wl->bitrates;
-       wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
-       wl->band.channels = wl->channels;
-       wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
-
-       wl->band.ht_cap.ht_supported = 1;
-       wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
-       wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
-       wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
-       wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
-
-       wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
-
-       wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
-#ifdef CONFIG_PM
-       wiphy->wowlan = &wowlan_support;
-#endif
-       wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
-       wiphy->max_scan_ie_len = 1000;
-       wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-       memcpy(wl->cipher_suites, wilc_cipher_suites,
-              sizeof(wilc_cipher_suites));
-       wiphy->cipher_suites = wl->cipher_suites;
-       wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
-       wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
-
-       wiphy->max_remain_on_channel_duration = 500;
-       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-                               BIT(NL80211_IFTYPE_AP) |
-                               BIT(NL80211_IFTYPE_MONITOR) |
-                               BIT(NL80211_IFTYPE_P2P_GO) |
-                               BIT(NL80211_IFTYPE_P2P_CLIENT);
-       wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
-
-       set_wiphy_dev(wiphy, dev);
-       wl->wiphy = wiphy;
-       ret = wiphy_register(wiphy);
-       if (ret) {
-               wiphy_free(wiphy);
-               return NULL;
-       }
-       return wl;
-}
-
-int wilc_init_host_int(struct net_device *net)
-{
-       int ret;
-       struct wilc_vif *vif = netdev_priv(net);
-       struct wilc_priv *priv = &vif->priv;
-
-       priv->p2p_listen_state = false;
-
-       mutex_init(&priv->scan_req_lock);
-       ret = wilc_init(net, &priv->hif_drv);
-       if (ret)
-               netdev_err(net, "Error while initializing hostinterface\n");
-
-       return ret;
-}
-
-void wilc_deinit_host_int(struct net_device *net)
-{
-       int ret;
-       struct wilc_vif *vif = netdev_priv(net);
-       struct wilc_priv *priv = &vif->priv;
-
-       priv->p2p_listen_state = false;
-
-       flush_workqueue(vif->wilc->hif_workqueue);
-       mutex_destroy(&priv->scan_req_lock);
-       ret = wilc_deinit(vif);
-
-       if (ret)
-               netdev_err(net, "Error while deinitializing host interface\n");
-}
-
diff --git a/drivers/staging/wilc1000/cfg80211.h b/drivers/staging/wilc1000/cfg80211.h
deleted file mode 100644 (file)
index 37b294c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#ifndef WILC_CFG80211_H
-#define WILC_CFG80211_H
-#include "netdev.h"
-
-struct wiphy *wilc_cfg_alloc(void);
-int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
-                      const struct wilc_hif_func *ops);
-struct wilc *wilc_create_wiphy(struct device *dev);
-void wilc_deinit_host_int(struct net_device *net);
-int wilc_init_host_int(struct net_device *net);
-void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size);
-struct wilc_vif *wilc_netdev_interface(struct wilc *wl, const char *name,
-                                      enum nl80211_iftype type);
-void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked);
-struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
-                                              const char *name,
-                                              struct net_device *real_dev);
-void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
-                                         struct wireless_dev *wdev,
-                                         struct mgmt_frame_regs *upd);
-struct wilc_vif *wilc_get_interface(struct wilc *wl);
-struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl);
-void wlan_deinit_locks(struct wilc *wilc);
-#endif
diff --git a/drivers/staging/wilc1000/fw.h b/drivers/staging/wilc1000/fw.h
deleted file mode 100644 (file)
index a76e1de..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#ifndef WILC_FW_H
-#define WILC_FW_H
-
-#include <linux/ieee80211.h>
-
-#define WILC_MAX_NUM_STA                       9
-#define WILC_MAX_RATES_SUPPORTED               12
-#define WILC_MAX_NUM_PMKIDS                    16
-#define WILC_MAX_NUM_SCANNED_CH                        14
-
-struct wilc_assoc_resp {
-       __le16 capab_info;
-       __le16 status_code;
-       __le16 aid;
-} __packed;
-
-struct wilc_pmkid {
-       u8 bssid[ETH_ALEN];
-       u8 pmkid[WLAN_PMKID_LEN];
-} __packed;
-
-struct wilc_pmkid_attr {
-       u8 numpmkid;
-       struct wilc_pmkid pmkidlist[WILC_MAX_NUM_PMKIDS];
-} __packed;
-
-struct wilc_reg_frame {
-       u8 reg;
-       u8 reg_id;
-       __le16 frame_type;
-} __packed;
-
-struct wilc_drv_handler {
-       __le32 handler;
-       u8 mode;
-} __packed;
-
-struct wilc_wep_key {
-       u8 index;
-       u8 key_len;
-       u8 key[0];
-} __packed;
-
-struct wilc_sta_wpa_ptk {
-       u8 mac_addr[ETH_ALEN];
-       u8 key_len;
-       u8 key[0];
-} __packed;
-
-struct wilc_ap_wpa_ptk {
-       u8 mac_addr[ETH_ALEN];
-       u8 index;
-       u8 key_len;
-       u8 key[0];
-} __packed;
-
-struct wilc_gtk_key {
-       u8 mac_addr[ETH_ALEN];
-       u8 rsc[8];
-       u8 index;
-       u8 key_len;
-       u8 key[0];
-} __packed;
-
-struct wilc_op_mode {
-       __le32 mode;
-} __packed;
-
-struct wilc_noa_opp_enable {
-       u8 ct_window;
-       u8 cnt;
-       __le32 duration;
-       __le32 interval;
-       __le32 start_time;
-} __packed;
-
-struct wilc_noa_opp_disable {
-       u8 cnt;
-       __le32 duration;
-       __le32 interval;
-       __le32 start_time;
-} __packed;
-
-struct wilc_join_bss_param {
-       char ssid[IEEE80211_MAX_SSID_LEN];
-       u8 ssid_terminator;
-       u8 bss_type;
-       u8 ch;
-       __le16 cap_info;
-       u8 sa[ETH_ALEN];
-       u8 bssid[ETH_ALEN];
-       __le16 beacon_period;
-       u8 dtim_period;
-       u8 supp_rates[WILC_MAX_RATES_SUPPORTED + 1];
-       u8 wmm_cap;
-       u8 uapsd_cap;
-       u8 ht_capable;
-       u8 rsn_found;
-       u8 rsn_grp_policy;
-       u8 mode_802_11i;
-       u8 p_suites[3];
-       u8 akm_suites[3];
-       u8 rsn_cap[2];
-       u8 noa_enabled;
-       __le32 tsf_lo;
-       u8 idx;
-       u8 opp_enabled;
-       union {
-               struct wilc_noa_opp_disable opp_dis;
-               struct wilc_noa_opp_enable opp_en;
-       };
-} __packed;
-#endif
diff --git a/drivers/staging/wilc1000/hif.c b/drivers/staging/wilc1000/hif.c
deleted file mode 100644 (file)
index d025a30..0000000
+++ /dev/null
@@ -1,1961 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#include "netdev.h"
-
-#define WILC_HIF_SCAN_TIMEOUT_MS                5000
-#define WILC_HIF_CONNECT_TIMEOUT_MS             9500
-
-#define WILC_FALSE_FRMWR_CHANNEL               100
-
-#define WILC_SCAN_WID_LIST_SIZE                6
-
-struct wilc_rcvd_mac_info {
-       u8 status;
-};
-
-struct wilc_set_multicast {
-       u32 enabled;
-       u32 cnt;
-       u8 *mc_list;
-};
-
-struct wilc_del_all_sta {
-       u8 assoc_sta;
-       u8 mac[WILC_MAX_NUM_STA][ETH_ALEN];
-};
-
-union wilc_message_body {
-       struct wilc_rcvd_net_info net_info;
-       struct wilc_rcvd_mac_info mac_info;
-       struct wilc_set_multicast mc_info;
-       struct wilc_remain_ch remain_on_ch;
-       char *data;
-};
-
-struct host_if_msg {
-       union wilc_message_body body;
-       struct wilc_vif *vif;
-       struct work_struct work;
-       void (*fn)(struct work_struct *ws);
-       struct completion work_comp;
-       bool is_sync;
-};
-
-/* 'msg' should be free by the caller for syc */
-static struct host_if_msg*
-wilc_alloc_work(struct wilc_vif *vif, void (*work_fun)(struct work_struct *),
-               bool is_sync)
-{
-       struct host_if_msg *msg;
-
-       if (!work_fun)
-               return ERR_PTR(-EINVAL);
-
-       msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
-       if (!msg)
-               return ERR_PTR(-ENOMEM);
-       msg->fn = work_fun;
-       msg->vif = vif;
-       msg->is_sync = is_sync;
-       if (is_sync)
-               init_completion(&msg->work_comp);
-
-       return msg;
-}
-
-static int wilc_enqueue_work(struct host_if_msg *msg)
-{
-       INIT_WORK(&msg->work, msg->fn);
-
-       if (!msg->vif || !msg->vif->wilc || !msg->vif->wilc->hif_workqueue)
-               return -EINVAL;
-
-       if (!queue_work(msg->vif->wilc->hif_workqueue, &msg->work))
-               return -EINVAL;
-
-       return 0;
-}
-
-/* The idx starts from 0 to (NUM_CONCURRENT_IFC - 1), but 0 index used as
- * special purpose in wilc device, so we add 1 to the index to starts from 1.
- * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
- */
-int wilc_get_vif_idx(struct wilc_vif *vif)
-{
-       return vif->idx + 1;
-}
-
-/* We need to minus 1 from idx which is from wilc device to get real index
- * of wilc->vif[], because we add 1 when pass to wilc device in the function
- * wilc_get_vif_idx.
- * As a result, the index should be between 0 and (NUM_CONCURRENT_IFC - 1).
- */
-static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
-{
-       int index = idx - 1;
-       struct wilc_vif *vif;
-
-       if (index < 0 || index >= WILC_NUM_CONCURRENT_IFC)
-               return NULL;
-
-       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
-               if (vif->idx == index)
-                       return vif;
-       }
-
-       return NULL;
-}
-
-static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
-{
-       int result = 0;
-       u8 abort_running_scan;
-       struct wid wid;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-       struct wilc_user_scan_req *scan_req;
-
-       if (evt == SCAN_EVENT_ABORTED) {
-               abort_running_scan = 1;
-               wid.id = WID_ABORT_RUNNING_SCAN;
-               wid.type = WID_CHAR;
-               wid.val = (s8 *)&abort_running_scan;
-               wid.size = sizeof(char);
-
-               result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-               if (result) {
-                       netdev_err(vif->ndev, "Failed to set abort running\n");
-                       result = -EFAULT;
-               }
-       }
-
-       if (!hif_drv) {
-               netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
-               return result;
-       }
-
-       scan_req = &hif_drv->usr_scan_req;
-       if (scan_req->scan_result) {
-               scan_req->scan_result(evt, NULL, scan_req->arg);
-               scan_req->scan_result = NULL;
-       }
-
-       return result;
-}
-
-int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
-             u8 *ch_freq_list, u8 ch_list_len,
-             void (*scan_result_fn)(enum scan_event,
-                                    struct wilc_rcvd_net_info *, void *),
-             void *user_arg, struct cfg80211_scan_request *request)
-{
-       int result = 0;
-       struct wid wid_list[WILC_SCAN_WID_LIST_SIZE];
-       u32 index = 0;
-       u32 i, scan_timeout;
-       u8 *buffer;
-       u8 valuesize = 0;
-       u8 *search_ssid_vals = NULL;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-
-       if (hif_drv->hif_state >= HOST_IF_SCANNING &&
-           hif_drv->hif_state < HOST_IF_CONNECTED) {
-               netdev_err(vif->ndev, "Already scan\n");
-               result = -EBUSY;
-               goto error;
-       }
-
-       if (vif->connecting) {
-               netdev_err(vif->ndev, "Don't do obss scan\n");
-               result = -EBUSY;
-               goto error;
-       }
-
-       hif_drv->usr_scan_req.ch_cnt = 0;
-
-       if (request->n_ssids) {
-               for (i = 0; i < request->n_ssids; i++)
-                       valuesize += ((request->ssids[i].ssid_len) + 1);
-               search_ssid_vals = kmalloc(valuesize + 1, GFP_KERNEL);
-               if (search_ssid_vals) {
-                       wid_list[index].id = WID_SSID_PROBE_REQ;
-                       wid_list[index].type = WID_STR;
-                       wid_list[index].val = search_ssid_vals;
-                       buffer = wid_list[index].val;
-
-                       *buffer++ = request->n_ssids;
-
-                       for (i = 0; i < request->n_ssids; i++) {
-                               *buffer++ = request->ssids[i].ssid_len;
-                               memcpy(buffer, request->ssids[i].ssid,
-                                      request->ssids[i].ssid_len);
-                               buffer += request->ssids[i].ssid_len;
-                       }
-                       wid_list[index].size = (s32)(valuesize + 1);
-                       index++;
-               }
-       }
-
-       wid_list[index].id = WID_INFO_ELEMENT_PROBE;
-       wid_list[index].type = WID_BIN_DATA;
-       wid_list[index].val = (s8 *)request->ie;
-       wid_list[index].size = request->ie_len;
-       index++;
-
-       wid_list[index].id = WID_SCAN_TYPE;
-       wid_list[index].type = WID_CHAR;
-       wid_list[index].size = sizeof(char);
-       wid_list[index].val = (s8 *)&scan_type;
-       index++;
-
-       if (scan_type == WILC_FW_PASSIVE_SCAN && request->duration) {
-               wid_list[index].id = WID_PASSIVE_SCAN_TIME;
-               wid_list[index].type = WID_SHORT;
-               wid_list[index].size = sizeof(u16);
-               wid_list[index].val = (s8 *)&request->duration;
-               index++;
-
-               scan_timeout = (request->duration * ch_list_len) + 500;
-       } else {
-               scan_timeout = WILC_HIF_SCAN_TIMEOUT_MS;
-       }
-
-       wid_list[index].id = WID_SCAN_CHANNEL_LIST;
-       wid_list[index].type = WID_BIN_DATA;
-
-       if (ch_freq_list && ch_list_len > 0) {
-               for (i = 0; i < ch_list_len; i++) {
-                       if (ch_freq_list[i] > 0)
-                               ch_freq_list[i] -= 1;
-               }
-       }
-
-       wid_list[index].val = ch_freq_list;
-       wid_list[index].size = ch_list_len;
-       index++;
-
-       wid_list[index].id = WID_START_SCAN_REQ;
-       wid_list[index].type = WID_CHAR;
-       wid_list[index].size = sizeof(char);
-       wid_list[index].val = (s8 *)&scan_source;
-       index++;
-
-       hif_drv->usr_scan_req.scan_result = scan_result_fn;
-       hif_drv->usr_scan_req.arg = user_arg;
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, index);
-       if (result) {
-               netdev_err(vif->ndev, "Failed to send scan parameters\n");
-               goto error;
-       }
-
-       hif_drv->scan_timer_vif = vif;
-       mod_timer(&hif_drv->scan_timer,
-                 jiffies + msecs_to_jiffies(scan_timeout));
-
-error:
-
-       kfree(search_ssid_vals);
-
-       return result;
-}
-
-static int wilc_send_connect_wid(struct wilc_vif *vif)
-{
-       int result = 0;
-       struct wid wid_list[4];
-       u32 wid_cnt = 0;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-       struct wilc_conn_info *conn_attr = &hif_drv->conn_info;
-       struct wilc_join_bss_param *bss_param = conn_attr->param;
-
-       wid_list[wid_cnt].id = WID_INFO_ELEMENT_ASSOCIATE;
-       wid_list[wid_cnt].type = WID_BIN_DATA;
-       wid_list[wid_cnt].val = conn_attr->req_ies;
-       wid_list[wid_cnt].size = conn_attr->req_ies_len;
-       wid_cnt++;
-
-       wid_list[wid_cnt].id = WID_11I_MODE;
-       wid_list[wid_cnt].type = WID_CHAR;
-       wid_list[wid_cnt].size = sizeof(char);
-       wid_list[wid_cnt].val = (s8 *)&conn_attr->security;
-       wid_cnt++;
-
-       wid_list[wid_cnt].id = WID_AUTH_TYPE;
-       wid_list[wid_cnt].type = WID_CHAR;
-       wid_list[wid_cnt].size = sizeof(char);
-       wid_list[wid_cnt].val = (s8 *)&conn_attr->auth_type;
-       wid_cnt++;
-
-       wid_list[wid_cnt].id = WID_JOIN_REQ_EXTENDED;
-       wid_list[wid_cnt].type = WID_STR;
-       wid_list[wid_cnt].size = sizeof(*bss_param);
-       wid_list[wid_cnt].val = (u8 *)bss_param;
-       wid_cnt++;
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, wid_cnt);
-       if (result) {
-               netdev_err(vif->ndev, "failed to send config packet\n");
-               goto error;
-       } else {
-               hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
-       }
-
-       return 0;
-
-error:
-
-       kfree(conn_attr->req_ies);
-       conn_attr->req_ies = NULL;
-
-       return result;
-}
-
-static void handle_connect_timeout(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-       struct wilc_vif *vif = msg->vif;
-       int result;
-       struct wid wid;
-       u16 dummy_reason_code = 0;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-
-       if (!hif_drv) {
-               netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
-               goto out;
-       }
-
-       hif_drv->hif_state = HOST_IF_IDLE;
-
-       if (hif_drv->conn_info.conn_result) {
-               hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
-                                              WILC_MAC_STATUS_DISCONNECTED,
-                                              hif_drv->conn_info.arg);
-
-       } else {
-               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
-       }
-
-       wid.id = WID_DISCONNECT;
-       wid.type = WID_CHAR;
-       wid.val = (s8 *)&dummy_reason_code;
-       wid.size = sizeof(char);
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to send disconnect\n");
-
-       hif_drv->conn_info.req_ies_len = 0;
-       kfree(hif_drv->conn_info.req_ies);
-       hif_drv->conn_info.req_ies = NULL;
-
-out:
-       kfree(msg);
-}
-
-void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
-                               struct cfg80211_crypto_settings *crypto)
-{
-       struct wilc_join_bss_param *param;
-       struct ieee80211_p2p_noa_attr noa_attr;
-       u8 rates_len = 0;
-       const u8 *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie;
-       const u8 *ht_ie, *wpa_ie, *wmm_ie, *rsn_ie;
-       int ret;
-       const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies);
-
-       param = kzalloc(sizeof(*param), GFP_KERNEL);
-       if (!param)
-               return NULL;
-
-       param->beacon_period = cpu_to_le16(bss->beacon_interval);
-       param->cap_info = cpu_to_le16(bss->capability);
-       param->bss_type = WILC_FW_BSS_TYPE_INFRA;
-       param->ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
-       ether_addr_copy(param->bssid, bss->bssid);
-
-       ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
-       if (ssid_elm) {
-               if (ssid_elm[1] <= IEEE80211_MAX_SSID_LEN)
-                       memcpy(param->ssid, ssid_elm + 2, ssid_elm[1]);
-       }
-
-       tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len);
-       if (tim_elm && tim_elm[1] >= 2)
-               param->dtim_period = tim_elm[3];
-
-       memset(param->p_suites, 0xFF, 3);
-       memset(param->akm_suites, 0xFF, 3);
-
-       rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies->data, ies->len);
-       if (rates_ie) {
-               rates_len = rates_ie[1];
-               if (rates_len > WILC_MAX_RATES_SUPPORTED)
-                       rates_len = WILC_MAX_RATES_SUPPORTED;
-               param->supp_rates[0] = rates_len;
-               memcpy(&param->supp_rates[1], rates_ie + 2, rates_len);
-       }
-
-       if (rates_len < WILC_MAX_RATES_SUPPORTED) {
-               supp_rates_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES,
-                                                ies->data, ies->len);
-               if (supp_rates_ie) {
-                       u8 ext_rates = supp_rates_ie[1];
-
-                       if (ext_rates > (WILC_MAX_RATES_SUPPORTED - rates_len))
-                               param->supp_rates[0] = WILC_MAX_RATES_SUPPORTED;
-                       else
-                               param->supp_rates[0] += ext_rates;
-
-                       memcpy(&param->supp_rates[rates_len + 1],
-                              supp_rates_ie + 2,
-                              (param->supp_rates[0] - rates_len));
-               }
-       }
-
-       ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies->data, ies->len);
-       if (ht_ie)
-               param->ht_capable = true;
-
-       ret = cfg80211_get_p2p_attr(ies->data, ies->len,
-                                   IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
-                                   (u8 *)&noa_attr, sizeof(noa_attr));
-       if (ret > 0) {
-               param->tsf_lo = cpu_to_le32(ies->tsf);
-               param->noa_enabled = 1;
-               param->idx = noa_attr.index;
-               if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) {
-                       param->opp_enabled = 1;
-                       param->opp_en.ct_window = noa_attr.oppps_ctwindow;
-                       param->opp_en.cnt = noa_attr.desc[0].count;
-                       param->opp_en.duration = noa_attr.desc[0].duration;
-                       param->opp_en.interval = noa_attr.desc[0].interval;
-                       param->opp_en.start_time = noa_attr.desc[0].start_time;
-               } else {
-                       param->opp_enabled = 0;
-                       param->opp_dis.cnt = noa_attr.desc[0].count;
-                       param->opp_dis.duration = noa_attr.desc[0].duration;
-                       param->opp_dis.interval = noa_attr.desc[0].interval;
-                       param->opp_dis.start_time = noa_attr.desc[0].start_time;
-               }
-       }
-       wmm_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
-                                        WLAN_OUI_TYPE_MICROSOFT_WMM,
-                                        ies->data, ies->len);
-       if (wmm_ie) {
-               struct ieee80211_wmm_param_ie *ie;
-
-               ie = (struct ieee80211_wmm_param_ie *)wmm_ie;
-               if ((ie->oui_subtype == 0 || ie->oui_subtype == 1) &&
-                   ie->version == 1) {
-                       param->wmm_cap = true;
-                       if (ie->qos_info & BIT(7))
-                               param->uapsd_cap = true;
-               }
-       }
-
-       wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
-                                        WLAN_OUI_TYPE_MICROSOFT_WPA,
-                                        ies->data, ies->len);
-       if (wpa_ie) {
-               param->mode_802_11i = 1;
-               param->rsn_found = true;
-       }
-
-       rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
-       if (rsn_ie) {
-               int offset = 8;
-
-               param->mode_802_11i = 2;
-               param->rsn_found = true;
-               /* extract RSN capabilities */
-               offset += (rsn_ie[offset] * 4) + 2;
-               offset += (rsn_ie[offset] * 4) + 2;
-               memcpy(param->rsn_cap, &rsn_ie[offset], 2);
-       }
-
-       if (param->rsn_found) {
-               int i;
-
-               param->rsn_grp_policy = crypto->cipher_group & 0xFF;
-               for (i = 0; i < crypto->n_ciphers_pairwise && i < 3; i++)
-                       param->p_suites[i] = crypto->ciphers_pairwise[i] & 0xFF;
-
-               for (i = 0; i < crypto->n_akm_suites && i < 3; i++)
-                       param->akm_suites[i] = crypto->akm_suites[i] & 0xFF;
-       }
-
-       return (void *)param;
-}
-
-static void handle_rcvd_ntwrk_info(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-       struct wilc_rcvd_net_info *rcvd_info = &msg->body.net_info;
-       struct wilc_user_scan_req *scan_req = &msg->vif->hif_drv->usr_scan_req;
-       const u8 *ch_elm;
-       u8 *ies;
-       int ies_len;
-       size_t offset;
-
-       if (ieee80211_is_probe_resp(rcvd_info->mgmt->frame_control))
-               offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
-       else if (ieee80211_is_beacon(rcvd_info->mgmt->frame_control))
-               offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
-       else
-               goto done;
-
-       ies = rcvd_info->mgmt->u.beacon.variable;
-       ies_len = rcvd_info->frame_len - offset;
-       if (ies_len <= 0)
-               goto done;
-
-       ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len);
-       if (ch_elm && ch_elm[1] > 0)
-               rcvd_info->ch = ch_elm[2];
-
-       if (scan_req->scan_result)
-               scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, rcvd_info,
-                                     scan_req->arg);
-
-done:
-       kfree(rcvd_info->mgmt);
-       kfree(msg);
-}
-
-static void host_int_get_assoc_res_info(struct wilc_vif *vif,
-                                       u8 *assoc_resp_info,
-                                       u32 max_assoc_resp_info_len,
-                                       u32 *rcvd_assoc_resp_info_len)
-{
-       int result;
-       struct wid wid;
-
-       wid.id = WID_ASSOC_RES_INFO;
-       wid.type = WID_STR;
-       wid.val = assoc_resp_info;
-       wid.size = max_assoc_resp_info_len;
-
-       result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
-       if (result) {
-               *rcvd_assoc_resp_info_len = 0;
-               netdev_err(vif->ndev, "Failed to send association response\n");
-               return;
-       }
-
-       *rcvd_assoc_resp_info_len = wid.size;
-}
-
-static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len,
-                                     struct wilc_conn_info *ret_conn_info)
-{
-       u8 *ies;
-       u16 ies_len;
-       struct wilc_assoc_resp *res = (struct wilc_assoc_resp *)buffer;
-
-       ret_conn_info->status = le16_to_cpu(res->status_code);
-       if (ret_conn_info->status == WLAN_STATUS_SUCCESS) {
-               ies = &buffer[sizeof(*res)];
-               ies_len = buffer_len - sizeof(*res);
-
-               ret_conn_info->resp_ies = kmemdup(ies, ies_len, GFP_KERNEL);
-               if (!ret_conn_info->resp_ies)
-                       return -ENOMEM;
-
-               ret_conn_info->resp_ies_len = ies_len;
-       }
-
-       return 0;
-}
-
-static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
-                                                 u8 mac_status)
-{
-       struct host_if_drv *hif_drv = vif->hif_drv;
-       struct wilc_conn_info *conn_info = &hif_drv->conn_info;
-
-       if (mac_status == WILC_MAC_STATUS_CONNECTED) {
-               u32 assoc_resp_info_len;
-
-               memset(hif_drv->assoc_resp, 0, WILC_MAX_ASSOC_RESP_FRAME_SIZE);
-
-               host_int_get_assoc_res_info(vif, hif_drv->assoc_resp,
-                                           WILC_MAX_ASSOC_RESP_FRAME_SIZE,
-                                           &assoc_resp_info_len);
-
-               if (assoc_resp_info_len != 0) {
-                       s32 err = 0;
-
-                       err = wilc_parse_assoc_resp_info(hif_drv->assoc_resp,
-                                                        assoc_resp_info_len,
-                                                        conn_info);
-                       if (err)
-                               netdev_err(vif->ndev,
-                                          "wilc_parse_assoc_resp_info() returned error %d\n",
-                                          err);
-               }
-       }
-
-       del_timer(&hif_drv->connect_timer);
-       conn_info->conn_result(CONN_DISCONN_EVENT_CONN_RESP, mac_status,
-                              hif_drv->conn_info.arg);
-
-       if (mac_status == WILC_MAC_STATUS_CONNECTED &&
-           conn_info->status == WLAN_STATUS_SUCCESS) {
-               ether_addr_copy(hif_drv->assoc_bssid, conn_info->bssid);
-               hif_drv->hif_state = HOST_IF_CONNECTED;
-       } else {
-               hif_drv->hif_state = HOST_IF_IDLE;
-       }
-
-       kfree(conn_info->resp_ies);
-       conn_info->resp_ies = NULL;
-       conn_info->resp_ies_len = 0;
-
-       kfree(conn_info->req_ies);
-       conn_info->req_ies = NULL;
-       conn_info->req_ies_len = 0;
-}
-
-static inline void host_int_handle_disconnect(struct wilc_vif *vif)
-{
-       struct host_if_drv *hif_drv = vif->hif_drv;
-
-       if (hif_drv->usr_scan_req.scan_result) {
-               del_timer(&hif_drv->scan_timer);
-               handle_scan_done(vif, SCAN_EVENT_ABORTED);
-       }
-
-       if (hif_drv->conn_info.conn_result)
-               hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
-                                              0, hif_drv->conn_info.arg);
-       else
-               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
-
-       eth_zero_addr(hif_drv->assoc_bssid);
-
-       hif_drv->conn_info.req_ies_len = 0;
-       kfree(hif_drv->conn_info.req_ies);
-       hif_drv->conn_info.req_ies = NULL;
-       hif_drv->hif_state = HOST_IF_IDLE;
-}
-
-static void handle_rcvd_gnrl_async_info(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-       struct wilc_vif *vif = msg->vif;
-       struct wilc_rcvd_mac_info *mac_info = &msg->body.mac_info;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-
-       if (!hif_drv) {
-               netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
-               goto free_msg;
-       }
-
-       if (!hif_drv->conn_info.conn_result) {
-               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
-               goto free_msg;
-       }
-
-       if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
-               host_int_parse_assoc_resp_info(vif, mac_info->status);
-       } else if (mac_info->status == WILC_MAC_STATUS_DISCONNECTED) {
-               if (hif_drv->hif_state == HOST_IF_CONNECTED) {
-                       host_int_handle_disconnect(vif);
-               } else if (hif_drv->usr_scan_req.scan_result) {
-                       del_timer(&hif_drv->scan_timer);
-                       handle_scan_done(vif, SCAN_EVENT_ABORTED);
-               }
-       }
-
-free_msg:
-       kfree(msg);
-}
-
-int wilc_disconnect(struct wilc_vif *vif)
-{
-       struct wid wid;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-       struct wilc_user_scan_req *scan_req;
-       struct wilc_conn_info *conn_info;
-       int result;
-       u16 dummy_reason_code = 0;
-
-       wid.id = WID_DISCONNECT;
-       wid.type = WID_CHAR;
-       wid.val = (s8 *)&dummy_reason_code;
-       wid.size = sizeof(char);
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result) {
-               netdev_err(vif->ndev, "Failed to send disconnect\n");
-               return result;
-       }
-
-       scan_req = &hif_drv->usr_scan_req;
-       conn_info = &hif_drv->conn_info;
-
-       if (scan_req->scan_result) {
-               del_timer(&hif_drv->scan_timer);
-               scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg);
-               scan_req->scan_result = NULL;
-       }
-
-       if (conn_info->conn_result) {
-               if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
-                       del_timer(&hif_drv->connect_timer);
-
-               conn_info->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, 0,
-                                      conn_info->arg);
-       } else {
-               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
-       }
-
-       hif_drv->hif_state = HOST_IF_IDLE;
-
-       eth_zero_addr(hif_drv->assoc_bssid);
-
-       conn_info->req_ies_len = 0;
-       kfree(conn_info->req_ies);
-       conn_info->req_ies = NULL;
-
-       return 0;
-}
-
-int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
-{
-       struct wid wid_list[5];
-       u32 wid_cnt = 0, result;
-
-       wid_list[wid_cnt].id = WID_LINKSPEED;
-       wid_list[wid_cnt].type = WID_CHAR;
-       wid_list[wid_cnt].size = sizeof(char);
-       wid_list[wid_cnt].val = (s8 *)&stats->link_speed;
-       wid_cnt++;
-
-       wid_list[wid_cnt].id = WID_RSSI;
-       wid_list[wid_cnt].type = WID_CHAR;
-       wid_list[wid_cnt].size = sizeof(char);
-       wid_list[wid_cnt].val = (s8 *)&stats->rssi;
-       wid_cnt++;
-
-       wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT;
-       wid_list[wid_cnt].type = WID_INT;
-       wid_list[wid_cnt].size = sizeof(u32);
-       wid_list[wid_cnt].val = (s8 *)&stats->tx_cnt;
-       wid_cnt++;
-
-       wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT;
-       wid_list[wid_cnt].type = WID_INT;
-       wid_list[wid_cnt].size = sizeof(u32);
-       wid_list[wid_cnt].val = (s8 *)&stats->rx_cnt;
-       wid_cnt++;
-
-       wid_list[wid_cnt].id = WID_FAILED_COUNT;
-       wid_list[wid_cnt].type = WID_INT;
-       wid_list[wid_cnt].size = sizeof(u32);
-       wid_list[wid_cnt].val = (s8 *)&stats->tx_fail_cnt;
-       wid_cnt++;
-
-       result = wilc_send_config_pkt(vif, WILC_GET_CFG, wid_list, wid_cnt);
-       if (result) {
-               netdev_err(vif->ndev, "Failed to send scan parameters\n");
-               return result;
-       }
-
-       if (stats->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
-           stats->link_speed != DEFAULT_LINK_SPEED)
-               wilc_enable_tcp_ack_filter(vif, true);
-       else if (stats->link_speed != DEFAULT_LINK_SPEED)
-               wilc_enable_tcp_ack_filter(vif, false);
-
-       return result;
-}
-
-static void handle_get_statistics(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-       struct wilc_vif *vif = msg->vif;
-       struct rf_info *stats = (struct rf_info *)msg->body.data;
-
-       wilc_get_statistics(vif, stats);
-
-       kfree(msg);
-}
-
-static void wilc_hif_pack_sta_param(u8 *cur_byte, const u8 *mac,
-                                   struct station_parameters *params)
-{
-       ether_addr_copy(cur_byte, mac);
-       cur_byte += ETH_ALEN;
-
-       put_unaligned_le16(params->aid, cur_byte);
-       cur_byte += 2;
-
-       *cur_byte++ = params->supported_rates_len;
-       if (params->supported_rates_len > 0)
-               memcpy(cur_byte, params->supported_rates,
-                      params->supported_rates_len);
-       cur_byte += params->supported_rates_len;
-
-       if (params->ht_capa) {
-               *cur_byte++ = true;
-               memcpy(cur_byte, params->ht_capa,
-                      sizeof(struct ieee80211_ht_cap));
-       } else {
-               *cur_byte++ = false;
-       }
-       cur_byte += sizeof(struct ieee80211_ht_cap);
-
-       put_unaligned_le16(params->sta_flags_mask, cur_byte);
-       cur_byte += 2;
-       put_unaligned_le16(params->sta_flags_set, cur_byte);
-}
-
-static int handle_remain_on_chan(struct wilc_vif *vif,
-                                struct wilc_remain_ch *hif_remain_ch)
-{
-       int result;
-       u8 remain_on_chan_flag;
-       struct wid wid;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-
-       if (hif_drv->usr_scan_req.scan_result)
-               return -EBUSY;
-
-       if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
-               return -EBUSY;
-
-       if (vif->connecting)
-               return -EBUSY;
-
-       remain_on_chan_flag = true;
-       wid.id = WID_REMAIN_ON_CHAN;
-       wid.type = WID_STR;
-       wid.size = 2;
-       wid.val = kmalloc(wid.size, GFP_KERNEL);
-       if (!wid.val)
-               return -ENOMEM;
-
-       wid.val[0] = remain_on_chan_flag;
-       wid.val[1] = (s8)hif_remain_ch->ch;
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       kfree(wid.val);
-       if (result)
-               return -EBUSY;
-
-       hif_drv->remain_on_ch.arg = hif_remain_ch->arg;
-       hif_drv->remain_on_ch.expired = hif_remain_ch->expired;
-       hif_drv->remain_on_ch.ch = hif_remain_ch->ch;
-       hif_drv->remain_on_ch.cookie = hif_remain_ch->cookie;
-       hif_drv->remain_on_ch_timer_vif = vif;
-
-       return 0;
-}
-
-static int wilc_handle_roc_expired(struct wilc_vif *vif, u64 cookie)
-{
-       u8 remain_on_chan_flag;
-       struct wid wid;
-       int result;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-
-       if (vif->priv.p2p_listen_state) {
-               remain_on_chan_flag = false;
-               wid.id = WID_REMAIN_ON_CHAN;
-               wid.type = WID_STR;
-               wid.size = 2;
-
-               wid.val = kmalloc(wid.size, GFP_KERNEL);
-               if (!wid.val)
-                       return -ENOMEM;
-
-               wid.val[0] = remain_on_chan_flag;
-               wid.val[1] = WILC_FALSE_FRMWR_CHANNEL;
-
-               result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-               kfree(wid.val);
-               if (result != 0) {
-                       netdev_err(vif->ndev, "Failed to set remain channel\n");
-                       return -EINVAL;
-               }
-
-               if (hif_drv->remain_on_ch.expired) {
-                       hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
-                                                     cookie);
-               }
-       } else {
-               netdev_dbg(vif->ndev, "Not in listen state\n");
-       }
-
-       return 0;
-}
-
-static void wilc_handle_listen_state_expired(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-
-       wilc_handle_roc_expired(msg->vif, msg->body.remain_on_ch.cookie);
-       kfree(msg);
-}
-
-static void listen_timer_cb(struct timer_list *t)
-{
-       struct host_if_drv *hif_drv = from_timer(hif_drv, t,
-                                                     remain_on_ch_timer);
-       struct wilc_vif *vif = hif_drv->remain_on_ch_timer_vif;
-       int result;
-       struct host_if_msg *msg;
-
-       del_timer(&vif->hif_drv->remain_on_ch_timer);
-
-       msg = wilc_alloc_work(vif, wilc_handle_listen_state_expired, false);
-       if (IS_ERR(msg))
-               return;
-
-       msg->body.remain_on_ch.cookie = vif->hif_drv->remain_on_ch.cookie;
-
-       result = wilc_enqueue_work(msg);
-       if (result) {
-               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-               kfree(msg);
-       }
-}
-
-static void handle_set_mcast_filter(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-       struct wilc_vif *vif = msg->vif;
-       struct wilc_set_multicast *set_mc = &msg->body.mc_info;
-       int result;
-       struct wid wid;
-       u8 *cur_byte;
-
-       wid.id = WID_SETUP_MULTICAST_FILTER;
-       wid.type = WID_BIN;
-       wid.size = sizeof(struct wilc_set_multicast) + (set_mc->cnt * ETH_ALEN);
-       wid.val = kmalloc(wid.size, GFP_KERNEL);
-       if (!wid.val)
-               goto error;
-
-       cur_byte = wid.val;
-       put_unaligned_le32(set_mc->enabled, cur_byte);
-       cur_byte += 4;
-
-       put_unaligned_le32(set_mc->cnt, cur_byte);
-       cur_byte += 4;
-
-       if (set_mc->cnt > 0 && set_mc->mc_list)
-               memcpy(cur_byte, set_mc->mc_list, set_mc->cnt * ETH_ALEN);
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to send setup multicast\n");
-
-error:
-       kfree(set_mc->mc_list);
-       kfree(wid.val);
-       kfree(msg);
-}
-
-static void handle_scan_timer(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-
-       handle_scan_done(msg->vif, SCAN_EVENT_ABORTED);
-       kfree(msg);
-}
-
-static void handle_scan_complete(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-
-       del_timer(&msg->vif->hif_drv->scan_timer);
-
-       handle_scan_done(msg->vif, SCAN_EVENT_DONE);
-
-       kfree(msg);
-}
-
-static void timer_scan_cb(struct timer_list *t)
-{
-       struct host_if_drv *hif_drv = from_timer(hif_drv, t, scan_timer);
-       struct wilc_vif *vif = hif_drv->scan_timer_vif;
-       struct host_if_msg *msg;
-       int result;
-
-       msg = wilc_alloc_work(vif, handle_scan_timer, false);
-       if (IS_ERR(msg))
-               return;
-
-       result = wilc_enqueue_work(msg);
-       if (result)
-               kfree(msg);
-}
-
-static void timer_connect_cb(struct timer_list *t)
-{
-       struct host_if_drv *hif_drv = from_timer(hif_drv, t,
-                                                     connect_timer);
-       struct wilc_vif *vif = hif_drv->connect_timer_vif;
-       struct host_if_msg *msg;
-       int result;
-
-       msg = wilc_alloc_work(vif, handle_connect_timeout, false);
-       if (IS_ERR(msg))
-               return;
-
-       result = wilc_enqueue_work(msg);
-       if (result)
-               kfree(msg);
-}
-
-int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
-{
-       struct wid wid;
-       int result;
-
-       wid.id = WID_REMOVE_WEP_KEY;
-       wid.type = WID_STR;
-       wid.size = sizeof(char);
-       wid.val = &index;
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev,
-                          "Failed to send remove wep key config packet\n");
-       return result;
-}
-
-int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
-{
-       struct wid wid;
-       int result;
-
-       wid.id = WID_KEY_ID;
-       wid.type = WID_CHAR;
-       wid.size = sizeof(char);
-       wid.val = &index;
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev,
-                          "Failed to send wep default key config packet\n");
-
-       return result;
-}
-
-int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
-                            u8 index)
-{
-       struct wid wid;
-       int result;
-       struct wilc_wep_key *wep_key;
-
-       wid.id = WID_ADD_WEP_KEY;
-       wid.type = WID_STR;
-       wid.size = sizeof(*wep_key) + len;
-       wep_key = kzalloc(wid.size, GFP_KERNEL);
-       if (!wep_key)
-               return -ENOMEM;
-
-       wid.val = (u8 *)wep_key;
-
-       wep_key->index = index;
-       wep_key->key_len = len;
-       memcpy(wep_key->key, key, len);
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev,
-                          "Failed to add wep key config packet\n");
-
-       kfree(wep_key);
-       return result;
-}
-
-int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
-                           u8 index, u8 mode, enum authtype auth_type)
-{
-       struct wid wid_list[3];
-       int result;
-       struct wilc_wep_key *wep_key;
-
-       wid_list[0].id = WID_11I_MODE;
-       wid_list[0].type = WID_CHAR;
-       wid_list[0].size = sizeof(char);
-       wid_list[0].val = &mode;
-
-       wid_list[1].id = WID_AUTH_TYPE;
-       wid_list[1].type = WID_CHAR;
-       wid_list[1].size = sizeof(char);
-       wid_list[1].val = (s8 *)&auth_type;
-
-       wid_list[2].id = WID_WEP_KEY_VALUE;
-       wid_list[2].type = WID_STR;
-       wid_list[2].size = sizeof(*wep_key) + len;
-       wep_key = kzalloc(wid_list[2].size, GFP_KERNEL);
-       if (!wep_key)
-               return -ENOMEM;
-
-       wid_list[2].val = (u8 *)wep_key;
-
-       wep_key->index = index;
-       wep_key->key_len = len;
-       memcpy(wep_key->key, key, len);
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-                                     ARRAY_SIZE(wid_list));
-       if (result)
-               netdev_err(vif->ndev,
-                          "Failed to add wep ap key config packet\n");
-
-       kfree(wep_key);
-       return result;
-}
-
-int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
-                const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
-                u8 mode, u8 cipher_mode, u8 index)
-{
-       int result = 0;
-       u8 t_key_len  = ptk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN;
-
-       if (mode == WILC_AP_MODE) {
-               struct wid wid_list[2];
-               struct wilc_ap_wpa_ptk *key_buf;
-
-               wid_list[0].id = WID_11I_MODE;
-               wid_list[0].type = WID_CHAR;
-               wid_list[0].size = sizeof(char);
-               wid_list[0].val = (s8 *)&cipher_mode;
-
-               key_buf = kzalloc(sizeof(*key_buf) + t_key_len, GFP_KERNEL);
-               if (!key_buf)
-                       return -ENOMEM;
-
-               ether_addr_copy(key_buf->mac_addr, mac_addr);
-               key_buf->index = index;
-               key_buf->key_len = t_key_len;
-               memcpy(&key_buf->key[0], ptk, ptk_key_len);
-
-               if (rx_mic)
-                       memcpy(&key_buf->key[ptk_key_len], rx_mic,
-                              WILC_RX_MIC_KEY_LEN);
-
-               if (tx_mic)
-                       memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN],
-                              tx_mic, WILC_TX_MIC_KEY_LEN);
-
-               wid_list[1].id = WID_ADD_PTK;
-               wid_list[1].type = WID_STR;
-               wid_list[1].size = sizeof(*key_buf) + t_key_len;
-               wid_list[1].val = (u8 *)key_buf;
-               result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-                                             ARRAY_SIZE(wid_list));
-               kfree(key_buf);
-       } else if (mode == WILC_STATION_MODE) {
-               struct wid wid;
-               struct wilc_sta_wpa_ptk *key_buf;
-
-               key_buf = kzalloc(sizeof(*key_buf) + t_key_len, GFP_KERNEL);
-               if (!key_buf)
-                       return -ENOMEM;
-
-               ether_addr_copy(key_buf->mac_addr, mac_addr);
-               key_buf->key_len = t_key_len;
-               memcpy(&key_buf->key[0], ptk, ptk_key_len);
-
-               if (rx_mic)
-                       memcpy(&key_buf->key[ptk_key_len], rx_mic,
-                              WILC_RX_MIC_KEY_LEN);
-
-               if (tx_mic)
-                       memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN],
-                              tx_mic, WILC_TX_MIC_KEY_LEN);
-
-               wid.id = WID_ADD_PTK;
-               wid.type = WID_STR;
-               wid.size = sizeof(*key_buf) + t_key_len;
-               wid.val = (s8 *)key_buf;
-               result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-               kfree(key_buf);
-       }
-
-       return result;
-}
-
-int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
-                   u8 index, u32 key_rsc_len, const u8 *key_rsc,
-                   const u8 *rx_mic, const u8 *tx_mic, u8 mode,
-                   u8 cipher_mode)
-{
-       int result = 0;
-       struct wilc_gtk_key *gtk_key;
-       int t_key_len = gtk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN;
-
-       gtk_key = kzalloc(sizeof(*gtk_key) + t_key_len, GFP_KERNEL);
-       if (!gtk_key)
-               return -ENOMEM;
-
-       /* fill bssid value only in station mode */
-       if (mode == WILC_STATION_MODE &&
-           vif->hif_drv->hif_state == HOST_IF_CONNECTED)
-               memcpy(gtk_key->mac_addr, vif->hif_drv->assoc_bssid, ETH_ALEN);
-
-       if (key_rsc)
-               memcpy(gtk_key->rsc, key_rsc, 8);
-       gtk_key->index = index;
-       gtk_key->key_len = t_key_len;
-       memcpy(&gtk_key->key[0], rx_gtk, gtk_key_len);
-
-       if (rx_mic)
-               memcpy(&gtk_key->key[gtk_key_len], rx_mic, WILC_RX_MIC_KEY_LEN);
-
-       if (tx_mic)
-               memcpy(&gtk_key->key[gtk_key_len + WILC_RX_MIC_KEY_LEN],
-                      tx_mic, WILC_TX_MIC_KEY_LEN);
-
-       if (mode == WILC_AP_MODE) {
-               struct wid wid_list[2];
-
-               wid_list[0].id = WID_11I_MODE;
-               wid_list[0].type = WID_CHAR;
-               wid_list[0].size = sizeof(char);
-               wid_list[0].val = (s8 *)&cipher_mode;
-
-               wid_list[1].id = WID_ADD_RX_GTK;
-               wid_list[1].type = WID_STR;
-               wid_list[1].size = sizeof(*gtk_key) + t_key_len;
-               wid_list[1].val = (u8 *)gtk_key;
-
-               result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-                                             ARRAY_SIZE(wid_list));
-       } else if (mode == WILC_STATION_MODE) {
-               struct wid wid;
-
-               wid.id = WID_ADD_RX_GTK;
-               wid.type = WID_STR;
-               wid.size = sizeof(*gtk_key) + t_key_len;
-               wid.val = (u8 *)gtk_key;
-               result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       }
-
-       kfree(gtk_key);
-       return result;
-}
-
-int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid)
-{
-       struct wid wid;
-
-       wid.id = WID_PMKID_INFO;
-       wid.type = WID_STR;
-       wid.size = (pmkid->numpmkid * sizeof(struct wilc_pmkid)) + 1;
-       wid.val = (u8 *)pmkid;
-
-       return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-}
-
-int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
-{
-       int result;
-       struct wid wid;
-
-       wid.id = WID_MAC_ADDR;
-       wid.type = WID_STR;
-       wid.size = ETH_ALEN;
-       wid.val = mac_addr;
-
-       result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to get mac address\n");
-
-       return result;
-}
-
-int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies,
-                     size_t ies_len)
-{
-       int result;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-       struct wilc_conn_info *conn_info = &hif_drv->conn_info;
-
-       if (bssid)
-               ether_addr_copy(conn_info->bssid, bssid);
-
-       if (ies) {
-               conn_info->req_ies_len = ies_len;
-               conn_info->req_ies = kmemdup(ies, ies_len, GFP_KERNEL);
-               if (!conn_info->req_ies)
-                       return -ENOMEM;
-       }
-
-       result = wilc_send_connect_wid(vif);
-       if (result)
-               goto free_ies;
-
-       hif_drv->connect_timer_vif = vif;
-       mod_timer(&hif_drv->connect_timer,
-                 jiffies + msecs_to_jiffies(WILC_HIF_CONNECT_TIMEOUT_MS));
-
-       return 0;
-
-free_ies:
-       kfree(conn_info->req_ies);
-
-       return result;
-}
-
-int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
-{
-       struct wid wid;
-       int result;
-
-       wid.id = WID_CURRENT_CHANNEL;
-       wid.type = WID_CHAR;
-       wid.size = sizeof(char);
-       wid.val = &channel;
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to set channel\n");
-
-       return result;
-}
-
-int wilc_set_operation_mode(struct wilc_vif *vif, int index, u8 mode,
-                           u8 ifc_id)
-{
-       struct wid wid;
-       int result;
-       struct wilc_drv_handler drv;
-
-       wid.id = WID_SET_OPERATION_MODE;
-       wid.type = WID_STR;
-       wid.size = sizeof(drv);
-       wid.val = (u8 *)&drv;
-
-       drv.handler = cpu_to_le32(index);
-       drv.mode = (ifc_id | (mode << 1));
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to set driver handler\n");
-
-       return result;
-}
-
-s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val)
-{
-       struct wid wid;
-       s32 result;
-
-       wid.id = WID_SET_STA_MAC_INACTIVE_TIME;
-       wid.type = WID_STR;
-       wid.size = ETH_ALEN;
-       wid.val = kzalloc(wid.size, GFP_KERNEL);
-       if (!wid.val)
-               return -ENOMEM;
-
-       ether_addr_copy(wid.val, mac);
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       kfree(wid.val);
-       if (result) {
-               netdev_err(vif->ndev, "Failed to set inactive mac\n");
-               return result;
-       }
-
-       wid.id = WID_GET_INACTIVE_TIME;
-       wid.type = WID_INT;
-       wid.val = (s8 *)out_val;
-       wid.size = sizeof(u32);
-       result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to get inactive time\n");
-
-       return result;
-}
-
-int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
-{
-       struct wid wid;
-       int result;
-
-       if (!rssi_level) {
-               netdev_err(vif->ndev, "%s: RSSI level is NULL\n", __func__);
-               return -EFAULT;
-       }
-
-       wid.id = WID_RSSI;
-       wid.type = WID_CHAR;
-       wid.size = sizeof(char);
-       wid.val = rssi_level;
-       result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to get RSSI value\n");
-
-       return result;
-}
-
-static int wilc_get_stats_async(struct wilc_vif *vif, struct rf_info *stats)
-{
-       int result;
-       struct host_if_msg *msg;
-
-       msg = wilc_alloc_work(vif, handle_get_statistics, false);
-       if (IS_ERR(msg))
-               return PTR_ERR(msg);
-
-       msg->body.data = (char *)stats;
-
-       result = wilc_enqueue_work(msg);
-       if (result) {
-               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-               kfree(msg);
-               return result;
-       }
-
-       return result;
-}
-
-int wilc_hif_set_cfg(struct wilc_vif *vif, struct cfg_param_attr *param)
-{
-       struct wid wid_list[4];
-       int i = 0;
-
-       if (param->flag & WILC_CFG_PARAM_RETRY_SHORT) {
-               wid_list[i].id = WID_SHORT_RETRY_LIMIT;
-               wid_list[i].val = (s8 *)&param->short_retry_limit;
-               wid_list[i].type = WID_SHORT;
-               wid_list[i].size = sizeof(u16);
-               i++;
-       }
-       if (param->flag & WILC_CFG_PARAM_RETRY_LONG) {
-               wid_list[i].id = WID_LONG_RETRY_LIMIT;
-               wid_list[i].val = (s8 *)&param->long_retry_limit;
-               wid_list[i].type = WID_SHORT;
-               wid_list[i].size = sizeof(u16);
-               i++;
-       }
-       if (param->flag & WILC_CFG_PARAM_FRAG_THRESHOLD) {
-               wid_list[i].id = WID_FRAG_THRESHOLD;
-               wid_list[i].val = (s8 *)&param->frag_threshold;
-               wid_list[i].type = WID_SHORT;
-               wid_list[i].size = sizeof(u16);
-               i++;
-       }
-       if (param->flag & WILC_CFG_PARAM_RTS_THRESHOLD) {
-               wid_list[i].id = WID_RTS_THRESHOLD;
-               wid_list[i].val = (s8 *)&param->rts_threshold;
-               wid_list[i].type = WID_SHORT;
-               wid_list[i].size = sizeof(u16);
-               i++;
-       }
-
-       return wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, i);
-}
-
-static void get_periodic_rssi(struct timer_list *t)
-{
-       struct wilc_vif *vif = from_timer(vif, t, periodic_rssi);
-
-       if (!vif->hif_drv) {
-               netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
-               return;
-       }
-
-       if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
-               wilc_get_stats_async(vif, &vif->periodic_stat);
-
-       mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
-}
-
-int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
-{
-       struct host_if_drv *hif_drv;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-
-       hif_drv  = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
-       if (!hif_drv)
-               return -ENOMEM;
-
-       *hif_drv_handler = hif_drv;
-
-       vif->hif_drv = hif_drv;
-
-       if (wilc->clients_count == 0)
-               mutex_init(&wilc->deinit_lock);
-
-       timer_setup(&vif->periodic_rssi, get_periodic_rssi, 0);
-       mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
-
-       timer_setup(&hif_drv->scan_timer, timer_scan_cb, 0);
-       timer_setup(&hif_drv->connect_timer, timer_connect_cb, 0);
-       timer_setup(&hif_drv->remain_on_ch_timer, listen_timer_cb, 0);
-
-       hif_drv->hif_state = HOST_IF_IDLE;
-
-       hif_drv->p2p_timeout = 0;
-
-       wilc->clients_count++;
-
-       return 0;
-}
-
-int wilc_deinit(struct wilc_vif *vif)
-{
-       int result = 0;
-       struct host_if_drv *hif_drv = vif->hif_drv;
-
-       if (!hif_drv) {
-               netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
-               return -EFAULT;
-       }
-
-       mutex_lock(&vif->wilc->deinit_lock);
-
-       del_timer_sync(&hif_drv->scan_timer);
-       del_timer_sync(&hif_drv->connect_timer);
-       del_timer_sync(&vif->periodic_rssi);
-       del_timer_sync(&hif_drv->remain_on_ch_timer);
-
-       if (hif_drv->usr_scan_req.scan_result) {
-               hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
-                                                 hif_drv->usr_scan_req.arg);
-               hif_drv->usr_scan_req.scan_result = NULL;
-       }
-
-       hif_drv->hif_state = HOST_IF_IDLE;
-
-       kfree(hif_drv);
-       vif->hif_drv = NULL;
-       vif->wilc->clients_count--;
-       mutex_unlock(&vif->wilc->deinit_lock);
-       return result;
-}
-
-void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
-{
-       int result;
-       struct host_if_msg *msg;
-       int id;
-       struct host_if_drv *hif_drv;
-       struct wilc_vif *vif;
-
-       id = get_unaligned_le32(&buffer[length - 4]);
-       vif = wilc_get_vif_from_idx(wilc, id);
-       if (!vif)
-               return;
-       hif_drv = vif->hif_drv;
-
-       if (!hif_drv) {
-               netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
-               return;
-       }
-
-       msg = wilc_alloc_work(vif, handle_rcvd_ntwrk_info, false);
-       if (IS_ERR(msg))
-               return;
-
-       msg->body.net_info.frame_len = get_unaligned_le16(&buffer[6]) - 1;
-       msg->body.net_info.rssi = buffer[8];
-       msg->body.net_info.mgmt = kmemdup(&buffer[9],
-                                         msg->body.net_info.frame_len,
-                                         GFP_KERNEL);
-       if (!msg->body.net_info.mgmt) {
-               kfree(msg);
-               return;
-       }
-
-       result = wilc_enqueue_work(msg);
-       if (result) {
-               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-               kfree(msg->body.net_info.mgmt);
-               kfree(msg);
-       }
-}
-
-void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length)
-{
-       int result;
-       struct host_if_msg *msg;
-       int id;
-       struct host_if_drv *hif_drv;
-       struct wilc_vif *vif;
-
-       mutex_lock(&wilc->deinit_lock);
-
-       id = get_unaligned_le32(&buffer[length - 4]);
-       vif = wilc_get_vif_from_idx(wilc, id);
-       if (!vif) {
-               mutex_unlock(&wilc->deinit_lock);
-               return;
-       }
-
-       hif_drv = vif->hif_drv;
-
-       if (!hif_drv) {
-               mutex_unlock(&wilc->deinit_lock);
-               return;
-       }
-
-       if (!hif_drv->conn_info.conn_result) {
-               netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
-               mutex_unlock(&wilc->deinit_lock);
-               return;
-       }
-
-       msg = wilc_alloc_work(vif, handle_rcvd_gnrl_async_info, false);
-       if (IS_ERR(msg)) {
-               mutex_unlock(&wilc->deinit_lock);
-               return;
-       }
-
-       msg->body.mac_info.status = buffer[7];
-       result = wilc_enqueue_work(msg);
-       if (result) {
-               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-               kfree(msg);
-       }
-
-       mutex_unlock(&wilc->deinit_lock);
-}
-
-void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length)
-{
-       int result;
-       int id;
-       struct host_if_drv *hif_drv;
-       struct wilc_vif *vif;
-
-       id = get_unaligned_le32(&buffer[length - 4]);
-       vif = wilc_get_vif_from_idx(wilc, id);
-       if (!vif)
-               return;
-       hif_drv = vif->hif_drv;
-
-       if (!hif_drv)
-               return;
-
-       if (hif_drv->usr_scan_req.scan_result) {
-               struct host_if_msg *msg;
-
-               msg = wilc_alloc_work(vif, handle_scan_complete, false);
-               if (IS_ERR(msg))
-                       return;
-
-               result = wilc_enqueue_work(msg);
-               if (result) {
-                       netdev_err(vif->ndev, "%s: enqueue work failed\n",
-                                  __func__);
-                       kfree(msg);
-               }
-       }
-}
-
-int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
-                          u32 duration, u16 chan,
-                          void (*expired)(void *, u64),
-                          void *user_arg)
-{
-       struct wilc_remain_ch roc;
-       int result;
-
-       roc.ch = chan;
-       roc.expired = expired;
-       roc.arg = user_arg;
-       roc.duration = duration;
-       roc.cookie = cookie;
-       result = handle_remain_on_chan(vif, &roc);
-       if (result)
-               netdev_err(vif->ndev, "%s: failed to set remain on channel\n",
-                          __func__);
-
-       return result;
-}
-
-int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie)
-{
-       if (!vif->hif_drv) {
-               netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
-               return -EFAULT;
-       }
-
-       del_timer(&vif->hif_drv->remain_on_ch_timer);
-
-       return wilc_handle_roc_expired(vif, cookie);
-}
-
-void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
-{
-       struct wid wid;
-       int result;
-       struct wilc_reg_frame reg_frame;
-
-       wid.id = WID_REGISTER_FRAME;
-       wid.type = WID_STR;
-       wid.size = sizeof(reg_frame);
-       wid.val = (u8 *)&reg_frame;
-
-       memset(&reg_frame, 0x0, sizeof(reg_frame));
-
-       if (reg)
-               reg_frame.reg = 1;
-
-       switch (frame_type) {
-       case IEEE80211_STYPE_ACTION:
-               reg_frame.reg_id = WILC_FW_ACTION_FRM_IDX;
-               break;
-
-       case IEEE80211_STYPE_PROBE_REQ:
-               reg_frame.reg_id = WILC_FW_PROBE_REQ_IDX;
-               break;
-
-       default:
-               break;
-       }
-       reg_frame.frame_type = cpu_to_le16(frame_type);
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to frame register\n");
-}
-
-int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
-                   struct cfg80211_beacon_data *params)
-{
-       struct wid wid;
-       int result;
-       u8 *cur_byte;
-
-       wid.id = WID_ADD_BEACON;
-       wid.type = WID_BIN;
-       wid.size = params->head_len + params->tail_len + 16;
-       wid.val = kzalloc(wid.size, GFP_KERNEL);
-       if (!wid.val)
-               return -ENOMEM;
-
-       cur_byte = wid.val;
-       put_unaligned_le32(interval, cur_byte);
-       cur_byte += 4;
-       put_unaligned_le32(dtim_period, cur_byte);
-       cur_byte += 4;
-       put_unaligned_le32(params->head_len, cur_byte);
-       cur_byte += 4;
-
-       if (params->head_len > 0)
-               memcpy(cur_byte, params->head, params->head_len);
-       cur_byte += params->head_len;
-
-       put_unaligned_le32(params->tail_len, cur_byte);
-       cur_byte += 4;
-
-       if (params->tail_len > 0)
-               memcpy(cur_byte, params->tail, params->tail_len);
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to send add beacon\n");
-
-       kfree(wid.val);
-
-       return result;
-}
-
-int wilc_del_beacon(struct wilc_vif *vif)
-{
-       int result;
-       struct wid wid;
-       u8 del_beacon = 0;
-
-       wid.id = WID_DEL_BEACON;
-       wid.type = WID_CHAR;
-       wid.size = sizeof(char);
-       wid.val = &del_beacon;
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to send delete beacon\n");
-
-       return result;
-}
-
-int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
-                    struct station_parameters *params)
-{
-       struct wid wid;
-       int result;
-       u8 *cur_byte;
-
-       wid.id = WID_ADD_STA;
-       wid.type = WID_BIN;
-       wid.size = WILC_ADD_STA_LENGTH + params->supported_rates_len;
-       wid.val = kmalloc(wid.size, GFP_KERNEL);
-       if (!wid.val)
-               return -ENOMEM;
-
-       cur_byte = wid.val;
-       wilc_hif_pack_sta_param(cur_byte, mac, params);
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result != 0)
-               netdev_err(vif->ndev, "Failed to send add station\n");
-
-       kfree(wid.val);
-
-       return result;
-}
-
-int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
-{
-       struct wid wid;
-       int result;
-
-       wid.id = WID_REMOVE_STA;
-       wid.type = WID_BIN;
-       wid.size = ETH_ALEN;
-       wid.val = kzalloc(wid.size, GFP_KERNEL);
-       if (!wid.val)
-               return -ENOMEM;
-
-       if (!mac_addr)
-               eth_broadcast_addr(wid.val);
-       else
-               ether_addr_copy(wid.val, mac_addr);
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to del station\n");
-
-       kfree(wid.val);
-
-       return result;
-}
-
-int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
-{
-       struct wid wid;
-       int result;
-       int i;
-       u8 assoc_sta = 0;
-       struct wilc_del_all_sta del_sta;
-
-       memset(&del_sta, 0x0, sizeof(del_sta));
-       for (i = 0; i < WILC_MAX_NUM_STA; i++) {
-               if (!is_zero_ether_addr(mac_addr[i])) {
-                       assoc_sta++;
-                       ether_addr_copy(del_sta.mac[i], mac_addr[i]);
-               }
-       }
-
-       if (!assoc_sta)
-               return 0;
-
-       del_sta.assoc_sta = assoc_sta;
-
-       wid.id = WID_DEL_ALL_STA;
-       wid.type = WID_STR;
-       wid.size = (assoc_sta * ETH_ALEN) + 1;
-       wid.val = (u8 *)&del_sta;
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to send delete all station\n");
-
-       return result;
-}
-
-int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
-                     struct station_parameters *params)
-{
-       struct wid wid;
-       int result;
-       u8 *cur_byte;
-
-       wid.id = WID_EDIT_STA;
-       wid.type = WID_BIN;
-       wid.size = WILC_ADD_STA_LENGTH + params->supported_rates_len;
-       wid.val = kmalloc(wid.size, GFP_KERNEL);
-       if (!wid.val)
-               return -ENOMEM;
-
-       cur_byte = wid.val;
-       wilc_hif_pack_sta_param(cur_byte, mac, params);
-
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to send edit station\n");
-
-       kfree(wid.val);
-       return result;
-}
-
-int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
-{
-       struct wid wid;
-       int result;
-       s8 power_mode;
-
-       if (enabled)
-               power_mode = WILC_FW_MIN_FAST_PS;
-       else
-               power_mode = WILC_FW_NO_POWERSAVE;
-
-       wid.id = WID_POWER_MANAGEMENT;
-       wid.val = &power_mode;
-       wid.size = sizeof(char);
-       result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-       if (result)
-               netdev_err(vif->ndev, "Failed to send power management\n");
-
-       return result;
-}
-
-int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count,
-                               u8 *mc_list)
-{
-       int result;
-       struct host_if_msg *msg;
-
-       msg = wilc_alloc_work(vif, handle_set_mcast_filter, false);
-       if (IS_ERR(msg))
-               return PTR_ERR(msg);
-
-       msg->body.mc_info.enabled = enabled;
-       msg->body.mc_info.cnt = count;
-       msg->body.mc_info.mc_list = mc_list;
-
-       result = wilc_enqueue_work(msg);
-       if (result) {
-               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-               kfree(msg);
-       }
-       return result;
-}
-
-int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
-{
-       struct wid wid;
-
-       wid.id = WID_TX_POWER;
-       wid.type = WID_CHAR;
-       wid.val = &tx_power;
-       wid.size = sizeof(char);
-
-       return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
-}
-
-int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
-{
-       struct wid wid;
-
-       wid.id = WID_TX_POWER;
-       wid.type = WID_CHAR;
-       wid.val = tx_power;
-       wid.size = sizeof(char);
-
-       return wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
-}
diff --git a/drivers/staging/wilc1000/hif.h b/drivers/staging/wilc1000/hif.h
deleted file mode 100644 (file)
index db91791..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries
- * All rights reserved.
- */
-
-#ifndef WILC_HIF_H
-#define WILC_HIF_H
-#include <linux/ieee80211.h>
-#include "wlan_if.h"
-
-enum {
-       WILC_IDLE_MODE = 0x0,
-       WILC_AP_MODE = 0x1,
-       WILC_STATION_MODE = 0x2,
-       WILC_GO_MODE = 0x3,
-       WILC_CLIENT_MODE = 0x4
-};
-
-#define WILC_MAX_NUM_PROBED_SSID               10
-
-#define WILC_TX_MIC_KEY_LEN                    8
-#define WILC_RX_MIC_KEY_LEN                    8
-
-#define WILC_ADD_STA_LENGTH                    40
-#define WILC_NUM_CONCURRENT_IFC                        2
-
-enum {
-       WILC_SET_CFG = 0,
-       WILC_GET_CFG
-};
-
-#define WILC_MAX_ASSOC_RESP_FRAME_SIZE   256
-
-struct rf_info {
-       u8 link_speed;
-       s8 rssi;
-       u32 tx_cnt;
-       u32 rx_cnt;
-       u32 tx_fail_cnt;
-};
-
-enum host_if_state {
-       HOST_IF_IDLE                    = 0,
-       HOST_IF_SCANNING                = 1,
-       HOST_IF_CONNECTING              = 2,
-       HOST_IF_WAITING_CONN_RESP       = 3,
-       HOST_IF_CONNECTED               = 4,
-       HOST_IF_P2P_LISTEN              = 5,
-       HOST_IF_FORCE_32BIT             = 0xFFFFFFFF
-};
-
-struct cfg_param_attr {
-       u32 flag;
-       u16 short_retry_limit;
-       u16 long_retry_limit;
-       u16 frag_threshold;
-       u16 rts_threshold;
-};
-
-enum cfg_param {
-       WILC_CFG_PARAM_RETRY_SHORT = BIT(0),
-       WILC_CFG_PARAM_RETRY_LONG = BIT(1),
-       WILC_CFG_PARAM_FRAG_THRESHOLD = BIT(2),
-       WILC_CFG_PARAM_RTS_THRESHOLD = BIT(3)
-};
-
-enum scan_event {
-       SCAN_EVENT_NETWORK_FOUND        = 0,
-       SCAN_EVENT_DONE                 = 1,
-       SCAN_EVENT_ABORTED              = 2,
-       SCAN_EVENT_FORCE_32BIT          = 0xFFFFFFFF
-};
-
-enum conn_event {
-       CONN_DISCONN_EVENT_CONN_RESP            = 0,
-       CONN_DISCONN_EVENT_DISCONN_NOTIF        = 1,
-       CONN_DISCONN_EVENT_FORCE_32BIT          = 0xFFFFFFFF
-};
-
-enum {
-       WILC_HIF_SDIO = 0,
-       WILC_HIF_SPI = BIT(0)
-};
-
-enum {
-       WILC_MAC_STATUS_INIT = -1,
-       WILC_MAC_STATUS_DISCONNECTED = 0,
-       WILC_MAC_STATUS_CONNECTED = 1
-};
-
-struct wilc_rcvd_net_info {
-       s8 rssi;
-       u8 ch;
-       u16 frame_len;
-       struct ieee80211_mgmt *mgmt;
-};
-
-struct wilc_user_scan_req {
-       void (*scan_result)(enum scan_event evt,
-                           struct wilc_rcvd_net_info *info, void *priv);
-       void *arg;
-       u32 ch_cnt;
-};
-
-struct wilc_conn_info {
-       u8 bssid[ETH_ALEN];
-       u8 security;
-       enum authtype auth_type;
-       u8 ch;
-       u8 *req_ies;
-       size_t req_ies_len;
-       u8 *resp_ies;
-       u16 resp_ies_len;
-       u16 status;
-       void (*conn_result)(enum conn_event evt, u8 status, void *priv_data);
-       void *arg;
-       void *param;
-};
-
-struct wilc_remain_ch {
-       u16 ch;
-       u32 duration;
-       void (*expired)(void *priv, u64 cookie);
-       void *arg;
-       u32 cookie;
-};
-
-struct wilc;
-struct host_if_drv {
-       struct wilc_user_scan_req usr_scan_req;
-       struct wilc_conn_info conn_info;
-       struct wilc_remain_ch remain_on_ch;
-       u64 p2p_timeout;
-
-       enum host_if_state hif_state;
-
-       u8 assoc_bssid[ETH_ALEN];
-
-       struct timer_list scan_timer;
-       struct wilc_vif *scan_timer_vif;
-
-       struct timer_list connect_timer;
-       struct wilc_vif *connect_timer_vif;
-
-       struct timer_list remain_on_ch_timer;
-       struct wilc_vif *remain_on_ch_timer_vif;
-
-       bool ifc_up;
-       u8 assoc_resp[WILC_MAX_ASSOC_RESP_FRAME_SIZE];
-};
-
-struct wilc_vif;
-int wilc_remove_wep_key(struct wilc_vif *vif, u8 index);
-int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index);
-int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
-                            u8 index);
-int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
-                           u8 index, u8 mode, enum authtype auth_type);
-int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
-                const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
-                u8 mode, u8 cipher_mode, u8 index);
-s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
-                          u32 *out_val);
-int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
-                   u8 index, u32 key_rsc_len, const u8 *key_rsc,
-                   const u8 *rx_mic, const u8 *tx_mic, u8 mode,
-                   u8 cipher_mode);
-int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid);
-int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr);
-int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies,
-                     size_t ies_len);
-int wilc_disconnect(struct wilc_vif *vif);
-int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel);
-int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level);
-int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
-             u8 *ch_freq_list, u8 ch_list_len,
-             void (*scan_result_fn)(enum scan_event,
-                                    struct wilc_rcvd_net_info *, void *),
-             void *user_arg, struct cfg80211_scan_request *request);
-int wilc_hif_set_cfg(struct wilc_vif *vif,
-                    struct cfg_param_attr *cfg_param);
-int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler);
-int wilc_deinit(struct wilc_vif *vif);
-int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
-                   struct cfg80211_beacon_data *params);
-int wilc_del_beacon(struct wilc_vif *vif);
-int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
-                    struct station_parameters *params);
-int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN]);
-int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr);
-int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
-                     struct station_parameters *params);
-int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout);
-int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count,
-                               u8 *mc_list);
-int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
-                          u32 duration, u16 chan,
-                          void (*expired)(void *, u64),
-                          void *user_arg);
-int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie);
-void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg);
-int wilc_set_operation_mode(struct wilc_vif *vif, int index, u8 mode,
-                           u8 ifc_id);
-int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats);
-int wilc_get_vif_idx(struct wilc_vif *vif);
-int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power);
-int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power);
-void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length);
-void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length);
-void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length);
-void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
-                               struct cfg80211_crypto_settings *crypto);
-#endif
diff --git a/drivers/staging/wilc1000/microchip,wilc1000.yaml b/drivers/staging/wilc1000/microchip,wilc1000.yaml
deleted file mode 100644 (file)
index 2c320eb..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/net/wireless/microchip,wilc1000.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Microchip WILC wireless devicetree bindings
-
-maintainers:
-  - Adham Abozaeid <adham.abozaeid@microchip.com>
-  - Ajay Singh <ajay.kathat@microchip.com>
-
-description:
-  The wilc1000 chips can be connected via SPI or SDIO. This document
-  describes the binding to connect wilc devices.
-
-properties:
-  compatible:
-    const: microchip,wilc1000
-
-  spi-max-frequency: true
-
-  interrupts:
-    maxItems: 1
-
-  clocks:
-    description: phandle to the clock connected on rtc clock line.
-    maxItems: 1
-
-  clock-names:
-    const: rtc
-
-required:
-  - compatible
-  - interrupts
-
-examples:
-  - |
-    spi {
-      #address-cells = <1>;
-      #size-cells = <0>;
-      wifi@0 {
-        compatible = "microchip,wilc1000";
-        spi-max-frequency = <48000000>;
-        reg = <0>;
-        interrupt-parent = <&pioC>;
-        interrupts = <27 0>;
-        clocks = <&pck1>;
-        clock-names = "rtc";
-      };
-    };
-
-  - |
-    mmc {
-      #address-cells = <1>;
-      #size-cells = <0>;
-      pinctrl-names = "default";
-      pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
-      non-removable;
-      vmmc-supply = <&vcc_mmc1_reg>;
-      vqmmc-supply = <&vcc_3v3_reg>;
-      bus-width = <4>;
-      wifi@0 {
-        compatible = "microchip,wilc1000";
-        reg = <0>;
-        interrupt-parent = <&pioC>;
-        interrupts = <27 0>;
-        clocks = <&pck1>;
-        clock-names = "rtc";
-      };
-    };
diff --git a/drivers/staging/wilc1000/mon.c b/drivers/staging/wilc1000/mon.c
deleted file mode 100644 (file)
index 6033141..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#include "cfg80211.h"
-
-struct wilc_wfi_radiotap_hdr {
-       struct ieee80211_radiotap_header hdr;
-       u8 rate;
-} __packed;
-
-struct wilc_wfi_radiotap_cb_hdr {
-       struct ieee80211_radiotap_header hdr;
-       u8 rate;
-       u8 dump;
-       u16 tx_flags;
-} __packed;
-
-#define TX_RADIOTAP_PRESENT ((1 << IEEE80211_RADIOTAP_RATE) |  \
-                            (1 << IEEE80211_RADIOTAP_TX_FLAGS))
-
-void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size)
-{
-       u32 header, pkt_offset;
-       struct sk_buff *skb = NULL;
-       struct wilc_wfi_radiotap_hdr *hdr;
-       struct wilc_wfi_radiotap_cb_hdr *cb_hdr;
-
-       if (!mon_dev)
-               return;
-
-       if (!netif_running(mon_dev))
-               return;
-
-       /* Get WILC header */
-       header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
-       /*
-        * The packet offset field contain info about what type of management
-        * the frame we are dealing with and ack status
-        */
-       pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
-
-       if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
-               /* hostapd callback mgmt frame */
-
-               skb = dev_alloc_skb(size + sizeof(*cb_hdr));
-               if (!skb)
-                       return;
-
-               skb_put_data(skb, buff, size);
-
-               cb_hdr = skb_push(skb, sizeof(*cb_hdr));
-               memset(cb_hdr, 0, sizeof(*cb_hdr));
-
-               cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
-
-               cb_hdr->hdr.it_len = cpu_to_le16(sizeof(*cb_hdr));
-
-               cb_hdr->hdr.it_present = cpu_to_le32(TX_RADIOTAP_PRESENT);
-
-               cb_hdr->rate = 5;
-
-               if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
-                       /* success */
-                       cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS;
-               } else {
-                       cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL;
-               }
-
-       } else {
-               skb = dev_alloc_skb(size + sizeof(*hdr));
-
-               if (!skb)
-                       return;
-
-               skb_put_data(skb, buff, size);
-               hdr = skb_push(skb, sizeof(*hdr));
-               memset(hdr, 0, sizeof(struct wilc_wfi_radiotap_hdr));
-               hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
-               hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
-               hdr->hdr.it_present = cpu_to_le32
-                               (1 << IEEE80211_RADIOTAP_RATE);
-               hdr->rate = 5;
-       }
-
-       skb->dev = mon_dev;
-       skb_reset_mac_header(skb);
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
-       skb->pkt_type = PACKET_OTHERHOST;
-       skb->protocol = htons(ETH_P_802_2);
-       memset(skb->cb, 0, sizeof(skb->cb));
-
-       netif_rx(skb);
-}
-
-struct tx_complete_mon_data {
-       int size;
-       void *buff;
-};
-
-static void mgmt_tx_complete(void *priv, int status)
-{
-       struct tx_complete_mon_data *pv_data = priv;
-       /*
-        * in case of fully hosting mode, the freeing will be done
-        * in response to the cfg packet
-        */
-       kfree(pv_data->buff);
-
-       kfree(pv_data);
-}
-
-static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len)
-{
-       struct tx_complete_mon_data *mgmt_tx = NULL;
-
-       if (!dev)
-               return -EFAULT;
-
-       netif_stop_queue(dev);
-       mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_ATOMIC);
-       if (!mgmt_tx)
-               return -ENOMEM;
-
-       mgmt_tx->buff = kmemdup(buf, len, GFP_ATOMIC);
-       if (!mgmt_tx->buff) {
-               kfree(mgmt_tx);
-               return -ENOMEM;
-       }
-
-       mgmt_tx->size = len;
-
-       wilc_wlan_txq_add_mgmt_pkt(dev, mgmt_tx, mgmt_tx->buff, mgmt_tx->size,
-                                  mgmt_tx_complete);
-
-       netif_wake_queue(dev);
-       return 0;
-}
-
-static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb,
-                                    struct net_device *dev)
-{
-       u32 rtap_len, ret = 0;
-       struct wilc_wfi_mon_priv  *mon_priv;
-       struct sk_buff *skb2;
-       struct wilc_wfi_radiotap_cb_hdr *cb_hdr;
-       u8 srcadd[ETH_ALEN];
-       u8 bssid[ETH_ALEN];
-
-       mon_priv = netdev_priv(dev);
-       if (!mon_priv)
-               return -EFAULT;
-
-       rtap_len = ieee80211_get_radiotap_len(skb->data);
-       if (skb->len < rtap_len)
-               return -1;
-
-       skb_pull(skb, rtap_len);
-
-       if (skb->data[0] == 0xc0 && is_broadcast_ether_addr(&skb->data[4])) {
-               skb2 = dev_alloc_skb(skb->len + sizeof(*cb_hdr));
-               if (!skb2)
-                       return -ENOMEM;
-
-               skb_put_data(skb2, skb->data, skb->len);
-
-               cb_hdr = skb_push(skb2, sizeof(*cb_hdr));
-               memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr));
-
-               cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
-
-               cb_hdr->hdr.it_len = cpu_to_le16(sizeof(*cb_hdr));
-
-               cb_hdr->hdr.it_present = cpu_to_le32(TX_RADIOTAP_PRESENT);
-
-               cb_hdr->rate = 5;
-               cb_hdr->tx_flags = 0x0004;
-
-               skb2->dev = dev;
-               skb_reset_mac_header(skb2);
-               skb2->ip_summed = CHECKSUM_UNNECESSARY;
-               skb2->pkt_type = PACKET_OTHERHOST;
-               skb2->protocol = htons(ETH_P_802_2);
-               memset(skb2->cb, 0, sizeof(skb2->cb));
-
-               netif_rx(skb2);
-
-               return 0;
-       }
-       skb->dev = mon_priv->real_ndev;
-
-       ether_addr_copy(srcadd, &skb->data[10]);
-       ether_addr_copy(bssid, &skb->data[16]);
-       /*
-        * Identify if data or mgmt packet, if source address and bssid
-        * fields are equal send it to mgmt frames handler
-        */
-       if (!(memcmp(srcadd, bssid, 6))) {
-               ret = mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len);
-               if (ret)
-                       netdev_err(dev, "fail to mgmt tx\n");
-               dev_kfree_skb(skb);
-       } else {
-               ret = wilc_mac_xmit(skb, mon_priv->real_ndev);
-       }
-
-       return ret;
-}
-
-static const struct net_device_ops wilc_wfi_netdev_ops = {
-       .ndo_start_xmit         = wilc_wfi_mon_xmit,
-
-};
-
-struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
-                                              const char *name,
-                                              struct net_device *real_dev)
-{
-       struct wilc_wfi_mon_priv *priv;
-
-       /* If monitor interface is already initialized, return it */
-       if (wl->monitor_dev)
-               return wl->monitor_dev;
-
-       wl->monitor_dev = alloc_etherdev(sizeof(struct wilc_wfi_mon_priv));
-       if (!wl->monitor_dev)
-               return NULL;
-
-       wl->monitor_dev->type = ARPHRD_IEEE80211_RADIOTAP;
-       strncpy(wl->monitor_dev->name, name, IFNAMSIZ);
-       wl->monitor_dev->name[IFNAMSIZ - 1] = 0;
-       wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops;
-       wl->monitor_dev->needs_free_netdev = true;
-
-       if (register_netdevice(wl->monitor_dev)) {
-               netdev_err(real_dev, "register_netdevice failed\n");
-               return NULL;
-       }
-       priv = netdev_priv(wl->monitor_dev);
-       if (!priv)
-               return NULL;
-
-       priv->real_ndev = real_dev;
-
-       return wl->monitor_dev;
-}
-
-void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked)
-{
-       if (!wl->monitor_dev)
-               return;
-
-       if (rtnl_locked)
-               unregister_netdevice(wl->monitor_dev);
-       else
-               unregister_netdev(wl->monitor_dev);
-       wl->monitor_dev = NULL;
-}
diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c
deleted file mode 100644 (file)
index fda0ab9..0000000
+++ /dev/null
@@ -1,931 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#include <linux/irq.h>
-#include <linux/kthread.h>
-#include <linux/firmware.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-
-#include "cfg80211.h"
-#include "wlan_cfg.h"
-
-#define WILC_MULTICAST_TABLE_SIZE      8
-
-static irqreturn_t isr_uh_routine(int irq, void *user_data)
-{
-       struct net_device *dev = user_data;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-
-       if (wilc->close) {
-               netdev_err(dev, "Can't handle UH interrupt\n");
-               return IRQ_HANDLED;
-       }
-       return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t isr_bh_routine(int irq, void *userdata)
-{
-       struct net_device *dev = userdata;
-       struct wilc_vif *vif = netdev_priv(userdata);
-       struct wilc *wilc = vif->wilc;
-
-       if (wilc->close) {
-               netdev_err(dev, "Can't handle BH interrupt\n");
-               return IRQ_HANDLED;
-       }
-
-       wilc_handle_isr(wilc);
-
-       return IRQ_HANDLED;
-}
-
-static int init_irq(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wl = vif->wilc;
-       int ret;
-
-       ret = request_threaded_irq(wl->dev_irq_num, isr_uh_routine,
-                                  isr_bh_routine,
-                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                  "WILC_IRQ", dev);
-       if (ret) {
-               netdev_err(dev, "Failed to request IRQ [%d]\n", ret);
-               return ret;
-       }
-       netdev_dbg(dev, "IRQ request succeeded IRQ-NUM= %d\n", wl->dev_irq_num);
-
-       return 0;
-}
-
-static void deinit_irq(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-
-       /* Deinitialize IRQ */
-       if (wilc->dev_irq_num)
-               free_irq(wilc->dev_irq_num, wilc);
-}
-
-void wilc_mac_indicate(struct wilc *wilc)
-{
-       s8 status;
-
-       wilc_wlan_cfg_get_val(wilc, WID_STATUS, &status, 1);
-       if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
-               wilc->mac_status = status;
-               complete(&wilc->sync_event);
-       } else {
-               wilc->mac_status = status;
-       }
-}
-
-static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
-{
-       struct net_device *ndev = NULL;
-       struct wilc_vif *vif;
-       struct ieee80211_hdr *h = (struct ieee80211_hdr *)mac_header;
-
-       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
-               if (vif->mode == WILC_STATION_MODE)
-                       if (ether_addr_equal_unaligned(h->addr2, vif->bssid)) {
-                               ndev = vif->ndev;
-                               goto out;
-                       }
-               if (vif->mode == WILC_AP_MODE)
-                       if (ether_addr_equal_unaligned(h->addr1, vif->bssid)) {
-                               ndev = vif->ndev;
-                               goto out;
-                       }
-       }
-out:
-       return ndev;
-}
-
-void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode)
-{
-       struct wilc_vif *vif = netdev_priv(wilc_netdev);
-
-       if (bssid)
-               ether_addr_copy(vif->bssid, bssid);
-       else
-               eth_zero_addr(vif->bssid);
-
-       vif->mode = mode;
-}
-
-int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
-{
-       int srcu_idx;
-       u8 ret_val = 0;
-       struct wilc_vif *vif;
-
-       srcu_idx = srcu_read_lock(&wilc->srcu);
-       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
-               if (!is_zero_ether_addr(vif->bssid))
-                       ret_val++;
-       }
-       srcu_read_unlock(&wilc->srcu, srcu_idx);
-       return ret_val;
-}
-
-static int wilc_txq_task(void *vp)
-{
-       int ret;
-       u32 txq_count;
-       struct wilc *wl = vp;
-
-       complete(&wl->txq_thread_started);
-       while (1) {
-               wait_for_completion(&wl->txq_event);
-
-               if (wl->close) {
-                       complete(&wl->txq_thread_started);
-
-                       while (!kthread_should_stop())
-                               schedule();
-                       break;
-               }
-               do {
-                       ret = wilc_wlan_handle_txq(wl, &txq_count);
-                       if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
-                               int srcu_idx;
-                               struct wilc_vif *ifc;
-
-                               srcu_idx = srcu_read_lock(&wl->srcu);
-                               list_for_each_entry_rcu(ifc, &wl->vif_list,
-                                                       list) {
-                                       if (ifc->mac_opened && ifc->ndev)
-                                               netif_wake_queue(ifc->ndev);
-                               }
-                               srcu_read_unlock(&wl->srcu, srcu_idx);
-                       }
-               } while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close);
-       }
-       return 0;
-}
-
-static int wilc_wlan_get_firmware(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-       int chip_id;
-       const struct firmware *wilc_firmware;
-       char *firmware;
-
-       chip_id = wilc_get_chipid(wilc, false);
-
-       if (chip_id < 0x1003a0)
-               firmware = FIRMWARE_1002;
-       else
-               firmware = FIRMWARE_1003;
-
-       netdev_info(dev, "loading firmware %s\n", firmware);
-
-       if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
-               netdev_err(dev, "%s - firmware not available\n", firmware);
-               return -EINVAL;
-       }
-       wilc->firmware = wilc_firmware;
-
-       return 0;
-}
-
-static int wilc_start_firmware(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-       int ret = 0;
-
-       ret = wilc_wlan_start(wilc);
-       if (ret)
-               return ret;
-
-       if (!wait_for_completion_timeout(&wilc->sync_event,
-                                        msecs_to_jiffies(5000)))
-               return -ETIME;
-
-       return 0;
-}
-
-static int wilc1000_firmware_download(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-       int ret = 0;
-
-       if (!wilc->firmware) {
-               netdev_err(dev, "Firmware buffer is NULL\n");
-               return -ENOBUFS;
-       }
-
-       ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data,
-                                         wilc->firmware->size);
-       if (ret)
-               return ret;
-
-       release_firmware(wilc->firmware);
-       wilc->firmware = NULL;
-
-       netdev_dbg(dev, "Download Succeeded\n");
-
-       return 0;
-}
-
-static int wilc_init_fw_config(struct net_device *dev, struct wilc_vif *vif)
-{
-       struct wilc_priv *priv = &vif->priv;
-       struct host_if_drv *hif_drv;
-       u8 b;
-       u16 hw;
-       u32 w;
-
-       netdev_dbg(dev, "Start configuring Firmware\n");
-       hif_drv = (struct host_if_drv *)priv->hif_drv;
-       netdev_dbg(dev, "Host = %p\n", hif_drv);
-
-       w = vif->iftype;
-       cpu_to_le32s(&w);
-       if (!wilc_wlan_cfg_set(vif, 1, WID_SET_OPERATION_MODE, (u8 *)&w, 4,
-                              0, 0))
-               goto fail;
-
-       b = WILC_FW_BSS_TYPE_INFRA;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_BSS_TYPE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_TX_RATE_AUTO;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_TX_RATE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_OPER_MODE_G_MIXED_11B_2;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11G_OPERATING_MODE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_PREAMBLE_SHORT;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_PREAMBLE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_11N_PROT_AUTO;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_PROT_MECH, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_ACTIVE_SCAN;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_SCAN_TYPE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_SITE_SURVEY_OFF;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_SITE_SURVEY, &b, 1, 0, 0))
-               goto fail;
-
-       hw = 0xffff;
-       cpu_to_le16s(&hw);
-       if (!wilc_wlan_cfg_set(vif, 0, WID_RTS_THRESHOLD, (u8 *)&hw, 2, 0, 0))
-               goto fail;
-
-       hw = 2346;
-       cpu_to_le16s(&hw);
-       if (!wilc_wlan_cfg_set(vif, 0, WID_FRAG_THRESHOLD, (u8 *)&hw, 2, 0, 0))
-               goto fail;
-
-       b = 0;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_BCAST_SSID, &b, 1, 0, 0))
-               goto fail;
-
-       b = 1;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_QOS_ENABLE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_NO_POWERSAVE;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_POWER_MANAGEMENT, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_SEC_NO;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11I_MODE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_AUTH_OPEN_SYSTEM;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_AUTH_TYPE, &b, 1, 0, 0))
-               goto fail;
-
-       b = 3;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_LISTEN_INTERVAL, &b, 1, 0, 0))
-               goto fail;
-
-       b = 3;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_DTIM_PERIOD, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_ACK_POLICY_NORMAL;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_ACK_POLICY, &b, 1, 0, 0))
-               goto fail;
-
-       b = 0;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_USER_CONTROL_ON_TX_POWER, &b, 1,
-                              0, 0))
-               goto fail;
-
-       b = 48;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11A, &b, 1, 0, 0))
-               goto fail;
-
-       b = 28;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11B, &b, 1, 0, 0))
-               goto fail;
-
-       hw = 100;
-       cpu_to_le16s(&hw);
-       if (!wilc_wlan_cfg_set(vif, 0, WID_BEACON_INTERVAL, (u8 *)&hw, 2, 0, 0))
-               goto fail;
-
-       b = WILC_FW_REKEY_POLICY_DISABLE;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_POLICY, &b, 1, 0, 0))
-               goto fail;
-
-       w = 84600;
-       cpu_to_le32s(&w);
-       if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PERIOD, (u8 *)&w, 4, 0, 0))
-               goto fail;
-
-       w = 500;
-       cpu_to_le32s(&w);
-       if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PACKET_COUNT, (u8 *)&w, 4, 0,
-                              0))
-               goto fail;
-
-       b = 1;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_SHORT_SLOT_ALLOWED, &b, 1, 0,
-                              0))
-               goto fail;
-
-       b = WILC_FW_ERP_PROT_SELF_CTS;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ERP_PROT_TYPE, &b, 1, 0, 0))
-               goto fail;
-
-       b = 1;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ENABLE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_11N_OP_MODE_HT_MIXED;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OPERATING_MODE, &b, 1, 0, 0))
-               goto fail;
-
-       b = 1;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_TXOP_PROT_DISABLE, &b, 1, 0, 0))
-               goto fail;
-
-       b = WILC_FW_OBBS_NONHT_DETECT_PROTECT_REPORT;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OBSS_NONHT_DETECTION, &b, 1,
-                              0, 0))
-               goto fail;
-
-       b = WILC_FW_HT_PROT_RTS_CTS_NONHT;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_HT_PROT_TYPE, &b, 1, 0, 0))
-               goto fail;
-
-       b = 0;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_RIFS_PROT_ENABLE, &b, 1, 0,
-                              0))
-               goto fail;
-
-       b = 7;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_CURRENT_TX_MCS, &b, 1, 0, 0))
-               goto fail;
-
-       b = 1;
-       if (!wilc_wlan_cfg_set(vif, 0, WID_11N_IMMEDIATE_BA_ENABLED, &b, 1,
-                              1, 1))
-               goto fail;
-
-       return 0;
-
-fail:
-       return -EINVAL;
-}
-
-static void wlan_deinitialize_threads(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wl = vif->wilc;
-
-       wl->close = 1;
-
-       complete(&wl->txq_event);
-
-       if (wl->txq_thread) {
-               kthread_stop(wl->txq_thread);
-               wl->txq_thread = NULL;
-       }
-}
-
-static void wilc_wlan_deinitialize(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wl = vif->wilc;
-
-       if (!wl) {
-               netdev_err(dev, "wl is NULL\n");
-               return;
-       }
-
-       if (wl->initialized) {
-               netdev_info(dev, "Deinitializing wilc1000...\n");
-
-               if (!wl->dev_irq_num &&
-                   wl->hif_func->disable_interrupt) {
-                       mutex_lock(&wl->hif_cs);
-                       wl->hif_func->disable_interrupt(wl);
-                       mutex_unlock(&wl->hif_cs);
-               }
-               complete(&wl->txq_event);
-
-               wlan_deinitialize_threads(dev);
-               deinit_irq(dev);
-
-               wilc_wlan_stop(wl, vif);
-               wilc_wlan_cleanup(dev);
-
-               wl->initialized = false;
-
-               netdev_dbg(dev, "wilc1000 deinitialization Done\n");
-       } else {
-               netdev_dbg(dev, "wilc1000 is not initialized\n");
-       }
-}
-
-static int wlan_initialize_threads(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-
-       wilc->txq_thread = kthread_run(wilc_txq_task, (void *)wilc,
-                                      "K_TXQ_TASK");
-       if (IS_ERR(wilc->txq_thread)) {
-               netdev_err(dev, "couldn't create TXQ thread\n");
-               wilc->close = 0;
-               return PTR_ERR(wilc->txq_thread);
-       }
-       wait_for_completion(&wilc->txq_thread_started);
-
-       return 0;
-}
-
-static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
-{
-       int ret = 0;
-       struct wilc *wl = vif->wilc;
-
-       if (!wl->initialized) {
-               wl->mac_status = WILC_MAC_STATUS_INIT;
-               wl->close = 0;
-
-               ret = wilc_wlan_init(dev);
-               if (ret)
-                       return ret;
-
-               ret = wlan_initialize_threads(dev);
-               if (ret)
-                       goto fail_wilc_wlan;
-
-               if (wl->dev_irq_num && init_irq(dev)) {
-                       ret = -EIO;
-                       goto fail_threads;
-               }
-
-               if (!wl->dev_irq_num &&
-                   wl->hif_func->enable_interrupt &&
-                   wl->hif_func->enable_interrupt(wl)) {
-                       ret = -EIO;
-                       goto fail_irq_init;
-               }
-
-               ret = wilc_wlan_get_firmware(dev);
-               if (ret)
-                       goto fail_irq_enable;
-
-               ret = wilc1000_firmware_download(dev);
-               if (ret)
-                       goto fail_irq_enable;
-
-               ret = wilc_start_firmware(dev);
-               if (ret)
-                       goto fail_irq_enable;
-
-               if (wilc_wlan_cfg_get(vif, 1, WID_FIRMWARE_VERSION, 1, 0)) {
-                       int size;
-                       char firmware_ver[20];
-
-                       size = wilc_wlan_cfg_get_val(wl, WID_FIRMWARE_VERSION,
-                                                    firmware_ver,
-                                                    sizeof(firmware_ver));
-                       firmware_ver[size] = '\0';
-                       netdev_dbg(dev, "Firmware Ver = %s\n", firmware_ver);
-               }
-
-               ret = wilc_init_fw_config(dev, vif);
-               if (ret) {
-                       netdev_err(dev, "Failed to configure firmware\n");
-                       goto fail_fw_start;
-               }
-               wl->initialized = true;
-               return 0;
-
-fail_fw_start:
-               wilc_wlan_stop(wl, vif);
-
-fail_irq_enable:
-               if (!wl->dev_irq_num &&
-                   wl->hif_func->disable_interrupt)
-                       wl->hif_func->disable_interrupt(wl);
-fail_irq_init:
-               if (wl->dev_irq_num)
-                       deinit_irq(dev);
-fail_threads:
-               wlan_deinitialize_threads(dev);
-fail_wilc_wlan:
-               wilc_wlan_cleanup(dev);
-               netdev_err(dev, "WLAN initialization FAILED\n");
-       } else {
-               netdev_dbg(dev, "wilc1000 already initialized\n");
-       }
-       return ret;
-}
-
-static int mac_init_fn(struct net_device *ndev)
-{
-       netif_start_queue(ndev);
-       netif_stop_queue(ndev);
-
-       return 0;
-}
-
-static int wilc_mac_open(struct net_device *ndev)
-{
-       struct wilc_vif *vif = netdev_priv(ndev);
-       struct wilc *wl = vif->wilc;
-       unsigned char mac_add[ETH_ALEN] = {0};
-       int ret = 0;
-       struct mgmt_frame_regs mgmt_regs = {};
-
-       if (!wl || !wl->dev) {
-               netdev_err(ndev, "device not ready\n");
-               return -ENODEV;
-       }
-
-       netdev_dbg(ndev, "MAC OPEN[%p]\n", ndev);
-
-       ret = wilc_init_host_int(ndev);
-       if (ret)
-               return ret;
-
-       ret = wilc_wlan_initialize(ndev, vif);
-       if (ret) {
-               wilc_deinit_host_int(ndev);
-               return ret;
-       }
-
-       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype,
-                               vif->idx);
-       wilc_get_mac_address(vif, mac_add);
-       netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
-       ether_addr_copy(ndev->dev_addr, mac_add);
-
-       if (!is_valid_ether_addr(ndev->dev_addr)) {
-               netdev_err(ndev, "Wrong MAC address\n");
-               wilc_deinit_host_int(ndev);
-               wilc_wlan_deinitialize(ndev);
-               return -EINVAL;
-       }
-
-       mgmt_regs.interface_stypes = vif->mgmt_reg_stypes;
-       /* so we detect a change */
-       vif->mgmt_reg_stypes = 0;
-       wilc_update_mgmt_frame_registrations(vif->ndev->ieee80211_ptr->wiphy,
-                                            vif->ndev->ieee80211_ptr,
-                                            &mgmt_regs);
-       netif_wake_queue(ndev);
-       wl->open_ifcs++;
-       vif->mac_opened = 1;
-       return 0;
-}
-
-static struct net_device_stats *mac_stats(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-
-       return &vif->netstats;
-}
-
-static void wilc_set_multicast_list(struct net_device *dev)
-{
-       struct netdev_hw_addr *ha;
-       struct wilc_vif *vif = netdev_priv(dev);
-       int i;
-       u8 *mc_list;
-       u8 *cur_mc;
-
-       if (dev->flags & IFF_PROMISC)
-               return;
-
-       if (dev->flags & IFF_ALLMULTI ||
-           dev->mc.count > WILC_MULTICAST_TABLE_SIZE) {
-               wilc_setup_multicast_filter(vif, 0, 0, NULL);
-               return;
-       }
-
-       if (dev->mc.count == 0) {
-               wilc_setup_multicast_filter(vif, 1, 0, NULL);
-               return;
-       }
-
-       mc_list = kmalloc_array(dev->mc.count, ETH_ALEN, GFP_ATOMIC);
-       if (!mc_list)
-               return;
-
-       cur_mc = mc_list;
-       i = 0;
-       netdev_for_each_mc_addr(ha, dev) {
-               memcpy(cur_mc, ha->addr, ETH_ALEN);
-               netdev_dbg(dev, "Entry[%d]: %pM\n", i, cur_mc);
-               i++;
-               cur_mc += ETH_ALEN;
-       }
-
-       if (wilc_setup_multicast_filter(vif, 1, dev->mc.count, mc_list))
-               kfree(mc_list);
-}
-
-static void wilc_tx_complete(void *priv, int status)
-{
-       struct tx_complete_data *pv_data = priv;
-
-       dev_kfree_skb(pv_data->skb);
-       kfree(pv_data);
-}
-
-netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
-       struct wilc_vif *vif = netdev_priv(ndev);
-       struct wilc *wilc = vif->wilc;
-       struct tx_complete_data *tx_data = NULL;
-       int queue_count;
-
-       if (skb->dev != ndev) {
-               netdev_err(ndev, "Packet not destined to this device\n");
-               return 0;
-       }
-
-       tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
-       if (!tx_data) {
-               dev_kfree_skb(skb);
-               netif_wake_queue(ndev);
-               return 0;
-       }
-
-       tx_data->buff = skb->data;
-       tx_data->size = skb->len;
-       tx_data->skb  = skb;
-
-       vif->netstats.tx_packets++;
-       vif->netstats.tx_bytes += tx_data->size;
-       queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
-                                               tx_data->buff, tx_data->size,
-                                               wilc_tx_complete);
-
-       if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
-               int srcu_idx;
-               struct wilc_vif *vif;
-
-               srcu_idx = srcu_read_lock(&wilc->srcu);
-               list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
-                       if (vif->mac_opened)
-                               netif_stop_queue(vif->ndev);
-               }
-               srcu_read_unlock(&wilc->srcu, srcu_idx);
-       }
-
-       return 0;
-}
-
-static int wilc_mac_close(struct net_device *ndev)
-{
-       struct wilc_vif *vif = netdev_priv(ndev);
-       struct wilc *wl = vif->wilc;
-
-       netdev_dbg(ndev, "Mac close\n");
-
-       if (wl->open_ifcs > 0)
-               wl->open_ifcs--;
-       else
-               return 0;
-
-       if (vif->ndev) {
-               netif_stop_queue(vif->ndev);
-
-               wilc_deinit_host_int(vif->ndev);
-       }
-
-       if (wl->open_ifcs == 0) {
-               netdev_dbg(ndev, "Deinitializing wilc1000\n");
-               wl->close = 1;
-               wilc_wlan_deinitialize(ndev);
-       }
-
-       vif->mac_opened = 0;
-
-       return 0;
-}
-
-void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size,
-                      u32 pkt_offset)
-{
-       unsigned int frame_len = 0;
-       int stats;
-       unsigned char *buff_to_send = NULL;
-       struct sk_buff *skb;
-       struct net_device *wilc_netdev;
-       struct wilc_vif *vif;
-
-       if (!wilc)
-               return;
-
-       wilc_netdev = get_if_handler(wilc, buff);
-       if (!wilc_netdev)
-               return;
-
-       buff += pkt_offset;
-       vif = netdev_priv(wilc_netdev);
-
-       if (size > 0) {
-               frame_len = size;
-               buff_to_send = buff;
-
-               skb = dev_alloc_skb(frame_len);
-               if (!skb)
-                       return;
-
-               skb->dev = wilc_netdev;
-
-               skb_put_data(skb, buff_to_send, frame_len);
-
-               skb->protocol = eth_type_trans(skb, wilc_netdev);
-               vif->netstats.rx_packets++;
-               vif->netstats.rx_bytes += frame_len;
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-               stats = netif_rx(skb);
-               netdev_dbg(wilc_netdev, "netif_rx ret value is: %d\n", stats);
-       }
-}
-
-void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
-{
-       int srcu_idx;
-       struct wilc_vif *vif;
-
-       srcu_idx = srcu_read_lock(&wilc->srcu);
-       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
-               u16 type = le16_to_cpup((__le16 *)buff);
-               u32 type_bit = BIT(type >> 4);
-
-               if (vif->priv.p2p_listen_state &&
-                   vif->mgmt_reg_stypes & type_bit)
-                       wilc_wfi_p2p_rx(vif, buff, size);
-
-               if (vif->monitor_flag)
-                       wilc_wfi_monitor_rx(wilc->monitor_dev, buff, size);
-       }
-       srcu_read_unlock(&wilc->srcu, srcu_idx);
-}
-
-static const struct net_device_ops wilc_netdev_ops = {
-       .ndo_init = mac_init_fn,
-       .ndo_open = wilc_mac_open,
-       .ndo_stop = wilc_mac_close,
-       .ndo_start_xmit = wilc_mac_xmit,
-       .ndo_get_stats = mac_stats,
-       .ndo_set_rx_mode  = wilc_set_multicast_list,
-};
-
-void wilc_netdev_cleanup(struct wilc *wilc)
-{
-       struct wilc_vif *vif;
-       int srcu_idx, ifc_cnt = 0;
-
-       if (!wilc)
-               return;
-
-       if (wilc->firmware) {
-               release_firmware(wilc->firmware);
-               wilc->firmware = NULL;
-       }
-
-       srcu_idx = srcu_read_lock(&wilc->srcu);
-       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
-               if (vif->ndev)
-                       unregister_netdev(vif->ndev);
-       }
-       srcu_read_unlock(&wilc->srcu, srcu_idx);
-
-       wilc_wfi_deinit_mon_interface(wilc, false);
-       flush_workqueue(wilc->hif_workqueue);
-       destroy_workqueue(wilc->hif_workqueue);
-
-       while (ifc_cnt < WILC_NUM_CONCURRENT_IFC) {
-               mutex_lock(&wilc->vif_mutex);
-               if (wilc->vif_num <= 0) {
-                       mutex_unlock(&wilc->vif_mutex);
-                       break;
-               }
-               vif = wilc_get_wl_to_vif(wilc);
-               if (!IS_ERR(vif))
-                       list_del_rcu(&vif->list);
-
-               wilc->vif_num--;
-               mutex_unlock(&wilc->vif_mutex);
-               synchronize_srcu(&wilc->srcu);
-               ifc_cnt++;
-       }
-
-       wilc_wlan_cfg_deinit(wilc);
-       wlan_deinit_locks(wilc);
-       kfree(wilc->bus_data);
-       wiphy_unregister(wilc->wiphy);
-       wiphy_free(wilc->wiphy);
-}
-EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
-
-static u8 wilc_get_available_idx(struct wilc *wl)
-{
-       int idx = 0;
-       struct wilc_vif *vif;
-       int srcu_idx;
-
-       srcu_idx = srcu_read_lock(&wl->srcu);
-       list_for_each_entry_rcu(vif, &wl->vif_list, list) {
-               if (vif->idx == 0)
-                       idx = 1;
-               else
-                       idx = 0;
-       }
-       srcu_read_unlock(&wl->srcu, srcu_idx);
-       return idx;
-}
-
-struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
-                                     int vif_type, enum nl80211_iftype type,
-                                     bool rtnl_locked)
-{
-       struct net_device *ndev;
-       struct wilc_vif *vif;
-       int ret;
-
-       ndev = alloc_etherdev(sizeof(*vif));
-       if (!ndev)
-               return ERR_PTR(-ENOMEM);
-
-       vif = netdev_priv(ndev);
-       ndev->ieee80211_ptr = &vif->priv.wdev;
-       strcpy(ndev->name, name);
-       vif->wilc = wl;
-       vif->ndev = ndev;
-       ndev->ml_priv = vif;
-
-       ndev->netdev_ops = &wilc_netdev_ops;
-
-       SET_NETDEV_DEV(ndev, wiphy_dev(wl->wiphy));
-
-       vif->priv.wdev.wiphy = wl->wiphy;
-       vif->priv.wdev.netdev = ndev;
-       vif->priv.wdev.iftype = type;
-       vif->priv.dev = ndev;
-
-       if (rtnl_locked)
-               ret = register_netdevice(ndev);
-       else
-               ret = register_netdev(ndev);
-
-       if (ret) {
-               free_netdev(ndev);
-               return ERR_PTR(-EFAULT);
-       }
-
-       ndev->needs_free_netdev = true;
-       vif->iftype = vif_type;
-       vif->idx = wilc_get_available_idx(wl);
-       vif->mac_opened = 0;
-       mutex_lock(&wl->vif_mutex);
-       list_add_tail_rcu(&vif->list, &wl->vif_list);
-       wl->vif_num += 1;
-       mutex_unlock(&wl->vif_mutex);
-       synchronize_srcu(&wl->srcu);
-
-       return vif;
-}
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/wilc1000/netdev.h b/drivers/staging/wilc1000/netdev.h
deleted file mode 100644 (file)
index d0a006b..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#ifndef WILC_NETDEV_H
-#define WILC_NETDEV_H
-
-#include <linux/tcp.h>
-#include <linux/ieee80211.h>
-#include <net/cfg80211.h>
-#include <net/ieee80211_radiotap.h>
-#include <linux/if_arp.h>
-#include <linux/gpio/consumer.h>
-
-#include "hif.h"
-#include "wlan.h"
-#include "wlan_cfg.h"
-
-#define FLOW_CONTROL_LOWER_THRESHOLD           128
-#define FLOW_CONTROL_UPPER_THRESHOLD           256
-
-#define PMKID_FOUND                            1
-#define NUM_STA_ASSOCIATED                     8
-
-#define TCP_ACK_FILTER_LINK_SPEED_THRESH       54
-#define DEFAULT_LINK_SPEED                     72
-
-struct wilc_wfi_stats {
-       unsigned long rx_packets;
-       unsigned long tx_packets;
-       unsigned long rx_bytes;
-       unsigned long tx_bytes;
-       u64 rx_time;
-       u64 tx_time;
-
-};
-
-struct wilc_wfi_key {
-       u8 *key;
-       u8 *seq;
-       int key_len;
-       int seq_len;
-       u32 cipher;
-};
-
-struct wilc_wfi_wep_key {
-       u8 *key;
-       u8 key_len;
-       u8 key_idx;
-};
-
-struct sta_info {
-       u8 sta_associated_bss[WILC_MAX_NUM_STA][ETH_ALEN];
-};
-
-/* Parameters needed for host interface for remaining on channel */
-struct wilc_wfi_p2p_listen_params {
-       struct ieee80211_channel *listen_ch;
-       u32 listen_duration;
-       u64 listen_cookie;
-};
-
-static const u32 wilc_cipher_suites[] = {
-       WLAN_CIPHER_SUITE_WEP40,
-       WLAN_CIPHER_SUITE_WEP104,
-       WLAN_CIPHER_SUITE_TKIP,
-       WLAN_CIPHER_SUITE_CCMP,
-       WLAN_CIPHER_SUITE_AES_CMAC
-};
-
-#define CHAN2G(_channel, _freq, _flags) {       \
-       .band             = NL80211_BAND_2GHZ, \
-       .center_freq      = (_freq),             \
-       .hw_value         = (_channel),          \
-       .flags            = (_flags),            \
-       .max_antenna_gain = 0,                   \
-       .max_power        = 30,                  \
-}
-
-static const struct ieee80211_channel wilc_2ghz_channels[] = {
-       CHAN2G(1,  2412, 0),
-       CHAN2G(2,  2417, 0),
-       CHAN2G(3,  2422, 0),
-       CHAN2G(4,  2427, 0),
-       CHAN2G(5,  2432, 0),
-       CHAN2G(6,  2437, 0),
-       CHAN2G(7,  2442, 0),
-       CHAN2G(8,  2447, 0),
-       CHAN2G(9,  2452, 0),
-       CHAN2G(10, 2457, 0),
-       CHAN2G(11, 2462, 0),
-       CHAN2G(12, 2467, 0),
-       CHAN2G(13, 2472, 0),
-       CHAN2G(14, 2484, 0)
-};
-
-#define RATETAB_ENT(_rate, _hw_value, _flags) {        \
-       .bitrate  = (_rate),                    \
-       .hw_value = (_hw_value),                \
-       .flags    = (_flags),                   \
-}
-
-static struct ieee80211_rate wilc_bitrates[] = {
-       RATETAB_ENT(10,  0,  0),
-       RATETAB_ENT(20,  1,  0),
-       RATETAB_ENT(55,  2,  0),
-       RATETAB_ENT(110, 3,  0),
-       RATETAB_ENT(60,  9,  0),
-       RATETAB_ENT(90,  6,  0),
-       RATETAB_ENT(120, 7,  0),
-       RATETAB_ENT(180, 8,  0),
-       RATETAB_ENT(240, 9,  0),
-       RATETAB_ENT(360, 10, 0),
-       RATETAB_ENT(480, 11, 0),
-       RATETAB_ENT(540, 12, 0)
-};
-
-struct wilc_priv {
-       struct wireless_dev wdev;
-       struct cfg80211_scan_request *scan_req;
-
-       struct wilc_wfi_p2p_listen_params remain_on_ch_params;
-       u64 tx_cookie;
-
-       bool cfg_scanning;
-
-       u8 associated_bss[ETH_ALEN];
-       struct sta_info assoc_stainfo;
-       struct sk_buff *skb;
-       struct net_device *dev;
-       struct host_if_drv *hif_drv;
-       struct wilc_pmkid_attr pmkid_list;
-       u8 wep_key[4][WLAN_KEY_LEN_WEP104];
-       u8 wep_key_len[4];
-
-       /* The real interface that the monitor is on */
-       struct net_device *real_ndev;
-       struct wilc_wfi_key *wilc_gtk[WILC_MAX_NUM_STA];
-       struct wilc_wfi_key *wilc_ptk[WILC_MAX_NUM_STA];
-       u8 wilc_groupkey;
-
-       /* mutexes */
-       struct mutex scan_req_lock;
-       bool p2p_listen_state;
-       int scanned_cnt;
-
-       u64 inc_roc_cookie;
-};
-
-#define MAX_TCP_SESSION                25
-#define MAX_PENDING_ACKS               256
-
-struct ack_session_info {
-       u32 seq_num;
-       u32 bigger_ack_num;
-       u16 src_port;
-       u16 dst_port;
-       u16 status;
-};
-
-struct pending_acks {
-       u32 ack_num;
-       u32 session_index;
-       struct txq_entry_t  *txqe;
-};
-
-struct tcp_ack_filter {
-       struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
-       struct pending_acks pending_acks[MAX_PENDING_ACKS];
-       u32 pending_base;
-       u32 tcp_session;
-       u32 pending_acks_idx;
-       bool enabled;
-};
-
-struct wilc_vif {
-       u8 idx;
-       u8 iftype;
-       int monitor_flag;
-       int mac_opened;
-       u32 mgmt_reg_stypes;
-       struct net_device_stats netstats;
-       struct wilc *wilc;
-       u8 bssid[ETH_ALEN];
-       struct host_if_drv *hif_drv;
-       struct net_device *ndev;
-       u8 mode;
-       struct timer_list during_ip_timer;
-       struct timer_list periodic_rssi;
-       struct rf_info periodic_stat;
-       struct tcp_ack_filter ack_filter;
-       bool connecting;
-       struct wilc_priv priv;
-       struct list_head list;
-       struct cfg80211_bss *bss;
-};
-
-struct wilc {
-       struct wiphy *wiphy;
-       const struct wilc_hif_func *hif_func;
-       int io_type;
-       s8 mac_status;
-       struct clk *rtc_clk;
-       bool initialized;
-       int dev_irq_num;
-       int close;
-       u8 vif_num;
-       struct list_head vif_list;
-
-       /* protect vif list */
-       struct mutex vif_mutex;
-       struct srcu_struct srcu;
-       u8 open_ifcs;
-
-       /* protect head of transmit queue */
-       struct mutex txq_add_to_head_cs;
-
-       /* protect txq_entry_t transmit queue */
-       spinlock_t txq_spinlock;
-
-       /* protect rxq_entry_t receiver queue */
-       struct mutex rxq_cs;
-
-       /* lock to protect hif access */
-       struct mutex hif_cs;
-
-       struct completion cfg_event;
-       struct completion sync_event;
-       struct completion txq_event;
-       struct completion txq_thread_started;
-
-       struct task_struct *txq_thread;
-
-       int quit;
-
-       /* lock to protect issue of wid command to firmware */
-       struct mutex cfg_cmd_lock;
-       struct wilc_cfg_frame cfg_frame;
-       u32 cfg_frame_offset;
-       u8 cfg_seq_no;
-
-       u8 *rx_buffer;
-       u32 rx_buffer_offset;
-       u8 *tx_buffer;
-
-       struct txq_entry_t txq_head;
-       int txq_entries;
-
-       struct rxq_entry_t rxq_head;
-
-       const struct firmware *firmware;
-
-       struct device *dev;
-       bool suspend_event;
-
-       int clients_count;
-       struct workqueue_struct *hif_workqueue;
-       enum chip_ps_states chip_ps_state;
-       struct wilc_cfg cfg;
-       void *bus_data;
-       struct net_device *monitor_dev;
-
-       /* deinit lock */
-       struct mutex deinit_lock;
-       u8 sta_ch;
-       u8 op_ch;
-       struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
-       struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
-       struct ieee80211_supported_band band;
-       u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
-};
-
-struct wilc_wfi_mon_priv {
-       struct net_device *real_ndev;
-};
-
-void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
-void wilc_mac_indicate(struct wilc *wilc);
-void wilc_netdev_cleanup(struct wilc *wilc);
-void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size);
-void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode);
-struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
-                                     int vif_type, enum nl80211_iftype type,
-                                     bool rtnl_locked);
-#endif
diff --git a/drivers/staging/wilc1000/sdio.c b/drivers/staging/wilc1000/sdio.c
deleted file mode 100644 (file)
index 36eb589..0000000
+++ /dev/null
@@ -1,1023 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#include <linux/clk.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio.h>
-#include <linux/of_irq.h>
-
-#include "netdev.h"
-#include "cfg80211.h"
-
-#define SDIO_MODALIAS "wilc1000_sdio"
-
-#define SDIO_VENDOR_ID_WILC 0x0296
-#define SDIO_DEVICE_ID_WILC 0x5347
-
-static const struct sdio_device_id wilc_sdio_ids[] = {
-       { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
-       { },
-};
-
-#define WILC_SDIO_BLOCK_SIZE 512
-
-struct wilc_sdio {
-       bool irq_gpio;
-       u32 block_size;
-       int has_thrpt_enh3;
-};
-
-struct sdio_cmd52 {
-       u32 read_write:         1;
-       u32 function:           3;
-       u32 raw:                1;
-       u32 address:            17;
-       u32 data:               8;
-};
-
-struct sdio_cmd53 {
-       u32 read_write:         1;
-       u32 function:           3;
-       u32 block_mode:         1;
-       u32 increment:          1;
-       u32 address:            17;
-       u32 count:              9;
-       u8 *buffer;
-       u32 block_size;
-};
-
-static const struct wilc_hif_func wilc_hif_sdio;
-
-static void wilc_sdio_interrupt(struct sdio_func *func)
-{
-       sdio_release_host(func);
-       wilc_handle_isr(sdio_get_drvdata(func));
-       sdio_claim_host(func);
-}
-
-static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd)
-{
-       struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
-       int ret;
-       u8 data;
-
-       sdio_claim_host(func);
-
-       func->num = cmd->function;
-       if (cmd->read_write) {  /* write */
-               if (cmd->raw) {
-                       sdio_writeb(func, cmd->data, cmd->address, &ret);
-                       data = sdio_readb(func, cmd->address, &ret);
-                       cmd->data = data;
-               } else {
-                       sdio_writeb(func, cmd->data, cmd->address, &ret);
-               }
-       } else {        /* read */
-               data = sdio_readb(func, cmd->address, &ret);
-               cmd->data = data;
-       }
-
-       sdio_release_host(func);
-
-       if (ret)
-               dev_err(&func->dev, "%s..failed, err(%d)\n", __func__, ret);
-       return ret;
-}
-
-static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd)
-{
-       struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
-       int size, ret;
-
-       sdio_claim_host(func);
-
-       func->num = cmd->function;
-       func->cur_blksize = cmd->block_size;
-       if (cmd->block_mode)
-               size = cmd->count * cmd->block_size;
-       else
-               size = cmd->count;
-
-       if (cmd->read_write) {  /* write */
-               ret = sdio_memcpy_toio(func, cmd->address,
-                                      (void *)cmd->buffer, size);
-       } else {        /* read */
-               ret = sdio_memcpy_fromio(func, (void *)cmd->buffer,
-                                        cmd->address,  size);
-       }
-
-       sdio_release_host(func);
-
-       if (ret)
-               dev_err(&func->dev, "%s..failed, err(%d)\n", __func__,  ret);
-
-       return ret;
-}
-
-static int wilc_sdio_probe(struct sdio_func *func,
-                          const struct sdio_device_id *id)
-{
-       struct wilc *wilc;
-       int ret;
-       struct wilc_sdio *sdio_priv;
-
-       sdio_priv = kzalloc(sizeof(*sdio_priv), GFP_KERNEL);
-       if (!sdio_priv)
-               return -ENOMEM;
-
-       ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO,
-                                &wilc_hif_sdio);
-       if (ret) {
-               kfree(sdio_priv);
-               return ret;
-       }
-
-       if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) {
-               struct device_node *np = func->card->dev.of_node;
-               int irq_num = of_irq_get(np, 0);
-
-               if (irq_num > 0) {
-                       wilc->dev_irq_num = irq_num;
-                       sdio_priv->irq_gpio = true;
-               }
-       }
-
-       sdio_set_drvdata(func, wilc);
-       wilc->bus_data = sdio_priv;
-       wilc->dev = &func->dev;
-
-       wilc->rtc_clk = devm_clk_get(&func->card->dev, "rtc");
-       if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER)
-               return -EPROBE_DEFER;
-       else if (!IS_ERR(wilc->rtc_clk))
-               clk_prepare_enable(wilc->rtc_clk);
-
-       dev_info(&func->dev, "Driver Initializing success\n");
-       return 0;
-}
-
-static void wilc_sdio_remove(struct sdio_func *func)
-{
-       struct wilc *wilc = sdio_get_drvdata(func);
-
-       if (!IS_ERR(wilc->rtc_clk))
-               clk_disable_unprepare(wilc->rtc_clk);
-
-       wilc_netdev_cleanup(wilc);
-}
-
-static int wilc_sdio_reset(struct wilc *wilc)
-{
-       struct sdio_cmd52 cmd;
-       int ret;
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-
-       cmd.read_write = 1;
-       cmd.function = 0;
-       cmd.raw = 0;
-       cmd.address = SDIO_CCCR_ABORT;
-       cmd.data = WILC_SDIO_CCCR_ABORT_RESET;
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev, "Fail cmd 52, reset cmd ...\n");
-               return ret;
-       }
-       return 0;
-}
-
-static int wilc_sdio_suspend(struct device *dev)
-{
-       struct sdio_func *func = dev_to_sdio_func(dev);
-       struct wilc *wilc = sdio_get_drvdata(func);
-       int ret;
-
-       dev_info(dev, "sdio suspend\n");
-       chip_wakeup(wilc);
-
-       if (!IS_ERR(wilc->rtc_clk))
-               clk_disable_unprepare(wilc->rtc_clk);
-
-       if (wilc->suspend_event) {
-               host_sleep_notify(wilc);
-               chip_allow_sleep(wilc);
-       }
-
-       ret = wilc_sdio_reset(wilc);
-       if (ret) {
-               dev_err(&func->dev, "Fail reset sdio\n");
-               return ret;
-       }
-       sdio_claim_host(func);
-
-       return 0;
-}
-
-static int wilc_sdio_enable_interrupt(struct wilc *dev)
-{
-       struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
-       int ret = 0;
-
-       sdio_claim_host(func);
-       ret = sdio_claim_irq(func, wilc_sdio_interrupt);
-       sdio_release_host(func);
-
-       if (ret < 0) {
-               dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret);
-               ret = -EIO;
-       }
-       return ret;
-}
-
-static void wilc_sdio_disable_interrupt(struct wilc *dev)
-{
-       struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
-       int ret;
-
-       sdio_claim_host(func);
-       ret = sdio_release_irq(func);
-       if (ret < 0)
-               dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret);
-       sdio_release_host(func);
-}
-
-/********************************************
- *
- *      Function 0
- *
- ********************************************/
-
-static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct sdio_cmd52 cmd;
-       int ret;
-
-       /**
-        *      Review: BIG ENDIAN
-        **/
-       cmd.read_write = 1;
-       cmd.function = 0;
-       cmd.raw = 0;
-       cmd.address = WILC_SDIO_FBR_CSA_REG;
-       cmd.data = (u8)adr;
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
-                       cmd.address);
-               return ret;
-       }
-
-       cmd.address = WILC_SDIO_FBR_CSA_REG + 1;
-       cmd.data = (u8)(adr >> 8);
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
-                       cmd.address);
-               return ret;
-       }
-
-       cmd.address = WILC_SDIO_FBR_CSA_REG + 2;
-       cmd.data = (u8)(adr >> 16);
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
-                       cmd.address);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int wilc_sdio_set_block_size(struct wilc *wilc, u8 func_num,
-                                   u32 block_size)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct sdio_cmd52 cmd;
-       int ret;
-
-       cmd.read_write = 1;
-       cmd.function = 0;
-       cmd.raw = 0;
-       cmd.address = SDIO_FBR_BASE(func_num) + SDIO_CCCR_BLKSIZE;
-       cmd.data = (u8)block_size;
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
-                       cmd.address);
-               return ret;
-       }
-
-       cmd.address = SDIO_FBR_BASE(func_num) + SDIO_CCCR_BLKSIZE +  1;
-       cmd.data = (u8)(block_size >> 8);
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
-                       cmd.address);
-               return ret;
-       }
-
-       return 0;
-}
-
-/********************************************
- *
- *      Sdio interfaces
- *
- ********************************************/
-static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct wilc_sdio *sdio_priv = wilc->bus_data;
-       int ret;
-
-       cpu_to_le32s(&data);
-
-       if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */
-               struct sdio_cmd52 cmd;
-
-               cmd.read_write = 1;
-               cmd.function = 0;
-               cmd.raw = 0;
-               cmd.address = addr;
-               cmd.data = data;
-               ret = wilc_sdio_cmd52(wilc, &cmd);
-               if (ret)
-                       dev_err(&func->dev,
-                               "Failed cmd 52, read reg (%08x) ...\n", addr);
-       } else {
-               struct sdio_cmd53 cmd;
-
-               /**
-                *      set the AHB address
-                **/
-               ret = wilc_sdio_set_func0_csa_address(wilc, addr);
-               if (ret)
-                       return ret;
-
-               cmd.read_write = 1;
-               cmd.function = 0;
-               cmd.address = WILC_SDIO_FBR_DATA_REG;
-               cmd.block_mode = 0;
-               cmd.increment = 1;
-               cmd.count = 4;
-               cmd.buffer = (u8 *)&data;
-               cmd.block_size = sdio_priv->block_size;
-               ret = wilc_sdio_cmd53(wilc, &cmd);
-               if (ret)
-                       dev_err(&func->dev,
-                               "Failed cmd53, write reg (%08x)...\n", addr);
-       }
-
-       return ret;
-}
-
-static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct wilc_sdio *sdio_priv = wilc->bus_data;
-       u32 block_size = sdio_priv->block_size;
-       struct sdio_cmd53 cmd;
-       int nblk, nleft, ret;
-
-       cmd.read_write = 1;
-       if (addr > 0) {
-               /**
-                *      func 0 access
-                **/
-               cmd.function = 0;
-               cmd.address = WILC_SDIO_FBR_DATA_REG;
-       } else {
-               /**
-                *      func 1 access
-                **/
-               cmd.function = 1;
-               cmd.address = WILC_SDIO_F1_DATA_REG;
-       }
-
-       size = ALIGN(size, 4);
-       nblk = size / block_size;
-       nleft = size % block_size;
-
-       if (nblk > 0) {
-               cmd.block_mode = 1;
-               cmd.increment = 1;
-               cmd.count = nblk;
-               cmd.buffer = buf;
-               cmd.block_size = block_size;
-               if (addr > 0) {
-                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
-                       if (ret)
-                               return ret;
-               }
-               ret = wilc_sdio_cmd53(wilc, &cmd);
-               if (ret) {
-                       dev_err(&func->dev,
-                               "Failed cmd53 [%x], block send...\n", addr);
-                       return ret;
-               }
-               if (addr > 0)
-                       addr += nblk * block_size;
-               buf += nblk * block_size;
-       }
-
-       if (nleft > 0) {
-               cmd.block_mode = 0;
-               cmd.increment = 1;
-               cmd.count = nleft;
-               cmd.buffer = buf;
-
-               cmd.block_size = block_size;
-
-               if (addr > 0) {
-                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
-                       if (ret)
-                               return ret;
-               }
-               ret = wilc_sdio_cmd53(wilc, &cmd);
-               if (ret) {
-                       dev_err(&func->dev,
-                               "Failed cmd53 [%x], bytes send...\n", addr);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct wilc_sdio *sdio_priv = wilc->bus_data;
-       int ret;
-
-       if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */
-               struct sdio_cmd52 cmd;
-
-               cmd.read_write = 0;
-               cmd.function = 0;
-               cmd.raw = 0;
-               cmd.address = addr;
-               ret = wilc_sdio_cmd52(wilc, &cmd);
-               if (ret) {
-                       dev_err(&func->dev,
-                               "Failed cmd 52, read reg (%08x) ...\n", addr);
-                       return ret;
-               }
-               *data = cmd.data;
-       } else {
-               struct sdio_cmd53 cmd;
-
-               ret = wilc_sdio_set_func0_csa_address(wilc, addr);
-               if (ret)
-                       return ret;
-
-               cmd.read_write = 0;
-               cmd.function = 0;
-               cmd.address = WILC_SDIO_FBR_DATA_REG;
-               cmd.block_mode = 0;
-               cmd.increment = 1;
-               cmd.count = 4;
-               cmd.buffer = (u8 *)data;
-
-               cmd.block_size = sdio_priv->block_size;
-               ret = wilc_sdio_cmd53(wilc, &cmd);
-               if (ret) {
-                       dev_err(&func->dev,
-                               "Failed cmd53, read reg (%08x)...\n", addr);
-                       return ret;
-               }
-       }
-
-       le32_to_cpus(data);
-       return 0;
-}
-
-static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct wilc_sdio *sdio_priv = wilc->bus_data;
-       u32 block_size = sdio_priv->block_size;
-       struct sdio_cmd53 cmd;
-       int nblk, nleft, ret;
-
-       cmd.read_write = 0;
-       if (addr > 0) {
-               /**
-                *      func 0 access
-                **/
-               cmd.function = 0;
-               cmd.address = WILC_SDIO_FBR_DATA_REG;
-       } else {
-               /**
-                *      func 1 access
-                **/
-               cmd.function = 1;
-               cmd.address = WILC_SDIO_F1_DATA_REG;
-       }
-
-       size = ALIGN(size, 4);
-       nblk = size / block_size;
-       nleft = size % block_size;
-
-       if (nblk > 0) {
-               cmd.block_mode = 1;
-               cmd.increment = 1;
-               cmd.count = nblk;
-               cmd.buffer = buf;
-               cmd.block_size = block_size;
-               if (addr > 0) {
-                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
-                       if (ret)
-                               return ret;
-               }
-               ret = wilc_sdio_cmd53(wilc, &cmd);
-               if (ret) {
-                       dev_err(&func->dev,
-                               "Failed cmd53 [%x], block read...\n", addr);
-                       return ret;
-               }
-               if (addr > 0)
-                       addr += nblk * block_size;
-               buf += nblk * block_size;
-       }       /* if (nblk > 0) */
-
-       if (nleft > 0) {
-               cmd.block_mode = 0;
-               cmd.increment = 1;
-               cmd.count = nleft;
-               cmd.buffer = buf;
-
-               cmd.block_size = block_size;
-
-               if (addr > 0) {
-                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
-                       if (ret)
-                               return ret;
-               }
-               ret = wilc_sdio_cmd53(wilc, &cmd);
-               if (ret) {
-                       dev_err(&func->dev,
-                               "Failed cmd53 [%x], bytes read...\n", addr);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-/********************************************
- *
- *      Bus interfaces
- *
- ********************************************/
-
-static int wilc_sdio_deinit(struct wilc *wilc)
-{
-       return 0;
-}
-
-static int wilc_sdio_init(struct wilc *wilc, bool resume)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct wilc_sdio *sdio_priv = wilc->bus_data;
-       struct sdio_cmd52 cmd;
-       int loop, ret;
-       u32 chipid;
-
-       /**
-        *      function 0 csa enable
-        **/
-       cmd.read_write = 1;
-       cmd.function = 0;
-       cmd.raw = 1;
-       cmd.address = SDIO_FBR_BASE(func->num);
-       cmd.data = SDIO_FBR_ENABLE_CSA;
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev, "Fail cmd 52, enable csa...\n");
-               return ret;
-       }
-
-       /**
-        *      function 0 block size
-        **/
-       ret = wilc_sdio_set_block_size(wilc, 0, WILC_SDIO_BLOCK_SIZE);
-       if (ret) {
-               dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");
-               return ret;
-       }
-       sdio_priv->block_size = WILC_SDIO_BLOCK_SIZE;
-
-       /**
-        *      enable func1 IO
-        **/
-       cmd.read_write = 1;
-       cmd.function = 0;
-       cmd.raw = 1;
-       cmd.address = SDIO_CCCR_IOEx;
-       cmd.data = WILC_SDIO_CCCR_IO_EN_FUNC1;
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev,
-                       "Fail cmd 52, set IOE register...\n");
-               return ret;
-       }
-
-       /**
-        *      make sure func 1 is up
-        **/
-       cmd.read_write = 0;
-       cmd.function = 0;
-       cmd.raw = 0;
-       cmd.address = SDIO_CCCR_IORx;
-       loop = 3;
-       do {
-               cmd.data = 0;
-               ret = wilc_sdio_cmd52(wilc, &cmd);
-               if (ret) {
-                       dev_err(&func->dev,
-                               "Fail cmd 52, get IOR register...\n");
-                       return ret;
-               }
-               if (cmd.data == WILC_SDIO_CCCR_IO_EN_FUNC1)
-                       break;
-       } while (loop--);
-
-       if (loop <= 0) {
-               dev_err(&func->dev, "Fail func 1 is not ready...\n");
-               return -EINVAL;
-       }
-
-       /**
-        *      func 1 is ready, set func 1 block size
-        **/
-       ret = wilc_sdio_set_block_size(wilc, 1, WILC_SDIO_BLOCK_SIZE);
-       if (ret) {
-               dev_err(&func->dev, "Fail set func 1 block size...\n");
-               return ret;
-       }
-
-       /**
-        *      func 1 interrupt enable
-        **/
-       cmd.read_write = 1;
-       cmd.function = 0;
-       cmd.raw = 1;
-       cmd.address = SDIO_CCCR_IENx;
-       cmd.data = WILC_SDIO_CCCR_IEN_MASTER | WILC_SDIO_CCCR_IEN_FUNC1;
-       ret = wilc_sdio_cmd52(wilc, &cmd);
-       if (ret) {
-               dev_err(&func->dev, "Fail cmd 52, set IEN register...\n");
-               return ret;
-       }
-
-       /**
-        *      make sure can read back chip id correctly
-        **/
-       if (!resume) {
-               int rev;
-
-               ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid);
-               if (ret) {
-                       dev_err(&func->dev, "Fail cmd read chip id...\n");
-                       return ret;
-               }
-               dev_err(&func->dev, "chipid (%08x)\n", chipid);
-               rev = FIELD_GET(WILC_CHIP_REV_FIELD, chipid);
-               if (rev > FIELD_GET(WILC_CHIP_REV_FIELD, WILC_1000_BASE_ID_2A))
-                       sdio_priv->has_thrpt_enh3 = 1;
-               else
-                       sdio_priv->has_thrpt_enh3 = 0;
-               dev_info(&func->dev, "has_thrpt_enh3 = %d...\n",
-                        sdio_priv->has_thrpt_enh3);
-       }
-
-       return 0;
-}
-
-static int wilc_sdio_read_size(struct wilc *wilc, u32 *size)
-{
-       u32 tmp;
-       struct sdio_cmd52 cmd;
-
-       /**
-        *      Read DMA count in words
-        **/
-       cmd.read_write = 0;
-       cmd.function = 0;
-       cmd.raw = 0;
-       cmd.address = WILC_SDIO_INTERRUPT_DATA_SZ_REG;
-       cmd.data = 0;
-       wilc_sdio_cmd52(wilc, &cmd);
-       tmp = cmd.data;
-
-       cmd.address = WILC_SDIO_INTERRUPT_DATA_SZ_REG + 1;
-       cmd.data = 0;
-       wilc_sdio_cmd52(wilc, &cmd);
-       tmp |= (cmd.data << 8);
-
-       *size = tmp;
-       return 0;
-}
-
-static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct wilc_sdio *sdio_priv = wilc->bus_data;
-       u32 tmp;
-       u8 irq_flags;
-       struct sdio_cmd52 cmd;
-
-       wilc_sdio_read_size(wilc, &tmp);
-
-       /**
-        *      Read IRQ flags
-        **/
-       if (!sdio_priv->irq_gpio) {
-               cmd.function = 1;
-               cmd.address = WILC_SDIO_EXT_IRQ_FLAG_REG;
-       } else {
-               cmd.function = 0;
-               cmd.address = WILC_SDIO_IRQ_FLAG_REG;
-       }
-       cmd.raw = 0;
-       cmd.read_write = 0;
-       cmd.data = 0;
-       wilc_sdio_cmd52(wilc, &cmd);
-       irq_flags = cmd.data;
-       tmp |= FIELD_PREP(IRG_FLAGS_MASK, cmd.data);
-
-       if (FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags))
-               dev_err(&func->dev, "Unexpected interrupt (1) int=%lx\n",
-                       FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags));
-
-       *int_status = tmp;
-
-       return 0;
-}
-
-static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct wilc_sdio *sdio_priv = wilc->bus_data;
-       int ret;
-       int vmm_ctl;
-
-       if (sdio_priv->has_thrpt_enh3) {
-               u32 reg = 0;
-
-               if (sdio_priv->irq_gpio)
-                       reg = val & (BIT(MAX_NUM_INT) - 1);
-
-               /* select VMM table 0 */
-               if (val & SEL_VMM_TBL0)
-                       reg |= BIT(5);
-               /* select VMM table 1 */
-               if (val & SEL_VMM_TBL1)
-                       reg |= BIT(6);
-               /* enable VMM */
-               if (val & EN_VMM)
-                       reg |= BIT(7);
-               if (reg) {
-                       struct sdio_cmd52 cmd;
-
-                       cmd.read_write = 1;
-                       cmd.function = 0;
-                       cmd.raw = 0;
-                       cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;
-                       cmd.data = reg;
-
-                       ret = wilc_sdio_cmd52(wilc, &cmd);
-                       if (ret) {
-                               dev_err(&func->dev,
-                                       "Failed cmd52, set (%02x) data (%d) ...\n",
-                                       cmd.address, __LINE__);
-                               return ret;
-                       }
-               }
-               return 0;
-       }
-       if (sdio_priv->irq_gpio) {
-               /* has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
-               /*
-                * Cannot clear multiple interrupts.
-                * Must clear each interrupt individually.
-                */
-               u32 flags;
-               int i;
-
-               flags = val & (BIT(MAX_NUM_INT) - 1);
-               for (i = 0; i < NUM_INT_EXT && flags; i++) {
-                       if (flags & BIT(i)) {
-                               struct sdio_cmd52 cmd;
-
-                               cmd.read_write = 1;
-                               cmd.function = 0;
-                               cmd.raw = 0;
-                               cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;
-                               cmd.data = BIT(i);
-
-                               ret = wilc_sdio_cmd52(wilc, &cmd);
-                               if (ret) {
-                                       dev_err(&func->dev,
-                                               "Failed cmd52, set (%02x) data (%d) ...\n",
-                                               cmd.address, __LINE__);
-                                       return ret;
-                               }
-                               flags &= ~BIT(i);
-                       }
-               }
-
-               for (i = NUM_INT_EXT; i < MAX_NUM_INT && flags; i++) {
-                       if (flags & BIT(i)) {
-                               dev_err(&func->dev,
-                                       "Unexpected interrupt cleared %d...\n",
-                                       i);
-                               flags &= ~BIT(i);
-                       }
-               }
-       }
-
-       vmm_ctl = 0;
-       /* select VMM table 0 */
-       if (val & SEL_VMM_TBL0)
-               vmm_ctl |= BIT(0);
-       /* select VMM table 1 */
-       if (val & SEL_VMM_TBL1)
-               vmm_ctl |= BIT(1);
-       /* enable VMM */
-       if (val & EN_VMM)
-               vmm_ctl |= BIT(2);
-
-       if (vmm_ctl) {
-               struct sdio_cmd52 cmd;
-
-               cmd.read_write = 1;
-               cmd.function = 0;
-               cmd.raw = 0;
-               cmd.address = WILC_SDIO_VMM_TBL_CTRL_REG;
-               cmd.data = vmm_ctl;
-               ret = wilc_sdio_cmd52(wilc, &cmd);
-               if (ret) {
-                       dev_err(&func->dev,
-                               "Failed cmd52, set (%02x) data (%d) ...\n",
-                               cmd.address, __LINE__);
-                       return ret;
-               }
-       }
-       return 0;
-}
-
-static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)
-{
-       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       struct wilc_sdio *sdio_priv = wilc->bus_data;
-       u32 reg;
-
-       if (nint > MAX_NUM_INT) {
-               dev_err(&func->dev, "Too many interrupts (%d)...\n", nint);
-               return -EINVAL;
-       }
-
-       /**
-        *      Disable power sequencer
-        **/
-       if (wilc_sdio_read_reg(wilc, WILC_MISC, &reg)) {
-               dev_err(&func->dev, "Failed read misc reg...\n");
-               return -EINVAL;
-       }
-
-       reg &= ~BIT(8);
-       if (wilc_sdio_write_reg(wilc, WILC_MISC, reg)) {
-               dev_err(&func->dev, "Failed write misc reg...\n");
-               return -EINVAL;
-       }
-
-       if (sdio_priv->irq_gpio) {
-               u32 reg;
-               int ret, i;
-
-               /**
-                *      interrupt pin mux select
-                **/
-               ret = wilc_sdio_read_reg(wilc, WILC_PIN_MUX_0, &reg);
-               if (ret) {
-                       dev_err(&func->dev, "Failed read reg (%08x)...\n",
-                               WILC_PIN_MUX_0);
-                       return ret;
-               }
-               reg |= BIT(8);
-               ret = wilc_sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);
-               if (ret) {
-                       dev_err(&func->dev, "Failed write reg (%08x)...\n",
-                               WILC_PIN_MUX_0);
-                       return ret;
-               }
-
-               /**
-                *      interrupt enable
-                **/
-               ret = wilc_sdio_read_reg(wilc, WILC_INTR_ENABLE, &reg);
-               if (ret) {
-                       dev_err(&func->dev, "Failed read reg (%08x)...\n",
-                               WILC_INTR_ENABLE);
-                       return ret;
-               }
-
-               for (i = 0; (i < 5) && (nint > 0); i++, nint--)
-                       reg |= BIT((27 + i));
-               ret = wilc_sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);
-               if (ret) {
-                       dev_err(&func->dev, "Failed write reg (%08x)...\n",
-                               WILC_INTR_ENABLE);
-                       return ret;
-               }
-               if (nint) {
-                       ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
-                       if (ret) {
-                               dev_err(&func->dev,
-                                       "Failed read reg (%08x)...\n",
-                                       WILC_INTR2_ENABLE);
-                               return ret;
-                       }
-
-                       for (i = 0; (i < 3) && (nint > 0); i++, nint--)
-                               reg |= BIT(i);
-
-                       ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
-                       if (ret) {
-                               dev_err(&func->dev,
-                                       "Failed write reg (%08x)...\n",
-                                       WILC_INTR2_ENABLE);
-                               return ret;
-                       }
-               }
-       }
-       return 0;
-}
-
-/* Global sdio HIF function table */
-static const struct wilc_hif_func wilc_hif_sdio = {
-       .hif_init = wilc_sdio_init,
-       .hif_deinit = wilc_sdio_deinit,
-       .hif_read_reg = wilc_sdio_read_reg,
-       .hif_write_reg = wilc_sdio_write_reg,
-       .hif_block_rx = wilc_sdio_read,
-       .hif_block_tx = wilc_sdio_write,
-       .hif_read_int = wilc_sdio_read_int,
-       .hif_clear_int_ext = wilc_sdio_clear_int_ext,
-       .hif_read_size = wilc_sdio_read_size,
-       .hif_block_tx_ext = wilc_sdio_write,
-       .hif_block_rx_ext = wilc_sdio_read,
-       .hif_sync_ext = wilc_sdio_sync_ext,
-       .enable_interrupt = wilc_sdio_enable_interrupt,
-       .disable_interrupt = wilc_sdio_disable_interrupt,
-};
-
-static int wilc_sdio_resume(struct device *dev)
-{
-       struct sdio_func *func = dev_to_sdio_func(dev);
-       struct wilc *wilc = sdio_get_drvdata(func);
-
-       dev_info(dev, "sdio resume\n");
-       sdio_release_host(func);
-       chip_wakeup(wilc);
-       wilc_sdio_init(wilc, true);
-
-       if (wilc->suspend_event)
-               host_wakeup_notify(wilc);
-
-       chip_allow_sleep(wilc);
-
-       return 0;
-}
-
-static const struct of_device_id wilc_of_match[] = {
-       { .compatible = "microchip,wilc1000", },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, wilc_of_match);
-
-static const struct dev_pm_ops wilc_sdio_pm_ops = {
-       .suspend = wilc_sdio_suspend,
-       .resume = wilc_sdio_resume,
-};
-
-static struct sdio_driver wilc_sdio_driver = {
-       .name           = SDIO_MODALIAS,
-       .id_table       = wilc_sdio_ids,
-       .probe          = wilc_sdio_probe,
-       .remove         = wilc_sdio_remove,
-       .drv = {
-               .pm = &wilc_sdio_pm_ops,
-               .of_match_table = wilc_of_match,
-       }
-};
-module_driver(wilc_sdio_driver,
-             sdio_register_driver,
-             sdio_unregister_driver);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/wilc1000/spi.c b/drivers/staging/wilc1000/spi.c
deleted file mode 100644 (file)
index 3f19e3f..0000000
+++ /dev/null
@@ -1,945 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#include <linux/clk.h>
-#include <linux/spi/spi.h>
-#include <linux/crc7.h>
-
-#include "netdev.h"
-#include "cfg80211.h"
-
-struct wilc_spi {
-       int crc_off;
-};
-
-static const struct wilc_hif_func wilc_hif_spi;
-
-/********************************************
- *
- *      Spi protocol Function
- *
- ********************************************/
-
-#define CMD_DMA_WRITE                          0xc1
-#define CMD_DMA_READ                           0xc2
-#define CMD_INTERNAL_WRITE                     0xc3
-#define CMD_INTERNAL_READ                      0xc4
-#define CMD_TERMINATE                          0xc5
-#define CMD_REPEAT                             0xc6
-#define CMD_DMA_EXT_WRITE                      0xc7
-#define CMD_DMA_EXT_READ                       0xc8
-#define CMD_SINGLE_WRITE                       0xc9
-#define CMD_SINGLE_READ                                0xca
-#define CMD_RESET                              0xcf
-
-#define DATA_PKT_SZ_256                                256
-#define DATA_PKT_SZ_512                                512
-#define DATA_PKT_SZ_1K                         1024
-#define DATA_PKT_SZ_4K                         (4 * 1024)
-#define DATA_PKT_SZ_8K                         (8 * 1024)
-#define DATA_PKT_SZ                            DATA_PKT_SZ_8K
-
-#define USE_SPI_DMA                            0
-
-#define WILC_SPI_COMMAND_STAT_SUCCESS          0
-#define WILC_GET_RESP_HDR_START(h)             (((h) >> 4) & 0xf)
-
-struct wilc_spi_cmd {
-       u8 cmd_type;
-       union {
-               struct {
-                       u8 addr[3];
-                       u8 crc[];
-               } __packed simple_cmd;
-               struct {
-                       u8 addr[3];
-                       u8 size[2];
-                       u8 crc[];
-               } __packed dma_cmd;
-               struct {
-                       u8 addr[3];
-                       u8 size[3];
-                       u8 crc[];
-               } __packed dma_cmd_ext;
-               struct {
-                       u8 addr[2];
-                       __be32 data;
-                       u8 crc[];
-               } __packed internal_w_cmd;
-               struct {
-                       u8 addr[3];
-                       __be32 data;
-                       u8 crc[];
-               } __packed w_cmd;
-       } u;
-} __packed;
-
-struct wilc_spi_read_rsp_data {
-       u8 rsp_cmd_type;
-       u8 status;
-       u8 resp_header;
-       u8 resp_data[4];
-       u8 crc[];
-} __packed;
-
-struct wilc_spi_rsp_data {
-       u8 rsp_cmd_type;
-       u8 status;
-} __packed;
-
-static int wilc_bus_probe(struct spi_device *spi)
-{
-       int ret;
-       struct wilc *wilc;
-       struct wilc_spi *spi_priv;
-
-       spi_priv = kzalloc(sizeof(*spi_priv), GFP_KERNEL);
-       if (!spi_priv)
-               return -ENOMEM;
-
-       ret = wilc_cfg80211_init(&wilc, &spi->dev, WILC_HIF_SPI, &wilc_hif_spi);
-       if (ret) {
-               kfree(spi_priv);
-               return ret;
-       }
-
-       spi_set_drvdata(spi, wilc);
-       wilc->dev = &spi->dev;
-       wilc->bus_data = spi_priv;
-       wilc->dev_irq_num = spi->irq;
-
-       wilc->rtc_clk = devm_clk_get(&spi->dev, "rtc_clk");
-       if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER)
-               return -EPROBE_DEFER;
-       else if (!IS_ERR(wilc->rtc_clk))
-               clk_prepare_enable(wilc->rtc_clk);
-
-       return 0;
-}
-
-static int wilc_bus_remove(struct spi_device *spi)
-{
-       struct wilc *wilc = spi_get_drvdata(spi);
-
-       if (!IS_ERR(wilc->rtc_clk))
-               clk_disable_unprepare(wilc->rtc_clk);
-
-       wilc_netdev_cleanup(wilc);
-       return 0;
-}
-
-static const struct of_device_id wilc_of_match[] = {
-       { .compatible = "microchip,wilc1000", },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, wilc_of_match);
-
-static struct spi_driver wilc_spi_driver = {
-       .driver = {
-               .name = MODALIAS,
-               .of_match_table = wilc_of_match,
-       },
-       .probe =  wilc_bus_probe,
-       .remove = wilc_bus_remove,
-};
-module_spi_driver(wilc_spi_driver);
-MODULE_LICENSE("GPL");
-
-static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int ret;
-       struct spi_message msg;
-
-       if (len > 0 && b) {
-               struct spi_transfer tr = {
-                       .tx_buf = b,
-                       .len = len,
-                       .delay = {
-                               .value = 0,
-                               .unit = SPI_DELAY_UNIT_USECS
-                       },
-               };
-               char *r_buffer = kzalloc(len, GFP_KERNEL);
-
-               if (!r_buffer)
-                       return -ENOMEM;
-
-               tr.rx_buf = r_buffer;
-               dev_dbg(&spi->dev, "Request writing %d bytes\n", len);
-
-               memset(&msg, 0, sizeof(msg));
-               spi_message_init(&msg);
-               msg.spi = spi;
-               msg.is_dma_mapped = USE_SPI_DMA;
-               spi_message_add_tail(&tr, &msg);
-
-               ret = spi_sync(spi, &msg);
-               if (ret < 0)
-                       dev_err(&spi->dev, "SPI transaction failed\n");
-
-               kfree(r_buffer);
-       } else {
-               dev_err(&spi->dev,
-                       "can't write data with the following length: %d\n",
-                       len);
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int ret;
-
-       if (rlen > 0) {
-               struct spi_message msg;
-               struct spi_transfer tr = {
-                       .rx_buf = rb,
-                       .len = rlen,
-                       .delay = {
-                               .value = 0,
-                               .unit = SPI_DELAY_UNIT_USECS
-                       },
-
-               };
-               char *t_buffer = kzalloc(rlen, GFP_KERNEL);
-
-               if (!t_buffer)
-                       return -ENOMEM;
-
-               tr.tx_buf = t_buffer;
-
-               memset(&msg, 0, sizeof(msg));
-               spi_message_init(&msg);
-               msg.spi = spi;
-               msg.is_dma_mapped = USE_SPI_DMA;
-               spi_message_add_tail(&tr, &msg);
-
-               ret = spi_sync(spi, &msg);
-               if (ret < 0)
-                       dev_err(&spi->dev, "SPI transaction failed\n");
-               kfree(t_buffer);
-       } else {
-               dev_err(&spi->dev,
-                       "can't read data with the following length: %u\n",
-                       rlen);
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int ret;
-
-       if (rlen > 0) {
-               struct spi_message msg;
-               struct spi_transfer tr = {
-                       .rx_buf = rb,
-                       .tx_buf = wb,
-                       .len = rlen,
-                       .bits_per_word = 8,
-                       .delay = {
-                               .value = 0,
-                               .unit = SPI_DELAY_UNIT_USECS
-                       },
-
-               };
-
-               memset(&msg, 0, sizeof(msg));
-               spi_message_init(&msg);
-               msg.spi = spi;
-               msg.is_dma_mapped = USE_SPI_DMA;
-
-               spi_message_add_tail(&tr, &msg);
-               ret = spi_sync(spi, &msg);
-               if (ret < 0)
-                       dev_err(&spi->dev, "SPI transaction failed\n");
-       } else {
-               dev_err(&spi->dev,
-                       "can't read data with the following length: %u\n",
-                       rlen);
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       struct wilc_spi *spi_priv = wilc->bus_data;
-       int ix, nbytes;
-       int result = 0;
-       u8 cmd, order, crc[2] = {0};
-
-       /*
-        * Data
-        */
-       ix = 0;
-       do {
-               if (sz <= DATA_PKT_SZ) {
-                       nbytes = sz;
-                       order = 0x3;
-               } else {
-                       nbytes = DATA_PKT_SZ;
-                       if (ix == 0)
-                               order = 0x1;
-                       else
-                               order = 0x02;
-               }
-
-               /*
-                * Write command
-                */
-               cmd = 0xf0;
-               cmd |= order;
-
-               if (wilc_spi_tx(wilc, &cmd, 1)) {
-                       dev_err(&spi->dev,
-                               "Failed data block cmd write, bus error...\n");
-                       result = -EINVAL;
-                       break;
-               }
-
-               /*
-                * Write data
-                */
-               if (wilc_spi_tx(wilc, &b[ix], nbytes)) {
-                       dev_err(&spi->dev,
-                               "Failed data block write, bus error...\n");
-                       result = -EINVAL;
-                       break;
-               }
-
-               /*
-                * Write Crc
-                */
-               if (!spi_priv->crc_off) {
-                       if (wilc_spi_tx(wilc, crc, 2)) {
-                               dev_err(&spi->dev, "Failed data block crc write, bus error...\n");
-                               result = -EINVAL;
-                               break;
-                       }
-               }
-
-               /*
-                * No need to wait for response
-                */
-               ix += nbytes;
-               sz -= nbytes;
-       } while (sz);
-
-       return result;
-}
-
-/********************************************
- *
- *      Spi Internal Read/Write Function
- *
- ********************************************/
-static u8 wilc_get_crc7(u8 *buffer, u32 len)
-{
-       return crc7_be(0xfe, buffer, len);
-}
-
-static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
-                               u8 clockless)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       struct wilc_spi *spi_priv = wilc->bus_data;
-       u8 wb[32], rb[32];
-       int cmd_len, resp_len;
-       u8 crc[2];
-       struct wilc_spi_cmd *c;
-       struct wilc_spi_read_rsp_data *r;
-
-       memset(wb, 0x0, sizeof(wb));
-       memset(rb, 0x0, sizeof(rb));
-       c = (struct wilc_spi_cmd *)wb;
-       c->cmd_type = cmd;
-       if (cmd == CMD_SINGLE_READ) {
-               c->u.simple_cmd.addr[0] = adr >> 16;
-               c->u.simple_cmd.addr[1] = adr >> 8;
-               c->u.simple_cmd.addr[2] = adr;
-       } else if (cmd == CMD_INTERNAL_READ) {
-               c->u.simple_cmd.addr[0] = adr >> 8;
-               if (clockless == 1)
-                       c->u.simple_cmd.addr[0] |= BIT(7);
-               c->u.simple_cmd.addr[1] = adr;
-               c->u.simple_cmd.addr[2] = 0x0;
-       } else {
-               dev_err(&spi->dev, "cmd [%x] not supported\n", cmd);
-               return -EINVAL;
-       }
-
-       cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);
-       resp_len = sizeof(*r);
-       if (!spi_priv->crc_off) {
-               c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
-               cmd_len += 1;
-               resp_len += 2;
-       }
-
-       if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
-               dev_err(&spi->dev,
-                       "spi buffer size too small (%d) (%d) (%zu)\n",
-                       cmd_len, resp_len, ARRAY_SIZE(wb));
-               return -EINVAL;
-       }
-
-       if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
-               dev_err(&spi->dev, "Failed cmd write, bus error...\n");
-               return -EINVAL;
-       }
-
-       r = (struct wilc_spi_read_rsp_data *)&rb[cmd_len];
-       if (r->rsp_cmd_type != cmd) {
-               dev_err(&spi->dev,
-                       "Failed cmd response, cmd (%02x), resp (%02x)\n",
-                       cmd, r->rsp_cmd_type);
-               return -EINVAL;
-       }
-
-       if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
-               dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
-                       r->status);
-               return -EINVAL;
-       }
-
-       if (WILC_GET_RESP_HDR_START(r->resp_header) != 0xf) {
-               dev_err(&spi->dev, "Error, data read response (%02x)\n",
-                       r->resp_header);
-               return -EINVAL;
-       }
-
-       if (b)
-               memcpy(b, r->resp_data, 4);
-
-       if (!spi_priv->crc_off)
-               memcpy(crc, r->crc, 2);
-
-       return 0;
-}
-
-static int wilc_spi_write_cmd(struct wilc *wilc, u8 cmd, u32 adr, u32 data,
-                             u8 clockless)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       struct wilc_spi *spi_priv = wilc->bus_data;
-       u8 wb[32], rb[32];
-       int cmd_len, resp_len;
-       struct wilc_spi_cmd *c;
-       struct wilc_spi_rsp_data *r;
-
-       memset(wb, 0x0, sizeof(wb));
-       memset(rb, 0x0, sizeof(rb));
-       c = (struct wilc_spi_cmd *)wb;
-       c->cmd_type = cmd;
-       if (cmd == CMD_INTERNAL_WRITE) {
-               c->u.internal_w_cmd.addr[0] = adr >> 8;
-               if (clockless == 1)
-                       c->u.internal_w_cmd.addr[0] |= BIT(7);
-
-               c->u.internal_w_cmd.addr[1] = adr;
-               c->u.internal_w_cmd.data = cpu_to_be32(data);
-               cmd_len = offsetof(struct wilc_spi_cmd, u.internal_w_cmd.crc);
-               if (!spi_priv->crc_off)
-                       c->u.internal_w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
-       } else if (cmd == CMD_SINGLE_WRITE) {
-               c->u.w_cmd.addr[0] = adr >> 16;
-               c->u.w_cmd.addr[1] = adr >> 8;
-               c->u.w_cmd.addr[2] = adr;
-               c->u.w_cmd.data = cpu_to_be32(data);
-               cmd_len = offsetof(struct wilc_spi_cmd, u.w_cmd.crc);
-               if (!spi_priv->crc_off)
-                       c->u.w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
-       } else {
-               dev_err(&spi->dev, "write cmd [%x] not supported\n", cmd);
-               return -EINVAL;
-       }
-
-       if (!spi_priv->crc_off)
-               cmd_len += 1;
-
-       resp_len = sizeof(*r);
-
-       if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
-               dev_err(&spi->dev,
-                       "spi buffer size too small (%d) (%d) (%zu)\n",
-                       cmd_len, resp_len, ARRAY_SIZE(wb));
-               return -EINVAL;
-       }
-
-       if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
-               dev_err(&spi->dev, "Failed cmd write, bus error...\n");
-               return -EINVAL;
-       }
-
-       r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
-       if (r->rsp_cmd_type != cmd) {
-               dev_err(&spi->dev,
-                       "Failed cmd response, cmd (%02x), resp (%02x)\n",
-                       cmd, r->rsp_cmd_type);
-               return -EINVAL;
-       }
-
-       if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
-               dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
-                       r->status);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int wilc_spi_dma_rw(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       struct wilc_spi *spi_priv = wilc->bus_data;
-       u8 wb[32], rb[32];
-       int cmd_len, resp_len;
-       int retry, ix = 0;
-       u8 crc[2];
-       struct wilc_spi_cmd *c;
-       struct wilc_spi_rsp_data *r;
-
-       memset(wb, 0x0, sizeof(wb));
-       memset(rb, 0x0, sizeof(rb));
-       c = (struct wilc_spi_cmd *)wb;
-       c->cmd_type = cmd;
-       if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_READ) {
-               c->u.dma_cmd.addr[0] = adr >> 16;
-               c->u.dma_cmd.addr[1] = adr >> 8;
-               c->u.dma_cmd.addr[2] = adr;
-               c->u.dma_cmd.size[0] = sz >> 8;
-               c->u.dma_cmd.size[1] = sz;
-               cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd.crc);
-               if (!spi_priv->crc_off)
-                       c->u.dma_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
-       } else if (cmd == CMD_DMA_EXT_WRITE || cmd == CMD_DMA_EXT_READ) {
-               c->u.dma_cmd_ext.addr[0] = adr >> 16;
-               c->u.dma_cmd_ext.addr[1] = adr >> 8;
-               c->u.dma_cmd_ext.addr[2] = adr;
-               c->u.dma_cmd_ext.size[0] = sz >> 16;
-               c->u.dma_cmd_ext.size[1] = sz >> 8;
-               c->u.dma_cmd_ext.size[2] = sz;
-               cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd_ext.crc);
-               if (!spi_priv->crc_off)
-                       c->u.dma_cmd_ext.crc[0] = wilc_get_crc7(wb, cmd_len);
-       } else {
-               dev_err(&spi->dev, "dma read write cmd [%x] not supported\n",
-                       cmd);
-               return -EINVAL;
-       }
-       if (!spi_priv->crc_off)
-               cmd_len += 1;
-
-       resp_len = sizeof(*r);
-
-       if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
-               dev_err(&spi->dev, "spi buffer size too small (%d)(%d) (%zu)\n",
-                       cmd_len, resp_len, ARRAY_SIZE(wb));
-               return -EINVAL;
-       }
-
-       if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
-               dev_err(&spi->dev, "Failed cmd write, bus error...\n");
-               return -EINVAL;
-       }
-
-       r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
-       if (r->rsp_cmd_type != cmd) {
-               dev_err(&spi->dev,
-                       "Failed cmd response, cmd (%02x), resp (%02x)\n",
-                       cmd, r->rsp_cmd_type);
-               return -EINVAL;
-       }
-
-       if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
-               dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
-                       r->status);
-               return -EINVAL;
-       }
-
-       if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_EXT_WRITE)
-               return 0;
-
-       while (sz > 0) {
-               int nbytes;
-               u8 rsp;
-
-               if (sz <= DATA_PKT_SZ)
-                       nbytes = sz;
-               else
-                       nbytes = DATA_PKT_SZ;
-
-               /*
-                * Data Response header
-                */
-               retry = 100;
-               do {
-                       if (wilc_spi_rx(wilc, &rsp, 1)) {
-                               dev_err(&spi->dev,
-                                       "Failed resp read, bus err\n");
-                               return -EINVAL;
-                       }
-                       if (WILC_GET_RESP_HDR_START(rsp) == 0xf)
-                               break;
-               } while (retry--);
-
-               /*
-                * Read bytes
-                */
-               if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
-                       dev_err(&spi->dev,
-                               "Failed block read, bus err\n");
-                       return -EINVAL;
-               }
-
-               /*
-                * Read Crc
-                */
-               if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) {
-                       dev_err(&spi->dev,
-                               "Failed block crc read, bus err\n");
-                       return -EINVAL;
-               }
-
-               ix += nbytes;
-               sz -= nbytes;
-       }
-       return 0;
-}
-
-static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int result;
-       u8 cmd = CMD_SINGLE_READ;
-       u8 clockless = 0;
-
-       if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) {
-               /* Clockless register */
-               cmd = CMD_INTERNAL_READ;
-               clockless = 1;
-       }
-
-       result = wilc_spi_single_read(wilc, cmd, addr, data, clockless);
-       if (result) {
-               dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr);
-               return result;
-       }
-
-       le32_to_cpus(data);
-
-       return 0;
-}
-
-static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int result;
-
-       if (size <= 4)
-               return -EINVAL;
-
-       result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_READ, addr, buf, size);
-       if (result) {
-               dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr);
-               return result;
-       }
-
-       return 0;
-}
-
-static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int result;
-
-       result = wilc_spi_write_cmd(wilc, CMD_INTERNAL_WRITE, adr, dat, 0);
-       if (result) {
-               dev_err(&spi->dev, "Failed internal write cmd...\n");
-               return result;
-       }
-
-       return 0;
-}
-
-static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int result;
-
-       result = wilc_spi_single_read(wilc, CMD_INTERNAL_READ, adr, data, 0);
-       if (result) {
-               dev_err(&spi->dev, "Failed internal read cmd...\n");
-               return result;
-       }
-
-       le32_to_cpus(data);
-
-       return 0;
-}
-
-/********************************************
- *
- *      Spi interfaces
- *
- ********************************************/
-
-static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int result;
-       u8 cmd = CMD_SINGLE_WRITE;
-       u8 clockless = 0;
-
-       if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) {
-               /* Clockless register */
-               cmd = CMD_INTERNAL_WRITE;
-               clockless = 1;
-       }
-
-       result = wilc_spi_write_cmd(wilc, cmd, addr, data, clockless);
-       if (result) {
-               dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr);
-               return result;
-       }
-
-       return 0;
-}
-
-static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       int result;
-
-       /*
-        * has to be greated than 4
-        */
-       if (size <= 4)
-               return -EINVAL;
-
-       result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_WRITE, addr, NULL, size);
-       if (result) {
-               dev_err(&spi->dev,
-                       "Failed cmd, write block (%08x)...\n", addr);
-               return result;
-       }
-
-       /*
-        * Data
-        */
-       result = spi_data_write(wilc, buf, size);
-       if (result) {
-               dev_err(&spi->dev, "Failed block data write...\n");
-               return result;
-       }
-
-       return 0;
-}
-
-/********************************************
- *
- *      Bus interfaces
- *
- ********************************************/
-
-static int wilc_spi_deinit(struct wilc *wilc)
-{
-       /*
-        * TODO:
-        */
-       return 0;
-}
-
-static int wilc_spi_init(struct wilc *wilc, bool resume)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       struct wilc_spi *spi_priv = wilc->bus_data;
-       u32 reg;
-       u32 chipid;
-       static int isinit;
-       int ret;
-
-       if (isinit) {
-               ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
-               if (ret)
-                       dev_err(&spi->dev, "Fail cmd read chip id...\n");
-
-               return ret;
-       }
-
-       /*
-        * configure protocol
-        */
-
-       /*
-        * TODO: We can remove the CRC trials if there is a definite
-        * way to reset
-        */
-       /* the SPI to it's initial value. */
-       ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg);
-       if (ret) {
-               /*
-                * Read failed. Try with CRC off. This might happen when module
-                * is removed but chip isn't reset
-                */
-               spi_priv->crc_off = 1;
-               dev_err(&spi->dev,
-                       "Failed read with CRC on, retrying with CRC off\n");
-               ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg);
-               if (ret) {
-                       /*
-                        * Read failed with both CRC on and off,
-                        * something went bad
-                        */
-                       dev_err(&spi->dev, "Failed internal read protocol\n");
-                       return ret;
-               }
-       }
-       if (spi_priv->crc_off == 0) {
-               reg &= ~0xc; /* disable crc checking */
-               reg &= ~0x70;
-               reg |= (0x5 << 4);
-               ret = spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg);
-               if (ret) {
-                       dev_err(&spi->dev,
-                               "[wilc spi %d]: Failed internal write reg\n",
-                               __LINE__);
-                       return ret;
-               }
-               spi_priv->crc_off = 1;
-       }
-
-       /*
-        * make sure can read back chip id correctly
-        */
-       ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
-       if (ret) {
-               dev_err(&spi->dev, "Fail cmd read chip id...\n");
-               return ret;
-       }
-
-       isinit = 1;
-
-       return 0;
-}
-
-static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
-{
-       int ret;
-
-       ret = spi_internal_read(wilc,
-                               WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE, size);
-       *size = FIELD_GET(IRQ_DMA_WD_CNT_MASK, *size);
-
-       return ret;
-}
-
-static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
-{
-       return spi_internal_read(wilc, WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE,
-                                int_status);
-}
-
-static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
-{
-       return spi_internal_write(wilc, WILC_SPI_INT_CLEAR - WILC_SPI_REG_BASE,
-                                 val);
-}
-
-static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
-{
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       u32 reg;
-       int ret, i;
-
-       if (nint > MAX_NUM_INT) {
-               dev_err(&spi->dev, "Too many interrupts (%d)...\n", nint);
-               return -EINVAL;
-       }
-
-       /*
-        * interrupt pin mux select
-        */
-       ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, &reg);
-       if (ret) {
-               dev_err(&spi->dev, "Failed read reg (%08x)...\n",
-                       WILC_PIN_MUX_0);
-               return ret;
-       }
-       reg |= BIT(8);
-       ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg);
-       if (ret) {
-               dev_err(&spi->dev, "Failed write reg (%08x)...\n",
-                       WILC_PIN_MUX_0);
-               return ret;
-       }
-
-       /*
-        * interrupt enable
-        */
-       ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, &reg);
-       if (ret) {
-               dev_err(&spi->dev, "Failed read reg (%08x)...\n",
-                       WILC_INTR_ENABLE);
-               return ret;
-       }
-
-       for (i = 0; (i < 5) && (nint > 0); i++, nint--)
-               reg |= (BIT((27 + i)));
-
-       ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg);
-       if (ret) {
-               dev_err(&spi->dev, "Failed write reg (%08x)...\n",
-                       WILC_INTR_ENABLE);
-               return ret;
-       }
-       if (nint) {
-               ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
-               if (ret) {
-                       dev_err(&spi->dev, "Failed read reg (%08x)...\n",
-                               WILC_INTR2_ENABLE);
-                       return ret;
-               }
-
-               for (i = 0; (i < 3) && (nint > 0); i++, nint--)
-                       reg |= BIT(i);
-
-               ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
-               if (ret) {
-                       dev_err(&spi->dev, "Failed write reg (%08x)...\n",
-                               WILC_INTR2_ENABLE);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-/* Global spi HIF function table */
-static const struct wilc_hif_func wilc_hif_spi = {
-       .hif_init = wilc_spi_init,
-       .hif_deinit = wilc_spi_deinit,
-       .hif_read_reg = wilc_spi_read_reg,
-       .hif_write_reg = wilc_spi_write_reg,
-       .hif_block_rx = wilc_spi_read,
-       .hif_block_tx = wilc_spi_write,
-       .hif_read_int = wilc_spi_read_int,
-       .hif_clear_int_ext = wilc_spi_clear_int_ext,
-       .hif_read_size = wilc_spi_read_size,
-       .hif_block_tx_ext = wilc_spi_write,
-       .hif_block_rx_ext = wilc_spi_read,
-       .hif_sync_ext = wilc_spi_sync_ext,
-};
diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/staging/wilc1000/wlan.c
deleted file mode 100644 (file)
index 6a82fb2..0000000
+++ /dev/null
@@ -1,1238 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#include <linux/if_ether.h>
-#include <linux/ip.h>
-#include "cfg80211.h"
-#include "wlan_cfg.h"
-
-static inline bool is_wilc1000(u32 id)
-{
-       return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
-}
-
-static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
-{
-       mutex_lock(&wilc->hif_cs);
-       if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP)
-               chip_wakeup(wilc);
-}
-
-static inline void release_bus(struct wilc *wilc, enum bus_release release)
-{
-       if (release == WILC_BUS_RELEASE_ALLOW_SLEEP)
-               chip_allow_sleep(wilc);
-       mutex_unlock(&wilc->hif_cs);
-}
-
-static void wilc_wlan_txq_remove(struct wilc *wilc, struct txq_entry_t *tqe)
-{
-       list_del(&tqe->list);
-       wilc->txq_entries -= 1;
-}
-
-static struct txq_entry_t *
-wilc_wlan_txq_remove_from_head(struct net_device *dev)
-{
-       struct txq_entry_t *tqe = NULL;
-       unsigned long flags;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-
-       spin_lock_irqsave(&wilc->txq_spinlock, flags);
-
-       if (!list_empty(&wilc->txq_head.list)) {
-               tqe = list_first_entry(&wilc->txq_head.list, struct txq_entry_t,
-                                      list);
-               list_del(&tqe->list);
-               wilc->txq_entries -= 1;
-       }
-       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
-       return tqe;
-}
-
-static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
-                                     struct txq_entry_t *tqe)
-{
-       unsigned long flags;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-
-       spin_lock_irqsave(&wilc->txq_spinlock, flags);
-
-       list_add_tail(&tqe->list, &wilc->txq_head.list);
-       wilc->txq_entries += 1;
-
-       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
-
-       complete(&wilc->txq_event);
-}
-
-static void wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
-                                     struct txq_entry_t *tqe)
-{
-       unsigned long flags;
-       struct wilc *wilc = vif->wilc;
-
-       mutex_lock(&wilc->txq_add_to_head_cs);
-
-       spin_lock_irqsave(&wilc->txq_spinlock, flags);
-
-       list_add(&tqe->list, &wilc->txq_head.list);
-       wilc->txq_entries += 1;
-
-       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
-       mutex_unlock(&wilc->txq_add_to_head_cs);
-       complete(&wilc->txq_event);
-}
-
-#define NOT_TCP_ACK                    (-1)
-
-static inline void add_tcp_session(struct wilc_vif *vif, u32 src_prt,
-                                  u32 dst_prt, u32 seq)
-{
-       struct tcp_ack_filter *f = &vif->ack_filter;
-
-       if (f->tcp_session < 2 * MAX_TCP_SESSION) {
-               f->ack_session_info[f->tcp_session].seq_num = seq;
-               f->ack_session_info[f->tcp_session].bigger_ack_num = 0;
-               f->ack_session_info[f->tcp_session].src_port = src_prt;
-               f->ack_session_info[f->tcp_session].dst_port = dst_prt;
-               f->tcp_session++;
-       }
-}
-
-static inline void update_tcp_session(struct wilc_vif *vif, u32 index, u32 ack)
-{
-       struct tcp_ack_filter *f = &vif->ack_filter;
-
-       if (index < 2 * MAX_TCP_SESSION &&
-           ack > f->ack_session_info[index].bigger_ack_num)
-               f->ack_session_info[index].bigger_ack_num = ack;
-}
-
-static inline void add_tcp_pending_ack(struct wilc_vif *vif, u32 ack,
-                                      u32 session_index,
-                                      struct txq_entry_t *txqe)
-{
-       struct tcp_ack_filter *f = &vif->ack_filter;
-       u32 i = f->pending_base + f->pending_acks_idx;
-
-       if (i < MAX_PENDING_ACKS) {
-               f->pending_acks[i].ack_num = ack;
-               f->pending_acks[i].txqe = txqe;
-               f->pending_acks[i].session_index = session_index;
-               txqe->ack_idx = i;
-               f->pending_acks_idx++;
-       }
-}
-
-static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
-{
-       void *buffer = tqe->buffer;
-       const struct ethhdr *eth_hdr_ptr = buffer;
-       int i;
-       unsigned long flags;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-       struct tcp_ack_filter *f = &vif->ack_filter;
-       const struct iphdr *ip_hdr_ptr;
-       const struct tcphdr *tcp_hdr_ptr;
-       u32 ihl, total_length, data_offset;
-
-       spin_lock_irqsave(&wilc->txq_spinlock, flags);
-
-       if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
-               goto out;
-
-       ip_hdr_ptr = buffer + ETH_HLEN;
-
-       if (ip_hdr_ptr->protocol != IPPROTO_TCP)
-               goto out;
-
-       ihl = ip_hdr_ptr->ihl << 2;
-       tcp_hdr_ptr = buffer + ETH_HLEN + ihl;
-       total_length = ntohs(ip_hdr_ptr->tot_len);
-
-       data_offset = tcp_hdr_ptr->doff << 2;
-       if (total_length == (ihl + data_offset)) {
-               u32 seq_no, ack_no;
-
-               seq_no = ntohl(tcp_hdr_ptr->seq);
-               ack_no = ntohl(tcp_hdr_ptr->ack_seq);
-               for (i = 0; i < f->tcp_session; i++) {
-                       u32 j = f->ack_session_info[i].seq_num;
-
-                       if (i < 2 * MAX_TCP_SESSION &&
-                           j == seq_no) {
-                               update_tcp_session(vif, i, ack_no);
-                               break;
-                       }
-               }
-               if (i == f->tcp_session)
-                       add_tcp_session(vif, 0, 0, seq_no);
-
-               add_tcp_pending_ack(vif, ack_no, i, tqe);
-       }
-
-out:
-       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
-}
-
-static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
-{
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-       struct tcp_ack_filter *f = &vif->ack_filter;
-       u32 i = 0;
-       u32 dropped = 0;
-       unsigned long flags;
-
-       spin_lock_irqsave(&wilc->txq_spinlock, flags);
-       for (i = f->pending_base;
-            i < (f->pending_base + f->pending_acks_idx); i++) {
-               u32 index;
-               u32 bigger_ack_num;
-
-               if (i >= MAX_PENDING_ACKS)
-                       break;
-
-               index = f->pending_acks[i].session_index;
-
-               if (index >= 2 * MAX_TCP_SESSION)
-                       break;
-
-               bigger_ack_num = f->ack_session_info[index].bigger_ack_num;
-
-               if (f->pending_acks[i].ack_num < bigger_ack_num) {
-                       struct txq_entry_t *tqe;
-
-                       tqe = f->pending_acks[i].txqe;
-                       if (tqe) {
-                               wilc_wlan_txq_remove(wilc, tqe);
-                               tqe->status = 1;
-                               if (tqe->tx_complete_func)
-                                       tqe->tx_complete_func(tqe->priv,
-                                                             tqe->status);
-                               kfree(tqe);
-                               dropped++;
-                       }
-               }
-       }
-       f->pending_acks_idx = 0;
-       f->tcp_session = 0;
-
-       if (f->pending_base == 0)
-               f->pending_base = MAX_TCP_SESSION;
-       else
-               f->pending_base = 0;
-
-       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
-
-       while (dropped > 0) {
-               wait_for_completion_timeout(&wilc->txq_event,
-                                           msecs_to_jiffies(1));
-               dropped--;
-       }
-}
-
-void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
-{
-       vif->ack_filter.enabled = value;
-}
-
-static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
-                                    u32 buffer_size)
-{
-       struct txq_entry_t *tqe;
-       struct wilc *wilc = vif->wilc;
-
-       netdev_dbg(vif->ndev, "Adding config packet ...\n");
-       if (wilc->quit) {
-               netdev_dbg(vif->ndev, "Return due to clear function\n");
-               complete(&wilc->cfg_event);
-               return 0;
-       }
-
-       tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
-       if (!tqe)
-               return 0;
-
-       tqe->type = WILC_CFG_PKT;
-       tqe->buffer = buffer;
-       tqe->buffer_size = buffer_size;
-       tqe->tx_complete_func = NULL;
-       tqe->priv = NULL;
-       tqe->ack_idx = NOT_TCP_ACK;
-       tqe->vif = vif;
-
-       wilc_wlan_txq_add_to_head(vif, tqe);
-
-       return 1;
-}
-
-int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
-                             u32 buffer_size,
-                             void (*tx_complete_fn)(void *, int))
-{
-       struct txq_entry_t *tqe;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc;
-
-       wilc = vif->wilc;
-
-       if (wilc->quit)
-               return 0;
-
-       tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
-
-       if (!tqe)
-               return 0;
-       tqe->type = WILC_NET_PKT;
-       tqe->buffer = buffer;
-       tqe->buffer_size = buffer_size;
-       tqe->tx_complete_func = tx_complete_fn;
-       tqe->priv = priv;
-       tqe->vif = vif;
-
-       tqe->ack_idx = NOT_TCP_ACK;
-       if (vif->ack_filter.enabled)
-               tcp_process(dev, tqe);
-       wilc_wlan_txq_add_to_tail(dev, tqe);
-       return wilc->txq_entries;
-}
-
-int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
-                              u32 buffer_size,
-                              void (*tx_complete_fn)(void *, int))
-{
-       struct txq_entry_t *tqe;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc;
-
-       wilc = vif->wilc;
-
-       if (wilc->quit)
-               return 0;
-
-       tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
-
-       if (!tqe)
-               return 0;
-       tqe->type = WILC_MGMT_PKT;
-       tqe->buffer = buffer;
-       tqe->buffer_size = buffer_size;
-       tqe->tx_complete_func = tx_complete_fn;
-       tqe->priv = priv;
-       tqe->ack_idx = NOT_TCP_ACK;
-       tqe->vif = vif;
-       wilc_wlan_txq_add_to_tail(dev, tqe);
-       return 1;
-}
-
-static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc)
-{
-       struct txq_entry_t *tqe = NULL;
-       unsigned long flags;
-
-       spin_lock_irqsave(&wilc->txq_spinlock, flags);
-
-       if (!list_empty(&wilc->txq_head.list))
-               tqe = list_first_entry(&wilc->txq_head.list, struct txq_entry_t,
-                                      list);
-
-       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
-
-       return tqe;
-}
-
-static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
-                                                 struct txq_entry_t *tqe)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&wilc->txq_spinlock, flags);
-
-       if (!list_is_last(&tqe->list, &wilc->txq_head.list))
-               tqe = list_next_entry(tqe, list);
-       else
-               tqe = NULL;
-       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
-
-       return tqe;
-}
-
-static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
-{
-       if (wilc->quit)
-               return;
-
-       mutex_lock(&wilc->rxq_cs);
-       list_add_tail(&rqe->list, &wilc->rxq_head.list);
-       mutex_unlock(&wilc->rxq_cs);
-}
-
-static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
-{
-       struct rxq_entry_t *rqe = NULL;
-
-       mutex_lock(&wilc->rxq_cs);
-       if (!list_empty(&wilc->rxq_head.list)) {
-               rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t,
-                                      list);
-               list_del(&rqe->list);
-       }
-       mutex_unlock(&wilc->rxq_cs);
-       return rqe;
-}
-
-void chip_allow_sleep(struct wilc *wilc)
-{
-       u32 reg = 0;
-
-       wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
-
-       wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
-                                     reg & ~WILC_SDIO_WAKEUP_BIT);
-       wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0);
-}
-EXPORT_SYMBOL_GPL(chip_allow_sleep);
-
-void chip_wakeup(struct wilc *wilc)
-{
-       u32 reg, clk_status_reg;
-       const struct wilc_hif_func *h = wilc->hif_func;
-
-       if (wilc->io_type == WILC_HIF_SPI) {
-               do {
-                       h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, &reg);
-                       h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
-                                        reg | WILC_SPI_WAKEUP_BIT);
-                       h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
-                                        reg & ~WILC_SPI_WAKEUP_BIT);
-
-                       do {
-                               usleep_range(2000, 2500);
-                               wilc_get_chipid(wilc, true);
-                       } while (wilc_get_chipid(wilc, true) == 0);
-               } while (wilc_get_chipid(wilc, true) == 0);
-       } else if (wilc->io_type == WILC_HIF_SDIO) {
-               h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG,
-                                WILC_SDIO_HOST_TO_FW_BIT);
-               usleep_range(200, 400);
-               h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
-               do {
-                       h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
-                                        reg | WILC_SDIO_WAKEUP_BIT);
-                       h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
-                                       &clk_status_reg);
-
-                       while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
-                               usleep_range(2000, 2500);
-
-                               h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
-                                               &clk_status_reg);
-                       }
-                       if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
-                               h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
-                                                reg & ~WILC_SDIO_WAKEUP_BIT);
-                       }
-               } while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT));
-       }
-
-       if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) {
-               if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) {
-                       u32 val32;
-
-                       h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32);
-                       val32 |= BIT(6);
-                       h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32);
-
-                       h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32);
-                       val32 |= BIT(6);
-                       h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32);
-               }
-       }
-       wilc->chip_ps_state = WILC_CHIP_WAKEDUP;
-}
-EXPORT_SYMBOL_GPL(chip_wakeup);
-
-void host_wakeup_notify(struct wilc *wilc)
-{
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
-       wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
-       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-}
-EXPORT_SYMBOL_GPL(host_wakeup_notify);
-
-void host_sleep_notify(struct wilc *wilc)
-{
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
-       wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
-       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-}
-EXPORT_SYMBOL_GPL(host_sleep_notify);
-
-int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
-{
-       int i, entries = 0;
-       u32 sum;
-       u32 reg;
-       u32 offset = 0;
-       int vmm_sz = 0;
-       struct txq_entry_t *tqe;
-       int ret = 0;
-       int counter;
-       int timeout;
-       u32 vmm_table[WILC_VMM_TBL_SIZE];
-       const struct wilc_hif_func *func;
-       u8 *txb = wilc->tx_buffer;
-       struct net_device *dev;
-       struct wilc_vif *vif;
-
-       if (wilc->quit)
-               goto out_update_cnt;
-
-       mutex_lock(&wilc->txq_add_to_head_cs);
-       tqe = wilc_wlan_txq_get_first(wilc);
-       if (!tqe)
-               goto out_unlock;
-       dev = tqe->vif->ndev;
-       wilc_wlan_txq_filter_dup_tcp_ack(dev);
-       i = 0;
-       sum = 0;
-       while (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) {
-               if (tqe->type == WILC_CFG_PKT)
-                       vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
-               else if (tqe->type == WILC_NET_PKT)
-                       vmm_sz = ETH_ETHERNET_HDR_OFFSET;
-               else
-                       vmm_sz = HOST_HDR_OFFSET;
-
-               vmm_sz += tqe->buffer_size;
-               vmm_sz = ALIGN(vmm_sz, 4);
-
-               if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE)
-                       break;
-
-               vmm_table[i] = vmm_sz / 4;
-               if (tqe->type == WILC_CFG_PKT)
-                       vmm_table[i] |= BIT(10);
-               cpu_to_le32s(&vmm_table[i]);
-
-               i++;
-               sum += vmm_sz;
-               tqe = wilc_wlan_txq_get_next(wilc, tqe);
-       }
-
-       if (i == 0)
-               goto out_unlock;
-       vmm_table[i] = 0x0;
-
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
-       counter = 0;
-       func = wilc->hif_func;
-       do {
-               ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
-               if (ret)
-                       break;
-
-               if ((reg & 0x1) == 0)
-                       break;
-
-               counter++;
-               if (counter > 200) {
-                       counter = 0;
-                       ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
-                       break;
-               }
-       } while (!wilc->quit);
-
-       if (ret)
-               goto out_release_bus;
-
-       timeout = 200;
-       do {
-               ret = func->hif_block_tx(wilc,
-                                        WILC_VMM_TBL_RX_SHADOW_BASE,
-                                        (u8 *)vmm_table,
-                                        ((i + 1) * 4));
-               if (ret)
-                       break;
-
-               ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
-               if (ret)
-                       break;
-
-               do {
-                       ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
-                       if (ret)
-                               break;
-                       if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
-                               entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
-                               break;
-                       }
-               } while (--timeout);
-               if (timeout <= 0) {
-                       ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
-                       break;
-               }
-
-               if (ret)
-                       break;
-
-               if (entries == 0) {
-                       ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
-                       if (ret)
-                               break;
-                       reg &= ~BIT(0);
-                       ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
-               }
-       } while (0);
-
-       if (ret)
-               goto out_release_bus;
-
-       if (entries == 0) {
-               /*
-                * No VMM space available in firmware so retry to transmit
-                * the packet from tx queue.
-                */
-               ret = WILC_VMM_ENTRY_FULL_RETRY;
-               goto out_release_bus;
-       }
-
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-
-       offset = 0;
-       i = 0;
-       do {
-               u32 header, buffer_offset;
-               char *bssid;
-               u8 mgmt_ptk = 0;
-
-               tqe = wilc_wlan_txq_remove_from_head(dev);
-               if (!tqe)
-                       break;
-
-               vif = tqe->vif;
-               if (vmm_table[i] == 0)
-                       break;
-
-               le32_to_cpus(&vmm_table[i]);
-               vmm_sz = FIELD_GET(WILC_VMM_BUFFER_SIZE, vmm_table[i]);
-               vmm_sz *= 4;
-
-               if (tqe->type == WILC_MGMT_PKT)
-                       mgmt_ptk = 1;
-
-               header = (FIELD_PREP(WILC_VMM_HDR_TYPE, tqe->type) |
-                         FIELD_PREP(WILC_VMM_HDR_MGMT_FIELD, mgmt_ptk) |
-                         FIELD_PREP(WILC_VMM_HDR_PKT_SIZE, tqe->buffer_size) |
-                         FIELD_PREP(WILC_VMM_HDR_BUFF_SIZE, vmm_sz));
-
-               cpu_to_le32s(&header);
-               memcpy(&txb[offset], &header, 4);
-               if (tqe->type == WILC_CFG_PKT) {
-                       buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
-               } else if (tqe->type == WILC_NET_PKT) {
-                       bssid = tqe->vif->bssid;
-                       buffer_offset = ETH_ETHERNET_HDR_OFFSET;
-                       memcpy(&txb[offset + 8], bssid, 6);
-               } else {
-                       buffer_offset = HOST_HDR_OFFSET;
-               }
-
-               memcpy(&txb[offset + buffer_offset],
-                      tqe->buffer, tqe->buffer_size);
-               offset += vmm_sz;
-               i++;
-               tqe->status = 1;
-               if (tqe->tx_complete_func)
-                       tqe->tx_complete_func(tqe->priv, tqe->status);
-               if (tqe->ack_idx != NOT_TCP_ACK &&
-                   tqe->ack_idx < MAX_PENDING_ACKS)
-                       vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL;
-               kfree(tqe);
-       } while (--entries);
-
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
-
-       ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
-       if (ret)
-               goto out_release_bus;
-
-       ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
-
-out_release_bus:
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-
-out_unlock:
-       mutex_unlock(&wilc->txq_add_to_head_cs);
-
-out_update_cnt:
-       *txq_count = wilc->txq_entries;
-       return ret;
-}
-
-static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
-{
-       int offset = 0;
-       u32 header;
-       u32 pkt_len, pkt_offset, tp_len;
-       int is_cfg_packet;
-       u8 *buff_ptr;
-
-       do {
-               buff_ptr = buffer + offset;
-               header = get_unaligned_le32(buff_ptr);
-
-               is_cfg_packet = FIELD_GET(WILC_PKT_HDR_CONFIG_FIELD, header);
-               pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
-               tp_len = FIELD_GET(WILC_PKT_HDR_TOTAL_LEN_FIELD, header);
-               pkt_len = FIELD_GET(WILC_PKT_HDR_LEN_FIELD, header);
-
-               if (pkt_len == 0 || tp_len == 0)
-                       break;
-
-               if (pkt_offset & IS_MANAGMEMENT) {
-                       buff_ptr += HOST_HDR_OFFSET;
-                       wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len);
-               } else {
-                       if (!is_cfg_packet) {
-                               wilc_frmw_to_host(wilc, buff_ptr, pkt_len,
-                                                 pkt_offset);
-                       } else {
-                               struct wilc_cfg_rsp rsp;
-
-                               buff_ptr += pkt_offset;
-
-                               wilc_wlan_cfg_indicate_rx(wilc, buff_ptr,
-                                                         pkt_len,
-                                                         &rsp);
-                               if (rsp.type == WILC_CFG_RSP) {
-                                       if (wilc->cfg_seq_no == rsp.seq_no)
-                                               complete(&wilc->cfg_event);
-                               } else if (rsp.type == WILC_CFG_RSP_STATUS) {
-                                       wilc_mac_indicate(wilc);
-                               }
-                       }
-               }
-               offset += tp_len;
-       } while (offset < size);
-}
-
-static void wilc_wlan_handle_rxq(struct wilc *wilc)
-{
-       int size;
-       u8 *buffer;
-       struct rxq_entry_t *rqe;
-
-       while (!wilc->quit) {
-               rqe = wilc_wlan_rxq_remove(wilc);
-               if (!rqe)
-                       break;
-
-               buffer = rqe->buffer;
-               size = rqe->buffer_size;
-               wilc_wlan_handle_rx_buff(wilc, buffer, size);
-
-               kfree(rqe);
-       }
-       if (wilc->quit)
-               complete(&wilc->cfg_event);
-}
-
-static void wilc_unknown_isr_ext(struct wilc *wilc)
-{
-       wilc->hif_func->hif_clear_int_ext(wilc, 0);
-}
-
-static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
-{
-       u32 offset = wilc->rx_buffer_offset;
-       u8 *buffer = NULL;
-       u32 size;
-       u32 retries = 0;
-       int ret = 0;
-       struct rxq_entry_t *rqe;
-
-       size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, int_status) << 2;
-
-       while (!size && retries < 10) {
-               wilc->hif_func->hif_read_size(wilc, &size);
-               size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, size) << 2;
-               retries++;
-       }
-
-       if (size <= 0)
-               return;
-
-       if (WILC_RX_BUFF_SIZE - offset < size)
-               offset = 0;
-
-       buffer = &wilc->rx_buffer[offset];
-
-       wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM);
-       ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
-       if (ret)
-               return;
-
-       offset += size;
-       wilc->rx_buffer_offset = offset;
-       rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
-       if (!rqe)
-               return;
-
-       rqe->buffer = buffer;
-       rqe->buffer_size = size;
-       wilc_wlan_rxq_add(wilc, rqe);
-       wilc_wlan_handle_rxq(wilc);
-}
-
-void wilc_handle_isr(struct wilc *wilc)
-{
-       u32 int_status;
-
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
-       wilc->hif_func->hif_read_int(wilc, &int_status);
-
-       if (int_status & DATA_INT_EXT)
-               wilc_wlan_handle_isr_ext(wilc, int_status);
-
-       if (!(int_status & (ALL_INT_EXT)))
-               wilc_unknown_isr_ext(wilc);
-
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-}
-EXPORT_SYMBOL_GPL(wilc_handle_isr);
-
-int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
-                               u32 buffer_size)
-{
-       u32 offset;
-       u32 addr, size, size2, blksz;
-       u8 *dma_buffer;
-       int ret = 0;
-
-       blksz = BIT(12);
-
-       dma_buffer = kmalloc(blksz, GFP_KERNEL);
-       if (!dma_buffer)
-               return -EIO;
-
-       offset = 0;
-       do {
-               addr = get_unaligned_le32(&buffer[offset]);
-               size = get_unaligned_le32(&buffer[offset + 4]);
-               acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
-               offset += 8;
-               while (((int)size) && (offset < buffer_size)) {
-                       if (size <= blksz)
-                               size2 = size;
-                       else
-                               size2 = blksz;
-
-                       memcpy(dma_buffer, &buffer[offset], size2);
-                       ret = wilc->hif_func->hif_block_tx(wilc, addr,
-                                                          dma_buffer, size2);
-                       if (ret)
-                               break;
-
-                       addr += size2;
-                       offset += size2;
-                       size -= size2;
-               }
-               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-
-               if (ret)
-                       goto fail;
-       } while (offset < buffer_size);
-
-fail:
-
-       kfree(dma_buffer);
-
-       return ret;
-}
-
-int wilc_wlan_start(struct wilc *wilc)
-{
-       u32 reg = 0;
-       int ret;
-       u32 chipid;
-
-       if (wilc->io_type == WILC_HIF_SDIO) {
-               reg = 0;
-               reg |= BIT(3);
-       } else if (wilc->io_type == WILC_HIF_SPI) {
-               reg = 1;
-       }
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
-       ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
-       if (ret) {
-               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-               return ret;
-       }
-       reg = 0;
-       if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
-               reg |= WILC_HAVE_SDIO_IRQ_GPIO;
-
-       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
-       if (ret) {
-               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-               return ret;
-       }
-
-       wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
-
-       ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
-       if (ret) {
-               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-               return ret;
-       }
-
-       wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
-       if ((reg & BIT(10)) == BIT(10)) {
-               reg &= ~BIT(10);
-               wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
-               wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
-       }
-
-       reg |= BIT(10);
-       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
-       wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
-       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-
-       return ret;
-}
-
-int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
-{
-       u32 reg = 0;
-       int ret;
-
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
-
-       ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
-       if (ret) {
-               netdev_err(vif->ndev, "Error while reading reg\n");
-               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-               return ret;
-       }
-
-       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
-                                       (reg | WILC_ABORT_REQ_BIT));
-       if (ret) {
-               netdev_err(vif->ndev, "Error while writing reg\n");
-               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-               return ret;
-       }
-
-       ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, &reg);
-       if (ret) {
-               netdev_err(vif->ndev, "Error while reading reg\n");
-               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-               return ret;
-       }
-       reg = BIT(0);
-
-       ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg);
-       if (ret) {
-               netdev_err(vif->ndev, "Error while writing reg\n");
-               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-               return ret;
-       }
-
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-
-       return 0;
-}
-
-void wilc_wlan_cleanup(struct net_device *dev)
-{
-       struct txq_entry_t *tqe;
-       struct rxq_entry_t *rqe;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-
-       wilc->quit = 1;
-       while ((tqe = wilc_wlan_txq_remove_from_head(dev))) {
-               if (tqe->tx_complete_func)
-                       tqe->tx_complete_func(tqe->priv, 0);
-               kfree(tqe);
-       }
-
-       while ((rqe = wilc_wlan_rxq_remove(wilc)))
-               kfree(rqe);
-
-       kfree(wilc->rx_buffer);
-       wilc->rx_buffer = NULL;
-       kfree(wilc->tx_buffer);
-       wilc->tx_buffer = NULL;
-       wilc->hif_func->hif_deinit(NULL);
-}
-
-static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
-                               u32 drv_handler)
-{
-       struct wilc *wilc = vif->wilc;
-       struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
-       int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr);
-
-       if (type == WILC_CFG_SET)
-               cfg->hdr.cmd_type = 'W';
-       else
-               cfg->hdr.cmd_type = 'Q';
-
-       cfg->hdr.seq_no = wilc->cfg_seq_no % 256;
-       cfg->hdr.total_len = cpu_to_le16(t_len);
-       cfg->hdr.driver_handler = cpu_to_le32(drv_handler);
-       wilc->cfg_seq_no = cfg->hdr.seq_no;
-
-       if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len))
-               return -1;
-
-       return 0;
-}
-
-int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
-                     u32 buffer_size, int commit, u32 drv_handler)
-{
-       u32 offset;
-       int ret_size;
-       struct wilc *wilc = vif->wilc;
-
-       mutex_lock(&wilc->cfg_cmd_lock);
-
-       if (start)
-               wilc->cfg_frame_offset = 0;
-
-       offset = wilc->cfg_frame_offset;
-       ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
-                                        wid, buffer, buffer_size);
-       offset += ret_size;
-       wilc->cfg_frame_offset = offset;
-
-       if (!commit) {
-               mutex_unlock(&wilc->cfg_cmd_lock);
-               return ret_size;
-       }
-
-       netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no);
-
-       if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
-               ret_size = 0;
-
-       if (!wait_for_completion_timeout(&wilc->cfg_event,
-                                        WILC_CFG_PKTS_TIMEOUT)) {
-               netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
-               ret_size = 0;
-       }
-
-       wilc->cfg_frame_offset = 0;
-       wilc->cfg_seq_no += 1;
-       mutex_unlock(&wilc->cfg_cmd_lock);
-
-       return ret_size;
-}
-
-int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
-                     u32 drv_handler)
-{
-       u32 offset;
-       int ret_size;
-       struct wilc *wilc = vif->wilc;
-
-       mutex_lock(&wilc->cfg_cmd_lock);
-
-       if (start)
-               wilc->cfg_frame_offset = 0;
-
-       offset = wilc->cfg_frame_offset;
-       ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid);
-       offset += ret_size;
-       wilc->cfg_frame_offset = offset;
-
-       if (!commit) {
-               mutex_unlock(&wilc->cfg_cmd_lock);
-               return ret_size;
-       }
-
-       if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
-               ret_size = 0;
-
-       if (!wait_for_completion_timeout(&wilc->cfg_event,
-                                        WILC_CFG_PKTS_TIMEOUT)) {
-               netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
-               ret_size = 0;
-       }
-       wilc->cfg_frame_offset = 0;
-       wilc->cfg_seq_no += 1;
-       mutex_unlock(&wilc->cfg_cmd_lock);
-
-       return ret_size;
-}
-
-int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
-                        u32 count)
-{
-       int i;
-       int ret = 0;
-       u32 drv = wilc_get_vif_idx(vif);
-
-       if (mode == WILC_GET_CFG) {
-               for (i = 0; i < count; i++) {
-                       if (!wilc_wlan_cfg_get(vif, !i,
-                                              wids[i].id,
-                                              (i == count - 1),
-                                              drv)) {
-                               ret = -ETIMEDOUT;
-                               break;
-                       }
-               }
-               for (i = 0; i < count; i++) {
-                       wids[i].size = wilc_wlan_cfg_get_val(vif->wilc,
-                                                            wids[i].id,
-                                                            wids[i].val,
-                                                            wids[i].size);
-               }
-       } else if (mode == WILC_SET_CFG) {
-               for (i = 0; i < count; i++) {
-                       if (!wilc_wlan_cfg_set(vif, !i,
-                                              wids[i].id,
-                                              wids[i].val,
-                                              wids[i].size,
-                                              (i == count - 1),
-                                              drv)) {
-                               ret = -ETIMEDOUT;
-                               break;
-                       }
-               }
-       }
-
-       return ret;
-}
-
-static int init_chip(struct net_device *dev)
-{
-       u32 chipid;
-       u32 reg;
-       int ret = 0;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc = vif->wilc;
-
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
-
-       chipid = wilc_get_chipid(wilc, true);
-
-       if ((chipid & 0xfff) != 0xa0) {
-               ret = wilc->hif_func->hif_read_reg(wilc,
-                                                  WILC_CORTUS_RESET_MUX_SEL,
-                                                  &reg);
-               if (ret) {
-                       netdev_err(dev, "fail read reg 0x1118\n");
-                       goto release;
-               }
-               reg |= BIT(0);
-               ret = wilc->hif_func->hif_write_reg(wilc,
-                                                   WILC_CORTUS_RESET_MUX_SEL,
-                                                   reg);
-               if (ret) {
-                       netdev_err(dev, "fail write reg 0x1118\n");
-                       goto release;
-               }
-               ret = wilc->hif_func->hif_write_reg(wilc,
-                                                   WILC_CORTUS_BOOT_REGISTER,
-                                                   WILC_CORTUS_BOOT_FROM_IRAM);
-               if (ret) {
-                       netdev_err(dev, "fail write reg 0xc0000\n");
-                       goto release;
-               }
-       }
-
-release:
-       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-
-       return ret;
-}
-
-u32 wilc_get_chipid(struct wilc *wilc, bool update)
-{
-       static u32 chipid;
-       u32 tempchipid = 0;
-       u32 rfrevid = 0;
-
-       if (chipid == 0 || update) {
-               wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &tempchipid);
-               wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
-                                            &rfrevid);
-               if (!is_wilc1000(tempchipid)) {
-                       chipid = 0;
-                       return chipid;
-               }
-               if (tempchipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
-                       if (rfrevid != 0x1)
-                               tempchipid = WILC_1000_BASE_ID_2A_REV1;
-               } else if (tempchipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
-                       if (rfrevid == 0x4)
-                               tempchipid = WILC_1000_BASE_ID_2B_REV1;
-                       else if (rfrevid != 0x3)
-                               tempchipid = WILC_1000_BASE_ID_2B_REV2;
-               }
-
-               chipid = tempchipid;
-       }
-       return chipid;
-}
-
-int wilc_wlan_init(struct net_device *dev)
-{
-       int ret = 0;
-       struct wilc_vif *vif = netdev_priv(dev);
-       struct wilc *wilc;
-
-       wilc = vif->wilc;
-
-       wilc->quit = 0;
-
-       if (wilc->hif_func->hif_init(wilc, false)) {
-               ret = -EIO;
-               goto fail;
-       }
-
-       if (!wilc->tx_buffer)
-               wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL);
-
-       if (!wilc->tx_buffer) {
-               ret = -ENOBUFS;
-               goto fail;
-       }
-
-       if (!wilc->rx_buffer)
-               wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL);
-
-       if (!wilc->rx_buffer) {
-               ret = -ENOBUFS;
-               goto fail;
-       }
-
-       if (init_chip(dev)) {
-               ret = -EIO;
-               goto fail;
-       }
-
-       return 0;
-
-fail:
-
-       kfree(wilc->rx_buffer);
-       wilc->rx_buffer = NULL;
-       kfree(wilc->tx_buffer);
-       wilc->tx_buffer = NULL;
-
-       return ret;
-}
diff --git a/drivers/staging/wilc1000/wlan.h b/drivers/staging/wilc1000/wlan.h
deleted file mode 100644 (file)
index 7689569..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#ifndef WILC_WLAN_H
-#define WILC_WLAN_H
-
-#include <linux/types.h>
-#include <linux/bitfield.h>
-
-/********************************************
- *
- *      Mac eth header length
- *
- ********************************************/
-#define MAX_MAC_HDR_LEN                        26 /* QOS_MAC_HDR_LEN */
-#define SUB_MSDU_HEADER_LENGTH         14
-#define SNAP_HDR_LEN                   8
-#define ETHERNET_HDR_LEN               14
-#define WORD_ALIGNMENT_PAD             0
-
-#define ETH_ETHERNET_HDR_OFFSET                (MAX_MAC_HDR_LEN + \
-                                        SUB_MSDU_HEADER_LENGTH + \
-                                        SNAP_HDR_LEN - \
-                                        ETHERNET_HDR_LEN + \
-                                        WORD_ALIGNMENT_PAD)
-
-#define HOST_HDR_OFFSET                        4
-#define ETHERNET_HDR_LEN               14
-#define IP_HDR_LEN                     20
-#define IP_HDR_OFFSET                  ETHERNET_HDR_LEN
-#define UDP_HDR_OFFSET                 (IP_HDR_LEN + IP_HDR_OFFSET)
-#define UDP_HDR_LEN                    8
-#define UDP_DATA_OFFSET                        (UDP_HDR_OFFSET + UDP_HDR_LEN)
-#define ETH_CONFIG_PKT_HDR_LEN         UDP_DATA_OFFSET
-
-#define ETH_CONFIG_PKT_HDR_OFFSET      (ETH_ETHERNET_HDR_OFFSET + \
-                                        ETH_CONFIG_PKT_HDR_LEN)
-
-/********************************************
- *
- *      Register Defines
- *
- ********************************************/
-#define WILC_PERIPH_REG_BASE           0x1000
-#define WILC_CHANGING_VIR_IF           0x108c
-#define WILC_CHIPID                    WILC_PERIPH_REG_BASE
-#define WILC_GLB_RESET_0               (WILC_PERIPH_REG_BASE + 0x400)
-#define WILC_PIN_MUX_0                 (WILC_PERIPH_REG_BASE + 0x408)
-#define WILC_HOST_TX_CTRL              (WILC_PERIPH_REG_BASE + 0x6c)
-#define WILC_HOST_RX_CTRL_0            (WILC_PERIPH_REG_BASE + 0x70)
-#define WILC_HOST_RX_CTRL_1            (WILC_PERIPH_REG_BASE + 0x74)
-#define WILC_HOST_VMM_CTL              (WILC_PERIPH_REG_BASE + 0x78)
-#define WILC_HOST_RX_CTRL              (WILC_PERIPH_REG_BASE + 0x80)
-#define WILC_HOST_RX_EXTRA_SIZE                (WILC_PERIPH_REG_BASE + 0x84)
-#define WILC_HOST_TX_CTRL_1            (WILC_PERIPH_REG_BASE + 0x88)
-#define WILC_MISC                      (WILC_PERIPH_REG_BASE + 0x428)
-#define WILC_INTR_REG_BASE             (WILC_PERIPH_REG_BASE + 0xa00)
-#define WILC_INTR_ENABLE               WILC_INTR_REG_BASE
-#define WILC_INTR2_ENABLE              (WILC_INTR_REG_BASE + 4)
-
-#define WILC_INTR_POLARITY             (WILC_INTR_REG_BASE + 0x10)
-#define WILC_INTR_TYPE                 (WILC_INTR_REG_BASE + 0x20)
-#define WILC_INTR_CLEAR                        (WILC_INTR_REG_BASE + 0x30)
-#define WILC_INTR_STATUS               (WILC_INTR_REG_BASE + 0x40)
-
-#define WILC_RF_REVISION_ID            0x13f4
-
-#define WILC_VMM_TBL_SIZE              64
-#define WILC_VMM_TX_TBL_BASE           0x150400
-#define WILC_VMM_RX_TBL_BASE           0x150500
-
-#define WILC_VMM_BASE                  0x150000
-#define WILC_VMM_CORE_CTL              WILC_VMM_BASE
-#define WILC_VMM_TBL_CTL               (WILC_VMM_BASE + 0x4)
-#define WILC_VMM_TBL_ENTRY             (WILC_VMM_BASE + 0x8)
-#define WILC_VMM_TBL0_SIZE             (WILC_VMM_BASE + 0xc)
-#define WILC_VMM_TO_HOST_SIZE          (WILC_VMM_BASE + 0x10)
-#define WILC_VMM_CORE_CFG              (WILC_VMM_BASE + 0x14)
-#define WILC_VMM_TBL_ACTIVE            (WILC_VMM_BASE + 040)
-#define WILC_VMM_TBL_STATUS            (WILC_VMM_BASE + 0x44)
-
-#define WILC_SPI_REG_BASE              0xe800
-#define WILC_SPI_CTL                   WILC_SPI_REG_BASE
-#define WILC_SPI_MASTER_DMA_ADDR       (WILC_SPI_REG_BASE + 0x4)
-#define WILC_SPI_MASTER_DMA_COUNT      (WILC_SPI_REG_BASE + 0x8)
-#define WILC_SPI_SLAVE_DMA_ADDR                (WILC_SPI_REG_BASE + 0xc)
-#define WILC_SPI_SLAVE_DMA_COUNT       (WILC_SPI_REG_BASE + 0x10)
-#define WILC_SPI_TX_MODE               (WILC_SPI_REG_BASE + 0x20)
-#define WILC_SPI_PROTOCOL_CONFIG       (WILC_SPI_REG_BASE + 0x24)
-#define WILC_SPI_INTR_CTL              (WILC_SPI_REG_BASE + 0x2c)
-#define WILC_SPI_INT_STATUS            (WILC_SPI_REG_BASE + 0x40)
-#define WILC_SPI_INT_CLEAR             (WILC_SPI_REG_BASE + 0x44)
-
-#define WILC_SPI_WAKEUP_REG            0x1
-#define WILC_SPI_WAKEUP_BIT            BIT(1)
-
-#define WILC_SPI_PROTOCOL_OFFSET       (WILC_SPI_PROTOCOL_CONFIG - \
-                                        WILC_SPI_REG_BASE)
-
-#define WILC_SPI_CLOCKLESS_ADDR_LIMIT  0x30
-
-/* Functions IO enables bits */
-#define WILC_SDIO_CCCR_IO_EN_FUNC1     BIT(1)
-
-/* Function/Interrupt enables bits */
-#define WILC_SDIO_CCCR_IEN_MASTER      BIT(0)
-#define WILC_SDIO_CCCR_IEN_FUNC1       BIT(1)
-
-/* Abort CCCR register bits */
-#define WILC_SDIO_CCCR_ABORT_RESET     BIT(3)
-
-/* Vendor specific CCCR registers */
-#define WILC_SDIO_WAKEUP_REG           0xf0
-#define WILC_SDIO_WAKEUP_BIT           BIT(0)
-
-#define WILC_SDIO_CLK_STATUS_REG       0xf1
-#define WILC_SDIO_CLK_STATUS_BIT       BIT(0)
-
-#define WILC_SDIO_INTERRUPT_DATA_SZ_REG        0xf2 /* Read size (2 bytes) */
-
-#define WILC_SDIO_VMM_TBL_CTRL_REG     0xf6
-#define WILC_SDIO_IRQ_FLAG_REG         0xf7
-#define WILC_SDIO_IRQ_CLEAR_FLAG_REG   0xf8
-
-#define WILC_SDIO_HOST_TO_FW_REG       0xfa
-#define WILC_SDIO_HOST_TO_FW_BIT       BIT(0)
-
-#define WILC_SDIO_FW_TO_HOST_REG       0xfc
-#define WILC_SDIO_FW_TO_HOST_BIT       BIT(0)
-
-/* Function 1 specific FBR register */
-#define WILC_SDIO_FBR_CSA_REG          0x10C /* CSA pointer (3 bytes) */
-#define WILC_SDIO_FBR_DATA_REG         0x10F
-
-#define WILC_SDIO_F1_DATA_REG          0x0
-#define WILC_SDIO_EXT_IRQ_FLAG_REG     0x4
-
-#define WILC_AHB_DATA_MEM_BASE         0x30000
-#define WILC_AHB_SHARE_MEM_BASE                0xd0000
-
-#define WILC_VMM_TBL_RX_SHADOW_BASE    WILC_AHB_SHARE_MEM_BASE
-#define WILC_VMM_TBL_RX_SHADOW_SIZE    256
-
-#define WILC_FW_HOST_COMM              0x13c0
-#define WILC_GP_REG_0                  0x149c
-#define WILC_GP_REG_1                  0x14a0
-
-#define WILC_HAVE_SDIO_IRQ_GPIO                BIT(0)
-#define WILC_HAVE_USE_PMU              BIT(1)
-#define WILC_HAVE_SLEEP_CLK_SRC_RTC    BIT(2)
-#define WILC_HAVE_SLEEP_CLK_SRC_XO     BIT(3)
-#define WILC_HAVE_EXT_PA_INV_TX_RX     BIT(4)
-#define WILC_HAVE_LEGACY_RF_SETTINGS   BIT(5)
-#define WILC_HAVE_XTAL_24              BIT(6)
-#define WILC_HAVE_DISABLE_WILC_UART    BIT(7)
-#define WILC_HAVE_USE_IRQ_AS_HOST_WAKE BIT(8)
-
-#define WILC_CORTUS_INTERRUPT_BASE     0x10A8
-#define WILC_CORTUS_INTERRUPT_1                (WILC_CORTUS_INTERRUPT_BASE + 0x4)
-#define WILC_CORTUS_INTERRUPT_2                (WILC_CORTUS_INTERRUPT_BASE + 0x8)
-
-/* tx control register 1 to 4 for RX */
-#define WILC_REG_4_TO_1_RX             0x1e1c
-
-/* tx control register 1 to 4 for TX Bank_0 */
-#define WILC_REG_4_TO_1_TX_BANK0       0x1e9c
-
-#define WILC_CORTUS_RESET_MUX_SEL      0x1118
-#define WILC_CORTUS_BOOT_REGISTER      0xc0000
-
-#define WILC_CORTUS_BOOT_FROM_IRAM     0x71
-
-#define WILC_1000_BASE_ID              0x100000
-
-#define WILC_1000_BASE_ID_2A           0x1002A0
-#define WILC_1000_BASE_ID_2A_REV1      (WILC_1000_BASE_ID_2A + 1)
-
-#define WILC_1000_BASE_ID_2B           0x1002B0
-#define WILC_1000_BASE_ID_2B_REV1      (WILC_1000_BASE_ID_2B + 1)
-#define WILC_1000_BASE_ID_2B_REV2      (WILC_1000_BASE_ID_2B + 2)
-
-#define WILC_CHIP_REV_FIELD            GENMASK(11, 0)
-
-/********************************************
- *
- *      Wlan Defines
- *
- ********************************************/
-#define WILC_CFG_PKT           1
-#define WILC_NET_PKT           0
-#define WILC_MGMT_PKT          2
-
-#define WILC_CFG_SET           1
-#define WILC_CFG_QUERY         0
-
-#define WILC_CFG_RSP           1
-#define WILC_CFG_RSP_STATUS    2
-#define WILC_CFG_RSP_SCAN      3
-
-#define WILC_ABORT_REQ_BIT             BIT(31)
-
-#define WILC_RX_BUFF_SIZE      (96 * 1024)
-#define WILC_TX_BUFF_SIZE      (64 * 1024)
-
-#define MODALIAS               "WILC_SPI"
-
-#define WILC_PKT_HDR_CONFIG_FIELD      BIT(31)
-#define WILC_PKT_HDR_OFFSET_FIELD      GENMASK(30, 22)
-#define WILC_PKT_HDR_TOTAL_LEN_FIELD   GENMASK(21, 11)
-#define WILC_PKT_HDR_LEN_FIELD         GENMASK(10, 0)
-
-#define WILC_INTERRUPT_DATA_SIZE       GENMASK(14, 0)
-
-#define WILC_VMM_BUFFER_SIZE           GENMASK(9, 0)
-
-#define WILC_VMM_HDR_TYPE              BIT(31)
-#define WILC_VMM_HDR_MGMT_FIELD                BIT(30)
-#define WILC_VMM_HDR_PKT_SIZE          GENMASK(29, 15)
-#define WILC_VMM_HDR_BUFF_SIZE         GENMASK(14, 0)
-
-#define WILC_VMM_ENTRY_COUNT           GENMASK(8, 3)
-#define WILC_VMM_ENTRY_AVAILABLE       BIT(2)
-/*******************************************/
-/*        E0 and later Interrupt flags.    */
-/*******************************************/
-/*******************************************/
-/*        E0 and later Interrupt flags.    */
-/*           IRQ Status word               */
-/* 15:0 = DMA count in words.              */
-/* 16: INT0 flag                           */
-/* 17: INT1 flag                           */
-/* 18: INT2 flag                           */
-/* 19: INT3 flag                           */
-/* 20: INT4 flag                           */
-/* 21: INT5 flag                           */
-/*******************************************/
-#define IRG_FLAGS_OFFSET       16
-#define IRQ_DMA_WD_CNT_MASK    GENMASK(IRG_FLAGS_OFFSET - 1, 0)
-#define INT_0                  BIT(IRG_FLAGS_OFFSET)
-#define INT_1                  BIT(IRG_FLAGS_OFFSET + 1)
-#define INT_2                  BIT(IRG_FLAGS_OFFSET + 2)
-#define INT_3                  BIT(IRG_FLAGS_OFFSET + 3)
-#define INT_4                  BIT(IRG_FLAGS_OFFSET + 4)
-#define INT_5                  BIT(IRG_FLAGS_OFFSET + 5)
-#define MAX_NUM_INT            5
-#define IRG_FLAGS_MASK         GENMASK(IRG_FLAGS_OFFSET + MAX_NUM_INT, \
-                                       IRG_FLAGS_OFFSET)
-
-/*******************************************/
-/*        E0 and later Interrupt flags.    */
-/*           IRQ Clear word                */
-/* 0: Clear INT0                           */
-/* 1: Clear INT1                           */
-/* 2: Clear INT2                           */
-/* 3: Clear INT3                           */
-/* 4: Clear INT4                           */
-/* 5: Clear INT5                           */
-/* 6: Select VMM table 1                   */
-/* 7: Select VMM table 2                   */
-/* 8: Enable VMM                           */
-/*******************************************/
-#define CLR_INT0               BIT(0)
-#define CLR_INT1               BIT(1)
-#define CLR_INT2               BIT(2)
-#define CLR_INT3               BIT(3)
-#define CLR_INT4               BIT(4)
-#define CLR_INT5               BIT(5)
-#define SEL_VMM_TBL0           BIT(6)
-#define SEL_VMM_TBL1           BIT(7)
-#define EN_VMM                 BIT(8)
-
-#define DATA_INT_EXT           INT_0
-#define ALL_INT_EXT            DATA_INT_EXT
-#define NUM_INT_EXT            1
-#define UNHANDLED_IRQ_MASK     GENMASK(MAX_NUM_INT - 1, NUM_INT_EXT)
-
-#define DATA_INT_CLR           CLR_INT0
-
-#define ENABLE_RX_VMM          (SEL_VMM_TBL1 | EN_VMM)
-#define ENABLE_TX_VMM          (SEL_VMM_TBL0 | EN_VMM)
-/* time for expiring the completion of cfg packets */
-#define WILC_CFG_PKTS_TIMEOUT  msecs_to_jiffies(2000)
-
-#define IS_MANAGMEMENT         0x100
-#define IS_MANAGMEMENT_CALLBACK        0x080
-#define IS_MGMT_STATUS_SUCCES  0x040
-
-#define WILC_WID_TYPE          GENMASK(15, 12)
-#define WILC_VMM_ENTRY_FULL_RETRY      1
-/********************************************
- *
- *      Tx/Rx Queue Structure
- *
- ********************************************/
-
-struct txq_entry_t {
-       struct list_head list;
-       int type;
-       int ack_idx;
-       u8 *buffer;
-       int buffer_size;
-       void *priv;
-       int status;
-       struct wilc_vif *vif;
-       void (*tx_complete_func)(void *priv, int status);
-};
-
-struct rxq_entry_t {
-       struct list_head list;
-       u8 *buffer;
-       int buffer_size;
-};
-
-/********************************************
- *
- *      Host IF Structure
- *
- ********************************************/
-struct wilc;
-struct wilc_hif_func {
-       int (*hif_init)(struct wilc *wilc, bool resume);
-       int (*hif_deinit)(struct wilc *wilc);
-       int (*hif_read_reg)(struct wilc *wilc, u32 addr, u32 *data);
-       int (*hif_write_reg)(struct wilc *wilc, u32 addr, u32 data);
-       int (*hif_block_rx)(struct wilc *wilc, u32 addr, u8 *buf, u32 size);
-       int (*hif_block_tx)(struct wilc *wilc, u32 addr, u8 *buf, u32 size);
-       int (*hif_read_int)(struct wilc *wilc, u32 *int_status);
-       int (*hif_clear_int_ext)(struct wilc *wilc, u32 val);
-       int (*hif_read_size)(struct wilc *wilc, u32 *size);
-       int (*hif_block_tx_ext)(struct wilc *wilc, u32 addr, u8 *buf, u32 size);
-       int (*hif_block_rx_ext)(struct wilc *wilc, u32 addr, u8 *buf, u32 size);
-       int (*hif_sync_ext)(struct wilc *wilc, int nint);
-       int (*enable_interrupt)(struct wilc *nic);
-       void (*disable_interrupt)(struct wilc *nic);
-};
-
-#define WILC_MAX_CFG_FRAME_SIZE                1468
-
-struct tx_complete_data {
-       int size;
-       void *buff;
-       struct sk_buff *skb;
-};
-
-struct wilc_cfg_cmd_hdr {
-       u8 cmd_type;
-       u8 seq_no;
-       __le16 total_len;
-       __le32 driver_handler;
-};
-
-struct wilc_cfg_frame {
-       struct wilc_cfg_cmd_hdr hdr;
-       u8 frame[WILC_MAX_CFG_FRAME_SIZE];
-};
-
-struct wilc_cfg_rsp {
-       u8 type;
-       u8 seq_no;
-};
-
-struct wilc;
-struct wilc_vif;
-
-int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
-                               u32 buffer_size);
-int wilc_wlan_start(struct wilc *wilc);
-int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif);
-int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
-                             u32 buffer_size,
-                             void (*tx_complete_fn)(void *, int));
-int wilc_wlan_handle_txq(struct wilc *wl, u32 *txq_count);
-void wilc_handle_isr(struct wilc *wilc);
-void wilc_wlan_cleanup(struct net_device *dev);
-int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
-                     u32 buffer_size, int commit, u32 drv_handler);
-int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
-                     u32 drv_handler);
-int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
-                              u32 buffer_size, void (*func)(void *, int));
-void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value);
-int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc);
-netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
-
-void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size);
-void host_wakeup_notify(struct wilc *wilc);
-void host_sleep_notify(struct wilc *wilc);
-void chip_allow_sleep(struct wilc *wilc);
-void chip_wakeup(struct wilc *wilc);
-int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
-                        u32 count);
-int wilc_wlan_init(struct net_device *dev);
-u32 wilc_get_chipid(struct wilc *wilc, bool update);
-#endif
diff --git a/drivers/staging/wilc1000/wlan_cfg.c b/drivers/staging/wilc1000/wlan_cfg.c
deleted file mode 100644 (file)
index fe2a7ed..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#include <linux/bitfield.h>
-#include "wlan_if.h"
-#include "wlan.h"
-#include "wlan_cfg.h"
-#include "netdev.h"
-
-enum cfg_cmd_type {
-       CFG_BYTE_CMD    = 0,
-       CFG_HWORD_CMD   = 1,
-       CFG_WORD_CMD    = 2,
-       CFG_STR_CMD     = 3,
-       CFG_BIN_CMD     = 4
-};
-
-static const struct wilc_cfg_byte g_cfg_byte[] = {
-       {WID_STATUS, 0},
-       {WID_RSSI, 0},
-       {WID_LINKSPEED, 0},
-       {WID_NIL, 0}
-};
-
-static const struct wilc_cfg_hword g_cfg_hword[] = {
-       {WID_NIL, 0}
-};
-
-static const struct wilc_cfg_word g_cfg_word[] = {
-       {WID_FAILED_COUNT, 0},
-       {WID_RECEIVED_FRAGMENT_COUNT, 0},
-       {WID_SUCCESS_FRAME_COUNT, 0},
-       {WID_GET_INACTIVE_TIME, 0},
-       {WID_NIL, 0}
-
-};
-
-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 WILC_RESP_MSG_TYPE_CONFIG_REPLY                'R'
-#define WILC_RESP_MSG_TYPE_STATUS_INFO         'I'
-#define WILC_RESP_MSG_TYPE_NETWORK_INFO                'N'
-#define WILC_RESP_MSG_TYPE_SCAN_COMPLETE       'S'
-
-/********************************************
- *
- *      Configuration Functions
- *
- ********************************************/
-
-static int wilc_wlan_cfg_set_byte(u8 *frame, u32 offset, u16 id, u8 val8)
-{
-       if ((offset + 4) >= WILC_MAX_CFG_FRAME_SIZE)
-               return 0;
-
-       put_unaligned_le16(id, &frame[offset]);
-       put_unaligned_le16(1, &frame[offset + 2]);
-       frame[offset + 4] = val8;
-       return 5;
-}
-
-static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, u16 id, u16 val16)
-{
-       if ((offset + 5) >= WILC_MAX_CFG_FRAME_SIZE)
-               return 0;
-
-       put_unaligned_le16(id, &frame[offset]);
-       put_unaligned_le16(2, &frame[offset + 2]);
-       put_unaligned_le16(val16, &frame[offset + 4]);
-
-       return 6;
-}
-
-static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32)
-{
-       if ((offset + 7) >= WILC_MAX_CFG_FRAME_SIZE)
-               return 0;
-
-       put_unaligned_le16(id, &frame[offset]);
-       put_unaligned_le16(4, &frame[offset + 2]);
-       put_unaligned_le32(val32, &frame[offset + 4]);
-
-       return 8;
-}
-
-static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str,
-                                u32 size)
-{
-       if ((offset + size + 4) >= WILC_MAX_CFG_FRAME_SIZE)
-               return 0;
-
-       put_unaligned_le16(id, &frame[offset]);
-       put_unaligned_le16(size, &frame[offset + 2]);
-       if (str && size != 0)
-               memcpy(&frame[offset + 4], str, size);
-
-       return (size + 4);
-}
-
-static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size)
-{
-       u32 i;
-       u8 checksum = 0;
-
-       if ((offset + size + 5) >= WILC_MAX_CFG_FRAME_SIZE)
-               return 0;
-
-       put_unaligned_le16(id, &frame[offset]);
-       put_unaligned_le16(size, &frame[offset + 2]);
-
-       if ((b) && size != 0) {
-               memcpy(&frame[offset + 4], b, size);
-               for (i = 0; i < size; i++)
-                       checksum += frame[offset + i + 4];
-       }
-
-       frame[offset + size + 4] = checksum;
-
-       return (size + 5);
-}
-
-/********************************************
- *
- *      Configuration Response Functions
- *
- ********************************************/
-
-static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
-{
-       u16 wid;
-       u32 len = 0, i = 0;
-       struct wilc_cfg *cfg = &wl->cfg;
-
-       while (size > 0) {
-               i = 0;
-               wid = get_unaligned_le16(info);
-
-               switch (FIELD_GET(WILC_WID_TYPE, wid)) {
-               case WID_CHAR:
-                       while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
-                               i++;
-
-                       if (cfg->b[i].id == wid)
-                               cfg->b[i].val = info[4];
-
-                       len = 3;
-                       break;
-
-               case WID_SHORT:
-                       while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
-                               i++;
-
-                       if (cfg->hw[i].id == wid)
-                               cfg->hw[i].val = get_unaligned_le16(&info[4]);
-
-                       len = 4;
-                       break;
-
-               case WID_INT:
-                       while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
-                               i++;
-
-                       if (cfg->w[i].id == wid)
-                               cfg->w[i].val = get_unaligned_le32(&info[4]);
-
-                       len = 6;
-                       break;
-
-               case WID_STR:
-                       while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
-                               i++;
-
-                       if (cfg->s[i].id == wid)
-                               memcpy(cfg->s[i].str, &info[2], info[2] + 2);
-
-                       len = 2 + info[2];
-                       break;
-
-               default:
-                       break;
-               }
-               size -= (2 + len);
-               info += (2 + len);
-       }
-}
-
-static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info)
-{
-       u32 wid, len;
-
-       wid = get_unaligned_le16(info);
-
-       len = info[2];
-
-       if (len == 1 && wid == WID_STATUS) {
-               int i = 0;
-
-               while (wl->cfg.b[i].id != WID_NIL &&
-                      wl->cfg.b[i].id != wid)
-                       i++;
-
-               if (wl->cfg.b[i].id == wid)
-                       wl->cfg.b[i].val = info[3];
-       }
-}
-
-/********************************************
- *
- *      Configuration Exported Functions
- *
- ********************************************/
-
-int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size)
-{
-       u8 type = FIELD_GET(WILC_WID_TYPE, id);
-       int ret = 0;
-
-       switch (type) {
-       case CFG_BYTE_CMD:
-               if (size >= 1)
-                       ret = wilc_wlan_cfg_set_byte(frame, offset, id, *buf);
-               break;
-
-       case CFG_HWORD_CMD:
-               if (size >= 2)
-                       ret = wilc_wlan_cfg_set_hword(frame, offset, id,
-                                                     *((u16 *)buf));
-               break;
-
-       case CFG_WORD_CMD:
-               if (size >= 4)
-                       ret = wilc_wlan_cfg_set_word(frame, offset, id,
-                                                    *((u32 *)buf));
-               break;
-
-       case CFG_STR_CMD:
-               ret = wilc_wlan_cfg_set_str(frame, offset, id, buf, size);
-               break;
-
-       case CFG_BIN_CMD:
-               ret = wilc_wlan_cfg_set_bin(frame, offset, id, buf, size);
-               break;
-       }
-
-       return ret;
-}
-
-int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id)
-{
-       if ((offset + 2) >= WILC_MAX_CFG_FRAME_SIZE)
-               return 0;
-
-       put_unaligned_le16(id, &frame[offset]);
-
-       return 2;
-}
-
-int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer,
-                         u32 buffer_size)
-{
-       u8 type = FIELD_GET(WILC_WID_TYPE, wid);
-       int i, ret = 0;
-       struct wilc_cfg *cfg = &wl->cfg;
-
-       i = 0;
-       if (type == CFG_BYTE_CMD) {
-               while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
-                       i++;
-
-               if (cfg->b[i].id == wid) {
-                       memcpy(buffer, &cfg->b[i].val, 1);
-                       ret = 1;
-               }
-       } else if (type == CFG_HWORD_CMD) {
-               while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
-                       i++;
-
-               if (cfg->hw[i].id == wid) {
-                       memcpy(buffer, &cfg->hw[i].val, 2);
-                       ret = 2;
-               }
-       } else if (type == CFG_WORD_CMD) {
-               while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
-                       i++;
-
-               if (cfg->w[i].id == wid) {
-                       memcpy(buffer, &cfg->w[i].val, 4);
-                       ret = 4;
-               }
-       } else if (type == CFG_STR_CMD) {
-               while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
-                       i++;
-
-               if (cfg->s[i].id == wid) {
-                       u16 size = get_unaligned_le16(cfg->s[i].str);
-
-                       if (buffer_size >= size) {
-                               memcpy(buffer, &cfg->s[i].str[2], size);
-                               ret = size;
-                       }
-               }
-       }
-       return ret;
-}
-
-void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
-                              struct wilc_cfg_rsp *rsp)
-{
-       u8 msg_type;
-       u8 msg_id;
-
-       msg_type = frame[0];
-       msg_id = frame[1];      /* seq no */
-       frame += 4;
-       size -= 4;
-       rsp->type = 0;
-
-       switch (msg_type) {
-       case WILC_RESP_MSG_TYPE_CONFIG_REPLY:
-               wilc_wlan_parse_response_frame(wilc, frame, size);
-               rsp->type = WILC_CFG_RSP;
-               rsp->seq_no = msg_id;
-               break;
-
-       case WILC_RESP_MSG_TYPE_STATUS_INFO:
-               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 */
-               wilc_gnrl_async_info_received(wilc, frame - 4, size + 4);
-               break;
-
-       case WILC_RESP_MSG_TYPE_NETWORK_INFO:
-               wilc_network_info_received(wilc, frame - 4, size + 4);
-               break;
-
-       case WILC_RESP_MSG_TYPE_SCAN_COMPLETE:
-               wilc_scan_complete_received(wilc, frame - 4, size + 4);
-               break;
-
-       default:
-               rsp->seq_no = msg_id;
-               break;
-       }
-}
-
-int wilc_wlan_cfg_init(struct wilc *wl)
-{
-       struct wilc_cfg_str_vals *str_vals;
-       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;
-
-       str_vals = kzalloc(sizeof(*str_vals), GFP_KERNEL);
-       if (!str_vals)
-               goto out_s;
-
-       wl->cfg.str_vals = str_vals;
-       /* store the string cfg parameters */
-       wl->cfg.s[i].id = WID_FIRMWARE_VERSION;
-       wl->cfg.s[i].str = str_vals->firmware_version;
-       i++;
-       wl->cfg.s[i].id = WID_MAC_ADDR;
-       wl->cfg.s[i].str = str_vals->mac_address;
-       i++;
-       wl->cfg.s[i].id = WID_ASSOC_RES_INFO;
-       wl->cfg.s[i].str = str_vals->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)
-{
-       kfree(wl->cfg.b);
-       kfree(wl->cfg.hw);
-       kfree(wl->cfg.w);
-       kfree(wl->cfg.s);
-       kfree(wl->cfg.str_vals);
-}
diff --git a/drivers/staging/wilc1000/wlan_cfg.h b/drivers/staging/wilc1000/wlan_cfg.h
deleted file mode 100644 (file)
index 614c567..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#ifndef WILC_WLAN_CFG_H
-#define WILC_WLAN_CFG_H
-
-struct wilc_cfg_byte {
-       u16 id;
-       u8 val;
-};
-
-struct wilc_cfg_hword {
-       u16 id;
-       u16 val;
-};
-
-struct wilc_cfg_word {
-       u16 id;
-       u32 val;
-};
-
-struct wilc_cfg_str {
-       u16 id;
-       u8 *str;
-};
-
-struct wilc_cfg_str_vals {
-       u8 mac_address[7];
-       u8 firmware_version[129];
-       u8 assoc_rsp[256];
-};
-
-struct wilc_cfg {
-       struct wilc_cfg_byte *b;
-       struct wilc_cfg_hword *hw;
-       struct wilc_cfg_word *w;
-       struct wilc_cfg_str *s;
-       struct wilc_cfg_str_vals *str_vals;
-};
-
-struct wilc;
-int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size);
-int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id);
-int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer,
-                         u32 buffer_size);
-void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
-                              struct wilc_cfg_rsp *rsp);
-int wilc_wlan_cfg_init(struct wilc *wl);
-void wilc_wlan_cfg_deinit(struct wilc *wl);
-
-#endif
diff --git a/drivers/staging/wilc1000/wlan_if.h b/drivers/staging/wilc1000/wlan_if.h
deleted file mode 100644 (file)
index f85fd57..0000000
+++ /dev/null
@@ -1,803 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#ifndef WILC_WLAN_IF_H
-#define WILC_WLAN_IF_H
-
-#include <linux/netdevice.h>
-#include "fw.h"
-
-/********************************************
- *
- *      Wlan Configuration ID
- *
- ********************************************/
-
-enum bss_types {
-       WILC_FW_BSS_TYPE_INFRA = 0,
-       WILC_FW_BSS_TYPE_INDEPENDENT,
-       WILC_FW_BSS_TYPE_AP,
-};
-
-enum {
-       WILC_FW_OPER_MODE_B_ONLY = 0,    /* 1, 2 M, otherwise 5, 11 M */
-       WILC_FW_OPER_MODE_G_ONLY,        /* 6,12,24 otherwise 9,18,36,48,54 */
-       WILC_FW_OPER_MODE_G_MIXED_11B_1, /* 1,2,5.5,11 otherwise all on */
-       WILC_FW_OPER_MODE_G_MIXED_11B_2, /* 1,2,5,11,6,12,24 otherwise all on */
-};
-
-enum {
-       WILC_FW_PREAMBLE_SHORT = 0,     /* Short Preamble */
-       WILC_FW_PREAMBLE_LONG = 1,      /* Long Preamble */
-       WILC_FW_PREAMBLE_AUTO = 2,      /* Auto Preamble Selection */
-};
-
-enum {
-       WILC_FW_PASSIVE_SCAN = 0,
-       WILC_FW_ACTIVE_SCAN = 1,
-};
-
-enum {
-       WILC_FW_NO_POWERSAVE = 0,
-       WILC_FW_MIN_FAST_PS = 1,
-       WILC_FW_MAX_FAST_PS = 2,
-       WILC_FW_MIN_PSPOLL_PS = 3,
-       WILC_FW_MAX_PSPOLL_PS = 4
-};
-
-enum chip_ps_states {
-       WILC_CHIP_WAKEDUP = 0,
-       WILC_CHIP_SLEEPING_AUTO = 1,
-       WILC_CHIP_SLEEPING_MANUAL = 2
-};
-
-enum bus_acquire {
-       WILC_BUS_ACQUIRE_ONLY = 0,
-       WILC_BUS_ACQUIRE_AND_WAKEUP = 1,
-};
-
-enum bus_release {
-       WILC_BUS_RELEASE_ONLY = 0,
-       WILC_BUS_RELEASE_ALLOW_SLEEP = 1,
-};
-
-enum {
-       WILC_FW_NO_ENCRYPT = 0,
-       WILC_FW_ENCRYPT_ENABLED = BIT(0),
-       WILC_FW_WEP = BIT(1),
-       WILC_FW_WEP_EXTENDED = BIT(2),
-       WILC_FW_WPA = BIT(3),
-       WILC_FW_WPA2 = BIT(4),
-       WILC_FW_AES = BIT(5),
-       WILC_FW_TKIP = BIT(6)
-};
-
-enum {
-       WILC_FW_SEC_NO = WILC_FW_NO_ENCRYPT,
-       WILC_FW_SEC_WEP = WILC_FW_WEP | WILC_FW_ENCRYPT_ENABLED,
-       WILC_FW_SEC_WEP_EXTENDED = WILC_FW_WEP_EXTENDED | WILC_FW_SEC_WEP,
-       WILC_FW_SEC_WPA = WILC_FW_WPA | WILC_FW_ENCRYPT_ENABLED,
-       WILC_FW_SEC_WPA_AES = WILC_FW_AES | WILC_FW_SEC_WPA,
-       WILC_FW_SEC_WPA_TKIP = WILC_FW_TKIP | WILC_FW_SEC_WPA,
-       WILC_FW_SEC_WPA2 = WILC_FW_WPA2 | WILC_FW_ENCRYPT_ENABLED,
-       WILC_FW_SEC_WPA2_AES = WILC_FW_AES | WILC_FW_SEC_WPA2,
-       WILC_FW_SEC_WPA2_TKIP = WILC_FW_TKIP | WILC_FW_SEC_WPA2
-};
-
-enum authtype {
-       WILC_FW_AUTH_OPEN_SYSTEM = 1,
-       WILC_FW_AUTH_SHARED_KEY = 2,
-       WILC_FW_AUTH_ANY = 3,
-       WILC_FW_AUTH_IEEE8021 = 5
-};
-
-enum site_survey {
-       WILC_FW_SITE_SURVEY_1CH = 0,
-       WILC_FW_SITE_SURVEY_ALL_CH = 1,
-       WILC_FW_SITE_SURVEY_OFF = 2
-};
-
-enum {
-       WILC_FW_ACK_POLICY_NORMAL = 0,
-       WILC_FW_ACK_NO_POLICY,
-};
-
-enum {
-       WILC_FW_REKEY_POLICY_DISABLE = 1,
-       WILC_FW_REKEY_POLICY_TIME_BASE,
-       WILC_FW_REKEY_POLICY_PKT_BASE,
-       WILC_FW_REKEY_POLICY_TIME_PKT_BASE
-};
-
-enum {
-       WILC_FW_FILTER_NO = 0x00,
-       WILC_FW_FILTER_AP_ONLY = 0x01,
-       WILC_FW_FILTER_STA_ONLY = 0x02
-};
-
-enum {
-       WILC_FW_11N_PROT_AUTO = 0,      /* Auto */
-       WILC_FW_11N_NO_PROT,            /* Do not use any protection */
-       WILC_FW_11N_PROT_ERP,           /* Protect all ERP frame exchanges */
-       WILC_FW_11N_PROT_HT,            /* Protect all HT frame exchanges  */
-       WILC_FW_11N_PROT_GF             /* Protect all GF frame exchanges  */
-};
-
-enum {
-       WILC_FW_ERP_PROT_SELF_CTS,
-       WILC_FW_ERP_PROT_RTS_CTS,
-};
-
-enum {
-       WILC_FW_11N_OP_MODE_HT_MIXED = 1,
-       WILC_FW_11N_OP_MODE_HT_ONLY_20MHZ,
-       WILC_FW_11N_OP_MODE_HT_ONLY_20_40MHZ,
-};
-
-enum {
-       WILC_FW_OBBS_NONHT_NO_DETECT = 0,
-       WILC_FW_OBBS_NONHT_DETECT_ONLY = 1,
-       WILC_FW_OBBS_NONHT_DETECT_PROTECT = 2,
-       WILC_FW_OBBS_NONHT_DETECT_PROTECT_REPORT = 3,
-};
-
-enum {
-       WILC_FW_HT_PROT_RTS_CTS_NONHT = 0,  /* RTS-CTS at non-HT rate */
-       WILC_FW_HT_PROT_FIRST_FRAME_NONHT,  /* First frame at non-HT rate */
-       WILC_FW_HT_PROT_LSIG_TXOP,          /* LSIG TXOP Protection */
-       WILC_FW_HT_PROT_FIRST_FRAME_MIXED,  /* First frame at Mixed format */
-};
-
-enum {
-       WILC_FW_SMPS_MODE_STATIC = 1,
-       WILC_FW_SMPS_MODE_DYNAMIC = 2,
-       WILC_FW_SMPS_MODE_MIMO = 3,     /* power save disable */
-};
-
-enum {
-       WILC_FW_TX_RATE_AUTO = 0,
-       WILC_FW_TX_RATE_MBPS_1 = 1,
-       WILC_FW_TX_RATE_MBPS_2 = 2,
-       WILC_FW_TX_RATE_MBPS_5_5 = 5,
-       WILC_FW_TX_RATE_MBPS_11 = 11,
-       WILC_FW_TX_RATE_MBPS_6 = 6,
-       WILC_FW_TX_RATE_MBPS_9 = 9,
-       WILC_FW_TX_RATE_MBPS_12 = 12,
-       WILC_FW_TX_RATE_MBPS_18 = 18,
-       WILC_FW_TX_RATE_MBPS_24 = 24,
-       WILC_FW_TX_RATE_MBPS_36 = 36,
-       WILC_FW_TX_RATE_MBPS_48 = 48,
-       WILC_FW_TX_RATE_MBPS_54 = 54
-};
-
-enum {
-       WILC_FW_DEFAULT_SCAN = 0,
-       WILC_FW_USER_SCAN = BIT(0),
-       WILC_FW_OBSS_PERIODIC_SCAN = BIT(1),
-       WILC_FW_OBSS_ONETIME_SCAN = BIT(2)
-};
-
-enum {
-       WILC_FW_ACTION_FRM_IDX = 0,
-       WILC_FW_PROBE_REQ_IDX = 1
-};
-
-enum wid_type {
-       WID_CHAR                = 0,
-       WID_SHORT               = 1,
-       WID_INT                 = 2,
-       WID_STR                 = 3,
-       WID_BIN_DATA            = 4,
-       WID_BIN                 = 5,
-};
-
-struct wid {
-       u16 id;
-       enum wid_type type;
-       s32 size;
-       s8 *val;
-};
-
-enum {
-       WID_NIL                         = 0xffff,
-
-       /*
-        *  BSS Type
-        *  -----------------------------------------------------------
-        *  Configuration : Infrastructure   Independent   Access Point
-        *  Values to set :         0               1            2
-        *  -----------------------------------------------------------
-        */
-       WID_BSS_TYPE                    = 0x0000,
-
-       /*
-        *  Transmit Rate
-        *  -----------------------------------------------------------
-        *  Configuration : 1  2  5.5  11  6  9  12  18  24  36  48  54
-        *  Values to set : 1  2    5  11  6  9  12  18  24  36  48  54
-        *  -----------------------------------------------------------
-        */
-       WID_CURRENT_TX_RATE             = 0x0001,
-
-       /*
-        *  Channel
-        *  -----------------------------------------------------------
-        *  Configuration(g) : 1  2  3  4  5  6  7  8  9 10 11 12 13 14
-        *  Values to set    : 1  2  3  4  5  6  7  8  9 10 11 12 13 14
-        *  -----------------------------------------------------------
-        */
-       WID_CURRENT_CHANNEL             = 0x0002,
-
-       /*
-        *  Preamble
-        *  -----------------------------------------------------------
-        *  Configuration :    short    long      Auto
-        *  Values to set :       0       1         2
-        *  -----------------------------------------------------------
-        */
-       WID_PREAMBLE                    = 0x0003,
-
-       /*
-        * 11g operating mode (ignored if 11g not present)
-        *  -----------------------------------------------------------
-        *  Configuration :   HighPerf  Compat(RSet #1) Compat(RSet #2)
-        *  Values to set :          1               2               3
-        *  -----------------------------------------------------------
-        */
-       WID_11G_OPERATING_MODE          = 0x0004,
-
-       /*
-        *  Mac status (response only)
-        *  -----------------------------------------------------------
-        *  Configuration :   disconnect  connect
-        *  Values to get :          0       1
-        *  -----------------------------------------------------------
-        */
-       WID_STATUS                      = 0x0005,
-
-       /*
-        *  Scan type
-        *  -----------------------------------------------------------
-        *  Configuration :   Passive Scanning   Active Scanning
-        *  Values to set :                  0                 1
-        *  -----------------------------------------------------------
-        */
-       WID_SCAN_TYPE                   = 0x0007,
-
-       /*
-        *  Key Id (WEP default key Id)
-        *  -----------------------------------------------------------
-        *  Configuration :   Any value between 0 to 3
-        *  Values to set :   Same value. Default is 0
-        *  -----------------------------------------------------------
-        */
-       WID_KEY_ID                      = 0x0009,
-
-       /*
-        *  QoS Enable
-        *  -----------------------------------------------------------
-        *  Configuration :   QoS Disable   WMM Enable
-        *  Values to set :   0             1
-        *  -----------------------------------------------------------
-        */
-       WID_QOS_ENABLE                  = 0x000A,
-
-       /*
-        *  Power Management
-        *  -----------------------------------------------------------
-        *  Configuration : NO_POWERSAVE MIN_POWERSAVE MAX_POWERSAVE
-        *  Values to set : 0            1             2
-        *  -----------------------------------------------------------
-        */
-       WID_POWER_MANAGEMENT            = 0x000B,
-
-       /*
-        *  WEP/802 11I Configuration
-        *  -----------------------------------------------------------
-        *  Configuration:Disable WP40 WP104 WPA-AES WPA-TKIP RSN-AES RSN-TKIP
-        *  Values (0x)  :   00     03   07     29       49       31      51
-        *  Configuration:WPA-AES+TKIP RSN-AES+TKIP
-        *  Values (0x)  :      69        71
-        *  -----------------------------------------------------------
-        */
-       WID_11I_MODE                    = 0x000C,
-
-       /*
-        *  WEP Configuration: Used in BSS STA mode only when WEP is enabled
-        *  -----------------------------------------------------------
-        *  Configuration : Open System Shared Key Any Type | 802.1x Auth
-        *  Values (0x)   :    01             02         03 |    BIT2
-        *  -----------------------------------------------------------
-        */
-       WID_AUTH_TYPE                   = 0x000D,
-
-       /*
-        *  Site Survey Type
-        *  -----------------------------------------------------------
-        *  Configuration       :  Values to set
-        *  Survey 1 Channel    :  0
-        *  survey all Channels :  1
-        *  Disable Site Survey :  2
-        *  -----------------------------------------------------------
-        */
-       WID_SITE_SURVEY                 = 0x000E,
-
-       /*
-        *  Listen Interval
-        *  -----------------------------------------------------------
-        *  Configuration :   Any value between 1 to 255
-        *  Values to set :   Same value. Default is 3
-        *  -----------------------------------------------------------
-        */
-       WID_LISTEN_INTERVAL             = 0x000F,
-
-       /*
-        *  DTIM Period
-        *  -----------------------------------------------------------
-        *  Configuration :   Any value between 1 to 255
-        *  Values to set :   Same value. Default is 3
-        *  -----------------------------------------------------------
-        */
-       WID_DTIM_PERIOD                 = 0x0010,
-
-       /*
-        *  ACK Policy
-        *  -----------------------------------------------------------
-        *  Configuration :   Normal Ack            No Ack
-        *  Values to set :       0                   1
-        *  -----------------------------------------------------------
-        */
-       WID_ACK_POLICY                  = 0x0011,
-
-       /*
-        *  Reset MAC (Set only)
-        *  -----------------------------------------------------------
-        *  Configuration :   Don't Reset       Reset   No Request
-        *  Values to set :       0               1         2
-        *  -----------------------------------------------------------
-        */
-       WID_RESET                       = 0x0012,
-
-       /*
-        *  Broadcast SSID Option: Setting this will adhere to "" SSID element
-        *  -----------------------------------------------------------
-        *  Configuration :   Enable             Disable
-        *  Values to set :   1                  0
-        *  -----------------------------------------------------------
-        */
-       WID_BCAST_SSID                  = 0x0015,
-
-       /*
-        *  Disconnect (Station)
-        *  -----------------------------------------------------------
-        *  Configuration :   Association ID
-        *  Values to set :   Association ID
-        *  -----------------------------------------------------------
-        */
-       WID_DISCONNECT                  = 0x0016,
-
-       /*
-        *  11a Tx Power Level
-        *  -----------------------------------------------------------
-        *  Configuration : Sets TX Power (Higher the value greater the power)
-        *  Values to set : Any value between 0 and 63 (inclusive Default 48)
-        *  -----------------------------------------------------------
-        */
-       WID_TX_POWER_LEVEL_11A          = 0x0018,
-
-       /*
-        *  Group Key Update Policy Selection
-        *  -----------------------------------------------------------
-        *  Configuration : Disabled timeBased packetBased timePacketBased
-        *  Values to set :   1            2          3              4
-        *  -----------------------------------------------------------
-        */
-       WID_REKEY_POLICY                = 0x0019,
-
-       /*
-        *  Allow Short Slot
-        *  -----------------------------------------------------------
-        *  Configuration : Disallow Short Slot      Allow Short Slot
-        *          (Enable Only Long Slot) (Enable Short Slot if applicable)
-        *  Values to set :    0         1
-        *  -----------------------------------------------------------
-        */
-       WID_SHORT_SLOT_ALLOWED          = 0x001A,
-
-       WID_PHY_ACTIVE_REG              = 0x001B,
-
-       /*
-        *  11b Tx Power Level
-        *  -----------------------------------------------------------
-        *  Configuration : Sets TX Power (Higher the value greater the power)
-        *  Values to set : Any value between 0 and 63 (inclusive Default 48)
-        *  -----------------------------------------------------------
-        */
-       WID_TX_POWER_LEVEL_11B          = 0x001D,
-
-       /*
-        *  Scan Request
-        *  -----------------------------------------------------------
-        *  Configuration : Request default scan
-        *  Values to set : 0
-        *  -----------------------------------------------------------
-        */
-       WID_START_SCAN_REQ              = 0x001E,
-
-       /*
-        *  Rssi (get only)
-        *  -----------------------------------------------------------
-        *  Configuration :
-        *  Values to get : Rssi value
-        *  -----------------------------------------------------------
-        */
-       WID_RSSI                        = 0x001F,
-
-       /*
-        * Join Request
-        *  -----------------------------------------------------------
-        *  Configuration : Request to join
-        *  Values to set : index of scan result
-        *  -----------------------------------------------------------
-        */
-       WID_JOIN_REQ                    = 0x0020,
-
-       WID_LINKSPEED                   = 0x0026,
-
-       /*
-        *  Enable User Control of TX Power
-        *  -----------------------------------------------------------
-        *  Configuration : Disable                  Enable
-        *  Values to set :    0                       1
-        *  -----------------------------------------------------------
-        */
-       WID_USER_CONTROL_ON_TX_POWER    = 0x0027,
-
-       WID_MEMORY_ACCESS_8BIT          = 0x0029,
-
-       /*
-        *  Enable Auto RX Sensitivity feature
-        *  -----------------------------------------------------------
-        *  Configuration : Disable                  Enable
-        *  Values to set :    0                       1
-        *  -----------------------------------------------------------
-        */
-       WID_AUTO_RX_SENSITIVITY         = 0x0032,
-
-       /*
-        *  Receive Buffer Based Ack
-        *  -----------------------------------------------------------
-        *  Configuration : Disable                  Enable
-        *  Values to set :    0                       1
-        *  -----------------------------------------------------------
-        */
-       WID_DATAFLOW_CONTROL            = 0x0033,
-
-       /*
-        *  Scan Filter
-        *  -----------------------------------------------------------
-        *  Configuration : Class       No filter   AP only   Station Only
-        *  Values to set :                0           1           2
-        *  Configuration : Priority    High Rssi   Low Rssi     Detect
-        *  Values to set :                0          0x4         0x0
-        *  Configuration : Channel     filter off  filter on
-        *  Values to set :                0          0x10
-        *  -----------------------------------------------------------
-        */
-       WID_SCAN_FILTER                 = 0x0036,
-
-       /*
-        *  Link Loss Threshold (measure in the beacon period)
-        *  -----------------------------------------------------------
-        *  Configuration : Any value between 10 and 254(Set to 255 disable)
-        *  Values to set : Same value. Default is 10
-        *  -----------------------------------------------------------
-        */
-       WID_LINK_LOSS_THRESHOLD         = 0x0037,
-
-       WID_ABORT_RUNNING_SCAN          = 0x003E,
-
-       /* NMAC Character WID list */
-       WID_WPS_START                   = 0x0043,
-
-       /*
-        *  Protection mode for MAC
-        *  -----------------------------------------------------------
-        *  Configuration :  Auto  No protection  ERP    HT    GF
-        *  Values to set :  0     1              2      3     4
-        *  -----------------------------------------------------------
-        */
-       WID_11N_PROT_MECH               = 0x0080,
-
-       /*
-        *  ERP Protection type for MAC
-        *  -----------------------------------------------------------
-        *  Configuration :  Self-CTS   RTS-CTS
-        *  Values to set :  0          1
-        *  -----------------------------------------------------------
-        */
-       WID_11N_ERP_PROT_TYPE           = 0x0081,
-
-       /*
-        *  HT Option Enable
-        *  -----------------------------------------------------------
-        *  Configuration :   HT Enable          HT Disable
-        *  Values to set :   1                  0
-        *  -----------------------------------------------------------
-        */
-       WID_11N_ENABLE                  = 0x0082,
-
-       /*
-        *  11n Operating mode (Note that 11g operating mode will also be
-        *  used in addition to this, if this is set to HT Mixed mode)
-        *  -----------------------------------------------------------
-        *   Configuration :  HT Mixed  HT Only-20MHz   HT Only-20/40MHz
-        *  Values to set :     1         2               3
-        *  -----------------------------------------------------------
-        */
-       WID_11N_OPERATING_MODE          = 0x0083,
-
-       /*
-        *  11n OBSS non-HT STA Detection flag
-        *  -----------------------------------------------------------
-        *  Configuration :  Do not detect
-        *  Values to set :  0
-        *  Configuration :  Detect, do not protect or report
-        *  Values to set :  1
-        *  Configuration :  Detect, protect and do not report
-        *  Values to set :  2
-        *  Configuration :  Detect, protect and report to other BSS
-        *  Values to set :  3
-        *  -----------------------------------------------------------
-        */
-       WID_11N_OBSS_NONHT_DETECTION    = 0x0084,
-
-       /*
-        *  11n HT Protection Type
-        *  -----------------------------------------------------------
-        *  Configuration :  RTS-CTS   First Frame Exchange at non-HT-rate
-        *  Values to set :  0         1
-        *  Configuration :  LSIG TXOP First Frame Exchange in Mixed Fmt
-        *  Values to set :  2         3
-        *  -----------------------------------------------------------
-        */
-       WID_11N_HT_PROT_TYPE            = 0x0085,
-
-       /*
-        *  11n RIFS Protection Enable Flag
-        *  -----------------------------------------------------------
-        *  Configuration :  Disable    Enable
-        *  Values to set :  0          1
-        *  -----------------------------------------------------------
-        */
-       WID_11N_RIFS_PROT_ENABLE        = 0x0086,
-
-       /*
-        *  SMPS Mode
-        *  -----------------------------------------------------------
-        *  Configuration :  Static   Dynamic   MIMO (Power Save Disabled)
-        *  Values to set :  1        2         3
-        *  -----------------------------------------------------------
-        */
-       WID_11N_SMPS_MODE               = 0x0087,
-
-       /*
-        *  Current transmit MCS
-        *  -----------------------------------------------------------
-        *  Configuration :  MCS Index for data rate
-        *  Values to set :  0 to 7
-        *  -----------------------------------------------------------
-        */
-       WID_11N_CURRENT_TX_MCS          = 0x0088,
-
-       WID_11N_PRINT_STATS             = 0x0089,
-
-       /*
-        *  11n Short GI Enable Flag
-        *  -----------------------------------------------------------
-        *  Configuration :  Disable    Enable
-        *  Values to set :  0          1
-        *  -----------------------------------------------------------
-        */
-       WID_11N_SHORT_GI_ENABLE         = 0x008D,
-
-       /*
-        *  11n RIFS Enable Flag
-        *  -----------------------------------------------------------
-        *  Configuration :  Disable    Enable
-        *  Values to set :  0          1
-        *  -----------------------------------------------------------
-        */
-       WID_RIFS_MODE                   = 0x0094,
-
-       /*
-        *  TX Abort Feature
-        *  -----------------------------------------------------------
-        *  Configuration :  Disable Self CTS    Enable Self CTS
-        *  Values to set :             0                      1
-        *  Configuration :  Disable TX Abort    Enable TX Abort
-        *  Values to set :             2                      3
-        *  Configuration :  Enable HW TX Abort Enable SW TX Abort
-        *  Values to set :             4                      5
-        *  -----------------------------------------------------------
-        */
-       WID_TX_ABORT_CONFIG             = 0x00A1,
-
-       WID_REG_TSSI_11B_VALUE          = 0x00A6,
-       WID_REG_TSSI_11G_VALUE          = 0x00A7,
-       WID_REG_TSSI_11N_VALUE          = 0x00A8,
-       WID_TX_CALIBRATION              = 0x00A9,
-       WID_DSCR_TSSI_11B_VALUE         = 0x00AA,
-       WID_DSCR_TSSI_11G_VALUE         = 0x00AB,
-       WID_DSCR_TSSI_11N_VALUE         = 0x00AC,
-
-       /*
-        *  Immediate Block-Ack Support
-        *  -----------------------------------------------------------
-        *  Configuration : Disable                  Enable
-        *  Values to set :    0                       1
-        *  -----------------------------------------------------------
-        */
-       WID_11N_IMMEDIATE_BA_ENABLED    = 0x00AF,
-
-       /*
-        *  TXOP Disable Flag
-        *  -----------------------------------------------------------
-        *  Configuration : Disable                  Enable
-        *  Values to set :    1                        0
-        *  -----------------------------------------------------------
-        */
-       WID_11N_TXOP_PROT_DISABLE       = 0x00B0,
-
-       WID_TX_POWER_LEVEL_11N          = 0x00B1,
-
-       /* Custom Character WID list */
-       /* SCAN Complete notification WID*/
-       WID_SCAN_COMPLETE               = 0x00C9,
-
-       WID_DEL_BEACON                  = 0x00CA,
-
-       WID_LOG_TERMINAL_SWITCH         = 0x00CD,
-       WID_TX_POWER                    = 0x00CE,
-       /*  EMAC Short WID list */
-       /*  RTS Threshold */
-       /*
-        *  -----------------------------------------------------------
-        *  Configuration :   Any value between 256 to 2347
-        *  Values to set :   Same value. Default is 2347
-        *  -----------------------------------------------------------
-        */
-       WID_RTS_THRESHOLD               = 0x1000,
-
-       /*
-        *  Fragmentation Threshold
-        *  -----------------------------------------------------------
-        *  Configuration :   Any value between 256 to 2346
-        *  Values to set :   Same value. Default is 2346
-        *  -----------------------------------------------------------
-        */
-       WID_FRAG_THRESHOLD              = 0x1001,
-
-       WID_SHORT_RETRY_LIMIT           = 0x1002,
-       WID_LONG_RETRY_LIMIT            = 0x1003,
-       WID_BEACON_INTERVAL             = 0x1006,
-       WID_MEMORY_ACCESS_16BIT         = 0x1008,
-       WID_PASSIVE_SCAN_TIME           = 0x100D,
-       WID_JOIN_START_TIMEOUT          = 0x100F,
-       WID_ASOC_TIMEOUT                = 0x1011,
-       WID_11I_PROTOCOL_TIMEOUT        = 0x1012,
-       WID_EAPOL_RESPONSE_TIMEOUT      = 0x1013,
-
-       /* NMAC Short WID list */
-       WID_11N_SIG_QUAL_VAL            = 0x1085,
-       WID_CCA_THRESHOLD               = 0x1087,
-
-       /* Custom Short WID list */
-
-       /* EMAC Integer WID list */
-       WID_FAILED_COUNT                = 0x2000,
-       WID_RETRY_COUNT                 = 0x2001,
-       WID_MULTIPLE_RETRY_COUNT        = 0x2002,
-       WID_FRAME_DUPLICATE_COUNT       = 0x2003,
-       WID_ACK_FAILURE_COUNT           = 0x2004,
-       WID_RECEIVED_FRAGMENT_COUNT     = 0x2005,
-       WID_MCAST_RECEIVED_FRAME_COUNT  = 0x2006,
-       WID_FCS_ERROR_COUNT             = 0x2007,
-       WID_SUCCESS_FRAME_COUNT         = 0x2008,
-       WID_HUT_TX_COUNT                = 0x200A,
-       WID_TX_FRAGMENT_COUNT           = 0x200B,
-       WID_TX_MULTICAST_FRAME_COUNT    = 0x200C,
-       WID_RTS_SUCCESS_COUNT           = 0x200D,
-       WID_RTS_FAILURE_COUNT           = 0x200E,
-       WID_WEP_UNDECRYPTABLE_COUNT     = 0x200F,
-       WID_REKEY_PERIOD                = 0x2010,
-       WID_REKEY_PACKET_COUNT          = 0x2011,
-       WID_1X_SERV_ADDR                = 0x2012,
-       WID_STACK_IP_ADDR               = 0x2013,
-       WID_STACK_NETMASK_ADDR          = 0x2014,
-       WID_HW_RX_COUNT                 = 0x2015,
-       WID_MEMORY_ADDRESS              = 0x201E,
-       WID_MEMORY_ACCESS_32BIT         = 0x201F,
-
-       /* NMAC Integer WID list */
-       /* Custom Integer WID list */
-       WID_GET_INACTIVE_TIME           = 0x2084,
-       /* EMAC String WID list */
-       WID_SSID                        = 0x3000,
-       WID_FIRMWARE_VERSION            = 0x3001,
-       WID_OPERATIONAL_RATE_SET        = 0x3002,
-       WID_BSSID                       = 0x3003,
-       WID_WEP_KEY_VALUE               = 0x3004,
-       WID_11I_PSK                     = 0x3008,
-       WID_11E_P_ACTION_REQ            = 0x3009,
-       WID_1X_KEY                      = 0x300A,
-       WID_HARDWARE_VERSION            = 0x300B,
-       WID_MAC_ADDR                    = 0x300C,
-       WID_HUT_DEST_ADDR               = 0x300D,
-       WID_PHY_VERSION                 = 0x300F,
-       WID_SUPP_USERNAME               = 0x3010,
-       WID_SUPP_PASSWORD               = 0x3011,
-       WID_SITE_SURVEY_RESULTS         = 0x3012,
-       WID_RX_POWER_LEVEL              = 0x3013,
-       WID_SET_STA_MAC_INACTIVE_TIME   = 0x3017,
-       WID_ADD_WEP_KEY                 = 0x3019,
-       WID_REMOVE_WEP_KEY              = 0x301A,
-       WID_ADD_PTK                     = 0x301B,
-       WID_ADD_RX_GTK                  = 0x301C,
-       WID_ADD_TX_GTK                  = 0x301D,
-       WID_REMOVE_KEY                  = 0x301E,
-       WID_ASSOC_REQ_INFO              = 0x301F,
-       WID_ASSOC_RES_INFO              = 0x3020,
-       WID_MANUFACTURER                = 0x3026, /* Added for CAPI tool */
-       WID_MODEL_NAME                  = 0x3027, /* Added for CAPI tool */
-       WID_MODEL_NUM                   = 0x3028, /* Added for CAPI tool */
-       WID_DEVICE_NAME                 = 0x3029, /* Added for CAPI tool */
-
-       /* NMAC String WID list */
-       WID_SET_OPERATION_MODE          = 0x3079,
-       WID_11N_P_ACTION_REQ            = 0x3080,
-       WID_HUT_TEST_ID                 = 0x3081,
-       WID_PMKID_INFO                  = 0x3082,
-       WID_FIRMWARE_INFO               = 0x3083,
-       WID_REGISTER_FRAME              = 0x3084,
-       WID_DEL_ALL_STA                 = 0x3085,
-       WID_REMAIN_ON_CHAN              = 0x3996,
-       WID_SSID_PROBE_REQ              = 0x3997,
-       WID_JOIN_REQ_EXTENDED           = 0x3998,
-
-       WID_IP_ADDRESS                  = 0x3999,
-
-       /* Custom String WID list */
-
-       /* EMAC Binary WID list */
-       WID_UAPSD_CONFIG                = 0x4001,
-       WID_UAPSD_STATUS                = 0x4002,
-       WID_WMM_AP_AC_PARAMS            = 0x4003,
-       WID_WMM_STA_AC_PARAMS           = 0x4004,
-       WID_NETWORK_INFO                = 0x4005,
-       WID_STA_JOIN_INFO               = 0x4006,
-       WID_CONNECTED_STA_LIST          = 0x4007,
-
-       /* NMAC Binary WID list */
-       WID_11N_AUTORATE_TABLE          = 0x4080,
-
-       WID_SCAN_CHANNEL_LIST           = 0x4084,
-
-       WID_INFO_ELEMENT_PROBE          = 0x4085,
-       WID_INFO_ELEMENT_ASSOCIATE      = 0x4086,
-       WID_ADD_STA                     = 0X4087,
-       WID_REMOVE_STA                  = 0X4088,
-       WID_EDIT_STA                    = 0X4089,
-       WID_ADD_BEACON                  = 0x408a,
-
-       WID_SETUP_MULTICAST_FILTER      = 0x408b,
-
-       /* Miscellaneous WIDs */
-       WID_ALL                         = 0x7FFE,
-       WID_MAX                         = 0xFFFF
-};
-
-#endif