diff options
Diffstat (limited to 'drivers/staging')
25 files changed, 4 insertions, 10664 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4ec5528f89fa..b3fb4d41e231 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -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" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 4d34198151b3..3d8c7ea21a10 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -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/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index 8e0f27e61652..509c8012d20b 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -46,7 +46,7 @@ MODULE_PARM_DESC(fcnt, "Num of frames per sub-buffer for sync channels as a powe static DEFINE_SPINLOCK(dim_lock); static void dim2_tasklet_fn(unsigned long data); -static DECLARE_TASKLET(dim2_tasklet, dim2_tasklet_fn, 0); +static DECLARE_TASKLET_OLD(dim2_tasklet, dim2_tasklet_fn); /** * struct hdm_channel - private structure to keep channel specific data diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c index c798672d61b2..cfb673a52b25 100644 --- a/drivers/staging/octeon/ethernet-mdio.c +++ b/drivers/staging/octeon/ethernet-mdio.c @@ -163,7 +163,7 @@ int cvm_oct_phy_setup_device(struct net_device *dev) of_node_put(phy_node); if (!phydev) - return -ENODEV; + return -EPROBE_DEFER; priv->last_link = 0; phy_start(phydev); diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h index e3771d48c49b..7f6716e3fad4 100644 --- a/drivers/staging/octeon/ethernet-mdio.h +++ b/drivers/staging/octeon/ethernet-mdio.h @@ -22,7 +22,5 @@ extern const struct ethtool_ops cvm_oct_ethtool_ops; -void octeon_mdiobus_force_mod_depencency(void); - int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); int cvm_oct_phy_setup_device(struct net_device *dev); diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index ab7dd8216006..9c71ad5af7b9 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -41,7 +41,7 @@ #endif static void cvm_oct_tx_do_cleanup(unsigned long arg); -static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup, 0); +static DECLARE_TASKLET_OLD(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup); /* Maximum number of SKBs to try to free per xmit packet. */ #define MAX_SKB_TO_FREE (MAX_OUT_QUEUE_DEPTH * 2) diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index f42c3816ce49..204f0b1e2739 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -689,8 +689,6 @@ static int cvm_oct_probe(struct platform_device *pdev) mtu_overhead += VLAN_HLEN; #endif - octeon_mdiobus_force_mod_depencency(); - pip = pdev->dev.of_node; if (!pip) { pr_err("Error: No 'pip' in /aliases\n"); @@ -987,6 +985,7 @@ static struct platform_driver cvm_oct_driver = { module_platform_driver(cvm_oct_driver); +MODULE_SOFTDEP("pre: mdio-cavium"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver."); diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig deleted file mode 100644 index 80c92e8bf8a5..000000000000 --- a/drivers/staging/wilc1000/Kconfig +++ /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 index a3305a0a888a..000000000000 --- a/drivers/staging/wilc1000/Makefile +++ /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 index b6065a0d660f..000000000000 --- a/drivers/staging/wilc1000/cfg80211.c +++ /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 index 37b294cb3b37..000000000000 --- a/drivers/staging/wilc1000/cfg80211.h +++ /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 index a76e1dea4345..000000000000 --- a/drivers/staging/wilc1000/fw.h +++ /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 index d025a3093015..000000000000 --- a/drivers/staging/wilc1000/hif.c +++ /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(¶m->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(¶m->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(>k_key->key[0], rx_gtk, gtk_key_len); - - if (rx_mic) - memcpy(>k_key->key[gtk_key_len], rx_mic, WILC_RX_MIC_KEY_LEN); - - if (tx_mic) - memcpy(>k_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 *)¶m->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 *)¶m->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 *)¶m->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 *)¶m->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 *)®_frame; - - memset(®_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 index db9179171f05..000000000000 --- a/drivers/staging/wilc1000/hif.h +++ /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 index 2c320eb2a8c4..000000000000 --- a/drivers/staging/wilc1000/microchip,wilc1000.yaml +++ /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 index 60331417bd98..000000000000 --- a/drivers/staging/wilc1000/mon.c +++ /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 index fda0ab97b02c..000000000000 --- a/drivers/staging/wilc1000/netdev.c +++ /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 index d0a006b68d08..000000000000 --- a/drivers/staging/wilc1000/netdev.h +++ /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 index 36eb589263bf..000000000000 --- a/drivers/staging/wilc1000/sdio.c +++ /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, ®)) { - 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, ®); - 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, ®); - 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, ®); - 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, ®); - 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 index 3f19e3f38a39..000000000000 --- a/drivers/staging/wilc1000/spi.c +++ /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, ®); - 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, ®); - 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, ®); - 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, ®); - 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, ®); - 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, ®); - 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 index 6a82fb2f283e..000000000000 --- a/drivers/staging/wilc1000/wlan.c +++ /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, ®); - - 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, ®); - 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, ®); - 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, ®); - 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, ®); - 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, ®); - 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, ®); - 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 |= 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, ®); - 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, ®); - 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, ®); - 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, - ®); - 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 index 7689569cd82f..000000000000 --- a/drivers/staging/wilc1000/wlan.h +++ /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 index fe2a7ed8e5cd..000000000000 --- a/drivers/staging/wilc1000/wlan_cfg.c +++ /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 index 614c5673f232..000000000000 --- a/drivers/staging/wilc1000/wlan_cfg.h +++ /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 index f85fd575136d..000000000000 --- a/drivers/staging/wilc1000/wlan_if.h +++ /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 |